SipMiddlewareApi » History » Version 34
Adrian Georgescu, 04/13/2009 11:07 AM
| 1 | 1 | Adrian Georgescu | = Middleware API = |
|---|---|---|---|
| 2 | |||
| 3 | [[TOC(WikiStart, Sip*, depth=3)]] |
||
| 4 | |||
| 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 | == Classes == |
||
| 13 | |||
| 14 | === Session === |
||
| 15 | |||
| 16 | A {{{sipsimple.session.Session}}} object represents a complete SIP session between the local and a remote endpoints, including media streams. |
||
| 17 | The currently supported media streams are audio and MSRP chat. |
||
| 18 | Both incoming and outgoing sessions are represented by this class. |
||
| 19 | |||
| 20 | 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 | 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 | |||
| 25 | 2 | Adrian Georgescu | [[Image(sipsimple-session-state-machine.png)]] |
| 26 | 1 | Adrian Georgescu | |
| 27 | 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 | |||
| 29 | ==== attributes ==== |
||
| 30 | |||
| 31 | '''state''':: |
||
| 32 | The state the object is currently in, being one of the states from the diagram above. |
||
| 33 | 18 | Ruud Klaver | '''account''':: |
| 34 | The {{{sipsimple.account.Account}}} or {{{sipsimple.account.BonjourAccount}}} object that the {{{Session}}} is associated with. |
||
| 35 | On an outbound session, this is the account the application specified on object instantiation. |
||
| 36 | 1 | Adrian Georgescu | '''direction''':: |
| 37 | A string indicating the direction of the initial negotiation of the session. |
||
| 38 | This can be either {{{None}}}, "incoming" or "outgoing". |
||
| 39 | '''start_time''':: |
||
| 40 | The time the session started as a {{{datetime.datetime}}} object, or {{{None}}} if the session was not yet started. |
||
| 41 | '''stop_time''':: |
||
| 42 | The time the session stopped as a {{{datetime.datetime}}} object, or {{{None}}} if the session has not yet terminated. |
||
| 43 | '''on_hold_by_local''':: |
||
| 44 | Boolean indicating whether the session was put on hold by the local party. |
||
| 45 | '''on_hold_by_remote''':: |
||
| 46 | Boolean indicating whether the session was put on hold by the remote party. |
||
| 47 | '''on_hold''':: |
||
| 48 | Boolean indicating whether the session was put on hold, either by the local or the remote party. |
||
| 49 | '''remote_user_agent''':: |
||
| 50 | A string indicating the remote user agent, if it provided one. |
||
| 51 | 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 | '''local_uri''':: |
||
| 53 | The {{{sipsimple.core.SIPURI}}} of the local party, if the session is active. |
||
| 54 | '''remote_uri''':: |
||
| 55 | The {{{sipsimple.core.SIPURI}}} of the remote party, if the session is active. |
||
| 56 | '''caller_uri''':: |
||
| 57 | The {{{sipsimple.core.SIPURI}}} of the calling party, if the session is active. |
||
| 58 | Depending on the direction, this is either {{{local_uri}}} or {{{remote_uri}}}. |
||
| 59 | '''callee_uri''':: |
||
| 60 | The {{{sipsimple.core.SIPURI}}} of the called party, if the session is active. |
||
| 61 | Depending on the direction, this is either {{{local_uri}}} or {{{remote_uri}}}. |
||
| 62 | '''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 | '''audio_transport''':: |
||
| 66 | The {{{sipsimple.core.AudioTransport}}} object used by the session, if it currently contains an audio stream. |
||
| 67 | Normally the application will not need to access this directly. |
||
| 68 | '''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 | If the audio stream was started, this attribute contains the sample rate of the audio negotiated. |
||
| 72 | '''audio_codec''':: |
||
| 73 | If the audio stream was started, this attribute contains the name of the audio codec that was negotiated. |
||
| 74 | '''audio_srtp_active''':: |
||
| 75 | If the audio stream was started, this boolean attribute indicates if SRTP is currently being used on the stream. |
||
| 76 | '''audio_local_rtp_address''':: |
||
| 77 | If an audio stream is present within the session, this attribute contains the local IP address used for the audio stream. |
||
| 78 | '''audio_local_rtp_port''':: |
||
| 79 | If an audio stream is present within the session, this attribute contains the local UDP port used for the audio stream. |
||
| 80 | '''audio_remote_rtp_address_sdp''':: |
||
| 81 | If the audio stream was started, this attribute contains the IP address that the remote party gave to send audio to. |
||
| 82 | '''audio_remote_rtp_port_sdp''':: |
||
| 83 | If the audio stream was started, this attribute contains the UDP port that the remote party gave to send audio to. |
||
| 84 | '''audio_remote_rtp_address_received''':: |
||
| 85 | If the audio stream was started, this attribute contains the remote IP address from which the audio stream is being received. |
||
| 86 | '''audio_remote_rtp_port_received''':: |
||
| 87 | If the audio stream was started, this attribute contains the remote UDP port from which the audio stream is being received. |
||
| 88 | '''audio_was_received''':: |
||
| 89 | This boolean property indicates if audio was actually received on the audio stream contained within this session. |
||
| 90 | '''audio_recording_file_name''':: |
||
| 91 | If the audio stream is currently being recorded to disk, this property contains the name of the {{{.wav}}} file being recorded to. |
||
| 92 | '''chat_transport''':: |
||
| 93 | The {{{sipsimple.msrp.MSRPChat}}} object used by the session as chat transport, if the session currently contains a chat stream. |
||
| 94 | Normally the application will not need to access this directly. |
||
| 95 | '''has_chat''':: |
||
| 96 | 23 | Ruud Klaver | A boolean property indicating if this {{{Session}}} currently has an active chat stream. |
| 97 | 1 | Adrian Georgescu | |
| 98 | ==== methods ==== |
||
| 99 | |||
| 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 | The local account to be associated with this {{{Session}}}. |
||
| 104 | '''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 | If there is a failure or the remote party rejected the offer, a {{{SIPSessionDidFail}}} notification will be sent, followed by a {{{SIPSessionDidEnd}}}. |
||
| 108 | Any time a ringing indication is received from the remote party, a {{{SIPSessionGotRingIndication}}} notification is sent. |
||
| 109 | 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 | [[BR]]''callee_uri'':[[BR]] |
||
| 112 | A {{{sipsimple.core.SIPURI}}} object representing the remote host to initiate the session to. |
||
| 113 | 19 | Ruud Klaver | [[BR]]''routes'':[[BR]] |
| 114 | An iterable of {{{sipsimple.core.Route}}} objects, specifying the IP, port and transport to the outbound proxy. |
||
| 115 | These routes will be tried in order, until one of them succeeds. |
||
| 116 | 1 | Adrian Georgescu | [[BR]]''audio'':[[BR]] |
| 117 | A boolean indicating whether an audio stream should be initially included in this session. |
||
| 118 | [[BR]]''chat'':[[BR]] |
||
| 119 | 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 | 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 | [[BR]]''audio'':[[BR]] |
||
| 126 | A boolean indicating whether an audio stream should be accepted for this session. |
||
| 127 | Note that this may only be set to {{{True}}} if an audio stream was actually proposed by the remote party. |
||
| 128 | [[BR]]''chat'':[[BR]] |
||
| 129 | A boolean indicating whether a chat stream should be accepted for this session. |
||
| 130 | Note that this may only be set to {{{True}}} if a chat stream was actually proposed by the remote party. |
||
| 131 | '''reject'''(''self''):: |
||
| 132 | 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 | '''hold'''(''self''):: |
||
| 136 | 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 | '''unhold'''(''self''):: |
||
| 140 | 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 | 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 | [[BR]]''file_name'':[[BR]] |
||
| 149 | The name of the {{{.wav}}} file to record to. |
||
| 150 | If this is set to {{{None}}}, a default file name including the session participants and the timestamp will be generated. |
||
| 151 | '''stop_recording_audio'''(''self''):: |
||
| 152 | 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 | '''send_dtmf'''(''self'', '''digit'''):: |
||
| 156 | 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 | 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 | This method may only be called while in the {{{ESTABLISHED}}} state. |
||
| 165 | [[BR]]''content'':[[BR]] |
||
| 166 | The body of the MSRP message as a string. |
||
| 167 | [[BR]]''content_type'':[[BR]] |
||
| 168 | 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 | This defaults to the SIP URI of the remote party of the session if the argument is set to {{{None}}} |
||
| 172 | [[BR]]''dt'':[[BR]] |
||
| 173 | A {{{datetime.datetime}}} object representing the timestamp to put on the CPIM wrapper of the message. |
||
| 174 | When set to {{{None}}}, this defaults to now. |
||
| 175 | '''add_audio'''(''self''):: |
||
| 176 | 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 | 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 | '''remove_audio'''(''self''):: |
||
| 181 | Stop the audio stream currently active within the session and inform the remote party of this. |
||
| 182 | This method may only be called while in the {{{ESTABLISHED}}} state on a {{{Session}}} object that has an audio stream. |
||
| 183 | '''add_chat'''(''self''):: |
||
| 184 | 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 | 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 | '''remove_chat'''(''self''):: |
||
| 189 | Stop the chat stream currently active within the session and inform the remote party of this. |
||
| 190 | 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 | 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 | A boolean indicating whether an audio stream should be accepted for this proposal. |
||
| 197 | Note that this may only be set to {{{True}}} if an audio stream was actually proposed by the remote party. |
||
| 198 | [[BR]]''chat'':[[BR]] |
||
| 199 | A boolean indicating whether a chat stream should be accepted for this proposal. |
||
| 200 | 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 | ==== notifications ==== |
||
| 209 | |||
| 210 | 26 | Luci Stanescu | '''SIPSessionChangedState''':: |
| 211 | 1 | Adrian Georgescu | Will be sent whenever the {{{Session}}} object changes its state. |
| 212 | [[BR]]''timestamp'':[[BR]] |
||
| 213 | A {{{datetime.datetime}}} object indicating when the notification was sent. |
||
| 214 | [[BR]]''prev_state'':[[BR]] |
||
| 215 | The previous state state the object was in. |
||
| 216 | [[BR]]''state'':[[BR]] |
||
| 217 | 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 | The application should listen for this notification from all objects specifically to get informed of incoming sessions. |
||
| 221 | [[BR]]''timestamp'':[[BR]] |
||
| 222 | A {{{datetime.datetime}}} object indicating when the notification was sent. |
||
| 223 | 19 | Ruud Klaver | [[BR]]''streams'':[[BR]] |
| 224 | 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 | [[BR]]''timestamp'':[[BR]] |
||
| 228 | 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 | [[BR]]''timestamp'':[[BR]] |
||
| 234 | 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 | In terms of SIP, this is sent after the final response to the {{{INVITE}}}, but before the {{{ACK}}}. |
||
| 238 | [[BR]]''timestamp'':[[BR]] |
||
| 239 | 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 | In terms of SIP this is sent after the {{{ACK}}} was sent or received. |
||
| 243 | [[BR]]''timestamp'':[[BR]] |
||
| 244 | 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 | 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 | A {{{datetime.datetime}}} object indicating when the notification was sent. |
||
| 251 | [[BR]]''originator'':[[BR]] |
||
| 252 | A string indicating the origin of the failure. |
||
| 253 | This will either be "local" or "remote". |
||
| 254 | [[BR]]''code'':[[BR]] |
||
| 255 | The SIP error code of the failure. |
||
| 256 | If this is 0, the error was an internal exception. |
||
| 257 | [[BR]]''reason'':[[BR]] |
||
| 258 | 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 | [[BR]]''timestamp'':[[BR]] |
||
| 262 | A {{{datetime.datetime}}} object indicating when the notification was sent. |
||
| 263 | 26 | Luci Stanescu | '''SIPSessionDidEnd''':: |
| 264 | 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 | A {{{datetime.datetime}}} object indicating when the notification was sent. |
||
| 267 | [[BR]]''originator'':[[BR]] |
||
| 268 | A string indicating who originated the termination. |
||
| 269 | 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 | [[BR]]''timestamp'':[[BR]] |
||
| 273 | A {{{datetime.datetime}}} object indicating when the notification was sent. |
||
| 274 | [[BR]]''originator'':[[BR]] |
||
| 275 | 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 | [[BR]]''timestamp'':[[BR]] |
||
| 279 | A {{{datetime.datetime}}} object indicating when the notification was sent. |
||
| 280 | [[BR]]''originator'':[[BR]] |
||
| 281 | 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 | [[BR]]''timestamp'':[[BR]] |
||
| 285 | A {{{datetime.datetime}}} object indicating when the notification was sent. |
||
| 286 | [[BR]]''file_name'':[[BR]] |
||
| 287 | 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 | [[BR]]''timestamp'':[[BR]] |
||
| 291 | A {{{datetime.datetime}}} object indicating when the notification was sent. |
||
| 292 | [[BR]]''file_name'':[[BR]] |
||
| 293 | 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 | [[BR]]''timestamp'':[[BR]] |
||
| 297 | A {{{datetime.datetime}}} object indicating when the notification was sent. |
||
| 298 | [[BR]]''file_name'':[[BR]] |
||
| 299 | 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 | [[BR]]''timestamp'':[[BR]] |
||
| 303 | A {{{datetime.datetime}}} object indicating when the notification was sent. |
||
| 304 | [[BR]]''file_name'':[[BR]] |
||
| 305 | 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 | [[BR]]''timestamp'':[[BR]] |
||
| 309 | 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 | [[BR]]''timestamp'':[[BR]] |
||
| 313 | A {{{datetime.datetime}}} object indicating when the notification was sent. |
||
| 314 | [[BR]]''digit'':[[BR]] |
||
| 315 | 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 | [[BR]]''content'':[[BR]] |
||
| 319 | The body of the message. |
||
| 320 | [[BR]]''content_type'':[[BR]] |
||
| 321 | The Content-Type of the body. |
||
| 322 | [[BR]]''cpim_headers'':[[BR]] |
||
| 323 | A dictionary of headers included in the CPIM wrapper. |
||
| 324 | [[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 | [[BR]]''message_id'':[[BR]] |
||
| 329 | The unique identifier of this message as a string, as previously returned by the {{{send_message()}}} method. |
||
| 330 | [[BR]]''code'':[[BR]] |
||
| 331 | The response code of the confirmation report. |
||
| 332 | [[BR]]''reason'':[[BR]] |
||
| 333 | 5 | Redmine Admin | The reason string of the confirmation report. |
| 334 | 1 | Adrian Georgescu | [[BR]]''message'':[[BR]] |
| 335 | 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 | [[BR]]''message_id'':[[BR]] |
||
| 339 | The unique identifier of this message as a string, as previously returned by the {{{send_message()}}} method. |
||
| 340 | [[BR]]''code'':[[BR]] |
||
| 341 | The response code of the confirmation report. |
||
| 342 | [[BR]]''reason'':[[BR]] |
||
| 343 | 5 | Redmine Admin | The reason string of the confirmation report. |
| 344 | 1 | Adrian Georgescu | [[BR]]''message'':[[BR]] |
| 345 | 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 | [[BR]]''timestamp'':[[BR]] |
||
| 349 | A {{{datetime.datetime}}} object indicating when the notification was sent. |
||
| 350 | [[BR]]''proposer'':[[BR]] |
||
| 351 | The party that did the stream proposal, can be either "local" or "remote". |
||
| 352 | 19 | Ruud Klaver | [[BR]]''streams'':[[BR]] |
| 353 | 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 | [[BR]]''timestamp'':[[BR]] |
||
| 357 | A {{{datetime.datetime}}} object indicating when the notification was sent. |
||
| 358 | [[BR]]''proposer'':[[BR]] |
||
| 359 | The party that did the stream proposal, can be either "local" or "remote". |
||
| 360 | [[BR]]''reason'':[[BR]] |
||
| 361 | The reason for rejecting the stream proposal. |
||
| 362 | '''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 | A {{{datetime.datetime}}} object indicating when the notification was sent. |
||
| 366 | [[BR]]''proposer'':[[BR]] |
||
| 367 | The party that did the stream proposal, can be either "local" or "remote". |
||
| 368 | '''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 | [[BR]]''timestamp'':[[BR]] |
||
| 372 | A {{{datetime.datetime}}} object indicating when the notification was sent. |
||
| 373 | [[BR]]''streams'':[[BR]] |
||
| 374 | A list indicating which streams are active on the session from this point onwards. |
||
| 375 | |||
| 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 | {{{ |
||
| 379 | 24 | Ruud Klaver | import sys |
| 380 | 6 | Ruud Klaver | from threading import Event |
| 381 | from zope.interface import implements |
||
| 382 | from application.notification import IObserver, NotificationCenter |
||
| 383 | 1 | Adrian Georgescu | |
| 384 | 24 | Ruud Klaver | from sipsimple.configuration import ConfigurationManager |
| 385 | from sipsimple.account import AccountManager |
||
| 386 | from sipsimple.engine import Engine |
||
| 387 | from sipsimple.session import Session |
||
| 388 | from sipsimple.core import SIPURI, Route |
||
| 389 | |||
| 390 | 1 | Adrian Georgescu | class SimpleOutboundCall(object): |
| 391 | # indicate that we implement the application.notification.IObserver interface |
||
| 392 | implements(IObserver) |
||
| 393 | |||
| 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 | self.engine_ended_event = Event() |
||
| 397 | 24 | Ruud Klaver | # start the configuration manager |
| 398 | ConfigurationManager().start() |
||
| 399 | # start the account manager |
||
| 400 | am = AccountManager() |
||
| 401 | am.start() |
||
| 402 | # start the Engine with configuration framework parameters |
||
| 403 | Engine().start_cfg() |
||
| 404 | # create a new Session using the default account |
||
| 405 | 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 | self.session.end() |
||
| 416 | # wait for the engine to stop, processed in handle_notification |
||
| 417 | self.engine_ended_event.wait() |
||
| 418 | # quit the progam, as this can only be done from the main thread |
||
| 419 | sys.exit() |
||
| 420 | |||
| 421 | 1 | Adrian Georgescu | def handle_notification(self, notification): |
| 422 | if notification.name == "SIPSessionDidEnd": |
||
| 423 | # if for whatever reason the session ended, stop the Engine |
||
| 424 | print "Session ended" |
||
| 425 | Engine().stop() |
||
| 426 | elif notification.name == "SIPEngineDidEnd": |
||
| 427 | # once the Engine has stopped, signal the (possibly) waiting main |
||
| 428 | # thread through a threading.Event |
||
| 429 | self.engine_ended_event.set() |
||
| 430 | |||
| 431 | # place an audio call from the specified account to the specified URI, through |
||
| 432 | # the specified SIP proxy |
||
| 433 | # edit this to reflect real settings |
||
| 434 | call = SimpleOutboundCall(SIPURI(user="bob", host="example.com"), Route("1.2.3.4")) |
||
| 435 | # block waiting for user input |
||
| 436 | print "Placing call, press enter to quit program" |
||
| 437 | raw_input() |
||
| 438 | # block in end() until the Engine has stopped |
||
| 439 | 26 | Luci Stanescu | call.end() |
| 440 | 6 | Ruud Klaver | }}} |
| 441 | 30 | Adrian Georgescu | |
| 442 | === SessionManager === |
||
| 443 | |||
| 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 | The SessionManager is implemented as a singleton, meaning that only one instance of this class exists within the middleware. |
||
| 447 | Note that, in order to be able to receive calls, the application has to instantiate this object. |
||
| 448 | |||
| 449 | ==== attributes ==== |
||
| 450 | |||
| 451 | '''sessions''':: |
||
| 452 | 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 | |||
| 454 | ==== methods ==== |
||
| 455 | |||
| 456 | '''!__init!__'''(''self''):: |
||
| 457 | This either returns a new {{{SessionManager}}} object with default configuration objects, or returns a copy of the already existing instance. |