DesignRTT

Version 5 (Anonymous, 05/31/2010 06:32 am)

1 1 Adrian Georgescu
2 5 Adrian Georgescu
h1. Real Time Text
3 1 Adrian Georgescu
4 1 Adrian Georgescu
5 1 Adrian Georgescu
6 1 Adrian Georgescu
7 1 Adrian Georgescu
8 5 Adrian Georgescu
h2. Introduction
9 1 Adrian Georgescu
10 1 Adrian Georgescu
11 5 Adrian Georgescu
!{ align=right, nolink}http://nlnet.nl/image/logo.gif!
12 5 Adrian Georgescu
13 5 Adrian Georgescu
!{ align=right, nolink}htdocs:R3TF_logo_web.jpg!
14 5 Adrian Georgescu
15 5 Adrian Georgescu
This document provides a proposal for how to integrate the T.140 Real-Time Text protocol over RTP, as described in "RFC 4103":http://tools.ietf.org/html/rfc4103, into the SIP SIMPLE client and consequently into "PJSIP":http://www.pjsip.org.  This is a joint effort between "R3TF":http://www.realtimetext.org, "NL NET fundation":http://nlnet.nl and "AG Projects":http://ag-projects.com with the goal of enabling Real Time Text as generic purpose communication tool.
16 5 Adrian Georgescu
17 5 Adrian Georgescu
18 5 Adrian Georgescu
h2. Use cases
19 5 Adrian Georgescu
20 5 Adrian Georgescu
21 5 Adrian Georgescu
* One can call a device directly using real-time text. The called device can be any ToIP client, it is possible with or without voice included
22 5 Adrian Georgescu
* One can decide to switch from IM mode to a more talking mode and press an activate real-time text button. This is similar with switching to voice.
23 5 Adrian Georgescu
* There is an hybrid form of real-time to be used as well. Real-time text preview. See: http://tools.ietf.org/html/draft-hellstrom-textpreview What you get is you see immediately what the other side is typing. And when he or she presses enter, it is sent en-bloc IM style thus combining best of both worlds
24 5 Adrian Georgescu
* Remote captioning, one big screen where one can modify the size of the text and receive the text interpreter text on it. The send window is almost non present in that mode (or only pulled up if one need to talk with the interpreter on one-on –one interpreter sessions).
25 5 Adrian Georgescu
26 1 Adrian Georgescu
> This document does not include any information on how to integrate RTT into the GUI, as this is not relevant at the PyPJUA level, the GUI is a separate project.
27 1 Adrian Georgescu
28 1 Adrian Georgescu
29 5 Adrian Georgescu
h2. Existing implementations
30 5 Adrian Georgescu
31 5 Adrian Georgescu
32 1 Adrian Georgescu
There are two known open source implementations of this protocol:
33 1 Adrian Georgescu
34 5 Adrian Georgescu
* The "RTP text/t140 Library":http://sourceforge.net/projects/rtp-text-t140/.
35 5 Adrian Georgescu
   This library is used in the "SIPCon1":http://sourceforge.net/projects/tipcon1/ client and is written in Java.
36 1 Adrian Georgescu
   Because it is written in Java and PJSIP is written in C, this library cannot be reused.
37 5 Adrian Georgescu
* "Asterisk":http://www.asterisk.org/ supports relaying T.140 over RTP, but is not an endpoint.
38 1 Adrian Georgescu
   Perhaps some code can be recycled from it, in particular the redundancy support (or RED).
