1 /*! \file janus_sip.c
2 * \author Lorenzo Miniero <lorenzo@meetecho.com>
3 * \copyright GNU General Public License v3
4 * \brief Janus SIP plugin
5 * \details Check the \ref sip for more details.
6 *
7 * \ingroup plugins
8 * \ref plugins
9 *
10 * \page sip SIP plugin documentation
11 * This is a simple SIP plugin for Janus, allowing WebRTC peers
12 * to register at a SIP server (e.g., Asterisk) and call SIP user agents
13 * through a Janus instance. Specifically, when attaching to the plugin peers
14 * are requested to provide their SIP server credentials, i.e., the address
15 * of the SIP server and their username/secret. This results in the plugin
16 * registering at the SIP server and acting as a SIP client on behalf of
17 * the web peer. Most of the SIP states and lifetime are masked by the plugin,
18 * and only the relevant events (e.g., INVITEs and BYEs) and functionality
19 * (call, hangup) are made available to the web peer: peers can call
20 * extensions at the SIP server or wait for incoming INVITEs, and during
21 * a call they can send DTMF tones. Calls can do plain RTP or SDES-SRTP.
22 *
23 * The concept behind this plugin is to allow different web pages associated
24 * to the same peer, and hence the same SIP user, to attach to the plugin
25 * at the same time and yet just do a SIP REGISTER once. The same should
26 * apply for calls: while an incoming call would be notified to all the
27 * web UIs associated to the peer, only one would be able to pick up and
28 * answer, in pretty much the same way as SIP forking works but without the
29 * need to fork in the same place. This specific functionality, though, has
30 * not been implemented as of yet.
31 *
32 * \section sipapi SIP Plugin API
33 *
34 * All requests you can send in the SIP Plugin API are asynchronous,
35 * which means all responses (successes and errors) will be delivered
36 * as events with the same transaction.
37 *
38 * The supported requests are \c register , \c unregister , \c call ,
39 * \c accept, \c decline , \c info , \c message , \c dtmf_info ,
40 * \c subscribe , \c unsubscribe , \c transfer , \c recording ,
41 * \c hold , \c unhold , \c update and \c hangup . \c register can be used,
42 * as the name suggests, to register a username at a SIP registrar to
43 * call and be called, while \c unregister unregisters it; \c call is used
44 * to send an INVITE to a different SIP URI through the plugin, while
45 * \c accept and \c decline are used to accept or reject the call in
46 * case one is invited instead of inviting; \c transfer takes care of
47 * attended and blind transfers (see \ref siptr for more details);
48 * \c hold and \c unhold can be used respectively to put a
49 * call on-hold and to resume it; \c info allows you to send a generic
50 * SIP INFO request, while \c dtmf_info is focused on using INFO for DTMF
51 * instead; \c message is the method you use to send a SIP message
52 * to the other peer; \c subscribe and \c unsubscribe are used to deal
53 * with SIP events, i.e., to send SUBSCRIBE requests that will result in
54 * NOTIFY asynchronous events; \c recording is used, instead, to record the
55 * conversation to one or more .mjr files (depending on the direction you
56 * want to record); \c update allows you to update an existing session
57 * (e.g., to do a renegotiation or force an ICE restart); finally, \c hangup
58 * can be used to terminate the communication at any time, either to
59 * hangup (BYE) an ongoing call or to cancel/decline (CANCEL/BYE) a call
60 * that hasn't started yet.
61 *
62 * No matter the request, an error response or event is always formatted
63 * like this:
64 *
65 \verbatim
66 {
67 "sip" : "event",
68 "error_code" : <numeric ID, check Macros below>,
69 "error" : "<error description as a string>"
70 }
71 \endverbatim
72 *
73 * Notice that the error syntax above refers to the plugin API messaging,
74 * and not SIP error codes obtained in response to SIP requests, which
75 * are notified using a different syntax:
76 *
77 \verbatim
78 {
79 "sip" : "event",
80 "result" : {
81 "event" : "<name of the error event>",
82 "code" : <SIP error code>,
83 "reason" : "<SIP error reason>",
84 "reason_header" : "<SIP reason header; optional>"
85 }
86 }
87 \endverbatim
88 *
89 * Coming to the available requests, you send a SIP REGISTER using the
90 * \c register request. To be more precise, a \c register request MAY result
91 * in a SIP REGISTER, as this method actually provides ways to start using
92 * a SIP account with no need for a registration. It is the case, for instance,
93 * of the so-called \c guest registrations: if you register as a \c guest ,
94 * it means you'll use the provided SIP URI in your \c From headers for calls,
95 * but you will actually not send a SIP REGISTER; this is especially useful
96 * for outgoing calls to services that don't require registration (e.g., IVR
97 * systems, or conference bridges), but also means you won't be able to
98 * receive calls unless peers know what your private SIP address is. A SIP
99 * REGISTER isn't sent also when registering as a \c helper : as we'll
100 * explain later, \c helper sessions are sessions only meant to facilitate
101 * the setup of \ref sipmc.
102 *
103 * That said, a \c register request has to be formatted as follows:
104 *
105 \verbatim
106 {
107 "request" : "register",
108 "type" : "<if guest or helper, no SIP REGISTER is actually sent; optional>",
109 "send_register" : <true|false; if false, no SIP REGISTER is actually sent; optional>,
110 "force_udp" : <true|false; if true, forces UDP for the SIP messaging; optional>,
111 "force_tcp" : <true|false; if true, forces TCP for the SIP messaging; optional>,
112 "sips" : <true|false; if true, configures a SIPS URI too when registering; optional>,
113 "rfc2543_cancel" : <true|false; if true, configures sip client to CANCEL pending INVITEs without having received a provisional response first; optional>,
114 "username" : "<SIP URI to register; mandatory>",
115 "secret" : "<password to use to register; optional>",
116 "ha1_secret" : "<prehashed password to use to register; optional>",
117 "authuser" : "<username to use to authenticate (overrides the one in the SIP URI); optional>",
118 "display_name" : "<display name to use when sending SIP REGISTER; optional>",
119 "user_agent" : "<user agent to use when sending SIP REGISTER; optional>",
120 "proxy" : "<server to register at; optional, as won't be needed in case the REGISTER is not goint to be sent (e.g., guests)>",
121 "outbound_proxy" : "<outbound proxy to use, if any; optional>",
122 "headers" : "<object with key/value mappings (header name/value), to specify custom headers to add to the SIP REGISTER; optional>",
123 "contact_params" : "<array of key/value objects, to specify custom Contact URI params to add to the SIP REGISTER; optional>",
124 "incoming_header_prefixes" : "<array of strings, to specify custom (non-standard) headers to read on incoming SIP events; optional>",
125 "refresh" : "<true|false; if true, only uses the SIP REGISTER as an update and not a new registration; optional>",
126 "master_id" : "<ID of an already registered account, if this is an helper for multiple calls (more on that later); optional>",
127 "register_ttl" : "<integer; number of seconds after which the registration should expire; optional>"
128 }
129 \endverbatim
130 *
131 * A \c registering event will be sent back, as this is an asynchronous request.
132 *
133 * In case it is required to, this request will originate a SIP REGISTER to the
134 * specified server with the right credentials. 401 and 407 responses will be
135 * handled automatically, and so errors will not be notified back to the caller
136 * unless they're definitive (e.g., wrong credentials). A failure to register
137 * will return an error with name \c registration_failed. A successful registration,
138 * instead, is notified in a \c registered event formatted like this:
139 *
140 \verbatim
141 {
142 "sip" : "event",
143 "result" : {
144 "event" : "registered",
145 "username" : <SIP URI username>,
146 "register_sent" : <true|false, depending on whether a REGISTER was sent or not>,
147 "master_id" : <unique ID of this registered session in the plugin, if a potential master>
148 }
149 }
150 \endverbatim
151 *
152 * To unregister, just send an \c unregister request with no other arguments:
153 *
154 \verbatim
155 {
156 "request" : "unregister"
157 }
158 \endverbatim
159 *
160 * As before, an \c unregistering event will be sent back. Just as before,
161 * this will also send a SIP REGISTER in case it had been sent originally.
162 * A successful unregistration is notified in an \c unregistered event:
163 *
164 \verbatim
165 {
166 "sip" : "event",
167 "result" : {
168 "event" : "unregistered",
169 "username" : <SIP URI username>,
170 "register_sent" : <true|false, depending on whether a REGISTER was sent or not>
171 }
172 }
173 \endverbatim
174 *
175 * Once registered, you can call or wait to be called: notice that you won't
176 * be able to get incoming calls if you chose never to send a REGISTER at
177 * all, though.
178 *
179 * To send a SIP INVITE, you can use the \c call request, which has to
180 * be formatted like this:
181 *
182 \verbatim
183 {
184 "request" : "call",
185 "call_id" : "<user-defined value of Call-ID SIP header used in all SIP requests throughout the call; optional>",
186 "uri" : "<SIP URI to call; mandatory>",
187 "refer_id" : <in case this is the result of a REFER, the unique identifier that addresses it; optional>,
188 "headers" : "<object with key/value mappings (header name/value), to specify custom headers to add to the SIP INVITE; optional>",
189 "srtp" : "<whether to mandate (sdes_mandatory) or offer (sdes_optional) SRTP support; optional>",
190 "srtp_profile" : "<SRTP profile to negotiate, in case SRTP is offered; optional>",
191 "secret" : "<password to use to call, only needed in case authentication is needed and no REGISTER was sent; optional>",
192 "ha1_secret" : "<prehashed password to use to call, only needed in case authentication is needed and no REGISTER was sent; optional>",
193 "authuser" : "<username to use to authenticate as to call, only needed in case authentication is needed and no REGISTER was sent; optional>",
194 "autoaccept_reinvites" : <true|false, whether we should blindly accept re-INVITEs with a 200 OK instead of relaying the SDP to the application; optional, TRUE by default>
195 }
196 \endverbatim
197 *
198 * A \c calling event will be sent back, as this is an asynchronous request.
199 *
200 * Notice that this request MUST be associated to a JSEP offer: there's no
201 * way to send an offerless INVITE via the SIP plugin. This will generate
202 * a SIP INVITE and send it according to the instructions. While a
203 * <code>100 Trying</code> will not be notified back to the user, a
204 * <code>180 Ringing</code> will, in a \c ringing event:
205 *
206 \verbatim
207 {
208 "sip" : "event",
209 "call_id" : "<value of SIP Call-ID header for related call>",
210 "result" : {
211 "event" : "ringing",
212 "headers" : "<object with key/value strings; custom headers extracted from SIP event based on incoming_header_prefix defined in register request; optional>"
213 }
214 }
215 \endverbatim
216 *
217 * If the call is declined, or any other error occurs, a \c hangup error
218 * event will be sent back. If the call is accepted, instead, an \c accepted
219 * event will be sent back to the user, along with the JSEP answer originated
220 * by the callee:
221 *
222 \verbatim
223 {
224 "sip" : "event",
225 "call_id" : "<value of SIP Call-ID header for related call>",
226 "result" : {
227 "event" : "accepted",
228 "username" : "<SIP URI of the callee>",
229 "headers" : "<object with key/value strings; custom headers extracted from SIP event based on incoming_header_prefix defined in register request; optional>"
230 }
231 }
232 \endverbatim
233 *
234 * At this point, PeerConnection-related considerations aside, the call
235 * can be considered established. A SIP ACK is sent automatically by the
236 * SIP plugin, so there's no action required of the application to do
237 * that manually.
238 *
239 * Notice that the SIP plugin supports early-media via \c 183 responses
240 * responses. In case a \c 183 response is received, it's sent back to
241 * the user, along with the JSEP answer originated by the callee, in
242 * a \c progress event:
243 *
244 \verbatim
245 {
246 "sip" : "event",
247 "call_id" : "<value of SIP Call-ID header for related call>",
248 "result" : {
249 "event" : "progress",
250 "username" : "<SIP URI of the callee>",
251 "headers" : "<object with key/value strings; custom headers extracted from SIP event based on incoming_header_prefix defined in register request; optional>"
252 }
253 }
254 \endverbatim
255 *
256 * In case the caller received a \c progress event, the following
257 * \c accepted event will NOT contain a JSEP answer, as the one received
258 * in the "Session Progress" event will act as the SDP answer for the session.
259 *
260 * Notice that you only use \c call to start a conversation, that is for
261 * the first INVITE. To update a session via a re-INVITE, e.g., to renegotiate
262 * a session to add/remove streams or force an ICE restart, you do NOT
263 * use \c call, but another request called \c update instead. This request
264 * needs no arguments, as the whole context is derived from the current
265 * state of the session. It does need the new JSEP offer to provide, though,
266 * as part of the renegotiation.
267 *
268 \verbatim
269 {
270 "request" : "update"
271 }
272 \endverbatim
273 *
274 * An \c updating event will be sent back, as this is an asynchronous request.
275 *
276 * While the \c call request allows you to send a SIP INVITE (and the
277 * \c update request allows you to update an existing session), there is
278 * a way to react to SIP INVITEs as well, that is to handle incoming calls.
279 * Incoming calls are notified to the application via \c incomingcall
280 * events:
281 *
282 \verbatim
283 {
284 "sip" : "event",
285 "call_id" : "<value of SIP Call-ID header for related call>",
286 "result" : {
287 "event" : "incomingcall",
288 "username" : "<SIP URI of the caller>",
289 "displayname" : "<display name of the caller, if available; optional>",
290 "callee" : "<SIP URI that was called (in case the user is associated with multiple public URIs)>",
291 "referred_by" : "<SIP URI header conveying the identity of the transferor, if this is a transfer; optional>",
292 "replaces" : "<call-ID of the call that this is supposed to replace, if this is an attended transfer; optional>",
293 "srtp" : "<whether the caller mandates (sdes_mandatory) or offers (sdes_optional) SRTP support; optional>",
294 "headers" : "<object with key/value strings; custom headers extracted from SIP event based on incoming_header_prefix defined in register request; optional>"
295 }
296 }
297 \endverbatim
298 *
299 * The \c incomingcall may or may not be accompanied by a JSEP offer, depending
300 * on whether the caller sent an offerless INVITE or a regular one. Either
301 * way, you can accept the incoming call with the \c accept request:
302 *
303 \verbatim
304 {
305 "request" : "accept",
306 "srtp" : "<whether to mandate (sdes_mandatory) or offer (sdes_optional) SRTP support; optional>",
307 "headers" : "<object with key/value mappings (header name/value), to specify custom headers to add to the SIP OK; optional>"
308 "autoaccept_reinvites" : <true|false, whether we should blindly accept re-INVITEs with a 200 OK instead of relaying the SDP to the browser; optional, TRUE by default>
309 }
310 \endverbatim
311 *
312 * An \c accepting event will be sent back, as this is an asynchronous request.
313 *
314 * This will result in a <code>200 OK</code> to be sent back to the caller.
315 * An \c accept request must always be accompanied by a JSEP answer (if the
316 * \c incomingcall event contained an offer) or offer (in case it was an
317 * offerless INVITE). In the former case, an \c accepted event will be
318 * sent back just to confirm the call can be considered established;
319 * in the latter case, instead, an \c accepting event will be sent back
320 * instead, and an \c accepted event will only follow later, as soon as
321 * a JSEP answer is available in the SIP ACK the caller sent back.
322 *
323 * Notice that in case you get an incoming call while you're in another
324 * call, you will NOT get an \c incomingcall event, but a \c missed_call
325 * event instead, and just as a notification as there's no way to have
326 * two calls at the same time on the same handle in the SIP plugin:
327 *
328 \verbatim
329 {
330 "sip" : "event",
331 "call_id" : "<value of SIP Call-ID header for related call>",
332 "result" : {
333 "event" : "missed_call",
334 "caller" : "<SIP URI of the caller>",
335 "displayname" : "<display name of the caller, if available; optional>",
336 "callee" : "<SIP URI that was called (in case the user is associated with multiple public URIs)>"
337 }
338 }
339 \endverbatim
340 *
341 * Besides, you only use \c accept to answer the first INVITE. To accept a
342 * re-INVITE instead, which would be notified via an \c updatingcall event,
343 * you do NOT use \c accept, but the previously introduced \c update instead.
344 * This request needs no arguments, as the whole context is derived from the current
345 * state of the session. It does need the new JSEP answer to provide, though,
346 * as part of the renegotiation. As before, an \c updated event will be
347 * sent back, as this is an asynchronous request.
348 *
349 * Closing a session depends on the call state. If you have an incoming
350 * call that you don't want to accept, use the \c decline request; in all
351 * other cases, use the \c hangup request instead. Both requests need no
352 * additional arguments, as the whole context can be extracted from the
353 * current state of the session in the plugin:
354 *
355 \verbatim
356 {
357 "request" : "decline",
358 "code" : <SIP code to be sent, if not set, 486 is used; optional>",
359 "headers" : "<object with key/value mappings (header name/value), to specify custom headers to add to the SIP request; optional>"
360 }
361 \endverbatim
362 *
363 \verbatim
364 {
365 "request" : "hangup",
366 "headers" : "<object with key/value mappings (header name/value), to specify custom headers to add to the SIP BYE; optional>"
367 }
368 \endverbatim
369 *
370 * Since these are asynchronous requests, you'll get an event in response:
371 * \c declining if you used \c decline and \c hangingup if you used \c hangup.
372 *
373 * As anticipated before, when a call is declined or being hung up, a
374 * \c hangup event is sent instead, which is basically a SIP error event
375 * notification as it includes the \c code and \c reason . A regular BYE,
376 * for instance, would be notified with \c 200 and <code>SIP BYE</code>,
377 * although a more verbose description may be provided as well.
378 *
379 * When a session has been established, there are different requests that
380 * you can use to interact with the session.
381 *
382 * First of all, you can put a call on-hold with the \c hold request.
383 * By default, this request will send a new INVITE to the peer with a
384 * \c sendonly direction for media, but in case you want to set a
385 * different direction (\c recvonly or \c inactive ) you can do that by
386 * passing a \c direction attribute as well:
387 *
388 \verbatim
389 {
390 "request" : "hold",
391 "direction" : "<sendonly, recvonly or inactive>"
392 }
393 \endverbatim
394 *
395 * No WebRTC renegotiation will be involved here on the holder side, as
396 * this will only trigger a re-INVITE on the SIP side. To remove the
397 * call from on-hold, just send a \c unhold request to the plugin,
398 * which requires no additional attributes:
399 *
400 \verbatim
401 {
402 "request" : "unhold"
403 }
404 \endverbatim
405 *
406 * and will restore the media direction that was set in the SDP before
407 * putting the call on-hold.
408 *
409 * The \c message request allows you to send a SIP MESSAGE to the peer.
410 * By default, it is sent in dialog, during active call.
411 * But, if the user is registered, it might be sent out of dialog also. In that case the uri parameter is required.
412 *
413 \verbatim
414 {
415 "request" : "message",
416 "call_id" : "<user-defined value of Call-ID SIP header used to send the message; optional>",
417 "content_type" : "<content type; optional>"
418 "content" : "<text to send>",
419 "uri" : "<SIP URI of the peer; optional; if set, the message will be sent out of dialog>",
420 "headers" : "<object with key/value mappings (header name/value), to specify custom headers to add to the SIP MESSAGE; optional>"
421 }
422 \endverbatim
423 *
424 * A \c messagesent event will be sent back. Incoming SIP MESSAGEs, instead,
425 * are notified in \c message events:
426 *
427 \verbatim
428 {
429 "sip" : "event",
430 "result" : {
431 "event" : "message",
432 "sender" : "<SIP URI of the message sender>",
433 "displayname" : "<display name of the sender, if available; optional>",
434 "content_type" : "<content type of the message>",
435 "content" : "<content of the message>",
436 "headers" : "<object with key/value strings; custom headers extracted from SIP event based on incoming_header_prefix defined in register request; optional>"
437 }
438 }
439 \endverbatim
440 *
441 * After delivery a \c messagedelivery event will be sent back with the SIP server response.
442 * Used to track the delivery status of the message.
443 *
444 \verbatim
445 {
446 "sip" : "event",
447 "call_id" : "<value of SIP Call-ID header for related message>",
448 "result" : {
449 "event" : "messagedelivery",
450 "code" : "<SIP error code>",
451 "reason" : "<SIP error reason>",
452 }
453 }
454 \endverbatim
455 *
456 * SIP INFO works pretty much the same way, except that you use an \c info
457 * request to one to the peer:
458 *
459 \verbatim
460 {
461 "request" : "info",
462 "type" : "<content type>"
463 "content" : "<message to send>",
464 "headers" : "<object with key/value mappings (header name/value), to specify custom headers to add to the SIP INFO; optional>"
465 }
466 \endverbatim
467 *
468 * A \c infosent event will be sent back. Incoming SIP INFOs, instead,
469 * are notified in \c info events:
470 *
471 \verbatim
472 {
473 "sip" : "event",
474 "result" : {
475 "event" : "info",
476 "sender" : "<SIP URI of the message sender>",
477 "displayname" : "<display name of the sender, if available; optional>",
478 "type" : "<content type of the message>",
479 "content" : "<content of the message>",
480 "headers" : "<object with key/value strings; custom headers extracted from SIP event based on incoming_header_prefix defined in register request; optional>"
481 }
482 }
483 \endverbatim
484 *
485 * As anticipated, SIP events are supported as well, using the SUBSCRIBE
486 * and NOTIFY mechanism. To do that, you need to use the \c subscribe
487 * request, which has to be formatted like this:
488 *
489 \verbatim
490 {
491 "request" : "subscribe",
492 "call_id" : "<user-defined value of Call-ID SIP header used in all SIP requests throughout the subscription; optional>",
493 "event" : "<the event to subscribe to, e.g., 'message-summary'; mandatory>",
494 "accept" : "<what should be put in the Accept header; optional>",
495 "to" : "<who should be the SUBSCRIBE addressed to; optional, will use the user's identity if missing>",
496 "subscribe_ttl" : "<integer; number of seconds after which the subscription should expire; optional>"
497 }
498 \endverbatim
499 *
500 * A \c subscribing event will be sent back, followed by a \c subscribe_succeeded if
501 * the SUBSCRIBE request was accepted, and a \c subscribe_failed if the transaction
502 * failed instead. Incoming SIP NOTIFY events, instead, are notified in \c notify events:
503 *
504 \verbatim
505 {
506 "sip" : "event",
507 "call_id" : "<value of SIP Call-ID header for related subscription>",
508 "result" : {
509 "event" : "notify",
510 "notify" : "<name of the event that the user is subscribed to, e.g., 'message-summary'>",
511 "substate" : "<substate of the subscription, e.g., 'active'>",
512 "content-type" : "<content-type of the message>"
513 "content" : "<content of the message>",
514 "headers" : "<object with key/value strings; custom headers extracted from SIP event based on incoming_header_prefix defined in register request; optional>"
515 }
516 }
517 \endverbatim
518 *
519 * You can also record a SIP call, and it works pretty much the same the
520 * VideoCall plugin does. Specifically, you make use of the \c recording
521 * request to either start or stop a recording, using the following syntax:
522 *
523 \verbatim
524 {
525 "request" : "recording",
526 "action" : "<start|stop, depending on whether you want to start or stop recording something>"
527 "audio" : <true|false; whether or not our audio should be recorded>,
528 "video" : <true|false; whether or not our video should be recorded>,
529 "peer_audio" : <true|false; whether or not our peer's audio should be recorded>,
530 "peer_video" : <true|false; whether or not our peer's video should be recorded>,
531 "filename" : "<base path/filename to use for all the recordings>"
532 }
533 \endverbatim
534 *
535 * As you can see, this means that the two sides of conversation are recorded
536 * separately, and so are the audio and video streams if available. You can
537 * choose which ones to record, in case you're interested in just a subset.
538 * The \c filename part is just a prefix, and dictates the actual filenames
539 * that will be used for the up-to-four recordings that may need to be enabled.
540 *
541 * A \c recordingupdated event is sent back in case the request is successful.
542 *
543 * \section sipmc Simultaneous SIP calls using the same account
544 *
545 * As anticipated in the previous sections, attaching to the SIP plugin
546 * with a Janus handle means creating a SIP stack on behalf of a user
547 * or application: this typically means registering an account, and being
548 * able to start or receive calls, handle subscriptions, and so on. This
549 * also means that, since in Janus each core handle can only be associated
550 * with a single PeerConnection, each SIP account is limited to a single
551 * call per time: if a user is in a SIP session already, and another call
552 * comes in, it's automatically rejected with a \c 486 \c Busy .
553 *
554 * While usually not a big deal, there are use cases where it might make
555 * sense to be able to support multiple concurrent calls, and maybe switch
556 * from one to the other seamlessly. This is possible in the SIP plugin
557 * using the so-called \c helper sessions. Specifically, \c helper sessions
558 * work under the assumption that there's a \c master session that is
559 * registered normally (the "regular" SIP plugin handle, that is), and
560 * that these \c helper sessions can simply be associated to that: any time
561 * another concurrent call is needed, if the \c master session is busy
562 * one of the \c helpers can be used; the more \c helper sessions are
563 * available, the more simultaneous calls can be established.
564 *
565 * The way this works is simple:
566 *
567 * 1. you create a SIP session the usual way, and send a regular \c register
568 * there; this will be the \c master session, and will return a \c master_id
569 * when successfully registered;
570 * 2. for each \c helper you want to add, you attach a new Janus handle
571 * to the SIP plugin, and send a \c register with \c type: \c "helper" and
572 * providing the same \c username as the master, plus a \c master_id attribute
573 * referencing the main session;
574 * 3. at this point, the new \c helper is associated to the \c master ,
575 * meaning it can be used to start new calls or receive calls exactly
576 * as the main session, and using the same account information, credentials,
577 * etc.
578 *
579 * Notice that, as soon as the \c master unregisters, or the Janus handle
580 * it's on is detached, all the \c helper sessions associated to it are
581 * automatically torn down as well. Specifically, the plugin will forcibly
582 * detach the related handles. Should you need to register again, and want
583 * some helpers there too, you'll have to add them again.
584 *
585 * If you want to see this in practice, the SIP plugin demo has a "hidden"
586 * function you can invoke from the JavaScript console to play with helpers:
587 * calling the \c addHelper() function will add a new helper, and show additional
588 * controls. You can add as many helpers as you want.
589 *
590 * \section siptr Attended and blind transfers
591 *
592 * The Janus SIP plugin supports both attended and blind transfers, and to
593 * do so mostly relies on the multiple calls functionality: as such, make
594 * sure you've read and are familiar with the section on \ref sipmc .
595 *
596 * Most of the transfer-related functionality are based on existing messages
597 * and events already documented in the previous section, but there are a
598 * few aspects you need to be aware of. First of all, if you're the transferor,
599 * you need to use a new request called \c transfer , that allows you to
600 * send a SIP REFER to the transferee so to reach a different target. The
601 * \c transfer request must be formatted like this:
602 *
603 \verbatim
604 {
605 "request" : "transfer",
606 "uri" : "<SIP URI to send the transferee too>",
607 "replace" : "<call-ID of the call this attended transfer is supposed to replace; default is none, which means blind/unattended transfer>"
608 }
609 \endverbatim
610 *
611 * Whether this is a blind (no call to replace) or attended transfer,
612 * a \c transferring event will be sent back, as this is an asynchronous
613 * request. Further updates will come in the form of NOTIFY-related events,
614 * as a REFER implicitly creates a subscription.
615 *
616 * The recipient of a REFER, instead, will receive an asynchronous event
617 * called \c transfer as well, with info it needs to be aware of. In fact,
618 * the SIP plugin doesn't do anything automatically: an incoming REFER is
619 * notified to the application, so that it can decide whether to follow
620 * up on the transfer or not. The syntax of the event is the following:
621 *
622 \verbatim
623 {
624 "sip" : "event",
625 "result" : {
626 "event" : "transfer",
627 "refer_id" : <unique ID, internal to Janus, of this referral>,
628 "refer_to" : "<SIP URI to call>",
629 "referred_by" : "<SIP URI SIP URI header conveying the identity of the transferor; optional>",
630 "replaces" : "<call-ID of the call this transfer is supposed to replace; optional, and only present for attended transfers>",
631 "headers" : "<object with key/value strings; custom headers extracted from SIP event based on incoming_header_prefix defined in register request; optional>"
632 }
633 }
634 \endverbatim
635 *
636 * The most important property in that list is \c refer_id as that value
637 * must be included in the \c call request to call the target, if the
638 * transfer is accepted: in fact, that's the only way the SIP plugin has
639 * to correlate the new outgoing call to the previous transfer request,
640 * and thus be able to notify the transferor about how the call is
641 * proceeding by means of NOTIFY events. Notice that, if the transferee
642 * decides to follow up on the transfer request, and they're already in
643 * a call (e.g., with the transferor), then they must use a different
644 * handle for the purpose, e.g., via a helper as described in the
645 * \ref sipmc section.
646 *
647 * The transfer target will receive the call exactly as previously discussed,
648 * with the difference that it may or may not include a \c referred_by
649 * property for information purposes. Just as the transferee, if they're
650 * already in a call, it's up to the application to create a helper to
651 * setup a new Janus handle to accept the transfer.
652 *
653 * Notice that the plugin will NOT put the involved calls on-hold, or
654 * automatically close calls that are meant to be replaced by a transfer.
655 * All this is the application responsibility, and as such it's up to
656 * the developer to react to events accordingly.
657 *
658 */
659
660 #include "plugin.h"
661
662 #include <arpa/inet.h>
663 #include <net/if.h>
664
665 #include <jansson.h>
666
667 #include <sofia-sip/msg_header.h>
668 #include <sofia-sip/nua.h>
669 #include <sofia-sip/nua_tag.h>
670 #include <sofia-sip/sdp.h>
671 #include <sofia-sip/sip_header.h>
672 #include <sofia-sip/sip_status.h>
673 #include <sofia-sip/url.h>
674 #include <sofia-sip/tport_tag.h>
675 #include <sofia-sip/su_log.h>
676 #include <sofia-sip/sofia_features.h>
677
678 #include "../debug.h"
679 #include "../apierror.h"
680 #include "../config.h"
681 #include "../mutex.h"
682 #include "../record.h"
683 #include "../rtp.h"
684 #include "../rtpsrtp.h"
685 #include "../rtcp.h"
686 #include "../sdp-utils.h"
687 #include "../utils.h"
688 #include "../ip-utils.h"
689
690
691 /* Plugin information */
692 #define JANUS_SIP_VERSION 8
693 #define JANUS_SIP_VERSION_STRING "0.0.8"
694 #define JANUS_SIP_DESCRIPTION "This is a simple SIP plugin for Janus, allowing WebRTC peers to register at a SIP server and call SIP user agents through a Janus instance."
695 #define JANUS_SIP_NAME "JANUS SIP plugin"
696 #define JANUS_SIP_AUTHOR "Meetecho s.r.l."
697 #define JANUS_SIP_PACKAGE "janus.plugin.sip"
698
699 /* Plugin methods */
700 janus_plugin *create(void);
701 int janus_sip_init(janus_callbacks *callback, const char *config_path);
702 void janus_sip_destroy(void);
703 int janus_sip_get_api_compatibility(void);
704 int janus_sip_get_version(void);
705 const char *janus_sip_get_version_string(void);
706 const char *janus_sip_get_description(void);
707 const char *janus_sip_get_name(void);
708 const char *janus_sip_get_author(void);
709 const char *janus_sip_get_package(void);
710 void janus_sip_create_session(janus_plugin_session *handle, int *error);
711 struct janus_plugin_result *janus_sip_handle_message(janus_plugin_session *handle, char *transaction, json_t *message, json_t *jsep);
712 void janus_sip_setup_media(janus_plugin_session *handle);
713 void janus_sip_incoming_rtp(janus_plugin_session *handle, janus_plugin_rtp *packet);
714 void janus_sip_incoming_rtcp(janus_plugin_session *handle, janus_plugin_rtcp *packet);
715 void janus_sip_hangup_media(janus_plugin_session *handle);
716 void janus_sip_destroy_session(janus_plugin_session *handle, int *error);
717 json_t *janus_sip_query_session(janus_plugin_session *handle);
718
719 /* Plugin setup */
720 static janus_plugin janus_sip_plugin =
721 JANUS_PLUGIN_INIT (
722 .init = janus_sip_init,
723 .destroy = janus_sip_destroy,
724
725 .get_api_compatibility = janus_sip_get_api_compatibility,
726 .get_version = janus_sip_get_version,
727 .get_version_string = janus_sip_get_version_string,
728 .get_description = janus_sip_get_description,
729 .get_name = janus_sip_get_name,
730 .get_author = janus_sip_get_author,
731 .get_package = janus_sip_get_package,
732
733 .create_session = janus_sip_create_session,
734 .handle_message = janus_sip_handle_message,
735 .setup_media = janus_sip_setup_media,
736 .incoming_rtp = janus_sip_incoming_rtp,
737 .incoming_rtcp = janus_sip_incoming_rtcp,
738 .hangup_media = janus_sip_hangup_media,
739 .destroy_session = janus_sip_destroy_session,
740 .query_session = janus_sip_query_session,
741 );
742
743 /* Plugin creator */
create(void)744 janus_plugin *create(void) {
745 JANUS_LOG(LOG_VERB, "%s created!\n", JANUS_SIP_NAME);
746 return &janus_sip_plugin;
747 }
748
749 /* Parameter validation */
750 static struct janus_json_parameter request_parameters[] = {
751 {"request", JSON_STRING, JANUS_JSON_PARAM_REQUIRED}
752 };
753 static struct janus_json_parameter register_parameters[] = {
754 {"type", JSON_STRING, 0},
755 {"send_register", JANUS_JSON_BOOL, 0},
756 {"force_udp", JANUS_JSON_BOOL, 0},
757 {"force_tcp", JANUS_JSON_BOOL, 0},
758 {"sips", JANUS_JSON_BOOL, 0},
759 {"rfc2543_cancel", JANUS_JSON_BOOL, 0},
760 {"username", JSON_STRING, JANUS_JSON_PARAM_REQUIRED},
761 {"secret", JSON_STRING, 0},
762 {"ha1_secret", JSON_STRING, 0},
763 {"authuser", JSON_STRING, 0},
764 {"display_name", JSON_STRING, 0},
765 {"user_agent", JSON_STRING, 0},
766 {"headers", JSON_OBJECT, 0},
767 {"contact_params", JSON_OBJECT, 0},
768 {"master_id", JANUS_JSON_INTEGER, 0},
769 {"refresh", JANUS_JSON_BOOL, 0},
770 {"incoming_header_prefixes", JSON_ARRAY, 0},
771 {"register_ttl", JANUS_JSON_INTEGER, 0}
772 };
773 static struct janus_json_parameter subscribe_parameters[] = {
774 {"to", JSON_STRING, 0},
775 {"event", JSON_STRING, JANUS_JSON_PARAM_REQUIRED},
776 {"accept", JSON_STRING, 0},
777 {"subscribe_ttl", JANUS_JSON_INTEGER, 0},
778 {"call_id", JANUS_JSON_STRING, 0}
779 };
780 static struct janus_json_parameter proxy_parameters[] = {
781 {"proxy", JSON_STRING, 0},
782 {"outbound_proxy", JSON_STRING, 0}
783 };
784 static struct janus_json_parameter call_parameters[] = {
785 {"uri", JSON_STRING, JANUS_JSON_PARAM_REQUIRED},
786 {"headers", JSON_OBJECT, 0},
787 {"srtp", JSON_STRING, 0},
788 {"srtp_profile", JSON_STRING, 0},
789 {"autoaccept_reinvites", JANUS_JSON_BOOL, 0},
790 {"refer_id", JANUS_JSON_INTEGER, 0},
791 /* The following are only needed in case "guest" registrations
792 * still need an authenticated INVITE for some reason */
793 {"secret", JSON_STRING, 0},
794 {"ha1_secret", JSON_STRING, 0},
795 {"authuser", JSON_STRING, 0}
796 };
797 static struct janus_json_parameter accept_parameters[] = {
798 {"srtp", JSON_STRING, 0},
799 {"headers", JSON_OBJECT, 0},
800 {"autoaccept_reinvites", JANUS_JSON_BOOL, 0}
801 };
802 static struct janus_json_parameter decline_parameters[] = {
803 {"code", JANUS_JSON_INTEGER, 0},
804 {"headers", JSON_OBJECT, 0},
805 {"refer_id", JANUS_JSON_INTEGER, 0}
806 };
807 static struct janus_json_parameter transfer_parameters[] = {
808 {"uri", JSON_STRING, JANUS_JSON_PARAM_REQUIRED},
809 {"call_id", JANUS_JSON_STRING, 0}
810 };
811 static struct janus_json_parameter hold_parameters[] = {
812 {"direction", JSON_STRING, 0}
813 };
814 static struct janus_json_parameter recording_parameters[] = {
815 {"action", JSON_STRING, JANUS_JSON_PARAM_REQUIRED},
816 {"audio", JANUS_JSON_BOOL, 0},
817 {"video", JANUS_JSON_BOOL, 0},
818 {"peer_audio", JANUS_JSON_BOOL, 0},
819 {"peer_video", JANUS_JSON_BOOL, 0},
820 {"filename", JSON_STRING, 0}
821 };
822 static struct janus_json_parameter dtmf_info_parameters[] = {
823 {"digit", JSON_STRING, JANUS_JSON_PARAM_REQUIRED},
824 {"duration", JSON_INTEGER, JANUS_JSON_PARAM_POSITIVE},
825 {"headers", JSON_OBJECT, 0}
826 };
827 static struct janus_json_parameter info_parameters[] = {
828 {"type", JSON_STRING, JANUS_JSON_PARAM_REQUIRED},
829 {"content", JSON_STRING, JANUS_JSON_PARAM_REQUIRED},
830 {"headers", JSON_OBJECT, 0}
831 };
832 static struct janus_json_parameter sipmessage_parameters[] = {
833 {"content_type", JSON_STRING, 0},
834 {"content", JSON_STRING, JANUS_JSON_PARAM_REQUIRED},
835 {"uri", JSON_STRING, 0},
836 {"headers", JSON_OBJECT, 0}
837 };
838
839 /* Useful stuff */
840 static volatile gint initialized = 0, stopping = 0;
841 static gboolean notify_events = TRUE;
842 static janus_callbacks *gateway = NULL;
843
844 static char *local_ip = NULL, *sdp_ip = NULL, *local_media_ip = NULL;
845 static int keepalive_interval = 120;
846 static gboolean behind_nat = FALSE;
847 static char *user_agent;
848 #define JANUS_DEFAULT_REGISTER_TTL 3600
849 static int register_ttl = JANUS_DEFAULT_REGISTER_TTL;
850 #define JANUS_DEFAULT_SUBSCRIBE_TTL 3600
851 static int subscribe_ttl = JANUS_DEFAULT_SUBSCRIBE_TTL;
852 static uint16_t rtp_range_min = 10000;
853 static uint16_t rtp_range_max = 60000;
854 static int dscp_audio_rtp = 0;
855 static int dscp_video_rtp = 0;
856
857 static gboolean query_contact_header = FALSE;
858
859 static GThread *handler_thread;
860 static void *janus_sip_handler(void *data);
861 static void janus_sip_hangup_media_internal(janus_plugin_session *handle);
862
863 typedef struct janus_sip_message {
864 janus_plugin_session *handle;
865 char *transaction;
866 json_t *message;
867 json_t *jsep;
868 } janus_sip_message;
869 static GAsyncQueue *messages = NULL;
870 static janus_sip_message exit_message;
871
872
873 typedef enum {
874 janus_sip_registration_status_disabled = -2,
875 janus_sip_registration_status_failed = -1,
876 janus_sip_registration_status_unregistered = 0,
877 janus_sip_registration_status_registering,
878 janus_sip_registration_status_registered,
879 janus_sip_registration_status_unregistering,
880 } janus_sip_registration_status;
881
janus_sip_registration_status_string(janus_sip_registration_status status)882 static const char *janus_sip_registration_status_string(janus_sip_registration_status status) {
883 switch(status) {
884 case janus_sip_registration_status_disabled:
885 return "disabled";
886 case janus_sip_registration_status_failed:
887 return "failed";
888 case janus_sip_registration_status_unregistered:
889 return "unregistered";
890 case janus_sip_registration_status_registering:
891 return "registering";
892 case janus_sip_registration_status_registered:
893 return "registered";
894 case janus_sip_registration_status_unregistering:
895 return "unregistering";
896 default:
897 return "unknown";
898 }
899 }
900
901
902 typedef enum {
903 janus_sip_call_status_idle = 0,
904 janus_sip_call_status_inviting,
905 janus_sip_call_status_invited,
906 janus_sip_call_status_incall,
907 janus_sip_call_status_incall_reinviting,
908 janus_sip_call_status_incall_reinvited,
909 janus_sip_call_status_closing,
910 } janus_sip_call_status;
911
janus_sip_call_status_string(janus_sip_call_status status)912 static const char *janus_sip_call_status_string(janus_sip_call_status status) {
913 switch(status) {
914 case janus_sip_call_status_idle:
915 return "idle";
916 case janus_sip_call_status_inviting:
917 return "inviting";
918 case janus_sip_call_status_invited:
919 return "invited";
920 case janus_sip_call_status_incall:
921 return "incall";
922 case janus_sip_call_status_incall_reinviting:
923 return "incall_reinviting";
924 case janus_sip_call_status_incall_reinvited:
925 return "incall_reinvited";
926 case janus_sip_call_status_closing:
927 return "closing";
928 default:
929 return "unknown";
930 }
931 }
932
933
934 /* Sofia stuff */
935 typedef struct ssip_s ssip_t;
936 typedef struct ssip_oper_s ssip_oper_t;
937
938 #undef SU_ROOT_MAGIC_T
939 #define SU_ROOT_MAGIC_T ssip_t
940 #undef NUA_MAGIC_T
941 #define NUA_MAGIC_T ssip_t
942 #undef NUA_HMAGIC_T
943 #define NUA_HMAGIC_T ssip_oper_t
944
945 struct ssip_s {
946 su_home_t s_home[1];
947 su_root_t *s_root;
948 nua_t *s_nua;
949 nua_handle_t *s_nh_r, *s_nh_i, *s_nh_m;
950 char *contact_header; /* Only needed for Sofia SIP >= 1.13 */
951 GHashTable *subscriptions;
952 janus_mutex smutex;
953 struct janus_sip_session *session;
954 };
955
956 typedef struct janus_sip_transfer {
957 struct janus_sip_session *session;
958 char *referred_by;
959 char *custom_headers;
960 nua_handle_t *nh_s;
961 nua_saved_event_t saved[1];
962 } janus_sip_transfer;
963
964 typedef enum {
965 janus_sip_secret_type_plaintext = 1,
966 janus_sip_secret_type_hashed = 2,
967 janus_sip_secret_type_unknown
968 } janus_sip_secret_type;
969
970 typedef struct janus_sip_account {
971 char *identity;
972 char *user_agent; /* Used to override the general UA string */
973 gboolean force_udp;
974 gboolean force_tcp;
975 gboolean sips;
976 gboolean rfc2543_cancel;
977 char *username;
978 char *display_name; /* Used for outgoing calls in the From header */
979 char *authuser; /**< username to use for authentication */
980 char *secret;
981 janus_sip_secret_type secret_type;
982 int sip_port;
983 char *proxy;
984 char *outbound_proxy;
985 janus_sip_registration_status registration_status;
986 } janus_sip_account;
987
988 typedef struct janus_sip_media {
989 char *remote_audio_ip; /* Peer audio media IP address */
990 char *remote_video_ip; /* Peer video media IP address */
991 gboolean earlymedia;
992 gboolean update;
993 gboolean autoaccept_reinvites;
994 gboolean ready;
995 gboolean require_srtp,
996 has_srtp_local_audio, has_srtp_local_video,
997 has_srtp_remote_audio, has_srtp_remote_video;
998 janus_srtp_profile srtp_profile;
999 gboolean on_hold;
1000 gboolean has_audio;
1001 int audio_rtp_fd, audio_rtcp_fd;
1002 int local_audio_rtp_port, remote_audio_rtp_port;
1003 int local_audio_rtcp_port, remote_audio_rtcp_port;
1004 guint32 audio_ssrc, audio_ssrc_peer;
1005 int audio_pt;
1006 const char *audio_pt_name;
1007 gint32 audio_srtp_tag;
1008 srtp_t audio_srtp_in, audio_srtp_out;
1009 srtp_policy_t audio_remote_policy, audio_local_policy;
1010 char *audio_srtp_local_profile, *audio_srtp_local_crypto;
1011 gboolean audio_send;
1012 janus_sdp_mdirection pre_hold_audio_dir;
1013 gboolean has_video;
1014 int video_rtp_fd, video_rtcp_fd;
1015 int local_video_rtp_port, remote_video_rtp_port;
1016 int local_video_rtcp_port, remote_video_rtcp_port;
1017 guint32 video_ssrc, video_ssrc_peer;
1018 guint32 simulcast_ssrc;
1019 int video_pt;
1020 const char *video_pt_name;
1021 gint32 video_srtp_tag;
1022 srtp_t video_srtp_in, video_srtp_out;
1023 srtp_policy_t video_remote_policy, video_local_policy;
1024 char *video_srtp_local_profile, *video_srtp_local_crypto;
1025 gboolean video_send;
1026 janus_sdp_mdirection pre_hold_video_dir;
1027 janus_rtp_switching_context context;
1028 int pipefd[2];
1029 gboolean updated;
1030 int video_orientation_extension_id;
1031 int audio_level_extension_id;
1032 } janus_sip_media;
1033
1034 typedef struct janus_sip_session {
1035 janus_plugin_session *handle;
1036 ssip_t *stack;
1037 janus_sip_account account;
1038 janus_sip_call_status status;
1039 janus_sip_media media;
1040 char *transaction;
1041 char *callee;
1042 char *callid;
1043 guint32 refer_id; /* In case we were asked to transfer, keep track of the ID */
1044 janus_sdp *sdp; /* The SDP this user sent */
1045 janus_recorder *arc; /* The Janus recorder instance for this user's audio, if enabled */
1046 janus_recorder *arc_peer; /* The Janus recorder instance for the peer's audio, if enabled */
1047 janus_recorder *vrc; /* The Janus recorder instance for this user's video, if enabled */
1048 janus_recorder *vrc_peer; /* The Janus recorder instance for the peer's video, if enabled */
1049 janus_mutex rec_mutex; /* Mutex to protect the recorders from race conditions */
1050 GThread *relayer_thread;
1051 volatile gint establishing, established;
1052 volatile gint hangingup;
1053 volatile gint destroyed;
1054 /* Sessions may be helpers under a "master" (e.g., for multiple calls from/to the same account) */
1055 guint32 master_id; /* Master ID the helpers refer to */
1056 struct janus_sip_session *master;
1057 gboolean helper; /* Whether this session is a helper or not */
1058 GList *helpers; /* The helper sessions, if this is the "master" */
1059 janus_mutex mutex;
1060 char *hangup_reason_header;
1061 GList *incoming_header_prefixes;
1062 GList *active_calls;
1063 janus_refcount ref;
1064 } janus_sip_session;
1065 static GHashTable *sessions;
1066 static GHashTable *identities;
1067 static GHashTable *callids;
1068 static GHashTable *messageids;
1069 static GHashTable *masters;
1070 static GHashTable *transfers;
1071 static janus_mutex sessions_mutex = JANUS_MUTEX_INITIALIZER;
1072
1073 static void janus_sip_srtp_cleanup(janus_sip_session *session);
1074 static void janus_sip_media_reset(janus_sip_session *session);
1075
janus_sip_call_update_status(janus_sip_session * session,janus_sip_call_status new_status)1076 static void janus_sip_call_update_status(janus_sip_session *session, janus_sip_call_status new_status) {
1077 if(session->status != new_status) {
1078 JANUS_LOG(LOG_VERB, "[%s] Call status change: [%s]-->[%s]\n", session->account.username == NULL ? "null" : session->account.username, janus_sip_call_status_string(session->status), janus_sip_call_status_string(new_status));
1079 session->status = new_status;
1080 }
1081 }
1082
janus_sip_call_is_established(janus_sip_session * session)1083 static gboolean janus_sip_call_is_established(janus_sip_session *session) {
1084 return (session->status == janus_sip_call_status_incall ||
1085 session->status == janus_sip_call_status_incall_reinviting ||
1086 session->status == janus_sip_call_status_incall_reinvited) ? TRUE : FALSE;
1087 }
1088
1089 static void janus_sip_media_reset(janus_sip_session *session);
1090
janus_sip_session_destroy(janus_sip_session * session)1091 static void janus_sip_session_destroy(janus_sip_session *session) {
1092 if(session && g_atomic_int_compare_and_exchange(&session->destroyed, 0, 1)) {
1093 if(session->master == NULL && session->account.identity)
1094 g_hash_table_remove(identities, session->account.identity);
1095 if(session->callid)
1096 g_hash_table_remove(callids, session->callid);
1097 janus_refcount_decrease(&session->ref);
1098 }
1099 }
1100
janus_sip_session_dereference(janus_sip_session * session)1101 static void janus_sip_session_dereference(janus_sip_session *session) {
1102 /* This is used to decrease the reference when removing to the messageids hashtable. janus_refcount_increase(&session->ref) must be called before inserting into messageids hashtable */
1103 janus_refcount_decrease(&session->ref);
1104 }
1105
janus_sip_session_free(const janus_refcount * session_ref)1106 static void janus_sip_session_free(const janus_refcount *session_ref) {
1107 janus_sip_session *session = janus_refcount_containerof(session_ref, janus_sip_session, ref);
1108 /* Remove the reference to the core plugin session */
1109 janus_refcount_decrease(&session->handle->ref);
1110 /* This session can be destroyed, free all the resources */
1111 if(session->master == NULL && session->account.identity) {
1112 g_free(session->account.identity);
1113 session->account.identity = NULL;
1114 }
1115 if(session->stack != NULL) {
1116 su_home_deinit(session->stack->s_home);
1117 su_home_unref(session->stack->s_home);
1118 janus_mutex_lock(&session->stack->smutex);
1119 if(session->stack->subscriptions != NULL)
1120 g_hash_table_unref(session->stack->subscriptions);
1121 session->stack->subscriptions = NULL;
1122 janus_mutex_unlock(&session->stack->smutex);
1123 g_free(session->stack->contact_header);
1124 g_free(session->stack);
1125 session->stack = NULL;
1126 }
1127 if(session->account.proxy) {
1128 g_free(session->account.proxy);
1129 session->account.proxy = NULL;
1130 }
1131 if(session->account.outbound_proxy) {
1132 g_free(session->account.outbound_proxy);
1133 session->account.outbound_proxy = NULL;
1134 }
1135 if(session->account.secret) {
1136 g_free(session->account.secret);
1137 session->account.secret = NULL;
1138 }
1139 if(session->account.username) {
1140 g_free(session->account.username);
1141 session->account.username = NULL;
1142 }
1143 if(session->account.display_name) {
1144 g_free(session->account.display_name);
1145 session->account.display_name = NULL;
1146 }
1147 if(session->account.user_agent) {
1148 g_free(session->account.user_agent);
1149 session->account.user_agent = NULL;
1150 }
1151 if(session->account.authuser) {
1152 g_free(session->account.authuser);
1153 session->account.authuser = NULL;
1154 }
1155 if(session->callee) {
1156 g_free(session->callee);
1157 session->callee = NULL;
1158 }
1159 if(session->callid) {
1160 g_free(session->callid);
1161 session->callid = NULL;
1162 }
1163 if(session->sdp) {
1164 janus_sdp_destroy(session->sdp);
1165 session->sdp = NULL;
1166 }
1167 if(session->transaction) {
1168 g_free(session->transaction);
1169 session->transaction = NULL;
1170 }
1171 if(session->media.remote_audio_ip) {
1172 g_free(session->media.remote_audio_ip);
1173 session->media.remote_audio_ip = NULL;
1174 }
1175 if(session->media.remote_video_ip) {
1176 g_free(session->media.remote_video_ip);
1177 session->media.remote_video_ip = NULL;
1178 }
1179 if(session->hangup_reason_header) {
1180 g_free(session->hangup_reason_header);
1181 session->hangup_reason_header = NULL;
1182 }
1183 if(session->incoming_header_prefixes) {
1184 g_list_free_full(session->incoming_header_prefixes, g_free);
1185 session->incoming_header_prefixes = NULL;
1186 }
1187 janus_sip_srtp_cleanup(session);
1188 g_free(session);
1189 }
1190
janus_sip_message_free(janus_sip_message * msg)1191 static void janus_sip_message_free(janus_sip_message *msg) {
1192 if(!msg || msg == &exit_message)
1193 return;
1194
1195 if(msg->handle && msg->handle->plugin_handle) {
1196 janus_sip_session *session = (janus_sip_session *)msg->handle->plugin_handle;
1197 janus_refcount_decrease(&session->ref);
1198 }
1199 msg->handle = NULL;
1200
1201 g_free(msg->transaction);
1202 msg->transaction = NULL;
1203 if(msg->message)
1204 json_decref(msg->message);
1205 msg->message = NULL;
1206 if(msg->jsep)
1207 json_decref(msg->jsep);
1208 msg->jsep = NULL;
1209
1210 g_free(msg);
1211 }
1212
janus_sip_transfer_destroy(janus_sip_transfer * t)1213 static void janus_sip_transfer_destroy(janus_sip_transfer *t) {
1214 if(t == NULL)
1215 return;
1216 g_free(t->referred_by);
1217 g_free(t->custom_headers);
1218 if(t->session != NULL)
1219 janus_refcount_decrease(&t->session->ref);
1220 g_free(t);
1221 }
1222
1223 /* SRTP stuff (in case we need SDES) */
janus_sip_srtp_set_local(janus_sip_session * session,gboolean video,char ** profile,char ** crypto)1224 static int janus_sip_srtp_set_local(janus_sip_session *session, gboolean video, char **profile, char **crypto) {
1225 if(session == NULL)
1226 return -1;
1227 /* Which SRTP profile are we going to negotiate? */
1228 int key_length = 0, salt_length = 0, master_length = 0;
1229 if(session->media.srtp_profile == JANUS_SRTP_AES128_CM_SHA1_32) {
1230 key_length = SRTP_MASTER_KEY_LENGTH;
1231 salt_length = SRTP_MASTER_SALT_LENGTH;
1232 master_length = SRTP_MASTER_LENGTH;
1233 *profile = g_strdup("AES_CM_128_HMAC_SHA1_32");
1234 } else if(session->media.srtp_profile == JANUS_SRTP_AES128_CM_SHA1_80) {
1235 key_length = SRTP_MASTER_KEY_LENGTH;
1236 salt_length = SRTP_MASTER_SALT_LENGTH;
1237 master_length = SRTP_MASTER_LENGTH;
1238 *profile = g_strdup("AES_CM_128_HMAC_SHA1_80");
1239 #ifdef HAVE_SRTP_AESGCM
1240 } else if(session->media.srtp_profile == JANUS_SRTP_AEAD_AES_128_GCM) {
1241 key_length = SRTP_AESGCM128_MASTER_KEY_LENGTH;
1242 salt_length = SRTP_AESGCM128_MASTER_SALT_LENGTH;
1243 master_length = SRTP_AESGCM128_MASTER_LENGTH;
1244 *profile = g_strdup("AEAD_AES_128_GCM");
1245 } else if(session->media.srtp_profile == JANUS_SRTP_AEAD_AES_256_GCM) {
1246 key_length = SRTP_AESGCM256_MASTER_KEY_LENGTH;
1247 salt_length = SRTP_AESGCM256_MASTER_SALT_LENGTH;
1248 master_length = SRTP_AESGCM256_MASTER_LENGTH;
1249 *profile = g_strdup("AEAD_AES_256_GCM");
1250 #endif
1251 } else {
1252 JANUS_LOG(LOG_ERR, "[SIP-%s] Unsupported SRTP profile\n", session->account.username);
1253 return -2;
1254 }
1255 JANUS_LOG(LOG_VERB, "[SIP-%s] %s\n", session->account.username, *profile);
1256 JANUS_LOG(LOG_VERB, "[SIP-%s] Key/Salt/Master: %d/%d/%d\n",
1257 session->account.username, master_length, key_length, salt_length);
1258 /* Generate key/salt */
1259 uint8_t *key = g_malloc0(master_length);
1260 srtp_crypto_get_random(key, master_length);
1261 /* Set SRTP policies */
1262 srtp_policy_t *policy = video ? &session->media.video_local_policy : &session->media.audio_local_policy;
1263 switch(session->media.srtp_profile) {
1264 case JANUS_SRTP_AES128_CM_SHA1_32:
1265 srtp_crypto_policy_set_aes_cm_128_hmac_sha1_32(&(policy->rtp));
1266 srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(&(policy->rtcp));
1267 break;
1268 case JANUS_SRTP_AES128_CM_SHA1_80:
1269 srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(&(policy->rtp));
1270 srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(&(policy->rtcp));
1271 break;
1272 #ifdef HAVE_SRTP_AESGCM
1273 case JANUS_SRTP_AEAD_AES_128_GCM:
1274 srtp_crypto_policy_set_aes_gcm_128_16_auth(&(policy->rtp));
1275 srtp_crypto_policy_set_aes_gcm_128_16_auth(&(policy->rtcp));
1276 break;
1277 case JANUS_SRTP_AEAD_AES_256_GCM:
1278 srtp_crypto_policy_set_aes_gcm_256_16_auth(&(policy->rtp));
1279 srtp_crypto_policy_set_aes_gcm_256_16_auth(&(policy->rtcp));
1280 break;
1281 #endif
1282 default:
1283 /* Will never happen? */
1284 JANUS_LOG(LOG_WARN, "[SIP-%s] Unsupported SRTP profile\n", session->account.username);
1285 break;
1286 }
1287 policy->ssrc.type = ssrc_any_inbound;
1288 policy->key = key;
1289 policy->next = NULL;
1290 /* Create SRTP context */
1291 srtp_err_status_t res = srtp_create(video ? &session->media.video_srtp_out : &session->media.audio_srtp_out, policy);
1292 if(res != srtp_err_status_ok) {
1293 /* Something went wrong... */
1294 JANUS_LOG(LOG_ERR, "Oops, error creating outbound SRTP session: %d (%s)\n", res, janus_srtp_error_str(res));
1295 g_free(*profile);
1296 *profile = NULL;
1297 g_free(key);
1298 policy->key = NULL;
1299 return -2;
1300 }
1301 /* Base64 encode the salt */
1302 *crypto = g_base64_encode(key, master_length);
1303 if((video && session->media.video_srtp_out) || (!video && session->media.audio_srtp_out)) {
1304 JANUS_LOG(LOG_VERB, "%s outbound SRTP session created\n", video ? "Video" : "Audio");
1305 }
1306 return 0;
1307 }
janus_sip_srtp_set_remote(janus_sip_session * session,gboolean video,const char * profile,const char * crypto)1308 static int janus_sip_srtp_set_remote(janus_sip_session *session, gboolean video, const char *profile, const char *crypto) {
1309 if(session == NULL || profile == NULL || crypto == NULL)
1310 return -1;
1311 /* Which SRTP profile is being negotiated? */
1312 JANUS_LOG(LOG_VERB, "[SIP-%s] %s\n", session->account.username, profile);
1313 gsize key_length = 0, salt_length = 0, master_length = 0;
1314 if(!strcasecmp(profile, "AES_CM_128_HMAC_SHA1_32")) {
1315 session->media.srtp_profile = JANUS_SRTP_AES128_CM_SHA1_32;
1316 key_length = SRTP_MASTER_KEY_LENGTH;
1317 salt_length = SRTP_MASTER_SALT_LENGTH;
1318 master_length = SRTP_MASTER_LENGTH;
1319 } else if(!strcasecmp(profile, "AES_CM_128_HMAC_SHA1_80")) {
1320 session->media.srtp_profile = JANUS_SRTP_AES128_CM_SHA1_80;
1321 key_length = SRTP_MASTER_KEY_LENGTH;
1322 salt_length = SRTP_MASTER_SALT_LENGTH;
1323 master_length = SRTP_MASTER_LENGTH;
1324 #ifdef HAVE_SRTP_AESGCM
1325 } else if(!strcasecmp(profile, "AEAD_AES_128_GCM")) {
1326 session->media.srtp_profile = JANUS_SRTP_AEAD_AES_128_GCM;
1327 key_length = SRTP_AESGCM128_MASTER_KEY_LENGTH;
1328 salt_length = SRTP_AESGCM128_MASTER_SALT_LENGTH;
1329 master_length = SRTP_AESGCM128_MASTER_LENGTH;
1330 } else if(!strcasecmp(profile, "AEAD_AES_256_GCM")) {
1331 session->media.srtp_profile = JANUS_SRTP_AEAD_AES_256_GCM;
1332 key_length = SRTP_AESGCM256_MASTER_KEY_LENGTH;
1333 salt_length = SRTP_AESGCM256_MASTER_SALT_LENGTH;
1334 master_length = SRTP_AESGCM256_MASTER_LENGTH;
1335 #endif
1336 } else {
1337 JANUS_LOG(LOG_WARN, "[SIP-%s] Unsupported SRTP profile %s\n", session->account.username, profile);
1338 return -2;
1339 }
1340 JANUS_LOG(LOG_VERB, "[SIP-%s] Key/Salt/Master: %zu/%zu/%zu\n",
1341 session->account.username, master_length, key_length, salt_length);
1342 /* Base64 decode the crypto string and set it as the remote SRTP context */
1343 gsize len = 0;
1344 guchar *decoded = g_base64_decode(crypto, &len);
1345 if(len < master_length) {
1346 /* FIXME Can this happen? */
1347 g_free(decoded);
1348 return -3;
1349 }
1350 /* Set SRTP policies */
1351 srtp_policy_t *policy = video ? &session->media.video_remote_policy : &session->media.audio_remote_policy;
1352 switch(session->media.srtp_profile) {
1353 case JANUS_SRTP_AES128_CM_SHA1_32:
1354 srtp_crypto_policy_set_aes_cm_128_hmac_sha1_32(&(policy->rtp));
1355 srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(&(policy->rtcp));
1356 break;
1357 case JANUS_SRTP_AES128_CM_SHA1_80:
1358 srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(&(policy->rtp));
1359 srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(&(policy->rtcp));
1360 break;
1361 #ifdef HAVE_SRTP_AESGCM
1362 case JANUS_SRTP_AEAD_AES_128_GCM:
1363 srtp_crypto_policy_set_aes_gcm_128_16_auth(&(policy->rtp));
1364 srtp_crypto_policy_set_aes_gcm_128_16_auth(&(policy->rtcp));
1365 break;
1366 case JANUS_SRTP_AEAD_AES_256_GCM:
1367 srtp_crypto_policy_set_aes_gcm_256_16_auth(&(policy->rtp));
1368 srtp_crypto_policy_set_aes_gcm_256_16_auth(&(policy->rtcp));
1369 break;
1370 #endif
1371 default:
1372 /* Will never happen? */
1373 JANUS_LOG(LOG_WARN, "[SIP-%s] Unsupported SRTP profile\n", session->account.username);
1374 break;
1375 }
1376 policy->ssrc.type = ssrc_any_inbound;
1377 policy->key = decoded;
1378 policy->next = NULL;
1379 /* Create SRTP context */
1380 srtp_err_status_t res = srtp_create(video ? &session->media.video_srtp_in : &session->media.audio_srtp_in, policy);
1381 if(res != srtp_err_status_ok) {
1382 /* Something went wrong... */
1383 JANUS_LOG(LOG_ERR, "Oops, error creating inbound SRTP session: %d (%s)\n", res, janus_srtp_error_str(res));
1384 g_free(decoded);
1385 policy->key = NULL;
1386 return -2;
1387 }
1388 if((video && session->media.video_srtp_in) || (!video && session->media.audio_srtp_in)) {
1389 JANUS_LOG(LOG_VERB, "%s inbound SRTP session created\n", video ? "Video" : "Audio");
1390 }
1391 return 0;
1392 }
janus_sip_srtp_cleanup(janus_sip_session * session)1393 static void janus_sip_srtp_cleanup(janus_sip_session *session) {
1394 if(session == NULL)
1395 return;
1396 session->media.require_srtp = FALSE;
1397 session->media.has_srtp_local_audio = FALSE;
1398 session->media.has_srtp_local_video = FALSE;
1399 session->media.has_srtp_remote_audio = FALSE;
1400 session->media.has_srtp_remote_video = FALSE;
1401 session->media.srtp_profile = 0;
1402 /* Audio */
1403 session->media.audio_srtp_tag = 0;
1404 if(session->media.audio_srtp_out)
1405 srtp_dealloc(session->media.audio_srtp_out);
1406 session->media.audio_srtp_out = NULL;
1407 g_free(session->media.audio_local_policy.key);
1408 session->media.audio_local_policy.key = NULL;
1409 if(session->media.audio_srtp_in)
1410 srtp_dealloc(session->media.audio_srtp_in);
1411 session->media.audio_srtp_in = NULL;
1412 g_free(session->media.audio_remote_policy.key);
1413 session->media.audio_remote_policy.key = NULL;
1414 if(session->media.audio_srtp_local_profile) {
1415 g_free(session->media.audio_srtp_local_profile);
1416 session->media.audio_srtp_local_profile = NULL;
1417 }
1418 if(session->media.audio_srtp_local_crypto) {
1419 g_free(session->media.audio_srtp_local_crypto);
1420 session->media.audio_srtp_local_crypto = NULL;
1421 }
1422 /* Video */
1423 session->media.video_srtp_tag = 0;
1424 if(session->media.video_srtp_out)
1425 srtp_dealloc(session->media.video_srtp_out);
1426 session->media.video_srtp_out = NULL;
1427 g_free(session->media.video_local_policy.key);
1428 session->media.video_local_policy.key = NULL;
1429 if(session->media.video_srtp_in)
1430 srtp_dealloc(session->media.video_srtp_in);
1431 session->media.video_srtp_in = NULL;
1432 g_free(session->media.video_remote_policy.key);
1433 session->media.video_remote_policy.key = NULL;
1434 if(session->media.video_srtp_local_profile) {
1435 g_free(session->media.video_srtp_local_profile);
1436 session->media.video_srtp_local_profile = NULL;
1437 }
1438 if(session->media.video_srtp_local_crypto) {
1439 g_free(session->media.video_srtp_local_crypto);
1440 session->media.video_srtp_local_crypto = NULL;
1441 }
1442 }
1443
janus_sip_media_reset(janus_sip_session * session)1444 static void janus_sip_media_reset(janus_sip_session *session) {
1445 if(session == NULL)
1446 return;
1447 g_free(session->media.remote_audio_ip);
1448 session->media.remote_audio_ip = NULL;
1449 g_free(session->media.remote_video_ip);
1450 session->media.remote_video_ip = NULL;
1451 session->media.earlymedia = FALSE;
1452 session->media.update = FALSE;
1453 session->media.updated = FALSE;
1454 session->media.autoaccept_reinvites = TRUE;
1455 session->media.ready = FALSE;
1456 session->media.require_srtp = FALSE;
1457 session->media.on_hold = FALSE;
1458 session->media.has_audio = FALSE;
1459 session->media.audio_pt = -1;
1460 session->media.audio_pt_name = NULL; /* Immutable string, no need to free*/
1461 session->media.audio_send = TRUE;
1462 session->media.pre_hold_audio_dir = JANUS_SDP_DEFAULT;
1463 session->media.has_video = FALSE;
1464 session->media.video_pt = -1;
1465 session->media.video_pt_name = NULL; /* Immutable string, no need to free*/
1466 session->media.video_send = TRUE;
1467 session->media.pre_hold_video_dir = JANUS_SDP_DEFAULT;
1468 session->media.video_orientation_extension_id = -1;
1469 session->media.audio_level_extension_id = -1;
1470 janus_rtp_switching_context_reset(&session->media.context);
1471 }
1472
1473
1474 /* Sofia Event thread */
1475 gpointer janus_sip_sofia_thread(gpointer user_data);
1476 /* Sofia callbacks */
1477 void janus_sip_sofia_callback(nua_event_t event, int status, char const *phrase, nua_t *nua, nua_magic_t *magic, nua_handle_t *nh, nua_hmagic_t *hmagic, sip_t const *sip, tagi_t tags[]);
1478 /* SDP parsing and manipulation */
1479 void janus_sip_sdp_process(janus_sip_session *session, janus_sdp *sdp, gboolean answer, gboolean update, gboolean *changed);
1480 char *janus_sip_sdp_manipulate(janus_sip_session *session, janus_sdp *sdp, gboolean answer);
1481 /* Media */
1482 static int janus_sip_allocate_local_ports(janus_sip_session *session, gboolean update);
1483 static void *janus_sip_relay_thread(void *data);
1484 static void janus_sip_media_cleanup(janus_sip_session *session);
1485
1486
1487 /* URI parsing utilies */
1488
1489 #define JANUS_SIP_URI_MAXLEN 1024
1490 typedef struct {
1491 char data[JANUS_SIP_URI_MAXLEN];
1492 url_t url[1];
1493 } janus_sip_uri_t;
1494
1495 /* Parses a SIP URI (SIPS is not supported), returns 0 on success, -1 otherwise */
janus_sip_parse_uri(janus_sip_uri_t * sip_uri,const char * data)1496 static int janus_sip_parse_uri(janus_sip_uri_t *sip_uri, const char *data) {
1497 g_strlcpy(sip_uri->data, data, JANUS_SIP_URI_MAXLEN);
1498 if(url_d(sip_uri->url, sip_uri->data) < 0 || sip_uri->url->url_type != url_sip)
1499 return -1;
1500 return 0;
1501 }
1502
1503 /* Similar to the above function, but it also accepts SIPS URIs */
janus_sip_parse_proxy_uri(janus_sip_uri_t * sip_uri,const char * data)1504 static int janus_sip_parse_proxy_uri(janus_sip_uri_t *sip_uri, const char *data) {
1505 g_strlcpy(sip_uri->data, data, JANUS_SIP_URI_MAXLEN);
1506 if(url_d(sip_uri->url, sip_uri->data) < 0 || (sip_uri->url->url_type != url_sip && sip_uri->url->url_type != url_sips))
1507 return -1;
1508 return 0;
1509 }
1510
1511 /* Helper to strip quotes from a SIP Reason Header */
janus_sip_remove_quotes(char * str)1512 static void janus_sip_remove_quotes(char *str) {
1513 size_t len = strlen(str);
1514 if(len > 2 && str[0] == '"' && str[len-1] == '"') {
1515 memmove(str, str+1, len-2);
1516 str[len-2] = 0;
1517 }
1518 }
1519
janus_sip_get_incoming_headers(const sip_t * sip,const janus_sip_session * session)1520 static json_t *janus_sip_get_incoming_headers(const sip_t *sip, const janus_sip_session *session) {
1521 json_t *headers = json_object();
1522 if(!sip)
1523 return headers;
1524 sip_unknown_t *unknown_header = sip->sip_unknown;
1525 while(unknown_header != NULL) {
1526 GList *temp = session->incoming_header_prefixes;
1527 while(temp != NULL) {
1528 char *header_prefix = (char *)temp->data;
1529 if(header_prefix != NULL && unknown_header->un_name != NULL) {
1530 if(strncasecmp(unknown_header->un_name, header_prefix, strlen(header_prefix)) == 0) {
1531 const char *header_name = g_strdup(unknown_header->un_name);
1532 json_object_set(headers, header_name, json_string(unknown_header->un_value));
1533 break;
1534 }
1535 }
1536 temp = temp->next;
1537 }
1538 unknown_header = unknown_header->un_next;
1539 }
1540 return headers;
1541 }
1542
1543 /* Error codes */
1544 #define JANUS_SIP_ERROR_UNKNOWN_ERROR 499
1545 #define JANUS_SIP_ERROR_NO_MESSAGE 440
1546 #define JANUS_SIP_ERROR_INVALID_JSON 441
1547 #define JANUS_SIP_ERROR_INVALID_REQUEST 442
1548 #define JANUS_SIP_ERROR_MISSING_ELEMENT 443
1549 #define JANUS_SIP_ERROR_INVALID_ELEMENT 444
1550 #define JANUS_SIP_ERROR_ALREADY_REGISTERED 445
1551 #define JANUS_SIP_ERROR_INVALID_ADDRESS 446
1552 #define JANUS_SIP_ERROR_WRONG_STATE 447
1553 #define JANUS_SIP_ERROR_MISSING_SDP 448
1554 #define JANUS_SIP_ERROR_LIBSOFIA_ERROR 449
1555 #define JANUS_SIP_ERROR_IO_ERROR 450
1556 #define JANUS_SIP_ERROR_RECORDING_ERROR 451
1557 #define JANUS_SIP_ERROR_TOO_STRICT 452
1558 #define JANUS_SIP_ERROR_HELPER_ERROR 453
1559 #define JANUS_SIP_ERROR_NO_SUCH_CALLID 454
1560
1561
1562 /* Random string helper (for call-ids) */
1563 static char charset[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
janus_sip_random_string(int length,char * buffer)1564 static void janus_sip_random_string(int length, char *buffer) {
1565 if(length > 0 && buffer) {
1566 int l = (int)(sizeof(charset)-1);
1567 int i=0;
1568 for(i=0; i<length; i++) {
1569 int key = janus_random_uint32() % l;
1570 buffer[i] = charset[key];
1571 }
1572 buffer[length-1] = '\0';
1573 }
1574 }
1575
janus_sip_parse_custom_headers(json_t * root,char * custom_headers,size_t size)1576 static void janus_sip_parse_custom_headers(json_t *root, char *custom_headers, size_t size) {
1577 custom_headers[0] = '\0';
1578 json_t *headers = json_object_get(root, "headers");
1579 if(headers) {
1580 if(json_object_size(headers) > 0) {
1581 /* Parse custom headers */
1582 const char *key = NULL;
1583 json_t *value = NULL;
1584 void *iter = json_object_iter(headers);
1585 while(iter != NULL) {
1586 key = json_object_iter_key(iter);
1587 value = json_object_get(headers, key);
1588 if(value == NULL || !json_is_string(value)) {
1589 JANUS_LOG(LOG_WARN, "Skipping header '%s': value is not a string\n", key);
1590 iter = json_object_iter_next(headers, iter);
1591 continue;
1592 }
1593 char h[255];
1594 g_snprintf(h, 255, "%s: %s\r\n", key, json_string_value(value));
1595 JANUS_LOG(LOG_VERB, "Adding custom header, %s\n", h);
1596 janus_strlcat(custom_headers, h, size);
1597 iter = json_object_iter_next(headers, iter);
1598 }
1599 }
1600 }
1601 }
1602
janus_sip_parse_custom_contact_params(json_t * root,char * custom_params,size_t size)1603 static void janus_sip_parse_custom_contact_params(json_t *root, char *custom_params, size_t size) {
1604 custom_params[0] = '\0';
1605 json_t *params = json_object_get(root, "contact_params");
1606 gboolean first = TRUE;
1607 if(params) {
1608 if(json_object_size(params) > 0) {
1609 /* Parse custom Contact URI params */
1610 const char *key = NULL;
1611 json_t *value = NULL;
1612 void *iter = json_object_iter(params);
1613 while(iter != NULL) {
1614 key = json_object_iter_key(iter);
1615 value = json_object_get(params, key);
1616 if(value == NULL || !json_is_string(value)) {
1617 JANUS_LOG(LOG_WARN, "Skipping param '%s': value is not a string\n", key);
1618 iter = json_object_iter_next(params, iter);
1619 continue;
1620 }
1621 char h[255];
1622 if(first) {
1623 first = FALSE;
1624 g_snprintf(h, 255, "%s=%s", key, json_string_value(value));
1625 } else {
1626 g_snprintf(h, 255, ";%s=%s", key, json_string_value(value));
1627 }
1628 JANUS_LOG(LOG_VERB, "Adding custom param, %s\n", h);
1629 janus_strlcat(custom_params, h, size);
1630 iter = json_object_iter_next(params, iter);
1631 }
1632 }
1633 }
1634 }
1635
1636 /* Sofia SIP logger function: when the Event Handlers mechanism is enabled,
1637 * we use this to intercept SIP messages sent by the stack (received
1638 * messages are more easily recoverable in janus_sip_sofia_callback) */
1639 char sofia_log[2048];
1640 char call_id[255];
1641 gboolean skip = FALSE, started = FALSE, append = FALSE;
janus_sip_sofia_logger(void * stream,char const * fmt,va_list ap)1642 static void janus_sip_sofia_logger(void *stream, char const *fmt, va_list ap) {
1643 if(!fmt)
1644 return;
1645 char line[255];
1646 #pragma GCC diagnostic ignored "-Wformat-nonliteral"
1647 #pragma GCC diagnostic ignored "-Wsuggest-attribute=format"
1648 g_vsnprintf(line, sizeof(line), fmt, ap);
1649 #pragma GCC diagnostic warning "-Wformat-nonliteral"
1650 #pragma GCC diagnostic warning "-Wsuggest-attribute=format"
1651 if(skip) {
1652 /* This is a message we're not interested in: just check when it ends */
1653 if(line[3] == '-') {
1654 skip = FALSE;
1655 append = FALSE;
1656 }
1657 return;
1658 }
1659 if(append) {
1660 /* We're copying a message in our buffer: check if this is the end */
1661 if(line[3] == '-') {
1662 if(!started) {
1663 /* Ok, start appending from now on */
1664 started = TRUE;
1665 sofia_log[0] = '\0';
1666 call_id[0] = '\0';
1667 } else {
1668 /* Message ended, handle it */
1669 skip = FALSE;
1670 append = FALSE;
1671 /* Look for the session this message belongs to */
1672 janus_sip_session *session = NULL;
1673 janus_mutex_lock(&sessions_mutex);
1674 if(strlen(call_id))
1675 session = g_hash_table_lookup(callids, call_id);
1676 if(!session) {
1677 /* Couldn't find any SIP session with that Call-ID, check the request */
1678 if(strstr(sofia_log, "REGISTER") == sofia_log || strstr(sofia_log, "SIP/2.0 ") == sofia_log) {
1679 /* FIXME This is a REGISTER or a response code:
1680 * check the To header and get the identity from there */
1681 char *from = strstr(sofia_log, "To: ");
1682 if(from) {
1683 from = from+4;
1684 char *start = strstr(from, "<");
1685 if(start) {
1686 start++;
1687 char *end = strstr(from, ">");
1688 if(end) {
1689 *end = '\0';
1690 g_snprintf(call_id, sizeof(call_id), "%s", start);
1691 *end = '>';
1692 session = g_hash_table_lookup(identities, call_id);
1693 }
1694 }
1695 }
1696 }
1697 }
1698 if(session)
1699 janus_refcount_increase(&session->ref);
1700 janus_mutex_unlock(&sessions_mutex);
1701 if(session) {
1702 /* Notify event handlers about the content of the whole outgoing SIP message */
1703 json_t *info = json_object();
1704 json_object_set_new(info, "event", json_string("sip-out"));
1705 json_object_set_new(info, "sip", json_string(sofia_log));
1706 gateway->notify_event(&janus_sip_plugin, session->handle, info);
1707 janus_refcount_decrease(&session->ref);
1708 } else {
1709 JANUS_LOG(LOG_WARN, "Couldn't find a session associated to this message, dropping it...\n%s", sofia_log);
1710 }
1711 /* Done, reset the buffers */
1712 sofia_log[0] = '\0';
1713 call_id[0] = '\0';
1714 }
1715 return;
1716 }
1717 if(strlen(line) == 1) {
1718 /* Append a carriage and return */
1719 janus_strlcat(sofia_log, "\r\n", sizeof(sofia_log));
1720 } else {
1721 /* If this is an OPTIONS, we don't care: drop it */
1722 char *header = &line[3];
1723 if(strstr(header, "OPTIONS") == header) {
1724 skip = TRUE;
1725 return;
1726 }
1727 /* Is this a Call-ID header? Keep note of it */
1728 if(strstr(header, "Call-ID") == header) {
1729 g_snprintf(call_id, sizeof(call_id), "%s", header+9);
1730 }
1731 /* Append the line to our buffer, skipping the indent */
1732 janus_strlcat(sofia_log, &line[3], sizeof(sofia_log));
1733 }
1734 return;
1735 }
1736 /* Still waiting to decide if this is a message we need */
1737 if(line[0] == 's' && line[1] == 'e' && line[2] == 'n' && line[3] == 'd' && line[4] == ' ') {
1738 /* An outgoing message is going to be logged, prepare for that */
1739 skip = FALSE;
1740 started = FALSE;
1741 append = TRUE;
1742 int length = atoi(&line[5]);
1743 JANUS_LOG(LOG_HUGE, "Intercepting message (%d bytes)\n", length);
1744 if(strstr(line, "-----"))
1745 started = TRUE;
1746 }
1747 }
1748
1749 /* Helpers to ref/unref sessions with active calls */
janus_sip_ref_active_call(janus_sip_session * session)1750 static void janus_sip_ref_active_call(janus_sip_session *session) {
1751 if(session == NULL)
1752 return;
1753 janus_sip_session *master = session->master;
1754 if(master) {
1755 janus_mutex_lock(&master->mutex);
1756 master->active_calls = g_list_append(master->active_calls, session);
1757 janus_refcount_increase(&session->ref);
1758 janus_mutex_unlock(&master->mutex);
1759 } else {
1760 janus_mutex_lock(&session->mutex);
1761 session->active_calls = g_list_append(session->active_calls, session);
1762 janus_refcount_increase(&session->ref);
1763 janus_mutex_unlock(&session->mutex);
1764 }
1765 }
janus_sip_unref_active_call(janus_sip_session * session)1766 static void janus_sip_unref_active_call(janus_sip_session *session) {
1767 if(session == NULL)
1768 return;
1769 janus_sip_session *master = session->master;
1770 if(master) {
1771 janus_mutex_lock(&master->mutex);
1772 if(g_list_find(master->active_calls, session) != NULL) {
1773 master->active_calls = g_list_remove(master->active_calls, session);
1774 janus_refcount_decrease(&session->ref);
1775 }
1776 janus_mutex_unlock(&master->mutex);
1777 } else {
1778 janus_mutex_lock(&session->mutex);
1779 if(g_list_find(session->active_calls, session) != NULL) {
1780 session->active_calls = g_list_remove(session->active_calls, session);
1781 janus_refcount_decrease(&session->ref);
1782 }
1783 janus_mutex_unlock(&session->mutex);
1784 }
1785 }
1786
1787
1788 /* Plugin implementation */
janus_sip_init(janus_callbacks * callback,const char * config_path)1789 int janus_sip_init(janus_callbacks *callback, const char *config_path) {
1790 if(g_atomic_int_get(&stopping)) {
1791 /* Still stopping from before */
1792 return -1;
1793 }
1794 if(callback == NULL || config_path == NULL) {
1795 /* Invalid arguments */
1796 return -1;
1797 }
1798
1799 /* First of all, let's check what version of Sofia SIP is available */
1800 int sofia_major = 0, sofia_minor = 0, sofia_patch = 0;
1801 if(sscanf(SOFIA_SIP_VERSION, "%d.%d.%d", &sofia_major, &sofia_minor, &sofia_patch) == 3) {
1802 if(sofia_major > 2 || (sofia_major >= 1 && sofia_minor >= 13)) {
1803 /* Versions of Sofia SIP >= 1.13 apparently don't add a Contact header in
1804 * dialogs, so we'll query it ourselves using nua_get_params (see #2597) */
1805 query_contact_header = TRUE;
1806 }
1807 }
1808
1809 /* Read configuration */
1810 char filename[255];
1811 g_snprintf(filename, 255, "%s/%s.jcfg", config_path, JANUS_SIP_PACKAGE);
1812 JANUS_LOG(LOG_VERB, "Configuration file: %s\n", filename);
1813 janus_config *config = janus_config_parse(filename);
1814 if(config == NULL) {
1815 JANUS_LOG(LOG_WARN, "Couldn't find .jcfg configuration file (%s), trying .cfg\n", JANUS_SIP_PACKAGE);
1816 g_snprintf(filename, 255, "%s/%s.cfg", config_path, JANUS_SIP_PACKAGE);
1817 JANUS_LOG(LOG_VERB, "Configuration file: %s\n", filename);
1818 config = janus_config_parse(filename);
1819 }
1820 if(config != NULL) {
1821 janus_config_print(config);
1822
1823 janus_config_category *config_general = janus_config_get_create(config, NULL, janus_config_type_category, "general");
1824 janus_config_item *item = janus_config_get(config, config_general, janus_config_type_item, "local_ip");
1825 if(item && item->value) {
1826 /* Verify that the address is valid */
1827 struct ifaddrs *ifas = NULL;
1828 janus_network_address iface;
1829 janus_network_address_string_buffer ibuf;
1830 if(getifaddrs(&ifas) == -1) {
1831 JANUS_LOG(LOG_ERR, "Unable to acquire list of network devices/interfaces; some configurations may not work as expected... %d (%s)\n",
1832 errno, g_strerror(errno));
1833 } else {
1834 if(janus_network_lookup_interface(ifas, item->value, &iface) != 0) {
1835 JANUS_LOG(LOG_WARN, "Error setting local IP address to %s, falling back to detecting IP address...\n", item->value);
1836 } else {
1837 if(janus_network_address_to_string_buffer(&iface, &ibuf) != 0 || janus_network_address_string_buffer_is_null(&ibuf)) {
1838 JANUS_LOG(LOG_WARN, "Error getting local IP address from %s, falling back to detecting IP address...\n", item->value);
1839 } else {
1840 local_ip = g_strdup(janus_network_address_string_from_buffer(&ibuf));
1841 }
1842 }
1843 freeifaddrs(ifas);
1844 }
1845 }
1846
1847 item = janus_config_get(config, config_general, janus_config_type_item, "local_media_ip");
1848 if(item && item->value)
1849 local_media_ip = g_strdup(item->value);
1850
1851 item = janus_config_get(config, config_general, janus_config_type_item, "sdp_ip");
1852 if(item && item->value) {
1853 sdp_ip = g_strdup(item->value);
1854 JANUS_LOG(LOG_VERB, "IP to advertise in SDP: %s\n", sdp_ip);
1855 }
1856
1857 item = janus_config_get(config, config_general, janus_config_type_item, "keepalive_interval");
1858 if(item && item->value)
1859 keepalive_interval = atoi(item->value);
1860 if(keepalive_interval < 0) {
1861 JANUS_LOG(LOG_ERR, "Invalid SIP keep-alive interval: %d (falling back to default)\n", keepalive_interval);
1862 keepalive_interval = 120;
1863 } else {
1864 JANUS_LOG(LOG_VERB, "SIP keep-alive interval set to %d seconds\n", keepalive_interval);
1865 }
1866
1867 item = janus_config_get(config, config_general, janus_config_type_item, "register_ttl");
1868 if(item && item->value)
1869 register_ttl = atoi(item->value);
1870 if(register_ttl < 0) {
1871 JANUS_LOG(LOG_ERR, "Invalid SIP registration TTL: %d (falling back to default)\n", register_ttl);
1872 register_ttl = JANUS_DEFAULT_REGISTER_TTL;
1873 } else {
1874 JANUS_LOG(LOG_VERB, "SIP registration TTL set to %d seconds\n", register_ttl);
1875 }
1876
1877 item = janus_config_get(config, config_general, janus_config_type_item, "behind_nat");
1878 if(item && item->value)
1879 behind_nat = janus_is_true(item->value);
1880
1881 item = janus_config_get(config, config_general, janus_config_type_item, "user_agent");
1882 if(item && item->value)
1883 user_agent = g_strdup(item->value);
1884 else
1885 user_agent = g_strdup("Janus WebRTC Server SIP Plugin "JANUS_SIP_VERSION_STRING);
1886 JANUS_LOG(LOG_VERB, "SIP User-Agent set to %s\n", user_agent);
1887
1888 item = janus_config_get(config, config_general, janus_config_type_item, "rtp_port_range");
1889 if(item && item->value) {
1890 /* Split in min and max port */
1891 char *maxport = strrchr(item->value, '-');
1892 if(maxport != NULL) {
1893 *maxport = '\0';
1894 maxport++;
1895 if(janus_string_to_uint16(item->value, &rtp_range_min) < 0)
1896 JANUS_LOG(LOG_WARN, "Invalid RTP min port value: %s (assuming 0)\n", item->value);
1897 if(janus_string_to_uint16(maxport, &rtp_range_max) < 0)
1898 JANUS_LOG(LOG_WARN, "Invalid RTP max port value: %s (assuming 0)\n", maxport);
1899 maxport--;
1900 *maxport = '-';
1901 }
1902 if(rtp_range_min > rtp_range_max) {
1903 uint16_t temp_port = rtp_range_min;
1904 rtp_range_min = rtp_range_max;
1905 rtp_range_max = temp_port;
1906 }
1907 if(rtp_range_max == 0)
1908 rtp_range_max = 65535;
1909 JANUS_LOG(LOG_VERB, "SIP RTP/RTCP port range: %u -- %u\n", rtp_range_min, rtp_range_max);
1910 }
1911
1912 item = janus_config_get(config, config_general, janus_config_type_item, "events");
1913 if(item != NULL && item->value != NULL)
1914 notify_events = janus_is_true(item->value);
1915 if(!notify_events && callback->events_is_enabled()) {
1916 JANUS_LOG(LOG_WARN, "Notification of events to handlers disabled for %s\n", JANUS_SIP_NAME);
1917 }
1918
1919 /* Is there any DSCP TOS to apply? */
1920 item = janus_config_get(config, config_general, janus_config_type_item, "dscp_audio_rtp");
1921 if(item && item->value) {
1922 int val = atoi(item->value);
1923 if(val < 0) {
1924 JANUS_LOG(LOG_WARN, "Ignoring dscp_audio_rtp value as it's not a positive integer\n");
1925 } else {
1926 dscp_audio_rtp = val;
1927 }
1928 }
1929 item = janus_config_get(config, config_general, janus_config_type_item, "dscp_video_rtp");
1930 if(item && item->value) {
1931 int val = atoi(item->value);
1932 if(val < 0) {
1933 JANUS_LOG(LOG_WARN, "Ignoring dscp_video_rtp value as it's not a positive integer\n");
1934 } else {
1935 dscp_video_rtp = val;
1936 }
1937 }
1938
1939 janus_config_destroy(config);
1940 }
1941 config = NULL;
1942
1943 if(local_ip == NULL) {
1944 local_ip = janus_network_detect_local_ip_as_string(janus_network_query_options_any_ip);
1945 if(local_ip == NULL) {
1946 JANUS_LOG(LOG_WARN, "Couldn't find any address! using 127.0.0.1 as the local IP... (which is NOT going to work out of your machine)\n");
1947 local_ip = g_strdup("127.0.0.1");
1948 }
1949 }
1950 JANUS_LOG(LOG_VERB, "Local IP set to %s\n", local_ip);
1951
1952 /* Setup sofia */
1953 su_init();
1954 if(notify_events && callback->events_is_enabled()) {
1955 JANUS_LOG(LOG_WARN, "sofia-sip logs are going to be redirected and they will not be shown in the process output\n");
1956 /* Enable the transport logging, as we want to have access to the SIP messages */
1957 setenv("TPORT_LOG", "1", 1);
1958 su_log_redirect(NULL, janus_sip_sofia_logger, NULL);
1959 }
1960
1961 sessions = g_hash_table_new_full(NULL, NULL, NULL, (GDestroyNotify)janus_sip_session_destroy);
1962 identities = g_hash_table_new(g_str_hash, g_str_equal);
1963 callids = g_hash_table_new(g_str_hash, g_str_equal);
1964 messageids = g_hash_table_new_full(NULL, NULL, (GDestroyNotify)g_free, (GDestroyNotify)janus_sip_session_dereference);
1965 masters = g_hash_table_new(NULL, NULL);
1966 transfers = g_hash_table_new_full(NULL, NULL, NULL, (GDestroyNotify)janus_sip_transfer_destroy);
1967 messages = g_async_queue_new_full((GDestroyNotify) janus_sip_message_free);
1968 /* This is the callback we'll need to invoke to contact the Janus core */
1969 gateway = callback;
1970
1971 g_atomic_int_set(&initialized, 1);
1972
1973 /* Launch the thread that will handle incoming messages */
1974 GError *error = NULL;
1975 handler_thread = g_thread_try_new("sip handler", janus_sip_handler, NULL, &error);
1976 if(error != NULL) {
1977 g_atomic_int_set(&initialized, 0);
1978 JANUS_LOG(LOG_ERR, "Got error %d (%s) trying to launch the SIP handler thread...\n",
1979 error->code, error->message ? error->message : "??");
1980 g_error_free(error);
1981 return -1;
1982 }
1983 JANUS_LOG(LOG_INFO, "%s initialized!\n", JANUS_SIP_NAME);
1984 return 0;
1985 }
1986
janus_sip_destroy(void)1987 void janus_sip_destroy(void) {
1988 if(!g_atomic_int_get(&initialized))
1989 return;
1990 g_atomic_int_set(&stopping, 1);
1991
1992 g_async_queue_push(messages, &exit_message);
1993 if(handler_thread != NULL) {
1994 g_thread_join(handler_thread);
1995 handler_thread = NULL;
1996 }
1997 /* FIXME We should destroy the sessions cleanly */
1998 janus_mutex_lock(&sessions_mutex);
1999 g_hash_table_destroy(sessions);
2000 g_hash_table_destroy(callids);
2001 g_hash_table_destroy(messageids);
2002 g_hash_table_destroy(identities);
2003 g_hash_table_destroy(masters);
2004 g_hash_table_destroy(transfers);
2005 sessions = NULL;
2006 callids = NULL;
2007 messageids = NULL;
2008 identities = NULL;
2009 masters = NULL;
2010 transfers = NULL;
2011 janus_mutex_unlock(&sessions_mutex);
2012 g_async_queue_unref(messages);
2013 messages = NULL;
2014 g_atomic_int_set(&initialized, 0);
2015 g_atomic_int_set(&stopping, 0);
2016
2017 /* Deinitialize sofia */
2018 su_deinit();
2019
2020 g_free(local_ip);
2021 g_free(local_media_ip);
2022 g_free(sdp_ip);
2023
2024 JANUS_LOG(LOG_INFO, "%s destroyed!\n", JANUS_SIP_NAME);
2025 }
2026
janus_sip_get_api_compatibility(void)2027 int janus_sip_get_api_compatibility(void) {
2028 /* Important! This is what your plugin MUST always return: don't lie here or bad things will happen */
2029 return JANUS_PLUGIN_API_VERSION;
2030 }
2031
janus_sip_get_version(void)2032 int janus_sip_get_version(void) {
2033 return JANUS_SIP_VERSION;
2034 }
2035
janus_sip_get_version_string(void)2036 const char *janus_sip_get_version_string(void) {
2037 return JANUS_SIP_VERSION_STRING;
2038 }
2039
janus_sip_get_description(void)2040 const char *janus_sip_get_description(void) {
2041 return JANUS_SIP_DESCRIPTION;
2042 }
2043
janus_sip_get_name(void)2044 const char *janus_sip_get_name(void) {
2045 return JANUS_SIP_NAME;
2046 }
2047
janus_sip_get_author(void)2048 const char *janus_sip_get_author(void) {
2049 return JANUS_SIP_AUTHOR;
2050 }
2051
janus_sip_get_package(void)2052 const char *janus_sip_get_package(void) {
2053 return JANUS_SIP_PACKAGE;
2054 }
2055
janus_sip_lookup_session(janus_plugin_session * handle)2056 static janus_sip_session *janus_sip_lookup_session(janus_plugin_session *handle) {
2057 janus_sip_session *session = NULL;
2058 if(g_hash_table_contains(sessions, handle)) {
2059 session = (janus_sip_session *)handle->plugin_handle;
2060 }
2061 return session;
2062 }
2063
janus_sip_create_session(janus_plugin_session * handle,int * error)2064 void janus_sip_create_session(janus_plugin_session *handle, int *error) {
2065 if(g_atomic_int_get(&stopping) || !g_atomic_int_get(&initialized)) {
2066 *error = -1;
2067 return;
2068 }
2069 janus_sip_session *session = g_malloc0(sizeof(janus_sip_session));
2070 session->handle = handle;
2071 session->account.identity = NULL;
2072 session->account.force_udp = FALSE;
2073 session->account.force_tcp = FALSE;
2074 session->account.sips = TRUE;
2075 session->account.rfc2543_cancel = FALSE;
2076 session->account.username = NULL;
2077 session->account.display_name = NULL;
2078 session->account.user_agent = NULL;
2079 session->account.authuser = NULL;
2080 session->account.secret = NULL;
2081 session->account.secret_type = janus_sip_secret_type_unknown;
2082 session->account.sip_port = 0;
2083 session->account.proxy = NULL;
2084 session->account.outbound_proxy = NULL;
2085 session->account.registration_status = janus_sip_registration_status_unregistered;
2086 session->status = janus_sip_call_status_idle;
2087 session->stack = NULL;
2088 session->transaction = NULL;
2089 session->callee = NULL;
2090 session->callid = NULL;
2091 session->sdp = NULL;
2092 session->hangup_reason_header = NULL;
2093 session->media.remote_audio_ip = NULL;
2094 session->media.remote_video_ip = NULL;
2095 session->media.earlymedia = FALSE;
2096 session->media.update = FALSE;
2097 session->media.autoaccept_reinvites = TRUE;
2098 session->media.ready = FALSE;
2099 session->media.require_srtp = FALSE;
2100 session->media.has_srtp_local_audio = FALSE;
2101 session->media.has_srtp_local_video = FALSE;
2102 session->media.has_srtp_remote_audio = FALSE;
2103 session->media.has_srtp_remote_video = FALSE;
2104 session->media.srtp_profile = 0;
2105 session->media.audio_srtp_local_profile = NULL;
2106 session->media.audio_srtp_local_crypto = NULL;
2107 session->media.video_srtp_local_profile = NULL;
2108 session->media.video_srtp_local_crypto = NULL;
2109 session->media.on_hold = FALSE;
2110 session->media.has_audio = FALSE;
2111 session->media.audio_rtp_fd = -1;
2112 session->media.audio_rtcp_fd= -1;
2113 session->media.local_audio_rtp_port = 0;
2114 session->media.remote_audio_rtp_port = 0;
2115 session->media.local_audio_rtcp_port = 0;
2116 session->media.remote_audio_rtcp_port = 0;
2117 session->media.audio_ssrc = 0;
2118 session->media.audio_ssrc_peer = 0;
2119 session->media.audio_pt = -1;
2120 session->media.audio_pt_name = NULL;
2121 session->media.audio_send = TRUE;
2122 session->media.pre_hold_audio_dir = JANUS_SDP_DEFAULT;
2123 session->media.has_video = FALSE;
2124 session->media.video_rtp_fd = -1;
2125 session->media.video_rtcp_fd= -1;
2126 session->media.local_video_rtp_port = 0;
2127 session->media.remote_video_rtp_port = 0;
2128 session->media.local_video_rtcp_port = 0;
2129 session->media.remote_video_rtcp_port = 0;
2130 session->media.video_ssrc = 0;
2131 session->media.video_ssrc_peer = 0;
2132 session->media.simulcast_ssrc = 0;
2133 session->media.video_pt = -1;
2134 session->media.video_pt_name = NULL;
2135 session->media.video_send = TRUE;
2136 session->media.pre_hold_video_dir = JANUS_SDP_DEFAULT;
2137 session->media.video_orientation_extension_id = -1;
2138 session->media.audio_level_extension_id = -1;
2139 /* Initialize the RTP context */
2140 janus_rtp_switching_context_reset(&session->media.context);
2141 session->media.pipefd[0] = -1;
2142 session->media.pipefd[1] = -1;
2143 session->media.updated = FALSE;
2144 session->media.audio_remote_policy.ssrc.type = ssrc_any_inbound;
2145 session->media.audio_local_policy.ssrc.type = ssrc_any_inbound;
2146 session->media.video_remote_policy.ssrc.type = ssrc_any_inbound;
2147 session->media.video_local_policy.ssrc.type = ssrc_any_inbound;
2148 janus_mutex_init(&session->rec_mutex);
2149 g_atomic_int_set(&session->establishing, 0);
2150 g_atomic_int_set(&session->established, 0);
2151 g_atomic_int_set(&session->hangingup, 0);
2152 g_atomic_int_set(&session->destroyed, 0);
2153 janus_mutex_init(&session->mutex);
2154 handle->plugin_handle = session;
2155 janus_refcount_init(&session->ref, janus_sip_session_free);
2156
2157 janus_mutex_lock(&sessions_mutex);
2158 g_hash_table_insert(sessions, handle, session);
2159 janus_mutex_unlock(&sessions_mutex);
2160
2161 return;
2162 }
2163
janus_sip_destroy_session(janus_plugin_session * handle,int * error)2164 void janus_sip_destroy_session(janus_plugin_session *handle, int *error) {
2165 if(g_atomic_int_get(&stopping) || !g_atomic_int_get(&initialized)) {
2166 *error = -1;
2167 return;
2168 }
2169 janus_mutex_lock(&sessions_mutex);
2170 janus_sip_session *session = janus_sip_lookup_session(handle);
2171 if(!session) {
2172 janus_mutex_unlock(&sessions_mutex);
2173 JANUS_LOG(LOG_ERR, "No SIP session associated with this handle...\n");
2174 *error = -2;
2175 return;
2176 }
2177 JANUS_LOG(LOG_VERB, "Destroying SIP session (%s)...\n", session->account.username ? session->account.username : "unregistered user");
2178 janus_sip_hangup_media_internal(handle);
2179 /* If this is a master or helper session, update the related sessions */
2180 if(session->master_id != 0) {
2181 if(session->master == NULL) {
2182 /* This is the master, remove it from the list */
2183 g_hash_table_remove(masters, GUINT_TO_POINTER(session->master_id));
2184 /* Remove the helper sessions */
2185 janus_mutex_lock(&session->mutex);
2186 GList *temp = NULL;
2187 while(session->helpers != NULL) {
2188 temp = session->helpers;
2189 session->helpers = g_list_remove_link(session->helpers, temp);
2190 janus_sip_session *helper = (janus_sip_session *)temp->data;
2191 if(helper != NULL && helper->handle != NULL) {
2192 /* Get rid of this helper */
2193 janus_refcount_decrease(&session->ref);
2194 janus_refcount_decrease(&helper->ref);
2195 gateway->end_session(helper->handle);
2196 }
2197 g_list_free(temp);
2198 }
2199 janus_mutex_unlock(&session->mutex);
2200 } else {
2201 /* This is a helper session, remove it from the list and remove the references */
2202 janus_sip_session *master = session->master;
2203 janus_mutex_lock(&master->mutex);
2204 gboolean found = (g_list_find(master->helpers, session) != NULL);
2205 if(found) {
2206 master->helpers = g_list_remove(master->helpers, session);
2207 janus_refcount_decrease(&session->ref);
2208 janus_refcount_decrease(&master->ref);
2209 }
2210 janus_mutex_unlock(&master->mutex);
2211 }
2212 }
2213 /* If this session was involved in a transfer, get rid of the reference */
2214 if(session->refer_id) {
2215 g_hash_table_remove(transfers, GUINT_TO_POINTER(session->refer_id));
2216 session->refer_id = 0;
2217 }
2218 /* Shutdown the NUA */
2219 if(session->stack) {
2220 janus_mutex_lock(&session->stack->smutex);
2221 if(session->stack->s_nua)
2222 nua_shutdown(session->stack->s_nua);
2223 janus_mutex_unlock(&session->stack->smutex);
2224 }
2225 g_hash_table_remove(sessions, handle);
2226 janus_mutex_unlock(&sessions_mutex);
2227 return;
2228 }
2229
janus_sip_query_session(janus_plugin_session * handle)2230 json_t *janus_sip_query_session(janus_plugin_session *handle) {
2231 if(g_atomic_int_get(&stopping) || !g_atomic_int_get(&initialized)) {
2232 return NULL;
2233 }
2234 janus_mutex_lock(&sessions_mutex);
2235 janus_sip_session *session = janus_sip_lookup_session(handle);
2236 if(!session) {
2237 janus_mutex_unlock(&sessions_mutex);
2238 JANUS_LOG(LOG_ERR, "No session associated with this handle...\n");
2239 return NULL;
2240 }
2241 janus_refcount_increase(&session->ref);
2242 janus_mutex_unlock(&sessions_mutex);
2243 /* Provide some generic info, e.g., if we're in a call and with whom */
2244 json_t *info = json_object();
2245 if(session->master != NULL) {
2246 /* This is an helper session, provide the details for the master session */
2247 json_object_set_new(info, "helper", json_true());
2248 json_t *master = json_object();
2249 json_object_set_new(master, "username", session->master->account.username ? json_string(session->master->account.username) : NULL);
2250 json_object_set_new(master, "authuser", session->master->account.authuser ? json_string(session->master->account.authuser) : NULL);
2251 json_object_set_new(master, "secret", session->master->account.secret ? json_string("(hidden)") : NULL);
2252 json_object_set_new(master, "display_name", session->master->account.display_name ? json_string(session->master->account.display_name) : NULL);
2253 json_object_set_new(master, "user_agent", session->master->account.user_agent ? json_string(session->master->account.user_agent) : NULL);
2254 json_object_set_new(master, "identity", session->master->account.identity ? json_string(session->master->account.identity) : NULL);
2255 json_object_set_new(master, "registration_status", json_string(janus_sip_registration_status_string(session->master->account.registration_status)));
2256 json_object_set_new(info, "master", master);
2257 }
2258 json_object_set_new(info, "username", session->account.username ? json_string(session->account.username) : NULL);
2259 json_object_set_new(info, "authuser", session->account.authuser ? json_string(session->account.authuser) : NULL);
2260 json_object_set_new(info, "secret", session->account.secret ? json_string("(hidden)") : NULL);
2261 json_object_set_new(info, "display_name", session->account.display_name ? json_string(session->account.display_name) : NULL);
2262 json_object_set_new(info, "user_agent", session->account.user_agent ? json_string(session->account.user_agent) : NULL);
2263 json_object_set_new(info, "identity", session->account.identity ? json_string(session->account.identity) : NULL);
2264 json_object_set_new(info, "registration_status", json_string(janus_sip_registration_status_string(session->account.registration_status)));
2265 json_object_set_new(info, "call_status", json_string(janus_sip_call_status_string(session->status)));
2266 janus_mutex_lock(&session->mutex);
2267 if(session->helpers != NULL)
2268 json_object_set_new(info, "helpers", json_integer(g_list_length(session->helpers)));
2269 if(session->callee) {
2270 json_object_set_new(info, "callee", json_string(session->callee));
2271 json_object_set_new(info, "srtp-required", json_string(session->media.require_srtp ? "yes" : "no"));
2272 json_object_set_new(info, "sdes-local-audio", json_string(session->media.has_srtp_local_audio ? "yes" : "no"));
2273 json_object_set_new(info, "sdes-local-video", json_string(session->media.has_srtp_local_video ? "yes" : "no"));
2274 json_object_set_new(info, "sdes-remote-audio", json_string(session->media.has_srtp_remote_audio ? "yes" : "no"));
2275 json_object_set_new(info, "sdes-remote-video", json_string(session->media.has_srtp_remote_video ? "yes" : "no"));
2276 }
2277 janus_mutex_unlock(&session->mutex);
2278 if(session->arc || session->vrc || session->arc_peer || session->vrc_peer) {
2279 json_t *recording = json_object();
2280 if(session->arc && session->arc->filename)
2281 json_object_set_new(recording, "audio", json_string(session->arc->filename));
2282 if(session->vrc && session->vrc->filename)
2283 json_object_set_new(recording, "video", json_string(session->vrc->filename));
2284 if(session->arc_peer && session->arc_peer->filename)
2285 json_object_set_new(recording, "audio-peer", json_string(session->arc_peer->filename));
2286 if(session->vrc_peer && session->vrc_peer->filename)
2287 json_object_set_new(recording, "video-peer", json_string(session->vrc_peer->filename));
2288 json_object_set_new(info, "recording", recording);
2289 }
2290 json_object_set_new(info, "establishing", json_integer(g_atomic_int_get(&session->establishing)));
2291 json_object_set_new(info, "established", json_integer(g_atomic_int_get(&session->established)));
2292 json_object_set_new(info, "hangingup", json_integer(g_atomic_int_get(&session->hangingup)));
2293 json_object_set_new(info, "destroyed", json_integer(g_atomic_int_get(&session->destroyed)));
2294 janus_refcount_decrease(&session->ref);
2295 return info;
2296 }
2297
janus_sip_handle_message(janus_plugin_session * handle,char * transaction,json_t * message,json_t * jsep)2298 struct janus_plugin_result *janus_sip_handle_message(janus_plugin_session *handle, char *transaction, json_t *message, json_t *jsep) {
2299 if(g_atomic_int_get(&stopping) || !g_atomic_int_get(&initialized))
2300 return janus_plugin_result_new(JANUS_PLUGIN_ERROR, g_atomic_int_get(&stopping) ? "Shutting down" : "Plugin not initialized", NULL);
2301
2302 janus_mutex_lock(&sessions_mutex);
2303 janus_sip_session *session = janus_sip_lookup_session(handle);
2304 if(!session) {
2305 janus_mutex_unlock(&sessions_mutex);
2306 return janus_plugin_result_new(JANUS_PLUGIN_ERROR, "No session associated with this handle", NULL);
2307 }
2308 /* Increase the reference counter for this session: we'll decrease it after we handle the message */
2309 janus_refcount_increase(&session->ref);
2310 janus_mutex_unlock(&sessions_mutex);
2311
2312 janus_sip_message *msg = g_malloc(sizeof(janus_sip_message));
2313 msg->handle = handle;
2314 msg->transaction = transaction;
2315 msg->message = message;
2316 msg->jsep = jsep;
2317 g_async_queue_push(messages, msg);
2318
2319 /* All the requests to this plugin are handled asynchronously */
2320 return janus_plugin_result_new(JANUS_PLUGIN_OK_WAIT, NULL, NULL);
2321 }
2322
janus_sip_setup_media(janus_plugin_session * handle)2323 void janus_sip_setup_media(janus_plugin_session *handle) {
2324 JANUS_LOG(LOG_INFO, "[%s-%p] WebRTC media is now available\n", JANUS_SIP_PACKAGE, handle);
2325 if(g_atomic_int_get(&stopping) || !g_atomic_int_get(&initialized))
2326 return;
2327 janus_mutex_lock(&sessions_mutex);
2328 janus_sip_session *session = janus_sip_lookup_session(handle);
2329 if(!session) {
2330 janus_mutex_unlock(&sessions_mutex);
2331 JANUS_LOG(LOG_ERR, "No session associated with this handle...\n");
2332 return;
2333 }
2334 if(g_atomic_int_get(&session->destroyed)) {
2335 janus_mutex_unlock(&sessions_mutex);
2336 return;
2337 }
2338 g_atomic_int_set(&session->established, 1);
2339 g_atomic_int_set(&session->establishing, 0);
2340 g_atomic_int_set(&session->hangingup, 0);
2341 janus_mutex_unlock(&sessions_mutex);
2342 /* TODO Only relay RTP/RTCP when we get this event */
2343 }
2344
janus_sip_incoming_rtp(janus_plugin_session * handle,janus_plugin_rtp * packet)2345 void janus_sip_incoming_rtp(janus_plugin_session *handle, janus_plugin_rtp *packet) {
2346 if(handle == NULL || g_atomic_int_get(&handle->stopped) || g_atomic_int_get(&stopping) || !g_atomic_int_get(&initialized))
2347 return;
2348 if(gateway) {
2349 /* Honour the audio/video active flags */
2350 janus_sip_session *session = (janus_sip_session *)handle->plugin_handle;
2351 if(!session || g_atomic_int_get(&session->destroyed)) {
2352 JANUS_LOG(LOG_ERR, "No session associated with this handle...\n");
2353 return;
2354 }
2355 if(!janus_sip_call_is_established(session))
2356 return;
2357 gboolean video = packet->video;
2358 char *buf = packet->buffer;
2359 uint16_t len = packet->length;
2360 /* Forward to our SIP peer */
2361 if(video) {
2362 if(!session->media.video_send) {
2363 /* Dropping video packet, peer doesn't want to receive it */
2364 return;
2365 }
2366 if(session->media.simulcast_ssrc) {
2367 /* The user is simulcasting: drop everything except the base layer */
2368 janus_rtp_header *header = (janus_rtp_header *)buf;
2369 uint32_t ssrc = ntohl(header->ssrc);
2370 if(ssrc != session->media.simulcast_ssrc) {
2371 JANUS_LOG(LOG_DBG, "Dropping packet (not base simulcast substream)\n");
2372 return;
2373 }
2374 }
2375 if(session->media.video_ssrc == 0) {
2376 janus_rtp_header *header = (janus_rtp_header *)buf;
2377 session->media.video_ssrc = ntohl(header->ssrc);
2378 JANUS_LOG(LOG_VERB, "Got SIP video SSRC: %"SCNu32"\n", session->media.video_ssrc);
2379 }
2380 if(session->media.has_video && session->media.video_rtp_fd != -1) {
2381 /* Save the frame if we're recording */
2382 janus_recorder_save_frame(session->vrc, buf, len);
2383 /* Is SRTP involved? */
2384 if(session->media.has_srtp_local_video) {
2385 char sbuf[2048];
2386 memcpy(&sbuf, buf, len);
2387 int protected = len;
2388 int res = srtp_protect(session->media.video_srtp_out, &sbuf, &protected);
2389 if(res != srtp_err_status_ok) {
2390 janus_rtp_header *header = (janus_rtp_header *)&sbuf;
2391 guint32 timestamp = ntohl(header->timestamp);
2392 guint16 seq = ntohs(header->seq_number);
2393 JANUS_LOG(LOG_ERR, "[SIP-%s] Video SRTP protect error... %s (len=%d-->%d, ts=%"SCNu32", seq=%"SCNu16")...\n",
2394 session->account.username, janus_srtp_error_str(res), len, protected, timestamp, seq);
2395 } else {
2396 /* Forward the frame to the peer */
2397 if(send(session->media.video_rtp_fd, sbuf, protected, 0) < 0) {
2398 janus_rtp_header *header = (janus_rtp_header *)&sbuf;
2399 guint32 timestamp = ntohl(header->timestamp);
2400 guint16 seq = ntohs(header->seq_number);
2401 JANUS_LOG(LOG_HUGE, "[SIP-%s] Error sending SRTP video packet... %s (len=%d, ts=%"SCNu32", seq=%"SCNu16")...\n",
2402 session->account.username, g_strerror(errno), protected, timestamp, seq);
2403 }
2404 }
2405 } else {
2406 /* Forward the frame to the peer */
2407 if(send(session->media.video_rtp_fd, buf, len, 0) < 0) {
2408 janus_rtp_header *header = (janus_rtp_header *)&buf;
2409 guint32 timestamp = ntohl(header->timestamp);
2410 guint16 seq = ntohs(header->seq_number);
2411 JANUS_LOG(LOG_HUGE, "[SIP-%s] Error sending RTP video packet... %s (len=%d, ts=%"SCNu32", seq=%"SCNu16")...\n",
2412 session->account.username, g_strerror(errno), len, timestamp, seq);
2413 }
2414 }
2415 }
2416 } else {
2417 if(!session->media.audio_send) {
2418 /* Dropping audio packet, peer doesn't want to receive it */
2419 return;
2420 }
2421 if(session->media.audio_ssrc == 0) {
2422 janus_rtp_header *header = (janus_rtp_header *)buf;
2423 session->media.audio_ssrc = ntohl(header->ssrc);
2424 JANUS_LOG(LOG_VERB, "Got SIP audio SSRC: %"SCNu32"\n", session->media.audio_ssrc);
2425 }
2426 if(session->media.has_audio && session->media.audio_rtp_fd != -1) {
2427 /* Save the frame if we're recording */
2428 janus_recorder_save_frame(session->arc, buf, len);
2429 /* Is SRTP involved? */
2430 if(session->media.has_srtp_local_audio) {
2431 char sbuf[2048];
2432 memcpy(&sbuf, buf, len);
2433 int protected = len;
2434 int res = srtp_protect(session->media.audio_srtp_out, &sbuf, &protected);
2435 if(res != srtp_err_status_ok) {
2436 janus_rtp_header *header = (janus_rtp_header *)&sbuf;
2437 guint32 timestamp = ntohl(header->timestamp);
2438 guint16 seq = ntohs(header->seq_number);
2439 JANUS_LOG(LOG_ERR, "[SIP-%s] Audio SRTP protect error... %s (len=%d-->%d, ts=%"SCNu32", seq=%"SCNu16")...\n",
2440 session->account.username, janus_srtp_error_str(res), len, protected, timestamp, seq);
2441 } else {
2442 /* Forward the frame to the peer */
2443 if(send(session->media.audio_rtp_fd, sbuf, protected, 0) < 0) {
2444 janus_rtp_header *header = (janus_rtp_header *)&sbuf;
2445 guint32 timestamp = ntohl(header->timestamp);
2446 guint16 seq = ntohs(header->seq_number);
2447 JANUS_LOG(LOG_HUGE, "[SIP-%s] Error sending SRTP audio packet... %s (len=%d, ts=%"SCNu32", seq=%"SCNu16")...\n",
2448 session->account.username, g_strerror(errno), protected, timestamp, seq);
2449 }
2450 }
2451 } else {
2452 /* Forward the frame to the peer */
2453 if(send(session->media.audio_rtp_fd, buf, len, 0) < 0) {
2454 janus_rtp_header *header = (janus_rtp_header *)&buf;
2455 guint32 timestamp = ntohl(header->timestamp);
2456 guint16 seq = ntohs(header->seq_number);
2457 JANUS_LOG(LOG_HUGE, "[SIP-%s] Error sending RTP audio packet... %s (len=%d, ts=%"SCNu32", seq=%"SCNu16")...\n",
2458 session->account.username, g_strerror(errno), len, timestamp, seq);
2459 }
2460 }
2461 }
2462 }
2463 }
2464 }
2465
janus_sip_incoming_rtcp(janus_plugin_session * handle,janus_plugin_rtcp * packet)2466 void janus_sip_incoming_rtcp(janus_plugin_session *handle, janus_plugin_rtcp *packet) {
2467 if(handle == NULL || g_atomic_int_get(&handle->stopped) || g_atomic_int_get(&stopping) || !g_atomic_int_get(&initialized))
2468 return;
2469 if(gateway) {
2470 janus_sip_session *session = (janus_sip_session *)handle->plugin_handle;
2471 if(!session || g_atomic_int_get(&session->destroyed)) {
2472 JANUS_LOG(LOG_ERR, "No session associated with this handle...\n");
2473 return;
2474 }
2475 if(!janus_sip_call_is_established(session))
2476 return;
2477 gboolean video = packet->video;
2478 char *buf = packet->buffer;
2479 uint16_t len = packet->length;
2480 /* Forward to our SIP peer */
2481 if(video) {
2482 if(session->media.has_video && session->media.video_rtcp_fd != -1) {
2483 /* Fix SSRCs as the Janus core does */
2484 JANUS_LOG(LOG_HUGE, "[SIP] Fixing SSRCs (local %u, peer %u)\n",
2485 session->media.video_ssrc, session->media.video_ssrc_peer);
2486 janus_rtcp_fix_ssrc(NULL, (char *)buf, len, 1, session->media.video_ssrc, session->media.video_ssrc_peer);
2487 /* Is SRTP involved? */
2488 if(session->media.has_srtp_local_video) {
2489 char sbuf[2048];
2490 memcpy(&sbuf, buf, len);
2491 int protected = len;
2492 int res = srtp_protect_rtcp(session->media.video_srtp_out, &sbuf, &protected);
2493 if(res != srtp_err_status_ok) {
2494 JANUS_LOG(LOG_ERR, "[SIP-%s] Video SRTCP protect error... %s (len=%d-->%d)...\n",
2495 session->account.username, janus_srtp_error_str(res), len, protected);
2496 } else {
2497 /* Forward the message to the peer */
2498 if(send(session->media.video_rtcp_fd, sbuf, protected, 0) < 0) {
2499 JANUS_LOG(LOG_HUGE, "[SIP-%s] Error sending SRTCP video packet... %s (len=%d)...\n",
2500 session->account.username, g_strerror(errno), protected);
2501 }
2502 }
2503 } else {
2504 /* Forward the message to the peer */
2505 if(send(session->media.video_rtcp_fd, buf, len, 0) < 0) {
2506 JANUS_LOG(LOG_HUGE, "[SIP-%s] Error sending RTCP video packet... %s (len=%d)...\n",
2507 session->account.username, g_strerror(errno), len);
2508 }
2509 }
2510 }
2511 } else {
2512 if(session->media.has_audio && session->media.audio_rtcp_fd != -1) {
2513 /* Fix SSRCs as the Janus core does */
2514 JANUS_LOG(LOG_HUGE, "[SIP] Fixing SSRCs (local %u, peer %u)\n",
2515 session->media.audio_ssrc, session->media.audio_ssrc_peer);
2516 janus_rtcp_fix_ssrc(NULL, (char *)buf, len, 1, session->media.audio_ssrc, session->media.audio_ssrc_peer);
2517 /* Is SRTP involved? */
2518 if(session->media.has_srtp_local_audio) {
2519 char sbuf[2048];
2520 memcpy(&sbuf, buf, len);
2521 int protected = len;
2522 int res = srtp_protect_rtcp(session->media.audio_srtp_out, &sbuf, &protected);
2523 if(res != srtp_err_status_ok) {
2524 JANUS_LOG(LOG_ERR, "[SIP-%s] Audio SRTCP protect error... %s (len=%d-->%d)...\n",
2525 session->account.username, janus_srtp_error_str(res), len, protected);
2526 } else {
2527 /* Forward the message to the peer */
2528 if(send(session->media.audio_rtcp_fd, sbuf, protected, 0) < 0) {
2529 JANUS_LOG(LOG_HUGE, "[SIP-%s] Error sending SRTCP audio packet... %s (len=%d)...\n",
2530 session->account.username, g_strerror(errno), protected);
2531 }
2532 }
2533 } else {
2534 /* Forward the message to the peer */
2535 if(send(session->media.audio_rtcp_fd, buf, len, 0) < 0) {
2536 JANUS_LOG(LOG_HUGE, "[SIP-%s] Error sending RTCP audio packet... %s (len=%d)...\n",
2537 session->account.username, g_strerror(errno), len);
2538 }
2539 }
2540 }
2541 }
2542 }
2543 }
2544
janus_sip_recorder_close(janus_sip_session * session,gboolean stop_audio,gboolean stop_audio_peer,gboolean stop_video,gboolean stop_video_peer)2545 static void janus_sip_recorder_close(janus_sip_session *session,
2546 gboolean stop_audio, gboolean stop_audio_peer, gboolean stop_video, gboolean stop_video_peer) {
2547 if(session->arc && stop_audio) {
2548 janus_recorder *rc = session->arc;
2549 session->arc = NULL;
2550 janus_recorder_close(rc);
2551 JANUS_LOG(LOG_INFO, "Closed user's audio recording %s\n", rc->filename ? rc->filename : "??");
2552 janus_recorder_destroy(rc);
2553 }
2554 if(session->arc_peer && stop_audio_peer) {
2555 janus_recorder *rc = session->arc_peer;
2556 session->arc_peer = NULL;
2557 janus_recorder_close(rc);
2558 JANUS_LOG(LOG_INFO, "Closed peer's audio recording %s\n", rc->filename ? rc->filename : "??");
2559 janus_recorder_destroy(rc);
2560 }
2561 if(session->vrc && stop_video) {
2562 janus_recorder *rc = session->vrc;
2563 session->vrc = NULL;
2564 janus_recorder_close(rc);
2565 JANUS_LOG(LOG_INFO, "Closed user's video recording %s\n", rc->filename ? rc->filename : "??");
2566 janus_recorder_destroy(rc);
2567 }
2568 if(session->vrc_peer && stop_video_peer) {
2569 janus_recorder *rc = session->vrc_peer;
2570 session->vrc_peer = NULL;
2571 janus_recorder_close(rc);
2572 JANUS_LOG(LOG_INFO, "Closed peer's video recording %s\n", rc->filename ? rc->filename : "??");
2573 janus_recorder_destroy(rc);
2574 }
2575 }
2576
janus_sip_hangup_media(janus_plugin_session * handle)2577 void janus_sip_hangup_media(janus_plugin_session *handle) {
2578 JANUS_LOG(LOG_INFO, "[%s-%p] No WebRTC media anymore\n", JANUS_SIP_PACKAGE, handle);
2579 janus_mutex_lock(&sessions_mutex);
2580 janus_sip_hangup_media_internal(handle);
2581 janus_mutex_unlock(&sessions_mutex);
2582 }
2583
janus_sip_hangup_media_internal(janus_plugin_session * handle)2584 static void janus_sip_hangup_media_internal(janus_plugin_session *handle) {
2585 if(g_atomic_int_get(&stopping) || !g_atomic_int_get(&initialized))
2586 return;
2587 janus_sip_session *session = janus_sip_lookup_session(handle);
2588 if(!session) {
2589 JANUS_LOG(LOG_ERR, "No session associated with this handle...\n");
2590 return;
2591 }
2592 if(g_atomic_int_get(&session->destroyed))
2593 return;
2594 if(!g_atomic_int_compare_and_exchange(&session->hangingup, 0, 1))
2595 return;
2596 session->media.simulcast_ssrc = 0;
2597 /* Do cleanup if media thread has not been created */
2598 if(!session->media.ready && !session->relayer_thread) {
2599 janus_mutex_lock(&session->mutex);
2600 janus_sip_media_cleanup(session);
2601 janus_mutex_unlock(&session->mutex);
2602 }
2603 /* Get rid of the recorders, if available */
2604 janus_mutex_lock(&session->rec_mutex);
2605 janus_sip_recorder_close(session, TRUE, TRUE, TRUE, TRUE);
2606 janus_mutex_unlock(&session->rec_mutex);
2607 if(!(session->status == janus_sip_call_status_inviting ||
2608 session->status == janus_sip_call_status_invited ||
2609 janus_sip_call_is_established(session))) {
2610 g_atomic_int_set(&session->establishing, 0);
2611 g_atomic_int_set(&session->established, 0);
2612 g_atomic_int_set(&session->hangingup, 0);
2613 return;
2614 }
2615 /* Involve SIP if needed */
2616 janus_mutex_lock(&session->mutex);
2617 if(session->stack->s_nh_i != NULL && session->callee != NULL) {
2618 g_free(session->callee);
2619 session->callee = NULL;
2620 janus_mutex_unlock(&session->mutex);
2621 /* Send a BYE */
2622 session->media.earlymedia = FALSE;
2623 session->media.update = FALSE;
2624 session->media.autoaccept_reinvites = TRUE;
2625 session->media.ready = FALSE;
2626 session->media.on_hold = FALSE;
2627
2628 /* Send a BYE or respond with 480 */
2629 if(janus_sip_call_is_established(session) || session->status == janus_sip_call_status_inviting)
2630 nua_bye(session->stack->s_nh_i, TAG_END());
2631 else
2632 nua_respond(session->stack->s_nh_i, 480, sip_status_phrase(480), TAG_END());
2633
2634 janus_sip_call_update_status(session, janus_sip_call_status_closing);
2635
2636 /* Notify the operation */
2637 json_t *event = json_object();
2638 json_object_set_new(event, "sip", json_string("event"));
2639 json_t *result = json_object();
2640 json_object_set_new(result, "event", json_string("hangingup"));
2641 json_object_set_new(event, "result", result);
2642 json_object_set_new(event, "call_id", json_string(session->callid));
2643 int ret = gateway->push_event(session->handle, &janus_sip_plugin, NULL, event, NULL);
2644 JANUS_LOG(LOG_VERB, " >> Pushing event: %d (%s)\n", ret, janus_get_api_error(ret));
2645 json_decref(event);
2646 } else {
2647 janus_mutex_unlock(&session->mutex);
2648 }
2649 g_atomic_int_set(&session->establishing, 0);
2650 g_atomic_int_set(&session->established, 0);
2651 g_atomic_int_set(&session->hangingup, 0);
2652 }
2653
2654 /* Thread to handle incoming messages */
janus_sip_handler(void * data)2655 static void *janus_sip_handler(void *data) {
2656 JANUS_LOG(LOG_VERB, "Joining SIP handler thread\n");
2657 janus_sip_message *msg = NULL;
2658 int error_code = 0;
2659 char error_cause[512];
2660 json_t *root = NULL;
2661 while(g_atomic_int_get(&initialized) && !g_atomic_int_get(&stopping)) {
2662 msg = g_async_queue_pop(messages);
2663 if(msg == &exit_message)
2664 break;
2665 if(msg->handle == NULL) {
2666 janus_sip_message_free(msg);
2667 continue;
2668 }
2669 janus_mutex_lock(&sessions_mutex);
2670 janus_sip_session *session = janus_sip_lookup_session(msg->handle);
2671 if(!session) {
2672 janus_mutex_unlock(&sessions_mutex);
2673 JANUS_LOG(LOG_ERR, "No session associated with this handle...\n");
2674 janus_sip_message_free(msg);
2675 continue;
2676 }
2677 if(g_atomic_int_get(&session->destroyed)) {
2678 janus_mutex_unlock(&sessions_mutex);
2679 janus_sip_message_free(msg);
2680 continue;
2681 }
2682 janus_mutex_unlock(&sessions_mutex);
2683 /* Handle request */
2684 error_code = 0;
2685 root = msg->message;
2686 if(msg->message == NULL) {
2687 JANUS_LOG(LOG_ERR, "No message??\n");
2688 error_code = JANUS_SIP_ERROR_NO_MESSAGE;
2689 g_snprintf(error_cause, 512, "%s", "No message??");
2690 goto error;
2691 }
2692 if(!json_is_object(root)) {
2693 JANUS_LOG(LOG_ERR, "JSON error: not an object\n");
2694 error_code = JANUS_SIP_ERROR_INVALID_JSON;
2695 g_snprintf(error_cause, 512, "JSON error: not an object");
2696 goto error;
2697 }
2698 JANUS_VALIDATE_JSON_OBJECT(root, request_parameters,
2699 error_code, error_cause, TRUE,
2700 JANUS_SIP_ERROR_MISSING_ELEMENT, JANUS_SIP_ERROR_INVALID_ELEMENT);
2701 if(error_code != 0)
2702 goto error;
2703 json_t *request = json_object_get(root, "request");
2704 const char *request_text = json_string_value(request);
2705 json_t *result = NULL;
2706
2707 if(!strcasecmp(request_text, "register")) {
2708 /* Send a REGISTER */
2709 JANUS_VALIDATE_JSON_OBJECT(root, register_parameters,
2710 error_code, error_cause, TRUE,
2711 JANUS_SIP_ERROR_MISSING_ELEMENT, JANUS_SIP_ERROR_INVALID_ELEMENT);
2712 if(error_code != 0)
2713 goto error;
2714 gboolean refresh = json_is_true(json_object_get(root, "refresh"));
2715 if(session->account.registration_status > janus_sip_registration_status_unregistered && !refresh) {
2716 JANUS_LOG(LOG_ERR, "Already registered (%s)\n", session->account.username);
2717 error_code = JANUS_SIP_ERROR_ALREADY_REGISTERED;
2718 g_snprintf(error_cause, 512, "Already registered (%s)", session->account.username);
2719 goto error;
2720 }
2721 /* Parse the request */
2722 gboolean guest = FALSE, helper = FALSE;
2723 json_t *type = json_object_get(root, "type");
2724 if(type != NULL) {
2725 const char *type_text = json_string_value(type);
2726 if(!strcmp(type_text, "guest")) {
2727 JANUS_LOG(LOG_INFO, "Registering as a guest\n");
2728 guest = TRUE;
2729 } else if(!strcmp(type_text, "helper")) {
2730 JANUS_LOG(LOG_INFO, "Registering as a helper\n");
2731 helper = TRUE;
2732 } else {
2733 JANUS_LOG(LOG_WARN, "Unknown type '%s', ignoring...\n", type_text);
2734 }
2735 }
2736 if(helper) {
2737 /* This is actually an helper session, for an already registered one */
2738 json_t *master = json_object_get(root, "master_id");
2739 if(master == NULL) {
2740 JANUS_LOG(LOG_ERR, "Missing mandatory element for helper (master_id)\n");
2741 error_code = JANUS_SIP_ERROR_MISSING_ELEMENT;
2742 g_snprintf(error_cause, 512, "Missing mandatory element for helper (master_id)");
2743 goto error;
2744 }
2745 guint32 master_id = json_integer_value(master);
2746 janus_mutex_lock(&sessions_mutex);
2747 if(session->master != NULL) {
2748 janus_mutex_unlock(&sessions_mutex);
2749 JANUS_LOG(LOG_ERR, "Session already a helper (%"SCNu32")\n", session->master_id);
2750 error_code = JANUS_SIP_ERROR_HELPER_ERROR;
2751 g_snprintf(error_cause, 512, "Session already a helper (%"SCNu32")", master_id);
2752 goto error;
2753 }
2754 janus_sip_session *ms = g_hash_table_lookup(masters, GUINT_TO_POINTER(master_id));
2755 if(ms == NULL) {
2756 janus_mutex_unlock(&sessions_mutex);
2757 JANUS_LOG(LOG_ERR, "No such master session (%"SCNu32")\n", master_id);
2758 error_code = JANUS_SIP_ERROR_HELPER_ERROR;
2759 g_snprintf(error_cause, 512, "No such master session (%"SCNu32")", master_id);
2760 goto error;
2761 }
2762 /* Add this session as an helper for the master */
2763 janus_refcount_increase(&session->ref);
2764 janus_refcount_increase(&ms->ref);
2765 session->helper = TRUE;
2766 session->master = ms;
2767 session->master_id = master_id;
2768 janus_mutex_lock(&ms->mutex);
2769 ms->helpers = g_list_append(ms->helpers, session);
2770 janus_mutex_unlock(&ms->mutex);
2771 session->account.registration_status = janus_sip_registration_status_disabled;
2772 g_free(session->account.username);
2773 session->account.username = ms->account.username ? g_strdup(ms->account.username) : NULL;
2774 if(session->stack == NULL) {
2775 session->stack = g_malloc0(sizeof(ssip_t));
2776 su_home_init(session->stack->s_home);
2777 if(session->master->stack->contact_header != NULL)
2778 session->stack->contact_header = g_strdup(session->master->stack->contact_header);
2779 }
2780 /* Check if custom headers need to be intercepted */
2781 json_t *header_prefixes_json = json_object_get(root, "incoming_header_prefixes");
2782 if(header_prefixes_json) {
2783 size_t index = 0;
2784 json_t *value = NULL;
2785 json_array_foreach(header_prefixes_json, index, value) {
2786 const char *header_prefix = json_string_value(value);
2787 if(header_prefix)
2788 session->incoming_header_prefixes = g_list_append(session->incoming_header_prefixes, g_strdup(header_prefix));
2789 }
2790 } else {
2791 /* No custom headers, inherit the parent's if any */
2792 if(ms->incoming_header_prefixes != NULL) {
2793 GList *temp = ms->incoming_header_prefixes;
2794 while(temp != NULL) {
2795 char *header_prefix = (char *)temp->data;
2796 if(header_prefix != NULL)
2797 session->incoming_header_prefixes = g_list_append(session->incoming_header_prefixes, g_strdup(header_prefix));
2798 temp = temp->next;
2799 }
2800 }
2801 }
2802 session->stack->session = session;
2803 janus_mutex_unlock(&sessions_mutex);
2804 /* Send an event back */
2805 result = json_object();
2806 json_object_set_new(result, "event", json_string("registered"));
2807 json_object_set_new(result, "username", json_string(ms->account.username));
2808 json_object_set_new(result, "register_sent", json_false());
2809 json_object_set_new(result, "helper", json_true());
2810 json_object_set_new(result, "master_id", json_integer(session->master_id));
2811 /* Also notify event handlers */
2812 if(notify_events && gateway->events_is_enabled()) {
2813 json_t *info = json_object();
2814 json_object_set_new(info, "event", json_string("registered"));
2815 json_object_set_new(info, "identity", json_string(ms->account.identity));
2816 json_object_set_new(info, "type", json_string("guest"));
2817 json_object_set_new(info, "helper", json_true());
2818 json_object_set_new(info, "master_id", json_integer(session->master_id));
2819 gateway->notify_event(&janus_sip_plugin, session->handle, info);
2820 }
2821 goto done;
2822 }
2823 if(session->master != NULL) {
2824 JANUS_LOG(LOG_ERR, "Can't register on a helper session\n");
2825 error_code = JANUS_SIP_ERROR_HELPER_ERROR;
2826 g_snprintf(error_cause, 512, "Can't register on a helper session");
2827 goto error;
2828 }
2829
2830 gboolean send_register = TRUE;
2831 json_t *do_register = json_object_get(root, "send_register");
2832 if(do_register != NULL) {
2833 if(guest) {
2834 JANUS_LOG(LOG_ERR, "Conflicting elements: send_register cannot be true if guest is true\n");
2835 error_code = JANUS_SIP_ERROR_INVALID_ELEMENT;
2836 g_snprintf(error_cause, 512, "Conflicting elements: send_register cannot be true if guest is true");
2837 goto error;
2838 }
2839 send_register = json_is_true(do_register);
2840 }
2841
2842 gboolean sips = TRUE;
2843 json_t *do_sips = json_object_get(root, "sips");
2844 if(do_sips != NULL) {
2845 sips = json_is_true(do_sips);
2846 }
2847 gboolean force_udp = FALSE;
2848 json_t *do_udp = json_object_get(root, "force_udp");
2849 if(do_udp != NULL) {
2850 force_udp = json_is_true(do_udp);
2851 }
2852 gboolean force_tcp = FALSE;
2853 json_t *do_tcp = json_object_get(root, "force_tcp");
2854 if(do_tcp != NULL) {
2855 force_tcp = json_is_true(do_tcp);
2856 }
2857 if(force_udp && force_tcp) {
2858 JANUS_LOG(LOG_ERR, "Conflicting elements: force_udp and force_tcp cannot both be true\n");
2859 error_code = JANUS_SIP_ERROR_INVALID_ELEMENT;
2860 g_snprintf(error_cause, 512, "Conflicting elements: force_udp and force_tcp cannot both be true");
2861 goto error;
2862 }
2863 gboolean rfc2543_cancel = FALSE;
2864 json_t *do_rfc2543_cancel = json_object_get(root, "rfc2543_cancel");
2865 if(do_rfc2543_cancel != NULL) {
2866 rfc2543_cancel = json_is_true(do_rfc2543_cancel);
2867 }
2868
2869 /* Parse addresses */
2870 json_t *proxy = json_object_get(root, "proxy");
2871 const char *proxy_text = NULL;
2872 if(proxy && !json_is_null(proxy)) {
2873 /* Has to be validated separately because it could be null */
2874 JANUS_VALIDATE_JSON_OBJECT(root, proxy_parameters,
2875 error_code, error_cause, TRUE,
2876 JANUS_SIP_ERROR_MISSING_ELEMENT, JANUS_SIP_ERROR_INVALID_ELEMENT);
2877 if(error_code != 0)
2878 goto error;
2879 proxy_text = json_string_value(proxy);
2880 janus_sip_uri_t proxy_uri;
2881 if(janus_sip_parse_proxy_uri(&proxy_uri, proxy_text) < 0) {
2882 JANUS_LOG(LOG_ERR, "Invalid proxy address %s\n", proxy_text);
2883 error_code = JANUS_SIP_ERROR_INVALID_ADDRESS;
2884 g_snprintf(error_cause, 512, "Invalid proxy address %s\n", proxy_text);
2885 goto error;
2886 }
2887 }
2888 json_t *outbound_proxy = json_object_get(root, "outbound_proxy");
2889 const char *obproxy_text = NULL;
2890 if(outbound_proxy && !json_is_null(outbound_proxy)) {
2891 /* Has to be validated separately because it could be null */
2892 JANUS_VALIDATE_JSON_OBJECT(root, proxy_parameters,
2893 error_code, error_cause, TRUE,
2894 JANUS_SIP_ERROR_MISSING_ELEMENT, JANUS_SIP_ERROR_INVALID_ELEMENT);
2895 if(error_code != 0)
2896 goto error;
2897 obproxy_text = json_string_value(outbound_proxy);
2898 janus_sip_uri_t outbound_proxy_uri;
2899 if(janus_sip_parse_proxy_uri(&outbound_proxy_uri, obproxy_text) < 0) {
2900 JANUS_LOG(LOG_ERR, "Invalid outbound_proxy address %s\n", obproxy_text);
2901 error_code = JANUS_SIP_ERROR_INVALID_ADDRESS;
2902 g_snprintf(error_cause, 512, "Invalid outbound_proxy address %s\n", obproxy_text);
2903 goto error;
2904 }
2905 }
2906
2907 /* Parse register TTL */
2908 int ttl = register_ttl;
2909 json_t *reg_ttl = json_object_get(root, "register_ttl");
2910 if(reg_ttl && json_is_integer(reg_ttl))
2911 ttl = json_integer_value(reg_ttl);
2912 if(ttl <= 0)
2913 ttl = JANUS_DEFAULT_REGISTER_TTL;
2914
2915 /* Parse display name */
2916 const char *display_name_text = NULL;
2917 json_t *display_name = json_object_get(root, "display_name");
2918 if(display_name && json_is_string(display_name))
2919 display_name_text = json_string_value(display_name);
2920
2921 /* Parse user agent */
2922 const char *user_agent_text = NULL;
2923 json_t *user_agent = json_object_get(root, "user_agent");
2924 if(user_agent && json_is_string(user_agent))
2925 user_agent_text = json_string_value(user_agent);
2926
2927 /* Now the user part (always needed, even for the guest case) */
2928 json_t *username = json_object_get(root, "username");
2929 if(!username) {
2930 /* The username is mandatory even when registering as guests */
2931 JANUS_LOG(LOG_ERR, "Missing element (username)\n");
2932 error_code = JANUS_SIP_ERROR_MISSING_ELEMENT;
2933 g_snprintf(error_cause, 512, "Missing element (username)");
2934 goto error;
2935 }
2936 const char *username_text = NULL;
2937 const char *secret_text = NULL;
2938 const char *authuser_text = NULL;
2939 janus_sip_secret_type secret_type = janus_sip_secret_type_plaintext;
2940 janus_sip_uri_t username_uri;
2941 char user_id[256];
2942 /* Parse address */
2943 username_text = json_string_value(username);
2944 if(janus_sip_parse_uri(&username_uri, username_text) < 0) {
2945 JANUS_LOG(LOG_ERR, "Invalid user address %s\n", username_text);
2946 error_code = JANUS_SIP_ERROR_INVALID_ADDRESS;
2947 g_snprintf(error_cause, 512, "Invalid user address %s\n", username_text);
2948 goto error;
2949 }
2950 g_strlcpy(user_id, username_uri.url->url_user, sizeof(user_id));
2951 if(guest) {
2952 /* Not needed, we can stop here: just say we're registered */
2953 JANUS_LOG(LOG_INFO, "Guest will have username %s\n", user_id);
2954 send_register = FALSE;
2955 } else {
2956 json_t *secret = json_object_get(root, "secret");
2957 json_t *ha1_secret = json_object_get(root, "ha1_secret");
2958 json_t *authuser = json_object_get(root, "authuser");
2959 if(!secret && !ha1_secret) {
2960 JANUS_LOG(LOG_ERR, "Missing element (secret or ha1_secret)\n");
2961 error_code = JANUS_SIP_ERROR_MISSING_ELEMENT;
2962 g_snprintf(error_cause, 512, "Missing element (secret or ha1_secret)");
2963 goto error;
2964 }
2965 if(secret && ha1_secret) {
2966 JANUS_LOG(LOG_ERR, "Conflicting elements specified (secret and ha1_secret)\n");
2967 error_code = JANUS_SIP_ERROR_INVALID_ELEMENT;
2968 g_snprintf(error_cause, 512, "Conflicting elements specified (secret and ha1_secret)");
2969 goto error;
2970 }
2971 if(secret) {
2972 secret_text = json_string_value(secret);
2973 secret_type = janus_sip_secret_type_plaintext;
2974 } else {
2975 secret_text = json_string_value(ha1_secret);
2976 secret_type = janus_sip_secret_type_hashed;
2977 }
2978 if(authuser) {
2979 authuser_text = json_string_value(authuser);
2980 }
2981 /* Got the values, try registering now */
2982 JANUS_LOG(LOG_VERB, "Registering user %s (auth=%s, secret %s) @ %s through %s (outbound proxy: %s)\n",
2983 username_text, secret_text, username_uri.url->url_host,
2984 authuser_text != NULL ? authuser_text : username_text,
2985 proxy_text != NULL ? proxy_text : "(null)",
2986 obproxy_text != NULL ? obproxy_text : "none");
2987 }
2988 /* Create a master ID if we don't have one yet */
2989 if(session->master_id == 0) {
2990 janus_mutex_lock(&sessions_mutex);
2991 while(session->master_id == 0) {
2992 session->master_id = janus_random_uint32();
2993 if(g_hash_table_lookup(masters, GUINT_TO_POINTER(session->master_id)) != NULL)
2994 session->master_id = 0;
2995 }
2996 g_hash_table_insert(masters, GUINT_TO_POINTER(session->master_id), session);
2997 janus_mutex_unlock(&sessions_mutex);
2998 }
2999
3000 json_t *header_prefixes_json = json_object_get(root, "incoming_header_prefixes");
3001 if(header_prefixes_json) {
3002 size_t index = 0;
3003 json_t *value = NULL;
3004 json_array_foreach(header_prefixes_json, index, value) {
3005 const char *header_prefix = json_string_value(value);
3006 if(header_prefix)
3007 session->incoming_header_prefixes = g_list_append(session->incoming_header_prefixes, g_strdup(header_prefix));
3008 }
3009 }
3010
3011 /* If this is a refresh, get rid of the old values */
3012 if(refresh) {
3013 /* Cleanup old values */
3014 if(session->account.identity != NULL) {
3015 janus_mutex_lock(&sessions_mutex);
3016 g_hash_table_remove(identities, session->account.identity);
3017 janus_mutex_unlock(&sessions_mutex);
3018 g_free(session->account.identity);
3019 }
3020 session->account.identity = NULL;
3021 session->account.force_udp = FALSE;
3022 session->account.force_tcp = FALSE;
3023 session->account.sips = TRUE;
3024 session->account.rfc2543_cancel = FALSE;
3025 if(session->account.username != NULL)
3026 g_free(session->account.username);
3027 session->account.username = NULL;
3028 if(session->account.display_name != NULL)
3029 g_free(session->account.display_name);
3030 session->account.display_name = NULL;
3031 if(session->account.authuser != NULL)
3032 g_free(session->account.authuser);
3033 session->account.authuser = NULL;
3034 if(session->account.secret != NULL)
3035 g_free(session->account.secret);
3036 session->account.secret = NULL;
3037 session->account.secret_type = janus_sip_secret_type_unknown;
3038 if(session->account.proxy != NULL)
3039 g_free(session->account.proxy);
3040 session->account.proxy = NULL;
3041 if(session->account.outbound_proxy != NULL)
3042 g_free(session->account.outbound_proxy);
3043 session->account.outbound_proxy = NULL;
3044 if(session->account.user_agent != NULL)
3045 g_free(session->account.user_agent);
3046 session->account.user_agent = NULL;
3047 session->account.registration_status = janus_sip_registration_status_unregistered;
3048 }
3049 session->account.identity = g_strdup(username_text);
3050 janus_mutex_lock(&sessions_mutex);
3051 g_hash_table_insert(identities, session->account.identity, session);
3052 janus_mutex_unlock(&sessions_mutex);
3053 session->account.force_udp = force_udp;
3054 session->account.force_tcp = force_tcp;
3055 session->account.sips = sips;
3056 session->account.rfc2543_cancel = rfc2543_cancel;
3057 session->account.username = g_strdup(user_id);
3058 session->account.authuser = g_strdup(authuser_text ? authuser_text : user_id);
3059 session->account.secret = secret_text ? g_strdup(secret_text) : NULL;
3060 session->account.secret_type = secret_type;
3061 if(display_name_text) {
3062 session->account.display_name = g_strdup(display_name_text);
3063 }
3064 if(user_agent_text) {
3065 session->account.user_agent = g_strdup(user_agent_text);
3066 }
3067 if(proxy_text) {
3068 session->account.proxy = g_strdup(proxy_text);
3069 }
3070 if(obproxy_text) {
3071 session->account.outbound_proxy = g_strdup(obproxy_text);
3072 }
3073
3074 session->account.registration_status = janus_sip_registration_status_registering;
3075 if(!refresh && session->stack == NULL) {
3076 /* Start the thread first */
3077 GError *error = NULL;
3078 char tname[16];
3079 g_snprintf(tname, sizeof(tname), "sip %s", session->account.username);
3080 janus_refcount_increase(&session->ref);
3081 g_thread_try_new(tname, janus_sip_sofia_thread, session, &error);
3082 if(error != NULL) {
3083 janus_refcount_decrease(&session->ref);
3084 JANUS_LOG(LOG_ERR, "Got error %d (%s) trying to launch the SIP Sofia thread...\n",
3085 error->code, error->message ? error->message : "??");
3086 error_code = JANUS_SIP_ERROR_UNKNOWN_ERROR;
3087 g_snprintf(error_cause, 512, "Got error %d (%s) trying to launch the SIP Sofia thread",
3088 error->code, error->message ? error->message : "??");
3089 g_error_free(error);
3090 goto error;
3091 }
3092 long int timeout = 0;
3093 while(session->stack == NULL || session->stack->s_nua == NULL) {
3094 g_usleep(100000);
3095 timeout += 100000;
3096 if(timeout >= 2000000) {
3097 break;
3098 }
3099 }
3100 if(timeout >= 2000000) {
3101 JANUS_LOG(LOG_ERR, "Two seconds passed and still no NUA, problems with the thread?\n");
3102 error_code = JANUS_SIP_ERROR_UNKNOWN_ERROR;
3103 g_snprintf(error_cause, 512, "Two seconds passed and still no NUA, problems with the thread?");
3104 goto error;
3105 }
3106 }
3107 if(session == NULL || session->stack == NULL) {
3108 JANUS_LOG(LOG_ERR, "Missing session or Sofia stack\n");
3109 error_code = JANUS_SIP_ERROR_UNKNOWN_ERROR;
3110 g_snprintf(error_cause, 512, "Missing session or Sofia stack");
3111 goto error;
3112 }
3113 if(session->stack->s_nh_r != NULL) {
3114 nua_handle_destroy(session->stack->s_nh_r);
3115 session->stack->s_nh_r = NULL;
3116 }
3117
3118 if(send_register) {
3119 /* Check if the REGISTER needs to be enriched with custom headers */
3120 char custom_headers[2048];
3121 janus_sip_parse_custom_headers(root, (char *)&custom_headers, sizeof(custom_headers));
3122 /* Do the same in case there are custom Contact URI params */
3123 char custom_params[2048];
3124 janus_sip_parse_custom_contact_params(root, (char *)&custom_params, sizeof(custom_params));
3125 /* Create a new NUA handle */
3126 janus_mutex_lock(&session->stack->smutex);
3127 if(session->stack->s_nua == NULL) {
3128 janus_mutex_unlock(&session->stack->smutex);
3129 JANUS_LOG(LOG_ERR, "NUA destroyed while registering?\n");
3130 error_code = JANUS_SIP_ERROR_LIBSOFIA_ERROR;
3131 g_snprintf(error_cause, 512, "Invalid NUA");
3132 goto error;
3133 }
3134 session->stack->s_nh_r = nua_handle(session->stack->s_nua, session, TAG_END());
3135 janus_mutex_unlock(&session->stack->smutex);
3136 if(session->stack->s_nh_r == NULL) {
3137 JANUS_LOG(LOG_ERR, "NUA Handle for REGISTER still null??\n");
3138 error_code = JANUS_SIP_ERROR_LIBSOFIA_ERROR;
3139 g_snprintf(error_cause, 512, "Invalid NUA Handle");
3140 goto error;
3141 }
3142 /* TTL */
3143 char ttl_text[20];
3144 g_snprintf(ttl_text, sizeof(ttl_text), "%d", ttl);
3145 /* Send the REGISTER */
3146 nua_register(session->stack->s_nh_r,
3147 NUTAG_M_USERNAME(session->account.authuser),
3148 NUTAG_M_DISPLAY(session->account.display_name),
3149 SIPTAG_FROM_STR(username_text),
3150 SIPTAG_TO_STR(username_text),
3151 TAG_IF(strlen(custom_headers) > 0, SIPTAG_HEADER_STR(custom_headers)),
3152 TAG_IF(strlen(custom_params) > 0, NUTAG_M_PARAMS(custom_params)),
3153 SIPTAG_EXPIRES_STR(ttl_text),
3154 NUTAG_REGISTRAR(proxy_text),
3155 NUTAG_PROXY(obproxy_text),
3156 TAG_END());
3157 result = json_object();
3158 json_object_set_new(result, "event", json_string("registering"));
3159 } else {
3160 JANUS_LOG(LOG_VERB, "Not sending a SIP REGISTER: either send_register was set to false or guest mode was enabled\n");
3161 session->account.registration_status = janus_sip_registration_status_disabled;
3162 result = json_object();
3163 json_object_set_new(result, "event", json_string("registered"));
3164 json_object_set_new(result, "username", json_string(session->account.username));
3165 json_object_set_new(result, "register_sent", json_false());
3166 json_object_set_new(result, "master_id", json_integer(session->master_id));
3167 /* Also notify event handlers */
3168 if(notify_events && gateway->events_is_enabled()) {
3169 json_t *info = json_object();
3170 json_object_set_new(info, "event", json_string("registered"));
3171 json_object_set_new(info, "identity", json_string(session->account.identity));
3172 json_object_set_new(info, "type", json_string("guest"));
3173 json_object_set_new(info, "master_id", json_integer(session->master_id));
3174 gateway->notify_event(&janus_sip_plugin, session->handle, info);
3175 }
3176 }
3177 } else if(!strcasecmp(request_text, "unregister")) {
3178 if(session->stack == NULL) {
3179 JANUS_LOG(LOG_ERR, "Wrong state (register first)\n");
3180 error_code = JANUS_SIP_ERROR_WRONG_STATE;
3181 g_snprintf(error_cause, 512, "Wrong state (register first)");
3182 goto error;
3183 }
3184 if(session->helper) {
3185 /* Not really "unregistering", we're just removing the association to the "master" */
3186 janus_sip_session *master = session->master;
3187 janus_mutex_lock(&master->mutex);
3188 gboolean found = (g_list_find(master->helpers, session) != NULL);
3189 if(found) {
3190 master->helpers = g_list_remove(master->helpers, session);
3191 janus_refcount_decrease(&session->ref);
3192 janus_refcount_decrease(&master->ref);
3193 }
3194 janus_mutex_unlock(&master->mutex);
3195 session->helper = FALSE;
3196 session->master = NULL;
3197 session->master_id = FALSE;
3198 /* Done */
3199 session->account.registration_status = janus_sip_registration_status_unregistered;
3200 result = json_object();
3201 json_object_set_new(result, "event", json_string("unregistering"));
3202 goto done;
3203 }
3204 if(session->account.registration_status < janus_sip_registration_status_registered) {
3205 JANUS_LOG(LOG_ERR, "Wrong state (not registered)\n");
3206 error_code = JANUS_SIP_ERROR_WRONG_STATE;
3207 g_snprintf(error_cause, 512, "Wrong state (not registered)");
3208 goto error;
3209 }
3210 if(session->stack->s_nh_r == NULL) {
3211 JANUS_LOG(LOG_ERR, "NUA Handle for REGISTER still null??\n");
3212 error_code = JANUS_SIP_ERROR_LIBSOFIA_ERROR;
3213 g_snprintf(error_cause, 512, "Invalid NUA Handle");
3214 goto error;
3215 }
3216 /* Unregister now */
3217 session->account.registration_status = janus_sip_registration_status_unregistering;
3218 nua_unregister(session->stack->s_nh_r, TAG_END());
3219 result = json_object();
3220 json_object_set_new(result, "event", json_string("unregistering"));
3221 } else if(!strcasecmp(request_text, "subscribe")) {
3222 /* Subscribe to some SIP events */
3223 JANUS_VALIDATE_JSON_OBJECT(root, subscribe_parameters,
3224 error_code, error_cause, TRUE,
3225 JANUS_SIP_ERROR_MISSING_ELEMENT, JANUS_SIP_ERROR_INVALID_ELEMENT);
3226 if(error_code != 0)
3227 goto error;
3228 if(session->account.registration_status != janus_sip_registration_status_registered &&
3229 session->account.registration_status != janus_sip_registration_status_disabled) {
3230 JANUS_LOG(LOG_ERR, "Wrong state (not registered)\n");
3231 error_code = JANUS_SIP_ERROR_WRONG_STATE;
3232 g_snprintf(error_cause, 512, "Wrong state (not registered)");
3233 goto error;
3234 }
3235 const char *to = json_string_value(json_object_get(root, "to"));
3236 if(to == NULL)
3237 to = session->account.identity;
3238 const char *event_type = json_string_value(json_object_get(root, "event"));
3239 const char *accept = json_string_value(json_object_get(root, "accept"));
3240
3241 /* TTL */
3242 int ttl = subscribe_ttl;
3243 json_t *sub_ttl = json_object_get(root, "subscribe_ttl");
3244 if(sub_ttl && json_is_integer(sub_ttl))
3245 ttl = json_integer_value(sub_ttl);
3246 if(ttl <= 0)
3247 ttl = JANUS_DEFAULT_SUBSCRIBE_TTL;
3248 char ttl_text[20];
3249 g_snprintf(ttl_text, sizeof(ttl_text), "%d", ttl);
3250
3251 /* Take call-id from request, if it exists */
3252 const char *callid = NULL;
3253 json_t *request_callid = json_object_get(root, "call_id");
3254 if(request_callid)
3255 callid = json_string_value(request_callid);
3256
3257 /* Do we have a handle for this subscription already? */
3258 janus_mutex_lock(&session->stack->smutex);
3259 nua_handle_t *nh = NULL;
3260 if(session->stack->subscriptions != NULL)
3261 nh = g_hash_table_lookup(session->stack->subscriptions, (char *)event_type);
3262 if(nh == NULL) {
3263 /* We don't, create one now */
3264 if(!session->helper) {
3265 if(session->stack->s_nua == NULL) {
3266 janus_mutex_unlock(&session->stack->smutex);
3267 JANUS_LOG(LOG_ERR, "NUA destroyed while subscribing?\n");
3268 error_code = JANUS_SIP_ERROR_LIBSOFIA_ERROR;
3269 g_snprintf(error_cause, 512, "Invalid NUA");
3270 goto error;
3271 }
3272 nh = nua_handle(session->stack->s_nua, session, TAG_END());
3273 } else {
3274 /* This is a helper, we need to use the master's SIP stack */
3275 if(session->master == NULL || session->master->stack == NULL) {
3276 error_code = JANUS_SIP_ERROR_HELPER_ERROR;
3277 g_snprintf(error_cause, 512, "Invalid master SIP stack");
3278 goto error;
3279 }
3280 janus_mutex_lock(&session->master->stack->smutex);
3281 if(session->master->stack->s_nua == NULL) {
3282 janus_mutex_unlock(&session->master->stack->smutex);
3283 JANUS_LOG(LOG_ERR, "NUA destroyed while subscribing?\n");
3284 error_code = JANUS_SIP_ERROR_LIBSOFIA_ERROR;
3285 g_snprintf(error_cause, 512, "Invalid NUA");
3286 goto error;
3287 }
3288 nh = nua_handle(session->master->stack->s_nua, session, TAG_END());
3289 janus_mutex_unlock(&session->master->stack->smutex);
3290 }
3291 if(session->stack->subscriptions == NULL) {
3292 /* We still need a table for mapping these subscriptions as well */
3293 session->stack->subscriptions = g_hash_table_new_full(g_int64_hash, g_int64_equal,
3294 (GDestroyNotify)g_free, (GDestroyNotify)nua_handle_destroy);
3295 }
3296 g_hash_table_insert(session->stack->subscriptions, g_strdup(event_type), nh);
3297 }
3298 janus_mutex_unlock(&session->stack->smutex);
3299 /* Send the SUBSCRIBE */
3300 nua_subscribe(nh,
3301 SIPTAG_TO_STR(to),
3302 SIPTAG_EVENT_STR(event_type),
3303 SIPTAG_CALL_ID_STR(callid),
3304 SIPTAG_ACCEPT_STR(accept),
3305 SIPTAG_EXPIRES_STR(ttl_text),
3306 NUTAG_PROXY(session->helper && session->master ?
3307 session->master->account.outbound_proxy : session->account.outbound_proxy),
3308 TAG_END());
3309 result = json_object();
3310 json_object_set_new(result, "event", json_string("subscribing"));
3311 if (callid)
3312 json_object_set_new(result, "call_id", json_string(callid));
3313 } else if(!strcasecmp(request_text, "unsubscribe")) {
3314 /* Unsubscribe from some SIP events */
3315 JANUS_VALIDATE_JSON_OBJECT(root, subscribe_parameters,
3316 error_code, error_cause, TRUE,
3317 JANUS_SIP_ERROR_MISSING_ELEMENT, JANUS_SIP_ERROR_INVALID_ELEMENT);
3318 if(error_code != 0)
3319 goto error;
3320 if(session->account.registration_status != janus_sip_registration_status_registered &&
3321 session->account.registration_status != janus_sip_registration_status_disabled) {
3322 JANUS_LOG(LOG_ERR, "Wrong state (not registered)\n");
3323 error_code = JANUS_SIP_ERROR_WRONG_STATE;
3324 g_snprintf(error_cause, 512, "Wrong state (not registered)");
3325 goto error;
3326 }
3327 const char *to = json_string_value(json_object_get(root, "to"));
3328 if(to == NULL)
3329 to = session->account.identity;
3330 const char *event_type = json_string_value(json_object_get(root, "event"));
3331 /* Get the handle we used for this subscription */
3332 janus_mutex_lock(&session->stack->smutex);
3333 nua_handle_t *nh = NULL;
3334 if(session->stack->subscriptions != NULL)
3335 nh = g_hash_table_lookup(session->stack->subscriptions, (char *)event_type);
3336 janus_mutex_unlock(&session->stack->smutex);
3337 if(nh == NULL) {
3338 JANUS_LOG(LOG_ERR, "Wrong state (not subscribed to this event)\n");
3339 error_code = JANUS_SIP_ERROR_WRONG_STATE;
3340 g_snprintf(error_cause, 512, "Wrong state (not subscribed to this event)");
3341 goto error;
3342 }
3343 /* Send the SUBSCRIBE with Expires set to 0 */
3344 nua_subscribe(nh, SIPTAG_TO_STR(to), SIPTAG_EVENT_STR(event_type),
3345 SIPTAG_EXPIRES_STR("0"), TAG_END());
3346 result = json_object();
3347 json_object_set_new(result, "event", json_string("unsubscribing"));
3348 } else if(!strcasecmp(request_text, "call")) {
3349 /* Call another peer */
3350 if(session->stack == NULL) {
3351 JANUS_LOG(LOG_ERR, "Wrong state (register first)\n");
3352 error_code = JANUS_SIP_ERROR_WRONG_STATE;
3353 g_snprintf(error_cause, 512, "Wrong state (register first)");
3354 goto error;
3355 }
3356 if(session->account.registration_status != janus_sip_registration_status_registered &&
3357 session->account.registration_status != janus_sip_registration_status_disabled) {
3358 JANUS_LOG(LOG_ERR, "Wrong state (not registered)\n");
3359 error_code = JANUS_SIP_ERROR_WRONG_STATE;
3360 g_snprintf(error_cause, 512, "Wrong state (not registered)");
3361 goto error;
3362 }
3363 if(session->status >= janus_sip_call_status_inviting) {
3364 JANUS_LOG(LOG_ERR, "Wrong state (already in a call? status=%s)\n", janus_sip_call_status_string(session->status));
3365 error_code = JANUS_SIP_ERROR_WRONG_STATE;
3366 g_snprintf(error_cause, 512, "Wrong state (already in a call? status=%s)", janus_sip_call_status_string(session->status));
3367 goto error;
3368 }
3369 JANUS_VALIDATE_JSON_OBJECT(root, call_parameters,
3370 error_code, error_cause, TRUE,
3371 JANUS_SIP_ERROR_MISSING_ELEMENT, JANUS_SIP_ERROR_INVALID_ELEMENT);
3372 if(error_code != 0)
3373 goto error;
3374 json_t *secret = json_object_get(root, "secret");
3375 json_t *ha1_secret = json_object_get(root, "ha1_secret");
3376 json_t *authuser = json_object_get(root, "authuser");
3377 if(secret && ha1_secret) {
3378 JANUS_LOG(LOG_ERR, "Conflicting elements specified (secret and ha1_secret)\n");
3379 error_code = JANUS_SIP_ERROR_INVALID_ELEMENT;
3380 g_snprintf(error_cause, 512, "Conflicting elements specified (secret and ha1_secret)");
3381 goto error;
3382 }
3383 json_t *uri = json_object_get(root, "uri");
3384 /* Check if the INVITE needs to be enriched with custom headers */
3385 char custom_headers[2048];
3386 janus_sip_parse_custom_headers(root, (char *)&custom_headers, sizeof(custom_headers));
3387 /* SDES-SRTP is disabled by default, let's see if we need to enable it */
3388 gboolean offer_srtp = FALSE, require_srtp = FALSE;
3389 janus_srtp_profile srtp_profile = JANUS_SRTP_AES128_CM_SHA1_80;
3390 json_t *srtp = json_object_get(root, "srtp");
3391 if(srtp) {
3392 const char *srtp_text = json_string_value(srtp);
3393 if(!strcasecmp(srtp_text, "sdes_optional")) {
3394 /* Negotiate SDES, but make it optional */
3395 offer_srtp = TRUE;
3396 } else if(!strcasecmp(srtp_text, "sdes_mandatory")) {
3397 /* Negotiate SDES, and require it */
3398 offer_srtp = TRUE;
3399 require_srtp = TRUE;
3400 } else {
3401 JANUS_LOG(LOG_ERR, "Invalid element (srtp can only be sdes_optional or sdes_mandatory)\n");
3402 error_code = JANUS_SIP_ERROR_INVALID_ELEMENT;
3403 g_snprintf(error_cause, 512, "Invalid element (srtp can only be sdes_optional or sdes_mandatory)");
3404 goto error;
3405 }
3406 if(offer_srtp) {
3407 /* Any SRTP profile different from the default? */
3408 srtp_profile = JANUS_SRTP_AES128_CM_SHA1_80;
3409 const char *profile = json_string_value(json_object_get(root, "srtp_profile"));
3410 if(profile) {
3411 if(!strcmp(profile, "AES_CM_128_HMAC_SHA1_32")) {
3412 srtp_profile = JANUS_SRTP_AES128_CM_SHA1_32;
3413 } else if(!strcmp(profile, "AES_CM_128_HMAC_SHA1_80")) {
3414 srtp_profile = JANUS_SRTP_AES128_CM_SHA1_80;
3415 #ifdef HAVE_SRTP_AESGCM
3416 } else if(!strcmp(profile, "AEAD_AES_128_GCM")) {
3417 srtp_profile = JANUS_SRTP_AEAD_AES_128_GCM;
3418 } else if(!strcmp(profile, "AEAD_AES_256_GCM")) {
3419 srtp_profile = JANUS_SRTP_AEAD_AES_256_GCM;
3420 #endif
3421 } else {
3422 JANUS_LOG(LOG_ERR, "Invalid element (unsupported SRTP profile)\n");
3423 error_code = JANUS_SIP_ERROR_INVALID_ELEMENT;
3424 g_snprintf(error_cause, 512, "Invalid element (unsupported SRTP profile)");
3425 goto error;
3426 }
3427 }
3428 }
3429 }
3430 json_t *aar = json_object_get(root, "autoaccept_reinvites");
3431 session->media.autoaccept_reinvites = aar ? json_is_true(aar) : TRUE;
3432 /* Parse address */
3433 const char *uri_text = json_string_value(uri);
3434 janus_sip_uri_t target_uri;
3435 if(janus_sip_parse_uri(&target_uri, uri_text) < 0) {
3436 JANUS_LOG(LOG_ERR, "Invalid user address %s\n", uri_text);
3437 error_code = JANUS_SIP_ERROR_INVALID_ADDRESS;
3438 g_snprintf(error_cause, 512, "Invalid user address %s\n", uri_text);
3439 goto error;
3440 }
3441 /* Any SDP to handle? if not, something's wrong */
3442 const char *msg_sdp_type = json_string_value(json_object_get(msg->jsep, "type"));
3443 const char *msg_sdp = json_string_value(json_object_get(msg->jsep, "sdp"));
3444 if(!msg_sdp) {
3445 JANUS_LOG(LOG_ERR, "Missing SDP\n");
3446 error_code = JANUS_SIP_ERROR_MISSING_SDP;
3447 g_snprintf(error_cause, 512, "Missing SDP");
3448 goto error;
3449 }
3450 if(json_is_true(json_object_get(msg->jsep, "e2ee"))) {
3451 /* Media is encrypted, but SIP endpoints will need unencrypted media frames */
3452 JANUS_LOG(LOG_ERR, "Media encryption unsupported by this plugin\n");
3453 error_code = JANUS_SIP_ERROR_INVALID_ELEMENT;
3454 g_snprintf(error_cause, 512, "Media encryption unsupported by this plugin");
3455 goto error;
3456 }
3457 if(strstr(msg_sdp, "m=application")) {
3458 JANUS_LOG(LOG_ERR, "The SIP plugin does not support DataChannels\n");
3459 error_code = JANUS_SIP_ERROR_MISSING_SDP;
3460 g_snprintf(error_cause, 512, "The SIP plugin does not support DataChannels");
3461 goto error;
3462 }
3463 JANUS_LOG(LOG_VERB, "%s is calling %s\n", session->account.username, uri_text);
3464 JANUS_LOG(LOG_VERB, "This is involving a negotiation (%s) as well:\n%s\n", msg_sdp_type, msg_sdp);
3465 /* Clean up SRTP stuff from before first, in case it's still needed */
3466 janus_sip_srtp_cleanup(session);
3467 session->media.require_srtp = require_srtp;
3468 session->media.has_srtp_local_audio = offer_srtp;
3469 session->media.has_srtp_local_video = offer_srtp;
3470 session->media.srtp_profile = srtp_profile;
3471 if(offer_srtp) {
3472 JANUS_LOG(LOG_VERB, "Going to negotiate SDES-SRTP (%s)...\n", require_srtp ? "mandatory" : "optional");
3473 }
3474
3475 /* Get video-orientation extension id from SDP we got */
3476 session->media.video_orientation_extension_id = janus_rtp_header_extension_get_id(msg_sdp, JANUS_RTP_EXTMAP_VIDEO_ORIENTATION);
3477 /* Get audio-level extension id from SDP we got */
3478 session->media.audio_level_extension_id = janus_rtp_header_extension_get_id(msg_sdp, JANUS_RTP_EXTMAP_AUDIO_LEVEL);
3479 /* Parse the SDP we got, manipulate some things, and generate a new one */
3480 char sdperror[100];
3481 janus_sdp *parsed_sdp = janus_sdp_parse(msg_sdp, sdperror, sizeof(sdperror));
3482 if(!parsed_sdp) {
3483 JANUS_LOG(LOG_ERR, "Error parsing SDP: %s\n", sdperror);
3484 error_code = JANUS_SIP_ERROR_MISSING_SDP;
3485 g_snprintf(error_cause, 512, "Error parsing SDP: %s", sdperror);
3486 goto error;
3487 }
3488 /* Allocate RTP ports and merge them with the anonymized SDP */
3489 if(strstr(msg_sdp, "m=audio") && !strstr(msg_sdp, "m=audio 0")) {
3490 JANUS_LOG(LOG_VERB, "Going to negotiate audio...\n");
3491 session->media.has_audio = TRUE; /* FIXME Maybe we need a better way to signal this */
3492 }
3493 if(strstr(msg_sdp, "m=video") && !strstr(msg_sdp, "m=video 0")) {
3494 JANUS_LOG(LOG_VERB, "Going to negotiate video...\n");
3495 session->media.has_video = TRUE; /* FIXME Maybe we need a better way to signal this */
3496 }
3497 janus_mutex_lock(&session->mutex);
3498 if(janus_sip_allocate_local_ports(session, FALSE) < 0) {
3499 janus_mutex_unlock(&session->mutex);
3500 JANUS_LOG(LOG_ERR, "Could not allocate RTP/RTCP ports\n");
3501 janus_sdp_destroy(parsed_sdp);
3502 error_code = JANUS_SIP_ERROR_IO_ERROR;
3503 g_snprintf(error_cause, 512, "Could not allocate RTP/RTCP ports");
3504 goto error;
3505 }
3506 janus_mutex_unlock(&session->mutex);
3507 char *sdp = janus_sip_sdp_manipulate(session, parsed_sdp, FALSE);
3508 if(sdp == NULL) {
3509 JANUS_LOG(LOG_ERR, "Error manipulating SDP\n");
3510 janus_sdp_destroy(parsed_sdp);
3511 error_code = JANUS_SIP_ERROR_IO_ERROR;
3512 g_snprintf(error_cause, 512, "Error manipulating SDP");
3513 goto error;
3514 }
3515 /* Take note of the SDP (may be useful for UPDATEs or re-INVITEs) */
3516 janus_sdp_destroy(session->sdp);
3517 session->sdp = parsed_sdp;
3518 JANUS_LOG(LOG_VERB, "Prepared SDP for INVITE:\n%s", sdp);
3519 /* Prepare the From header */
3520 char from_hdr[1024];
3521 /* Prepare the stack */
3522 if(session->stack->s_nh_i != NULL)
3523 nua_handle_destroy(session->stack->s_nh_i);
3524 if(!session->helper) {
3525 janus_mutex_lock(&session->stack->smutex);
3526 if(session->stack->s_nua == NULL) {
3527 janus_mutex_unlock(&session->stack->smutex);
3528 JANUS_LOG(LOG_ERR, "NUA destroyed while calling?\n");
3529 error_code = JANUS_SIP_ERROR_LIBSOFIA_ERROR;
3530 g_snprintf(error_cause, 512, "Invalid NUA");
3531 goto error;
3532 }
3533 session->stack->s_nh_i = nua_handle(session->stack->s_nua, session, TAG_END());
3534 janus_mutex_unlock(&session->stack->smutex);
3535 if(session->account.display_name) {
3536 g_snprintf(from_hdr, sizeof(from_hdr), "\"%s\" <%s>", session->account.display_name, session->account.identity);
3537 } else {
3538 g_snprintf(from_hdr, sizeof(from_hdr), "%s", session->account.identity);
3539 }
3540 } else {
3541 /* This is a helper, we need to use the master's SIP stack */
3542 if(session->master == NULL || session->master->stack == NULL) {
3543 g_free(sdp);
3544 session->sdp = NULL;
3545 janus_sdp_destroy(parsed_sdp);
3546 error_code = JANUS_SIP_ERROR_HELPER_ERROR;
3547 g_snprintf(error_cause, 512, "Invalid master SIP stack");
3548 goto error;
3549 }
3550 janus_mutex_lock(&session->master->stack->smutex);
3551 if(session->master->stack->s_nua == NULL) {
3552 janus_mutex_unlock(&session->master->stack->smutex);
3553 g_free(sdp);
3554 session->sdp = NULL;
3555 janus_sdp_destroy(parsed_sdp);
3556 error_code = JANUS_SIP_ERROR_LIBSOFIA_ERROR;
3557 g_snprintf(error_cause, 512, "Invalid NUA");
3558 goto error;
3559 }
3560 session->stack->s_nh_i = nua_handle(session->master->stack->s_nua, session, TAG_END());
3561 janus_mutex_unlock(&session->master->stack->smutex);
3562 if(session->master->account.display_name) {
3563 g_snprintf(from_hdr, sizeof(from_hdr), "\"%s\" <%s>", session->master->account.display_name, session->master->account.identity);
3564 } else {
3565 g_snprintf(from_hdr, sizeof(from_hdr), "%s", session->master->account.identity);
3566 }
3567 }
3568 if(session->stack->s_nh_i == NULL) {
3569 JANUS_LOG(LOG_WARN, "NUA Handle for INVITE still null??\n");
3570 g_free(sdp);
3571 session->sdp = NULL;
3572 janus_sdp_destroy(parsed_sdp);
3573 error_code = JANUS_SIP_ERROR_LIBSOFIA_ERROR;
3574 g_snprintf(error_cause, 512, "Invalid NUA Handle");
3575 goto error;
3576 }
3577 g_atomic_int_set(&session->hangingup, 0);
3578 janus_sip_call_update_status(session, janus_sip_call_status_inviting);
3579 char *callid;
3580 json_t *request_callid = json_object_get(root, "call_id");
3581 /* Take call-id from request, if it exists */
3582 if(request_callid) {
3583 callid = g_strdup(json_string_value(request_callid));
3584 } else {
3585 /* If call-id does not exist in request, create a random one */
3586 callid = g_malloc0(24);
3587 janus_sip_random_string(24, callid);
3588 }
3589 /* Also notify event handlers */
3590 if(notify_events && gateway->events_is_enabled()) {
3591 json_t *info = json_object();
3592 json_object_set_new(info, "event", json_string("calling"));
3593 json_object_set_new(info, "callee", json_string(uri_text));
3594 json_object_set_new(info, "call-id", json_string(callid));
3595 json_object_set_new(info, "sdp", json_string(sdp));
3596 gateway->notify_event(&janus_sip_plugin, session->handle, info);
3597 }
3598 /* If we're here because of a REFER, tell the transferer the request was accepted */
3599 guint32 refer_id = json_integer_value(json_object_get(root, "refer_id"));
3600 char *referred_by = NULL;
3601 if(refer_id > 0) {
3602 JANUS_LOG(LOG_VERB, "Call is after a refer (%"SCNu32")\n", refer_id);
3603 janus_mutex_lock(&sessions_mutex);
3604 janus_sip_transfer *transfer = g_hash_table_lookup(transfers, GUINT_TO_POINTER(refer_id));
3605 janus_mutex_unlock(&sessions_mutex);
3606 if(transfer != NULL) {
3607 if(session->refer_id > 0 && session->refer_id != refer_id) {
3608 janus_mutex_lock(&sessions_mutex);
3609 g_hash_table_remove(transfers, GUINT_TO_POINTER(session->refer_id));
3610 janus_mutex_unlock(&sessions_mutex);
3611 }
3612 session->refer_id = refer_id;
3613 referred_by = transfer->referred_by ? g_strdup(transfer->referred_by) : NULL;
3614 /* Any custom headers we should include? (e.g., Replaces) */
3615 janus_strlcat(custom_headers, transfer->custom_headers, sizeof(custom_headers));
3616 }
3617 }
3618 /* If the user negotiated simulcasting, just stick with the base substream */
3619 json_t *msg_simulcast = json_object_get(msg->jsep, "simulcast");
3620 if(msg_simulcast) {
3621 JANUS_LOG(LOG_WARN, "Client negotiated simulcasting which we don't do here, falling back to base substream...\n");
3622 json_t *s = json_object_get(msg_simulcast, "ssrcs");
3623 if(s && json_array_size(s) > 0)
3624 session->media.simulcast_ssrc = json_integer_value(json_array_get(s, 0));
3625 }
3626 /* Check if there are new credentials to authenticate the INVITE */
3627 if(authuser) {
3628 JANUS_LOG(LOG_VERB, "Updating credentials (authuser) for authenticating the INVITE\n");
3629 if(!session->helper) {
3630 g_free(session->account.authuser);
3631 session->account.authuser = g_strdup(json_string_value(authuser));
3632 } else if(session->master != NULL) {
3633 g_free(session->master->account.authuser);
3634 session->master->account.authuser = g_strdup(json_string_value(authuser));
3635 }
3636 }
3637 if(secret) {
3638 JANUS_LOG(LOG_VERB, "Updating credentials (secret) for authenticating the INVITE\n");
3639 if(!session->helper) {
3640 g_free(session->account.secret);
3641 session->account.secret = g_strdup(json_string_value(secret));
3642 session->account.secret_type = janus_sip_secret_type_plaintext;
3643 } else if(session->master != NULL) {
3644 g_free(session->master->account.secret);
3645 session->master->account.secret = g_strdup(json_string_value(secret));
3646 session->master->account.secret_type = janus_sip_secret_type_plaintext;
3647 }
3648 } else if(ha1_secret) {
3649 JANUS_LOG(LOG_VERB, "Updating credentials (ha1_secret) for authenticating the INVITE\n");
3650 if(!session->helper) {
3651 g_free(session->account.secret);
3652 session->account.secret = g_strdup(json_string_value(ha1_secret));
3653 session->account.secret_type = janus_sip_secret_type_hashed;
3654 } else if(session->master != NULL) {
3655 g_free(session->master->account.secret);
3656 session->master->account.secret = g_strdup(json_string_value(ha1_secret));
3657 session->master->account.secret_type = janus_sip_secret_type_hashed;
3658 }
3659 }
3660 /* Send INVITE */
3661 janus_mutex_lock(&session->mutex);
3662 g_free(session->callee);
3663 session->callee = g_strdup(uri_text);
3664 janus_mutex_unlock(&session->mutex);
3665 g_free(session->callid);
3666 session->callid = callid;
3667 janus_mutex_lock(&sessions_mutex);
3668 g_hash_table_insert(callids, session->callid, session);
3669 janus_mutex_unlock(&sessions_mutex);
3670 g_atomic_int_set(&session->establishing, 1);
3671 /* Add a reference for this call */
3672 janus_sip_ref_active_call(session);
3673 /* Check if we need to manually add the Contact header */
3674 gboolean add_contact_header = (session->stack->contact_header != NULL);
3675 /* Send the INVITE */
3676 nua_invite(session->stack->s_nh_i,
3677 SIPTAG_FROM_STR(from_hdr),
3678 SIPTAG_TO_STR(uri_text),
3679 SIPTAG_CALL_ID_STR(callid),
3680 TAG_IF(add_contact_header, SIPTAG_CONTACT_STR(session->stack->contact_header)),
3681 SOATAG_USER_SDP_STR(sdp),
3682 NUTAG_PROXY(session->helper && session->master ?
3683 session->master->account.outbound_proxy : session->account.outbound_proxy),
3684 TAG_IF(referred_by != NULL, SIPTAG_REFERRED_BY_STR(referred_by)),
3685 TAG_IF(strlen(custom_headers) > 0, SIPTAG_HEADER_STR(custom_headers)),
3686 NUTAG_AUTOANSWER(0),
3687 NUTAG_AUTOACK(FALSE),
3688 TAG_END());
3689 g_free(sdp);
3690 g_free(session->transaction);
3691 g_free(referred_by);
3692 session->transaction = msg->transaction ? g_strdup(msg->transaction) : NULL;
3693 /* Send an ack back */
3694 result = json_object();
3695 json_object_set_new(result, "event", json_string("calling"));
3696 json_object_set_new(result, "call_id", json_string(session->callid));
3697 } else if(!strcasecmp(request_text, "accept")) {
3698 if(session->status != janus_sip_call_status_invited) {
3699 JANUS_LOG(LOG_ERR, "Wrong state (not invited? status=%s)\n", janus_sip_call_status_string(session->status));
3700 error_code = JANUS_SIP_ERROR_WRONG_STATE;
3701 g_snprintf(error_cause, 512, "Wrong state (not invited? status=%s)", janus_sip_call_status_string(session->status));
3702 goto error;
3703 }
3704 janus_mutex_lock(&session->mutex);
3705 if(session->callee == NULL) {
3706 janus_mutex_unlock(&session->mutex);
3707 JANUS_LOG(LOG_ERR, "Wrong state (no caller?)\n");
3708 error_code = JANUS_SIP_ERROR_WRONG_STATE;
3709 g_snprintf(error_cause, 512, "Wrong state (no caller?)");
3710 goto error;
3711 }
3712 janus_mutex_unlock(&session->mutex);
3713 JANUS_VALIDATE_JSON_OBJECT(root, accept_parameters,
3714 error_code, error_cause, TRUE,
3715 JANUS_SIP_ERROR_MISSING_ELEMENT, JANUS_SIP_ERROR_INVALID_ELEMENT);
3716 if(error_code != 0)
3717 goto error;
3718 json_t *srtp = json_object_get(root, "srtp");
3719 gboolean answer_srtp = FALSE;
3720 if(srtp) {
3721 const char *srtp_text = json_string_value(srtp);
3722 if(!strcasecmp(srtp_text, "sdes_optional")) {
3723 /* Negotiate SDES, but make it optional */
3724 answer_srtp = TRUE;
3725 } else if(!strcasecmp(srtp_text, "sdes_mandatory")) {
3726 /* Negotiate SDES, and require it */
3727 answer_srtp = TRUE;
3728 session->media.require_srtp = TRUE;
3729 } else {
3730 JANUS_LOG(LOG_ERR, "Invalid element (srtp can only be sdes_optional or sdes_mandatory)\n");
3731 error_code = JANUS_SIP_ERROR_INVALID_ELEMENT;
3732 g_snprintf(error_cause, 512, "Invalid element (srtp can only be sdes_optional or sdes_mandatory)");
3733 goto error;
3734 }
3735 }
3736 gboolean has_srtp = TRUE;
3737 if(session->media.has_audio)
3738 has_srtp = (has_srtp && session->media.has_srtp_remote_audio);
3739 if(session->media.has_video)
3740 has_srtp = (has_srtp && session->media.has_srtp_remote_video);
3741 if(session->media.require_srtp && !has_srtp) {
3742 JANUS_LOG(LOG_ERR, "Can't accept the call: SDES-SRTP required, but caller didn't offer it\n");
3743 error_code = JANUS_SIP_ERROR_TOO_STRICT;
3744 g_snprintf(error_cause, 512, "Can't accept the call: SDES-SRTP required, but caller didn't offer it");
3745 goto error;
3746 }
3747 answer_srtp = answer_srtp || session->media.has_srtp_remote_audio || session->media.has_srtp_remote_video;
3748 json_t *aar = json_object_get(root, "autoaccept_reinvites");
3749 session->media.autoaccept_reinvites = aar ? json_is_true(aar) : TRUE;
3750 /* Any SDP to handle? if not, something's wrong */
3751 const char *msg_sdp_type = json_string_value(json_object_get(msg->jsep, "type"));
3752 const char *msg_sdp = json_string_value(json_object_get(msg->jsep, "sdp"));
3753 if(!msg_sdp) {
3754 JANUS_LOG(LOG_ERR, "Missing SDP\n");
3755 error_code = JANUS_SIP_ERROR_MISSING_SDP;
3756 g_snprintf(error_cause, 512, "Missing SDP");
3757 goto error;
3758 }
3759 if(json_is_true(json_object_get(msg->jsep, "e2ee"))) {
3760 /* Media is encrypted, but SIP endpoints will need unencrypted media frames */
3761 JANUS_LOG(LOG_ERR, "Media encryption unsupported by this plugin\n");
3762 error_code = JANUS_SIP_ERROR_INVALID_ELEMENT;
3763 g_snprintf(error_cause, 512, "Media encryption unsupported by this plugin");
3764 goto error;
3765 }
3766 /* Accept a call from another peer */
3767 JANUS_LOG(LOG_VERB, "We're accepting the call from %s\n", session->callee);
3768 gboolean answer = !strcasecmp(msg_sdp_type, "answer");
3769 if(!answer) {
3770 JANUS_LOG(LOG_VERB, "This is a response to an offerless INVITE\n");
3771 }
3772 JANUS_LOG(LOG_VERB, "This is involving a negotiation (%s) as well:\n%s\n", msg_sdp_type, msg_sdp);
3773 session->media.has_srtp_local_audio = answer_srtp && session->media.has_srtp_remote_audio;
3774 session->media.has_srtp_local_video = answer_srtp && session->media.has_srtp_remote_video;
3775 if(answer_srtp) {
3776 JANUS_LOG(LOG_VERB, "Going to negotiate SDES-SRTP (%s)...\n", session->media.require_srtp ? "mandatory" : "optional");
3777 }
3778
3779 /* Get video-orientation extension id from SDP we got */
3780 session->media.video_orientation_extension_id = janus_rtp_header_extension_get_id(msg_sdp, JANUS_RTP_EXTMAP_VIDEO_ORIENTATION);
3781 /* Get audio-level extension id from SDP we got */
3782 session->media.audio_level_extension_id = janus_rtp_header_extension_get_id(msg_sdp, JANUS_RTP_EXTMAP_AUDIO_LEVEL);
3783 /* Parse the SDP we got, manipulate some things, and generate a new one */
3784 char sdperror[100];
3785 janus_sdp *parsed_sdp = janus_sdp_parse(msg_sdp, sdperror, sizeof(sdperror));
3786 if(!parsed_sdp) {
3787 JANUS_LOG(LOG_ERR, "Error parsing SDP: %s\n", sdperror);
3788 error_code = JANUS_SIP_ERROR_MISSING_SDP;
3789 g_snprintf(error_cause, 512, "Error parsing SDP: %s", sdperror);
3790 goto error;
3791 }
3792 /* Allocate RTP ports and merge them with the anonymized SDP */
3793 if(strstr(msg_sdp, "m=audio") && !strstr(msg_sdp, "m=audio 0")) {
3794 JANUS_LOG(LOG_VERB, "Going to negotiate audio...\n");
3795 session->media.has_audio = TRUE; /* FIXME Maybe we need a better way to signal this */
3796 }
3797 if(strstr(msg_sdp, "m=video") && !strstr(msg_sdp, "m=video 0")) {
3798 JANUS_LOG(LOG_VERB, "Going to negotiate video...\n");
3799 session->media.has_video = TRUE; /* FIXME Maybe we need a better way to signal this */
3800 }
3801 janus_mutex_lock(&session->mutex);
3802 if(janus_sip_allocate_local_ports(session, FALSE) < 0) {
3803 janus_mutex_unlock(&session->mutex);
3804 JANUS_LOG(LOG_ERR, "Could not allocate RTP/RTCP ports\n");
3805 janus_sdp_destroy(parsed_sdp);
3806 error_code = JANUS_SIP_ERROR_IO_ERROR;
3807 g_snprintf(error_cause, 512, "Could not allocate RTP/RTCP ports");
3808 goto error;
3809 }
3810 janus_mutex_unlock(&session->mutex);
3811 char *sdp = janus_sip_sdp_manipulate(session, parsed_sdp, TRUE);
3812 if(sdp == NULL) {
3813 JANUS_LOG(LOG_ERR, "Could not allocate RTP/RTCP ports\n");
3814 janus_sdp_destroy(parsed_sdp);
3815 error_code = JANUS_SIP_ERROR_IO_ERROR;
3816 g_snprintf(error_cause, 512, "Could not allocate RTP/RTCP ports");
3817 goto error;
3818 }
3819 if(session->media.audio_pt > -1) {
3820 session->media.audio_pt_name = janus_get_codec_from_pt(sdp, session->media.audio_pt);
3821 JANUS_LOG(LOG_VERB, "Detected audio codec: %d (%s)\n", session->media.audio_pt, session->media.audio_pt_name);
3822 }
3823 if(session->media.video_pt > -1) {
3824 session->media.video_pt_name = janus_get_codec_from_pt(sdp, session->media.video_pt);
3825 JANUS_LOG(LOG_VERB, "Detected video codec: %d (%s)\n", session->media.video_pt, session->media.video_pt_name);
3826 }
3827 /* Take note of the SDP (may be useful for UPDATEs or re-INVITEs) */
3828 janus_sdp_destroy(session->sdp);
3829 session->sdp = parsed_sdp;
3830 JANUS_LOG(LOG_VERB, "Prepared SDP for 200 OK:\n%s", sdp);
3831 /* If the user negotiated simulcasting, just stick with the base substream */
3832 json_t *msg_simulcast = json_object_get(msg->jsep, "simulcast");
3833 if(msg_simulcast) {
3834 JANUS_LOG(LOG_WARN, "Client negotiated simulcasting which we don't do here, falling back to base substream...\n");
3835 json_t *s = json_object_get(msg_simulcast, "ssrcs");
3836 if(s && json_array_size(s) > 0)
3837 session->media.simulcast_ssrc = json_integer_value(json_array_get(s, 0));
3838 }
3839 /* Also notify event handlers */
3840 if(notify_events && gateway->events_is_enabled()) {
3841 json_t *info = json_object();
3842 json_object_set_new(info, "event", json_string(answer ? "accepted" : "accepting"));
3843 if(session->callid)
3844 json_object_set_new(info, "call-id", json_string(session->callid));
3845 gateway->notify_event(&janus_sip_plugin, session->handle, info);
3846 }
3847 /* Check if the OK needs to be enriched with custom headers */
3848 char custom_headers[2048];
3849 janus_sip_parse_custom_headers(root, (char *)&custom_headers, sizeof(custom_headers));
3850 /* Send 200 OK */
3851 if(!answer) {
3852 if(session->transaction)
3853 g_free(session->transaction);
3854 session->transaction = msg->transaction ? g_strdup(msg->transaction) : NULL;
3855 }
3856 g_atomic_int_set(&session->hangingup, 0);
3857 janus_sip_call_update_status(session, janus_sip_call_status_incall);
3858 if(session->stack->s_nh_i == NULL) {
3859 JANUS_LOG(LOG_WARN, "NUA Handle for 200 OK still null??\n");
3860 }
3861 nua_respond(session->stack->s_nh_i,
3862 200, sip_status_phrase(200),
3863 SOATAG_USER_SDP_STR(sdp),
3864 SOATAG_RTP_SELECT(SOA_RTP_SELECT_COMMON),
3865 NUTAG_AUTOANSWER(0),
3866 NUTAG_AUTOACK(FALSE),
3867 TAG_IF(strlen(custom_headers) > 0, SIPTAG_HEADER_STR(custom_headers)),
3868 TAG_END());
3869 g_free(sdp);
3870 /* Send an ack back */
3871 result = json_object();
3872 json_object_set_new(result, "event", json_string(answer ? "accepted" : "accepting"));
3873 if(answer) {
3874 /* Start the media */
3875 session->media.ready = TRUE; /* FIXME Maybe we need a better way to signal this */
3876 GError *error = NULL;
3877 char tname[16];
3878 g_snprintf(tname, sizeof(tname), "siprtp %s", session->account.username);
3879 janus_refcount_increase(&session->ref);
3880 session->relayer_thread = g_thread_try_new(tname, janus_sip_relay_thread, session, &error);
3881 if(error != NULL) {
3882 session->relayer_thread = NULL;
3883 session->media.ready = FALSE;
3884 janus_refcount_decrease(&session->ref);
3885 JANUS_LOG(LOG_ERR, "Got error %d (%s) trying to launch the RTP/RTCP thread...\n",
3886 error->code, error->message ? error->message : "??");
3887 g_error_free(error);
3888 }
3889 }
3890 } else if(!strcasecmp(request_text, "update")) {
3891 /* Update an existing call */
3892 if(!(session->status == janus_sip_call_status_incall_reinvited || session->status == janus_sip_call_status_incall)) {
3893 JANUS_LOG(LOG_ERR, "Wrong state (not in a call? status=%s)\n", janus_sip_call_status_string(session->status));
3894 error_code = JANUS_SIP_ERROR_WRONG_STATE;
3895 g_snprintf(error_cause, 512, "Wrong state (not in a call?)");
3896 goto error;
3897 }
3898 janus_mutex_lock(&session->mutex);
3899 if(session->callee == NULL) {
3900 janus_mutex_unlock(&session->mutex);
3901 JANUS_LOG(LOG_ERR, "Wrong state (no callee?)\n");
3902 error_code = JANUS_SIP_ERROR_WRONG_STATE;
3903 g_snprintf(error_cause, 512, "Wrong state (no callee?)");
3904 goto error;
3905 }
3906 janus_mutex_unlock(&session->mutex);
3907 if(session->sdp == NULL) {
3908 JANUS_LOG(LOG_ERR, "Wrong state (no local SDP?)\n");
3909 error_code = JANUS_SIP_ERROR_WRONG_STATE;
3910 g_snprintf(error_cause, 512, "Wrong state (no local SDP?)");
3911 goto error;
3912 }
3913 /* Any SDP to handle? if not, something's wrong */
3914 const char *msg_sdp = json_string_value(json_object_get(msg->jsep, "sdp"));
3915 if(!msg_sdp) {
3916 JANUS_LOG(LOG_ERR, "Missing SDP update\n");
3917 error_code = JANUS_SIP_ERROR_MISSING_SDP;
3918 g_snprintf(error_cause, 512, "Missing SDP update");
3919 goto error;
3920 }
3921 if(!json_is_true(json_object_get(msg->jsep, "update"))) {
3922 JANUS_LOG(LOG_ERR, "Missing SDP update\n");
3923 error_code = JANUS_SIP_ERROR_MISSING_SDP;
3924 g_snprintf(error_cause, 512, "Missing SDP update");
3925 goto error;
3926 }
3927 if(json_is_true(json_object_get(msg->jsep, "e2ee"))) {
3928 /* Media is encrypted, but SIP endpoints will need unencrypted media frames */
3929 JANUS_LOG(LOG_ERR, "Media encryption unsupported by this plugin\n");
3930 error_code = JANUS_SIP_ERROR_INVALID_ELEMENT;
3931 g_snprintf(error_cause, 512, "Media encryption unsupported by this plugin");
3932 goto error;
3933 }
3934 const char *msg_sdp_type = json_string_value(json_object_get(msg->jsep, "type"));
3935 gboolean offer = !strcasecmp(msg_sdp_type, "offer");
3936 if(!offer && session->status == janus_sip_call_status_incall) {
3937 JANUS_LOG(LOG_ERR, "[SIP-%s] SDP type %s is incompatible with session status %s\n", session->account.username, msg_sdp_type, janus_sip_call_status_string(session->status));
3938 error_code = JANUS_SIP_ERROR_MISSING_SDP;
3939 g_snprintf(error_cause, 512, "[SIP-%s] SDP type %s is incompatible with session status %s\n", session->account.username, msg_sdp_type, janus_sip_call_status_string(session->status));
3940 goto error;
3941 }
3942
3943 /* Get video-orientation extension id from SDP we got */
3944 session->media.video_orientation_extension_id = janus_rtp_header_extension_get_id(msg_sdp, JANUS_RTP_EXTMAP_VIDEO_ORIENTATION);
3945 /* Get audio-level extension id from SDP we got */
3946 session->media.audio_level_extension_id = janus_rtp_header_extension_get_id(msg_sdp, JANUS_RTP_EXTMAP_AUDIO_LEVEL);
3947 /* Parse the SDP we got, manipulate some things, and generate a new one */
3948 char sdperror[100];
3949 janus_sdp *parsed_sdp = janus_sdp_parse(msg_sdp, sdperror, sizeof(sdperror));
3950 if(!parsed_sdp) {
3951 JANUS_LOG(LOG_ERR, "Error parsing SDP: %s\n", sdperror);
3952 error_code = JANUS_SIP_ERROR_MISSING_SDP;
3953 g_snprintf(error_cause, 512, "Error parsing SDP: %s", sdperror);
3954 goto error;
3955 }
3956
3957 if(session->status == janus_sip_call_status_incall_reinvited && offer) {
3958 /* We have re-INVITE in progress */
3959 JANUS_LOG(LOG_VERB, "[SIP-%s] We have incoming offereless re-INVITE in progress\n", session->account.username);
3960 }
3961
3962 if(offer)
3963 session->sdp->o_version++;
3964
3965 gboolean audio_added = strstr(msg_sdp, "m=audio") && !strstr(msg_sdp, "m=audio 0") && session->media.local_audio_rtp_port == 0;
3966 gboolean video_added = strstr(msg_sdp, "m=video") && !strstr(msg_sdp, "m=video 0") && session->media.local_video_rtp_port == 0;
3967 if(audio_added)
3968 session->media.has_audio = TRUE; /* FIXME Maybe we need a better way to signal this */
3969 if(video_added)
3970 session->media.has_video = TRUE; /* FIXME Maybe we need a better way to signal this */
3971
3972 if(offer) {
3973 gboolean offer_srtp = session->media.require_srtp || session->media.has_srtp_local_audio || session->media.has_srtp_local_video;
3974 session->media.has_srtp_local_audio = offer_srtp;
3975 session->media.has_srtp_local_video = offer_srtp;
3976 } else {
3977 gboolean has_srtp = TRUE;
3978 if (session->media.has_audio)
3979 has_srtp = (has_srtp && session->media.has_srtp_remote_audio);
3980 if (session->media.has_video)
3981 has_srtp = (has_srtp && session->media.has_srtp_remote_video);
3982 if (session->media.require_srtp && !has_srtp) {
3983 JANUS_LOG(LOG_ERR,
3984 "Can't update the call: SDES-SRTP required, but caller didn't offer it\n");
3985 error_code = JANUS_SIP_ERROR_TOO_STRICT;
3986 g_snprintf(error_cause, 512,
3987 "Can't update the call: SDES-SRTP required, but caller didn't offer it");
3988 goto error;
3989 }
3990 session->media.has_srtp_local_audio = session->media.has_srtp_remote_audio;
3991 session->media.has_srtp_local_video = session->media.has_srtp_remote_video;
3992 }
3993 if(audio_added || video_added) {
3994 janus_mutex_lock(&session->mutex);
3995 if(janus_sip_allocate_local_ports(session, TRUE) < 0) {
3996 janus_mutex_unlock(&session->mutex);
3997 JANUS_LOG(LOG_ERR, "Could not allocate RTP/RTCP ports\n");
3998 janus_sdp_destroy(parsed_sdp);
3999 error_code = JANUS_SIP_ERROR_IO_ERROR;
4000 g_snprintf(error_cause, 512, "Could not allocate RTP/RTCP ports");
4001 goto error;
4002 }
4003 janus_mutex_unlock(&session->mutex);
4004 if(!offer)
4005 session->media.updated = TRUE;
4006 }
4007 char *sdp = janus_sip_sdp_manipulate(session, parsed_sdp, !offer);
4008 if(sdp == NULL) {
4009 JANUS_LOG(LOG_ERR, "Error manipulating SDP\n");
4010 janus_sdp_destroy(parsed_sdp);
4011 error_code = JANUS_SIP_ERROR_IO_ERROR;
4012 g_snprintf(error_cause, 512, "Error manipulating SDP");
4013 goto error;
4014 }
4015 if(!offer) {
4016 if(session->media.audio_pt_name == NULL && session->media.audio_pt > -1) {
4017 session->media.audio_pt_name = janus_get_codec_from_pt(sdp, session->media.audio_pt);
4018 JANUS_LOG(LOG_VERB, "Detected audio codec: %d (%s)\n", session->media.audio_pt, session->media.audio_pt_name);
4019 }
4020 if(session->media.video_pt_name == NULL && session->media.video_pt > -1) {
4021 session->media.video_pt_name = janus_get_codec_from_pt(sdp, session->media.video_pt);
4022 JANUS_LOG(LOG_VERB, "Detected video codec: %d (%s)\n", session->media.video_pt, session->media.video_pt_name);
4023 }
4024 }
4025 /* Take note of the new SDP */
4026 janus_sdp_destroy(session->sdp);
4027 session->sdp = parsed_sdp;
4028 session->media.update = offer;
4029 JANUS_LOG(LOG_VERB, "Prepared SDP for update:\n%s", sdp);
4030 if(session->status == janus_sip_call_status_incall) {
4031 /* We're sending a re-INVITE ourselves */
4032 nua_invite(session->stack->s_nh_i,
4033 SOATAG_USER_SDP_STR(sdp),
4034 TAG_END());
4035 } else {
4036 /* We're answering to a re-INVITE we received */
4037 nua_respond(session->stack->s_nh_i,
4038 200, sip_status_phrase(200),
4039 SOATAG_USER_SDP_STR(sdp),
4040 SOATAG_RTP_SELECT(SOA_RTP_SELECT_COMMON),
4041 NUTAG_AUTOANSWER(0),
4042 TAG_END());
4043 }
4044 g_free(sdp);
4045 /* Send an ack back */
4046 result = json_object();
4047 json_object_set_new(result, "event", json_string(offer ? "updating" : "updated"));
4048 } else if(!strcasecmp(request_text, "decline")) {
4049 JANUS_VALIDATE_JSON_OBJECT(root, decline_parameters,
4050 error_code, error_cause, TRUE,
4051 JANUS_SIP_ERROR_MISSING_ELEMENT, JANUS_SIP_ERROR_INVALID_ELEMENT);
4052 if(error_code != 0)
4053 goto error;
4054 /* Wheck if we're declining a call transfer, rather than an incoming call */
4055 guint32 refer_id = json_integer_value(json_object_get(root, "refer_id"));
4056 if(refer_id > 0) {
4057 janus_mutex_lock(&sessions_mutex);
4058 janus_sip_transfer *transfer = g_hash_table_lookup(transfers, GUINT_TO_POINTER(refer_id));
4059 janus_mutex_unlock(&sessions_mutex);
4060 if(transfer != NULL && transfer->nh_s != NULL) {
4061 /* Send a NOTIFY with the error code */
4062 int response_code = 603;
4063 json_t *code_json = json_object_get(root, "code");
4064 if(code_json)
4065 response_code = json_integer_value(code_json);
4066 if(response_code <= 399) {
4067 JANUS_LOG(LOG_WARN, "Invalid SIP response code specified, using 603 to decline transfer\n");
4068 response_code = 603;
4069 }
4070 char content[100];
4071 g_snprintf(content, sizeof(content), "SIP/2.0 %d %s", response_code, sip_status_phrase(response_code));
4072 nua_notify(transfer->nh_s,
4073 NUTAG_SUBSTATE(nua_substate_terminated),
4074 SIPTAG_CONTENT_TYPE_STR("message/sipfrag"),
4075 SIPTAG_PAYLOAD_STR(content),
4076 NUTAG_WITH_SAVED(transfer->saved),
4077 TAG_END());
4078 /* Also notify event handlers */
4079 if(notify_events && gateway->events_is_enabled()) {
4080 json_t *info = json_object();
4081 json_object_set_new(info, "event", json_string("declined"));
4082 json_object_set_new(info, "refer_id", json_integer(refer_id));
4083 json_object_set_new(info, "code", json_integer(response_code));
4084 gateway->notify_event(&janus_sip_plugin, session->handle, info);
4085 }
4086 /* Notify the operation */
4087 result = json_object();
4088 json_object_set_new(result, "event", json_string("declining"));
4089 json_object_set_new(result, "refer_id", json_integer(refer_id));
4090 json_object_set_new(result, "code", json_integer(response_code));
4091 janus_mutex_lock(&sessions_mutex);
4092 g_hash_table_remove(transfers, GUINT_TO_POINTER(refer_id));
4093 janus_mutex_unlock(&sessions_mutex);
4094 goto done;
4095 } else {
4096 janus_mutex_lock(&sessions_mutex);
4097 g_hash_table_remove(transfers, GUINT_TO_POINTER(refer_id));
4098 janus_mutex_unlock(&sessions_mutex);
4099 JANUS_LOG(LOG_ERR, "Wrong state (no transfer?)\n");
4100 error_code = JANUS_SIP_ERROR_WRONG_STATE;
4101 g_snprintf(error_cause, 512, "Wrong state (no transfer?)");
4102 goto error;
4103 }
4104 }
4105 /* Reject an incoming call */
4106 if(session->status != janus_sip_call_status_invited) {
4107 JANUS_LOG(LOG_ERR, "Wrong state (not invited? status=%s)\n", janus_sip_call_status_string(session->status));
4108 /* Ignore */
4109 janus_sip_message_free(msg);
4110 continue;
4111 //~ g_snprintf(error_cause, 512, "Wrong state (not in a call?)");
4112 //~ goto error;
4113 }
4114 janus_mutex_lock(&session->mutex);
4115 if(session->callee == NULL) {
4116 janus_mutex_unlock(&session->mutex);
4117 JANUS_LOG(LOG_ERR, "Wrong state (no callee?)\n");
4118 error_code = JANUS_SIP_ERROR_WRONG_STATE;
4119 g_snprintf(error_cause, 512, "Wrong state (no callee?)");
4120 goto error;
4121 }
4122 janus_mutex_unlock(&session->mutex);
4123 session->media.earlymedia = FALSE;
4124 session->media.update = FALSE;
4125 session->media.autoaccept_reinvites = TRUE;
4126 session->media.ready = FALSE;
4127 session->media.on_hold = FALSE;
4128 janus_sip_call_update_status(session, janus_sip_call_status_closing);
4129 if(session->stack->s_nh_i == NULL) {
4130 JANUS_LOG(LOG_WARN, "NUA Handle for 200 OK still null??\n");
4131 }
4132 int response_code = 486;
4133 json_t *code_json = json_object_get(root, "code");
4134 if(code_json)
4135 response_code = json_integer_value(code_json);
4136 if(response_code <= 399) {
4137 JANUS_LOG(LOG_WARN, "Invalid SIP response code specified, using 486 to decline call\n");
4138 response_code = 486;
4139 }
4140 /* Check if the response needs to be enriched with custom headers */
4141 char custom_headers[2048];
4142 janus_sip_parse_custom_headers(root, (char *)&custom_headers, sizeof(custom_headers));
4143 nua_respond(session->stack->s_nh_i, response_code, sip_status_phrase(response_code),
4144 TAG_IF(strlen(custom_headers) > 0, SIPTAG_HEADER_STR(custom_headers)),
4145 TAG_END());
4146 janus_mutex_lock(&session->mutex);
4147 /* Also notify event handlers */
4148 if(notify_events && gateway->events_is_enabled()) {
4149 json_t *info = json_object();
4150 json_object_set_new(info, "event", json_string("declined"));
4151 json_object_set_new(info, "callee", json_string(session->callee));
4152 if(session->callid)
4153 json_object_set_new(info, "call-id", json_string(session->callid));
4154 json_object_set_new(info, "code", json_integer(response_code));
4155 gateway->notify_event(&janus_sip_plugin, session->handle, info);
4156 }
4157 g_free(session->callee);
4158 session->callee = NULL;
4159 janus_mutex_unlock(&session->mutex);
4160 /* Notify the operation */
4161 result = json_object();
4162 json_object_set_new(result, "event", json_string("declining"));
4163 json_object_set_new(result, "code", json_integer(response_code));
4164 if(session->callid)
4165 json_object_set_new(result, "call_id", json_string(session->callid));
4166 } else if(!strcasecmp(request_text, "transfer")) {
4167 /* Transfer an existing call */
4168 JANUS_VALIDATE_JSON_OBJECT(root, transfer_parameters,
4169 error_code, error_cause, TRUE,
4170 JANUS_SIP_ERROR_MISSING_ELEMENT, JANUS_SIP_ERROR_INVALID_ELEMENT);
4171 if(error_code != 0)
4172 goto error;
4173 if(!janus_sip_call_is_established(session)) {
4174 JANUS_LOG(LOG_ERR, "Wrong state (not in a call? status=%s)\n", janus_sip_call_status_string(session->status));
4175 g_snprintf(error_cause, 512, "Wrong state (not in a call?)");
4176 goto error;
4177 }
4178 janus_mutex_lock(&session->mutex);
4179 if(session->callee == NULL) {
4180 janus_mutex_unlock(&session->mutex);
4181 JANUS_LOG(LOG_ERR, "Wrong state (no callee?)\n");
4182 error_code = JANUS_SIP_ERROR_WRONG_STATE;
4183 g_snprintf(error_cause, 512, "Wrong state (no callee?)");
4184 goto error;
4185 }
4186 janus_mutex_unlock(&session->mutex);
4187 if(session->sdp == NULL) {
4188 JANUS_LOG(LOG_ERR, "Wrong state (no local SDP?)\n");
4189 error_code = JANUS_SIP_ERROR_WRONG_STATE;
4190 g_snprintf(error_cause, 512, "Wrong state (no local SDP?)");
4191 goto error;
4192 }
4193 /* Transfer to the following URI */
4194 json_t *uri = json_object_get(root, "uri");
4195 const char *uri_text = json_string_value(uri);
4196 janus_sip_uri_t target_uri;
4197 if(janus_sip_parse_uri(&target_uri, uri_text) < 0) {
4198 JANUS_LOG(LOG_ERR, "Invalid user address %s\n", uri_text);
4199 error_code = JANUS_SIP_ERROR_INVALID_ADDRESS;
4200 g_snprintf(error_cause, 512, "Invalid user address %s\n", uri_text);
4201 goto error;
4202 }
4203 /* Is this a blind (unattended) or warm (attended) transfer? (default=blind) */
4204 const char *callid = json_string_value(json_object_get(root, "replace"));
4205 sip_refer_to_t *refer_to = NULL;
4206 if(callid != NULL) {
4207 /* This is an attended transfer, make sure this call exists */
4208 janus_mutex_lock(&sessions_mutex);
4209 janus_sip_session *replaced = g_hash_table_lookup(callids, callid);
4210 janus_mutex_unlock(&sessions_mutex);
4211 if(replaced == NULL || replaced->stack == NULL || replaced->stack->s_nh_i == NULL) {
4212 JANUS_LOG(LOG_ERR, "No such call-ID %s\n", callid);
4213 error_code = JANUS_SIP_ERROR_NO_SUCH_CALLID;
4214 g_snprintf(error_cause, 512, "No such call-ID %s", callid);
4215 goto error;
4216 }
4217 /* Craft the Replaces header field */
4218 sip_replaces_t *r = nua_handle_make_replaces(replaced->stack->s_nh_i, session->stack->s_home, 0);
4219 char *replaces = sip_headers_as_url_query(session->stack->s_home, SIPTAG_REPLACES(r), TAG_END());
4220 #pragma GCC diagnostic ignored "-Winline"
4221 refer_to = sip_refer_to_format(session->stack->s_home, "<%s?%s>", uri_text, replaces);
4222 #pragma GCC diagnostic warning "-Winline"
4223 JANUS_LOG(LOG_VERB, "Attended transfer: <%s?%s>\n", uri_text, replaces);
4224 su_free(session->stack->s_home, r);
4225 su_free(session->stack->s_home, replaces);
4226 }
4227 #pragma GCC diagnostic ignored "-Winline"
4228 if(refer_to == NULL)
4229 refer_to = sip_refer_to_format(session->stack->s_home, "<%s>", uri_text);
4230 #pragma GCC diagnostic warning "-Winline"
4231 /* Send the REFER */
4232 nua_refer(session->stack->s_nh_i,
4233 SIPTAG_REFER_TO(refer_to),
4234 TAG_END());
4235
4236 /* Notify the operation */
4237 result = json_object();
4238 json_object_set_new(result, "event", json_string("transferring"));
4239 } else if(!strcasecmp(request_text, "hold") || !strcasecmp(request_text, "unhold")) {
4240 /* We either need to put the call on-hold, or resume it */
4241 if(session->status != janus_sip_call_status_incall) {
4242 JANUS_LOG(LOG_ERR, "Wrong state (not in a call? status=%s)\n", janus_sip_call_status_string(session->status));
4243 /* Ignore */
4244 janus_sip_message_free(msg);
4245 continue;
4246 //~ g_snprintf(error_cause, 512, "Wrong state (not in a call?)");
4247 //~ goto error;
4248 }
4249 janus_mutex_lock(&session->mutex);
4250 if(session->callee == NULL) {
4251 janus_mutex_unlock(&session->mutex);
4252 JANUS_LOG(LOG_ERR, "Wrong state (no callee?)\n");
4253 error_code = JANUS_SIP_ERROR_WRONG_STATE;
4254 g_snprintf(error_cause, 512, "Wrong state (no callee?)");
4255 goto error;
4256 }
4257 janus_mutex_unlock(&session->mutex);
4258 if(session->sdp == NULL) {
4259 JANUS_LOG(LOG_ERR, "Wrong state (no SDP?)\n");
4260 error_code = JANUS_SIP_ERROR_WRONG_STATE;
4261 g_snprintf(error_cause, 512, "Wrong state (no SDP?)");
4262 goto error;
4263 }
4264 gboolean hold = !strcasecmp(request_text, "hold");
4265 if(hold != session->media.on_hold) {
4266 /* To put the call on-hold, we need to change the media direction:
4267 * resuming it means resuming the direction we had before */
4268 janus_sdp_mdirection hold_dir = JANUS_SDP_SENDONLY;
4269 if(hold) {
4270 /* By default when holding we use recvonly, but the
4271 * actual direction to set can be passed via API too */
4272 JANUS_VALIDATE_JSON_OBJECT(root, hold_parameters,
4273 error_code, error_cause, TRUE,
4274 JANUS_SIP_ERROR_MISSING_ELEMENT, JANUS_SIP_ERROR_INVALID_ELEMENT);
4275 if(error_code != 0)
4276 goto error;
4277 json_t *hdir = json_object_get(root, "direction");
4278 if(hdir != NULL) {
4279 const char *dir = json_string_value(hdir);
4280 hold_dir = janus_sdp_parse_mdirection(dir);
4281 if(hold_dir != JANUS_SDP_SENDONLY && hold_dir != JANUS_SDP_RECVONLY &&
4282 hold_dir != JANUS_SDP_INACTIVE) {
4283 /* Invalid direction */
4284 JANUS_LOG(LOG_ERR, "Invalid direction (can only be sendonly, recvonly or inactive)\n");
4285 error_code = JANUS_SIP_ERROR_INVALID_ELEMENT;
4286 g_snprintf(error_cause, 512, "Invalid direction (can only be sendonly, recvonly or inactive)");
4287 goto error;
4288 }
4289 }
4290 }
4291 session->media.on_hold = hold;
4292 janus_sdp_mline *m = janus_sdp_mline_find(session->sdp, JANUS_SDP_AUDIO);
4293 if(m) {
4294 if(hold) {
4295 /* Take note of the original media direction */
4296 session->media.pre_hold_audio_dir = m->direction;
4297 if(m->direction != hold_dir) {
4298 /* Update the media direction */
4299 switch(m->direction) {
4300 case JANUS_SDP_DEFAULT:
4301 case JANUS_SDP_SENDRECV:
4302 m->direction = hold_dir;
4303 break;
4304 default:
4305 m->direction = JANUS_SDP_INACTIVE;
4306 break;
4307 }
4308 }
4309 } else {
4310 m->direction = session->media.pre_hold_audio_dir;
4311 }
4312 }
4313 m = janus_sdp_mline_find(session->sdp, JANUS_SDP_VIDEO);
4314 if(m) {
4315 if(hold) {
4316 /* Take note of the original media direction */
4317 session->media.pre_hold_video_dir = m->direction;
4318 if(m->direction != hold_dir) {
4319 /* Update the media direction */
4320 switch(m->direction) {
4321 case JANUS_SDP_DEFAULT:
4322 case JANUS_SDP_SENDRECV:
4323 m->direction = hold_dir;
4324 break;
4325 default:
4326 m->direction = JANUS_SDP_INACTIVE;
4327 break;
4328 }
4329 }
4330 } else {
4331 m->direction = session->media.pre_hold_video_dir;
4332 }
4333 }
4334 /* Check if the INVITE needs to be enriched with custom headers */
4335 char custom_headers[2048];
4336 janus_sip_parse_custom_headers(root, (char *)&custom_headers, sizeof(custom_headers));
4337
4338 /* Send the re-INVITE */
4339 char *sdp = janus_sdp_write(session->sdp);
4340 nua_invite(session->stack->s_nh_i,
4341 SOATAG_USER_SDP_STR(sdp),
4342 TAG_IF(strlen(custom_headers) > 0, SIPTAG_HEADER_STR(custom_headers)),
4343 TAG_END());
4344 g_free(sdp);
4345 }
4346 /* Send an ack back */
4347 result = json_object();
4348 json_object_set_new(result, "event", json_string(hold ? "holding" : "resuming"));
4349 } else if(!strcasecmp(request_text, "hangup")) {
4350 /* Hangup an ongoing call */
4351 if(!janus_sip_call_is_established(session) && session->status != janus_sip_call_status_inviting) {
4352 JANUS_LOG(LOG_ERR, "Wrong state (not established/inviting? status=%s)\n",
4353 janus_sip_call_status_string(session->status));
4354 /* Ignore */
4355 janus_sip_message_free(msg);
4356 continue;
4357 }
4358 janus_mutex_lock(&session->mutex);
4359 if(session->callee == NULL) {
4360 janus_mutex_unlock(&session->mutex);
4361 JANUS_LOG(LOG_ERR, "Wrong state (no callee?)\n");
4362 error_code = JANUS_SIP_ERROR_WRONG_STATE;
4363 g_snprintf(error_cause, 512, "Wrong state (no callee?)");
4364 goto error;
4365 }
4366 janus_mutex_unlock(&session->mutex);
4367 session->media.earlymedia = FALSE;
4368 session->media.update = FALSE;
4369 session->media.autoaccept_reinvites = TRUE;
4370 session->media.ready = FALSE;
4371 session->media.on_hold = FALSE;
4372 janus_sip_call_update_status(session, janus_sip_call_status_closing);
4373 char custom_headers[2048];
4374 janus_sip_parse_custom_headers(root, (char *)&custom_headers, sizeof(custom_headers));
4375 nua_bye(session->stack->s_nh_i,
4376 TAG_IF(strlen(custom_headers) > 0, SIPTAG_HEADER_STR(custom_headers)),
4377 TAG_END());
4378 janus_mutex_lock(&session->mutex);
4379 g_free(session->callee);
4380 session->callee = NULL;
4381 janus_mutex_unlock(&session->mutex);
4382 /* Notify the operation */
4383 result = json_object();
4384 json_object_set_new(result, "event", json_string("hangingup"));
4385 } else if(!strcasecmp(request_text, "recording")) {
4386 /* Start or stop recording */
4387 if(!(session->status == janus_sip_call_status_inviting || /* Presume it makes sense to start recording with early media? */
4388 janus_sip_call_is_established(session))) {
4389 JANUS_LOG(LOG_ERR, "Wrong state (not in a call? status=%s)\n", janus_sip_call_status_string(session->status));
4390 g_snprintf(error_cause, 512, "Wrong state (not in a call?)");
4391 goto error;
4392 }
4393 janus_mutex_lock(&session->mutex);
4394 if(session->callee == NULL) {
4395 janus_mutex_unlock(&session->mutex);
4396 JANUS_LOG(LOG_ERR, "Wrong state (no callee?)\n");
4397 error_code = JANUS_SIP_ERROR_WRONG_STATE;
4398 g_snprintf(error_cause, 512, "Wrong state (no callee?)");
4399 goto error;
4400 }
4401 janus_mutex_unlock(&session->mutex);
4402 JANUS_VALIDATE_JSON_OBJECT(root, recording_parameters,
4403 error_code, error_cause, TRUE,
4404 JANUS_SIP_ERROR_MISSING_ELEMENT, JANUS_SIP_ERROR_INVALID_ELEMENT);
4405 if(error_code != 0)
4406 goto error;
4407 json_t *action = json_object_get(root, "action");
4408 const char *action_text = json_string_value(action);
4409 if(strcasecmp(action_text, "start") && strcasecmp(action_text, "stop") &&
4410 strcasecmp(action_text, "pause") && strcasecmp(action_text, "resume")) {
4411 JANUS_LOG(LOG_ERR, "Invalid action (should be start|stop|pause|resume)\n");
4412 error_code = JANUS_SIP_ERROR_INVALID_ELEMENT;
4413 g_snprintf(error_cause, 512, "Invalid action (should be start|stop|pause|resume)");
4414 goto error;
4415 }
4416 gboolean record_audio = FALSE, record_video = FALSE, /* No media is recorded by default */
4417 record_peer_audio = FALSE, record_peer_video = FALSE;
4418 json_t *audio = json_object_get(root, "audio");
4419 record_audio = audio ? json_is_true(audio) : FALSE;
4420 json_t *video = json_object_get(root, "video");
4421 record_video = video ? json_is_true(video) : FALSE;
4422 json_t *peer_audio = json_object_get(root, "peer_audio");
4423 record_peer_audio = peer_audio ? json_is_true(peer_audio) : FALSE;
4424 json_t *peer_video = json_object_get(root, "peer_video");
4425 record_peer_video = peer_video ? json_is_true(peer_video) : FALSE;
4426 if(!record_audio && !record_video && !record_peer_audio && !record_peer_video) {
4427 JANUS_LOG(LOG_ERR, "Invalid request (at least one of audio, video, peer_audio and peer_video should be true)\n");
4428 error_code = JANUS_SIP_ERROR_RECORDING_ERROR;
4429 g_snprintf(error_cause, 512, "Invalid request (at least one of audio, video, peer_audio and peer_video should be true)");
4430 goto error;
4431 }
4432 json_t *recfile = json_object_get(root, "filename");
4433 const char *recording_base = json_string_value(recfile);
4434 janus_mutex_lock(&session->rec_mutex);
4435 if(!strcasecmp(action_text, "start")) {
4436 /* Start recording something */
4437 char filename[255];
4438 gint64 now = janus_get_real_time();
4439 if(record_peer_audio || record_peer_video) {
4440 JANUS_LOG(LOG_INFO, "Starting recording of peer's %s (user %s, call %s)\n",
4441 (record_peer_audio && record_peer_video ? "audio and video" : (record_peer_audio ? "audio" : "video")),
4442 session->account.username, session->transaction);
4443 /* Start recording this peer's audio and/or video */
4444 if(record_peer_audio) {
4445 memset(filename, 0, 255);
4446 if(recording_base) {
4447 /* Use the filename and path we have been provided */
4448 g_snprintf(filename, 255, "%s-peer-audio", recording_base);
4449 /* FIXME This only works if offer/answer happened */
4450 session->arc_peer = janus_recorder_create(NULL, session->media.audio_pt_name, filename);
4451 if(session->arc_peer == NULL) {
4452 /* FIXME We should notify the fact the recorder could not be created */
4453 JANUS_LOG(LOG_ERR, "Couldn't open an audio recording file for this peer!\n");
4454 }
4455 } else {
4456 /* Build a filename */
4457 g_snprintf(filename, 255, "sip-%s-%s-%"SCNi64"-peer-audio",
4458 session->account.username ? session->account.username : "unknown",
4459 session->transaction ? session->transaction : "unknown",
4460 now);
4461 /* FIXME This only works if offer/answer happened */
4462 session->arc_peer = janus_recorder_create(NULL, session->media.audio_pt_name, filename);
4463 if(session->arc_peer == NULL) {
4464 /* FIXME We should notify the fact the recorder could not be created */
4465 JANUS_LOG(LOG_ERR, "Couldn't open an audio recording file for this peer!\n");
4466 }
4467 }
4468 }
4469 if(record_peer_video) {
4470 memset(filename, 0, 255);
4471 if(recording_base) {
4472 /* Use the filename and path we have been provided */
4473 g_snprintf(filename, 255, "%s-peer-video", recording_base);
4474 /* FIXME This only works if offer/answer happened */
4475 session->vrc_peer = janus_recorder_create(NULL, session->media.video_pt_name, filename);
4476 if(session->vrc_peer == NULL) {
4477 /* FIXME We should notify the fact the recorder could not be created */
4478 JANUS_LOG(LOG_ERR, "Couldn't open an video recording file for this peer!\n");
4479 }
4480 } else {
4481 /* Build a filename */
4482 g_snprintf(filename, 255, "sip-%s-%s-%"SCNi64"-peer-video",
4483 session->account.username ? session->account.username : "unknown",
4484 session->transaction ? session->transaction : "unknown",
4485 now);
4486 /* FIXME This only works if offer/answer happened */
4487 session->vrc_peer = janus_recorder_create(NULL, session->media.video_pt_name, filename);
4488 if(session->vrc_peer == NULL) {
4489 /* FIXME We should notify the fact the recorder could not be created */
4490 JANUS_LOG(LOG_ERR, "Couldn't open an video recording file for this peer!\n");
4491 }
4492 }
4493 /* TODO We should send a FIR/PLI to this peer... */
4494 }
4495 }
4496 if(record_audio || record_video) {
4497 /* Start recording the user's audio and/or video */
4498 JANUS_LOG(LOG_INFO, "Starting recording of user's %s (user %s, call %s)\n",
4499 (record_audio && record_video ? "audio and video" : (record_audio ? "audio" : "video")),
4500 session->account.username, session->transaction);
4501 if(record_audio) {
4502 memset(filename, 0, 255);
4503 if(recording_base) {
4504 /* Use the filename and path we have been provided */
4505 g_snprintf(filename, 255, "%s-user-audio", recording_base);
4506 /* FIXME This only works if offer/answer happened */
4507 session->arc = janus_recorder_create(NULL, session->media.audio_pt_name, filename);
4508 if(session->arc == NULL) {
4509 /* FIXME We should notify the fact the recorder could not be created */
4510 JANUS_LOG(LOG_ERR, "Couldn't open an audio recording file for this peer!\n");
4511 }
4512 } else {
4513 /* Build a filename */
4514 g_snprintf(filename, 255, "sip-%s-%s-%"SCNi64"-own-audio",
4515 session->account.username ? session->account.username : "unknown",
4516 session->transaction ? session->transaction : "unknown",
4517 now);
4518 /* FIXME This only works if offer/answer happened */
4519 session->arc = janus_recorder_create(NULL, session->media.audio_pt_name, filename);
4520 if(session->arc == NULL) {
4521 /* FIXME We should notify the fact the recorder could not be created */
4522 JANUS_LOG(LOG_ERR, "Couldn't open an audio recording file for this peer!\n");
4523 }
4524 }
4525 }
4526 if(record_video) {
4527 memset(filename, 0, 255);
4528 if(recording_base) {
4529 /* Use the filename and path we have been provided */
4530 g_snprintf(filename, 255, "%s-user-video", recording_base);
4531 /* FIXME This only works if offer/answer happened */
4532 session->vrc = janus_recorder_create(NULL, session->media.video_pt_name, filename);
4533 if(session->vrc == NULL) {
4534 /* FIXME We should notify the fact the recorder could not be created */
4535 JANUS_LOG(LOG_ERR, "Couldn't open an video recording file for this user!\n");
4536 }
4537 } else {
4538 /* Build a filename */
4539 g_snprintf(filename, 255, "sip-%s-%s-%"SCNi64"-own-video",
4540 session->account.username ? session->account.username : "unknown",
4541 session->transaction ? session->transaction : "unknown",
4542 now);
4543 /* FIXME This only works if offer/answer happened */
4544 session->vrc = janus_recorder_create(NULL, session->media.video_pt_name, filename);
4545 if(session->vrc == NULL) {
4546 /* FIXME We should notify the fact the recorder could not be created */
4547 JANUS_LOG(LOG_ERR, "Couldn't open an video recording file for this user!\n");
4548 }
4549 }
4550 /* Send a PLI */
4551 JANUS_LOG(LOG_VERB, "Recording video, sending a PLI to kickstart it\n");
4552 gateway->send_pli(session->handle);
4553 }
4554 }
4555 } else if(!strcasecmp(action_text, "pause")) {
4556 if(record_audio)
4557 janus_recorder_pause(session->arc);
4558 if(record_video)
4559 janus_recorder_pause(session->vrc);
4560 if(record_peer_audio)
4561 janus_recorder_pause(session->arc_peer);
4562 if(record_peer_video)
4563 janus_recorder_pause(session->vrc_peer);
4564 } else if(!strcasecmp(action_text, "resume")) {
4565 if(record_audio)
4566 janus_recorder_resume(session->arc);
4567 if(record_video && !janus_recorder_resume(session->vrc))
4568 gateway->send_pli(session->handle);
4569 if(record_peer_audio)
4570 janus_recorder_resume(session->arc_peer);
4571 if(record_peer_video)
4572 janus_recorder_resume(session->vrc_peer);
4573 } else {
4574 /* Stop recording something: notice that this never returns an error, even when we were not recording anything */
4575 janus_sip_recorder_close(session, record_audio, record_peer_audio, record_video, record_peer_video);
4576 }
4577 janus_mutex_unlock(&session->rec_mutex);
4578 /* Notify the result */
4579 result = json_object();
4580 json_object_set_new(result, "event", json_string("recordingupdated"));
4581 } else if(!strcasecmp(request_text, "info")) {
4582 /* Send a SIP INFO request: we'll need the payload type and content */
4583 if(!janus_sip_call_is_established(session)) {
4584 JANUS_LOG(LOG_ERR, "Wrong state (not established? status=%s)\n", janus_sip_call_status_string(session->status));
4585 g_snprintf(error_cause, 512, "Wrong state (not in a call?)");
4586 goto error;
4587 }
4588 janus_mutex_lock(&session->mutex);
4589 if(session->callee == NULL) {
4590 janus_mutex_unlock(&session->mutex);
4591 JANUS_LOG(LOG_ERR, "Wrong state (no callee?)\n");
4592 error_code = JANUS_SIP_ERROR_WRONG_STATE;
4593 g_snprintf(error_cause, 512, "Wrong state (no callee?)");
4594 goto error;
4595 }
4596 janus_mutex_unlock(&session->mutex);
4597 JANUS_VALIDATE_JSON_OBJECT(root, info_parameters,
4598 error_code, error_cause, TRUE,
4599 JANUS_SIP_ERROR_MISSING_ELEMENT, JANUS_SIP_ERROR_INVALID_ELEMENT);
4600 if(error_code != 0)
4601 goto error;
4602 const char *info_type = json_string_value(json_object_get(root, "type"));
4603 const char *info_content = json_string_value(json_object_get(root, "content"));
4604 char custom_headers[2048];
4605 janus_sip_parse_custom_headers(root, (char *)&custom_headers, sizeof(custom_headers));
4606 nua_info(session->stack->s_nh_i,
4607 SIPTAG_CONTENT_TYPE_STR(info_type),
4608 SIPTAG_PAYLOAD_STR(info_content),
4609 TAG_IF(strlen(custom_headers) > 0, SIPTAG_HEADER_STR(custom_headers)),
4610 TAG_END());
4611 /* Notify the operation */
4612 result = json_object();
4613 json_object_set_new(result, "event", json_string("infosent"));
4614 } else if(!strcasecmp(request_text, "message")) {
4615 /* Send a SIP MESSAGE request: we'll only need the content and optional payload type */
4616 JANUS_VALIDATE_JSON_OBJECT(root, sipmessage_parameters,
4617 error_code, error_cause, TRUE,
4618 JANUS_SIP_ERROR_MISSING_ELEMENT, JANUS_SIP_ERROR_INVALID_ELEMENT);
4619 if(error_code != 0) {
4620 goto error;
4621 }
4622 gboolean in_dialog_message = TRUE;
4623 json_t *uri = json_object_get(root, "uri");
4624 const char *uri_text = json_string_value(uri);
4625 if(uri != NULL)
4626 in_dialog_message = FALSE;
4627
4628 if(in_dialog_message) {
4629 if(!(session->status == janus_sip_call_status_inviting || janus_sip_call_is_established(session))) {
4630 JANUS_LOG(LOG_ERR, "Wrong state (not established? status=%s)\n", janus_sip_call_status_string(session->status));
4631 g_snprintf(error_cause, 512, "Wrong state (not in a call?)");
4632 goto error;
4633 }
4634 janus_mutex_lock(&session->mutex);
4635 if(session->callee == NULL) {
4636 janus_mutex_unlock(&session->mutex);
4637 JANUS_LOG(LOG_ERR, "Wrong state (no callee?)\n");
4638 error_code = JANUS_SIP_ERROR_WRONG_STATE;
4639 g_snprintf(error_cause, 512, "Wrong state (no callee?)");
4640 goto error;
4641 }
4642 janus_mutex_unlock(&session->mutex);
4643 } else {
4644 if(session->account.registration_status != janus_sip_registration_status_registered &&
4645 session->account.registration_status != janus_sip_registration_status_disabled) {
4646 JANUS_LOG(LOG_ERR, "Wrong state (not registered)\n");
4647 error_code = JANUS_SIP_ERROR_WRONG_STATE;
4648 g_snprintf(error_cause, 512, "Wrong state (not registered)");
4649 goto error;
4650 }
4651 janus_sip_uri_t target_uri;
4652 if(janus_sip_parse_uri(&target_uri, uri_text) < 0) {
4653 JANUS_LOG(LOG_ERR, "Invalid user address %s\n", uri_text);
4654 error_code = JANUS_SIP_ERROR_INVALID_ADDRESS;
4655 g_snprintf(error_cause, 512, "Invalid user address %s\n", uri_text);
4656 goto error;
4657 }
4658 }
4659
4660 const char *content_type = "text/plain";
4661 json_t *content_type_text = json_object_get(root, "content_type");
4662 if(content_type_text && json_is_string(content_type_text))
4663 content_type = json_string_value(content_type_text);
4664
4665 const char *msg_content = json_string_value(json_object_get(root, "content"));
4666 char custom_headers[2048];
4667 janus_sip_parse_custom_headers(root, (char *)&custom_headers, sizeof(custom_headers));
4668
4669 char *message_callid = NULL;
4670 if(in_dialog_message) {
4671 /* Take Call-ID, later used to report delivery status */
4672 message_callid = g_strdup(session->callid) ;
4673 nua_message(session->stack->s_nh_i,
4674 SIPTAG_CONTENT_TYPE_STR(content_type),
4675 SIPTAG_PAYLOAD_STR(msg_content),
4676 TAG_IF(strlen(custom_headers) > 0, SIPTAG_HEADER_STR(custom_headers)),
4677 TAG_END());
4678 } else {
4679 /* Get appropriate handle */
4680 nua_handle_t *nh = NULL;
4681 if(!session->helper) {
4682 janus_mutex_lock(&session->stack->smutex);
4683 if(session->stack->s_nua == NULL) {
4684 janus_mutex_unlock(&session->stack->smutex);
4685 JANUS_LOG(LOG_ERR, "NUA destroyed while sending message?\n");
4686 error_code = JANUS_SIP_ERROR_LIBSOFIA_ERROR;
4687 g_snprintf(error_cause, 512, "Invalid NUA");
4688 goto error;
4689 }
4690 nh = nua_handle(session->stack->s_nua, session, TAG_END());
4691 janus_mutex_unlock(&session->stack->smutex);
4692 } else {
4693 /* This is a helper, we need to use the master's SIP stack */
4694 if(session->master == NULL || session->master->stack == NULL) {
4695 error_code = JANUS_SIP_ERROR_HELPER_ERROR;
4696 g_snprintf(error_cause, 512, "Invalid master SIP stack");
4697 goto error;
4698 }
4699 janus_mutex_lock(&session->master->stack->smutex);
4700 if(session->master->stack->s_nua == NULL) {
4701 janus_mutex_unlock(&session->master->stack->smutex);
4702 JANUS_LOG(LOG_ERR, "NUA destroyed while sending message?\n");
4703 error_code = JANUS_SIP_ERROR_LIBSOFIA_ERROR;
4704 g_snprintf(error_cause, 512, "Invalid NUA");
4705 goto error;
4706 }
4707 nh = nua_handle(session->master->stack->s_nua, session, TAG_END());
4708 janus_mutex_unlock(&session->master->stack->smutex);
4709 }
4710 json_t *request_callid = json_object_get(root, "call_id");
4711 /* Use call-id from the request, if it exists */
4712 if(request_callid) {
4713 message_callid = g_strdup(json_string_value(request_callid));
4714 } else {
4715 /* If call-id does not exist in request, create a random one */
4716 message_callid = g_malloc0(24);
4717 janus_sip_random_string(24, message_callid);
4718 }
4719 nua_message(nh,
4720 SIPTAG_TO_STR(uri_text),
4721 SIPTAG_CONTENT_TYPE_STR(content_type),
4722 SIPTAG_PAYLOAD_STR(msg_content),
4723 NUTAG_PROXY(session->helper && session->master ?
4724 session->master->account.outbound_proxy : session->account.outbound_proxy),
4725 TAG_IF(strlen(custom_headers) > 0, SIPTAG_HEADER_STR(custom_headers)),
4726 SIPTAG_CALL_ID_STR(message_callid),
4727 TAG_END());
4728 }
4729 /* Notify the application */
4730 result = json_object();
4731 json_object_set_new(result, "event", json_string("messagesent"));
4732 json_object_set_new(result, "call_id", json_string(message_callid));
4733 /* Store message id and session */
4734 janus_mutex_lock(&sessions_mutex);
4735 janus_refcount_increase(&session->ref);
4736 g_hash_table_insert(messageids, g_strdup(message_callid), session);
4737 janus_mutex_unlock(&sessions_mutex);
4738 g_free(message_callid);
4739 } else if(!strcasecmp(request_text, "dtmf_info")) {
4740 /* Send DMTF tones using SIP INFO
4741 * (https://tools.ietf.org/html/draft-kaplan-dispatch-info-dtmf-package-00)
4742 */
4743 if(!janus_sip_call_is_established(session)) {
4744 JANUS_LOG(LOG_ERR, "Wrong state (not established? status=%s)\n", janus_sip_call_status_string(session->status));
4745 g_snprintf(error_cause, 512, "Wrong state (not in a call?)");
4746 goto error;
4747 }
4748 janus_mutex_lock(&session->mutex);
4749 if(session->callee == NULL) {
4750 janus_mutex_unlock(&session->mutex);
4751 JANUS_LOG(LOG_ERR, "Wrong state (no callee?)\n");
4752 error_code = JANUS_SIP_ERROR_WRONG_STATE;
4753 g_snprintf(error_cause, 512, "Wrong state (no callee?)");
4754 goto error;
4755 }
4756 janus_mutex_unlock(&session->mutex);
4757 JANUS_VALIDATE_JSON_OBJECT(root, dtmf_info_parameters,
4758 error_code, error_cause, TRUE,
4759 JANUS_SIP_ERROR_MISSING_ELEMENT, JANUS_SIP_ERROR_INVALID_ELEMENT);
4760 if(error_code != 0)
4761 goto error;
4762 json_t *digit = json_object_get(root, "digit");
4763 const char *digit_text = json_string_value(digit);
4764 if(strlen(digit_text) != 1) {
4765 JANUS_LOG(LOG_ERR, "Invalid element (digit should be one character))\n");
4766 error_code = JANUS_SIP_ERROR_INVALID_ELEMENT;
4767 g_snprintf(error_cause, 512, "Invalid element (digit should be one character)");
4768 goto error;
4769 }
4770 int duration_ms = 0;
4771 json_t *duration = json_object_get(root, "duration");
4772 duration_ms = duration ? json_integer_value(duration) : 0;
4773 if(duration_ms <= 0 || duration_ms > 5000) {
4774 duration_ms = 160; /* default value */
4775 }
4776 char payload[64];
4777 g_snprintf(payload, sizeof(payload), "Signal=%s\r\nDuration=%d", digit_text, duration_ms);
4778 char custom_headers[2048];
4779 janus_sip_parse_custom_headers(root, (char *)&custom_headers, sizeof(custom_headers));
4780 nua_info(session->stack->s_nh_i,
4781 SIPTAG_CONTENT_TYPE_STR("application/dtmf-relay"),
4782 SIPTAG_PAYLOAD_STR(payload),
4783 TAG_IF(strlen(custom_headers) > 0, SIPTAG_HEADER_STR(custom_headers)),
4784 TAG_END());
4785 /* Notify the result */
4786 result = json_object();
4787 json_object_set_new(result, "event", json_string("dtmfsent"));
4788 } else {
4789 JANUS_LOG(LOG_ERR, "Unknown request (%s)\n", request_text);
4790 error_code = JANUS_SIP_ERROR_INVALID_REQUEST;
4791 g_snprintf(error_cause, 512, "Unknown request (%s)", request_text);
4792 goto error;
4793 }
4794
4795 done:
4796 {
4797 /* Prepare JSON event */
4798 json_t *event = json_object();
4799 json_object_set_new(event, "sip", json_string("event"));
4800 if(result != NULL)
4801 json_object_set_new(event, "result", result);
4802 json_object_set_new(event, "call_id", json_string(session->callid));
4803 int ret = gateway->push_event(msg->handle, &janus_sip_plugin, msg->transaction, event, NULL);
4804 JANUS_LOG(LOG_VERB, " >> Pushing event: %d (%s)\n", ret, janus_get_api_error(ret));
4805 json_decref(event);
4806 janus_sip_message_free(msg);
4807 continue;
4808 }
4809
4810 error:
4811 {
4812 /* Prepare JSON error event */
4813 json_t *event = json_object();
4814 json_object_set_new(event, "sip", json_string("event"));
4815 json_object_set_new(event, "error_code", json_integer(error_code));
4816 json_object_set_new(event, "error", json_string(error_cause));
4817 json_object_set_new(event, "call_id", json_string(session->callid));
4818 int ret = gateway->push_event(msg->handle, &janus_sip_plugin, msg->transaction, event, NULL);
4819 JANUS_LOG(LOG_VERB, " >> Pushing event: %d (%s)\n", ret, janus_get_api_error(ret));
4820 json_decref(event);
4821 janus_sip_message_free(msg);
4822 }
4823 }
4824 JANUS_LOG(LOG_VERB, "Leaving SIP handler thread\n");
4825 return NULL;
4826 }
4827
4828
4829 /* Sofia callbacks */
janus_sip_sofia_callback(nua_event_t event,int status,char const * phrase,nua_t * nua,nua_magic_t * magic,nua_handle_t * nh,nua_hmagic_t * hmagic,sip_t const * sip,tagi_t tags[])4830 void janus_sip_sofia_callback(nua_event_t event, int status, char const *phrase, nua_t *nua, nua_magic_t *magic, nua_handle_t *nh, nua_hmagic_t *hmagic, sip_t const *sip, tagi_t tags[])
4831 {
4832 janus_sip_session *session = (janus_sip_session *)(hmagic ? hmagic : magic);
4833 ssip_t *ssip = session->stack;
4834
4835 /* Notify event handlers about the content of the whole incoming SIP message, if any */
4836 if(notify_events && gateway->events_is_enabled() && ssip) {
4837 /* Print the incoming message */
4838 size_t msg_size = 0;
4839 msg_t *msg = nua_current_request(nua);
4840 if(msg) {
4841 char *msg_str = msg_as_string(ssip->s_home, msg, NULL, 0, &msg_size);
4842 json_t *info = json_object();
4843 json_object_set_new(info, "event", json_string("sip-in"));
4844 json_object_set_new(info, "sip", json_string(msg_str));
4845 gateway->notify_event(&janus_sip_plugin, session->handle, info);
4846 su_free(ssip->s_home, msg_str);
4847 }
4848 }
4849
4850 switch (event) {
4851 /* Status or Error Indications */
4852 case nua_i_active:
4853 JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
4854 break;
4855 case nua_i_error:
4856 JANUS_LOG(LOG_WARN, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
4857 break;
4858 case nua_i_fork:
4859 JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
4860 break;
4861 case nua_i_media_error:
4862 JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
4863 break;
4864 case nua_i_subscription:
4865 JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
4866 break;
4867 case nua_i_state:;
4868 tagi_t const *ti = tl_find(tags, nutag_callstate);
4869 enum nua_callstate callstate = ti ? ti->t_value : -1;
4870 JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s, call state [%s]\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??", nua_callstate_name(callstate));
4871 /* There are several call states, but we care about the terminated state in order to send the 'hangup' event
4872 * and the proceeding state in order to send the 'proceeding' event so the client can play a ringback tone for
4873 * the user since we don't send early media. (assuming this is the right session, of course).
4874 * http://sofia-sip.sourceforge.net/refdocs/nua/nua__tag_8h.html#a516dc237722dc8ca4f4aa3524b2b444b
4875 */
4876 if(callstate == nua_callstate_proceeding &&
4877 (session->stack->s_nh_i == nh || session->stack->s_nh_i == NULL)) {
4878 json_t *call = json_object();
4879 json_object_set_new(call, "sip", json_string("event"));
4880 json_t *calling = json_object();
4881 json_object_set_new(calling, "event", json_string("proceeding"));
4882 json_object_set_new(calling, "code", json_integer(status));
4883 json_object_set_new(call, "result", calling);
4884 json_object_set_new(call, "call_id", json_string(session->callid));
4885 int ret = gateway->push_event(session->handle, &janus_sip_plugin, session->transaction, call, NULL);
4886 JANUS_LOG(LOG_VERB, " >> Pushing event: %d (%s)\n", ret, janus_get_api_error(ret));
4887 json_decref(call);
4888 /* Also notify event handlers */
4889 if(notify_events && gateway->events_is_enabled()) {
4890 json_t *info = json_object();
4891 json_object_set_new(info, "event", json_string("proceeding"));
4892 if(session->callid)
4893 json_object_set_new(info, "call-id", json_string(session->callid));
4894 json_object_set_new(info, "code", json_integer(status));
4895 gateway->notify_event(&janus_sip_plugin, session->handle, info);
4896 }
4897 } else if(callstate == nua_callstate_terminated &&
4898 (session->stack->s_nh_i == nh || session->stack->s_nh_i == NULL)) {
4899 session->media.earlymedia = FALSE;
4900 session->media.update = FALSE;
4901 session->media.autoaccept_reinvites = TRUE;
4902 session->media.ready = FALSE;
4903 session->media.on_hold = FALSE;
4904 janus_sip_call_update_status(session, janus_sip_call_status_idle);
4905 session->stack->s_nh_i = NULL;
4906 json_t *call = json_object();
4907 json_object_set_new(call, "sip", json_string("event"));
4908 json_t *calling = json_object();
4909 json_object_set_new(calling, "event", json_string("hangup"));
4910 json_object_set_new(calling, "code", json_integer(status));
4911 json_object_set_new(calling, "reason", json_string(phrase ? phrase : ""));
4912 if(session->hangup_reason_header)
4913 json_object_set_new(calling, "reason_header", json_string(session->hangup_reason_header));
4914 json_object_set_new(call, "result", calling);
4915 json_object_set_new(call, "call_id", json_string(session->callid));
4916 int ret = gateway->push_event(session->handle, &janus_sip_plugin, session->transaction, call, NULL);
4917 JANUS_LOG(LOG_VERB, " >> Pushing event: %d (%s)\n", ret, janus_get_api_error(ret));
4918 json_decref(call);
4919 /* Also notify event handlers */
4920 if(notify_events && gateway->events_is_enabled()) {
4921 json_t *info = json_object();
4922 json_object_set_new(info, "event", json_string("hangup"));
4923 if(session->callid)
4924 json_object_set_new(info, "call-id", json_string(session->callid));
4925 json_object_set_new(info, "code", json_integer(status));
4926 if(phrase)
4927 json_object_set_new(info, "reason", json_string(phrase));
4928 if(session->hangup_reason_header)
4929 json_object_set_new(info, "reason_header", json_string(session->hangup_reason_header));
4930 gateway->notify_event(&janus_sip_plugin, session->handle, info);
4931 }
4932 /* Get rid of any PeerConnection that may have been set up */
4933 if(session->callid) {
4934 janus_mutex_lock(&sessions_mutex);
4935 g_hash_table_remove(callids, session->callid);
4936 janus_mutex_unlock(&sessions_mutex);
4937 }
4938 g_free(session->callid);
4939 session->callid = NULL;
4940 g_free(session->transaction);
4941 session->transaction = NULL;
4942 g_free(session->hangup_reason_header);
4943 session->hangup_reason_header = NULL;
4944 if(g_atomic_int_get(&session->establishing) || g_atomic_int_get(&session->established))
4945 gateway->close_pc(session->handle);
4946 } else if(session->stack->s_nh_i == nh && callstate == nua_callstate_calling && session->status == janus_sip_call_status_incall) {
4947 /* Have just sent re-INVITE */
4948 janus_sip_call_update_status(session, janus_sip_call_status_incall_reinviting);
4949 } else if(session->stack->s_nh_i == nh && callstate == nua_callstate_ready &&
4950 (session->status == janus_sip_call_status_incall_reinviting || session->status == janus_sip_call_status_incall_reinvited)) {
4951 /* Clear re-INVITE progress status */
4952 janus_sip_call_update_status(session, janus_sip_call_status_incall);
4953 }
4954 break;
4955 case nua_i_terminated: {
4956 JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
4957 /* We had a reference to this session for this call, get rid of it */
4958 janus_sip_unref_active_call(session);
4959 break;
4960 }
4961 /* SIP requests */
4962 case nua_i_ack: {
4963 JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
4964 /* We're only interested in this when there's been an offerless INVITE, as here's where we'd get our answer */
4965 if(sip->sip_payload && sip->sip_payload->pl_data) {
4966 JANUS_LOG(LOG_VERB, "This ACK contains a payload, probably as a result of an offerless INVITE: simulating 200 OK...\n");
4967 janus_sip_sofia_callback(nua_r_invite, 700, "ACK", nua, magic, nh, hmagic, sip, tags);
4968 }
4969 break;
4970 }
4971 case nua_i_outbound:
4972 JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
4973 break;
4974 case nua_i_bye: {
4975 JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
4976 if(sip->sip_reason && sip->sip_reason->re_text) {
4977 session->hangup_reason_header = g_strdup(sip->sip_reason->re_text);
4978 janus_sip_remove_quotes(session->hangup_reason_header);
4979 }
4980 break;
4981 }
4982 case nua_i_cancel: {
4983 JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
4984 if(sip->sip_reason && sip->sip_reason->re_text) {
4985 session->hangup_reason_header = g_strdup(sip->sip_reason->re_text);
4986 janus_sip_remove_quotes(session->hangup_reason_header);
4987 }
4988 break;
4989 }
4990 case nua_i_invite: {
4991 JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
4992 /* Add a reference for this call */
4993 janus_sip_ref_active_call(session);
4994 if(ssip == NULL) {
4995 JANUS_LOG(LOG_ERR, "\tInvalid SIP stack\n");
4996 nua_respond(nh, 500, sip_status_phrase(500), TAG_END());
4997 break;
4998 }
4999 if(sip->sip_from == NULL || sip->sip_from->a_url->url_user == NULL ||
5000 sip->sip_to == NULL || sip->sip_to->a_url->url_user == NULL) {
5001 JANUS_LOG(LOG_ERR, "\tInvalid request (missing From or To)\n");
5002 nua_respond(nh, 400, sip_status_phrase(400), TAG_END());
5003 break;
5004 }
5005 gboolean reinvite = FALSE, busy = FALSE;
5006 if(session->stack->s_nh_i == NULL) {
5007 if(g_atomic_int_get(&session->establishing) || g_atomic_int_get(&session->established) || session->relayer_thread != NULL) {
5008 /* Still busy establishing another call (or maybe still cleaning up the previous call) */
5009 busy = TRUE;
5010 }
5011 } else {
5012 if(session->stack->s_nh_i == nh) {
5013 /* re-INVITE, we'll check what changed later */
5014 reinvite = TRUE;
5015 JANUS_LOG(LOG_VERB, "Got a re-INVITE...\n");
5016 } else if(session->status >= janus_sip_call_status_inviting) {
5017 /* Busy with another call */
5018 busy = TRUE;
5019 }
5020 }
5021 if(busy) {
5022 /* This session is busy, any helper that can take it? */
5023 JANUS_LOG(LOG_VERB, "Busy... maybe a helper can help?\n");
5024 janus_sip_session *helper = NULL;
5025 janus_mutex_lock(&session->mutex);
5026 /* Find a free helper */
5027 GList *temp = session->helpers;
5028 while(temp != NULL) {
5029 helper = (janus_sip_session *)temp->data;
5030 if(helper->stack->s_nh_i == NULL && !g_atomic_int_get(&helper->establishing) &&
5031 !g_atomic_int_get(&helper->established) && helper->relayer_thread == NULL) {
5032 /* Found! */
5033 break;
5034 }
5035 JANUS_LOG(LOG_VERB, " -- Helper %p is busy too...\n", helper);
5036 helper = NULL;
5037 temp = temp->next;
5038 }
5039 janus_mutex_unlock(&session->mutex);
5040 if(helper != NULL) {
5041 /* Bind the call to the helper and handle it there */
5042 JANUS_LOG(LOG_VERB, "Passing INVITE to helper %p\n", helper);
5043 nua_handle_bind(nh, helper);
5044 /* This session won't need the reference anymore, the helper will */
5045 janus_sip_unref_active_call(session);
5046 janus_sip_sofia_callback(event, status, phrase, nua, magic, nh, helper, sip, tags);
5047 break;
5048 }
5049 JANUS_LOG(LOG_VERB, "\tAlready in a call (busy, status=%s)\n", janus_sip_call_status_string(session->status));
5050 nua_respond(nh, 486, sip_status_phrase(486), TAG_END());
5051 /* Notify the web app about the missed invite */
5052 json_t *missed = json_object();
5053 json_object_set_new(missed, "sip", json_string("event"));
5054 json_t *result = json_object();
5055 json_object_set_new(result, "event", json_string("missed_call"));
5056 char *caller_text = url_as_string(session->stack->s_home, sip->sip_from->a_url);
5057 json_object_set_new(result, "caller", json_string(caller_text));
5058 if(sip->sip_from->a_display) {
5059 json_object_set_new(result, "displayname", json_string(sip->sip_from->a_display));
5060 }
5061 char *callee_text = url_as_string(session->stack->s_home, sip->sip_to->a_url);
5062 json_object_set_new(result, "callee", json_string(callee_text));
5063 json_object_set_new(missed, "result", result);
5064 json_object_set_new(missed, "call_id", json_string(sip->sip_call_id->i_id));
5065 int ret = gateway->push_event(session->handle, &janus_sip_plugin, session->transaction, missed, NULL);
5066 JANUS_LOG(LOG_VERB, " >> Pushing event to peer: %d (%s)\n", ret, janus_get_api_error(ret));
5067 json_decref(missed);
5068 /* Also notify event handlers */
5069 if(notify_events && gateway->events_is_enabled()) {
5070 json_t *info = json_object();
5071 json_object_set_new(info, "event", json_string("missed_call"));
5072 json_object_set_new(info, "caller", json_string(caller_text));
5073 json_object_set_new(info, "callee", json_string(callee_text));
5074 gateway->notify_event(&janus_sip_plugin, session->handle, info);
5075 }
5076 su_free(session->stack->s_home, caller_text);
5077 su_free(session->stack->s_home, callee_text);
5078 break;
5079 }
5080 if(!reinvite) {
5081 g_atomic_int_set(&session->establishing, 1);
5082 } else {
5083 /* This is a re-INVITE, we have a reference already */
5084 janus_sip_unref_active_call(session);
5085 }
5086 /* Check if there's an SDP to process */
5087 janus_sdp *sdp = NULL;
5088 if(!sip->sip_payload) {
5089 JANUS_LOG(LOG_VERB,"Received offerless %s\n", reinvite ? "re-INVITE" : "INVITE");
5090 } else {
5091 char sdperror[100];
5092 sdp = janus_sdp_parse(sip->sip_payload->pl_data, sdperror, sizeof(sdperror));
5093 if(!sdp) {
5094 JANUS_LOG(LOG_ERR, "\tError parsing SDP! %s\n", sdperror);
5095 g_atomic_int_set(&session->establishing, 0);
5096 nua_respond(nh, 488, sip_status_phrase(488), TAG_END());
5097 break;
5098 }
5099 }
5100 if(!reinvite) {
5101 janus_mutex_lock(&session->mutex);
5102 /* New incoming call */
5103 g_free(session->callee);
5104 char *caller_text = url_as_string(session->stack->s_home, sip->sip_from->a_url);
5105 session->callee = g_strdup(caller_text);
5106 janus_mutex_unlock(&session->mutex);
5107 su_free(session->stack->s_home, caller_text);
5108 g_free(session->callid);
5109 session->callid = sip && sip->sip_call_id ? g_strdup(sip->sip_call_id->i_id) : NULL;
5110 if(session->callid) {
5111 janus_mutex_lock(&sessions_mutex);
5112 g_hash_table_insert(callids, session->callid, session);
5113 janus_mutex_unlock(&sessions_mutex);
5114 }
5115 janus_sip_call_update_status(session, janus_sip_call_status_invited);
5116 /* Clean up SRTP stuff from before first, in case it's still needed */
5117 janus_sip_srtp_cleanup(session);
5118 }
5119 /* Parse SDP */
5120 JANUS_LOG(LOG_VERB, "Someone is %s a call:\n%s",
5121 reinvite ? "updating" : "inviting us in",
5122 sip->sip_payload ? sip->sip_payload->pl_data : "(no SDP)");
5123 gboolean changed = FALSE;
5124 if(sdp) {
5125 janus_sip_sdp_process(session, sdp, FALSE, reinvite, &changed);
5126 /* Check if offer has neither audio nor video, fail with 488 */
5127 if(!session->media.has_audio && !session->media.has_video) {
5128 g_atomic_int_set(&session->establishing, 0);
5129 nua_respond(nh, 488, sip_status_phrase(488), TAG_END());
5130 janus_sdp_destroy(sdp);
5131 break;
5132 }
5133 /* Also fail with 488 if there's no remote IP addresses that can be used for RTP */
5134 if(!session->media.remote_audio_ip && !session->media.remote_video_ip) {
5135 g_atomic_int_set(&session->establishing, 0);
5136 nua_respond(nh, 488, sip_status_phrase(488), TAG_END());
5137 janus_sdp_destroy(sdp);
5138 break;
5139 }
5140 }
5141 if(reinvite && session->media.autoaccept_reinvites) {
5142 /* No need to involve the application: we reply ourselves */
5143 nua_respond(nh, 200, sip_status_phrase(200), TAG_END());
5144 janus_sdp_destroy(sdp);
5145 break;
5146 }
5147 /* Check if there's an isfocus feature parameter in the Contact header */
5148 gboolean is_focus = FALSE;
5149 if(sip->sip_contact && sip->sip_contact->m_params) {
5150 int i=0;
5151 for(i=0; sip->sip_contact->m_params[i]; i++) {
5152 if(!strcasecmp(sip->sip_contact->m_params[i], "isfocus")) {
5153 /* The peer is a conference bridge */
5154 is_focus = TRUE;
5155 break;
5156 }
5157 }
5158 }
5159 /* If this is a re-INVITE, take note of that */
5160 if(reinvite) {
5161 session->media.update = TRUE;
5162 /* Mark status as janus_sip_call_status_incall_reinvited only when handling reinvites ourselves*/
5163 janus_sip_call_update_status(session, janus_sip_call_status_incall_reinvited);
5164 }
5165
5166 /* Notify the application about the new incoming call or re-INVITE */
5167 json_t *jsep = NULL;
5168 if(sdp)
5169 jsep = json_pack("{ssss}", "type", "offer", "sdp", sip->sip_payload->pl_data);
5170 json_t *call = json_object();
5171 json_object_set_new(call, "sip", json_string("event"));
5172 json_t *calling = json_object();
5173 json_object_set_new(calling, "event", json_string(reinvite ? "updatingcall" : "incomingcall"));
5174 json_object_set_new(calling, "username", json_string(session->callee));
5175 if(session->callid)
5176 json_object_set_new(calling, "call_id", json_string(session->callid));
5177 if(sip->sip_from->a_display) {
5178 json_object_set_new(calling, "displayname", json_string(sip->sip_from->a_display));
5179 }
5180 char *callee_text = url_as_string(session->stack->s_home, sip->sip_to->a_url);
5181 json_object_set_new(calling, "callee", json_string(callee_text));
5182 if(session->incoming_header_prefixes) {
5183 json_t *headers = janus_sip_get_incoming_headers(sip, session);
5184 json_object_set_new(calling, "headers", headers);
5185 }
5186 char *referred_by = NULL;
5187 if(sip->sip_referred_by) {
5188 char *rby_text = sip_header_as_string(session->stack->s_home, (const sip_header_t *)sip->sip_referred_by);
5189 referred_by = g_strdup(rby_text);
5190 su_free(session->stack->s_home, rby_text);
5191 json_object_set_new(calling, "referred_by", json_string(referred_by));
5192 }
5193 if(sip->sip_replaces && sip->sip_replaces->rp_call_id) {
5194 json_object_set_new(calling, "replaces", json_string(sip->sip_replaces->rp_call_id));
5195 }
5196 if(is_focus)
5197 json_object_set_new(calling, "isfocus", json_true());
5198 if(sdp && (session->media.has_srtp_remote_audio || session->media.has_srtp_remote_video)) {
5199 /* FIXME Maybe a true/false instead? */
5200 json_object_set_new(calling, "srtp", json_string(session->media.require_srtp ? "sdes_mandatory" : "sdes_optional"));
5201 }
5202 json_object_set_new(call, "result", calling);
5203 json_object_set_new(call, "call_id", json_string(session->callid));
5204 int ret = gateway->push_event(session->handle, &janus_sip_plugin, session->transaction, call, jsep);
5205 JANUS_LOG(LOG_VERB, " >> Pushing event to peer: %d (%s)\n", ret, janus_get_api_error(ret));
5206 json_decref(call);
5207 if(jsep)
5208 json_decref(jsep);
5209 janus_sdp_destroy(sdp);
5210 /* Also notify event handlers */
5211 if(notify_events && gateway->events_is_enabled()) {
5212 json_t *info = json_object();
5213 json_object_set_new(info, "event", json_string(reinvite ? "updatingcall" : "incomingcall"));
5214 if(session->callid)
5215 json_object_set_new(info, "call-id", json_string(session->callid));
5216 json_object_set_new(info, "username", json_string(session->callee));
5217 if(sip->sip_from->a_display)
5218 json_object_set_new(info, "displayname", json_string(sip->sip_from->a_display));
5219 json_object_set_new(info, "callee", json_string(callee_text));
5220 if(referred_by)
5221 json_object_set_new(info, "referred_by", json_string(referred_by));
5222 gateway->notify_event(&janus_sip_plugin, session->handle, info);
5223 }
5224 g_free(referred_by);
5225 if(!reinvite) {
5226 /* Send a Ringing back */
5227 nua_respond(nh, 180, sip_status_phrase(180), TAG_END());
5228 session->stack->s_nh_i = nh;
5229 }
5230 break;
5231 }
5232 case nua_i_refer: {
5233 JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
5234 /* We're being asked to transfer a call */
5235 if(sip == NULL || sip->sip_refer_to == NULL) {
5236 JANUS_LOG(LOG_ERR, "Missing Refer-To header\n");
5237 nua_respond(nh, 400, sip_status_phrase(400), TAG_END());
5238 break;
5239 }
5240 /* Access the headers we need */
5241 char *refer_to = NULL, *referred_by = NULL, *custom_headers = NULL, *replaces = NULL;
5242 const char *url_headers = sip->sip_refer_to->r_url->url_headers;
5243 if(url_headers != NULL) {
5244 /* Convert to SIP headers */
5245 sip->sip_refer_to->r_url->url_headers = NULL;
5246 custom_headers = url_query_as_header_string(session->stack->s_home, url_headers);
5247 /* FIXME Look for the "replaces" part, to extract the call-id */
5248 char *start = strstr(custom_headers, "replaces:");
5249 if(start != NULL) {
5250 start += strlen("replaces:");
5251 char *end = strchr(start, ';');
5252 if(end != NULL) {
5253 /* Found */
5254 *end = '\0';
5255 replaces = g_strdup(start);
5256 *end = ';';
5257 }
5258 }
5259 }
5260 refer_to = url_as_string(session->stack->s_home, sip->sip_refer_to->r_url);
5261 sip->sip_refer_to->r_url->url_headers = url_headers;
5262 if(sip->sip_referred_by != NULL)
5263 referred_by = sip_header_as_string(session->stack->s_home, (const sip_header_t *)sip->sip_referred_by);
5264 else if(sip->sip_from != NULL)
5265 referred_by = url_as_string(session->stack->s_home, sip->sip_from->a_url);
5266 JANUS_LOG(LOG_VERB, "Incoming REFER: %s (by %s, headers: %s)\n",
5267 refer_to, referred_by ? referred_by : "unknown", custom_headers ? custom_headers : "unknown");
5268 /* Send a 202 back */
5269 nua_respond(nh, 202, sip_status_phrase(202), NUTAG_WITH_CURRENT(nua), TAG_END());
5270 JANUS_LOG(LOG_VERB, "[%p] 202\n", nh);
5271 /* Take note of the session and NUA handle we got the REFER from (for NOTIFY) */
5272 janus_mutex_lock(&sessions_mutex);
5273 guint32 refer_id = 0;
5274 while(refer_id == 0) {
5275 refer_id = janus_random_uint32();
5276 if(g_hash_table_lookup(transfers, GUINT_TO_POINTER(refer_id)) != NULL) {
5277 refer_id = 0;
5278 continue;
5279 }
5280 janus_sip_transfer *t = g_malloc(sizeof(janus_sip_transfer));
5281 janus_refcount_increase(&session->ref);
5282 t->session = session;
5283 t->referred_by = referred_by ? g_strdup(referred_by) : NULL;
5284 t->custom_headers = custom_headers ? g_strdup(custom_headers) : NULL;
5285 t->nh_s = nh;
5286 nua_save_event(nua, t->saved);
5287 g_hash_table_insert(transfers, GUINT_TO_POINTER(refer_id), t);
5288 }
5289 janus_mutex_unlock(&sessions_mutex);
5290 /* Notify the application */
5291 json_t *info = json_object();
5292 json_object_set_new(info, "sip", json_string("event"));
5293 json_t *result = json_object();
5294 json_object_set_new(result, "event", json_string("transfer"));
5295 json_object_set_new(result, "refer_id", json_integer(refer_id));
5296 json_object_set_new(result, "refer_to", json_string(refer_to));
5297 if(referred_by != NULL) {
5298 json_object_set_new(result, "referred_by", json_string(referred_by));
5299 su_free(session->stack->s_home, referred_by);
5300 }
5301 if(replaces != NULL) {
5302 json_object_set_new(result, "replaces", json_string(replaces));
5303 g_free(replaces);
5304 }
5305 if(session->incoming_header_prefixes) {
5306 json_t *headers = janus_sip_get_incoming_headers(sip, session);
5307 json_object_set_new(result, "headers", headers);
5308 }
5309 su_free(session->stack->s_home, refer_to);
5310 if(custom_headers != NULL)
5311 su_free(session->stack->s_home, custom_headers);
5312 json_object_set_new(info, "result", result);
5313 int ret = gateway->push_event(session->handle, &janus_sip_plugin, session->transaction, info, NULL);
5314 JANUS_LOG(LOG_VERB, " >> Pushing event to peer: %d (%s)\n", ret, janus_get_api_error(ret));
5315 json_decref(info);
5316 break;
5317 }
5318 case nua_i_info: {
5319 JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
5320 /* We expect a payload */
5321 if(!sip->sip_content_type || !sip->sip_content_type->c_type || !sip->sip_payload || !sip->sip_payload->pl_data) {
5322 return;
5323 }
5324 const char *type = sip->sip_content_type->c_type;
5325 char *payload = sip->sip_payload->pl_data;
5326 /* Notify the application */
5327 json_t *info = json_object();
5328 json_object_set_new(info, "sip", json_string("event"));
5329 json_t *result = json_object();
5330 json_object_set_new(result, "event", json_string("info"));
5331 char *caller_text = url_as_string(session->stack->s_home, sip->sip_from->a_url);
5332 json_object_set_new(result, "sender", json_string(caller_text));
5333 su_free(session->stack->s_home, caller_text);
5334 if(sip->sip_from && sip->sip_from->a_display && strlen(sip->sip_from->a_display) > 0) {
5335 json_object_set_new(result, "displayname", json_string(sip->sip_from->a_display));
5336 }
5337 json_object_set_new(result, "type", json_string(type));
5338 json_object_set_new(result, "content", json_string(payload));
5339 if(session->incoming_header_prefixes) {
5340 json_t *headers = janus_sip_get_incoming_headers(sip, session);
5341 json_object_set_new(result, "headers", headers);
5342 }
5343 if(session->callid)
5344 json_object_set_new(info, "call_id", json_string(session->callid));
5345 json_object_set_new(info, "result", result);
5346 int ret = gateway->push_event(session->handle, &janus_sip_plugin, session->transaction, info, NULL);
5347 JANUS_LOG(LOG_VERB, " >> Pushing event to peer: %d (%s)\n", ret, janus_get_api_error(ret));
5348 json_decref(info);
5349 break;
5350 }
5351 case nua_i_message: {
5352 JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
5353 /* We expect a payload */
5354 if(!sip->sip_content_type || !sip->sip_content_type->c_type || !sip->sip_payload || !sip->sip_payload->pl_data) {
5355 return;
5356 }
5357 const char *content_type = sip->sip_content_type->c_type;
5358 char *payload = sip->sip_payload->pl_data;
5359 /* Notify the application */
5360 json_t *message = json_object();
5361 json_object_set_new(message, "sip", json_string("event"));
5362 json_t *result = json_object();
5363 json_object_set_new(result, "event", json_string("message"));
5364 char *caller_text = url_as_string(session->stack->s_home, sip->sip_from->a_url);
5365 json_object_set_new(result, "sender", json_string(caller_text));
5366 su_free(session->stack->s_home, caller_text);
5367 if(sip->sip_from && sip->sip_from->a_display && strlen(sip->sip_from->a_display) > 0) {
5368 json_object_set_new(result, "displayname", json_string(sip->sip_from->a_display));
5369 }
5370 json_object_set_new(result, "content", json_string(payload));
5371 if(session->incoming_header_prefixes) {
5372 json_t *headers = janus_sip_get_incoming_headers(sip, session);
5373 json_object_set_new(result, "headers", headers);
5374 }
5375 if(session->callid)
5376 json_object_set_new(message, "call_id", json_string(session->callid));
5377 json_object_set_new(result, "content_type", json_string(content_type));
5378 json_object_set_new(message, "result", result);
5379 int ret = gateway->push_event(session->handle, &janus_sip_plugin, session->transaction, message, NULL);
5380 JANUS_LOG(LOG_VERB, " >> Pushing event to peer: %d (%s)\n", ret, janus_get_api_error(ret));
5381 json_decref(message);
5382 break;
5383 }
5384 case nua_i_notify: {
5385 JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
5386 /* We expect a payload */
5387 if(!sip) {
5388 /* No SIP message? Maybe an internal message? */
5389 return;
5390 }
5391 if(!sip->sip_payload || !sip->sip_payload->pl_data) {
5392 /* Send a 200 back and ignore the message */
5393 nua_respond(nh, 200, sip_status_phrase(200), TAG_END());
5394 return;
5395 }
5396 /* Notify the application */
5397 json_t *notify = json_object();
5398 json_object_set_new(notify, "sip", json_string("event"));
5399 json_object_set_new(notify, "call_id", json_string(sip->sip_call_id->i_id));
5400 json_t *result = json_object();
5401 json_object_set_new(result, "event", json_string("notify"));
5402 if(sip->sip_event != NULL)
5403 json_object_set_new(result, "notify", json_string(sip->sip_event->o_type));
5404 const tagi_t *t = tl_find(tags, nutag_substate);
5405 if(t != NULL) {
5406 enum nua_substate substate = (enum nua_substate)(t->t_value);
5407 json_object_set_new(result, "substate", json_string(nua_substate_name(substate)));
5408 }
5409 if(sip->sip_content_type != NULL)
5410 json_object_set_new(result, "content-type", json_string(sip->sip_content_type->c_type));
5411 json_object_set_new(result, "content", json_string(sip->sip_payload->pl_data));
5412 if(session->incoming_header_prefixes) {
5413 json_t *headers = janus_sip_get_incoming_headers(sip, session);
5414 json_object_set_new(result, "headers", headers);
5415 }
5416 json_object_set_new(notify, "result", result);
5417 int ret = gateway->push_event(session->handle, &janus_sip_plugin, session->transaction, notify, NULL);
5418 JANUS_LOG(LOG_VERB, " >> Pushing event to peer: %d (%s)\n", ret, janus_get_api_error(ret));
5419 json_decref(notify);
5420 break;
5421 }
5422 case nua_i_options:
5423 JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
5424 /* Stack responds automatically to OPTIONS request unless OPTIONS is
5425 * included in the set of application methods, set by NUTAG_APPL_METHOD(). */
5426 break;
5427 /* Responses */
5428 case nua_r_get_params:
5429 JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
5430 const tagi_t* from = NULL;
5431 if((status != 200) || ((from = tl_find(tags, siptag_from_str)) == NULL)) {
5432 JANUS_LOG(LOG_WARN, "Unable to find 'siptag_from_str' among all the tags\n");
5433 break;
5434 }
5435 const char *from_value = (const char *)from->t_value;
5436 if(from_value == NULL || strlen(from_value) < 2) {
5437 JANUS_LOG(LOG_WARN, "Invalid 'siptag_from_str' value '%s'\n", from_value);
5438 break;
5439 }
5440 JANUS_LOG(LOG_VERB, "'siptag_from_str': %s\n", from_value);
5441 g_free(ssip->contact_header);
5442 ssip->contact_header = g_strdup(from_value);
5443 break;
5444 case nua_r_set_params:
5445 JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
5446 break;
5447 case nua_r_notifier:
5448 JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
5449 break;
5450 case nua_r_shutdown:
5451 JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
5452 if(status < 200 && !g_atomic_int_get(&stopping)) {
5453 /* shutdown in progress -> return */
5454 break;
5455 }
5456 if(status >= 200 && ssip != NULL) {
5457 /* Check if this session (and/or its helpers) had dangling
5458 * references for ongoing calls: we won't receive other events
5459 * after this, so it's up to us to clean up after ourselfes */
5460 janus_mutex_lock(&session->mutex);
5461 while(session->active_calls) {
5462 janus_sip_session *s = (janus_sip_session *)session->active_calls->data;
5463 if(s != NULL) {
5464 JANUS_LOG(LOG_VERB, "[%p] Removing reference\n", s);
5465 janus_refcount_decrease(&s->ref);
5466 }
5467 session->active_calls = g_list_remove(session->active_calls, s);
5468 }
5469 janus_mutex_unlock(&session->mutex);
5470 /* End the event loop: su_root_run() will return */
5471 su_root_break(ssip->s_root);
5472 }
5473 break;
5474 case nua_r_terminate:
5475 JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
5476 break;
5477 /* SIP responses */
5478 case nua_r_bye:
5479 JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
5480 break;
5481 case nua_r_cancel:
5482 JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
5483 break;
5484 case nua_r_info:
5485 JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
5486 /* FIXME Should we notify the user, in case the SIP INFO returned an error? */
5487 break;
5488 case nua_r_message:
5489 JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
5490 /* Handle authetntication for SIP MESSAGE - eg. SippySoft Softswitch requires 401 authentication even if SIP user is registerered */
5491 if(status == 401 || status == 407) {
5492 const char *scheme = NULL;
5493 const char *realm = NULL;
5494 if(status == 401) {
5495 /* Get scheme/realm from 401 error */
5496 sip_www_authenticate_t const* www_auth = sip->sip_www_authenticate;
5497 scheme = www_auth->au_scheme;
5498 realm = msg_params_find(www_auth->au_params, "realm=");
5499 } else {
5500 /* Get scheme/realm from 407 error, proxy-auth */
5501 sip_proxy_authenticate_t const* proxy_auth = sip->sip_proxy_authenticate;
5502 scheme = proxy_auth->au_scheme;
5503 realm = msg_params_find(proxy_auth->au_params, "realm=");
5504 }
5505 char authuser[100], secret[100];
5506 memset(authuser, 0, sizeof(authuser));
5507 memset(secret, 0, sizeof(secret));
5508 if(session->helper) {
5509 /* This is an helper session, we'll need the credentials from the master */
5510 if(session->master == NULL) {
5511 JANUS_LOG(LOG_WARN, "No master session for this helper, authentication will fail...\n");
5512 } else {
5513 session = session->master;
5514 }
5515 }
5516 if(session->account.authuser && strchr(session->account.authuser, ':')) {
5517 /* The authuser contains a colon: wrap it in quotes */
5518 g_snprintf(authuser, sizeof(authuser), "\"%s\"", session->account.authuser);
5519 } else {
5520 g_snprintf(authuser, sizeof(authuser), "%s", session->account.authuser);
5521 }
5522 if(session->account.secret && strchr(session->account.secret, ':')) {
5523 /* The secret contains a colon: wrap it in quotes */
5524 g_snprintf(secret, sizeof(secret), "\"%s\"", session->account.secret);
5525 } else {
5526 g_snprintf(secret, sizeof(secret), "%s", session->account.secret);
5527 }
5528 char auth[256];
5529 memset(auth, 0, sizeof(auth));
5530 g_snprintf(auth, sizeof(auth), "%s%s:%s:%s:%s%s",
5531 session->account.secret_type == janus_sip_secret_type_hashed ? "HA1+" : "",
5532 scheme,
5533 realm,
5534 authuser,
5535 session->account.secret_type == janus_sip_secret_type_hashed ? "HA1+" : "",
5536 secret);
5537 JANUS_LOG(LOG_VERB, "\t%s\n", auth);
5538 /* Authenticate */
5539 nua_authenticate(nh,
5540 NUTAG_AUTH(auth),
5541 TAG_END());
5542 } else {
5543 char *messageid = g_strdup(sip->sip_call_id->i_id);
5544 /* Find session associated with the message */
5545 janus_mutex_lock(&sessions_mutex);
5546 janus_sip_session *message_session = g_hash_table_lookup(messageids, messageid);
5547 if (!message_session) {
5548 message_session = session;
5549 JANUS_LOG(LOG_VERB, "Message (%s) not associated with any session, event will be reported to master\n", messageid);
5550 }
5551 janus_mutex_unlock(&sessions_mutex);
5552 /* MESSAGE response, notify the application */
5553 json_t *result = json_object();
5554 /* SIP code and reason */
5555 json_object_set_new(result, "event", json_string("messagedelivery"));
5556 json_object_set_new(result, "code", json_integer(status));
5557 json_object_set_new(result, "reason", json_string(phrase));
5558 /* Build the delivery receipt */
5559 json_t *dr = json_object();
5560 json_object_set_new(dr, "sip", json_string("event"));
5561 json_object_set_new(dr, "result", result);
5562 json_object_set_new(dr, "call_id", json_string(messageid));
5563 /* Report delivery */
5564 int ret = gateway->push_event(message_session->handle, &janus_sip_plugin, message_session->transaction, dr, NULL);
5565 JANUS_LOG(LOG_VERB, " >> Pushing event to peer: %d (%s)\n", ret, janus_get_api_error(ret));
5566 json_decref(dr);
5567 janus_mutex_lock(&sessions_mutex);
5568 g_hash_table_remove(messageids, messageid);
5569 janus_mutex_unlock(&sessions_mutex);
5570 g_free(messageid);
5571 }
5572 break;
5573 case nua_r_refer: {
5574 JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
5575 /* We got a response to our REFER */
5576 JANUS_LOG(LOG_VERB, "Response to REFER received\n");
5577 break;
5578 }
5579 case nua_r_invite: {
5580 JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
5581
5582 /* If this INVITE was triggered by a REFER, notify the transferer */
5583 if(session->refer_id > 0) {
5584 janus_mutex_lock(&sessions_mutex);
5585 janus_sip_transfer *transfer = g_hash_table_lookup(transfers, GUINT_TO_POINTER(session->refer_id));
5586 janus_mutex_unlock(&sessions_mutex);
5587 if(transfer != NULL && transfer->nh_s != NULL) {
5588 /* Send a NOTIFY */
5589 char content[100];
5590 g_snprintf(content, sizeof(content), "SIP/2.0 %d %s", status, phrase);
5591 nua_notify(transfer->nh_s,
5592 NUTAG_SUBSTATE(nua_substate_active),
5593 SIPTAG_CONTENT_TYPE_STR("message/sipfrag"),
5594 SIPTAG_PAYLOAD_STR(content),
5595 TAG_END());
5596 }
5597 }
5598
5599 gboolean in_progress = FALSE;
5600 if(status < 200) {
5601 /* Not ready yet, either notify the user (e.g., "ringing") or handle early media (if it's a 183) */
5602 if(status == 180) {
5603 /* Ringing, notify the application */
5604 json_t *ringing = json_object();
5605 json_object_set_new(ringing, "sip", json_string("event"));
5606 json_t *result = json_object();
5607 json_object_set_new(result, "event", json_string("ringing"));
5608 if(session->incoming_header_prefixes) {
5609 json_t *headers = janus_sip_get_incoming_headers(sip, session);
5610 json_object_set_new(result, "headers", headers);
5611 }
5612 json_object_set_new(ringing, "result", result);
5613 json_object_set_new(ringing, "call_id", json_string(session->callid));
5614 int ret = gateway->push_event(session->handle, &janus_sip_plugin, session->transaction, ringing, NULL);
5615 JANUS_LOG(LOG_VERB, " >> Pushing event to peer: %d (%s)\n", ret, janus_get_api_error(ret));
5616 json_decref(ringing);
5617 break;
5618 } else if(status == 183) {
5619 /* If's a Session Progress: check if there's an SDP, and if so, treat it like a 200 */
5620 if(!sip->sip_payload || !sip->sip_payload->pl_data)
5621 break;
5622 in_progress = TRUE;
5623 } else {
5624 /* Nothing to do, let's wait for a 200 OK */
5625 break;
5626 }
5627 } else if(status == 401 || status == 407) {
5628 const char *scheme = NULL;
5629 const char *realm = NULL;
5630 if(status == 401) {
5631 /* Get scheme/realm from 401 error */
5632 sip_www_authenticate_t const* www_auth = sip->sip_www_authenticate;
5633 scheme = www_auth->au_scheme;
5634 realm = msg_params_find(www_auth->au_params, "realm=");
5635 } else {
5636 /* Get scheme/realm from 407 error, proxy-auth */
5637 sip_proxy_authenticate_t const* proxy_auth = sip->sip_proxy_authenticate;
5638 scheme = proxy_auth->au_scheme;
5639 realm = msg_params_find(proxy_auth->au_params, "realm=");
5640 }
5641 char authuser[100], secret[100];
5642 memset(authuser, 0, sizeof(authuser));
5643 memset(secret, 0, sizeof(secret));
5644 if(session->helper) {
5645 /* This is an helper session, we'll need the credentials from the master */
5646 if(session->master == NULL) {
5647 JANUS_LOG(LOG_WARN, "No master session for this helper, authentication will fail...\n");
5648 } else {
5649 session = session->master;
5650 }
5651 }
5652 if(session->account.authuser && strchr(session->account.authuser, ':')) {
5653 /* The authuser contains a colon: wrap it in quotes */
5654 g_snprintf(authuser, sizeof(authuser), "\"%s\"", session->account.authuser);
5655 } else {
5656 g_snprintf(authuser, sizeof(authuser), "%s", session->account.authuser);
5657 }
5658 if(session->account.secret && strchr(session->account.secret, ':')) {
5659 /* The secret contains a colon: wrap it in quotes */
5660 g_snprintf(secret, sizeof(secret), "\"%s\"", session->account.secret);
5661 } else {
5662 g_snprintf(secret, sizeof(secret), "%s", session->account.secret);
5663 }
5664 char auth[256];
5665 memset(auth, 0, sizeof(auth));
5666 g_snprintf(auth, sizeof(auth), "%s%s:%s:%s:%s%s",
5667 session->account.secret_type == janus_sip_secret_type_hashed ? "HA1+" : "",
5668 scheme,
5669 realm,
5670 authuser,
5671 session->account.secret_type == janus_sip_secret_type_hashed ? "HA1+" : "",
5672 secret);
5673 JANUS_LOG(LOG_VERB, "\t%s\n", auth);
5674 /* Authenticate */
5675 nua_authenticate(nh,
5676 NUTAG_AUTH(auth),
5677 TAG_END());
5678 break;
5679 } else if(status == 700) {
5680 JANUS_LOG(LOG_VERB, "Handling SDP answer in ACK\n");
5681 } else if(status >= 400 && status != 700) {
5682 break;
5683 }
5684 if(ssip == NULL) {
5685 JANUS_LOG(LOG_ERR, "\tInvalid SIP stack\n");
5686 nua_respond(nh, 500, sip_status_phrase(500), TAG_END());
5687 break;
5688 }
5689 if(sip->sip_payload == NULL) {
5690 JANUS_LOG(LOG_ERR, "\tMissing SDP\n");
5691 nua_respond(nh, 488, sip_status_phrase(488), TAG_END());
5692 break;
5693 }
5694 char sdperror[100];
5695 janus_sdp *sdp = janus_sdp_parse(sip->sip_payload->pl_data, sdperror, sizeof(sdperror));
5696 if(!sdp) {
5697 JANUS_LOG(LOG_ERR, "\tError parsing SDP! %s\n", sdperror);
5698 nua_respond(nh, 488, sip_status_phrase(488), TAG_END());
5699 break;
5700 }
5701 /* Send an ACK, if needed */
5702 if(!in_progress) {
5703 char *route = NULL;
5704 sip_record_route_t *srr = sip->sip_record_route;
5705 if(srr != NULL) {
5706 while(srr->r_next != NULL)
5707 srr = srr->r_next;
5708 route = srr ? url_as_string(session->stack->s_home, srr->r_url) : NULL;
5709 }
5710 JANUS_LOG(LOG_VERB, "Sending ACK (route=%s)\n", route ? route : "none");
5711 nua_ack(nh,
5712 TAG_IF(route, NTATAG_DEFAULT_PROXY(route)),
5713 TAG_END());
5714 if(route != NULL)
5715 su_free(session->stack->s_home, route);
5716 }
5717 /* Parse SDP */
5718 JANUS_LOG(LOG_VERB, "Peer accepted our call:\n%s", sip->sip_payload->pl_data);
5719 janus_sip_call_update_status(session, janus_sip_call_status_incall);
5720 char *fixed_sdp = sip->sip_payload->pl_data;
5721 gboolean changed = FALSE;
5722 gboolean update = session->media.ready;
5723 janus_sip_sdp_process(session, sdp, TRUE, update, &changed);
5724 /* If we asked for SRTP and are not getting it, fail */
5725 gboolean has_srtp = TRUE;
5726 if(session->media.has_audio)
5727 has_srtp = (has_srtp && session->media.has_srtp_remote_audio);
5728 if(session->media.has_video)
5729 has_srtp = (has_srtp && session->media.has_srtp_remote_video);
5730 if(session->media.require_srtp && !has_srtp) {
5731 JANUS_LOG(LOG_ERR, "We asked for mandatory SRTP but didn't get any in the reply!\n");
5732 janus_sdp_destroy(sdp);
5733 /* Hangup immediately */
5734 session->media.earlymedia = FALSE;
5735 session->media.update = FALSE;
5736 session->media.autoaccept_reinvites = TRUE;
5737 session->media.ready = FALSE;
5738 session->media.on_hold = FALSE;
5739 janus_sip_call_update_status(session, janus_sip_call_status_closing);
5740 nua_bye(nh, TAG_END());
5741 janus_mutex_lock(&session->mutex);
5742 g_free(session->callee);
5743 session->callee = NULL;
5744 janus_mutex_unlock(&session->mutex);
5745 break;
5746 }
5747 if(!session->media.remote_audio_ip && !session->media.remote_video_ip) {
5748 /* No remote address parsed? Give up */
5749 JANUS_LOG(LOG_ERR, "\tNo remote IP address found for RTP, something's wrong with the SDP!\n");
5750 janus_sdp_destroy(sdp);
5751 /* Hangup immediately */
5752 session->media.earlymedia = FALSE;
5753 session->media.update = FALSE;
5754 session->media.autoaccept_reinvites = TRUE;
5755 session->media.ready = FALSE;
5756 session->media.on_hold = FALSE;
5757 janus_sip_call_update_status(session, janus_sip_call_status_closing);
5758 nua_bye(nh, TAG_END());
5759 janus_mutex_lock(&session->mutex);
5760 g_free(session->callee);
5761 session->callee = NULL;
5762 janus_mutex_unlock(&session->mutex);
5763 break;
5764 }
5765 if(session->media.audio_pt > -1) {
5766 session->media.audio_pt_name = janus_get_codec_from_pt(fixed_sdp, session->media.audio_pt);
5767 JANUS_LOG(LOG_VERB, "Detected audio codec: %d (%s)\n", session->media.audio_pt, session->media.audio_pt_name);
5768 }
5769 if(session->media.video_pt > -1) {
5770 session->media.video_pt_name = janus_get_codec_from_pt(fixed_sdp, session->media.video_pt);
5771 JANUS_LOG(LOG_VERB, "Detected video codec: %d (%s)\n", session->media.video_pt, session->media.video_pt_name);
5772 }
5773 session->media.ready = TRUE; /* FIXME Maybe we need a better way to signal this */
5774 if(update && !session->media.earlymedia && !session->media.update) {
5775 /* Don't push to the application if this is in response to a hold/unhold we sent ourselves */
5776 JANUS_LOG(LOG_VERB, "This is an update to an existing call (possibly in response to hold/unhold)\n");
5777 janus_sdp_destroy(sdp);
5778 break;
5779 }
5780 if(!session->media.earlymedia && !session->media.update) {
5781 GError *error = NULL;
5782 char tname[16];
5783 g_snprintf(tname, sizeof(tname), "siprtp %s", session->account.username);
5784 janus_refcount_increase(&session->ref);
5785 session->relayer_thread = g_thread_try_new(tname, janus_sip_relay_thread, session, &error);
5786 if(error != NULL) {
5787 session->relayer_thread = NULL;
5788 session->media.ready = FALSE;
5789 janus_refcount_decrease(&session->ref);
5790 JANUS_LOG(LOG_ERR, "Got error %d (%s) trying to launch the RTP/RTCP thread...\n",
5791 error->code, error->message ? error->message : "??");
5792 g_error_free(error);
5793 }
5794 }
5795 /* Check if there's an isfocus feature parameter in the Contact header */
5796 gboolean is_focus = FALSE;
5797 if(sip->sip_contact && sip->sip_contact->m_params) {
5798 int i=0;
5799 for(i=0; sip->sip_contact->m_params[i]; i++) {
5800 if(!strcasecmp(sip->sip_contact->m_params[i], "isfocus")) {
5801 /* The peer is a conference bridge */
5802 is_focus = TRUE;
5803 break;
5804 }
5805 }
5806 }
5807 /* Send event back to the application */
5808 json_t *jsep = NULL;
5809 if(!session->media.earlymedia) {
5810 jsep = json_pack("{ssss}", "type", "answer", "sdp", fixed_sdp);
5811 } else {
5812 /* We've received the 200 OK after the 183, we can remove the flag now */
5813 session->media.earlymedia = FALSE;
5814 }
5815 if(in_progress) {
5816 /* If we just received the 183, set the flag instead so that we can handle the 200 OK differently */
5817 session->media.earlymedia = TRUE;
5818 }
5819 json_t *call = json_object();
5820 json_object_set_new(call, "sip", json_string("event"));
5821 json_t *calling = json_object();
5822 json_object_set_new(calling, "event", json_string(in_progress ? "progress" : "accepted"));
5823 json_object_set_new(calling, "username", json_string(session->callee));
5824 if(is_focus)
5825 json_object_set_new(calling, "isfocus", json_true());
5826 if(session->incoming_header_prefixes) {
5827 json_t *headers = janus_sip_get_incoming_headers(sip, session);
5828 json_object_set_new(calling, "headers", headers);
5829 }
5830 json_object_set_new(call, "result", calling);
5831 json_object_set_new(call, "call_id", json_string(session->callid));
5832 int ret = gateway->push_event(session->handle, &janus_sip_plugin, session->transaction, call, jsep);
5833 JANUS_LOG(LOG_VERB, " >> Pushing event to peer: %d (%s)\n", ret, janus_get_api_error(ret));
5834 json_decref(call);
5835 json_decref(jsep);
5836 janus_sdp_destroy(sdp);
5837 /* Also notify event handlers */
5838 if(!session->media.update && notify_events && gateway->events_is_enabled()) {
5839 json_t *info = json_object();
5840 json_object_set_new(info, "event", json_string(in_progress ? "progress" : "accepted"));
5841 if(session->callid)
5842 json_object_set_new(info, "call-id", json_string(session->callid));
5843 json_object_set_new(info, "username", json_string(session->callee));
5844 gateway->notify_event(&janus_sip_plugin, session->handle, info);
5845 }
5846 if(session->media.update) {
5847 /* We just received a 200 OK to an update we sent */
5848 session->media.update = FALSE;
5849 }
5850 break;
5851 }
5852 case nua_r_register:
5853 case nua_r_unregister: {
5854 JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
5855 if(status == 200) {
5856 if(event == nua_r_register) {
5857 if(session->account.registration_status < janus_sip_registration_status_registered)
5858 session->account.registration_status = janus_sip_registration_status_registered;
5859 } else {
5860 session->account.registration_status = janus_sip_registration_status_unregistered;
5861 }
5862 const char *event_name = (event == nua_r_register ? "registered" : "unregistered");
5863 JANUS_LOG(LOG_VERB, "Successfully %s\n", event_name);
5864 /* Notify the application */
5865 json_t *reg = json_object();
5866 json_object_set_new(reg, "sip", json_string("event"));
5867 json_t *reging = json_object();
5868 json_object_set_new(reging, "event", json_string(event_name));
5869 json_object_set_new(reging, "username", json_string(session->account.username));
5870 if(event == nua_r_register) {
5871 json_object_set_new(reging, "register_sent", json_true());
5872 json_object_set_new(reging, "master_id", json_integer(session->master_id));
5873 }
5874 if(session->incoming_header_prefixes) {
5875 json_t *headers = janus_sip_get_incoming_headers(sip, session);
5876 json_object_set_new(reging, "headers", headers);
5877 }
5878 json_object_set_new(reg, "result", reging);
5879 int ret = gateway->push_event(session->handle, &janus_sip_plugin, session->transaction, reg, NULL);
5880 JANUS_LOG(LOG_VERB, " >> Pushing event to peer: %d (%s)\n", ret, janus_get_api_error(ret));
5881 json_decref(reg);
5882 /* If we unregistered and this session had helpers, get rid of them */
5883 if(event == nua_r_unregister) {
5884 janus_mutex_lock(&session->mutex);
5885 GList *temp = NULL;
5886 while(session->helpers != NULL) {
5887 temp = session->helpers;
5888 session->helpers = g_list_remove_link(session->helpers, temp);
5889 janus_sip_session *helper = (janus_sip_session *)temp->data;
5890 if(helper != NULL && helper->handle != NULL) {
5891 /* Get rid of this helper */
5892 janus_refcount_decrease(&session->ref);
5893 janus_refcount_decrease(&helper->ref);
5894 gateway->end_session(helper->handle);
5895 }
5896 g_list_free(temp);
5897 }
5898 janus_mutex_unlock(&session->mutex);
5899 }
5900 /* Also notify event handlers */
5901 if(notify_events && gateway->events_is_enabled()) {
5902 json_t *info = json_object();
5903 json_object_set_new(info, "event", json_string(event_name));
5904 json_object_set_new(info, "identity", json_string(session->account.identity));
5905 if(session->account.proxy)
5906 json_object_set_new(info, "proxy", json_string(session->account.proxy));
5907 gateway->notify_event(&janus_sip_plugin, session->handle, info);
5908 }
5909 } else if(status == 401 || status == 407) {
5910 const char *scheme = NULL;
5911 const char *realm = NULL;
5912 if(status == 401) {
5913 /* Get scheme/realm from 401 error */
5914 sip_www_authenticate_t const* www_auth = sip->sip_www_authenticate;
5915 if(www_auth == NULL) {
5916 /* No WWW-Authenticate header, give up */
5917 goto auth_failed;
5918 }
5919 scheme = www_auth->au_scheme;
5920 realm = msg_params_find(www_auth->au_params, "realm=");
5921 } else {
5922 /* Get scheme/realm from 407 error, proxy-auth */
5923 sip_proxy_authenticate_t const* proxy_auth = sip->sip_proxy_authenticate;
5924 if(proxy_auth == NULL) {
5925 /* No Proxy-Authenticate header, give up */
5926 goto auth_failed;
5927 }
5928 scheme = proxy_auth->au_scheme;
5929 realm = msg_params_find(proxy_auth->au_params, "realm=");
5930 }
5931 char authuser[100], secret[100];
5932 memset(authuser, 0, sizeof(authuser));
5933 memset(secret, 0, sizeof(secret));
5934 if(session->account.authuser && strchr(session->account.authuser, ':')) {
5935 /* The authuser contains a colon: wrap it in quotes */
5936 g_snprintf(authuser, sizeof(authuser), "\"%s\"", session->account.authuser);
5937 } else {
5938 g_snprintf(authuser, sizeof(authuser), "%s", session->account.authuser);
5939 }
5940 if(session->account.secret && strchr(session->account.secret, ':')) {
5941 /* The secret contains a colon: wrap it in quotes */
5942 g_snprintf(secret, sizeof(secret), "\"%s\"", session->account.secret);
5943 } else {
5944 g_snprintf(secret, sizeof(secret), "%s", session->account.secret);
5945 }
5946 char auth[256];
5947 memset(auth, 0, sizeof(auth));
5948 g_snprintf(auth, sizeof(auth), "%s%s:%s:%s:%s%s",
5949 session->account.secret_type == janus_sip_secret_type_hashed ? "HA1+" : "",
5950 scheme,
5951 realm,
5952 authuser,
5953 session->account.secret_type == janus_sip_secret_type_hashed ? "HA1+" : "",
5954 secret);
5955 JANUS_LOG(LOG_VERB, "\t%s\n", auth);
5956 /* Authenticate */
5957 nua_authenticate(nh,
5958 NUTAG_AUTH(auth),
5959 TAG_END());
5960 } else if(status >= 400) {
5961 auth_failed:
5962 /* Authentication failed? */
5963 session->account.registration_status = janus_sip_registration_status_failed;
5964 /* Cleanup registration values */
5965 if(session->account.identity != NULL) {
5966 janus_mutex_lock(&sessions_mutex);
5967 g_hash_table_remove(identities, session->account.identity);
5968 janus_mutex_unlock(&sessions_mutex);
5969 g_free(session->account.identity);
5970 }
5971 session->account.identity = NULL;
5972 session->account.force_udp = FALSE;
5973 session->account.force_tcp = FALSE;
5974 session->account.sips = TRUE;
5975 session->account.rfc2543_cancel = FALSE;
5976 if(session->account.username != NULL)
5977 g_free(session->account.username);
5978 session->account.username = NULL;
5979 if(session->account.display_name != NULL)
5980 g_free(session->account.display_name);
5981 session->account.display_name = NULL;
5982 if(session->account.authuser != NULL)
5983 g_free(session->account.authuser);
5984 session->account.authuser = NULL;
5985 if(session->account.secret != NULL)
5986 g_free(session->account.secret);
5987 session->account.secret = NULL;
5988 session->account.secret_type = janus_sip_secret_type_unknown;
5989 if(session->account.proxy != NULL)
5990 g_free(session->account.proxy);
5991 session->account.proxy = NULL;
5992 if(session->account.outbound_proxy != NULL)
5993 g_free(session->account.outbound_proxy);
5994 session->account.outbound_proxy = NULL;
5995 if(session->account.user_agent != NULL)
5996 g_free(session->account.user_agent);
5997 session->account.user_agent = NULL;
5998 session->account.registration_status = janus_sip_registration_status_unregistered;
5999 /* Tell the application... */
6000 json_t *event = json_object();
6001 json_object_set_new(event, "sip", json_string("event"));
6002 json_t *result = json_object();
6003 json_object_set_new(result, "event", json_string("registration_failed"));
6004 json_object_set_new(result, "code", json_integer(status));
6005 json_object_set_new(result, "reason", json_string(phrase ? phrase : ""));
6006 if(session->incoming_header_prefixes) {
6007 json_t *headers = janus_sip_get_incoming_headers(sip, session);
6008 json_object_set_new(result, "headers", headers);
6009 }
6010 json_object_set_new(event, "result", result);
6011 int ret = gateway->push_event(session->handle, &janus_sip_plugin, session->transaction, event, NULL);
6012 JANUS_LOG(LOG_VERB, " >> Pushing event to peer: %d (%s)\n", ret, janus_get_api_error(ret));
6013 json_decref(event);
6014 /* Also notify event handlers */
6015 if(notify_events && gateway->events_is_enabled()) {
6016 json_t *info = json_object();
6017 json_object_set_new(info, "event", json_string("registration_failed"));
6018 json_object_set_new(info, "code", json_integer(status));
6019 json_object_set_new(info, "reason", json_string(phrase ? phrase : ""));
6020 gateway->notify_event(&janus_sip_plugin, session->handle, info);
6021 }
6022 }
6023 break;
6024 }
6025 case nua_r_subscribe: {
6026 JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
6027 if(status == 200 || status == 202) {
6028 /* Success */
6029 json_t *event = json_object();
6030 json_object_set_new(event, "sip", json_string("event"));
6031 json_object_set_new(event, "call_id", json_string(sip->sip_call_id->i_id));
6032 json_t *result = json_object();
6033 json_object_set_new(result, "event", json_string("subscribe_succeeded"));
6034 json_object_set_new(result, "code", json_integer(status));
6035 if(session->incoming_header_prefixes) {
6036 json_t *headers = janus_sip_get_incoming_headers(sip, session);
6037 json_object_set_new(result, "headers", headers);
6038 }
6039 if (sip->sip_expires)
6040 json_object_set_new(result, "expires", json_integer(sip->sip_expires->ex_delta));
6041 json_object_set_new(result, "reason", json_string(phrase ? phrase : ""));
6042 json_object_set_new(event, "result", result);
6043 int ret = gateway->push_event(session->handle, &janus_sip_plugin, session->transaction, event, NULL);
6044 JANUS_LOG(LOG_VERB, " >> Pushing event to peer: %d (%s)\n", ret, janus_get_api_error(ret));
6045 json_decref(event);
6046 } else if(status == 401 || status == 407) {
6047 const char *scheme = NULL;
6048 const char *realm = NULL;
6049 if(status == 401) {
6050 /* Get scheme/realm from 401 error */
6051 sip_www_authenticate_t const* www_auth = sip->sip_www_authenticate;
6052 scheme = www_auth->au_scheme;
6053 realm = msg_params_find(www_auth->au_params, "realm=");
6054 } else {
6055 /* Get scheme/realm from 407 error, proxy-auth */
6056 sip_proxy_authenticate_t const* proxy_auth = sip->sip_proxy_authenticate;
6057 scheme = proxy_auth->au_scheme;
6058 realm = msg_params_find(proxy_auth->au_params, "realm=");
6059 }
6060 char authuser[100], secret[100];
6061 memset(authuser, 0, sizeof(authuser));
6062 memset(secret, 0, sizeof(secret));
6063 if(session->helper) {
6064 /* This is an helper session, we'll need the credentials from the master */
6065 if(session->master == NULL) {
6066 JANUS_LOG(LOG_WARN, "No master session for this helper, authentication will fail...\n");
6067 } else {
6068 session = session->master;
6069 }
6070 }
6071 if(session->account.authuser && strchr(session->account.authuser, ':')) {
6072 /* The authuser contains a colon: wrap it in quotes */
6073 g_snprintf(authuser, sizeof(authuser), "\"%s\"", session->account.authuser);
6074 } else {
6075 g_snprintf(authuser, sizeof(authuser), "%s", session->account.authuser);
6076 }
6077 if(session->account.secret && strchr(session->account.secret, ':')) {
6078 /* The secret contains a colon: wrap it in quotes */
6079 g_snprintf(secret, sizeof(secret), "\"%s\"", session->account.secret);
6080 } else {
6081 g_snprintf(secret, sizeof(secret), "%s", session->account.secret);
6082 }
6083 char auth[256];
6084 memset(auth, 0, sizeof(auth));
6085 g_snprintf(auth, sizeof(auth), "%s%s:%s:%s:%s%s",
6086 session->account.secret_type == janus_sip_secret_type_hashed ? "HA1+" : "",
6087 scheme,
6088 realm,
6089 authuser,
6090 session->account.secret_type == janus_sip_secret_type_hashed ? "HA1+" : "",
6091 secret);
6092 JANUS_LOG(LOG_VERB, "\t%s\n", auth);
6093 /* Authenticate */
6094 nua_authenticate(nh,
6095 NUTAG_AUTH(auth),
6096 TAG_END());
6097 break;
6098 } else if(status >= 400) {
6099 /* Something went wrong */
6100 JANUS_LOG(LOG_WARN, "[%s] SUBSCRIBE failed: %d %s\n", session->account.username, status, phrase ? phrase : "");
6101 json_t *event = json_object();
6102 json_object_set_new(event, "sip", json_string("event"));
6103 json_object_set_new(event, "call_id", json_string(sip->sip_call_id->i_id));
6104 json_t *result = json_object();
6105 json_object_set_new(result, "event", json_string("subscribe_failed"));
6106 json_object_set_new(result, "code", json_integer(status));
6107 json_object_set_new(result, "reason", json_string(phrase ? phrase : ""));
6108 if(session->incoming_header_prefixes) {
6109 json_t *headers = janus_sip_get_incoming_headers(sip, session);
6110 json_object_set_new(result, "headers", headers);
6111 }
6112 json_object_set_new(event, "result", result);
6113 int ret = gateway->push_event(session->handle, &janus_sip_plugin, session->transaction, event, NULL);
6114 JANUS_LOG(LOG_VERB, " >> Pushing event to peer: %d (%s)\n", ret, janus_get_api_error(ret));
6115 json_decref(event);
6116 }
6117 break;
6118 }
6119 case nua_r_notify: {
6120 JANUS_LOG(LOG_WARN, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
6121 /* We got a response to a NOTIFY we sent, but we really don't care */
6122 break;
6123 }
6124 default:
6125 /* unknown event -> print out error message */
6126 JANUS_LOG(LOG_ERR, "Unknown event %d (%s)\n", event, nua_event_name(event));
6127 break;
6128 }
6129 }
6130
janus_sip_sdp_process(janus_sip_session * session,janus_sdp * sdp,gboolean answer,gboolean update,gboolean * changed)6131 void janus_sip_sdp_process(janus_sip_session *session, janus_sdp *sdp, gboolean answer, gboolean update, gboolean *changed) {
6132 if(!session || !sdp)
6133 return;
6134 /* c= */
6135 if(sdp->c_addr) {
6136 if(update) {
6137 if(changed && (!session->media.remote_audio_ip || strcmp(sdp->c_addr, session->media.remote_audio_ip))) {
6138 /* This is an update and an address changed */
6139 *changed = TRUE;
6140 }
6141 if(changed && (!session->media.remote_video_ip || strcmp(sdp->c_addr, session->media.remote_video_ip))) {
6142 /* This is an update and an address changed */
6143 *changed = TRUE;
6144 }
6145 }
6146 /* Regardless if we audio and video are being negotiated we set their connection addresses
6147 * from session level c= header by default. If media level connection addresses are available
6148 * they will be set when processing appropriate media description.*/
6149 g_free(session->media.remote_audio_ip);
6150 session->media.remote_audio_ip = g_strdup(sdp->c_addr);
6151 g_free(session->media.remote_video_ip);
6152 session->media.remote_video_ip = g_strdup(sdp->c_addr);
6153 }
6154 GList *temp = sdp->m_lines;
6155 while(temp) {
6156 janus_sdp_mline *m = (janus_sdp_mline *)temp->data;
6157 session->media.require_srtp = session->media.require_srtp || (m->proto && !strcasecmp(m->proto, "RTP/SAVP"));
6158 if(m->type == JANUS_SDP_AUDIO) {
6159 if(m->port) {
6160 if(m->port != session->media.remote_audio_rtp_port) {
6161 /* This is an update and an address changed */
6162 if(changed)
6163 *changed = TRUE;
6164 }
6165 session->media.has_audio = TRUE;
6166 session->media.remote_audio_rtp_port = m->port;
6167 session->media.remote_audio_rtcp_port = m->port+1; /* FIXME We're assuming RTCP is on the next port */
6168 if(m->direction == JANUS_SDP_SENDONLY || m->direction == JANUS_SDP_INACTIVE)
6169 session->media.audio_send = FALSE;
6170 else
6171 session->media.audio_send = TRUE;
6172 } else {
6173 session->media.audio_send = FALSE;
6174 }
6175 } else if(m->type == JANUS_SDP_VIDEO) {
6176 if(m->port) {
6177 if(m->port != session->media.remote_video_rtp_port) {
6178 /* This is an update and an address changed */
6179 if(changed)
6180 *changed = TRUE;
6181 }
6182 session->media.has_video = TRUE;
6183 session->media.remote_video_rtp_port = m->port;
6184 session->media.remote_video_rtcp_port = m->port+1; /* FIXME We're assuming RTCP is on the next port */
6185 if(m->direction == JANUS_SDP_SENDONLY || m->direction == JANUS_SDP_INACTIVE)
6186 session->media.video_send = FALSE;
6187 else
6188 session->media.video_send = TRUE;
6189 } else {
6190 session->media.video_send = FALSE;
6191 }
6192 } else {
6193 JANUS_LOG(LOG_WARN, "Unsupported media line (not audio/video)\n");
6194 temp = temp->next;
6195 continue;
6196 }
6197 if(m->c_addr && m->type == JANUS_SDP_AUDIO) {
6198 if(update && (!session->media.remote_audio_ip || strcmp(m->c_addr, session->media.remote_audio_ip))) {
6199 /* This is an update and an address changed */
6200 if(changed)
6201 *changed = TRUE;
6202 }
6203 g_free(session->media.remote_audio_ip);
6204 session->media.remote_audio_ip = g_strdup(m->c_addr);
6205 }
6206 else if(m->c_addr && m->type == JANUS_SDP_VIDEO) {
6207 if(update && (!session->media.remote_video_ip || strcmp(m->c_addr, session->media.remote_video_ip))) {
6208 /* This is an update and an address changed */
6209 if(changed)
6210 *changed = TRUE;
6211 }
6212 g_free(session->media.remote_video_ip);
6213 session->media.remote_video_ip = g_strdup(m->c_addr);
6214 }
6215
6216 GList *tempA = m->attributes;
6217 while(tempA) {
6218 janus_sdp_attribute *a = (janus_sdp_attribute *)tempA->data;
6219 if(a->name) {
6220 if(!strcasecmp(a->name, "crypto")) {
6221 if(m->type == JANUS_SDP_AUDIO || m->type == JANUS_SDP_VIDEO) {
6222 if((m->type == JANUS_SDP_AUDIO && session->media.audio_srtp_in != NULL) || (m->type == JANUS_SDP_VIDEO && session->media.video_srtp_in != NULL)) {
6223 /* Remote SRTP is already set */
6224 tempA = tempA->next;
6225 continue;
6226 }
6227 gint32 tag = 0;
6228 char profile[101], crypto[101];
6229 int res = a->value ? (sscanf(a->value, "%"SCNi32" %100s inline:%100s",
6230 &tag, profile, crypto)) : 0;
6231 if(res != 3) {
6232 JANUS_LOG(LOG_WARN, "Failed to parse crypto line, ignoring... %s\n", a->value);
6233 } else {
6234 gboolean video = (m->type == JANUS_SDP_VIDEO);
6235 if(answer && ((!video && tag != session->media.audio_srtp_tag) || (video && tag != session->media.video_srtp_tag))) {
6236 /* Not the tag for the crypto line we offered */
6237 tempA = tempA->next;
6238 continue;
6239 }
6240 if(janus_sip_srtp_set_remote(session, video, profile, crypto) < 0) {
6241 /* Unsupported profile? */
6242 tempA = tempA->next;
6243 continue;
6244 }
6245 if(!video) {
6246 session->media.audio_srtp_tag = tag;
6247 session->media.has_srtp_remote_audio = TRUE;
6248 } else {
6249 session->media.video_srtp_tag = tag;
6250 session->media.has_srtp_remote_video = TRUE;
6251 }
6252 }
6253 }
6254 }
6255 }
6256 tempA = tempA->next;
6257 }
6258
6259 if(answer && (m->type == JANUS_SDP_AUDIO || m->type == JANUS_SDP_VIDEO)) {
6260 /* Check which codec was negotiated eventually */
6261 int pt = -1;
6262 if(m->ptypes)
6263 pt = GPOINTER_TO_INT(m->ptypes->data);
6264 if(pt > -1) {
6265 if(m->type == JANUS_SDP_AUDIO) {
6266 session->media.audio_pt = pt;
6267 } else {
6268 session->media.video_pt = pt;
6269 }
6270 }
6271 }
6272 temp = temp->next;
6273 }
6274
6275 if(update && changed && *changed) {
6276 /* Something changed: mark this on the session, so that the thread can update the sockets */
6277 session->media.updated = TRUE;
6278 if(session->media.pipefd[1] > 0) {
6279 int code = 1;
6280 ssize_t res = 0;
6281 do {
6282 res = write(session->media.pipefd[1], &code, sizeof(int));
6283 } while(res == -1 && errno == EINTR);
6284 }
6285 }
6286 }
6287
janus_sip_sdp_manipulate(janus_sip_session * session,janus_sdp * sdp,gboolean answer)6288 char *janus_sip_sdp_manipulate(janus_sip_session *session, janus_sdp *sdp, gboolean answer) {
6289 if(!session || !session->stack || !sdp)
6290 return NULL;
6291 GHashTable *codecs = NULL;
6292 GList *pts_to_remove = NULL;
6293 /* Start replacing stuff */
6294 JANUS_LOG(LOG_VERB, "Setting protocol to %s\n", session->media.require_srtp ? "RTP/SAVP" : "RTP/AVP");
6295 if(sdp->c_addr) {
6296 g_free(sdp->c_addr);
6297 sdp->c_addr = g_strdup(sdp_ip ? sdp_ip : (local_media_ip ? local_media_ip : local_ip));
6298 }
6299 GList *temp = sdp->m_lines;
6300 while(temp) {
6301 janus_sdp_mline *m = (janus_sdp_mline *)temp->data;
6302 g_free(m->proto);
6303 m->proto = g_strdup(session->media.require_srtp ? "RTP/SAVP" : "RTP/AVP");
6304 if(m->type == JANUS_SDP_AUDIO) {
6305 m->port = session->media.local_audio_rtp_port;
6306 if(session->media.has_srtp_local_audio) {
6307 if(!session->media.audio_srtp_local_profile || !session->media.audio_srtp_local_crypto) {
6308 janus_sip_srtp_set_local(session, FALSE, &session->media.audio_srtp_local_profile, &session->media.audio_srtp_local_crypto);
6309 }
6310 if(session->media.audio_srtp_tag == 0)
6311 session->media.audio_srtp_tag = 1;
6312 janus_sdp_attribute *a = janus_sdp_attribute_create("crypto", "%"SCNi32" %s inline:%s",
6313 session->media.audio_srtp_tag, session->media.audio_srtp_local_profile, session->media.audio_srtp_local_crypto);
6314 m->attributes = g_list_append(m->attributes, a);
6315 }
6316 } else if(m->type == JANUS_SDP_VIDEO) {
6317 m->port = session->media.local_video_rtp_port;
6318 if(session->media.has_srtp_local_video) {
6319 if(!session->media.video_srtp_local_profile || !session->media.video_srtp_local_crypto) {
6320 janus_sip_srtp_set_local(session, TRUE, &session->media.video_srtp_local_profile, &session->media.video_srtp_local_crypto);
6321 }
6322 if(session->media.video_srtp_tag == 0)
6323 session->media.video_srtp_tag = 1;
6324 janus_sdp_attribute *a = janus_sdp_attribute_create("crypto", "%"SCNi32" %s inline:%s",
6325 session->media.video_srtp_tag, session->media.video_srtp_local_profile, session->media.video_srtp_local_crypto);
6326 m->attributes = g_list_append(m->attributes, a);
6327 }
6328 }
6329 g_free(m->c_addr);
6330 m->c_addr = g_strdup(sdp_ip ? sdp_ip : (local_media_ip ? local_media_ip : local_ip));
6331 if(answer && (m->type == JANUS_SDP_AUDIO || m->type == JANUS_SDP_VIDEO)) {
6332 /* Check which codec was negotiated eventually */
6333 int pt = -1;
6334 if(m->ptypes)
6335 pt = GPOINTER_TO_INT(m->ptypes->data);
6336 if(pt > -1) {
6337 if(m->type == JANUS_SDP_AUDIO) {
6338 session->media.audio_pt = pt;
6339 } else {
6340 session->media.video_pt = pt;
6341 }
6342 }
6343 }
6344 /* If this is an answer, get rid of multiple versions of the same
6345 * codec as well (e.g., video profiles), as that confuses the hell
6346 * out of SOATAG_RTP_SELECT(SOA_RTP_SELECT_COMMON) in nua_respond() */
6347 if(answer) {
6348 if(codecs == NULL)
6349 codecs = g_hash_table_new_full(g_str_hash, g_str_equal, (GDestroyNotify)g_free, NULL);
6350 /* Check all rtpmap attributes */
6351 int pt = -1;
6352 char codec[50];
6353 GList *ma = m->attributes;
6354 while(ma) {
6355 janus_sdp_attribute *a = (janus_sdp_attribute *)ma->data;
6356 if(a->name != NULL && a->value != NULL && !strcasecmp(a->name, "rtpmap")) {
6357 if(sscanf(a->value, "%3d %49s", &pt, codec) == 2) {
6358 if(g_hash_table_lookup(codecs, codec) != NULL) {
6359 /* We already have a version of this codec, remove the payload type */
6360 pts_to_remove = g_list_append(pts_to_remove, GINT_TO_POINTER(pt));
6361 JANUS_LOG(LOG_HUGE, "Removing %d (%s)\n", pt, codec);
6362 } else {
6363 /* Keep track of this codec */
6364 g_hash_table_insert(codecs, g_strdup(codec), GINT_TO_POINTER(pt));
6365 }
6366 }
6367 }
6368 ma = ma->next;
6369 }
6370 }
6371 temp = temp->next;
6372 }
6373 /* If we need to remove some payload types from the SDP, do it now */
6374 if(pts_to_remove != NULL) {
6375 GList *temp = pts_to_remove;
6376 while(temp) {
6377 int pt = GPOINTER_TO_INT(temp->data);
6378 janus_sdp_remove_payload_type(sdp, pt);
6379 temp = temp->next;
6380 }
6381 g_list_free(pts_to_remove);
6382 }
6383 /* Generate a SDP string out of our changes */
6384 return janus_sdp_write(sdp);
6385 }
6386
6387 /* Bind local RTP/RTCP sockets */
janus_sip_allocate_local_ports(janus_sip_session * session,gboolean update)6388 static int janus_sip_allocate_local_ports(janus_sip_session *session, gboolean update) {
6389 if(session == NULL) {
6390 JANUS_LOG(LOG_ERR, "Invalid session\n");
6391 return -1;
6392 }
6393 if(!update) {
6394 /* Reset status */
6395 if(session->media.audio_rtp_fd != -1) {
6396 close(session->media.audio_rtp_fd);
6397 session->media.audio_rtp_fd = -1;
6398 }
6399 if(session->media.audio_rtcp_fd != -1) {
6400 close(session->media.audio_rtcp_fd);
6401 session->media.audio_rtcp_fd = -1;
6402 }
6403 session->media.local_audio_rtp_port = 0;
6404 session->media.local_audio_rtcp_port = 0;
6405 session->media.audio_ssrc = 0;
6406 if(session->media.video_rtp_fd != -1) {
6407 close(session->media.video_rtp_fd);
6408 session->media.video_rtp_fd = -1;
6409 }
6410 if(session->media.video_rtcp_fd != -1) {
6411 close(session->media.video_rtcp_fd);
6412 session->media.video_rtcp_fd = -1;
6413 }
6414 session->media.local_video_rtp_port = 0;
6415 session->media.local_video_rtcp_port = 0;
6416 session->media.video_ssrc = 0;
6417 if(session->media.pipefd[0] > 0) {
6418 close(session->media.pipefd[0]);
6419 session->media.pipefd[0] = -1;
6420 }
6421 if(session->media.pipefd[1] > 0) {
6422 close(session->media.pipefd[1]);
6423 session->media.pipefd[1] = -1;
6424 }
6425 }
6426 /* Start */
6427 int attempts = 100; /* FIXME Don't retry forever */
6428 if(session->media.has_audio) {
6429 JANUS_LOG(LOG_VERB, "Allocating audio ports:\n");
6430 struct sockaddr_in audio_rtp_address, audio_rtcp_address;
6431 while(session->media.local_audio_rtp_port == 0 || session->media.local_audio_rtcp_port == 0) {
6432 if(attempts == 0) /* Too many failures */
6433 return -1;
6434 if(session->media.audio_rtp_fd == -1) {
6435 session->media.audio_rtp_fd = socket(AF_INET, SOCK_DGRAM, 0);
6436 /* Set the DSCP value if set in the config file */
6437 if(session->media.audio_rtp_fd != -1 && dscp_audio_rtp > 0) {
6438 int optval = dscp_audio_rtp << 2;
6439 int ret = setsockopt(session->media.audio_rtp_fd, IPPROTO_IP, IP_TOS, &optval, sizeof(optval));
6440 if(ret < 0) {
6441 JANUS_LOG(LOG_WARN, "Error setting IP_TOS %d on audio RTP socket (error=%s)\n",
6442 optval, g_strerror(errno));
6443 }
6444 }
6445 }
6446 if(session->media.audio_rtcp_fd == -1) {
6447 session->media.audio_rtcp_fd = socket(AF_INET, SOCK_DGRAM, 0);
6448 }
6449 if(session->media.audio_rtp_fd == -1 || session->media.audio_rtcp_fd == -1) {
6450 JANUS_LOG(LOG_ERR, "Error creating audio sockets...\n");
6451 return -1;
6452 }
6453 int rtp_port = g_random_int_range(rtp_range_min, rtp_range_max);
6454 if(rtp_port % 2)
6455 rtp_port++; /* Pick an even port for RTP */
6456 audio_rtp_address.sin_family = AF_INET;
6457 audio_rtp_address.sin_port = htons(rtp_port);
6458 inet_pton(AF_INET, (local_media_ip ? local_media_ip : local_ip), &audio_rtp_address.sin_addr.s_addr);
6459 if(bind(session->media.audio_rtp_fd, (struct sockaddr *)(&audio_rtp_address), sizeof(struct sockaddr)) < 0) {
6460 JANUS_LOG(LOG_ERR, "Bind failed for audio RTP (port %d), trying a different one...\n", rtp_port);
6461 close(session->media.audio_rtp_fd);
6462 session->media.audio_rtp_fd = -1;
6463 attempts--;
6464 continue;
6465 }
6466 JANUS_LOG(LOG_VERB, "Audio RTP listener bound to %s:%d(%d)\n", (local_media_ip ? local_media_ip : local_ip), rtp_port, session->media.audio_rtp_fd);
6467 int rtcp_port = rtp_port+1;
6468 audio_rtcp_address.sin_family = AF_INET;
6469 audio_rtcp_address.sin_port = htons(rtcp_port);
6470 inet_pton(AF_INET, (local_media_ip ? local_media_ip : local_ip), &audio_rtcp_address.sin_addr.s_addr);
6471 if(bind(session->media.audio_rtcp_fd, (struct sockaddr *)(&audio_rtcp_address), sizeof(struct sockaddr)) < 0) {
6472 JANUS_LOG(LOG_ERR, "Bind failed for audio RTCP (port %d), trying a different one...\n", rtcp_port);
6473 /* RTP socket is not valid anymore, reset it */
6474 close(session->media.audio_rtp_fd);
6475 session->media.audio_rtp_fd = -1;
6476 close(session->media.audio_rtcp_fd);
6477 session->media.audio_rtcp_fd = -1;
6478 attempts--;
6479 continue;
6480 }
6481 JANUS_LOG(LOG_VERB, "Audio RTCP listener bound to %s:%d(%d)\n", (local_media_ip ? local_media_ip : local_ip), rtcp_port, session->media.audio_rtcp_fd);
6482 session->media.local_audio_rtp_port = rtp_port;
6483 session->media.local_audio_rtcp_port = rtcp_port;
6484 }
6485 }
6486 if(session->media.has_video) {
6487 JANUS_LOG(LOG_VERB, "Allocating video ports:\n");
6488 struct sockaddr_in video_rtp_address, video_rtcp_address;
6489 while(session->media.local_video_rtp_port == 0 || session->media.local_video_rtcp_port == 0) {
6490 if(attempts == 0) /* Too many failures */
6491 return -1;
6492 if(session->media.video_rtp_fd == -1) {
6493 session->media.video_rtp_fd = socket(AF_INET, SOCK_DGRAM, 0);
6494 /* Set the DSCP value if set in the config file */
6495 if(session->media.video_rtp_fd != -1 && dscp_video_rtp > 0) {
6496 int optval = dscp_video_rtp << 2;
6497 int ret = setsockopt(session->media.video_rtp_fd, IPPROTO_IP, IP_TOS, &optval, sizeof(optval));
6498 if(ret < 0) {
6499 JANUS_LOG(LOG_WARN, "Error setting IP_TOS %d on video RTP socket (error=%s)\n",
6500 optval, g_strerror(errno));
6501 }
6502 }
6503 }
6504 if(session->media.video_rtcp_fd == -1) {
6505 session->media.video_rtcp_fd = socket(AF_INET, SOCK_DGRAM, 0);
6506 }
6507 if(session->media.video_rtp_fd == -1 || session->media.video_rtcp_fd == -1) {
6508 JANUS_LOG(LOG_ERR, "Error creating video sockets...\n");
6509 return -1;
6510 }
6511 int rtp_port = g_random_int_range(rtp_range_min, rtp_range_max);
6512 if(rtp_port % 2)
6513 rtp_port++; /* Pick an even port for RTP */
6514 video_rtp_address.sin_family = AF_INET;
6515 video_rtp_address.sin_port = htons(rtp_port);
6516 inet_pton(AF_INET, (local_media_ip ? local_media_ip : local_ip), &video_rtp_address.sin_addr.s_addr);
6517 if(bind(session->media.video_rtp_fd, (struct sockaddr *)(&video_rtp_address), sizeof(struct sockaddr)) < 0) {
6518 JANUS_LOG(LOG_ERR, "Bind failed for video RTP (port %d), trying a different one...\n", rtp_port);
6519 close(session->media.video_rtp_fd);
6520 session->media.video_rtp_fd = -1;
6521 attempts--;
6522 continue;
6523 }
6524 JANUS_LOG(LOG_VERB, "Video RTP listener bound to %s:%d(%d)\n", (local_media_ip ? local_media_ip : local_ip), rtp_port, session->media.video_rtp_fd);
6525 int rtcp_port = rtp_port+1;
6526 video_rtcp_address.sin_family = AF_INET;
6527 video_rtcp_address.sin_port = htons(rtcp_port);
6528 inet_pton(AF_INET, (local_media_ip ? local_media_ip : local_ip), &video_rtcp_address.sin_addr.s_addr);
6529 if(bind(session->media.video_rtcp_fd, (struct sockaddr *)(&video_rtcp_address), sizeof(struct sockaddr)) < 0) {
6530 JANUS_LOG(LOG_ERR, "Bind failed for video RTCP (port %d), trying a different one...\n", rtcp_port);
6531 /* RTP socket is not valid anymore, reset it */
6532 close(session->media.video_rtp_fd);
6533 session->media.video_rtp_fd = -1;
6534 close(session->media.video_rtcp_fd);
6535 session->media.video_rtcp_fd = -1;
6536 attempts--;
6537 continue;
6538 }
6539 JANUS_LOG(LOG_VERB, "Video RTCP listener bound to %s:%d(%d)\n", (local_media_ip ? local_media_ip : local_ip), rtcp_port, session->media.video_rtcp_fd);
6540 session->media.local_video_rtp_port = rtp_port;
6541 session->media.local_video_rtcp_port = rtcp_port;
6542 }
6543 }
6544 if(!update) {
6545 /* We need this to quickly interrupt the poll when it's time to update a session or wrap up */
6546 pipe(session->media.pipefd);
6547 }
6548 return 0;
6549 }
6550
6551 /* Helper method to (re)connect RTP/RTCP sockets */
janus_sip_connect_sockets(janus_sip_session * session,struct sockaddr_in * audio_server_addr,struct sockaddr_in * video_server_addr)6552 static void janus_sip_connect_sockets(janus_sip_session *session, struct sockaddr_in *audio_server_addr, struct sockaddr_in *video_server_addr) {
6553 if(!session || (!audio_server_addr && !video_server_addr))
6554 return;
6555
6556 /* Connect peers (FIXME This pretty much sucks right now) */
6557 if(session->media.remote_audio_rtp_port && audio_server_addr && session->media.audio_rtp_fd != -1) {
6558 audio_server_addr->sin_port = htons(session->media.remote_audio_rtp_port);
6559 if(connect(session->media.audio_rtp_fd, (struct sockaddr *)audio_server_addr, sizeof(struct sockaddr)) == -1) {
6560 JANUS_LOG(LOG_ERR, "[SIP-%s] Couldn't connect audio RTP? (%s:%d)\n", session->account.username, session->media.remote_audio_ip, session->media.remote_audio_rtp_port);
6561 JANUS_LOG(LOG_ERR, "[SIP-%s] -- %d (%s)\n", session->account.username, errno, g_strerror(errno));
6562 }
6563 }
6564 if(session->media.remote_audio_rtcp_port && audio_server_addr && session->media.audio_rtcp_fd != -1) {
6565 audio_server_addr->sin_port = htons(session->media.remote_audio_rtcp_port);
6566 if(connect(session->media.audio_rtcp_fd, (struct sockaddr *)audio_server_addr, sizeof(struct sockaddr)) == -1) {
6567 JANUS_LOG(LOG_ERR, "[SIP-%s] Couldn't connect audio RTCP? (%s:%d)\n", session->account.username, session->media.remote_audio_ip, session->media.remote_audio_rtcp_port);
6568 JANUS_LOG(LOG_ERR, "[SIP-%s] -- %d (%s)\n", session->account.username, errno, g_strerror(errno));
6569 }
6570 }
6571 if(session->media.remote_video_rtp_port && video_server_addr && session->media.video_rtp_fd != -1) {
6572 video_server_addr->sin_port = htons(session->media.remote_video_rtp_port);
6573 if(connect(session->media.video_rtp_fd, (struct sockaddr *)video_server_addr, sizeof(struct sockaddr)) == -1) {
6574 JANUS_LOG(LOG_ERR, "[SIP-%s] Couldn't connect video RTP? (%s:%d)\n", session->account.username, session->media.remote_video_ip, session->media.remote_video_rtp_port);
6575 JANUS_LOG(LOG_ERR, "[SIP-%s] -- %d (%s)\n", session->account.username, errno, g_strerror(errno));
6576 }
6577 }
6578 if(session->media.remote_video_rtcp_port && video_server_addr && session->media.video_rtcp_fd != -1) {
6579 video_server_addr->sin_port = htons(session->media.remote_video_rtcp_port);
6580 if(connect(session->media.video_rtcp_fd, (struct sockaddr *)video_server_addr, sizeof(struct sockaddr)) == -1) {
6581 JANUS_LOG(LOG_ERR, "[SIP-%s] Couldn't connect video RTCP? (%s:%d)\n", session->account.username, session->media.remote_video_ip, session->media.remote_video_rtcp_port);
6582 JANUS_LOG(LOG_ERR, "[SIP-%s] -- %d (%s)\n", session->account.username, errno, g_strerror(errno));
6583 }
6584 }
6585 }
6586
janus_sip_media_cleanup(janus_sip_session * session)6587 static void janus_sip_media_cleanup(janus_sip_session *session) {
6588 if(session->media.audio_rtp_fd != -1) {
6589 close(session->media.audio_rtp_fd);
6590 session->media.audio_rtp_fd = -1;
6591 }
6592 if(session->media.audio_rtcp_fd != -1) {
6593 close(session->media.audio_rtcp_fd);
6594 session->media.audio_rtcp_fd = -1;
6595 }
6596 session->media.local_audio_rtp_port = 0;
6597 session->media.local_audio_rtcp_port = 0;
6598 session->media.remote_audio_rtp_port = 0;
6599 session->media.remote_audio_rtcp_port = 0;
6600 session->media.audio_ssrc = 0;
6601 session->media.audio_ssrc_peer = 0;
6602 if(session->media.video_rtp_fd != -1) {
6603 close(session->media.video_rtp_fd);
6604 session->media.video_rtp_fd = -1;
6605 }
6606 if(session->media.video_rtcp_fd != -1) {
6607 close(session->media.video_rtcp_fd);
6608 session->media.video_rtcp_fd = -1;
6609 }
6610 session->media.local_video_rtp_port = 0;
6611 session->media.local_video_rtcp_port = 0;
6612 session->media.remote_video_rtp_port = 0;
6613 session->media.remote_video_rtcp_port = 0;
6614 session->media.video_ssrc = 0;
6615 session->media.video_ssrc_peer = 0;
6616 session->media.simulcast_ssrc = 0;
6617 if(session->media.pipefd[0] > 0) {
6618 close(session->media.pipefd[0]);
6619 session->media.pipefd[0] = -1;
6620 }
6621 if(session->media.pipefd[1] > 0) {
6622 close(session->media.pipefd[1]);
6623 session->media.pipefd[1] = -1;
6624 }
6625 /* Clean up SRTP stuff, if needed */
6626 janus_sip_srtp_cleanup(session);
6627
6628 /* Media fields not cleaned up elsewhere */
6629 janus_sip_media_reset(session);
6630 }
6631
6632 /* Thread to relay RTP/RTCP frames coming from the SIP peer */
janus_sip_relay_thread(void * data)6633 static void *janus_sip_relay_thread(void *data) {
6634 janus_sip_session *session = (janus_sip_session *)data;
6635 if(!session) {
6636 g_thread_unref(g_thread_self());
6637 return NULL;
6638 }
6639 if(!session->account.username || !session->callee) {
6640 janus_refcount_decrease(&session->ref);
6641 g_thread_unref(g_thread_self());
6642 return NULL;
6643 }
6644 JANUS_LOG(LOG_VERB, "Starting relay thread (%s <--> %s)\n", session->account.username, session->callee);
6645
6646 if(!session->callee) {
6647 JANUS_LOG(LOG_WARN, "[SIP-%s] Leaving thread, no callee...\n", session->account.username);
6648 janus_refcount_decrease(&session->ref);
6649 g_thread_unref(g_thread_self());
6650 return NULL;
6651 }
6652 /* File descriptors */
6653 socklen_t addrlen;
6654 struct sockaddr_in remote;
6655 int resfd = 0, bytes = 0, pollerrs = 0;
6656 struct pollfd fds[5];
6657 int pipe_fd = session->media.pipefd[0];
6658 char buffer[1500];
6659 memset(buffer, 0, 1500);
6660 if(pipe_fd == -1) {
6661 /* If the pipe file descriptor doesn't exist, it means we're done already,
6662 * and/or we may never be notified about sessions being closed, so give up */
6663 JANUS_LOG(LOG_WARN, "[SIP-%s] Leaving thread, no pipe file descriptor...\n", session->account.username);
6664 janus_refcount_decrease(&session->ref);
6665 g_thread_unref(g_thread_self());
6666 return NULL;
6667 }
6668 /* Loop */
6669 int num = 0;
6670 gboolean goon = TRUE;
6671
6672 session->media.updated = TRUE; /* Connect UDP sockets upon loop entry */
6673 gboolean have_audio_server_ip = TRUE;
6674 gboolean have_video_server_ip = TRUE;
6675
6676 while(goon && session != NULL && !g_atomic_int_get(&session->destroyed) &&
6677 session->status > janus_sip_call_status_idle &&
6678 session->status < janus_sip_call_status_closing) { /* FIXME We need a per-call watchdog as well */
6679
6680 if(session->media.updated) {
6681 /* Apparently there was a session update, or the loop has just been entered */
6682 session->media.updated = FALSE;
6683
6684 have_audio_server_ip = session->media.remote_audio_ip != NULL;
6685 struct sockaddr_in audio_server_addr;
6686 memset(&audio_server_addr, 0, sizeof(struct sockaddr_in));
6687 audio_server_addr.sin_family = AF_INET;
6688
6689 have_video_server_ip = session->media.remote_video_ip != NULL;
6690 struct sockaddr_in video_server_addr;
6691 memset(&video_server_addr, 0, sizeof(struct sockaddr_in));
6692 video_server_addr.sin_family = AF_INET;
6693
6694 if(session->media.remote_audio_ip && inet_aton(session->media.remote_audio_ip, &audio_server_addr.sin_addr) == 0) { /* Not a numeric IP... */
6695 /* Note that gethostbyname() may block waiting for response if it triggers on the wire request.*/
6696 struct hostent *host = gethostbyname(session->media.remote_audio_ip); /* ...resolve name */
6697 if(!host) {
6698 JANUS_LOG(LOG_ERR, "[SIP-%s] Couldn't get host (%s)\n", session->account.username, session->media.remote_audio_ip);
6699 have_audio_server_ip = FALSE;
6700 } else {
6701 audio_server_addr.sin_addr = *(struct in_addr *)host->h_addr_list;
6702 }
6703 }
6704
6705 if(session->media.remote_video_ip && inet_aton(session->media.remote_video_ip, &video_server_addr.sin_addr) == 0) { /* Not a numeric IP... */
6706 /* Note that gethostbyname() may block waiting for response if it triggers on the wire request.*/
6707 struct hostent *host = gethostbyname(session->media.remote_video_ip); /* ...resolve name */
6708 if(!host) {
6709 JANUS_LOG(LOG_ERR, "[SIP-%s] Couldn't get host (%s)\n", session->account.username, session->media.remote_video_ip);
6710 have_video_server_ip = FALSE;
6711 } else {
6712 video_server_addr.sin_addr = *(struct in_addr *)host->h_addr_list;
6713 }
6714 }
6715
6716 if(have_audio_server_ip || have_video_server_ip) {
6717 janus_sip_connect_sockets(session, have_audio_server_ip ? &audio_server_addr : NULL,
6718 have_video_server_ip ? &video_server_addr : NULL);
6719 } else if(session->media.remote_audio_ip == NULL && session->media.remote_video_ip == NULL) {
6720 JANUS_LOG(LOG_ERR, "[SIP-%p] Couldn't update session details: both audio and video remote IP addresses are NULL\n",
6721 session->account.username);
6722 } else {
6723 if(session->media.remote_audio_ip)
6724 JANUS_LOG(LOG_ERR, "[SIP-%p] Couldn't update session details: audio remote IP address (%s) is invalid\n",
6725 session->account.username, session->media.remote_audio_ip);
6726 if(session->media.remote_video_ip)
6727 JANUS_LOG(LOG_ERR, "[SIP-%p] Couldn't update session details: video remote IP address (%s) is invalid\n",
6728 session->account.username, session->media.remote_video_ip);
6729 }
6730
6731 /* In case we're on hold (remote address is 0.0.0.0) set the send properties to FALSE */
6732 if(have_audio_server_ip && !strcmp(session->media.remote_audio_ip, "0.0.0.0"))
6733 session->media.audio_send = FALSE;
6734 if(have_video_server_ip && !strcmp(session->media.remote_video_ip, "0.0.0.0"))
6735 session->media.video_send = FALSE;
6736 }
6737
6738 /* Prepare poll */
6739 num = 0;
6740 if(session->media.audio_rtp_fd != -1) {
6741 fds[num].fd = session->media.audio_rtp_fd;
6742 fds[num].events = POLLIN;
6743 fds[num].revents = 0;
6744 num++;
6745 }
6746 if(session->media.audio_rtcp_fd != -1) {
6747 fds[num].fd = session->media.audio_rtcp_fd;
6748 fds[num].events = POLLIN;
6749 fds[num].revents = 0;
6750 num++;
6751 }
6752 if(session->media.video_rtp_fd != -1) {
6753 fds[num].fd = session->media.video_rtp_fd;
6754 fds[num].events = POLLIN;
6755 fds[num].revents = 0;
6756 num++;
6757 }
6758 if(session->media.video_rtcp_fd != -1) {
6759 fds[num].fd = session->media.video_rtcp_fd;
6760 fds[num].events = POLLIN;
6761 fds[num].revents = 0;
6762 num++;
6763 }
6764 /* Finally, let's add the pipe */
6765 pipe_fd = session->media.pipefd[0];
6766 if(pipe_fd == -1) {
6767 /* Pipe was closed? Means the call is over */
6768 break;
6769 }
6770 fds[num].fd = pipe_fd;
6771 fds[num].events = POLLIN;
6772 fds[num].revents = 0;
6773 num++;
6774 /* Wait for some data */
6775 resfd = poll(fds, num, 1000);
6776 if(resfd < 0) {
6777 if(errno == EINTR) {
6778 JANUS_LOG(LOG_HUGE, "[SIP-%s] Got an EINTR (%s), ignoring...\n", session->account.username, g_strerror(errno));
6779 continue;
6780 }
6781 JANUS_LOG(LOG_ERR, "[SIP-%s] Error polling...\n", session->account.username);
6782 JANUS_LOG(LOG_ERR, "[SIP-%s] -- %d (%s)\n", session->account.username, errno, g_strerror(errno));
6783 break;
6784 } else if(resfd == 0) {
6785 /* No data, keep going */
6786 continue;
6787 }
6788 if(session == NULL || g_atomic_int_get(&session->destroyed) ||
6789 session->status <= janus_sip_call_status_idle ||
6790 session->status >= janus_sip_call_status_closing)
6791 break;
6792 int i = 0;
6793 for(i=0; i<num; i++) {
6794 if(fds[i].revents & (POLLERR | POLLHUP)) {
6795 /* If we just updated the session, let's wait until things have calmed down */
6796 if(session->media.updated)
6797 break;
6798 /* Check the socket error */
6799 int error = 0;
6800 socklen_t errlen = sizeof(error);
6801 getsockopt(fds[i].fd, SOL_SOCKET, SO_ERROR, (void *)&error, &errlen);
6802 if(error == 0) {
6803 /* Maybe not a breaking error after all? */
6804 continue;
6805 } else if(error == 111) {
6806 /* ICMP error? If it's related to RTCP, let's just close the RTCP socket and move on */
6807 if(fds[i].fd == session->media.audio_rtcp_fd) {
6808 JANUS_LOG(LOG_WARN, "[SIP-%s] Got a '%s' on the audio RTCP socket, closing it\n",
6809 session->account.username, g_strerror(error));
6810 janus_mutex_lock(&session->mutex);
6811 close(session->media.audio_rtcp_fd);
6812 session->media.audio_rtcp_fd = -1;
6813 janus_mutex_unlock(&session->mutex);
6814 continue;
6815 } else if(fds[i].fd == session->media.video_rtcp_fd) {
6816 JANUS_LOG(LOG_WARN, "[SIP-%s] Got a '%s' on the video RTCP socket, closing it\n",
6817 session->account.username, g_strerror(error));
6818 janus_mutex_lock(&session->mutex);
6819 close(session->media.video_rtcp_fd);
6820 session->media.video_rtcp_fd = -1;
6821 janus_mutex_unlock(&session->mutex);
6822 continue;
6823 }
6824 }
6825 /* FIXME Should we be more tolerant of ICMP errors on RTP sockets as well? */
6826 pollerrs++;
6827 if(pollerrs < 100)
6828 continue;
6829 JANUS_LOG(LOG_ERR, "[SIP-%s] Too many errors polling %d (socket #%d): %s...\n", session->account.username,
6830 fds[i].fd, i, fds[i].revents & POLLERR ? "POLLERR" : "POLLHUP");
6831 JANUS_LOG(LOG_ERR, "[SIP-%s] -- %d (%s)\n", session->account.username, error, g_strerror(error));
6832 goon = FALSE; /* Can we assume it's pretty much over, after a POLLERR? */
6833 /* FIXME Simulate a "hangup" coming from the application */
6834 janus_sip_hangup_media(session->handle);
6835 break;
6836 } else if(fds[i].revents & POLLIN) {
6837 if(pipe_fd != -1 && fds[i].fd == pipe_fd) {
6838 /* Poll interrupted for a reason, go on */
6839 int code = 0;
6840 (void)read(pipe_fd, &code, sizeof(int));
6841 break;
6842 }
6843 /* Got an RTP/RTCP packet */
6844 if(session->media.audio_rtp_fd != -1 && fds[i].fd == session->media.audio_rtp_fd) {
6845 /* Got something audio (RTP) */
6846 addrlen = sizeof(remote);
6847 bytes = recvfrom(session->media.audio_rtp_fd, buffer, 1500, 0, (struct sockaddr*)&remote, &addrlen);
6848 if(bytes < 0 || !janus_is_rtp(buffer, bytes)) {
6849 /* Failed to read or not an RTP packet? */
6850 continue;
6851 }
6852 pollerrs = 0;
6853 janus_rtp_header *header = (janus_rtp_header *)buffer;
6854 if(session->media.audio_ssrc_peer == 0) {
6855 session->media.audio_ssrc_peer = ntohl(header->ssrc);
6856 JANUS_LOG(LOG_VERB, "Got SIP peer audio SSRC: %"SCNu32"\n", session->media.audio_ssrc_peer);
6857 }
6858 /* Is this SRTP? */
6859 if(session->media.has_srtp_remote_audio) {
6860 int buflen = bytes;
6861 srtp_err_status_t res = srtp_unprotect(session->media.audio_srtp_in, buffer, &buflen);
6862 if(res != srtp_err_status_ok && res != srtp_err_status_replay_fail && res != srtp_err_status_replay_old) {
6863 guint32 timestamp = ntohl(header->timestamp);
6864 guint16 seq = ntohs(header->seq_number);
6865 JANUS_LOG(LOG_ERR, "[SIP-%s] Audio SRTP unprotect error: %s (len=%d-->%d, ts=%"SCNu32", seq=%"SCNu16")\n",
6866 session->account.username, janus_srtp_error_str(res), bytes, buflen, timestamp, seq);
6867 continue;
6868 }
6869 bytes = buflen;
6870 }
6871 /* Check if the SSRC changed (e.g., after a re-INVITE or UPDATE) */
6872 janus_rtp_header_update(header, &session->media.context, FALSE, 0);
6873 /* Save the frame if we're recording */
6874 header->ssrc = htonl(session->media.audio_ssrc_peer);
6875 janus_recorder_save_frame(session->arc_peer, buffer, bytes);
6876 /* Relay to application */
6877 janus_plugin_rtp rtp = { .video = FALSE, .buffer = buffer, .length = bytes };
6878 janus_plugin_rtp_extensions_reset(&rtp.extensions);
6879 /* Add audio-level extension, if present */
6880 if(session->media.audio_level_extension_id != -1) {
6881 gboolean vad = FALSE;
6882 int level = -1;
6883 if(janus_rtp_header_extension_parse_audio_level(buffer, bytes,
6884 session->media.audio_level_extension_id, &vad, &level) == 0) {
6885 rtp.extensions.audio_level = level;
6886 rtp.extensions.audio_level_vad = vad;
6887 }
6888 }
6889 gateway->relay_rtp(session->handle, &rtp);
6890 continue;
6891 } else if(session->media.audio_rtcp_fd != -1 && fds[i].fd == session->media.audio_rtcp_fd) {
6892 /* Got something audio (RTCP) */
6893 addrlen = sizeof(remote);
6894 bytes = recvfrom(session->media.audio_rtcp_fd, buffer, 1500, 0, (struct sockaddr*)&remote, &addrlen);
6895 if(bytes < 0 || !janus_is_rtcp(buffer, bytes)) {
6896 /* Failed to read or not an RTCP packet? */
6897 continue;
6898 }
6899 pollerrs = 0;
6900 /* Is this SRTCP? */
6901 if(session->media.has_srtp_remote_audio) {
6902 int buflen = bytes;
6903 srtp_err_status_t res = srtp_unprotect_rtcp(session->media.audio_srtp_in, buffer, &buflen);
6904 if(res != srtp_err_status_ok && res != srtp_err_status_replay_fail && res != srtp_err_status_replay_old) {
6905 JANUS_LOG(LOG_ERR, "[SIP-%s] Audio SRTCP unprotect error: %s (len=%d-->%d)\n",
6906 session->account.username, janus_srtp_error_str(res), bytes, buflen);
6907 continue;
6908 }
6909 bytes = buflen;
6910 }
6911 /* Relay to application */
6912 janus_plugin_rtcp rtcp = { .video = FALSE, .buffer = buffer, bytes };
6913 gateway->relay_rtcp(session->handle, &rtcp);
6914 continue;
6915 } else if(session->media.video_rtp_fd != -1 && fds[i].fd == session->media.video_rtp_fd) {
6916 /* Got something video (RTP) */
6917 addrlen = sizeof(remote);
6918 bytes = recvfrom(session->media.video_rtp_fd, buffer, 1500, 0, (struct sockaddr*)&remote, &addrlen);
6919 if(bytes < 0 || !janus_is_rtp(buffer, bytes)) {
6920 /* Failed to read or not an RTP packet? */
6921 continue;
6922 }
6923 pollerrs = 0;
6924 janus_rtp_header *header = (janus_rtp_header *)buffer;
6925 if(session->media.video_ssrc_peer == 0) {
6926 session->media.video_ssrc_peer = ntohl(header->ssrc);
6927 JANUS_LOG(LOG_VERB, "Got SIP peer video SSRC: %"SCNu32"\n", session->media.video_ssrc_peer);
6928 }
6929 /* Is this SRTP? */
6930 if(session->media.has_srtp_remote_video) {
6931 int buflen = bytes;
6932 srtp_err_status_t res = srtp_unprotect(session->media.video_srtp_in, buffer, &buflen);
6933 if(res != srtp_err_status_ok && res != srtp_err_status_replay_fail && res != srtp_err_status_replay_old) {
6934 guint32 timestamp = ntohl(header->timestamp);
6935 guint16 seq = ntohs(header->seq_number);
6936 JANUS_LOG(LOG_ERR, "[SIP-%s] Video SRTP unprotect error: %s (len=%d-->%d, ts=%"SCNu32", seq=%"SCNu16")\n",
6937 session->account.username, janus_srtp_error_str(res), bytes, buflen, timestamp, seq);
6938 continue;
6939 }
6940 bytes = buflen;
6941 }
6942 /* Check if the SSRC changed (e.g., after a re-INVITE or UPDATE) */
6943 janus_rtp_header_update(header, &session->media.context, TRUE, 0);
6944 /* Save the frame if we're recording */
6945 header->ssrc = htonl(session->media.video_ssrc_peer);
6946 janus_recorder_save_frame(session->vrc_peer, buffer, bytes);
6947 /* Relay to application */
6948 janus_plugin_rtp rtp = { .video = TRUE, .buffer = buffer, .length = bytes };
6949 janus_plugin_rtp_extensions_reset(&rtp.extensions);
6950 /* Add video-orientation extension, if present */
6951 if(session->media.video_orientation_extension_id > 0) {
6952 gboolean c = FALSE, f = FALSE, r1 = FALSE, r0 = FALSE;
6953 if(janus_rtp_header_extension_parse_video_orientation(buffer, bytes,
6954 session->media.video_orientation_extension_id, &c, &f, &r1, &r0) == 0) {
6955 rtp.extensions.video_rotation = 0;
6956 if(r1 && r0)
6957 rtp.extensions.video_rotation = 270;
6958 else if(r1)
6959 rtp.extensions.video_rotation = 180;
6960 else if(r0)
6961 rtp.extensions.video_rotation = 90;
6962 rtp.extensions.video_back_camera = c;
6963 rtp.extensions.video_flipped = f;
6964 }
6965 }
6966 gateway->relay_rtp(session->handle, &rtp);
6967 continue;
6968 } else if(session->media.video_rtcp_fd != -1 && fds[i].fd == session->media.video_rtcp_fd) {
6969 /* Got something video (RTCP) */
6970 addrlen = sizeof(remote);
6971 bytes = recvfrom(session->media.video_rtcp_fd, buffer, 1500, 0, (struct sockaddr*)&remote, &addrlen);
6972 if(bytes < 0 || !janus_is_rtcp(buffer, bytes)) {
6973 /* Failed to read or not an RTCP packet? */
6974 continue;
6975 }
6976 pollerrs = 0;
6977 /* Is this SRTCP? */
6978 if(session->media.has_srtp_remote_video) {
6979 int buflen = bytes;
6980 srtp_err_status_t res = srtp_unprotect_rtcp(session->media.video_srtp_in, buffer, &buflen);
6981 if(res != srtp_err_status_ok && res != srtp_err_status_replay_fail && res != srtp_err_status_replay_old) {
6982 JANUS_LOG(LOG_ERR, "[SIP-%s] Video SRTP unprotect error: %s (len=%d-->%d)\n",
6983 session->account.username, janus_srtp_error_str(res), bytes, buflen);
6984 continue;
6985 }
6986 bytes = buflen;
6987 }
6988 /* Relay to application */
6989 janus_plugin_rtcp rtcp = { .video = TRUE, .buffer = buffer, bytes };
6990 gateway->relay_rtcp(session->handle, &rtcp);
6991 continue;
6992 }
6993 }
6994 }
6995 }
6996 /* Cleanup the media session */
6997 janus_mutex_lock(&session->mutex);
6998 janus_sip_media_cleanup(session);
6999 janus_mutex_unlock(&session->mutex);
7000 /* Done */
7001 JANUS_LOG(LOG_VERB, "Leaving SIP relay thread\n");
7002 session->relayer_thread = NULL;
7003 janus_refcount_decrease(&session->ref);
7004 g_thread_unref(g_thread_self());
7005 return NULL;
7006 }
7007
7008
7009 /* Sofia Event thread */
janus_sip_sofia_thread(gpointer user_data)7010 gpointer janus_sip_sofia_thread(gpointer user_data) {
7011 janus_sip_session *session = (janus_sip_session *)user_data;
7012 if(session == NULL) {
7013 g_thread_unref(g_thread_self());
7014 return NULL;
7015 }
7016 if(session->account.username == NULL) {
7017 janus_refcount_decrease(&session->ref);
7018 g_thread_unref(g_thread_self());
7019 return NULL;
7020 }
7021 JANUS_LOG(LOG_VERB, "Joining sofia loop thread (%s)...\n", session->account.username);
7022 session->stack = g_malloc0(sizeof(ssip_t));
7023 su_home_init(session->stack->s_home);
7024 session->stack->session = session;
7025 session->stack->s_nua = NULL;
7026 session->stack->s_nh_r = NULL;
7027 session->stack->s_nh_i = NULL;
7028 session->stack->s_nh_m = NULL;
7029 session->stack->s_root = su_root_create(session->stack);
7030 session->stack->subscriptions = NULL;
7031 janus_mutex_init(&session->stack->smutex);
7032 JANUS_LOG(LOG_VERB, "Setting up sofia stack (sip:%s@%s)\n", session->account.username, local_ip);
7033 char sip_url[128];
7034 char sips_url[128];
7035 char *ipv6;
7036 ipv6 = strstr(local_ip, ":");
7037 if(session->account.force_udp)
7038 g_snprintf(sip_url, sizeof(sip_url), "sip:%s%s%s:*;transport=udp", ipv6 ? "[" : "", local_ip, ipv6 ? "]" : "");
7039 else if(session->account.force_tcp)
7040 g_snprintf(sip_url, sizeof(sip_url), "sip:%s%s%s:*;transport=tcp", ipv6 ? "[" : "", local_ip, ipv6 ? "]" : "");
7041 else
7042 g_snprintf(sip_url, sizeof(sip_url), "sip:%s%s%s:*", ipv6 ? "[" : "", local_ip, ipv6 ? "]" : "");
7043 g_snprintf(sips_url, sizeof(sips_url), "sips:%s%s%s:*", ipv6 ? "[" : "", local_ip, ipv6 ? "]" : "");
7044 char outbound_options[256] = "use-rport no-validate";
7045 if(keepalive_interval > 0)
7046 janus_strlcat(outbound_options, " options-keepalive", sizeof(outbound_options));
7047 if(!behind_nat)
7048 janus_strlcat(outbound_options, " no-natify", sizeof(outbound_options));
7049 session->stack->s_nua = nua_create(session->stack->s_root,
7050 janus_sip_sofia_callback,
7051 session,
7052 SIPTAG_ALLOW_STR("INVITE, ACK, BYE, CANCEL, OPTIONS, UPDATE, REFER, MESSAGE, INFO, NOTIFY"),
7053 NUTAG_M_USERNAME(session->account.username),
7054 NUTAG_URL(sip_url),
7055 TAG_IF(session->account.sips, NUTAG_SIPS_URL(sips_url)),
7056 SIPTAG_USER_AGENT_STR(session->account.user_agent ? session->account.user_agent : user_agent),
7057 NUTAG_KEEPALIVE(keepalive_interval * 1000), /* Sofia expects it in milliseconds */
7058 NUTAG_OUTBOUND(outbound_options),
7059 NUTAG_APPL_METHOD("REFER"), /* We'll respond to incoming REFER messages ourselves */
7060 SIPTAG_SUPPORTED_STR("replaces"), /* Advertise that we support the Replaces header */
7061 SIPTAG_SUPPORTED(NULL),
7062 NTATAG_CANCEL_2543(session->account.rfc2543_cancel),
7063 TAG_NULL());
7064 if(query_contact_header)
7065 nua_get_params(session->stack->s_nua, SIPTAG_FROM_STR(""), TAG_END());
7066 su_root_run(session->stack->s_root);
7067 /* When we get here, we're done */
7068 janus_mutex_lock(&session->stack->smutex);
7069 nua_t *s_nua = session->stack->s_nua;
7070 session->stack->s_nua = NULL;
7071 janus_mutex_unlock(&session->stack->smutex);
7072 if(session->stack->s_nh_r != NULL) {
7073 nua_handle_destroy(session->stack->s_nh_r);
7074 session->stack->s_nh_r = NULL;
7075 }
7076 if(session->stack->s_nh_i != NULL) {
7077 nua_handle_destroy(session->stack->s_nh_i);
7078 session->stack->s_nh_i = NULL;
7079 }
7080 if(session->stack->s_nh_m != NULL) {
7081 nua_handle_destroy(session->stack->s_nh_m);
7082 session->stack->s_nh_m = NULL;
7083 }
7084 nua_destroy(s_nua);
7085 su_root_destroy(session->stack->s_root);
7086 session->stack->s_root = NULL;
7087 janus_refcount_decrease(&session->ref);
7088 JANUS_LOG(LOG_VERB, "Leaving sofia loop thread...\n");
7089 g_thread_unref(g_thread_self());
7090 return NULL;
7091 }
7092