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