39 1 Adrian Georgescu
40 1 Adrian Georgescu
41 5 Adrian Georgescu
h2. Relation to PyPJUA and PJSIP
42 5 Adrian Georgescu
43 5 Adrian Georgescu
44 1 Adrian Georgescu
Implementing T.140 over RTP can be subdivided into several tasks:
45 1 Adrian Georgescu
46 5 Adrian Georgescu
* RTT codec development as described in "RFC 4103":http://tools.ietf.org/html/rfc4103 to transmit and receive text over RTP (written in C)
47 5 Adrian Georgescu
* SDP negotiation for RTT session development (written in Python)
48 5 Adrian Georgescu
* Handling events generated by the RTT codec in the Graphical User Interface (not addressed by this document)
49 1 Adrian Georgescu
50 5 Adrian Georgescu
Sending and receiving of "RTP":http://www.pjsip.org/pjmedia/docs/html/group+PJMED+RTP.htm and "RTCP":http://www.pjsip.org/pjmedia/docs/html/group+PJMED+RTCP.htm packets is already implemented in PJSIP and will be reused. The actual RTT codec must be written in C similar to an audio stream implementation and pushed to PJSIP project repository. Decoding and encoding of SDP in SIP SIMPLE client is done in PyPjUA layer, so a dedicated Python object must be developed to handle it in SIP SIMPLE client.
51 1 Adrian Georgescu
52 1 Adrian Georgescu
53 5 Adrian Georgescu
h2. Audio stream implementation in PJSIP
54 1 Adrian Georgescu
55 5 Adrian Georgescu
56 5 Adrian Georgescu
!{ nolink}http://www.pjsip.org/images/diagram.jpg!
57 5 Adrian Georgescu
58 1 Adrian Georgescu
To determine how T.140 over RTP should be implemented in PJSIP, we first need to examine how the API to create and manage audio streams works in PJSIP, as RTT should be implemented in a similar fashion.
59 1 Adrian Georgescu
60 5 Adrian Georgescu
We consider the API from the point of view of PyPJUA, which in the diagram above is in the same position as "PJSUA":http://www.pjsip.org/pjsip/docs/html/group+PJSUA+LIB.htm. Currently audio is the only type of media stream supported by PJSIP. First, the local SDP is generated, either when initating a new @INVITE@ or when an incoming @INVITE@ including SDP is received.
61 5 Adrian Georgescu
This can be done by PJSIP using the "pjmedia_endpt_create_sdp()":http://www.pjsip.org/pjmedia/docs/html/group+PJMED+ENDPT.htm#ga49360a690c292dddd722b39c2f8c8bb function, which creates SDP with exactly one audio stream.
62 5 Adrian Georgescu
Once SDP negotiation has been completed, which is done in the "pjsip_inv":http://www.pjsip.org/pjsip/docs/html/group+PJSIP+INV.htm module using the "SDP negotation framework":http://www.pjsip.org/pjmedia/docs/html/group+PJMEDIA+SDP+NEG.htm, PyPJUA is handed two "pjmedia_sdp_session":http://www.pjsip.org/pjmedia/docs/html/structpjmedia+sdp+session.htm structs, which represent the local and remote SDP.
63 1 Adrian Georgescu
Using this, PyPJUA should perform the following steps:
64 5 Adrian Georgescu
* Call the "pjmedia_stream_info_from_sdp()":http://www.pjsip.org/pjmedia/docs/html/group+PJMEDIA+SESSION.htm#ge0400f365c07b6f141f202defe92f2a6 function, giving both SDP structures as parameters.
65 5 Adrian Georgescu
   This will initalize a "pjmedia_stream_info":http://www.pjsip.org/pjmedia/docs/html/structpjmedia+stream+info.htm structure.
66 5 Adrian Georgescu
* Use this "pjmedia_stream_info":http://www.pjsip.org/pjmedia/docs/html/structpjmedia+stream+info.htm structure to create an opaque @pjmedia_stream@ struct by means of the "pjmedia_stream_create()":http://www.pjsip.org/pjmedia/docs/html/group+PJMED+STRM.htm#g67575c8e7b15e325b98ebaa89639b550 function.
67 1 Adrian Georgescu
   This opaque struct actually represents an audio stream and contains within it the following:
68 5 Adrian Georgescu
*** An instance of the audio codec used.
69 5 Adrian Georgescu
*** An "adaptive jitter buffer":http://www.pjsip.org/pjmedia/docs/html/group+PJMED+JBUF.htm
70 5 Adrian Georgescu
*** Two instances of "pjmedia_rtp_session":http://www.pjsip.org/pjmedia/docs/html/structpjmedia+rtp+session.htm, representing the RTP streams in both directions.
71 5 Adrian Georgescu
*** One instance of "pjmdia_rtcp_session":http://www.pjsip.org/pjmedia/docs/html/structpjmedia+rtcp+session.htm.
72 5 Adrian Georgescu
*** A reference to the media transport that was created earlier to carry the RTP and RTCP streams.
73 5 Adrian Georgescu
     This could be a simple "UDP transport":http://www.pjsip.org/pjmedia/docs/html/group+PJMEDIA+TRANSPORT+UDP.htm or an "ICE transport":http://www.pjsip.org/pjmedia/docs/html/group+PJMEDIA+TRANSPORT+ICE.htm, possibly wrapped by a "SRTP transport":http://www.pjsip.org/pjmedia/docs/html/group+PJMEDIA+TRANSPORT+SRTP.htm.
