SipMiddlewareApi
Version 34 (Adrian Georgescu, 04/13/2009 11:07 am)
1 | 1 | Adrian Georgescu | = Middleware API = |
---|---|---|---|
2 | 1 | Adrian Georgescu | |
3 | 1 | Adrian Georgescu | [[TOC(WikiStart, Sip*, depth=3)]] |
4 | 1 | Adrian Georgescu | |
5 | 21 | 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 library. |
6 | 14 | Adrian Georgescu | |
7 | 25 | Adrian Georgescu | * To communicate with other sub-systems, the middleware uses the notification system provided by the [http://pypi.python.org/pypi/python-application python-application] package |
8 | 34 | Adrian Georgescu | * The middleware use the [wiki:SipConfigurationAPI configuration API] to access general and SIP account settings |
9 | 1 | Adrian Georgescu | |
10 | 33 | Adrian Georgescu | [[Image(sipsimple-middleware.png)]] |
11 | 1 | Adrian Georgescu | |
12 | 1 | Adrian Georgescu | == Classes == |
13 | 1 | Adrian Georgescu | |
14 | 1 | Adrian Georgescu | === Session === |
15 | 1 | Adrian Georgescu | |
16 | 1 | Adrian Georgescu | A {{{sipsimple.session.Session}}} object represents a complete SIP session between the local and a remote endpoints, including media streams. |
17 | 1 | Adrian Georgescu | The currently supported media streams are audio and MSRP chat. |
18 | 1 | Adrian Georgescu | Both incoming and outgoing sessions are represented by this class. |
19 | 1 | Adrian Georgescu | |
20 | 1 | Adrian Georgescu | 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. |
21 | 1 | Adrian Georgescu | State changes are triggered by methods called on the object by the application or by received network events. |
22 | 26 | Luci Stanescu | Every time this attribute changes, a {{{SIPSessionChangedState}}} notification is sent by the object. |
23 | 1 | Adrian Georgescu | These states and their transitions are represented in the following diagram: |
24 | 1 | Adrian Georgescu | |
25 | 2 | Adrian Georgescu | [[Image(sipsimple-session-state-machine.png)]] |
26 | 1 | Adrian Georgescu | |
27 | 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. |
28 | 1 | Adrian Georgescu | |
29 | 1 | Adrian Georgescu | ==== attributes ==== |
30 | 1 | Adrian Georgescu | |
31 | 1 | Adrian Georgescu | '''state''':: |
32 | 1 | Adrian Georgescu | The state the object is currently in, being one of the states from the diagram above. |
33 | 18 | Ruud Klaver | '''account''':: |
34 | 18 | Ruud Klaver | The {{{sipsimple.account.Account}}} or {{{sipsimple.account.BonjourAccount}}} object that the {{{Session}}} is associated with. |
35 | 18 | Ruud Klaver | On an outbound session, this is the account the application specified on object instantiation. |
36 | 1 | Adrian Georgescu | '''direction''':: |
37 | 1 | Adrian Georgescu | A string indicating the direction of the initial negotiation of the session. |
38 | 1 | Adrian Georgescu | This can be either {{{None}}}, "incoming" or "outgoing". |
39 | 1 | Adrian Georgescu | '''start_time''':: |
40 | 1 | Adrian Georgescu | The time the session started as a {{{datetime.datetime}}} object, or {{{None}}} if the session was not yet started. |
41 | 1 | Adrian Georgescu | '''stop_time''':: |
42 | 1 | Adrian Georgescu | The time the session stopped as a {{{datetime.datetime}}} object, or {{{None}}} if the session has not yet terminated. |
43 | 1 | Adrian Georgescu | '''on_hold_by_local''':: |
44 | 1 | Adrian Georgescu | Boolean indicating whether the session was put on hold by the local party. |
45 | 1 | Adrian Georgescu | '''on_hold_by_remote''':: |
46 | 1 | Adrian Georgescu | Boolean indicating whether the session was put on hold by the remote party. |
47 | 1 | Adrian Georgescu | '''on_hold''':: |
48 | 1 | Adrian Georgescu | Boolean indicating whether the session was put on hold, either by the local or the remote party. |
49 | 1 | Adrian Georgescu | '''remote_user_agent''':: |
50 | 1 | Adrian Georgescu | A string indicating the remote user agent, if it provided one. |
51 | 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). |
52 | 1 | Adrian Georgescu | '''local_uri''':: |
53 | 1 | Adrian Georgescu | The {{{sipsimple.core.SIPURI}}} of the local party, if the session is active. |
54 | 1 | Adrian Georgescu | '''remote_uri''':: |
55 | 1 | Adrian Georgescu | The {{{sipsimple.core.SIPURI}}} of the remote party, if the session is active. |
56 | 1 | Adrian Georgescu | '''caller_uri''':: |
57 | 1 | Adrian Georgescu | The {{{sipsimple.core.SIPURI}}} of the calling party, if the session is active. |
58 | 1 | Adrian Georgescu | Depending on the direction, this is either {{{local_uri}}} or {{{remote_uri}}}. |
59 | 1 | Adrian Georgescu | '''callee_uri''':: |
60 | 1 | Adrian Georgescu | The {{{sipsimple.core.SIPURI}}} of the called party, if the session is active. |
61 | 1 | Adrian Georgescu | Depending on the direction, this is either {{{local_uri}}} or {{{remote_uri}}}. |
62 | 1 | Adrian Georgescu | '''route''':: |
63 | 20 | Ruud Klaver | A copy of the {{{sipsimple.core.Route}}} object passed when the {{{connect()}}} method was called. |
64 | 1 | Adrian Georgescu | On incoming or inactive sessions this is {{{None}}}. |
65 | 1 | Adrian Georgescu | '''audio_transport''':: |
66 | 1 | Adrian Georgescu | The {{{sipsimple.core.AudioTransport}}} object used by the session, if it currently contains an audio stream. |
67 | 1 | Adrian Georgescu | Normally the application will not need to access this directly. |
68 | 1 | Adrian Georgescu | '''has_audio''':: |
69 | 23 | Ruud Klaver | A boolean indicating if this {{{Session}}} currently has an active audio stream. |
70 | 1 | Adrian Georgescu | '''audio_sample_rate''':: |
71 | 1 | Adrian Georgescu | If the audio stream was started, this attribute contains the sample rate of the audio negotiated. |
72 | 1 | Adrian Georgescu | '''audio_codec''':: |
73 | 1 | Adrian Georgescu | If the audio stream was started, this attribute contains the name of the audio codec that was negotiated. |
74 | 1 | Adrian Georgescu | '''audio_srtp_active''':: |
75 | 1 | Adrian Georgescu | If the audio stream was started, this boolean attribute indicates if SRTP is currently being used on the stream. |
76 | 1 | Adrian Georgescu | '''audio_local_rtp_address''':: |
77 | 1 | Adrian Georgescu | If an audio stream is present within the session, this attribute contains the local IP address used for the audio stream. |
78 | 1 | Adrian Georgescu | '''audio_local_rtp_port''':: |
79 | 1 | Adrian Georgescu | If an audio stream is present within the session, this attribute contains the local UDP port used for the audio stream. |
80 | 1 | Adrian Georgescu | '''audio_remote_rtp_address_sdp''':: |
81 | 1 | Adrian Georgescu | If the audio stream was started, this attribute contains the IP address that the remote party gave to send audio to. |
82 | 1 | Adrian Georgescu | '''audio_remote_rtp_port_sdp''':: |
83 | 1 | Adrian Georgescu | If the audio stream was started, this attribute contains the UDP port that the remote party gave to send audio to. |
84 | 1 | Adrian Georgescu | '''audio_remote_rtp_address_received''':: |
85 | 1 | Adrian Georgescu | If the audio stream was started, this attribute contains the remote IP address from which the audio stream is being received. |
86 | 1 | Adrian Georgescu | '''audio_remote_rtp_port_received''':: |
87 | 1 | Adrian Georgescu | If the audio stream was started, this attribute contains the remote UDP port from which the audio stream is being received. |
88 | 1 | Adrian Georgescu | '''audio_was_received''':: |
89 | 1 | Adrian Georgescu | This boolean property indicates if audio was actually received on the audio stream contained within this session. |
90 | 1 | Adrian Georgescu | '''audio_recording_file_name''':: |
91 | 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. |
92 | 1 | Adrian Georgescu | '''chat_transport''':: |
93 | 1 | Adrian Georgescu | The {{{sipsimple.msrp.MSRPChat}}} object used by the session as chat transport, if the session currently contains a chat stream. |
94 | 1 | Adrian Georgescu | Normally the application will not need to access this directly. |
95 | 1 | Adrian Georgescu | '''has_chat''':: |
96 | 23 | Ruud Klaver | A boolean property indicating if this {{{Session}}} currently has an active chat stream. |
97 | 1 | Adrian Georgescu | |
98 | 1 | Adrian Georgescu | ==== methods ==== |
99 | 1 | Adrian Georgescu | |
100 | 18 | Ruud Klaver | '''!__init!__'''(''self'', '''account'''):: |
101 | 1 | Adrian Georgescu | Creates a new {{{Session}}} object in the {{{NULL}}} state. |
102 | 19 | Ruud Klaver | [[BR]]''account'':[[BR]] |
103 | 19 | Ruud Klaver | The local account to be associated with this {{{Session}}}. |
104 | 19 | Ruud Klaver | '''connect'''(''self'', '''callee_uri''', '''routes''', '''audio'''={{{False}}}, '''chat'''={{{False}}}):: |
105 | 1 | Adrian Georgescu | 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. |
106 | 26 | Luci Stanescu | Before contacting the remote party, a {{{SIPSessionNewOutgoing}}} notification will be emitted. |
107 | 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}}}. |
108 | 26 | Luci Stanescu | Any time a ringing indication is received from the remote party, a {{{SIPSessionGotRingIndication}}} notification is sent. |
109 | 26 | Luci Stanescu | If the remote party accepted the session, a {{{SIPSessionWillStart}}} notification will be sent, followed by a {{{SIPSessionDidStart}}} notification when the session is actually established. |
110 | 1 | Adrian Georgescu | This method may only be called while in the {{{NULL}}} state. |
111 | 1 | Adrian Georgescu | [[BR]]''callee_uri'':[[BR]] |
112 | 1 | Adrian Georgescu | A {{{sipsimple.core.SIPURI}}} object representing the remote host to initiate the session to. |
113 | 19 | Ruud Klaver | [[BR]]''routes'':[[BR]] |
114 | 19 | Ruud Klaver | An iterable of {{{sipsimple.core.Route}}} objects, specifying the IP, port and transport to the outbound proxy. |
115 | 19 | Ruud Klaver | These routes will be tried in order, until one of them succeeds. |
116 | 1 | Adrian Georgescu | [[BR]]''audio'':[[BR]] |
117 | 1 | Adrian Georgescu | A boolean indicating whether an audio stream should be initially included in this session. |
118 | 1 | Adrian Georgescu | [[BR]]''chat'':[[BR]] |
119 | 1 | Adrian Georgescu | A boolean indicating whether a chat stream should be initially included in this session. |
120 | 19 | Ruud Klaver | '''accept'''(''self'', '''audio'''={{{False}}}, '''chat'''={{{False}}}):: |
121 | 1 | Adrian Georgescu | Calling this methods will accept an incoming session and move the state machine to the {{{ACCEPTING}}} state. |
122 | 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. |
123 | 26 | Luci Stanescu | After this method is called, {{{SIPSessionWillStart}}} followed by {{{SIPSessionDidStart}}} will be emitted, or {{{SIPSessionDidFail}}} followed by {{{SIPSessionDidEnd}}} on an error. |
124 | 1 | Adrian Georgescu | This method may only be called while in the {{{INCOMING}}} state. |
125 | 1 | Adrian Georgescu | [[BR]]''audio'':[[BR]] |
126 | 1 | Adrian Georgescu | A boolean indicating whether an audio stream should be accepted for this session. |
127 | 1 | Adrian Georgescu | Note that this may only be set to {{{True}}} if an audio stream was actually proposed by the remote party. |
128 | 1 | Adrian Georgescu | [[BR]]''chat'':[[BR]] |
129 | 1 | Adrian Georgescu | A boolean indicating whether a chat stream should be accepted for this session. |
130 | 1 | Adrian Georgescu | Note that this may only be set to {{{True}}} if a chat stream was actually proposed by the remote party. |
131 | 1 | Adrian Georgescu | '''reject'''(''self''):: |
132 | 1 | Adrian Georgescu | Reject an incoming session and move it to the {{{TERMINATING}}} state, which eventually leads to the {{{TERMINATED}}} state. |
133 | 26 | Luci Stanescu | Calling this method will cause the {{{Session}}} object to emit a {{{SIPSessionWillEnd}}} notification, followed by a {{{SIPSessionDidEnd}}} notification. |
134 | 1 | Adrian Georgescu | This method may only be called while in the {{{INCOMING}}} state. |
135 | 1 | Adrian Georgescu | '''hold'''(''self''):: |
136 | 1 | Adrian Georgescu | Put the session on hold. |
137 | 26 | Luci Stanescu | This will cause a {{{SIPGotHoldRequest}}} notification to be sent. |
138 | 1 | Adrian Georgescu | This method may only be called while in the {{{ESTABLISHED}}} state. |
139 | 1 | Adrian Georgescu | '''unhold'''(''self''):: |
140 | 1 | Adrian Georgescu | Take the session out of hold. |
141 | 26 | Luci Stanescu | This will cause a {{{SIPGotUnholdRequest}}} notification to be sent. |
142 | 1 | Adrian Georgescu | This method may only be called while in the {{{ESTABLISHED}}} state. |
143 | 19 | Ruud Klaver | '''start_recording_audio'''(''self'', '''file_name'''={{{None}}}):: |
144 | 1 | Adrian Georgescu | If an audio stream is present within this session, calling this method will record the audio to a {{{.wav}}} file. |
145 | 1 | Adrian Georgescu | Note that when the session is on hold, nothing will be recorded to the file. |
146 | 26 | Luci Stanescu | Right before starting the recording a {{{SIPSessionWillStartRecordingAudio}}} notification will be emitted, followed by a {{{SIPSessionDidStartRecordingAudio}}}. |
147 | 1 | Adrian Georgescu | This method may only be called while in the {{{ESTABLISHED}}} state. |
148 | 1 | Adrian Georgescu | [[BR]]''file_name'':[[BR]] |
149 | 1 | Adrian Georgescu | The name of the {{{.wav}}} file to record to. |
150 | 1 | Adrian Georgescu | If this is set to {{{None}}}, a default file name including the session participants and the timestamp will be generated. |
151 | 1 | Adrian Georgescu | '''stop_recording_audio'''(''self''):: |
152 | 1 | Adrian Georgescu | This will stop a previously started recording. |
153 | 26 | Luci Stanescu | Before stopping, a {{{SIPSessionWillStopRecordingAudio}}} notification will be sent, followed by a {{{SIPSessionDidStopRecordingAudio}}}. |
154 | 1 | Adrian Georgescu | This method may only be called while in the {{{ESTABLISHED}}} state. |
155 | 1 | Adrian Georgescu | '''send_dtmf'''(''self'', '''digit'''):: |
156 | 1 | Adrian Georgescu | If this session currently has an active audio stream, send a DTMF digit to the remote party over it. |
157 | 23 | Ruud Klaver | This method may only be called while in the {{{ESTABLISHED}}} state and if the session has an active audio stream. |
158 | 1 | Adrian Georgescu | [[BR]]''digit'':[[BR]] |
159 | 1 | Adrian Georgescu | This should a string of length 1, containing a valid DTMF digit value. |
160 | 13 | Luci Stanescu | '''send_message'''(''self'', '''content''', '''content_type'''="text/plain", '''to_uri'''={{{None}}}, '''dt'''={{{None}}}):: |
161 | 1 | Adrian Georgescu | If this session currently has an active MSRP chat with the remote party, send a message over with the with the specified parameters. |
162 | 26 | Luci Stanescu | This will result in either a {{{SIPSessionDidDeliverMessage}}} or a {{{SIPSessionDidNotDeliverMessage}}} notification being sent. |
163 | 1 | Adrian Georgescu | These notifications include a unique ID as data attribute which is also returned by this method. |
164 | 1 | Adrian Georgescu | This method may only be called while in the {{{ESTABLISHED}}} state. |
165 | 1 | Adrian Georgescu | [[BR]]''content'':[[BR]] |
166 | 1 | Adrian Georgescu | The body of the MSRP message as a string. |
167 | 1 | Adrian Georgescu | [[BR]]''content_type'':[[BR]] |
168 | 1 | Adrian Georgescu | The Content-Type of the body as a string |
169 | 22 | Ruud Klaver | [[BR]]''to_uri'':[[BR]] |
170 | 1 | Adrian Georgescu | The {{{sipsimple.core.SIPURI}}} that should be put in the {{{To:}}} header of the CPIM wrapper of the message. |
171 | 1 | Adrian Georgescu | This defaults to the SIP URI of the remote party of the session if the argument is set to {{{None}}} |
172 | 1 | Adrian Georgescu | [[BR]]''dt'':[[BR]] |
173 | 1 | Adrian Georgescu | A {{{datetime.datetime}}} object representing the timestamp to put on the CPIM wrapper of the message. |
174 | 1 | Adrian Georgescu | When set to {{{None}}}, this defaults to now. |
175 | 1 | Adrian Georgescu | '''add_audio'''(''self''):: |
176 | 1 | Adrian Georgescu | Propose the remote party to add an audio stream to this session. |
177 | 26 | Luci Stanescu | Calling this method will cause a {{{SIPSessionGotStreamProposal}}} notification to be emitted. |
178 | 26 | Luci Stanescu | 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. |
179 | 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. |
180 | 1 | Adrian Georgescu | '''remove_audio'''(''self''):: |
181 | 1 | Adrian Georgescu | Stop the audio stream currently active within the session and inform the remote party of this. |
182 | 1 | Adrian Georgescu | This method may only be called while in the {{{ESTABLISHED}}} state on a {{{Session}}} object that has an audio stream. |
183 | 1 | Adrian Georgescu | '''add_chat'''(''self''):: |
184 | 1 | Adrian Georgescu | Propose the remote party to add a chat stream to this session. |
185 | 26 | Luci Stanescu | Calling this method will cause a {{{SIPSessionGotStreamProposal}}} notification to be emitted. |
186 | 26 | Luci Stanescu | 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. |
187 | 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. |
188 | 1 | Adrian Georgescu | '''remove_chat'''(''self''):: |
189 | 1 | Adrian Georgescu | Stop the chat stream currently active within the session and inform the remote party of this. |
190 | 1 | Adrian Georgescu | This method may only be called while in the {{{ESTABLISHED}}} state on a {{{Session}}} object that has a chat stream. |
191 | 19 | Ruud Klaver | '''accept_proposal'''(''self'', '''audio'''={{{False}}}, '''chat'''={{{False}}}):: |
192 | 26 | Luci Stanescu | 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. |
193 | 26 | Luci Stanescu | 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. |
194 | 1 | Adrian Georgescu | This method may only be called while in the {{{PROPOSED}}} state. |
195 | 19 | Ruud Klaver | [[BR]]''audio'':[[BR]] |
196 | 19 | Ruud Klaver | A boolean indicating whether an audio stream should be accepted for this proposal. |
197 | 19 | Ruud Klaver | Note that this may only be set to {{{True}}} if an audio stream was actually proposed by the remote party. |
198 | 19 | Ruud Klaver | [[BR]]''chat'':[[BR]] |
199 | 19 | Ruud Klaver | A boolean indicating whether a chat stream should be accepted for this proposal. |
200 | 19 | Ruud Klaver | Note that this may only be set to {{{True}}} if a chat stream was actually proposed by the remote party. |
201 | 1 | Adrian Georgescu | '''reject_proposal'''(''self''):: |
202 | 26 | Luci Stanescu | 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. |
203 | 1 | Adrian Georgescu | This method may only be called while in the {{{PROPOSED}}} state. |
204 | 23 | Ruud Klaver | '''end'''(''self''):: |
205 | 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. |
206 | 26 | Luci Stanescu | Right before termination a {{{SIPSessionWillEnd}}} notification is sent, after termination {{{SIPSessionDidEnd}}} is sent. |
207 | 1 | Adrian Georgescu | |
208 | 1 | Adrian Georgescu | ==== notifications ==== |
209 | 1 | Adrian Georgescu | |
210 | 26 | Luci Stanescu | '''SIPSessionChangedState''':: |
211 | 1 | Adrian Georgescu | Will be sent whenever the {{{Session}}} object changes its state. |
212 | 1 | Adrian Georgescu | [[BR]]''timestamp'':[[BR]] |
213 | 1 | Adrian Georgescu | A {{{datetime.datetime}}} object indicating when the notification was sent. |
214 | 1 | Adrian Georgescu | [[BR]]''prev_state'':[[BR]] |
215 | 1 | Adrian Georgescu | The previous state state the object was in. |
216 | 1 | Adrian Georgescu | [[BR]]''state'':[[BR]] |
217 | 1 | Adrian Georgescu | The new state the object is in. |
218 | 26 | Luci Stanescu | '''SIPSessionNewIncoming''':: |
219 | 1 | Adrian Georgescu | Will be sent when a new incoming {{{Session}}} is received. |
220 | 1 | Adrian Georgescu | The application should listen for this notification from all objects specifically to get informed of incoming sessions. |
221 | 1 | Adrian Georgescu | [[BR]]''timestamp'':[[BR]] |
222 | 1 | Adrian Georgescu | A {{{datetime.datetime}}} object indicating when the notification was sent. |
223 | 19 | Ruud Klaver | [[BR]]''streams'':[[BR]] |
224 | 19 | Ruud Klaver | A list of strings indicating the streams that were proposed by the remote party. |
225 | 26 | Luci Stanescu | '''SIPSessionNewOutgoing''':: |
226 | 1 | Adrian Georgescu | Will be sent when the applcation requests a new outgoing {{{Session}}}. |
227 | 1 | Adrian Georgescu | [[BR]]''timestamp'':[[BR]] |
228 | 1 | Adrian Georgescu | A {{{datetime.datetime}}} object indicating when the notification was sent. |
229 | 19 | Ruud Klaver | [[BR]]''streams'':[[BR]] |
230 | 32 | Adrian Georgescu | A list of strings indicating the streams that were proposed to the remote party. |
231 | 26 | Luci Stanescu | '''SIPSessionGotRingIndication''':: |
232 | 1 | Adrian Georgescu | Will be sent when an outgoing {{{Session}}} receives an indication that a remote device is ringing. |
233 | 1 | Adrian Georgescu | [[BR]]''timestamp'':[[BR]] |
234 | 1 | Adrian Georgescu | A {{{datetime.datetime}}} object indicating when the notification was sent. |
235 | 26 | Luci Stanescu | '''SIPSessionWillStart''':: |
236 | 1 | Adrian Georgescu | Will be sent just before a {{{Session}}} completes negotiation. |
237 | 1 | Adrian Georgescu | In terms of SIP, this is sent after the final response to the {{{INVITE}}}, but before the {{{ACK}}}. |
238 | 1 | Adrian Georgescu | [[BR]]''timestamp'':[[BR]] |
239 | 1 | Adrian Georgescu | A {{{datetime.datetime}}} object indicating when the notification was sent. |
240 | 26 | Luci Stanescu | '''SIPSessionDidStart''':: |
241 | 1 | Adrian Georgescu | Will be sent when a {{{Session}}} completes negotiation. |
242 | 1 | Adrian Georgescu | In terms of SIP this is sent after the {{{ACK}}} was sent or received. |
243 | 1 | Adrian Georgescu | [[BR]]''timestamp'':[[BR]] |
244 | 1 | Adrian Georgescu | A {{{datetime.datetime}}} object indicating when the notification was sent. |
245 | 26 | Luci Stanescu | '''SIPSessionDidFail''':: |
246 | 1 | Adrian Georgescu | This notification is sent whenever the session fails. |
247 | 1 | Adrian Georgescu | The failure reason is included in the data attributes. |
248 | 26 | Luci Stanescu | This notification is always followed by {{{SIPSessionDidEnd}}}. |
249 | 1 | Adrian Georgescu | [[BR]]''timestamp'':[[BR]] |
250 | 1 | Adrian Georgescu | A {{{datetime.datetime}}} object indicating when the notification was sent. |
251 | 1 | Adrian Georgescu | [[BR]]''originator'':[[BR]] |
252 | 1 | Adrian Georgescu | A string indicating the origin of the failure. |
253 | 1 | Adrian Georgescu | This will either be "local" or "remote". |
254 | 1 | Adrian Georgescu | [[BR]]''code'':[[BR]] |
255 | 1 | Adrian Georgescu | The SIP error code of the failure. |
256 | 1 | Adrian Georgescu | If this is 0, the error was an internal exception. |
257 | 1 | Adrian Georgescu | [[BR]]''reason'':[[BR]] |
258 | 1 | Adrian Georgescu | A string explaining the reason of the failure. |
259 | 26 | Luci Stanescu | '''SIPSessionWillEnd''':: |
260 | 1 | Adrian Georgescu | Will be sent just before terminating a {{{Session}}} at the request of the application. |
261 | 1 | Adrian Georgescu | [[BR]]''timestamp'':[[BR]] |
262 | 1 | Adrian Georgescu | A {{{datetime.datetime}}} object indicating when the notification was sent. |
263 | 26 | Luci Stanescu | '''SIPSessionDidEnd''':: |
264 | 26 | Luci Stanescu | 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. |
265 | 1 | Adrian Georgescu | [[BR]]''timestamp'':[[BR]] |
266 | 1 | Adrian Georgescu | A {{{datetime.datetime}}} object indicating when the notification was sent. |
267 | 1 | Adrian Georgescu | [[BR]]''originator'':[[BR]] |
268 | 1 | Adrian Georgescu | A string indicating who originated the termination. |
269 | 1 | Adrian Georgescu | This will either be "local" or "remote". |
270 | 26 | Luci Stanescu | '''SIPSessionGotHoldRequest''':: |
271 | 1 | Adrian Georgescu | Will be sent when the session got put on hold, either by the local or the remote party. |
272 | 1 | Adrian Georgescu | [[BR]]''timestamp'':[[BR]] |
273 | 1 | Adrian Georgescu | A {{{datetime.datetime}}} object indicating when the notification was sent. |
274 | 1 | Adrian Georgescu | [[BR]]''originator'':[[BR]] |
275 | 1 | Adrian Georgescu | A string indicating who originated the hold request, and consequently in which direction the session got put on hold. |
276 | 26 | Luci Stanescu | '''SIPSessionGotUnholdRequest''':: |
277 | 1 | Adrian Georgescu | Will be sent when the session got taken out of hold, either by the local or the remote party. |
278 | 1 | Adrian Georgescu | [[BR]]''timestamp'':[[BR]] |
279 | 1 | Adrian Georgescu | A {{{datetime.datetime}}} object indicating when the notification was sent. |
280 | 1 | Adrian Georgescu | [[BR]]''originator'':[[BR]] |
281 | 1 | Adrian Georgescu | A string indicating who sent the original hold request, and consequently in which direction the session got taken out of hold. |
282 | 26 | Luci Stanescu | '''SIPSessionWillStartRecordingAudio''':: |
283 | 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. |
284 | 1 | Adrian Georgescu | [[BR]]''timestamp'':[[BR]] |
285 | 1 | Adrian Georgescu | A {{{datetime.datetime}}} object indicating when the notification was sent. |
286 | 1 | Adrian Georgescu | [[BR]]''file_name'':[[BR]] |
287 | 1 | Adrian Georgescu | The name of the recording {{{.wav}}} file, including full path. |
288 | 26 | Luci Stanescu | '''SIPSessionDidStartRecordingAudio''':: |
289 | 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. |
290 | 1 | Adrian Georgescu | [[BR]]''timestamp'':[[BR]] |
291 | 1 | Adrian Georgescu | A {{{datetime.datetime}}} object indicating when the notification was sent. |
292 | 1 | Adrian Georgescu | [[BR]]''file_name'':[[BR]] |
293 | 1 | Adrian Georgescu | The name of the recording {{{.wav}}} file, including full path. |
294 | 26 | Luci Stanescu | '''SIPSessionWillStopRecordingAudio''':: |
295 | 1 | Adrian Georgescu | Will be sent when the application requested ending the recording to a {{{.wav}}} file, just before recording stops. |
296 | 1 | Adrian Georgescu | [[BR]]''timestamp'':[[BR]] |
297 | 1 | Adrian Georgescu | A {{{datetime.datetime}}} object indicating when the notification was sent. |
298 | 1 | Adrian Georgescu | [[BR]]''file_name'':[[BR]] |
299 | 1 | Adrian Georgescu | The name of the recording {{{.wav}}} file, including full path. |
300 | 26 | Luci Stanescu | '''SIPSessionDidStopRecordingAudio''':: |
301 | 1 | Adrian Georgescu | Will be sent when the application requested ending the recording to a {{{.wav}}} file, just before recording stops. |
302 | 1 | Adrian Georgescu | [[BR]]''timestamp'':[[BR]] |
303 | 1 | Adrian Georgescu | A {{{datetime.datetime}}} object indicating when the notification was sent. |
304 | 1 | Adrian Georgescu | [[BR]]''file_name'':[[BR]] |
305 | 1 | Adrian Georgescu | The name of the recording {{{.wav}}} file, including full path. |
306 | 26 | Luci Stanescu | '''SIPSessionGotNoAudio''':: |
307 | 1 | Adrian Georgescu | This notification will be sent if 5 seconds after the audio stream starts, no audio was received from the remote party. |
308 | 1 | Adrian Georgescu | [[BR]]''timestamp'':[[BR]] |
309 | 1 | Adrian Georgescu | A {{{datetime.datetime}}} object indicating when the notification was sent. |
310 | 26 | Luci Stanescu | '''SIPSessionGotDTMF''':: |
311 | 1 | Adrian Georgescu | Will be send if there is a DMTF digit received from the remote party on the audio stream. |
312 | 1 | Adrian Georgescu | [[BR]]''timestamp'':[[BR]] |
313 | 1 | Adrian Georgescu | A {{{datetime.datetime}}} object indicating when the notification was sent. |
314 | 1 | Adrian Georgescu | [[BR]]''digit'':[[BR]] |
315 | 1 | Adrian Georgescu | The DTMF digit that was received, in the form of a string of length 1. |
316 | 26 | Luci Stanescu | '''SIPSessionGotMessage''':: |
317 | 1 | Adrian Georgescu | Will be sent whenever a MSRP message is received on the chat stream of the session. |
318 | 1 | Adrian Georgescu | [[BR]]''content'':[[BR]] |
319 | 1 | Adrian Georgescu | The body of the message. |
320 | 1 | Adrian Georgescu | [[BR]]''content_type'':[[BR]] |
321 | 1 | Adrian Georgescu | The Content-Type of the body. |
322 | 1 | Adrian Georgescu | [[BR]]''cpim_headers'':[[BR]] |
323 | 1 | Adrian Georgescu | A dictionary of headers included in the CPIM wrapper. |
324 | 1 | Adrian Georgescu | [[BR]]''message'':[[BR]] |
325 | 5 | Redmine Admin | Raw MSRP message, an msrplib.protocol.MSRPData instance |
326 | 26 | Luci Stanescu | '''SIPSessionDidDeliverMessage''':: |
327 | 1 | Adrian Georgescu | Will be sent when a previously sent MSRP chat message got delivered to the remote party. |
328 | 1 | Adrian Georgescu | [[BR]]''message_id'':[[BR]] |
329 | 1 | Adrian Georgescu | The unique identifier of this message as a string, as previously returned by the {{{send_message()}}} method. |
330 | 1 | Adrian Georgescu | [[BR]]''code'':[[BR]] |
331 | 1 | Adrian Georgescu | The response code of the confirmation report. |
332 | 1 | Adrian Georgescu | [[BR]]''reason'':[[BR]] |
333 | 5 | Redmine Admin | The reason string of the confirmation report. |
334 | 1 | Adrian Georgescu | [[BR]]''message'':[[BR]] |
335 | 1 | Adrian Georgescu | Raw MSRP message, an msrplib.protocol.MSRPData instance |
336 | 26 | Luci Stanescu | '''SIPSessionDidDeliverMessage''':: |
337 | 1 | Adrian Georgescu | Will be sent when a previously sent MSRP chat message did not get delivered to the remote party. |
338 | 1 | Adrian Georgescu | [[BR]]''message_id'':[[BR]] |
339 | 1 | Adrian Georgescu | The unique identifier of this message as a string, as previously returned by the {{{send_message()}}} method. |
340 | 1 | Adrian Georgescu | [[BR]]''code'':[[BR]] |
341 | 1 | Adrian Georgescu | The response code of the confirmation report. |
342 | 1 | Adrian Georgescu | [[BR]]''reason'':[[BR]] |
343 | 5 | Redmine Admin | The reason string of the confirmation report. |
344 | 1 | Adrian Georgescu | [[BR]]''message'':[[BR]] |
345 | 1 | Adrian Georgescu | Raw MSRP message, an msrplib.protocol.MSRPData instance |
346 | 26 | Luci Stanescu | '''SIPSessionGotStreamProposal''':: |
347 | 1 | Adrian Georgescu | Will be sent when either the local or the remote party proposes to add a stream to the session. |
348 | 1 | Adrian Georgescu | [[BR]]''timestamp'':[[BR]] |
349 | 1 | Adrian Georgescu | A {{{datetime.datetime}}} object indicating when the notification was sent. |
350 | 1 | Adrian Georgescu | [[BR]]''proposer'':[[BR]] |
351 | 1 | Adrian Georgescu | The party that did the stream proposal, can be either "local" or "remote". |
352 | 19 | Ruud Klaver | [[BR]]''streams'':[[BR]] |
353 | 19 | Ruud Klaver | A list of strings indicating the streams that were proposed. |
354 | 26 | Luci Stanescu | '''SIPSessionRejectedStreamProposal''':: |
355 | 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. |
356 | 1 | Adrian Georgescu | [[BR]]''timestamp'':[[BR]] |
357 | 1 | Adrian Georgescu | A {{{datetime.datetime}}} object indicating when the notification was sent. |
358 | 1 | Adrian Georgescu | [[BR]]''proposer'':[[BR]] |
359 | 1 | Adrian Georgescu | The party that did the stream proposal, can be either "local" or "remote". |
360 | 1 | Adrian Georgescu | [[BR]]''reason'':[[BR]] |
361 | 1 | Adrian Georgescu | The reason for rejecting the stream proposal. |
362 | 1 | Adrian Georgescu | '''SIPSessionRejectedStreamProposal''':: |
363 | 26 | Luci Stanescu | Will be sent when either the local or the remote party accepts a proposal to have (a) stream(s) added to the session. |
364 | 1 | Adrian Georgescu | [[BR]]''timestamp'':[[BR]] |
365 | 1 | Adrian Georgescu | A {{{datetime.datetime}}} object indicating when the notification was sent. |
366 | 1 | Adrian Georgescu | [[BR]]''proposer'':[[BR]] |
367 | 1 | Adrian Georgescu | The party that did the stream proposal, can be either "local" or "remote". |
368 | 1 | Adrian Georgescu | '''SIPSessionGotStreamUpdate''':: |
369 | 26 | Luci Stanescu | Will be sent when a media stream is either activated or deactivated. |
370 | 23 | Ruud Klaver | An application should listen to this notification in order to know when a media stream can be used. |
371 | 23 | Ruud Klaver | [[BR]]''timestamp'':[[BR]] |
372 | 23 | Ruud Klaver | A {{{datetime.datetime}}} object indicating when the notification was sent. |
373 | 23 | Ruud Klaver | [[BR]]''streams'':[[BR]] |
374 | 23 | Ruud Klaver | A list indicating which streams are active on the session from this point onwards. |
375 | 23 | Ruud Klaver | |
376 | 30 | Adrian Georgescu | As an example for how to use the {{{Session}}} object, the following provides a basic Python program that initiates an outgoing SIP session request: |
377 | 6 | Ruud Klaver | |
378 | 6 | Ruud Klaver | {{{ |
379 | 24 | Ruud Klaver | import sys |
380 | 6 | Ruud Klaver | from threading import Event |
381 | 6 | Ruud Klaver | from zope.interface import implements |
382 | 6 | Ruud Klaver | from application.notification import IObserver, NotificationCenter |
383 | 1 | Adrian Georgescu | |
384 | 24 | Ruud Klaver | from sipsimple.configuration import ConfigurationManager |
385 | 24 | Ruud Klaver | from sipsimple.account import AccountManager |
386 | 24 | Ruud Klaver | from sipsimple.engine import Engine |
387 | 24 | Ruud Klaver | from sipsimple.session import Session |
388 | 24 | Ruud Klaver | from sipsimple.core import SIPURI, Route |
389 | 24 | Ruud Klaver | |
390 | 1 | Adrian Georgescu | class SimpleOutboundCall(object): |
391 | 1 | Adrian Georgescu | # indicate that we implement the application.notification.IObserver interface |
392 | 1 | Adrian Georgescu | implements(IObserver) |
393 | 1 | Adrian Georgescu | |
394 | 24 | Ruud Klaver | def __init__(self, remote_uri, route): |
395 | 1 | Adrian Georgescu | # setup a threading.Event to signal that the Engine has stopped |
396 | 1 | Adrian Georgescu | self.engine_ended_event = Event() |
397 | 24 | Ruud Klaver | # start the configuration manager |
398 | 24 | Ruud Klaver | ConfigurationManager().start() |
399 | 24 | Ruud Klaver | # start the account manager |
400 | 24 | Ruud Klaver | am = AccountManager() |
401 | 24 | Ruud Klaver | am.start() |
402 | 24 | Ruud Klaver | # start the Engine with configuration framework parameters |
403 | 24 | Ruud Klaver | Engine().start_cfg() |
404 | 24 | Ruud Klaver | # create a new Session using the default account |
405 | 24 | Ruud Klaver | self.session = Session(am.default_account) |
406 | 6 | Ruud Klaver | # listen for the notification that the Engine stopped |
407 | 26 | Luci Stanescu | NotificationCenter().add_observer(self, "SIPEngineDidEnd", Engine()) |
408 | 6 | Ruud Klaver | # listen for the notification that the Session ended |
409 | 26 | Luci Stanescu | NotificationCenter().add_observer(self, "SIPSessionDidEnd", self.session) |
410 | 6 | Ruud Klaver | # start a new outbound session |
411 | 24 | Ruud Klaver | self.session.connect(remote_uri, [route], audio=True) |
412 | 6 | Ruud Klaver | |
413 | 23 | Ruud Klaver | def end(self): |
414 | 6 | Ruud Klaver | # if the Session is still active, terminate it |
415 | 6 | Ruud Klaver | self.session.end() |
416 | 6 | Ruud Klaver | # wait for the engine to stop, processed in handle_notification |
417 | 6 | Ruud Klaver | self.engine_ended_event.wait() |
418 | 6 | Ruud Klaver | # quit the progam, as this can only be done from the main thread |
419 | 6 | Ruud Klaver | sys.exit() |
420 | 6 | Ruud Klaver | |
421 | 1 | Adrian Georgescu | def handle_notification(self, notification): |
422 | 1 | Adrian Georgescu | if notification.name == "SIPSessionDidEnd": |
423 | 1 | Adrian Georgescu | # if for whatever reason the session ended, stop the Engine |
424 | 1 | Adrian Georgescu | print "Session ended" |
425 | 1 | Adrian Georgescu | Engine().stop() |
426 | 1 | Adrian Georgescu | elif notification.name == "SIPEngineDidEnd": |
427 | 1 | Adrian Georgescu | # once the Engine has stopped, signal the (possibly) waiting main |
428 | 1 | Adrian Georgescu | # thread through a threading.Event |
429 | 1 | Adrian Georgescu | self.engine_ended_event.set() |
430 | 1 | Adrian Georgescu | |
431 | 1 | Adrian Georgescu | # place an audio call from the specified account to the specified URI, through |
432 | 1 | Adrian Georgescu | # the specified SIP proxy |
433 | 1 | Adrian Georgescu | # edit this to reflect real settings |
434 | 1 | Adrian Georgescu | call = SimpleOutboundCall(SIPURI(user="bob", host="example.com"), Route("1.2.3.4")) |
435 | 1 | Adrian Georgescu | # block waiting for user input |
436 | 1 | Adrian Georgescu | print "Placing call, press enter to quit program" |
437 | 1 | Adrian Georgescu | raw_input() |
438 | 1 | Adrian Georgescu | # block in end() until the Engine has stopped |
439 | 26 | Luci Stanescu | call.end() |
440 | 6 | Ruud Klaver | }}} |
441 | 30 | Adrian Georgescu | |
442 | 30 | Adrian Georgescu | === SessionManager === |
443 | 30 | Adrian Georgescu | |
444 | 31 | Adrian Georgescu | The {{{sipsimple.session.SessionManager}}} class is a singleton, which acts as the central aggregation point for sessions within the middleware. |
445 | 30 | Adrian Georgescu | Although it is mainly used internally, the application can use it to query information about all active sessions. |
446 | 30 | Adrian Georgescu | The SessionManager is implemented as a singleton, meaning that only one instance of this class exists within the middleware. |
447 | 30 | Adrian Georgescu | Note that, in order to be able to receive calls, the application has to instantiate this object. |
448 | 30 | Adrian Georgescu | |
449 | 30 | Adrian Georgescu | ==== attributes ==== |
450 | 30 | Adrian Georgescu | |
451 | 30 | Adrian Georgescu | '''sessions''':: |
452 | 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. |
453 | 30 | Adrian Georgescu | |
454 | 30 | Adrian Georgescu | ==== methods ==== |
455 | 30 | Adrian Georgescu | |
456 | 30 | Adrian Georgescu | '''!__init!__'''(''self''):: |
457 | 30 | Adrian Georgescu | This either returns a new {{{SessionManager}}} object with default configuration objects, or returns a copy of the already existing instance. |