SipMiddlewareApi

Version 62 (Luci Stanescu, 03/25/2010 11:43 pm)

1 1 Adrian Georgescu
= Middleware API =
2 1 Adrian Georgescu
3 1 Adrian Georgescu
[[TOC(WikiStart, Sip*, depth=3)]]
4 1 Adrian Georgescu
5 60 Adrian Georgescu
This chapter describes the event driven ''Middleware API'' that can be used by a developer to build a user interface for SIP SIMPLE client SDK.  
6 14 Adrian Georgescu
7 54 Adrian Georgescu
 * For sub-systems communications the Middleware uses the [http://pypi.python.org/pypi/python-application/ Notification Bus] provided by [http://pypi.python.org/pypi/python-application/ python-application]
8 49 Adrian Georgescu
 * For configuration the Middleware uses the [wiki:SipConfigurationAPI Configuration API] to access General and SIP account  settings
9 1 Adrian Georgescu
10 59 Adrian Georgescu
To see a working example for how to use Middleware, see the [http://sipsimpleclient.com/wiki/SipTesting#TestingGuide Command Line Tools] provided with the library.
11 59 Adrian Georgescu
12 53 Adrian Georgescu
[[Image(sipsimple-middleware.png, align=center, width=800)]]
13 1 Adrian Georgescu
14 62 Luci Stanescu
== High-level audio API ==
15 62 Luci Stanescu
16 62 Luci Stanescu
The high-level audio API hides the complexity of using the low-level PJMEDIA interface. This is implemented in the {{{sipsimple.audio}}} module and contains the following components:
17 62 Luci Stanescu
 * IAudioPort: an interface describing an object capable of producing and/or consuming audio data.
18 62 Luci Stanescu
 * AudioDevice: an object conforming to the IAudioPort interface which describes a physical audio device.
19 62 Luci Stanescu
 * AudioBridge: a collection of objects conforming to IAudioPort which connects all of them in a full mesh.
20 62 Luci Stanescu
 * WavePlayer: an object conforming to the IAudioPort interface which can playback the audio data from a {{{.wav}}} file.
21 62 Luci Stanescu
 * WaveRecorder: an object conforming to the IAudioPort interface which can record audio data to a {{{.wav}}} file.
22 62 Luci Stanescu
23 62 Luci Stanescu
=== IAudioPort ===
24 62 Luci Stanescu
25 62 Luci Stanescu
The IAudioPort interface describes an object capable of producing and/or consuming audio data. This can be a dynamic object, which changes its role during its lifetime and notifies such changes using a notification, which is part of the interface.
26 62 Luci Stanescu
27 62 Luci Stanescu
==== attributes ====
28 62 Luci Stanescu
29 62 Luci Stanescu
 '''mixer'''::
30 62 Luci Stanescu
  The {{{AudioMixer}}} this audio object is connected to. Only audio objects connected to the same mixer will be able to send audio data from one to another.
31 62 Luci Stanescu
 '''consumer_slot'''::
32 62 Luci Stanescu
  An integer representing the slot (see [wiki:SipCoreApiDocumentation#AudioMixer AudioMixer]) which this object uses to consume audio data, or {{{None}}} if this object is not a consumer.
33 62 Luci Stanescu
 '''producer_slot'''::
34 62 Luci Stanescu
  An integer representing the slot (see [wiki:SipCoreApiDocumentation#AudioMixer AudioMixer]) which this object uses to produce audio data, or {{{None}}} if this object is not a producer.
35 62 Luci Stanescu
36 62 Luci Stanescu
==== notifications ====
37 62 Luci Stanescu
 
38 62 Luci Stanescu
 '''AudioPortDidChangeSlots'''::
39 62 Luci Stanescu
  This notification needs to be sent by implementations of this interface when the slots it has change, so as to let the {{{AudioBridges}}} it is part of know that reconnections need to be made.
40 62 Luci Stanescu
  [[BR]]consumer_slot_changed:[[BR]]
41 62 Luci Stanescu
  A bool indicating whether the consumer slot was changed.
42 62 Luci Stanescu
  [[BR]]producer_slot_changed:[[BR]]
43 62 Luci Stanescu
  A bool indicating whether the producer slot was changed.
44 62 Luci Stanescu
  [[BR]]old_consumer_slot:[[BR]]
45 62 Luci Stanescu
  The old slot for consuming audio data. Only required if consumer_slot_changed is {{{True}}}.
46 62 Luci Stanescu
  [[BR]]new_consumer_slot:[[BR]]
47 62 Luci Stanescu
  The new slot for consuming audio data. Only required if consumer_slot_changed is {{{True}}}.
48 62 Luci Stanescu
  [[BR]]old_producer_slot:[[BR]]
49 62 Luci Stanescu
  The old slot for producing audio data. Only required if producer_slot_changed is {{{True}}}.
50 62 Luci Stanescu
  [[BR]]new_producer_slot:[[BR]]
51 62 Luci Stanescu
  The new slot for producing audio data. Only required if producer_slot_changed is {{{True}}}.
52 62 Luci Stanescu
53 62 Luci Stanescu
=== AudioDevice ===
54 62 Luci Stanescu
55 62 Luci Stanescu
The AudioDevice represents the physical audio device which is part of a {{{AudioMixer}}}, implementing the {{{IAudioPort}}} interface. As such, it can be uniquely identified by the mixer it represents.
56 62 Luci Stanescu
57 62 Luci Stanescu
==== methods ====
58 62 Luci Stanescu
59 62 Luci Stanescu
 '''!__init!__'''(''self'', '''mixer''', '''input_muted'''={{{False}}}, '''output_muted'''={{{False}}}):
60 62 Luci Stanescu
  Instantiates a new AudioDevice which represents the physical device associated with the specified {{{AudioMixer}}}.
61 62 Luci Stanescu
  [[BR]]mixer:[[BR]]
62 62 Luci Stanescu
  The {{{AudioMixer}}} whose physical device this object represents.
63 62 Luci Stanescu
  [[BR]]input_muted:[[BR]]
64 62 Luci Stanescu
  A boolean which indicates whether this object should act as a producer of audio data.
65 62 Luci Stanescu
  [[BR]]output_muted:[[BR]]
66 62 Luci Stanescu
  A boolean which indicates whether this object should act as a consumer of audio data.
67 62 Luci Stanescu
68 62 Luci Stanescu
==== attributes ====
69 62 Luci Stanescu
70 62 Luci Stanescu
 '''input_muted'''::
71 62 Luci Stanescu
  A writable property which controls whether this object should act as a producer of audio data. An {{{AudioPortDidChange}}} slots notification is sent when this attribute is changed to force connections to be reconsidered within the {{{AudioBridges}}} this object is part of.
72 62 Luci Stanescu
 '''output_muted'''::
73 62 Luci Stanescu
  A writable property which controls whether this object should act as a consumer of audio data. An {{{AudioPortDidChange}}} slots notification is sent when this attribute is changed to force connections to be reconsidered within  the {{{AudioBridges}}} this object is part of.
74 62 Luci Stanescu
75 62 Luci Stanescu
=== AudioBridge ===
76 62 Luci Stanescu
77 62 Luci Stanescu
The {{{AudioBridge}}} is the basic component which is able to connect {{{IAudioPort}}} implementations. It acts as a container which connects as the producers to all the consumers which are part of it. An object which is both a producer and a consumer of audio data will not be connected to itself. Being an implementation of {{{IAudioPort}}} itself, an {{{AudioBridge}}} can be part of another {{{AudioBridge}}}. The {{{AudioBridge}}} does not keep strong references to the ports it contains and once the port's reference count reaches 0, it is automatically removed from the {{{AudioBridge}}}.
78 62 Luci Stanescu
> Note: although this is not enforced, there should never be any cycles when connecting {{{AudioBridges}}}.
79 62 Luci Stanescu
80 62 Luci Stanescu
==== methods ====
81 62 Luci Stanescu
82 62 Luci Stanescu
 '''!__init!__'''(''self'', '''mixer''')::
83 62 Luci Stanescu
  Instantiate a new {{{AudioBridge}}} which uses the specified {{{AudioMixer}}} for mixing.
84 62 Luci Stanescu
 '''add'''(''self'', '''port''')::
85 62 Luci Stanescu
  Add an implementation of {{{IAudioPort}}} to this AudioBridge. This will connect the new port to all the existing ports of the bridge. A port cannot be added more than once to an {{{AudioBridge}}}; thus, this object acts like a set.
86 62 Luci Stanescu
 '''remove'''(''self'', '''port''')::
87 62 Luci Stanescu
  Remove a port from this {{{AudioBridge}}}. The port must have previously been added to the {{{AudioBridge}}}, otherwise a {{{ValueError}}} is raised.
88 62 Luci Stanescu
89 62 Luci Stanescu
=== WavePlayer ===
90 62 Luci Stanescu
91 62 Luci Stanescu
A {{{WavePlayer}}} is an implementation of {{{IAudioPort}}} which is capable of producing audio data read from a {{{.wav}}} file. This object is completely reusable, as it can be started and stopped any number of times.
92 62 Luci Stanescu
93 62 Luci Stanescu
==== methods ====
94 62 Luci Stanescu
95 62 Luci Stanescu
 '''!__init!__'''(''self'', '''mixer''', '''filename''', '''volume'''={{{100}}}, '''loop_count'''={{{1}}}, '''pause_time'''={{{0}}}, '''initial_play'''={{{True}}})::
96 62 Luci Stanescu
  Instantiate a new {{{WavePlayer}}} which is capable of playing a {{{.wav}}} file repeatedly. All the parameters are available as attributes of the object, but should not be changed once the object has been started.
97 62 Luci Stanescu
  [[BR]]mixer:[[BR]]
98 62 Luci Stanescu
  The {{{AudioMixer}}} this object is connected to.
99 62 Luci Stanescu
  [[BR]]filename:[[BR]]
100 62 Luci Stanescu
  The full path to the {{{.wav}}} file from which audio data is to be read.
101 62 Luci Stanescu
  [[BR]]volume:[[BR]]
102 62 Luci Stanescu
  The volume at which the file should be played.
103 62 Luci Stanescu
  [[BR]]loop_count:[[BR]]
104 62 Luci Stanescu
  The number of times the file should be played, or {{{0}}} for infinity.
105 62 Luci Stanescu
  [[BR]]pause_time:[[BR]]
106 62 Luci Stanescu
  How many seconds to wait between successive plays of the file. 
107 62 Luci Stanescu
  [[BR]]initial_play:[[BR]]
108 62 Luci Stanescu
  Whether or not the file to play once the {{{WavePlayer}}} is started, or to wait {{{pause_time}}} seconds before the first play.
109 62 Luci Stanescu
 '''start'''(''self'')::
110 62 Luci Stanescu
  Start playing the {{{.wav}}} file.
111 62 Luci Stanescu
 '''stop'''(''self'')::
112 62 Luci Stanescu
  Stop playuing the {{{.wav}}} file immediately.
113 62 Luci Stanescu
114 62 Luci Stanescu
==== attributes ====
115 62 Luci Stanescu
116 62 Luci Stanescu
 '''is_active'''::
117 62 Luci Stanescu
  A boolean indicating whether or not this {{{WavePlayer}}} is currently playing.
118 62 Luci Stanescu
119 62 Luci Stanescu
==== notifications ====
120 62 Luci Stanescu
121 62 Luci Stanescu
 '''WavePlayerDidStart'''::
122 62 Luci Stanescu
  This notification is sent when the {{{WavePlayer}}} starts playing the file the first time after the {{{start()}}} method has been called.
123 62 Luci Stanescu
  [[BR]]timestamp:[[BR]]
124 62 Luci Stanescu
  A {{{datetime.datetime}}} object indicating when the notification was sent.
125 62 Luci Stanescu
 '''WavePlayerDidEnd'''::
126 62 Luci Stanescu
  This notification is sent when the {{{WavePlayer}}} is done playing either as a result of playing the number of times it was told to, or because the {{{stop()}}} method has been called.
127 62 Luci Stanescu
  [[BR]]timestamp:[[BR]]
128 62 Luci Stanescu
  A {{{datetime.datetime}}} object indicating when the notification was sent.
129 62 Luci Stanescu
 '''WavePlayerDidFail'''::
130 62 Luci Stanescu
  This notification is sent when the {{{WavePlayer}}} is not capable of playing the {{{.wav}}} file.
131 62 Luci Stanescu
  [[BR]]timestamp:[[BR]]
132 62 Luci Stanescu
  A {{{datetime.datetime}}} object indicating when the notification was sent.
133 62 Luci Stanescu
  [[BR]]error:[[BR]]
134 62 Luci Stanescu
  The exception raised by the {{{WaveFile}}} which identifies the cause for not being able to play the {{{.wav}}} file.
135 62 Luci Stanescu
136 62 Luci Stanescu
=== WaveRecorder ===
137 62 Luci Stanescu
138 62 Luci Stanescu
A {{{WaveRecorder}}} is an implementation of {{{IAudioPort}}} is is capable of consuming audio data and writing it to a {{{.wav}}} file. Just like {{{WavePlayer}}}, this object is reusable: once stopped it can be started again, but if the filename attribute is not changed, the previously written file will be overwritten.
139 62 Luci Stanescu
140 62 Luci Stanescu
==== methods ====
141 62 Luci Stanescu
142 62 Luci Stanescu
 '''!__init!__'''(''self'', '''mixer''', '''filename''')::
143 62 Luci Stanescu
  Instantiate a new {{{WaveRecorder}}}.
144 62 Luci Stanescu
  [[BR]]mixer:[[BR]]
145 62 Luci Stanescu
  The {{{AudioMixer}}} this {{{WaveRecorder}}} is connected to.
146 62 Luci Stanescu
  [[BR]]filename:[[BR]]
147 62 Luci Stanescu
  The full path to the {{{.wav}}} file where this object should write the audio data. The file must be writable. The directories up to the file will be created if possible when the {{{start()}}} method is called.
148 62 Luci Stanescu
 '''start'''(''self'')::
149 62 Luci Stanescu
  Start consuming audio data and writing it to the {{{.wav}}} file. If this object is not part of an {{{AudioBridge}}}, not audio data will be written.
150 62 Luci Stanescu
 '''stop'''(''self'')::
151 62 Luci Stanescu
  Stop consuming audio data and close the {{{.wav}}} file.
152 62 Luci Stanescu
153 62 Luci Stanescu
==== attributes ====
154 62 Luci Stanescu
155 62 Luci Stanescu
 '''is_active'''::
156 62 Luci Stanescu
  A boolean indicating whether or not this {{{WaveRecorder}}} is currently recording audio data.
157 62 Luci Stanescu
158 1 Adrian Georgescu
== SIPApplication ==
159 1 Adrian Georgescu
160 62 Luci Stanescu
Implemented in [browser:sipsimple/application.py]
161 1 Adrian Georgescu
162 62 Luci Stanescu
Implements a high-level application responsable for starting and stopping various sub-systems required to implement a fully featured SIP User Agent application. The SIPApplication class is a Singleton and can be instantiated from any part of the code, obtaining a reference to the same object. The SIPApplication takes care of initializing the following components:
163 62 Luci Stanescu
 * the twisted thread
164 62 Luci Stanescu
 * the configuration system, via the [wiki:SipConfigurationAPI#ConfigurationManager ConfigurationManager].
165 62 Luci Stanescu
 * the core [wiki:SipCoreApiDocumentation#Engine Engine] using the settings in the configuration
166 62 Luci Stanescu
 * the [wiki:SipMiddlewareApi#AccountManager AccountManager], using the accounts in the configuration
167 62 Luci Stanescu
 * two [wiki:SipMiddlewareApi#AudioBridge AudioBridges], using the settings in the configuration
168 1 Adrian Georgescu
169 62 Luci Stanescu
The attributes in this class can be set and accessed on both this class and its subclasses, as they are implemented using descriptors which keep single value for each attribute, irrespective of the class from which that attribute is set/accessed. Usually, all attributes should be considered read-only.
170 1 Adrian Georgescu
171 62 Luci Stanescu
=== Methods  ===
172 62 Luci Stanescu
173 62 Luci Stanescu
 '''!__init!__'''(''self'')::
174 62 Luci Stanescu
  Instantiates a new SIPApplication.
175 62 Luci Stanescu
 '''start'''(''self'', '''config_backend''')::
176 62 Luci Stanescu
  Starts the {{{SIPApplication}}} which initializes all the components in the correct order. The {{{config_backend}}} is used to start the {{{ConfigurationManager}}}. If any error occurs with loading the configuration, the exception raised by the {{{ConfigurationManager}}} is propagated by this method and {{{SIPApplication}}} can be started again. After this, any fatal errors will result in the SIPApplication being stopped and unusable, which means the whole application will need to stop. This method returns as soon as the twisted thread has been started, which means the application must wait for the {{{SIPApplicationDidStart}}} notification in order to know that the application started.
177 62 Luci Stanescu
 '''stop'''(''self'')::
178 62 Luci Stanescu
  Stop all the components started by the SIPApplication. This method returns immediately, but a {{{SIPApplicationDidEnd}}} notification is sent when all the components have been stopped.
179 62 Luci Stanescu
180 1 Adrian Georgescu
=== Attributes ===
181 1 Adrian Georgescu
182 62 Luci Stanescu
 '''running'''::
183 62 Luci Stanescu
  {{{True}}} if the SIPApplication is running (it has been started and it has not been told to stop), {{{False}}} otherwise.
184 62 Luci Stanescu
 '''alert_audio_mixer'''::
185 62 Luci Stanescu
  The {{{AudioMixer}}} object created on the alert audio device as defined by the configuration (by SIPSimpleSettings.audio.alert_device).
186 62 Luci Stanescu
 '''alert_audio_bridge'''::
187 62 Luci Stanescu
  An {{{AudioBridge}}} where {{{IAudioPort}}} objects can be added to playback sound to the alert device.
188 62 Luci Stanescu
 '''alert_audio_device'''::
189 62 Luci Stanescu
  An {{{AudioDevice}}} which corresponds to the alert device as defined by the configuration. This will always be part of the alert_audio_bridge.
190 62 Luci Stanescu
 '''voice_audio_mixer'''::
191 62 Luci Stanescu
  The {{{AudioMixer}}} object created on the voice audio device as defined by the configuration (by SIPSimpleSettings.audio.input_device and SIPSimpleSettings.audio.output_device).
192 62 Luci Stanescu
 '''voice_audio_bridge'''::
193 62 Luci Stanescu
  An {{{AudioBridge}}} where {{{IAudioPort}}} objects can be added to playback sound to the output device or record sound from the input device.
194 62 Luci Stanescu
 '''voice_audio_device'''::
195 62 Luci Stanescu
  An {{{AudioDevice}}} which corresponds to the voice device as defined by the configuration. This will always be part of the voice_audio_bridge.
196 1 Adrian Georgescu
197 1 Adrian Georgescu
=== Notifications  ===
198 62 Luci Stanescu
199 62 Luci Stanescu
 '''SIPApplicationWillStart'''::
200 62 Luci Stanescu
  This notification is sent just after the configuration has been loaded and the twisted thread started, but before any other components have been initialized.
201 62 Luci Stanescu
  [[BR]]timestamp:[[BR]]
202 62 Luci Stanescu
  A {{{datetime.datetime}}} object indicating when the notification was sent.
203 62 Luci Stanescu
 '''SIPApplicationDidStart'''::
204 62 Luci Stanescu
  This notification is sent when all the components have been initialized. Note: it doesn't mean that all components have succeeded, for example, the account might not have registered by this time, but the registration process will have started.
205 62 Luci Stanescu
  [[BR]]timestamp:[[BR]]
206 62 Luci Stanescu
  A {{{datetime.datetime}}} object indicating when the notification was sent.
207 62 Luci Stanescu
 '''SIPApplicationWillEnd'''::
208 62 Luci Stanescu
  This notification is sent as soon as the {{{stop()}}} method has been called.
209 62 Luci Stanescu
  [[BR]]timestamp:[[BR]]
210 62 Luci Stanescu
  A {{{datetime.datetime}}} object indicating when the notification was sent.
211 62 Luci Stanescu
 '''SIPApplicationDidEnd'''::
212 62 Luci Stanescu
  This notification is sent when all the components have been stopped. All components have been given reasonable time to shutdown gracefully, such as the account unregistering. However, because of factors outside the control of the middleware, such as network problems, some components might not have actually shutdown gracefully; this is needed because otherwise the SIPApplication could hang indefinitely (for example because the system is no longer connected to a network and it cannot be determined when it will be again).
213 62 Luci Stanescu
  [[BR]]timestamp:[[BR]]
214 62 Luci Stanescu
  A {{{datetime.datetime}}} object indicating when the notification was sent.
215 62 Luci Stanescu
 '''SIPApplicationFailedToStartTLS'''::
216 62 Luci Stanescu
  This notification is sent when a problem arises with initializing the TLS transport. In this case, the Engine will be started without TLS support and this notification contains the error which identifies the cause for not being able to start the TLS transport.
217 62 Luci Stanescu
  [[BR]]timestamp:[[BR]]
218 62 Luci Stanescu
  A {{{datetime.datetime}}} object indicating when the notification was sent.
219 62 Luci Stanescu
  [[BR]]error:[[BR]]
220 62 Luci Stanescu
  The exception raised by the Engine which identifies the cause for not being able to start the TLS transport.
221 50 Adrian Georgescu
222 50 Adrian Georgescu
223 1 Adrian Georgescu
== Session ==
224 51 Adrian Georgescu
225 51 Adrian Georgescu
[[Image(sipsimple-session-state-machine.png, align=right, width=400)]]
226 44 Adrian Georgescu
227 44 Adrian Georgescu
Implemented in [browser:sipsimple/session.py]
228 1 Adrian Georgescu
229 1 Adrian Georgescu
A {{{sipsimple.session.Session}}} object represents a complete SIP session between the local and a remote endpoints. Both incoming and outgoing sessions are represented by this class.
230 1 Adrian Georgescu
231 26 Luci Stanescu
A {{{Session}}} instance is a stateful object, meaning that it has a {{{state}}} attribute and that the lifetime of the session traverses different states, from session creation to termination.
232 1 Adrian Georgescu
State changes are triggered by methods called on the object by the application or by received network events.
233 1 Adrian Georgescu
Every time this attribute changes, a {{{SIPSessionChangedState}}} notification is sent by the object.
234 2 Adrian Georgescu
These states and their transitions are represented in the following diagram:
235 1 Adrian Georgescu
236 1 Adrian Georgescu
Although these states are crucial to the correct operation of the {{{Session}}} object, an application using this object does not need to keep track of these states, as a different set of notifications is also emitted, which provide all the necessary information to the application.
237 50 Adrian Georgescu
238 1 Adrian Georgescu
=== Attributes ===
239 1 Adrian Georgescu
240 1 Adrian Georgescu
 '''state'''::
241 18 Ruud Klaver
  The state the object is currently in, being one of the states from the diagram above.
242 18 Ruud Klaver
 '''account'''::
243 18 Ruud Klaver
  The {{{sipsimple.account.Account}}} or {{{sipsimple.account.BonjourAccount}}} object that the {{{Session}}} is associated with.
244 1 Adrian Georgescu
  On an outbound session, this is the account the application specified on object instantiation.
245 1 Adrian Georgescu
 '''direction'''::
246 1 Adrian Georgescu
  A string indicating the direction of the initial negotiation of the session.
247 1 Adrian Georgescu
  This can be either {{{None}}}, "incoming" or "outgoing".
248 1 Adrian Georgescu
 '''start_time'''::
249 1 Adrian Georgescu
  The time the session started as a {{{datetime.datetime}}} object, or {{{None}}} if the session was not yet started.
250 1 Adrian Georgescu
 '''stop_time'''::
251 1 Adrian Georgescu
  The time the session stopped as a {{{datetime.datetime}}} object, or {{{None}}} if the session has not yet terminated.
252 1 Adrian Georgescu
 '''on_hold_by_local'''::
253 1 Adrian Georgescu
  Boolean indicating whether the session was put on hold by the local party.
254 1 Adrian Georgescu
 '''on_hold_by_remote'''::
255 1 Adrian Georgescu
  Boolean indicating whether the session was put on hold by the remote party.
256 1 Adrian Georgescu
 '''on_hold'''::
257 1 Adrian Georgescu
  Boolean indicating whether the session was put on hold, either by the local or the remote party.
258 1 Adrian Georgescu
 '''remote_user_agent'''::
259 1 Adrian Georgescu
  A string indicating the remote user agent, if it provided one.
260 1 Adrian Georgescu
  Initially this will be {{{None}}}, it will be set as soon as this information is received from the remote party (which may be never).
261 1 Adrian Georgescu
 '''local_uri'''::
262 1 Adrian Georgescu
  The {{{sipsimple.core.SIPURI}}} of the local party, if the session is active.
263 1 Adrian Georgescu
 '''remote_uri'''::
264 1 Adrian Georgescu
  The {{{sipsimple.core.SIPURI}}} of the remote party, if the session is active.
265 1 Adrian Georgescu
 '''caller_uri'''::
266 1 Adrian Georgescu
  The {{{sipsimple.core.SIPURI}}} of the calling party, if the session is active.
267 1 Adrian Georgescu
  Depending on the direction, this is either {{{local_uri}}} or {{{remote_uri}}}.
268 1 Adrian Georgescu
 '''callee_uri'''::
269 1 Adrian Georgescu
  The {{{sipsimple.core.SIPURI}}} of the called party, if the session is active.
270 1 Adrian Georgescu
  Depending on the direction, this is either {{{local_uri}}} or {{{remote_uri}}}.
271 20 Ruud Klaver
 '''route'''::
272 1 Adrian Georgescu
  A copy of the {{{sipsimple.core.Route}}} object passed when the {{{connect()}}} method was called.
273 1 Adrian Georgescu
  On incoming or inactive sessions this is {{{None}}}.
274 1 Adrian Georgescu
 '''audio_transport'''::
275 1 Adrian Georgescu
  The {{{sipsimple.core.AudioTransport}}} object used by the session, if it currently contains an audio stream.
276 1 Adrian Georgescu
  Normally the application will not need to access this directly.
277 23 Ruud Klaver
 '''has_audio'''::
278 1 Adrian Georgescu
  A boolean indicating if this {{{Session}}} currently has an active audio stream.
279 1 Adrian Georgescu
 '''audio_sample_rate'''::
280 1 Adrian Georgescu
  If the audio stream was started, this attribute contains the sample rate of the audio negotiated.
281 1 Adrian Georgescu
 '''audio_codec'''::
282 1 Adrian Georgescu
  If the audio stream was started, this attribute contains the name of the audio codec that was negotiated.
283 1 Adrian Georgescu
 '''audio_srtp_active'''::
284 1 Adrian Georgescu
  If the audio stream was started, this boolean attribute indicates if SRTP is currently being used on the stream.
285 1 Adrian Georgescu
 '''audio_local_rtp_address'''::
286 1 Adrian Georgescu
  If an audio stream is present within the session, this attribute contains the local IP address used for the audio stream.
287 1 Adrian Georgescu
 '''audio_local_rtp_port'''::
288 1 Adrian Georgescu
  If an audio stream is present within the session, this attribute contains the local UDP port used for the audio stream.
289 1 Adrian Georgescu
 '''audio_remote_rtp_address_sdp'''::
290 1 Adrian Georgescu
  If the audio stream was started, this attribute contains the IP address that the remote party gave to send audio to.
291 1 Adrian Georgescu
 '''audio_remote_rtp_port_sdp'''::
292 1 Adrian Georgescu
  If the audio stream was started, this attribute contains the UDP port that the remote party gave to send audio to.
293 1 Adrian Georgescu
 '''audio_remote_rtp_address_received'''::
294 1 Adrian Georgescu
  If the audio stream was started, this attribute contains the remote IP address from which the audio stream is being received.
295 1 Adrian Georgescu
 '''audio_remote_rtp_port_received'''::
296 1 Adrian Georgescu
  If the audio stream was started, this attribute contains the remote UDP port from which the audio stream is being received.
297 1 Adrian Georgescu
 '''audio_was_received'''::
298 1 Adrian Georgescu
  This boolean property indicates if audio was actually received on the audio stream contained within this session.
299 1 Adrian Georgescu
 '''audio_recording_file_name'''::
300 1 Adrian Georgescu
  If the audio stream is currently being recorded to disk, this property contains the name of the {{{.wav}}} file being recorded to.
301 1 Adrian Georgescu
 '''chat_transport'''::
302 1 Adrian Georgescu
  The {{{sipsimple.msrp.MSRPChat}}} object used by the session as chat transport, if the session currently contains a chat stream.
303 1 Adrian Georgescu
  Normally the application will not need to access this directly.
304 23 Ruud Klaver
 '''has_chat'''::
305 1 Adrian Georgescu
  A boolean property indicating if this {{{Session}}} currently has an active chat stream.
306 50 Adrian Georgescu
307 1 Adrian Georgescu
=== Methods ===
308 18 Ruud Klaver
309 1 Adrian Georgescu
 '''!__init!__'''(''self'', '''account''')::
310 19 Ruud Klaver
  Creates a new {{{Session}}} object in the {{{NULL}}} state.
311 19 Ruud Klaver
  [[BR]]''account'':[[BR]]
312 19 Ruud Klaver
  The local account to be associated with this {{{Session}}}.
313 1 Adrian Georgescu
 '''connect'''(''self'', '''callee_uri''', '''routes''', '''audio'''={{{False}}}, '''chat'''={{{False}}})::
314 26 Luci Stanescu
  Will set up the {{{Session}}} as outbound and propose the new session to the specified remote party and move the state machine to the {{{CALLING}}} state.
315 26 Luci Stanescu
  Before contacting the remote party, a {{{SIPSessionNewOutgoing}}} notification will be emitted.
316 26 Luci Stanescu
  If there is a failure or the remote party rejected the offer, a {{{SIPSessionDidFail}}} notification will be sent, followed by a {{{SIPSessionDidEnd}}}.
317 26 Luci Stanescu
  Any time a ringing indication is received from the remote party, a {{{SIPSessionGotRingIndication}}} notification is sent.
318 1 Adrian Georgescu
  If the remote party accepted the session, a {{{SIPSessionWillStart}}} notification will be sent, followed by a {{{SIPSessionDidStart}}} notification when the session is actually established.
319 1 Adrian Georgescu
  This method may only be called while in the {{{NULL}}} state.
320 1 Adrian Georgescu
  [[BR]]''callee_uri'':[[BR]]
321 19 Ruud Klaver
  A {{{sipsimple.core.SIPURI}}} object representing the remote host to initiate the session to.
322 19 Ruud Klaver
  [[BR]]''routes'':[[BR]]
323 19 Ruud Klaver
  An iterable of {{{sipsimple.core.Route}}} objects, specifying the IP, port and transport to the outbound proxy.
324 1 Adrian Georgescu
  These routes will be tried in order, until one of them succeeds.
325 1 Adrian Georgescu
  [[BR]]''audio'':[[BR]]
326 1 Adrian Georgescu
  A boolean indicating whether an audio stream should be initially included in this session.
327 1 Adrian Georgescu
  [[BR]]''chat'':[[BR]]
328 19 Ruud Klaver
  A boolean indicating whether a chat stream should be initially included in this session.
329 1 Adrian Georgescu
 '''accept'''(''self'', '''audio'''={{{False}}}, '''chat'''={{{False}}})::
330 26 Luci Stanescu
  Calling this methods will accept an incoming session and move the state machine to the {{{ACCEPTING}}} state.
331 26 Luci Stanescu
  When there is a new incoming session, a {{{SIPSessionNewIncoming}}} notification is sent, after which the application can call this method on the sender of the notification.
332 1 Adrian Georgescu
  After this method is called, {{{SIPSessionWillStart}}} followed by {{{SIPSessionDidStart}}} will be emitted, or {{{SIPSessionDidFail}}} followed by {{{SIPSessionDidEnd}}} on an error.
333 1 Adrian Georgescu
  This method may only be called while in the {{{INCOMING}}} state.
334 1 Adrian Georgescu
  [[BR]]''audio'':[[BR]]
335 1 Adrian Georgescu
  A boolean indicating whether an audio stream should be accepted for this session.
336 1 Adrian Georgescu
  Note that this may only be set to {{{True}}} if an audio stream was actually proposed by the remote party.
337 1 Adrian Georgescu
  [[BR]]''chat'':[[BR]]
338 1 Adrian Georgescu
  A boolean indicating whether a chat stream should be accepted for this session.
339 41 Ruud Klaver
  Note that this may only be set to {{{True}}} if a chat stream was actually proposed by the remote party.
340 1 Adrian Georgescu
 '''reject'''(''self'', '''is_busy'''={{{False}}})::
341 26 Luci Stanescu
  Reject an incoming session and move it to the {{{TERMINATING}}} state, which eventually leads to the {{{TERMINATED}}} state.
342 1 Adrian Georgescu
  Calling this method will cause the {{{Session}}} object to emit a {{{SIPSessionWillEnd}}} notification, followed by a {{{SIPSessionDidEnd}}} notification.
343 41 Ruud Klaver
  This method may only be called while in the {{{INCOMING}}} state.
344 41 Ruud Klaver
  [[BR]]''chat'':[[BR]]
345 1 Adrian Georgescu
  A boolean indicating whether the response code sent to the remote party should be 486 (Busy) instead of 603 (Decline).
346 1 Adrian Georgescu
 '''hold'''(''self'')::
347 26 Luci Stanescu
  Put the session on hold.
348 1 Adrian Georgescu
  This will cause a {{{SIPGotHoldRequest}}} notification to be sent.
349 1 Adrian Georgescu
  This method may only be called while in the {{{ESTABLISHED}}} state.
350 1 Adrian Georgescu
 '''unhold'''(''self'')::
351 26 Luci Stanescu
  Take the session out of hold.
352 1 Adrian Georgescu
  This will cause a {{{SIPGotUnholdRequest}}} notification to be sent.
353 19 Ruud Klaver
  This method may only be called while in the {{{ESTABLISHED}}} state.
354 1 Adrian Georgescu
 '''start_recording_audio'''(''self'', '''file_name'''={{{None}}})::
355 1 Adrian Georgescu
  If an audio stream is present within this session, calling this method will record the audio to a {{{.wav}}} file.
356 26 Luci Stanescu
  Note that when the session is on hold, nothing will be recorded to the file.
357 1 Adrian Georgescu
  Right before starting the recording a {{{SIPSessionWillStartRecordingAudio}}} notification will be emitted, followed by a {{{SIPSessionDidStartRecordingAudio}}}.
358 1 Adrian Georgescu
  This method may only be called while in the {{{ESTABLISHED}}} state.
359 1 Adrian Georgescu
  [[BR]]''file_name'':[[BR]]
360 1 Adrian Georgescu
  The name of the {{{.wav}}} file to record to.
361 1 Adrian Georgescu
  If this is set to {{{None}}}, a default file name including the session participants and the timestamp will be generated.
362 1 Adrian Georgescu
 '''stop_recording_audio'''(''self'')::
363 26 Luci Stanescu
  This will stop a previously started recording.
364 1 Adrian Georgescu
  Before stopping, a {{{SIPSessionWillStopRecordingAudio}}} notification will be sent, followed by a {{{SIPSessionDidStopRecordingAudio}}}.
365 1 Adrian Georgescu
  This method may only be called while in the {{{ESTABLISHED}}} state.
366 1 Adrian Georgescu
 '''send_dtmf'''(''self'', '''digit''')::
367 23 Ruud Klaver
  If this session currently has an active audio stream, send a DTMF digit to the remote party over it.
368 1 Adrian Georgescu
  This method may only be called while in the {{{ESTABLISHED}}} state and if the session has an active audio stream.
369 1 Adrian Georgescu
  [[BR]]''digit'':[[BR]]
370 13 Luci Stanescu
  This should a string of length 1, containing a valid DTMF digit value.
371 1 Adrian Georgescu
 '''send_message'''(''self'', '''content''', '''content_type'''="text/plain", '''to_uri'''={{{None}}}, '''dt'''={{{None}}})::
372 26 Luci Stanescu
  If this session currently has an active MSRP chat with the remote party, send a message over with the with the specified parameters.
373 1 Adrian Georgescu
  This will result in either a {{{SIPSessionDidDeliverMessage}}} or a {{{SIPSessionDidNotDeliverMessage}}} notification being sent.
374 1 Adrian Georgescu
  These notifications include a unique ID as data attribute which is also returned by this method.
375 1 Adrian Georgescu
  This method may only be called while in the {{{ESTABLISHED}}} state.
376 1 Adrian Georgescu
  [[BR]]''content'':[[BR]]
377 1 Adrian Georgescu
  The body of the MSRP message as a string.
378 1 Adrian Georgescu
  [[BR]]''content_type'':[[BR]]
379 22 Ruud Klaver
  The Content-Type of the body as a string
380 1 Adrian Georgescu
  [[BR]]''to_uri'':[[BR]]
381 1 Adrian Georgescu
  The {{{sipsimple.core.SIPURI}}} that should be put in the {{{To:}}} header of the CPIM wrapper of the message.
382 1 Adrian Georgescu
  This defaults to the SIP URI of the remote party of the session if the argument is set to {{{None}}}
383 1 Adrian Georgescu
  [[BR]]''dt'':[[BR]]
384 1 Adrian Georgescu
  A {{{datetime.datetime}}} object representing the timestamp to put on the CPIM wrapper of the message.
385 1 Adrian Georgescu
  When set to {{{None}}}, this defaults to now.
386 1 Adrian Georgescu
 '''add_audio'''(''self'')::
387 26 Luci Stanescu
  Propose the remote party to add an audio stream to this session.
388 26 Luci Stanescu
  Calling this method will cause a {{{SIPSessionGotStreamProposal}}} notification to be emitted.
389 1 Adrian Georgescu
  After this, the state machine will move into the {{{PROPOSING}}} state until either a {{{SIPSessionAcceptedStreamProposal}}} or {{{SIPSessionRejectedStreamProposal}}} notification is sent, informing the application if the remote party accepted the proposal.
390 1 Adrian Georgescu
  This method may only be called while in the {{{ESTABLISHED}}} state on a {{{Session}}} object that does not currently have an audio stream.
391 1 Adrian Georgescu
 '''remove_audio'''(''self'')::
392 1 Adrian Georgescu
  Stop the audio stream currently active within the session and inform the remote party of this.
393 1 Adrian Georgescu
  This method may only be called while in the {{{ESTABLISHED}}} state on a {{{Session}}} object that has an audio stream.
394 1 Adrian Georgescu
 '''add_chat'''(''self'')::
395 26 Luci Stanescu
  Propose the remote party to add a chat stream to this session.
396 26 Luci Stanescu
  Calling this method will cause a {{{SIPSessionGotStreamProposal}}} notification to be emitted.
397 1 Adrian Georgescu
  After this, the state machine will move into the {{{PROPOSING}}} state until either a {{{SIPSessionAcceptedStreamProposal}}} or {{{SIPSessionRejectedStreamProposal}}} notification is sent, informing the application if the remote party accepted the proposal.
398 1 Adrian Georgescu
  This method may only be called while in the {{{ESTABLISHED}}} state on a {{{Session}}} object that does not currently have a chat stream.
399 1 Adrian Georgescu
 '''remove_chat'''(''self'')::
400 1 Adrian Georgescu
  Stop the chat stream currently active within the session and inform the remote party of this.
401 19 Ruud Klaver
  This method may only be called while in the {{{ESTABLISHED}}} state on a {{{Session}}} object that has a chat stream.
402 26 Luci Stanescu
 '''accept_proposal'''(''self'', '''audio'''={{{False}}}, '''chat'''={{{False}}})::
403 1 Adrian Georgescu
  When the remote party proposes to add a new stream, signaled by the {{{SIPSessionGotStreamProposal}}} notification, the application can use this method to accept the stream(s) being proposed.
404 19 Ruud Klaver
  After calling this method a {{{SIPSessionAcceptedStreamProposal}}} notification is sent, unless an error occurs while setting up the new stream, in which case a {{{SIPSessionRejectedStreamProposal}}} notification is sent and a rejection is sent to the remote party.
405 19 Ruud Klaver
  This method may only be called while in the {{{PROPOSED}}} state.
406 19 Ruud Klaver
  [[BR]]''audio'':[[BR]]
407 19 Ruud Klaver
  A boolean indicating whether an audio stream should be accepted for this proposal.
408 19 Ruud Klaver
  Note that this may only be set to {{{True}}} if an audio stream was actually proposed by the remote party.
409 19 Ruud Klaver
  [[BR]]''chat'':[[BR]]
410 26 Luci Stanescu
  A boolean indicating whether a chat stream should be accepted for this proposal.
411 1 Adrian Georgescu
  Note that this may only be set to {{{True}}} if a chat stream was actually proposed by the remote party.
412 1 Adrian Georgescu
 '''reject_proposal'''(''self'')::
413 41 Ruud Klaver
  When the remote party proposes (a) stream(s) that the application does not want to accept, this method can be used to reject the proposal, after which a {{{SIPSessionRejectedStreamProposal}}} notification is sent.
414 1 Adrian Georgescu
  This method may only be called while in the {{{PROPOSED}}} state.
415 1 Adrian Georgescu
 '''end'''(''self'' '''is_busy'''={{{False}}})::
416 1 Adrian Georgescu
  This method may be called any time when the {{{Session}}} object is active (i.e. not in the {{{NULL}}}, {{{TERMINATING}}} or {{{TERMINATED}}} states) in order to terminate the session.
417 41 Ruud Klaver
  Right before termination a {{{SIPSessionWillEnd}}} notification is sent, after termination {{{SIPSessionDidEnd}}} is sent.
418 41 Ruud Klaver
  [[BR]]''chat'':[[BR]]
419 1 Adrian Georgescu
  A boolean indicating whether the response code sent to the remote party should be 486 (Busy) instead of 603 (Decline).
420 50 Adrian Georgescu
421 1 Adrian Georgescu
=== Notifications ===
422 26 Luci Stanescu
423 1 Adrian Georgescu
 '''SIPSessionChangedState'''::
424 1 Adrian Georgescu
  Will be sent whenever the {{{Session}}} object changes its state.
425 1 Adrian Georgescu
  [[BR]]''timestamp'':[[BR]]
426 1 Adrian Georgescu
  A {{{datetime.datetime}}} object indicating when the notification was sent.
427 1 Adrian Georgescu
  [[BR]]''prev_state'':[[BR]]
428 1 Adrian Georgescu
  The previous state state the object was in.
429 1 Adrian Georgescu
  [[BR]]''state'':[[BR]]
430 26 Luci Stanescu
  The new state the object is in.
431 1 Adrian Georgescu
 '''SIPSessionNewIncoming'''::
432 1 Adrian Georgescu
  Will be sent when a new incoming {{{Session}}} is received.
433 1 Adrian Georgescu
  The application should listen for this notification from all objects specifically to get informed of incoming sessions.
434 1 Adrian Georgescu
  [[BR]]''timestamp'':[[BR]]
435 19 Ruud Klaver
  A {{{datetime.datetime}}} object indicating when the notification was sent.
436 19 Ruud Klaver
  [[BR]]''streams'':[[BR]]
437 26 Luci Stanescu
  A list of strings indicating the streams that were proposed by the remote party.
438 1 Adrian Georgescu
 '''SIPSessionNewOutgoing'''::
439 1 Adrian Georgescu
  Will be sent when the applcation requests a new outgoing {{{Session}}}.
440 1 Adrian Georgescu
  [[BR]]''timestamp'':[[BR]]
441 19 Ruud Klaver
  A {{{datetime.datetime}}} object indicating when the notification was sent.
442 32 Adrian Georgescu
  [[BR]]''streams'':[[BR]]
443 26 Luci Stanescu
  A list of strings indicating the streams that were proposed to the remote party.
444 1 Adrian Georgescu
 '''SIPSessionGotRingIndication'''::
445 1 Adrian Georgescu
  Will be sent when an outgoing {{{Session}}} receives an indication that a remote device is ringing.
446 1 Adrian Georgescu
  [[BR]]''timestamp'':[[BR]]
447 26 Luci Stanescu
  A {{{datetime.datetime}}} object indicating when the notification was sent.
448 1 Adrian Georgescu
 '''SIPSessionWillStart'''::
449 1 Adrian Georgescu
  Will be sent just before a {{{Session}}} completes negotiation.
450 1 Adrian Georgescu
  In terms of SIP, this is sent after the final response to the {{{INVITE}}}, but before the {{{ACK}}}.
451 1 Adrian Georgescu
  [[BR]]''timestamp'':[[BR]]
452 26 Luci Stanescu
  A {{{datetime.datetime}}} object indicating when the notification was sent.
453 1 Adrian Georgescu
 '''SIPSessionDidStart'''::
454 1 Adrian Georgescu
  Will be sent when a {{{Session}}} completes negotiation.
455 1 Adrian Georgescu
  In terms of SIP this is sent after the {{{ACK}}} was sent or received.
456 1 Adrian Georgescu
  [[BR]]''timestamp'':[[BR]]
457 26 Luci Stanescu
  A {{{datetime.datetime}}} object indicating when the notification was sent.
458 1 Adrian Georgescu
 '''SIPSessionDidFail'''::
459 1 Adrian Georgescu
  This notification is sent whenever the session fails.
460 26 Luci Stanescu
  The failure reason is included in the data attributes.
461 1 Adrian Georgescu
  This notification is always followed by {{{SIPSessionDidEnd}}}.
462 1 Adrian Georgescu
  [[BR]]''timestamp'':[[BR]]
463 1 Adrian Georgescu
  A {{{datetime.datetime}}} object indicating when the notification was sent.
464 1 Adrian Georgescu
  [[BR]]''originator'':[[BR]]
465 1 Adrian Georgescu
  A string indicating the origin of the failure.
466 1 Adrian Georgescu
  This will either be "local" or "remote".
467 1 Adrian Georgescu
  [[BR]]''code'':[[BR]]
468 1 Adrian Georgescu
  The SIP error code of the failure.
469 1 Adrian Georgescu
  If this is 0, the error was an internal exception.
470 1 Adrian Georgescu
  [[BR]]''reason'':[[BR]]
471 26 Luci Stanescu
  A string explaining the reason of the failure.
472 1 Adrian Georgescu
 '''SIPSessionWillEnd'''::
473 1 Adrian Georgescu
  Will be sent just before terminating a {{{Session}}} at the request of the application.
474 1 Adrian Georgescu
  [[BR]]''timestamp'':[[BR]]
475 26 Luci Stanescu
  A {{{datetime.datetime}}} object indicating when the notification was sent.
476 26 Luci Stanescu
 '''SIPSessionDidEnd'''::
477 1 Adrian Georgescu
  Will be sent always when a {{{Session}}} ends, either because of a failure (in which case it is preceded by {{{SIPSessionDidFail}}}), remote or local session termination.
478 1 Adrian Georgescu
  [[BR]]''timestamp'':[[BR]]
479 1 Adrian Georgescu
  A {{{datetime.datetime}}} object indicating when the notification was sent.
480 1 Adrian Georgescu
  [[BR]]''originator'':[[BR]]
481 1 Adrian Georgescu
  A string indicating who originated the termination.
482 26 Luci Stanescu
  This will either be "local" or "remote".
483 1 Adrian Georgescu
 '''SIPSessionGotHoldRequest'''::
484 1 Adrian Georgescu
  Will be sent when the session got put on hold, either by the local or the remote party.
485 1 Adrian Georgescu
  [[BR]]''timestamp'':[[BR]]
486 1 Adrian Georgescu
  A {{{datetime.datetime}}} object indicating when the notification was sent.
487 1 Adrian Georgescu
  [[BR]]''originator'':[[BR]]
488 26 Luci Stanescu
  A string indicating who originated the hold request, and consequently in which direction the session got put on hold.
489 1 Adrian Georgescu
 '''SIPSessionGotUnholdRequest'''::
490 1 Adrian Georgescu
  Will be sent when the session got taken out of hold, either by the local or the remote party.
491 1 Adrian Georgescu
  [[BR]]''timestamp'':[[BR]]
492 1 Adrian Georgescu
  A {{{datetime.datetime}}} object indicating when the notification was sent.
493 1 Adrian Georgescu
  [[BR]]''originator'':[[BR]]
494 26 Luci Stanescu
  A string indicating who sent the original hold request, and consequently in which direction the session got taken out of hold.
495 1 Adrian Georgescu
 '''SIPSessionWillStartRecordingAudio'''::
496 1 Adrian Georgescu
  Will be sent when the application requested that the audio stream active within the session be record to a {{{.wav}}} file, just before recording starts.
497 1 Adrian Georgescu
  [[BR]]''timestamp'':[[BR]]
498 1 Adrian Georgescu
  A {{{datetime.datetime}}} object indicating when the notification was sent.
499 1 Adrian Georgescu
  [[BR]]''file_name'':[[BR]]
500 26 Luci Stanescu
  The name of the recording {{{.wav}}} file, including full path.
501 1 Adrian Georgescu
 '''SIPSessionDidStartRecordingAudio'''::
502 1 Adrian Georgescu
  Will be sent when the application requested that the audio stream active within the session be record to a {{{.wav}}} file, just after recording starts.
503 1 Adrian Georgescu
  [[BR]]''timestamp'':[[BR]]
504 1 Adrian Georgescu
  A {{{datetime.datetime}}} object indicating when the notification was sent.
505 1 Adrian Georgescu
  [[BR]]''file_name'':[[BR]]
506 26 Luci Stanescu
  The name of the recording {{{.wav}}} file, including full path.
507 1 Adrian Georgescu
 '''SIPSessionWillStopRecordingAudio'''::
508 1 Adrian Georgescu
  Will be sent when the application requested ending the recording to a {{{.wav}}} file, just before recording stops.
509 1 Adrian Georgescu
  [[BR]]''timestamp'':[[BR]]
510 1 Adrian Georgescu
  A {{{datetime.datetime}}} object indicating when the notification was sent.
511 1 Adrian Georgescu
  [[BR]]''file_name'':[[BR]]
512 26 Luci Stanescu
  The name of the recording {{{.wav}}} file, including full path.
513 1 Adrian Georgescu
 '''SIPSessionDidStopRecordingAudio'''::
514 1 Adrian Georgescu
  Will be sent when the application requested ending the recording to a {{{.wav}}} file, just before recording stops.
515 1 Adrian Georgescu
  [[BR]]''timestamp'':[[BR]]
516 1 Adrian Georgescu
  A {{{datetime.datetime}}} object indicating when the notification was sent.
517 1 Adrian Georgescu
  [[BR]]''file_name'':[[BR]]
518 26 Luci Stanescu
  The name of the recording {{{.wav}}} file, including full path.
519 1 Adrian Georgescu
 '''SIPSessionGotNoAudio'''::
520 1 Adrian Georgescu
  This notification will be sent if 5 seconds after the audio stream starts, no audio was received from the remote party.
521 1 Adrian Georgescu
  [[BR]]''timestamp'':[[BR]]
522 26 Luci Stanescu
  A {{{datetime.datetime}}} object indicating when the notification was sent.
523 1 Adrian Georgescu
 '''SIPSessionGotDTMF'''::
524 1 Adrian Georgescu
  Will be send if there is a DMTF digit received from the remote party on the audio stream. 
525 1 Adrian Georgescu
  [[BR]]''timestamp'':[[BR]]
526 1 Adrian Georgescu
  A {{{datetime.datetime}}} object indicating when the notification was sent.
527 1 Adrian Georgescu
  [[BR]]''digit'':[[BR]]
528 26 Luci Stanescu
  The DTMF digit that was received, in the form of a string of length 1.
529 1 Adrian Georgescu
 '''SIPSessionGotMessage'''::
530 1 Adrian Georgescu
  Will be sent whenever a MSRP message is received on the chat stream of the session.
531 1 Adrian Georgescu
  [[BR]]''content'':[[BR]]
532 1 Adrian Georgescu
  The body of the message.
533 1 Adrian Georgescu
  [[BR]]''content_type'':[[BR]]
534 1 Adrian Georgescu
  The Content-Type of the body.
535 1 Adrian Georgescu
  [[BR]]''cpim_headers'':[[BR]]
536 1 Adrian Georgescu
  A dictionary of headers included in the CPIM wrapper.
537 5 Redmine Admin
  [[BR]]''message'':[[BR]]
538 26 Luci Stanescu
  Raw MSRP message, an msrplib.protocol.MSRPData instance
539 1 Adrian Georgescu
 '''SIPSessionDidDeliverMessage'''::
540 1 Adrian Georgescu
  Will be sent when a previously sent MSRP chat message got delivered to the remote party.
541 1 Adrian Georgescu
  [[BR]]''message_id'':[[BR]]
542 1 Adrian Georgescu
  The unique identifier of this message as a string, as previously returned by the {{{send_message()}}} method.
543 1 Adrian Georgescu
  [[BR]]''code'':[[BR]]
544 1 Adrian Georgescu
  The response code of the confirmation report.
545 5 Redmine Admin
  [[BR]]''reason'':[[BR]]
546 1 Adrian Georgescu
  The reason string of the confirmation report.
547 1 Adrian Georgescu
  [[BR]]''message'':[[BR]]
548 26 Luci Stanescu
  Raw MSRP message, an msrplib.protocol.MSRPData instance
549 1 Adrian Georgescu
 '''SIPSessionDidDeliverMessage'''::
550 1 Adrian Georgescu
  Will be sent when a previously sent MSRP chat message did not get delivered to the remote party.
551 1 Adrian Georgescu
  [[BR]]''message_id'':[[BR]]
552 1 Adrian Georgescu
  The unique identifier of this message as a string, as previously returned by the {{{send_message()}}} method.
553 1 Adrian Georgescu
  [[BR]]''code'':[[BR]]
554 1 Adrian Georgescu
  The response code of the confirmation report.
555 5 Redmine Admin
  [[BR]]''reason'':[[BR]]
556 1 Adrian Georgescu
  The reason string of the confirmation report.
557 1 Adrian Georgescu
  [[BR]]''message'':[[BR]]
558 26 Luci Stanescu
  Raw MSRP message, an msrplib.protocol.MSRPData instance
559 1 Adrian Georgescu
 '''SIPSessionGotStreamProposal'''::
560 1 Adrian Georgescu
  Will be sent when either the local or the remote party proposes to add a stream to the session.
561 1 Adrian Georgescu
  [[BR]]''timestamp'':[[BR]]
562 1 Adrian Georgescu
  A {{{datetime.datetime}}} object indicating when the notification was sent.
563 1 Adrian Georgescu
  [[BR]]''proposer'':[[BR]]
564 19 Ruud Klaver
  The party that did the stream proposal, can be either "local" or "remote".
565 19 Ruud Klaver
  [[BR]]''streams'':[[BR]]
566 26 Luci Stanescu
  A list of strings indicating the streams that were proposed.
567 1 Adrian Georgescu
 '''SIPSessionRejectedStreamProposal'''::
568 1 Adrian Georgescu
  Will be sent when either the local or the remote party rejects a proposal to have (a) stream(s) added to the session.
569 1 Adrian Georgescu
  [[BR]]''timestamp'':[[BR]]
570 1 Adrian Georgescu
  A {{{datetime.datetime}}} object indicating when the notification was sent.
571 1 Adrian Georgescu
  [[BR]]''proposer'':[[BR]]
572 1 Adrian Georgescu
  The party that did the stream proposal, can be either "local" or "remote".
573 1 Adrian Georgescu
  [[BR]]''reason'':[[BR]]
574 1 Adrian Georgescu
  The reason for rejecting the stream proposal.
575 26 Luci Stanescu
 '''SIPSessionRejectedStreamProposal'''::
576 1 Adrian Georgescu
  Will be sent when either the local or the remote party accepts a proposal to have (a) stream(s) added to the session.
577 1 Adrian Georgescu
  [[BR]]''timestamp'':[[BR]]
578 1 Adrian Georgescu
  A {{{datetime.datetime}}} object indicating when the notification was sent.
579 1 Adrian Georgescu
  [[BR]]''proposer'':[[BR]]
580 1 Adrian Georgescu
  The party that did the stream proposal, can be either "local" or "remote".
581 26 Luci Stanescu
 '''SIPSessionGotStreamUpdate'''::
582 23 Ruud Klaver
  Will be sent when a media stream is either activated or deactivated.
583 23 Ruud Klaver
  An application should listen to this notification in order to know when a media stream can be used.
584 23 Ruud Klaver
  [[BR]]''timestamp'':[[BR]]
585 23 Ruud Klaver
  A {{{datetime.datetime}}} object indicating when the notification was sent.
586 23 Ruud Klaver
  [[BR]]''streams'':[[BR]]
587 23 Ruud Klaver
  A list indicating which streams are active on the session from this point onwards.
588 30 Adrian Georgescu
589 6 Ruud Klaver
As an example for how to use the {{{Session}}} object, the following provides a basic Python program that initiates an outgoing SIP session request:
590 6 Ruud Klaver
591 24 Ruud Klaver
{{{
592 6 Ruud Klaver
import sys
593 6 Ruud Klaver
from threading import Event
594 6 Ruud Klaver
from zope.interface import implements
595 1 Adrian Georgescu
from application.notification import IObserver, NotificationCenter
596 24 Ruud Klaver
597 24 Ruud Klaver
from sipsimple.configuration import ConfigurationManager
598 24 Ruud Klaver
from sipsimple.account import AccountManager
599 24 Ruud Klaver
from sipsimple.engine import Engine
600 24 Ruud Klaver
from sipsimple.session import Session
601 24 Ruud Klaver
from sipsimple.core import SIPURI, Route
602 1 Adrian Georgescu
603 1 Adrian Georgescu
class SimpleOutboundCall(object):
604 1 Adrian Georgescu
    # indicate that we implement the application.notification.IObserver interface
605 1 Adrian Georgescu
    implements(IObserver)
606 24 Ruud Klaver
607 1 Adrian Georgescu
    def __init__(self, remote_uri, route):
608 1 Adrian Georgescu
        # setup a threading.Event to signal that the Engine has stopped
609 24 Ruud Klaver
        self.engine_ended_event = Event()
610 24 Ruud Klaver
        # start the configuration manager
611 24 Ruud Klaver
        ConfigurationManager().start()
612 24 Ruud Klaver
        # start the account manager
613 24 Ruud Klaver
        am = AccountManager()
614 24 Ruud Klaver
        am.start()
615 24 Ruud Klaver
        # start the Engine with configuration framework parameters
616 24 Ruud Klaver
        Engine().start_cfg()
617 24 Ruud Klaver
        # create a new Session using the default account
618 6 Ruud Klaver
        self.session = Session(am.default_account)
619 26 Luci Stanescu
        # listen for the notification that the Engine stopped
620 6 Ruud Klaver
        NotificationCenter().add_observer(self, "SIPEngineDidEnd", Engine())
621 26 Luci Stanescu
        # listen for the notification that the Session ended
622 6 Ruud Klaver
        NotificationCenter().add_observer(self, "SIPSessionDidEnd", self.session)
623 24 Ruud Klaver
        # start a new outbound session
624 6 Ruud Klaver
        self.session.connect(remote_uri, [route], audio=True)
625 23 Ruud Klaver
626 6 Ruud Klaver
    def end(self):
627 6 Ruud Klaver
        # if the Session is still active, terminate it
628 6 Ruud Klaver
        self.session.end()
629 6 Ruud Klaver
        # wait for the engine to stop, processed in handle_notification
630 6 Ruud Klaver
        self.engine_ended_event.wait()
631 6 Ruud Klaver
        # quit the progam, as this can only be done from the main thread
632 6 Ruud Klaver
        sys.exit()
633 1 Adrian Georgescu
634 1 Adrian Georgescu
    def handle_notification(self, notification):
635 1 Adrian Georgescu
        if notification.name == "SIPSessionDidEnd":
636 1 Adrian Georgescu
            # if for whatever reason the session ended, stop the Engine
637 1 Adrian Georgescu
            print "Session ended"
638 1 Adrian Georgescu
            Engine().stop()
639 1 Adrian Georgescu
        elif notification.name == "SIPEngineDidEnd":
640 1 Adrian Georgescu
            # once the Engine has stopped, signal the (possibly) waiting main
641 1 Adrian Georgescu
            # thread through a threading.Event
642 1 Adrian Georgescu
            self.engine_ended_event.set()
643 1 Adrian Georgescu
644 1 Adrian Georgescu
# place an audio call from the specified account to the specified URI, through
645 1 Adrian Georgescu
# the specified SIP proxy
646 1 Adrian Georgescu
# edit this to reflect real settings
647 1 Adrian Georgescu
call = SimpleOutboundCall(SIPURI(user="bob", host="example.com"), Route("1.2.3.4"))
648 1 Adrian Georgescu
# block waiting for user input
649 26 Luci Stanescu
print "Placing call, press enter to quit program"
650 6 Ruud Klaver
raw_input()
651 30 Adrian Georgescu
# block in end() until the Engine has stopped
652 30 Adrian Georgescu
call.end()
653 47 Adrian Georgescu
}}}
654 50 Adrian Georgescu
655 31 Adrian Georgescu
== SessionManager ==
656 1 Adrian Georgescu
657 30 Adrian Georgescu
Implemented in [browser:sipsimple/session.py]
658 30 Adrian Georgescu
659 30 Adrian Georgescu
The {{{sipsimple.session.SessionManager}}} class is a singleton, which acts as the central aggregation point for sessions within the middleware.
660 1 Adrian Georgescu
Although it is mainly used internally, the application can use it to query information about all active sessions.
661 30 Adrian Georgescu
The SessionManager is implemented as a singleton, meaning that only one instance of this class exists within the middleware.
662 30 Adrian Georgescu
Note that, in order to be able to receive calls, the application has to instantiate this object.
663 50 Adrian Georgescu
664 30 Adrian Georgescu
=== Attributes ===
665 1 Adrian Georgescu
666 30 Adrian Georgescu
 '''sessions'''::
667 30 Adrian Georgescu
  A property providing a copy of the list of all active {{{Sesssion}}} objects within the application, meaning any {{{Session}}} object that exists globally within the application and is not in the {{{NULL}}} or {{{TERMINATED}}} state.
668 50 Adrian Georgescu
669 30 Adrian Georgescu
=== Methods ===
670 30 Adrian Georgescu
671 35 Luci Stanescu
 '''!__init!__'''(''self'')::
672 1 Adrian Georgescu
  This either returns a new {{{SessionManager}}} object with default configuration objects, or returns a copy of the already existing instance.
673 35 Luci Stanescu
674 50 Adrian Georgescu
675 47 Adrian Georgescu
== Account ==
676 47 Adrian Georgescu
677 35 Luci Stanescu
Implemented in [browser:sipsimple/account.py]
678 40 Luci Stanescu
679 35 Luci Stanescu
The {{{sipsimple.account.Account}}} objects represent the SIP accounts which are used by the middleware. It has a dual purpose: it acts as both a container for account-related settings and as a complex object which can be used to interact with various per-account functions, such as presence, registration etc. This page documents the latter case, while the former is explained in the [wiki:SipConfigurationAPI#Account Configuration API].
680 35 Luci Stanescu
681 35 Luci Stanescu
There is exactly one instance of {{{Account}}} per SIP account used and it is uniquely identifiable by its SIP ID, in the form ''user@domain''. It is a singleton, in the sense that instantiating {{{Account}}} using an already used SIP ID will return the same object. However, this is not the recommended way of accessing accounts, as this can lead to creation of new ones; the recommended way is by using the [wiki:SipMiddlewareApi#AccountManager AccountManager]. The next sections will use a lowercase, monospaced {{{account}}} to represent an instance of {{{Account}}}.
682 50 Adrian Georgescu
683 35 Luci Stanescu
=== States ===
684 35 Luci Stanescu
685 35 Luci Stanescu
The {{{Account}}} objects have a setting flag called {{{enabled}}} which, if set to {{{False}}} will deactivate it: none of the internal functions will work in this case; in addition, the application using the middleware should not do anything with a disabled account. After changing it's value, the {{{save()}}} method needs to be called, as the flag is a setting and will not be used until this method is called:
686 35 Luci Stanescu
{{{
687 35 Luci Stanescu
account.enabled = True
688 35 Luci Stanescu
account.save()
689 37 Luci Stanescu
}}}
690 37 Luci Stanescu
691 39 Luci Stanescu
The {{{Account}}} objects will activate automatically when they are loaded/created if the {{{enabled}}} flag is set to {{{True}}} and the {{{sipsimple.engine.Engine}}} is running; if it is not running, the accounts will activate after the engine starts.
692 39 Luci Stanescu
693 35 Luci Stanescu
In order to create a new account, just create a new instance of {{{Account}}} with an id which doesn't belong to any other account.
694 35 Luci Stanescu
695 35 Luci Stanescu
The other functions of {{{Account}}} which run automatically have other enabled flags as well. They will only be activated when both the global enabled flag is set and the function-specific one. These are:
696 1 Adrian Georgescu
697 35 Luci Stanescu
 '''Account.registration.enabled'''::
698 35 Luci Stanescu
  This flag controls the automatic registration of the account. The notifications '''SIPAccountRegistrationDidSucceed''', '''SIPAccountRegistrationDidFail''' and '''SIPAccountRegistrationDidEnd''' are used to inform the status of this registration.
699 35 Luci Stanescu
 '''Account.presence.enabled'''::
700 35 Luci Stanescu
  This flag controls the automatic subscription to buddies for the ''presence'' event and the publication of data in this event. (Not implemented yet)
701 35 Luci Stanescu
 '''Account.dialog_event.enabled'''::
702 35 Luci Stanescu
  This flag controls the automatic subscription to buddies for the ''dialog-info'' event and the publication of data in this event. (Not implemented yet)
703 35 Luci Stanescu
 '''Account.message_summary.enabled'''::
704 1 Adrian Georgescu
  This flag controls the automatic subscription to the ''message-summary'' event in order to find out about voicemail messages. (Not implemented yet)
705 39 Luci Stanescu
706 36 Luci Stanescu
The {{{save()}}} method needs to be called after changing these flags in order for them to take effect. The methods available on {{{Account}}} objects are inherited from [wiki:SipConfigurationAPI#SettingsObject SettingsObject].
707 50 Adrian Georgescu
708 36 Luci Stanescu
=== Attributes ===
709 36 Luci Stanescu
710 36 Luci Stanescu
The following attributes can be used on an Account object and need to be considered read-only.
711 36 Luci Stanescu
712 36 Luci Stanescu
 '''id'''::
713 36 Luci Stanescu
  This attribute is of type {{{sipsimple.configuration.datatypes.SIPAddress}}} (a subclass of {{{str}}}) and contains the SIP id of the account. It can be used as a normal string in the form ''user@domain'', but it also allows access to the components via the attributes {{{username}}} and {{{domain}}}.
714 36 Luci Stanescu
  {{{
715 36 Luci Stanescu
  account.id # 'alice@example.com'
716 36 Luci Stanescu
  account.id.username # 'alice'
717 36 Luci Stanescu
  account.id.domain # 'example.com'
718 36 Luci Stanescu
  }}}
719 36 Luci Stanescu
 '''contact'''::
720 36 Luci Stanescu
  This attribute can be used to construct the Contact URI for SIP requests sent on behalf of this account. It's type is {{{sipsimple.account.ContactURI}}} which is a subclass of {{{sipsimple.configuration.datatypes.SIPAddress}}}. In addition to the attributes defined in {{{SIPAddress}}}, it can be indexed by a string representing a transport ({{{'udp'}}}, {{{'tcp'}}} or {{{'tls'}}}) which will return a {{{sipsimple.core.SIPURI}}} object with the appropriate port and transport parameter. The username part is a randomly generated 8 character string consisting of lowercase letters; the domain part is the IP address on which the {{{Engine}}} is listening (as specified by the SIPSimpleSettings.local_ip setting).
721 1 Adrian Georgescu
  {{{
722 36 Luci Stanescu
  account.contact # 'hnfkybrt@10.0.0.1'
723 36 Luci Stanescu
  account.contact.username # 'hnfkybrt'
724 36 Luci Stanescu
  account.contact.domain # '10.0.0.1'
725 36 Luci Stanescu
  account.contact['udp'] # <SIPURI "sip:hnfkybrt@10.0.0.1:53024">
726 36 Luci Stanescu
  account.contact['tls'] # <SIPURI "sip:hnfkybrt@10.0.0.1:54478;transport=tls">
727 36 Luci Stanescu
  }}}
728 36 Luci Stanescu
 '''credentials'''::
729 36 Luci Stanescu
  This attribute is of type {{{sipsimple.core.Credentials}}} object which is built from the {{{id}}} attribute and {{{display_name}}} and {{{password}}} settings of the Account. Whenever one of these settings are changed, this attribute is updated.
730 36 Luci Stanescu
  {{{
731 36 Luci Stanescu
  account.credentials # <Credentials for '"Alice" <sip:alice@example.com>'>
732 37 Luci Stanescu
  }}}
733 50 Adrian Georgescu
734 37 Luci Stanescu
=== Notifications ===
735 37 Luci Stanescu
736 37 Luci Stanescu
 '''CFGSettingsObjectDidChange'''::
737 37 Luci Stanescu
  This notification is sent when the {{{save()}}} method is called on the account after some of the settings were changed. As the notification belongs to the {{{SettingsObject}}} class, it is exaplained in detail in [wiki:SipConfigurationAPI#SettingsObjectNotifications SettingsObject Notifications].
738 37 Luci Stanescu
 '''SIPAccountDidActivate'''::
739 37 Luci Stanescu
  This notification is sent when the {{{Account}}} activates. This can happen when the {{{Account}}} is loaded if it's enabled flag is set and the Engine is running, and at any later time when the status of the Engine changes or the enabled flag is modified. The notification does not contain any data.
740 37 Luci Stanescu
 '''SIPAccountDidDeactivate'''::
741 37 Luci Stanescu
  This notification is sent when the {{{Account}}} deactivates. This can happend when the {{{Engine}}} is stopped or when the enabled flag of the account is set to {{{False}}}. The notification does not contain any data.
742 37 Luci Stanescu
 '''SIPAccountRegistrationDidSucceed'''::
743 37 Luci Stanescu
  This notification is sent when a REGISTER request sent for the account succeeds (it is also sent for each refresh of the registration). The data contained in this notification is:
744 37 Luci Stanescu
  [[BR]]''code'':[[BR]]
745 37 Luci Stanescu
   The status code of the response for the REGISTER request.
746 37 Luci Stanescu
  [[BR]]''reason'':[[BR]]
747 37 Luci Stanescu
   The reason of the response for the REGISTER request.
748 37 Luci Stanescu
  [[BR]]''contact_uri'':[[BR]]
749 37 Luci Stanescu
   The Contact URI which was registered.
750 37 Luci Stanescu
  [[BR]]''contact_uri_list'':[[BR]]
751 37 Luci Stanescu
   A list containing all the contact URIs registered for this SIP account.
752 37 Luci Stanescu
  [[BR]]''expires'':[[BR]]
753 37 Luci Stanescu
   The amount in seconds in which this registration will expire.
754 37 Luci Stanescu
  [[BR]]''registration'':[[BR]]
755 37 Luci Stanescu
   The {{{sipsimple.core.Registration}}} object used to register this account.
756 37 Luci Stanescu
 '''SIPAccountRegistrationDidFail'''::
757 37 Luci Stanescu
  This notification is sent when a REGISTER request sent for the account fails. It can fail either because a negative response was returned or because PJSIP considered the request failed (e.g. on timeout). The data contained in this notification is:
758 37 Luci Stanescu
  [[BR]]''code'':[[BR]]
759 37 Luci Stanescu
   The status code of the response for the REGISTER request. This is only present if the notification is sent as a result of a response being received.
760 37 Luci Stanescu
  [[BR]]''reason'':[[BR]]
761 37 Luci Stanescu
   The reason for the failure of the REGISTER request.
762 37 Luci Stanescu
  [[BR]]''registration'':[[BR]]
763 1 Adrian Georgescu
   The {{{sipsimple.core.Registration}}} object which failed.
764 37 Luci Stanescu
  [[BR]]''next_route'':[[BR]]
765 37 Luci Stanescu
   A {{{sipsimple.core.Route}}} object which will be tried next for registering the account, or {{{None}}} if a new DNS lookup needs to be performed.
766 37 Luci Stanescu
  [[BR]]''delay'':[[BR]]
767 37 Luci Stanescu
   The amount in seconds as a {{{float}}} after which the next route will be tried for registering the account.
768 1 Adrian Georgescu
 '''SIPAccountRegistrationDidEnd'''::
769 37 Luci Stanescu
  This notification is sent when a registration is ended (the account is unregistered). The data contained in this notification is:
770 37 Luci Stanescu
  [[BR]]''code'':[[BR]]
771 1 Adrian Georgescu
   The status code of the response for the REGISTER with {{{Expires: 0}}} request. This is only present if a response was received.
772 37 Luci Stanescu
  [[BR]]''reason'':[[BR]]
773 37 Luci Stanescu
   The reason returned in the response for the Register with {{{Expires: 0}}} request. This is only present if a response was received
774 37 Luci Stanescu
  [[BR]]''registration'':[[BR]]
775 37 Luci Stanescu
   The {{{sipsimple.core.Registration}}} object which ended.
776 50 Adrian Georgescu
777 37 Luci Stanescu
== BonjourAccount ==
778 48 Adrian Georgescu
779 48 Adrian Georgescu
Implemented in [browser:sipsimple/account.py]
780 37 Luci Stanescu
781 37 Luci Stanescu
The {{{sipsimple.account.BonjourAccount}}} represents the SIP account used for P2P mode; it does not interact with any server. The class is a singleton, as there can only be one such account on a system. Similar to the {{{Account}}}, it is used both as a complex object, which implements the functions for bonjour mode, as well as a container for the related settings.
782 50 Adrian Georgescu
783 38 Luci Stanescu
=== States ===
784 38 Luci Stanescu
785 38 Luci Stanescu
The {{{BonjourAccount}}} has an {{{enabled}}} flags which controls whether this account will be used or not. If it is set to {{{False}}}, none of the internal functions will be activated and, in addition, the account should not be used by the application. The bonjour account can only activated if the Engine is running; once it is started, if the enabled flag is set, the account will activate. When the {{{BonjourAccount}}} is activated, it will broadcast the contact address on the LAN. (Not implemented yet)
786 50 Adrian Georgescu
787 38 Luci Stanescu
=== Attributes ===
788 38 Luci Stanescu
789 38 Luci Stanescu
The following attributes can be used on an BonjourAccount object and need to be considered read-only.
790 38 Luci Stanescu
791 38 Luci Stanescu
 '''id'''::
792 38 Luci Stanescu
  This attribute is of type {{{sipsimple.configuration.datatypes.SIPAddress}}} (a subclass of {{{str}}}) and contains the SIP id of the account, which is {{{'bonjour@local'}}}. It can be used as a normal string, but it also allows access to the components via the attributes {{{username}}} and {{{domain}}}.
793 38 Luci Stanescu
  {{{
794 38 Luci Stanescu
  bonjour_account.id # 'bonjour@local'
795 38 Luci Stanescu
  bonjour_account.id.username # 'bonjour'
796 1 Adrian Georgescu
  bonjour_account.id.domain # 'local'
797 38 Luci Stanescu
  }}}
798 38 Luci Stanescu
 '''contact'''::
799 38 Luci Stanescu
  This attribute can be used to construct the Contact URI for SIP requests sent on behalf of this account. It's type is {{{sipsimple.account.ContactURI}}} which is a subclass of {{{sipsimple.configuration.datatypes.SIPAddress}}}. In addition to the attributes defined in {{{SIPAddress}}}, it can be indexed by a string representing a transport ({{{'udp'}}}, {{{'tcp'}}} or {{{'tls'}}}) which will return a {{{sipsimple.core.SIPURI}}} object with the appropriate port and transport parameter. The username part is a randomly generated 8 character string consisting of lowercase letters; the domain part is the IP address on which the {{{Engine}}} is listening (as specified by the SIPSimpleSettings.local_ip setting).
800 38 Luci Stanescu
  {{{
801 38 Luci Stanescu
  account.contact # 'lxzvgack@10.0.0.1'
802 38 Luci Stanescu
  account.contact.username # 'lxzvgack'
803 38 Luci Stanescu
  account.contact.domain # '10.0.0.1'
804 38 Luci Stanescu
  account.contact['udp'] # <SIPURI "sip:lxzvgack@10.0.0.1:53024">
805 1 Adrian Georgescu
  account.contact['tls'] # <SIPURI "sip:lxzvgack@10.0.0.1:54478;transport=tls">
806 38 Luci Stanescu
  }}}
807 38 Luci Stanescu
 '''credentials'''::
808 38 Luci Stanescu
  This attribute is of type {{{sipsimple.core.Credentials}}} object which is built from the {{{contact}}} attribute and {{{display_name}}} setting of the BonjourAccount; the password is set to the empty string. Whenever the display_name setting is changed, this attribute is updated.
809 1 Adrian Georgescu
  {{{
810 1 Adrian Georgescu
  account.credentials # <Credentials for '"Alice" <sip:lxzvgack@10.0.0.1>'>
811 39 Luci Stanescu
  }}}
812 50 Adrian Georgescu
813 39 Luci Stanescu
=== Notifications ===
814 39 Luci Stanescu
815 39 Luci Stanescu
 '''CFGSettingsObjectDidChange'''::
816 39 Luci Stanescu
  This notification is sent when the {{{save()}}} method is called on the account after some of the settings were changed. As the notification belongs to the {{{SettingsObject}}} class, it is exaplained in detail in [wiki:SipConfigurationAPI#SettingsObjectNotifications SettingsObject Notifications].
817 39 Luci Stanescu
 '''SIPAccountDidActivate'''::
818 39 Luci Stanescu
  This notification is sent when the {{{BonjourAccount}}} activates. This can happen when the {{{BonjourAccount}}} is loaded if it's enabled flag is set and the Engine is running, and at any later time when the status of the Engine changes or the enabled flag is modified. The notification does not contain any data.
819 39 Luci Stanescu
 '''SIPAccountDidDeactivate'''::
820 39 Luci Stanescu
  This notification is sent when the {{{BonjourAccount}}} deactivates. This can happend when the {{{Engine}}} is stopped or when the enabled flag of the account is set to {{{False}}}. The notification does not contain any data.
821 39 Luci Stanescu
822 50 Adrian Georgescu
823 48 Adrian Georgescu
== AccountManager ==
824 39 Luci Stanescu
825 39 Luci Stanescu
Implemented in [browser:sipsimple/account.py]
826 39 Luci Stanescu
827 39 Luci Stanescu
The {{{sipsimple.account.AccountManager}}} is the entity responsible for loading and keeping track of the existing accounts. It is a singleton and can be instantiated anywhere, obtaining the same instance. It cannot be used until its {{{start}}} method has been called.
828 50 Adrian Georgescu
829 39 Luci Stanescu
=== Methods ===
830 39 Luci Stanescu
831 39 Luci Stanescu
 '''!__init!__'''(''self'')::
832 39 Luci Stanescu
  The {{{__init__}}} method allows the {{{AccountManager}}} to be instantiated without passing any parameters. A reference to the {{{AccountManager}}} can be obtained anywhere before it is started.
833 39 Luci Stanescu
 '''start'''(''self'')::
834 39 Luci Stanescu
  This method will load all the existing accounts from the configuration. If the Engine is running, the accounts will also activate. This method can only be called after the [wiki:SipConfigurationAPI#ConfigurationManager ConfigurationManager] has been started. A '''SIPAccountManagerDidAddAccount''' will be sent for each account loaded.
835 39 Luci Stanescu
 '''stop'''(''self'')::
836 39 Luci Stanescu
  Calling this method will deactivate all accounts managed by the {{{AccountManager}}}.
837 39 Luci Stanescu
 '''has_account'''(''self'', '''id''')::
838 39 Luci Stanescu
  This method returns {{{True}}} if an account which has the specifed SIP ID (must be a string) exists and {{{False}}} otherwise.
839 39 Luci Stanescu
 '''get_account'''(''self'', '''id''')::
840 39 Luci Stanescu
  Returns the account (either an {{{Account}}} instance or the {{{BonjourAccount}}} instance) with the specified SIP ID. Will raise a {{{KeyError}}} if such an account does not exist.
841 39 Luci Stanescu
 '''get_accounts'''(''self'')::
842 39 Luci Stanescu
  Returns a list containing all the managed accounts.
843 39 Luci Stanescu
 '''iter_accounts'''(''self'')::
844 39 Luci Stanescu
  Returns an iterator through all the managed accounts.
845 39 Luci Stanescu
 '''find_account'''(''self'', '''contact_uri''')::
846 39 Luci Stanescu
  Returns an account with matches the specified {{{contact_uri}}} which must be a {{{sipsimple.core.SIPURI}}} instance. Only the accounts with the enabled flag set will be considered. Returns None if such an account does not exist.
847 50 Adrian Georgescu
848 39 Luci Stanescu
=== Notifications ===
849 39 Luci Stanescu
850 39 Luci Stanescu
 '''SIPAccountManagerDidAddAccount'''::
851 39 Luci Stanescu
  This notification is sent when a new account becomes available to the {{{AccountManager}}}. The notification is also sent when the accounts are loaded from the configuration. The data contains a single attribute, {{{account}}} which is the account object which was added.
852 39 Luci Stanescu
 '''SIPAccountManagerDidRemoveAccount'''::
853 39 Luci Stanescu
  This notification is sent when an account is deleted using the {{{delete}}} method. The data contains a single attribute, {{{account}}} which is the account object which was deleted.
854 39 Luci Stanescu
 '''SIPAccountManagerDidChangeDefaultAccount'''::
855 39 Luci Stanescu
  This notification is sent when the default account changes. The notification contains two attributes:
856 39 Luci Stanescu
  [[BR]]''old_account'':[[BR]]
857 39 Luci Stanescu
   This is the account object which used to be the default account.
858 39 Luci Stanescu
  [[BR]]''account'':[[BR]]
859 55 Adrian Georgescu
   This is the account object which is the new default account.
860 55 Adrian Georgescu
861 55 Adrian Georgescu
== IMediaStream ==
862 55 Adrian Georgescu
863 55 Adrian Georgescu
Implemented in [browser:sipsimple/streams/__init__.py]
864 55 Adrian Georgescu
865 55 Adrian Georgescu
This module automatically registers media streams to a stream registry
866 55 Adrian Georgescu
allowing for a plug and play mechanism of various types of media negoticated
867 55 Adrian Georgescu
in a SIP session that can be added to this library by using a generic API.
868 55 Adrian Georgescu
869 55 Adrian Georgescu
For actual usage see rtp.py and msrp.py that implement media streams based
870 55 Adrian Georgescu
on their respective RTP and MSRP protocols.
871 55 Adrian Georgescu
872 55 Adrian Georgescu
873 55 Adrian Georgescu
=== Atributes ===
874 55 Adrian Georgescu
875 55 Adrian Georgescu
 '''type''' (class attribute)::
876 55 Adrian Georgescu
 A string identifying the stream type (ex: audio, video, ...)
877 55 Adrian Georgescu
 '''priority'''::
878 55 Adrian Georgescu
 An integer value indicating the stream priority relative to the other streams types (higher numbers have higher priority)
879 55 Adrian Georgescu
 '''hold_supported'''::
880 55 Adrian Georgescu
 True if the stream supports hold
881 55 Adrian Georgescu
 '''on_hold_by_local'''::
882 55 Adrian Georgescu
 True if the stream is on hold by the local party
883 55 Adrian Georgescu
 '''on_hold_by_remote'''::
884 55 Adrian Georgescu
 True if the stream is on hold by the remote
885 55 Adrian Georgescu
 '''on_hold'''::
886 55 Adrian Georgescu
 True if either on_hold_by_local or on_hold_by_remote is true
887 55 Adrian Georgescu
888 55 Adrian Georgescu
=== Methods ===
889 55 Adrian Georgescu
890 55 Adrian Georgescu
 '''!__init!__'''(''self'', ''account'')::
891 55 Adrian Georgescu
 Initializes the generic stream instance.
892 55 Adrian Georgescu
 '''new_from_sdp'''(''cls'', ''account'', ''remote_sdp'', ''stream_index'')::
893 55 Adrian Georgescu
 '''get_local_media'''(''self'', ''for_offer'')::
894 55 Adrian Georgescu
 '''initialize'''(''self'', ''session'', ''direction'')::
895 55 Adrian Georgescu
 Initializes the stream 
896 55 Adrian Georgescu
 '''start'''(''self'', ''local_sdp'', ''remote_sdp'', ''stream_index'')::
897 55 Adrian Georgescu
 Completes the stream related connection. [[BR]]
898 55 Adrian Georgescu
 When done, must fire StreamChatDidStart notification. 
899 55 Adrian Georgescu
 '''end'''(''self'')::
900 1 Adrian Georgescu
 Ends the stream.  When done, must fire StreamChatDidEnd notification. 
901 55 Adrian Georgescu
 '''validate_update'''(''self'', ''remote_sdp'', ''stream_index'')::
902 58 Adrian Georgescu
 '''update'''(''self'', ''local_sdp'', ''remote_sdp'', ''stream_index'')::
903 55 Adrian Georgescu
 '''deactivate'''(''self'')::
904 55 Adrian Georgescu
 '''hold'''(''self'')::
905 55 Adrian Georgescu
 Puts the stream on hold if supported by the stream. Typically used by audio and video streams.
906 55 Adrian Georgescu
 '''unhold'''(''self'')::
907 55 Adrian Georgescu
 Takes the stream off hold.
908 55 Adrian Georgescu
909 55 Adrian Georgescu
=== Notifications ===
910 55 Adrian Georgescu
911 55 Adrian Georgescu
These notifications must be generated by all streams in order for the upper layer (SIP session) to perform the right decissions.
912 55 Adrian Georgescu
913 55 Adrian Georgescu
 '''MediaStreamDidInitialize'''::
914 55 Adrian Georgescu
 Sent when the {{{Stream}}} instance is initialized
915 55 Adrian Georgescu
 '''MediaStreamDidStart'''::
916 55 Adrian Georgescu
 Sent when the {{{Stream}}} instance has started.
917 55 Adrian Georgescu
 '''MediaStreamDidFail'''::
918 55 Adrian Georgescu
 Sent when the {{{Stream}}} instance has failed.
919 55 Adrian Georgescu
 '''MediaStreamWillEnd'''::
920 55 Adrian Georgescu
 Sent before the {{{Stream}}} instance will end.
921 55 Adrian Georgescu
 '''MediaStreamDidEnd'''::
922 55 Adrian Georgescu
 Sent when the {{{Stream}}} instance did ended.
923 55 Adrian Georgescu
924 55 Adrian Georgescu
== MediaStreamRegistry ==
925 55 Adrian Georgescu
926 55 Adrian Georgescu
The MediaStream registry is used to register streams that can be automatically dealt with by the SIP session layer.
927 55 Adrian Georgescu
928 55 Adrian Georgescu
There are several pre-built streams based on the '''iMediaStream''' API:
929 55 Adrian Georgescu
930 55 Adrian Georgescu
 * {{{sipsimple.streams.msrp.MSRPStreamBase}}}  - MSRP base stream, all MSRP derived streams inherit this
931 55 Adrian Georgescu
 * {{{sipsimple.streams.msrp.ChatStream}}} - Chat stream based on MSRP 
932 55 Adrian Georgescu
 * {{{sipsimple.streams.msrp.FileSelector}}} - Helper for selecting a file for FileTransferStream
933 55 Adrian Georgescu
 * {{{sipsimple.streams.msrp.FileTransferStream}}} - File Transfer stream based on MSRP 
934 55 Adrian Georgescu
 * {{{sipsimple.streams.msrp.VNCConnectionError}}} - Helper class for DesktopSharingStream
935 55 Adrian Georgescu
 * {{{sipsimple.streams.msrp.DesktopSharingHandlerBase}}}  - Helper class for DesktopSharingStream
936 55 Adrian Georgescu
 * {{{sipsimple.streams.msrp.InternalVNCViewerHandler}}} - Helper class for DesktopSharingStream
937 55 Adrian Georgescu
 * {{{sipsimple.streams.msrp.InternalVNCViewerHandler}}}  - Helper class for DesktopSharingStream
938 55 Adrian Georgescu
 * {{{sipsimple.streams.msrp.ExternalVNCViewerHandler}}}  - Helper class for DesktopSharingStream
939 55 Adrian Georgescu
 * {{{sipsimple.streams.msrp.ExternalVNCServerHandler}}}  - Helper class for DesktopSharingStream
940 55 Adrian Georgescu
 * {{{sipsimple.streams.msrp.DesktopSharingStream}}} -  Desktop Sharing stream based on VNC over MSRP 
941 55 Adrian Georgescu
 * {{{sipsimple.streams.msrp.NotificationProxyLogger}}} - Helper class for handling MSRP library logs
942 55 Adrian Georgescu
943 55 Adrian Georgescu
These classes are used internally by [wiki:SipMiddlewareApi#Session Session], which provides the necessary methods to access their features. The notifications posted by these classes are also handled internally by [wiki:SipMiddlewareApi#Session Session]. The notifications that are relevant to the user are then reposted by the Session instance. Refer to [wiki:SipMiddlewareApi#Session Session documentation] for details on the Session API. 
944 55 Adrian Georgescu
945 55 Adrian Georgescu
== AudioStream ==
946 55 Adrian Georgescu
947 55 Adrian Georgescu
Implemented in [browser:sipsimple/streams/rtp.py]
948 57 Adrian Georgescu
949 57 Adrian Georgescu
=== SDP Example ===
950 57 Adrian Georgescu
951 57 Adrian Georgescu
{{{
952 57 Adrian Georgescu
Content-Type: application/sdp
953 57 Adrian Georgescu
Content-Length:  1093
954 57 Adrian Georgescu
955 57 Adrian Georgescu
v=0
956 57 Adrian Georgescu
o=- 3467525278 3467525278 IN IP4 192.168.1.6
957 57 Adrian Georgescu
s=blink-0.10.7-beta
958 57 Adrian Georgescu
c=IN IP4 80.101.96.20
959 57 Adrian Georgescu
t=0 0
960 57 Adrian Georgescu
m=audio 55328 RTP/AVP 104 103 102 3 9 0 8 101
961 57 Adrian Georgescu
a=rtcp:55329 IN IP4 80.101.96.20
962 57 Adrian Georgescu
a=rtpmap:104 speex/32000
963 57 Adrian Georgescu
a=rtpmap:103 speex/16000
964 57 Adrian Georgescu
a=rtpmap:102 speex/8000
965 57 Adrian Georgescu
a=rtpmap:3 GSM/8000
966 57 Adrian Georgescu
a=rtpmap:9 G722/8000
967 57 Adrian Georgescu
a=rtpmap:0 PCMU/8000
968 57 Adrian Georgescu
a=rtpmap:8 PCMA/8000
969 57 Adrian Georgescu
a=rtpmap:101 telephone-event/8000
970 57 Adrian Georgescu
a=fmtp:101 0-15
971 57 Adrian Georgescu
a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:esI6DbLY1+Aceu0JNswN9Z10DcFx5cZwqJcu91jb
972 57 Adrian Georgescu
a=crypto:2 AES_CM_128_HMAC_SHA1_32 inline:SHuEMm1BYJqOF4udKl73EaCwnsI57pO86bYKsg70
973 57 Adrian Georgescu
a=ice-ufrag:2701ed80
974 57 Adrian Georgescu
a=ice-pwd:6f8f8281
975 57 Adrian Georgescu
a=candidate:S 1 UDP 31 80.101.96.20 55328 typ srflx raddr 192.168.1.6 rport 55328
976 57 Adrian Georgescu
a=candidate:H 1 UDP 23 192.168.1.6 55328 typ host
977 57 Adrian Georgescu
a=candidate:H 1 UDP 23 10.211.55.2 55328 typ host
978 57 Adrian Georgescu
a=candidate:H 1 UDP 23 10.37.129.2 55328 typ host
979 57 Adrian Georgescu
a=candidate:S 2 UDP 30 80.101.96.20 55329 typ srflx raddr 192.168.1.6 rport 55329
980 57 Adrian Georgescu
a=candidate:H 2 UDP 22 192.168.1.6 55329 typ host
981 57 Adrian Georgescu
a=candidate:H 2 UDP 22 10.211.55.2 55329 typ host
982 57 Adrian Georgescu
a=candidate:H 2 UDP 22 10.37.129.2 55329 typ host
983 57 Adrian Georgescu
a=sendrecv
984 57 Adrian Georgescu
}}}
985 55 Adrian Georgescu
986 55 Adrian Georgescu
=== Atributes ===
987 55 Adrian Georgescu
988 55 Adrian Georgescu
 '''recording_file_name''' (class attribute)::
989 55 Adrian Georgescu
 '''sample_rate''' (class attribute)::
990 55 Adrian Georgescu
 '''local_rtp_address''' (class attribute)::
991 55 Adrian Georgescu
 '''local_rtp_port''' (class attribute)::
992 55 Adrian Georgescu
 '''remote_rtp_address''' (class attribute)::
993 55 Adrian Georgescu
 '''remote_rtp_port''' (class attribute)::
994 1 Adrian Georgescu
 '''srtp_active''' (class attribute)::
995 1 Adrian Georgescu
 '''statistics''' (class attribute)::
996 58 Adrian Georgescu
997 58 Adrian Georgescu
=== Methods ===
998 58 Adrian Georgescu
999 58 Adrian Georgescu
 '''send_dtmf'''(''digit'')::
1000 58 Adrian Georgescu
 '''start_recording'''(''file_name=None'', ''separate=False'')::
1001 58 Adrian Georgescu
 '''stop_recording'''()::
1002 55 Adrian Georgescu
 
1003 55 Adrian Georgescu
=== Notifications ===
1004 55 Adrian Georgescu
1005 55 Adrian Georgescu
 '''AudioStreamDidChangeHoldState'''::
1006 55 Adrian Georgescu
 '''AudioStreamDidStartRecordingAudio'''::
1007 55 Adrian Georgescu
 '''AudioStreamDidStopRecordingAudio'''::
1008 55 Adrian Georgescu
 '''AudioStreamGotDTMF'''::
1009 55 Adrian Georgescu
 '''AudioStreamWillStartRecordingAudio''::
1010 55 Adrian Georgescu
 '''AudioStreamWillStopRecordingAudio'''::
1011 55 Adrian Georgescu
 
1012 55 Adrian Georgescu
== MSRPStreamBase ==
1013 55 Adrian Georgescu
1014 55 Adrian Georgescu
Implemented in [browser:sipsimple/streams/msrp.py]
1015 55 Adrian Georgescu
1016 55 Adrian Georgescu
=== Atributes ===
1017 55 Adrian Georgescu
1018 55 Adrian Georgescu
 '''media_type'''::
1019 55 Adrian Georgescu
 '''accept_types'''::
1020 55 Adrian Georgescu
 '''accept_wrapped_types'''::
1021 55 Adrian Georgescu
 '''use_msrp_session'''::
1022 55 Adrian Georgescu
1023 55 Adrian Georgescu
=== Notifications ===
1024 55 Adrian Georgescu
1025 55 Adrian Georgescu
 '''MSRPLibraryLog'''::
1026 55 Adrian Georgescu
 '''MSRPTransportTrace'''::
1027 55 Adrian Georgescu
1028 55 Adrian Georgescu
== ChatStream ==
1029 55 Adrian Georgescu
1030 55 Adrian Georgescu
Implemented in [browser:sipsimple/streams/msrp.py]
1031 55 Adrian Georgescu
1032 55 Adrian Georgescu
{{{sipsimple.streams.msrp.ChatStream}}} implements Instant Messaging (IM) over MSRP for the [wiki:SipMiddlewareApi middleware]. This class performs the following functions:
1033 55 Adrian Georgescu
1034 55 Adrian Georgescu
 * automatically wraps outgoing messages with Message/CPIM if that's necessary according to accept-types
1035 55 Adrian Georgescu
 * unwraps incoming Message/CPIM messages; for each incoming message, {{{ChatStreamGotMessage}}} is posted
1036 55 Adrian Georgescu
 * plays notification sounds on received/sent message
1037 55 Adrian Georgescu
 * reacts to and composes iscomposing payloads
1038 57 Adrian Georgescu
1039 57 Adrian Georgescu
=== SDP Example ===
1040 57 Adrian Georgescu
1041 57 Adrian Georgescu
{{{
1042 57 Adrian Georgescu
Content-Type: application/sdp
1043 57 Adrian Georgescu
Content-Length:   283
1044 57 Adrian Georgescu
1045 57 Adrian Georgescu
v=0
1046 57 Adrian Georgescu
o=- 3467525214 3467525214 IN IP4 192.168.1.6
1047 57 Adrian Georgescu
s=blink-0.10.7-beta
1048 57 Adrian Georgescu
c=IN IP4 192.168.1.6
1049 57 Adrian Georgescu
t=0 0
1050 57 Adrian Georgescu
m=message 2855 TCP/TLS/MSRP *
1051 57 Adrian Georgescu
a=path:msrps://192.168.1.6:2855/ca7940f12ddef14c3c32;tcp
1052 57 Adrian Georgescu
a=accept-types:message/cpim text/* application/im-iscomposing+xml
1053 57 Adrian Georgescu
a=accept-wrapped-types:*
1054 57 Adrian Georgescu
}}}
1055 55 Adrian Georgescu
1056 55 Adrian Georgescu
=== Methods ===
1057 55 Adrian Georgescu
1058 55 Adrian Georgescu
 '''!__init!__'''(''self'', ''account'', ''direction'')::
1059 55 Adrian Georgescu
 Initializes the ChatStream instance.
1060 55 Adrian Georgescu
1061 55 Adrian Georgescu
 '''initialize'''(''self'')::
1062 55 Adrian Georgescu
 Initializes the MSRP connection; connects to the relay if necessary. When done, fires ChatStreamDidInitialize (with 'sdpmedia' attribute, containing the appropriate 'SDPMedia' instance)
1063 55 Adrian Georgescu
1064 55 Adrian Georgescu
 '''start'''(''self'', ''remote_media'')::
1065 55 Adrian Georgescu
 Completes the MSRP connection establishment; this includes binding the MSRP session. [[BR]]
1066 55 Adrian Georgescu
 When done, fires MSRPChatDidStart notification. At this point each incoming message is posted as a {{{ChatStreamGotMessage}}} notification
1067 55 Adrian Georgescu
1068 55 Adrian Georgescu
 '''end'''(''self'')::
1069 55 Adrian Georgescu
 Closes the MSRP connection or cleans up after initialize(), whatever is necessary. [[BR]]
1070 55 Adrian Georgescu
 Before doing anything posts {{{ChatStreamWillEnd}}} notification.
1071 55 Adrian Georgescu
 When done, posts {{{ChatStreamDidEnd}}} notification. If there was an error, posts {{{ChatStreamDidFail}}} notification. 
1072 55 Adrian Georgescu
 {{{ChatStreamDidEnd}}} notification will be posted anyway.
1073 55 Adrian Georgescu
1074 55 Adrian Georgescu
 '''send_message'''(''self'', ''content'', ''content_type''={{{'text/plain'}}}, ''to_uri''={{{None}}}, ''dt''={{{None}}})::
1075 55 Adrian Georgescu
 Sends IM message. Prefer Message/CPIM wrapper if it is supported. If called before the connection was established, the messages will be
1076 55 Adrian Georgescu
 queued until ChatStreamDidStart notification.
1077 55 Adrian Georgescu
1078 55 Adrian Georgescu
 Returns the generated MSRP chunk (MSRPData instance); to get Message-ID use its 'message_id' attribute.
1079 55 Adrian Georgescu
1080 55 Adrian Georgescu
 ''content'' str:[[BR]]
1081 55 Adrian Georgescu
 content of the message
1082 55 Adrian Georgescu
1083 55 Adrian Georgescu
 ''to_uri'' SIPURI:[[BR]]
1084 55 Adrian Georgescu
 "To" header of CPIM wrapper; use to override the default supplied to {{{__init__}}}.
1085 55 Adrian Georgescu
 May only differ from the one supplied in __init__ if the remote party supports private messages. If it does not, {{{MSRPChatError}}} will be raised;
1086 55 Adrian Georgescu
1087 55 Adrian Georgescu
 ''content_type'' str:[[BR]]
1088 55 Adrian Georgescu
 Content-Type of wrapped message if Message/CPIM is used (Content-Type of MSRP message is always Message/CPIM in that case);
1089 55 Adrian Georgescu
 otherwise, Content-Type of MSRP message.
1090 55 Adrian Georgescu
1091 55 Adrian Georgescu
 These MSRP headers are used to enable end-to-end success reports and to disable hop-to-hop successful responses:
1092 55 Adrian Georgescu
{{{
1093 55 Adrian Georgescu
Failure-Report: partial
1094 55 Adrian Georgescu
Success-Report: yes
1095 55 Adrian Georgescu
}}}
1096 55 Adrian Georgescu
1097 55 Adrian Georgescu
 '''send_composing_indication'''(''self'', ''state'', ''refresh'', ''last_active=None'', ''remote_identity=None'')::
1098 55 Adrian Georgescu
 Send is composing notification.
1099 55 Adrian Georgescu
1100 55 Adrian Georgescu
=== Notifications ===
1101 55 Adrian Georgescu
1102 55 Adrian Georgescu
To communicate with the middleware, MSRPChat class uses the notification system provided by the [http://pypi.python.org/pypi/python-application python-application] package.
1103 55 Adrian Georgescu
1104 55 Adrian Georgescu
 '''ChatStreamGotMessage'''::
1105 55 Adrian Georgescu
 Sent whenever a new incoming message is received,
1106 55 Adrian Georgescu
  [[BR]]''content'':[[BR]]
1107 55 Adrian Georgescu
  The string that the remote user has typed.
1108 55 Adrian Georgescu
  [[BR]]''content_type'':[[BR]]
1109 55 Adrian Georgescu
  Content-Type of the user message.
1110 55 Adrian Georgescu
  [[BR]]''cpim_headers'':[[BR]]
1111 55 Adrian Georgescu
  A dictionary of CPIM headers. (Empty dictionary if no CPIM wrapper was used).
1112 55 Adrian Georgescu
  [[BR]]''message'':[[BR]]
1113 55 Adrian Georgescu
  A {{{msrplib.protocol.MSRPData}}} instance providing all the MSRP information about the chunk.
1114 55 Adrian Georgescu
 '''ChatStreamDidDeliverMessage'''::
1115 55 Adrian Georgescu
 Sent when a successful report is received.
1116 55 Adrian Georgescu
  [[BR]]''message_id'':[[BR]]
1117 55 Adrian Georgescu
  Text identifier of the message.
1118 55 Adrian Georgescu
  [[BR]]''code'':[[BR]]
1119 55 Adrian Georgescu
  Integer result code.
1120 55 Adrian Georgescu
  [[BR]]''reason'':[[BR]]
1121 55 Adrian Georgescu
  Text comment.
1122 55 Adrian Georgescu
  [[BR]]''message'':[[BR]]
1123 55 Adrian Georgescu
  A {{{msrplib.protocol.MSRPData}}} instance providing all the MSRP information about the report.
1124 55 Adrian Georgescu
 '''ChatStreamDidNotDeliverMessage'''::
1125 55 Adrian Georgescu
 Sent when a failure report of failure transaction response is received.
1126 55 Adrian Georgescu
  [[BR]]''message_id'':[[BR]]
1127 55 Adrian Georgescu
  Text identifier of the message.
1128 55 Adrian Georgescu
  [[BR]]''code'':[[BR]]
1129 55 Adrian Georgescu
  Integer result code.
1130 55 Adrian Georgescu
  [[BR]]''reason'':[[BR]]
1131 55 Adrian Georgescu
  Text comment.
1132 55 Adrian Georgescu
  [[BR]]''message'':[[BR]]
1133 55 Adrian Georgescu
  A {{{msrplib.protocol.MSRPData}}} instance providing all the MSRP information about the report.
1134 55 Adrian Georgescu
 '''ChatStreamDidSendMessage'''::
1135 55 Adrian Georgescu
 Sent when an outgoing message has been sent.
1136 55 Adrian Georgescu
 '''ChatStreamGotComposingIndication'''::
1137 55 Adrian Georgescu
 Sent when a iscomposing payload is received.
1138 55 Adrian Georgescu
1139 55 Adrian Georgescu
1140 55 Adrian Georgescu
== FileTransferStream ==
1141 55 Adrian Georgescu
1142 55 Adrian Georgescu
Implemented in [browser:sipsimple/streams/msrp.py]
1143 57 Adrian Georgescu
1144 57 Adrian Georgescu
=== SDP Example ===
1145 57 Adrian Georgescu
1146 57 Adrian Georgescu
{{{
1147 57 Adrian Georgescu
Content-Type: application/sdp
1148 57 Adrian Georgescu
Content-Length:   383
1149 57 Adrian Georgescu
1150 57 Adrian Georgescu
v=0
1151 57 Adrian Georgescu
o=- 3467525166 3467525166 IN IP4 192.168.1.6
1152 57 Adrian Georgescu
s=blink-0.10.7-beta
1153 57 Adrian Georgescu
c=IN IP4 192.168.1.6
1154 57 Adrian Georgescu
t=0 0
1155 57 Adrian Georgescu
m=message 2855 TCP/TLS/MSRP *
1156 57 Adrian Georgescu
a=path:msrps://192.168.1.6:2855/e593357dc9abe90754bd;tcp
1157 57 Adrian Georgescu
a=sendonly
1158 57 Adrian Georgescu
a=accept-types:*
1159 57 Adrian Georgescu
a=accept-wrapped-types:*
1160 57 Adrian Georgescu
a=file-selector:name:"reblink.pdf" type:com.adobe.pdf size:268759 hash:sha1:60:A1:BE:8D:71:DB:E3:8E:84:C9:2C:62:9E:F2:99:78:9D:68:79:F6
1161 57 Adrian Georgescu
}}}
1162 55 Adrian Georgescu
1163 55 Adrian Georgescu
=== Methods ===
1164 55 Adrian Georgescu
=== Notifications ===
1165 55 Adrian Georgescu
1166 55 Adrian Georgescu
 '''FileTransferStreamDidDeliverChunk'''::
1167 55 Adrian Georgescu
 '''FileTransferStreamDidFinish'''::
1168 55 Adrian Georgescu
 '''FileTransferStreamDidNotDeliverChunk'''::
1169 55 Adrian Georgescu
 '''FileTransferStreamGotChunk'''::
1170 55 Adrian Georgescu
1171 55 Adrian Georgescu
== DesktopSharingStream ==
1172 55 Adrian Georgescu
1173 56 Adrian Georgescu
Implemented in [browser:sipsimple/streams/msrp.py]
1174 56 Adrian Georgescu
1175 1 Adrian Georgescu
There is no standard defining this usage but is fairly easy to implement in clients that already support MSRP. To traverse a NAT-ed router, a [http://msrprelay.org MSRP relay] configured for the called party domain is needed. Below is an example of the Session Description Protocol used for establishing a Desktop sharing session. 
1176 57 Adrian Georgescu
1177 56 Adrian Georgescu
=== SDP Example ===
1178 56 Adrian Georgescu
1179 56 Adrian Georgescu
{{{
1180 56 Adrian Georgescu
m=application 2855 TCP/TLS/MSRP *
1181 56 Adrian Georgescu
a=path:msrps://10.0.1.19:2855/b599b22d1b1d6a3324c8;tcp
1182 56 Adrian Georgescu
a=accept-types:application/x-rfb
1183 56 Adrian Georgescu
a=setup:active
1184 56 Adrian Georgescu
}}}
1185 56 Adrian Georgescu
1186 55 Adrian Georgescu
1187 55 Adrian Georgescu
=== Methods ===
1188 55 Adrian Georgescu
1189 55 Adrian Georgescu
=== Notifications ===
1190 55 Adrian Georgescu
1191 55 Adrian Georgescu
 '''DesktopSharingHandlerDidFail'''::
1192 61 Luci Stanescu
 '''DesktopSharingStreamGotData'''::
1193 61 Luci Stanescu
1194 61 Luci Stanescu
1195 61 Luci Stanescu
=== Route ===
1196 61 Luci Stanescu
1197 61 Luci Stanescu
This class provides a means for the application using the SIP core to set the destination address, port and transport for a particular request, i.e. the outbound proxy.
1198 61 Luci Stanescu
As it is the application's responsibility to look this up and pass it as an argument for every SIP primitive class it creates.
1199 61 Luci Stanescu
The contents of the {{{Route}}} object will be placed in the {{{Route}}} header of the request.
1200 61 Luci Stanescu
As with the {{{SIPURI}}} object, the attributes of this object are the same as the arguments to the {{{__init__}}} method.
1201 61 Luci Stanescu
1202 61 Luci Stanescu
==== methods ====
1203 61 Luci Stanescu
1204 61 Luci Stanescu
 '''!__init!__'''(''self'', '''address''', '''port'''=5060, '''transport'''={{{None}}})::
1205 61 Luci Stanescu
  Creates the Route object with the specified parameters as attributes.
1206 61 Luci Stanescu
  Each of these attributes can be accessed on the object once instanced.
1207 61 Luci Stanescu
  [[BR]]''address'':[[BR]]
1208 61 Luci Stanescu
  The IPv4 address that the request in question should be sent to as a string.
1209 61 Luci Stanescu
  [[BR]]''port'':[[BR]]
1210 61 Luci Stanescu
  The port to send the requests to, represented as an int.
1211 61 Luci Stanescu
  [[BR]]''transport'':[[BR]]
1212 61 Luci Stanescu
  The transport to use, this can be a string of either "udp", "tcp" or "tls" (case insensitive), depending on what transports are enabled on the {{{PJSIPUA}}} object.
1213 61 Luci Stanescu
 '''copy'''(''self'')::
1214 1 Adrian Georgescu
  Returns a copy of the {{{Route}}} object.