74 5 Adrian Georgescu
* Start the stream using the "pjmedia_stream_start()":http://www.pjsip.org/pjmedia/docs/html/group+PJMED+STRM.htm#g93d59e3be009de86a3823303784d31a2 function and fetch the port to be connected to the sound cart or conference brige using the "pjmedia_stream_get_port()":http://www.pjsip.org/pjmedia/docs/html/group+PJMED+STRM.htm#ge3cb31df5aa921ef3085d5eb539af063 function.
75 1 Adrian Georgescu
76 1 Adrian Georgescu
77 5 Adrian Georgescu
h2. RTT codec development
78 5 Adrian Georgescu
79 5 Adrian Georgescu
80 5 Adrian Georgescu
An object would need to be implemented that is similar to the @pjmedia_stream@ object, but for a RTT stream, for example by the name of @pjmedia_rtt_stream@.
81 1 Adrian Georgescu
Since RTT only has one codec, the encoding and decoding can be integrated into this object.
82 1 Adrian Georgescu
First, the SDP needs to be generated in some way to include RTT, if the user requests this.
83 1 Adrian Georgescu
This will be done by PyPJUA.
84 5 Adrian Georgescu
The sequence of events to create and use a @pjemdia_rtt_stream@ after SDP negotiation is complete would look like this:
85 1 Adrian Georgescu
86 5 Adrian Georgescu
* For the audio stream, the "pjmedia_stream_info":http://www.pjsip.org/pjmedia/docs/html/structpjmedia+stream+info.htm structure will be initialized by the "pjmedia_stream_info_from_sdp()":http://www.pjsip.org/pjmedia/docs/html/group+PJMEDIA+SESSION.htm#ge0400f365c07b6f141f202defe92f2a6 function.
87 1 Adrian Georgescu
   This function may need some adjusting as currently it does only checking on audio codecs.
88 5 Adrian Georgescu
* A @pjmedia_rtt_stream@ object is created using a function like @pjmedia_rtt_stream_create@, passing as arguments the @pjmedia_stream_info@ structure and a previously created @pjmedia_transport@ object.
89 1 Adrian Georgescu
   This object will manage the following:
90 5 Adrian Georgescu
*** An instance of the T.140 encoder and decoder, which probably consists of some text buffers for RED.
91 5 Adrian Georgescu
*** Two instances of "pjmedia_rtp_session":http://www.pjsip.org/pjmedia/docs/html/structpjmedia+rtp+session.htm, representing the RTP streams in both directions.
92 5 Adrian Georgescu
*** One instance of "pjmdia_rtcp_session":http://www.pjsip.org/pjmedia/docs/html/structpjmedia+rtcp+session.htm.
93 5 Adrian Georgescu
*** A reference to the media transport that was created earlier to carry the RTP and RTCP streams.
94 5 Adrian Georgescu
* The stream should be started through some function, e.g. @pjmedia_rtt_stream_start@.
95 1 Adrian Georgescu
   This will set a timer that performs transmission every interval.
96 5 Adrian Georgescu
* The application can transmit text by appending characters to the internal transmission buffer by calling some function, like @pjmedia_rtt_stream_send@.
97 5 Adrian Georgescu
* The application could receive text either by reading from the internal reception buffer by calling a function, like @pjmedia_rtt_stream_receive@, or have a previously set callback called whenever there is new text.
98 1 Adrian Georgescu
   The former has the disadvantage that the application will have to do active polling on the object and possibly cause buffer overruns if it doesn't poll, the latter has the disadvantage that because of the short intervals the callback may be called quite frequently, which may prove to be inefficient, particularly in a Python environment.
99 1 Adrian Georgescu
100 1 Adrian Georgescu
101 5 Adrian Georgescu
h2. SDP negotiation for RTT session
102 1 Adrian Georgescu
103 5 Adrian Georgescu
104 5 Adrian Georgescu
In PyPJUA a @RTTStream@ class will be created, which represents a T.140 stream. It should have a method to send text and an event will be associated with it which will be called on the event handler whenever there is incoming text. Internally, it should also govern the SDP generation.
105 5 Adrian Georgescu
106 5 Adrian Georgescu
107 5 Adrian Georgescu
h2. Handling events generated by the RTT codec
108 5 Adrian Georgescu
109 1 Adrian Georgescu
110 1 Adrian Georgescu
The GUI must be notified every time there is a new character received from RTT codec or every time the user types in a character in the GUI for an established session.