1 /* $Id$ */
2 /*
3  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
4  * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20 #include <pjsua-lib/pjsua.h>
21 #include <pjsua-lib/pjsua_internal.h>
22 
23 
24 #define THIS_FILE		"pjsua_call.c"
25 
26 
27 /* Retry interval of sending re-INVITE for locking a codec when remote
28  * SDP answer contains multiple codec, in milliseconds.
29  */
30 #define LOCK_CODEC_RETRY_INTERVAL   200
31 
32 /*
33  * Max UPDATE/re-INVITE retry to lock codec
34  */
35 #define LOCK_CODEC_MAX_RETRY	     5
36 
37 /* Determine whether we should restart ICE upon receiving a re-INVITE
38  * with no SDP.
39  */
40 #define RESTART_ICE_ON_REINVITE      1
41 
42 /* Retry interval of trying to hangup a call. */
43 #define CALL_HANGUP_RETRY_INTERVAL   5000
44 
45 /* Max number of hangup retries. */
46 #define CALL_HANGUP_MAX_RETRY	     4
47 
48 /*
49  * The INFO method.
50  */
51 const pjsip_method pjsip_info_method =
52 {
53     PJSIP_OTHER_METHOD,
54     { "INFO", 4 }
55 };
56 
57 /* UPDATE method */
58 static const pjsip_method pjsip_update_method =
59 {
60     PJSIP_OTHER_METHOD,
61     { "UPDATE", 6 }
62 };
63 
64 /* This callback receives notification from invite session when the
65  * session state has changed.
66  */
67 static void pjsua_call_on_state_changed(pjsip_inv_session *inv,
68 					pjsip_event *e);
69 
70 /* This callback is called by invite session framework when UAC session
71  * has forked.
72  */
73 static void pjsua_call_on_forked( pjsip_inv_session *inv,
74 				  pjsip_event *e);
75 
76 /*
77  * Callback to be called when SDP offer/answer negotiation has just completed
78  * in the session. This function will start/update media if negotiation
79  * has succeeded.
80  */
81 static void pjsua_call_on_media_update(pjsip_inv_session *inv,
82 				       pj_status_t status);
83 
84 /*
85  * Called when session received new offer.
86  */
87 static void pjsua_call_on_rx_offer(pjsip_inv_session *inv,
88 				struct pjsip_inv_on_rx_offer_cb_param *param);
89 
90 /*
91  * Called when receiving re-INVITE.
92  */
93 static pj_status_t pjsua_call_on_rx_reinvite(pjsip_inv_session *inv,
94     		                  	     const pjmedia_sdp_session *offer,
95                                   	     pjsip_rx_data *rdata);
96 
97 /*
98  * Called to generate new offer.
99  */
100 static void pjsua_call_on_create_offer(pjsip_inv_session *inv,
101 				       pjmedia_sdp_session **offer);
102 
103 /*
104  * This callback is called when transaction state has changed in INVITE
105  * session. We use this to trap:
106  *  - incoming REFER request.
107  *  - incoming MESSAGE request.
108  */
109 static void pjsua_call_on_tsx_state_changed(pjsip_inv_session *inv,
110 					    pjsip_transaction *tsx,
111 					    pjsip_event *e);
112 
113 /*
114  * Redirection handler.
115  */
116 static pjsip_redirect_op pjsua_call_on_redirected(pjsip_inv_session *inv,
117 						  const pjsip_uri *target,
118 						  const pjsip_event *e);
119 
120 
121 /* Create SDP for call hold. */
122 static pj_status_t create_sdp_of_call_hold(pjsua_call *call,
123 					   pjmedia_sdp_session **p_sdp);
124 
125 /*
126  * Callback called by event framework when the xfer subscription state
127  * has changed.
128  */
129 static void xfer_client_on_evsub_state( pjsip_evsub *sub, pjsip_event *event);
130 static void xfer_server_on_evsub_state( pjsip_evsub *sub, pjsip_event *event);
131 
132 /* Timer callback to send re-INVITE/UPDATE to lock codec or ICE update */
133 static void reinv_timer_cb(pj_timer_heap_t *th, pj_timer_entry *entry);
134 
135 /* Timer callback to hangup the call */
136 static void hangup_timer_cb(pj_timer_heap_t *th, pj_timer_entry *entry);
137 
138 /* Check and send reinvite for lock codec and ICE update */
139 static pj_status_t process_pending_reinvite(pjsua_call *call);
140 
141 /* Timer callbacks for trickle ICE */
142 static void trickle_ice_send_sip_info(pj_timer_heap_t *th,
143 				      struct pj_timer_entry *te);
144 static void trickle_ice_retrans_18x(pj_timer_heap_t *th,
145 				    struct pj_timer_entry *te);
146 
147 /*
148  * Reset call descriptor.
149  */
reset_call(pjsua_call_id id)150 static void reset_call(pjsua_call_id id)
151 {
152     pjsua_call *call = &pjsua_var.calls[id];
153     unsigned i;
154 
155     if (call->incoming_data) {
156 	pjsip_rx_data_free_cloned(call->incoming_data);
157 	call->incoming_data = NULL;
158     }
159     pj_bzero(call, sizeof(*call));
160     call->index = id;
161     call->last_text.ptr = call->last_text_buf_;
162     call->cname.ptr = call->cname_buf;
163     call->cname.slen = sizeof(call->cname_buf);
164     for (i=0; i<PJ_ARRAY_SIZE(call->media); ++i) {
165 	pjsua_call_media *call_med = &call->media[i];
166 	call_med->ssrc = pj_rand();
167 	call_med->strm.a.conf_slot = PJSUA_INVALID_ID;
168 	call_med->strm.v.cap_win_id = PJSUA_INVALID_ID;
169 	call_med->strm.v.rdr_win_id = PJSUA_INVALID_ID;
170 	call_med->strm.v.strm_dec_slot = PJSUA_INVALID_ID;
171 	call_med->strm.v.strm_enc_slot = PJSUA_INVALID_ID;
172 	call_med->call = call;
173 	call_med->idx = i;
174 	call_med->tp_auto_del = PJ_TRUE;
175     }
176     pjsua_call_setting_default(&call->opt);
177     pj_timer_entry_init(&call->reinv_timer, PJ_FALSE,
178 			(void*)(pj_size_t)id, &reinv_timer_cb);
179     pj_bzero(&call->trickle_ice, sizeof(call->trickle_ice));
180     pj_timer_entry_init(&call->trickle_ice.timer, 0, call,
181 			&trickle_ice_send_sip_info);
182 }
183 
184 /* Get DTMF method type name */
get_dtmf_method_name(int type)185 static const char* get_dtmf_method_name(int type)
186 {
187     switch (type) {
188 	case PJSUA_DTMF_METHOD_RFC2833:
189 	    return "RFC2833";
190 	case PJSUA_DTMF_METHOD_SIP_INFO:
191 	    return "SIP INFO";
192     }
193     return "(Unknown)";
194 }
195 
196 /*
197  * Init call subsystem.
198  */
pjsua_call_subsys_init(const pjsua_config * cfg)199 pj_status_t pjsua_call_subsys_init(const pjsua_config *cfg)
200 {
201     pjsip_inv_callback inv_cb;
202     unsigned i;
203     const pj_str_t str_norefersub = { "norefersub", 10 };
204     const pj_str_t str_trickle_ice = { "trickle-ice", 11 };
205     pj_status_t status;
206 
207     /* Init calls array. */
208     for (i=0; i<PJ_ARRAY_SIZE(pjsua_var.calls); ++i)
209 	reset_call(i);
210 
211     /* Copy config */
212     pjsua_config_dup(pjsua_var.pool, &pjsua_var.ua_cfg, cfg);
213 
214     /* Verify settings */
215     if (pjsua_var.ua_cfg.max_calls >= PJSUA_MAX_CALLS) {
216 	pjsua_var.ua_cfg.max_calls = PJSUA_MAX_CALLS;
217     }
218 
219     /* Check the route URI's and force loose route if required */
220     for (i=0; i<pjsua_var.ua_cfg.outbound_proxy_cnt; ++i) {
221 	status = normalize_route_uri(pjsua_var.pool,
222 				     &pjsua_var.ua_cfg.outbound_proxy[i]);
223 	if (status != PJ_SUCCESS)
224 	    return status;
225     }
226 
227     /* Initialize invite session callback. */
228     pj_bzero(&inv_cb, sizeof(inv_cb));
229     inv_cb.on_state_changed = &pjsua_call_on_state_changed;
230     inv_cb.on_new_session = &pjsua_call_on_forked;
231     inv_cb.on_media_update = &pjsua_call_on_media_update;
232     inv_cb.on_rx_offer2 = &pjsua_call_on_rx_offer;
233     inv_cb.on_create_offer = &pjsua_call_on_create_offer;
234     inv_cb.on_tsx_state_changed = &pjsua_call_on_tsx_state_changed;
235     inv_cb.on_redirected = &pjsua_call_on_redirected;
236     if (pjsua_var.ua_cfg.cb.on_call_rx_reinvite) {
237     	inv_cb.on_rx_reinvite = &pjsua_call_on_rx_reinvite;
238     }
239 
240     /* Initialize invite session module: */
241     status = pjsip_inv_usage_init(pjsua_var.endpt, &inv_cb);
242     PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
243 
244     /* Add "norefersub" in Supported header */
245     pjsip_endpt_add_capability(pjsua_var.endpt, NULL, PJSIP_H_SUPPORTED,
246 			       NULL, 1, &str_norefersub);
247 
248     /* Add "INFO" in Allow header, for DTMF and video key frame request. */
249     pjsip_endpt_add_capability(pjsua_var.endpt, NULL, PJSIP_H_ALLOW,
250 			       NULL, 1, &pjsip_info_method.name);
251 
252     /* Add "trickle-ice" in Supported header */
253     pjsip_endpt_add_capability(pjsua_var.endpt, NULL, PJSIP_H_SUPPORTED,
254 			       NULL, 1, &str_trickle_ice);
255 
256     return status;
257 }
258 
259 
260 /*
261  * Start call subsystem.
262  */
pjsua_call_subsys_start(void)263 pj_status_t pjsua_call_subsys_start(void)
264 {
265     /* Nothing to do */
266     return PJ_SUCCESS;
267 }
268 
269 
270 /*
271  * Get maximum number of calls configured in pjsua.
272  */
pjsua_call_get_max_count(void)273 PJ_DEF(unsigned) pjsua_call_get_max_count(void)
274 {
275     return pjsua_var.ua_cfg.max_calls;
276 }
277 
278 
279 /*
280  * Get number of currently active calls.
281  */
pjsua_call_get_count(void)282 PJ_DEF(unsigned) pjsua_call_get_count(void)
283 {
284     return pjsua_var.call_cnt;
285 }
286 
287 
288 /*
289  * Enum calls.
290  */
pjsua_enum_calls(pjsua_call_id ids[],unsigned * count)291 PJ_DEF(pj_status_t) pjsua_enum_calls( pjsua_call_id ids[],
292 				      unsigned *count)
293 {
294     unsigned i, c;
295 
296     PJ_ASSERT_RETURN(ids && *count, PJ_EINVAL);
297 
298     PJSUA_LOCK();
299 
300     for (i=0, c=0; c<*count && i<pjsua_var.ua_cfg.max_calls; ++i) {
301 	if (!pjsua_var.calls[i].inv)
302 	    continue;
303 	ids[c] = i;
304 	++c;
305     }
306 
307     *count = c;
308 
309     PJSUA_UNLOCK();
310 
311     return PJ_SUCCESS;
312 }
313 
314 
315 /* Allocate one call id */
alloc_call_id(void)316 static pjsua_call_id alloc_call_id(void)
317 {
318     pjsua_call_id cid;
319 
320 #if 1
321     /* New algorithm: round-robin */
322     if (pjsua_var.next_call_id >= (int)pjsua_var.ua_cfg.max_calls ||
323 	pjsua_var.next_call_id < 0)
324     {
325 	pjsua_var.next_call_id = 0;
326     }
327 
328     for (cid=pjsua_var.next_call_id;
329 	 cid<(int)pjsua_var.ua_cfg.max_calls;
330 	 ++cid)
331     {
332 	if (pjsua_var.calls[cid].inv == NULL &&
333             pjsua_var.calls[cid].async_call.dlg == NULL)
334         {
335 	    ++pjsua_var.next_call_id;
336 	    return cid;
337 	}
338     }
339 
340     for (cid=0; cid < pjsua_var.next_call_id; ++cid) {
341 	if (pjsua_var.calls[cid].inv == NULL &&
342             pjsua_var.calls[cid].async_call.dlg == NULL)
343         {
344 	    ++pjsua_var.next_call_id;
345 	    return cid;
346 	}
347     }
348 
349 #else
350     /* Old algorithm */
351     for (cid=0; cid<(int)pjsua_var.ua_cfg.max_calls; ++cid) {
352 	if (pjsua_var.calls[cid].inv == NULL)
353 	    return cid;
354     }
355 #endif
356 
357     return PJSUA_INVALID_ID;
358 }
359 
360 /* Get signaling secure level.
361  * Return:
362  *  0: if signaling is not secure
363  *  1: if TLS transport is used for immediate hop
364  *  2: if end-to-end signaling is secure.
365  */
get_secure_level(pjsua_acc_id acc_id,const pj_str_t * dst_uri)366 static int get_secure_level(pjsua_acc_id acc_id, const pj_str_t *dst_uri)
367 {
368     const pj_str_t tls = pj_str(";transport=tls");
369     const pj_str_t sips = pj_str("sips:");
370     pjsua_acc *acc = &pjsua_var.acc[acc_id];
371 
372     if (pj_stristr(dst_uri, &sips))
373 	return 2;
374 
375     if (!pj_list_empty(&acc->route_set)) {
376 	pjsip_route_hdr *r = acc->route_set.next;
377 	pjsip_uri *uri = r->name_addr.uri;
378 	pjsip_sip_uri *sip_uri;
379 
380 	sip_uri = (pjsip_sip_uri*)pjsip_uri_get_uri(uri);
381 	if (pj_stricmp2(&sip_uri->transport_param, "tls")==0)
382 	    return 1;
383 
384     } else {
385 	if (pj_stristr(dst_uri, &tls))
386 	    return 1;
387     }
388 
389     return 0;
390 }
391 
392 /*
393 static int call_get_secure_level(pjsua_call *call)
394 {
395     if (call->inv->dlg->secure)
396 	return 2;
397 
398     if (!pj_list_empty(&call->inv->dlg->route_set)) {
399 	pjsip_route_hdr *r = call->inv->dlg->route_set.next;
400 	pjsip_uri *uri = r->name_addr.uri;
401 	pjsip_sip_uri *sip_uri;
402 
403 	sip_uri = (pjsip_sip_uri*)pjsip_uri_get_uri(uri);
404 	if (pj_stricmp2(&sip_uri->transport_param, "tls")==0)
405 	    return 1;
406 
407     } else {
408 	pjsip_sip_uri *sip_uri;
409 
410 	if (PJSIP_URI_SCHEME_IS_SIPS(call->inv->dlg->target))
411 	    return 2;
412 	if (!PJSIP_URI_SCHEME_IS_SIP(call->inv->dlg->target))
413 	    return 0;
414 
415 	sip_uri = (pjsip_sip_uri*) pjsip_uri_get_uri(call->inv->dlg->target);
416 	if (pj_stricmp2(&sip_uri->transport_param, "tls")==0)
417 	    return 1;
418     }
419 
420     return 0;
421 }
422 */
423 
424 /* Outgoing call callback when media transport creation is completed. */
425 static pj_status_t
on_make_call_med_tp_complete(pjsua_call_id call_id,const pjsua_med_tp_state_info * info)426 on_make_call_med_tp_complete(pjsua_call_id call_id,
427                              const pjsua_med_tp_state_info *info)
428 {
429     pjmedia_sdp_session *offer = NULL;
430     pjsip_inv_session *inv = NULL;
431     pjsua_call *call = &pjsua_var.calls[call_id];
432     pjsua_acc *acc = &pjsua_var.acc[call->acc_id];
433     pjsip_dialog *dlg = call->async_call.dlg;
434     unsigned options = 0;
435     pjsip_tx_data *tdata;
436     pj_bool_t cb_called = PJ_FALSE;
437     pj_status_t status = (info? info->status: PJ_SUCCESS);
438 
439     PJSUA_LOCK();
440 
441     /* Increment the dialog's lock otherwise when invite session creation
442      * fails the dialog will be destroyed prematurely.
443      */
444     pjsip_dlg_inc_lock(dlg);
445 
446     /* Decrement dialog session. */
447     pjsip_dlg_dec_session(dlg, &pjsua_var.mod);
448 
449     if (status != PJ_SUCCESS) {
450 	pj_str_t err_str;
451 	pj_ssize_t title_len;
452 
453 	call->last_code = PJSIP_SC_TEMPORARILY_UNAVAILABLE;
454 	pj_strcpy2(&call->last_text, "Media init error: ");
455 
456 	title_len = call->last_text.slen;
457 	err_str = pj_strerror(status, call->last_text_buf_ + title_len,
458 	                      sizeof(call->last_text_buf_) - title_len);
459 	call->last_text.slen += err_str.slen;
460 
461 	pjsua_perror(THIS_FILE, "Error initializing media channel", status);
462 	goto on_error;
463     }
464 
465     /* pjsua_media_channel_deinit() has been called or
466      * call has been hung up.
467      */
468     if (call->async_call.med_ch_deinit ||
469         call->async_call.call_var.out_call.hangup)
470     {
471         PJ_LOG(4,(THIS_FILE, "Call has been hung up or media channel has "
472                              "been deinitialized"));
473         goto on_error;
474     }
475 
476     /* Create offer */
477     if ((call->opt.flag & PJSUA_CALL_NO_SDP_OFFER) == 0) {
478         status = pjsua_media_channel_create_sdp(call->index, dlg->pool, NULL,
479                                                 &offer, NULL);
480         if (status != PJ_SUCCESS) {
481             pjsua_perror(THIS_FILE, "Error initializing media channel", status);
482             goto on_error;
483         }
484     }
485 
486     /* Create the INVITE session: */
487     options |= PJSIP_INV_SUPPORT_100REL;
488     if (acc->cfg.require_100rel == PJSUA_100REL_MANDATORY)
489 	options |= PJSIP_INV_REQUIRE_100REL;
490     if (acc->cfg.use_timer != PJSUA_SIP_TIMER_INACTIVE) {
491 	options |= PJSIP_INV_SUPPORT_TIMER;
492 	if (acc->cfg.use_timer == PJSUA_SIP_TIMER_REQUIRED)
493 	    options |= PJSIP_INV_REQUIRE_TIMER;
494 	else if (acc->cfg.use_timer == PJSUA_SIP_TIMER_ALWAYS)
495 	    options |= PJSIP_INV_ALWAYS_USE_TIMER;
496     }
497     if (acc->cfg.ice_cfg.enable_ice &&
498 	acc->cfg.ice_cfg.ice_opt.trickle != PJ_ICE_SESS_TRICKLE_DISABLED)
499     {
500 	options |= PJSIP_INV_SUPPORT_TRICKLE_ICE;
501     }
502 
503     status = pjsip_inv_create_uac( dlg, offer, options, &inv);
504     if (status != PJ_SUCCESS) {
505 	pjsua_perror(THIS_FILE, "Invite session creation failed", status);
506 	goto on_error;
507     }
508 
509     /* Init Session Timers */
510     status = pjsip_timer_init_session(inv, &acc->cfg.timer_setting);
511     if (status != PJ_SUCCESS) {
512 	pjsua_perror(THIS_FILE, "Session Timer init failed", status);
513 	goto on_error;
514     }
515 
516     /* Create and associate our data in the session. */
517     call->inv = inv;
518 
519     dlg->mod_data[pjsua_var.mod.id] = call;
520     inv->mod_data[pjsua_var.mod.id] = call;
521 
522     /* If account is locked to specific transport, then lock dialog
523      * to this transport too.
524      */
525     if (acc->cfg.transport_id != PJSUA_INVALID_ID) {
526 	pjsip_tpselector tp_sel;
527 
528 	pjsua_init_tpselector(acc->cfg.transport_id, &tp_sel);
529 	pjsip_dlg_set_transport(dlg, &tp_sel);
530     }
531 
532     /* Set dialog Route-Set: */
533     if (!pj_list_empty(&acc->route_set))
534 	pjsip_dlg_set_route_set(dlg, &acc->route_set);
535 
536 
537     /* Set credentials: */
538     if (acc->cred_cnt) {
539 	pjsip_auth_clt_set_credentials( &dlg->auth_sess,
540 					acc->cred_cnt, acc->cred);
541     }
542 
543     /* Set authentication preference */
544     pjsip_auth_clt_set_prefs(&dlg->auth_sess, &acc->cfg.auth_pref);
545 
546     /* Create initial INVITE: */
547 
548     status = pjsip_inv_invite(inv, &tdata);
549     if (status != PJ_SUCCESS) {
550 	pjsua_perror(THIS_FILE, "Unable to create initial INVITE request",
551 		     status);
552 	goto on_error;
553     }
554 
555 
556     /* Add additional headers etc */
557 
558     pjsua_process_msg_data( tdata,
559                             call->async_call.call_var.out_call.msg_data);
560 
561     /* Must increment call counter now */
562     ++pjsua_var.call_cnt;
563 
564     /* Send initial INVITE: */
565 
566     status = pjsip_inv_send_msg(inv, tdata);
567     if (status != PJ_SUCCESS) {
568 	cb_called = PJ_TRUE;
569 
570 	/* Upon failure to send first request, the invite
571 	 * session would have been cleared.
572 	 */
573 	inv = NULL;
574 	goto on_error;
575     }
576 
577     /* Done. */
578     call->med_ch_cb = NULL;
579 
580     pjsip_dlg_dec_lock(dlg);
581     PJSUA_UNLOCK();
582 
583     return PJ_SUCCESS;
584 
585 on_error:
586     if (inv == NULL && call_id != -1 && !cb_called &&
587     	!call->hanging_up &&
588 	pjsua_var.ua_cfg.cb.on_call_state)
589     {
590 	/* Use user event rather than NULL to avoid crash in
591 	 * unsuspecting app.
592 	 */
593 	pjsip_event user_event;
594 	PJSIP_EVENT_INIT_USER(user_event, 0, 0, 0, 0);
595 
596         (*pjsua_var.ua_cfg.cb.on_call_state)(call_id, &user_event);
597     }
598 
599     if (dlg) {
600 	/* This may destroy the dialog */
601 	pjsip_dlg_dec_lock(dlg);
602     }
603 
604     if (inv != NULL) {
605 	pjsip_inv_terminate(inv, PJSIP_SC_OK, PJ_FALSE);
606     }
607 
608     if (call_id != -1) {
609 	pjsua_media_channel_deinit(call_id);
610 	reset_call(call_id);
611     }
612 
613     call->med_ch_cb = NULL;
614 
615     pjsua_check_snd_dev_idle();
616 
617     PJSUA_UNLOCK();
618     return status;
619 }
620 
621 
622 /*
623  * Cleanup call setting flag to avoid one time flags, such as
624  * PJSUA_CALL_UNHOLD, PJSUA_CALL_UPDATE_CONTACT, or
625  * PJSUA_CALL_NO_SDP_OFFER, to be sticky (ticket #1793).
626  */
pjsua_call_cleanup_flag(pjsua_call_setting * opt)627 void pjsua_call_cleanup_flag(pjsua_call_setting *opt)
628 {
629     opt->flag &= ~(PJSUA_CALL_UNHOLD | PJSUA_CALL_UPDATE_CONTACT |
630 		   PJSUA_CALL_NO_SDP_OFFER | PJSUA_CALL_REINIT_MEDIA |
631 		   PJSUA_CALL_UPDATE_VIA);
632 }
633 
634 
635 /*
636  * Initialize call settings based on account ID.
637  */
pjsua_call_setting_default(pjsua_call_setting * opt)638 PJ_DEF(void) pjsua_call_setting_default(pjsua_call_setting *opt)
639 {
640     pj_assert(opt);
641 
642     pj_bzero(opt, sizeof(*opt));
643     opt->flag = PJSUA_CALL_INCLUDE_DISABLED_MEDIA;
644     opt->aud_cnt = 1;
645 
646 #if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0)
647     opt->vid_cnt = 1;
648     opt->req_keyframe_method = PJSUA_VID_REQ_KEYFRAME_SIP_INFO |
649 			       PJSUA_VID_REQ_KEYFRAME_RTCP_PLI;
650 #endif
651 }
652 
653 /*
654  * Initialize pjsua_call_send_dtmf_param default values.
655  */
pjsua_call_send_dtmf_param_default(pjsua_call_send_dtmf_param * param)656 PJ_DEF(void) pjsua_call_send_dtmf_param_default(
657 					     pjsua_call_send_dtmf_param *param)
658 {
659     pj_bzero(param, sizeof(*param));
660     param->duration = PJSUA_CALL_SEND_DTMF_DURATION_DEFAULT;
661 }
662 
apply_call_setting(pjsua_call * call,const pjsua_call_setting * opt,const pjmedia_sdp_session * rem_sdp)663 static pj_status_t apply_call_setting(pjsua_call *call,
664 				      const pjsua_call_setting *opt,
665 				      const pjmedia_sdp_session *rem_sdp)
666 {
667     pj_assert(call);
668 
669     if (!opt) {
670 	pjsua_call_cleanup_flag(&call->opt);
671     } else {
672     	call->opt = *opt;
673     }
674 
675 #if !PJMEDIA_HAS_VIDEO
676     pj_assert(call->opt.vid_cnt == 0);
677 #endif
678 
679     if (call->opt.flag & PJSUA_CALL_REINIT_MEDIA) {
680     	pjsua_media_channel_deinit(call->index);
681     }
682 
683     /* If call is established or media channel hasn't been initialized,
684      * reinit media channel.
685      */
686     if ((call->inv && call->inv->state == PJSIP_INV_STATE_CONNECTING &&
687          call->med_cnt == 0) ||
688         (call->inv && call->inv->state == PJSIP_INV_STATE_CONFIRMED) ||
689         (call->opt.flag & PJSUA_CALL_REINIT_MEDIA))
690     {
691 	pjsip_role_e role = rem_sdp? PJSIP_ROLE_UAS : PJSIP_ROLE_UAC;
692 	pj_status_t status;
693 
694 	status = pjsua_media_channel_init(call->index, role,
695 					  call->secure_level,
696 					  call->inv->pool_prov,
697 					  rem_sdp, NULL,
698 					  PJ_FALSE, NULL);
699 	if (status != PJ_SUCCESS) {
700 	    pjsua_perror(THIS_FILE, "Error re-initializing media channel",
701 			 status);
702 	    return status;
703 	}
704     }
705 
706     return PJ_SUCCESS;
707 }
708 
dlg_set_via(pjsip_dialog * dlg,pjsua_acc * acc)709 static void dlg_set_via(pjsip_dialog *dlg, pjsua_acc *acc)
710 {
711     if (acc->cfg.allow_via_rewrite && acc->via_addr.host.slen > 0) {
712         pjsip_dlg_set_via_sent_by(dlg, &acc->via_addr, acc->via_tp);
713     } else if (!pjsua_sip_acc_is_using_stun(acc->index)) {
714    	/* Choose local interface to use in Via if acc is not using
715    	 * STUN. See https://trac.pjsip.org/repos/ticket/1804
716    	 */
717    	pjsip_host_port via_addr;
718    	const void *via_tp;
719 
720    	if (pjsua_acc_get_uac_addr(acc->index, dlg->pool, &acc->cfg.id,
721    				   &via_addr, NULL, NULL,
722    				   &via_tp) == PJ_SUCCESS)
723    	{
724    	    pjsip_dlg_set_via_sent_by(dlg, &via_addr,
725    	                              (pjsip_transport*)via_tp);
726    	}
727     }
728 }
729 
730 
dlg_set_target(pjsip_dialog * dlg,const pj_str_t * target)731 static pj_status_t dlg_set_target(pjsip_dialog *dlg, const pj_str_t *target)
732 {
733     pjsip_uri *target_uri;
734     pj_str_t tmp;
735     pj_status_t status;
736 
737     /* Parse target & verify */
738     pj_strdup_with_null(dlg->pool, &tmp, target);
739     target_uri = pjsip_parse_uri(dlg->pool, tmp.ptr, tmp.slen, 0);
740     if (!target_uri) {
741 	return PJSIP_EINVALIDURI;
742     }
743     if (!PJSIP_URI_SCHEME_IS_SIP(target_uri) &&
744 	!PJSIP_URI_SCHEME_IS_SIPS(target_uri))
745     {
746 	return PJSIP_EINVALIDSCHEME;
747     }
748 
749     /* Add the new target */
750     status = pjsip_target_set_add_uri(&dlg->target_set, dlg->pool,
751 				      target_uri, 0);
752     if (status != PJ_SUCCESS)
753 	return status;
754 
755     /* Set it as current target */
756     status = pjsip_target_set_set_current(&dlg->target_set,
757 			    pjsip_target_set_get_next(&dlg->target_set));
758     if (status != PJ_SUCCESS)
759 	return status;
760 
761     /* Update dialog target URI */
762     dlg->target = target_uri;
763 
764     return PJ_SUCCESS;
765 }
766 
767 
768 /* Get account contact for call and update dialog transport */
call_update_contact(pjsua_call * call,pj_str_t ** new_contact)769 void call_update_contact(pjsua_call *call, pj_str_t **new_contact)
770 {
771     pjsip_tpselector tp_sel;
772     pjsua_acc *acc = &pjsua_var.acc[call->acc_id];
773 
774     if (acc->cfg.force_contact.slen)
775 	*new_contact = &acc->cfg.force_contact;
776     else if (acc->contact.slen)
777 	*new_contact = &acc->contact;
778     else {
779 	/* Non-registering account */
780 	pjsip_dialog *dlg = call->inv->dlg;
781 	pj_str_t tmp_contact;
782 	pj_status_t status;
783 
784 	status = pjsua_acc_create_uac_contact(dlg->pool,
785 					      &tmp_contact,
786 					      acc->index,
787 					      &dlg->remote.info_str);
788 	if (status == PJ_SUCCESS) {
789 	    *new_contact = PJ_POOL_ZALLOC_T(dlg->pool, pj_str_t);
790 	    **new_contact = tmp_contact;
791 	} else {
792 	    PJ_PERROR(3,(THIS_FILE, status,
793 			 "Call %d: failed creating contact "
794 			 "for contact update", call->index));
795 	}
796     }
797 
798 
799     /* When contact is changed, the account transport may have been
800      * changed too, so let's update the dialog's transport too.
801      */
802     pjsua_init_tpselector(acc->cfg.transport_id, &tp_sel);
803     pjsip_dlg_set_transport(call->inv->dlg, &tp_sel);
804 }
805 
806 
807 
808 /*
809  * Make outgoing call to the specified URI using the specified account.
810  */
pjsua_call_make_call(pjsua_acc_id acc_id,const pj_str_t * dest_uri,const pjsua_call_setting * opt,void * user_data,const pjsua_msg_data * msg_data,pjsua_call_id * p_call_id)811 PJ_DEF(pj_status_t) pjsua_call_make_call(pjsua_acc_id acc_id,
812 					 const pj_str_t *dest_uri,
813 					 const pjsua_call_setting *opt,
814 					 void *user_data,
815 					 const pjsua_msg_data *msg_data,
816 					 pjsua_call_id *p_call_id)
817 {
818     pj_pool_t *tmp_pool = NULL;
819     pjsip_dialog *dlg = NULL;
820     pjsua_acc *acc;
821     pjsua_call *call;
822     int call_id = -1;
823     pj_str_t contact;
824     pj_status_t status;
825 
826     /* Check that account is valid */
827     PJ_ASSERT_RETURN(acc_id>=0 && acc_id<(int)PJ_ARRAY_SIZE(pjsua_var.acc),
828 		     PJ_EINVAL);
829 
830     /* Check arguments */
831     PJ_ASSERT_RETURN(dest_uri, PJ_EINVAL);
832 
833     PJ_LOG(4,(THIS_FILE, "Making call with acc #%d to %.*s", acc_id,
834 	      (int)dest_uri->slen, dest_uri->ptr));
835 
836     pj_log_push_indent();
837 
838     PJSUA_LOCK();
839 
840     acc = &pjsua_var.acc[acc_id];
841     if (!acc->valid) {
842 	pjsua_perror(THIS_FILE, "Unable to make call because account "
843 		     "is not valid", PJ_EINVALIDOP);
844 	status = PJ_EINVALIDOP;
845 	goto on_error;
846     }
847 
848     /* Find free call slot. */
849     call_id = alloc_call_id();
850 
851     if (call_id == PJSUA_INVALID_ID) {
852 	pjsua_perror(THIS_FILE, "Error making call", PJ_ETOOMANY);
853 	status = PJ_ETOOMANY;
854 	goto on_error;
855     }
856 
857     /* Clear call descriptor */
858     reset_call(call_id);
859 
860     call = &pjsua_var.calls[call_id];
861 
862     /* Associate session with account */
863     call->acc_id = acc_id;
864     call->call_hold_type = acc->cfg.call_hold_type;
865 
866     /* Generate per-session RTCP CNAME, according to RFC 7022. */
867     pj_create_random_string(call->cname_buf, call->cname.slen);
868 
869     /* Apply call setting */
870     status = apply_call_setting(call, opt, NULL);
871     if (status != PJ_SUCCESS) {
872 	pjsua_perror(THIS_FILE, "Failed to apply call setting", status);
873 	goto on_error;
874     }
875 
876     /* Create sound port if none is instantiated, to check if sound device
877      * can be used. But only do this with the conference bridge, as with
878      * audio switchboard (i.e. APS-Direct), we can only open the sound
879      * device once the correct format has been known
880      */
881     if (!pjsua_var.is_mswitch && pjsua_var.snd_port==NULL &&
882 	pjsua_var.null_snd==NULL && !pjsua_var.no_snd && call->opt.aud_cnt > 0)
883     {
884 	status = pjsua_set_snd_dev(pjsua_var.cap_dev, pjsua_var.play_dev);
885 	if (status != PJ_SUCCESS)
886 	    goto on_error;
887     }
888 
889     /* Create temporary pool */
890     tmp_pool = pjsua_pool_create("tmpcall10", 512, 256);
891 
892     /* Verify that destination URI is valid before calling
893      * pjsua_acc_create_uac_contact, or otherwise there
894      * a misleading "Invalid Contact URI" error will be printed
895      * when pjsua_acc_create_uac_contact() fails.
896      */
897     if (1) {
898 	pjsip_uri *uri;
899 	pj_str_t dup;
900 
901 	pj_strdup_with_null(tmp_pool, &dup, dest_uri);
902 	uri = pjsip_parse_uri(tmp_pool, dup.ptr, dup.slen, 0);
903 
904 	if (uri == NULL) {
905 	    pjsua_perror(THIS_FILE, "Unable to make call",
906 			 PJSIP_EINVALIDREQURI);
907 	    status = PJSIP_EINVALIDREQURI;
908 	    goto on_error;
909 	}
910     }
911 
912     /* Mark call start time. */
913     pj_gettimeofday(&call->start_time);
914 
915     /* Reset first response time */
916     call->res_time.sec = 0;
917 
918     /* Create suitable Contact header unless a Contact header has been
919      * set in the account.
920      */
921     if (acc->contact.slen) {
922 	contact = acc->contact;
923     } else {
924 	status = pjsua_acc_create_uac_contact(tmp_pool, &contact,
925 					      acc_id, dest_uri);
926 	if (status != PJ_SUCCESS) {
927 	    pjsua_perror(THIS_FILE, "Unable to generate Contact header",
928 			 status);
929 	    goto on_error;
930 	}
931     }
932 
933     /* Create outgoing dialog: */
934     status = pjsip_dlg_create_uac( pjsip_ua_instance(),
935 				   &acc->cfg.id, &contact,
936 				   dest_uri,
937                                    (msg_data && msg_data->target_uri.slen?
938                                     &msg_data->target_uri: dest_uri),
939                                    &dlg);
940     if (status != PJ_SUCCESS) {
941 	pjsua_perror(THIS_FILE, "Dialog creation failed", status);
942 	goto on_error;
943     }
944 
945     /* Increment the dialog's lock otherwise when invite session creation
946      * fails the dialog will be destroyed prematurely.
947      */
948     pjsip_dlg_inc_lock(dlg);
949 
950     dlg_set_via(dlg, acc);
951 
952     /* Calculate call's secure level */
953     call->secure_level = get_secure_level(acc_id, dest_uri);
954 
955     /* Attach user data */
956     call->user_data = user_data;
957 
958     /* Store variables required for the callback after the async
959      * media transport creation is completed.
960      */
961     if (msg_data) {
962 	call->async_call.call_var.out_call.msg_data = pjsua_msg_data_clone(
963                                                           dlg->pool, msg_data);
964     }
965     call->async_call.dlg = dlg;
966 
967     /* Temporarily increment dialog session. Without this, dialog will be
968      * prematurely destroyed if dec_lock() is called on the dialog before
969      * the invite session is created.
970      */
971     pjsip_dlg_inc_session(dlg, &pjsua_var.mod);
972 
973     if ((call->opt.flag & PJSUA_CALL_NO_SDP_OFFER) == 0) {
974         /* Init media channel */
975         status = pjsua_media_channel_init(call->index, PJSIP_ROLE_UAC,
976                                           call->secure_level, dlg->pool,
977                                           NULL, NULL, PJ_TRUE,
978                                           &on_make_call_med_tp_complete);
979     }
980     if (status == PJ_SUCCESS) {
981         status = on_make_call_med_tp_complete(call->index, NULL);
982         if (status != PJ_SUCCESS)
983 	    goto on_error;
984     } else if (status != PJ_EPENDING) {
985 	pjsua_perror(THIS_FILE, "Error initializing media channel", status);
986         pjsip_dlg_dec_session(dlg, &pjsua_var.mod);
987 	goto on_error;
988     }
989 
990     /* Done. */
991 
992     if (p_call_id)
993 	*p_call_id = call_id;
994 
995     pjsip_dlg_dec_lock(dlg);
996     pj_pool_release(tmp_pool);
997     PJSUA_UNLOCK();
998 
999     pj_log_pop_indent();
1000 
1001     return PJ_SUCCESS;
1002 
1003 
1004 on_error:
1005     if (dlg) {
1006 	/* This may destroy the dialog */
1007 	pjsip_dlg_dec_lock(dlg);
1008     }
1009 
1010     if (call_id != -1) {
1011 	pjsua_media_channel_deinit(call_id);
1012 	reset_call(call_id);
1013     }
1014 
1015     pjsua_check_snd_dev_idle();
1016 
1017     if (tmp_pool)
1018 	pj_pool_release(tmp_pool);
1019     PJSUA_UNLOCK();
1020 
1021     pj_log_pop_indent();
1022     return status;
1023 }
1024 
1025 
1026 /* Get the NAT type information in remote's SDP */
update_remote_nat_type(pjsua_call * call,const pjmedia_sdp_session * sdp)1027 static void update_remote_nat_type(pjsua_call *call,
1028 				   const pjmedia_sdp_session *sdp)
1029 {
1030     const pjmedia_sdp_attr *xnat;
1031 
1032     xnat = pjmedia_sdp_attr_find2(sdp->attr_count, sdp->attr, "X-nat", NULL);
1033     if (xnat) {
1034 	call->rem_nat_type = (pj_stun_nat_type) (xnat->value.ptr[0] - '0');
1035     } else {
1036 	call->rem_nat_type = PJ_STUN_NAT_TYPE_UNKNOWN;
1037     }
1038 
1039     PJ_LOG(5,(THIS_FILE, "Call %d: remote NAT type is %d (%s)", call->index,
1040 	      call->rem_nat_type, pj_stun_get_nat_name(call->rem_nat_type)));
1041 }
1042 
1043 
process_incoming_call_replace(pjsua_call * call,pjsip_dialog * replaced_dlg)1044 static pj_status_t process_incoming_call_replace(pjsua_call *call,
1045 						 pjsip_dialog *replaced_dlg)
1046 {
1047     pjsip_inv_session *replaced_inv;
1048     struct pjsua_call *replaced_call;
1049     pjsip_tx_data *tdata = NULL;
1050     pj_status_t status = PJ_SUCCESS;
1051 
1052     /* Get the invite session in the dialog */
1053     replaced_inv = pjsip_dlg_get_inv_session(replaced_dlg);
1054 
1055     /* Get the replaced call instance */
1056     replaced_call = (pjsua_call*) replaced_dlg->mod_data[pjsua_var.mod.id];
1057 
1058     /* Notify application */
1059     if (!replaced_call->hanging_up && pjsua_var.ua_cfg.cb.on_call_replaced)
1060 	pjsua_var.ua_cfg.cb.on_call_replaced(replaced_call->index,
1061 					     call->index);
1062 
1063     if (replaced_call->inv->state <= PJSIP_INV_STATE_EARLY &&
1064 	replaced_call->inv->role != PJSIP_ROLE_UAC)
1065     {
1066 	if (replaced_call->last_code > 100 && replaced_call->last_code < 200)
1067 	{
1068 	    pjsip_status_code code = replaced_call->last_code;
1069 	    pj_str_t *text = &replaced_call->last_text;
1070 
1071     	    PJ_LOG(4,(THIS_FILE, "Answering replacement call %d with %d/%.*s",
1072 				 call->index, code, text->slen, text->ptr));
1073 
1074 	    /* Answer the new call with last response in the replaced call */
1075 	    status = pjsip_inv_answer(call->inv, code, text, NULL, &tdata);
1076 	}
1077     } else {
1078     	PJ_LOG(4,(THIS_FILE, "Answering replacement call %d with 200/OK",
1079 			     call->index));
1080 
1081 	/* Answer the new call with 200 response */
1082 	status = pjsip_inv_answer(call->inv, 200, NULL, NULL, &tdata);
1083     }
1084 
1085     if (status == PJ_SUCCESS && tdata)
1086 	status = pjsip_inv_send_msg(call->inv, tdata);
1087 
1088     if (status != PJ_SUCCESS)
1089 	pjsua_perror(THIS_FILE, "Error answering session", status);
1090 
1091     /* Note that inv may be invalid if 200/OK has caused error in
1092      * starting the media.
1093      */
1094 
1095     PJ_LOG(4,(THIS_FILE, "Disconnecting replaced call %d",
1096 			 replaced_call->index));
1097 
1098     /* Disconnect replaced invite session */
1099     status = pjsip_inv_end_session(replaced_inv, PJSIP_SC_GONE, NULL,
1100 				   &tdata);
1101     if (status == PJ_SUCCESS && tdata)
1102 	status = pjsip_inv_send_msg(replaced_inv, tdata);
1103 
1104     if (status != PJ_SUCCESS)
1105 	pjsua_perror(THIS_FILE, "Error terminating session", status);
1106 
1107     return status;
1108 }
1109 
1110 
process_pending_call_answer(pjsua_call * call)1111 static void process_pending_call_answer(pjsua_call *call)
1112 {
1113     struct call_answer *answer, *next;
1114 
1115     /* No initial answer yet, this function should be called again later */
1116     if (!call->inv->last_answer)
1117 	return;
1118 
1119     answer = call->async_call.call_var.inc_call.answers.next;
1120     while (answer != &call->async_call.call_var.inc_call.answers) {
1121         next = answer->next;
1122 	pjsua_call_answer2(call->index, answer->opt, answer->code,
1123 			   answer->reason, answer->msg_data);
1124 
1125         /* Call might have been disconnected if application is answering
1126          * with 200/OK and the media failed to start.
1127          * See pjsua_call_answer() below.
1128          */
1129         if (!call->inv || !call->inv->pool_prov)
1130             break;
1131 
1132         pj_list_erase(answer);
1133         answer = next;
1134     }
1135 }
1136 
create_temp_sdp(pj_pool_t * pool,const pjmedia_sdp_session * rem_sdp,pjmedia_sdp_session ** p_sdp)1137 pj_status_t create_temp_sdp(pj_pool_t *pool,
1138 			    const pjmedia_sdp_session *rem_sdp,
1139     			    pjmedia_sdp_session **p_sdp)
1140 {
1141     const pj_str_t STR_AUDIO = { "audio", 5 };
1142     const pj_str_t STR_VIDEO = { "video", 5 };
1143     const pj_str_t STR_IP6 = { "IP6", 3};
1144 
1145     pjmedia_sdp_session *sdp;
1146     pj_sockaddr origin;
1147     pj_uint16_t tmp_port = 50123;
1148     pj_status_t status = PJ_SUCCESS;
1149     pj_str_t tmp_st;
1150     unsigned i = 0;
1151     pj_bool_t sess_use_ipv4 = PJ_TRUE;
1152 
1153     /* Get one address to use in the origin field */
1154     pj_sockaddr_init(PJ_AF_INET, &origin, pj_strset2(&tmp_st, "127.0.0.1"), 0);
1155 
1156     /* Create the base (blank) SDP */
1157     status = pjmedia_endpt_create_base_sdp(pjsua_var.med_endpt, pool, NULL,
1158                                            &origin, &sdp);
1159     if (status != PJ_SUCCESS)
1160 	return status;
1161 
1162     if (rem_sdp->conn && pj_stricmp(&rem_sdp->conn->addr_type, &STR_IP6)==0) {
1163 	sess_use_ipv4 = PJ_FALSE;
1164     }
1165 
1166     for (; i< rem_sdp->media_count ; ++i) {
1167 	pjmedia_sdp_media *m = NULL;
1168 	pjmedia_sock_info sock_info;
1169 	pj_bool_t med_use_ipv4 = sess_use_ipv4;
1170 
1171 	if (rem_sdp->media[i]->conn &&
1172 	    pj_stricmp(&rem_sdp->media[i]->conn->addr_type, &STR_IP6) == 0)
1173 	{
1174 	    med_use_ipv4 = PJ_FALSE;
1175 	}
1176 
1177 	pj_sockaddr_init(med_use_ipv4?PJ_AF_INET:PJ_AF_INET6,
1178 			 &sock_info.rtp_addr_name,
1179 			 med_use_ipv4?pj_strset2(&tmp_st, "127.0.0.1"):
1180 				      pj_strset2(&tmp_st, "::1"),
1181 			 rem_sdp->media[i]->desc.port? (tmp_port++):0);
1182 
1183 	pj_sockaddr_init(med_use_ipv4?PJ_AF_INET:PJ_AF_INET6,
1184 			 &sock_info.rtcp_addr_name,
1185 			 med_use_ipv4?pj_strset2(&tmp_st, "127.0.0.1"):
1186 				      pj_strset2(&tmp_st, "::1"),
1187 			 rem_sdp->media[i]->desc.port? (tmp_port++):0);
1188 
1189 	if (pj_stricmp(&rem_sdp->media[i]->desc.media, &STR_AUDIO)==0) {
1190 	    m = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_media);
1191 	    status = pjmedia_endpt_create_audio_sdp(pjsua_var.med_endpt,
1192 						    pool, &sock_info, 0, &m);
1193 
1194 	    if (status != PJ_SUCCESS)
1195 		return status;
1196 
1197 	} else if (pj_stricmp(&rem_sdp->media[i]->desc.media, &STR_VIDEO)==0) {
1198 #if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0)
1199 	    m = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_media);
1200 	    status = pjmedia_endpt_create_video_sdp(pjsua_var.med_endpt, pool,
1201 						    &sock_info, 0, &m);
1202 	    if (status != PJ_SUCCESS)
1203 		return status;
1204 #else
1205 	    m = pjmedia_sdp_media_clone_deactivate(pool, rem_sdp->media[i]);
1206 #endif
1207 	} else {
1208 	    m = pjmedia_sdp_media_clone_deactivate(pool, rem_sdp->media[i]);
1209 	}
1210 	if (status != PJ_SUCCESS)
1211 	    return status;
1212 
1213 	/* Add connection line, if none */
1214 	if (m->conn == NULL && sdp->conn == NULL) {
1215 	    m->conn = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_conn);
1216 	    m->conn->net_type = pj_str("IN");
1217 	    if (med_use_ipv4) {
1218 		m->conn->addr_type = pj_str("IP4");
1219 		m->conn->addr = pj_str("127.0.0.1");
1220 	    } else {
1221 		m->conn->addr_type = pj_str("IP6");
1222 		m->conn->addr = pj_str("::1");
1223 	    }
1224 	}
1225 
1226 	/* Disable media if it has zero format/codec */
1227 	if (m->desc.fmt_count == 0) {
1228 	    m->desc.fmt[m->desc.fmt_count++] = pj_str("0");
1229 	    pjmedia_sdp_media_deactivate(pool, m);
1230 	}
1231 
1232 	sdp->media[sdp->media_count++] = m;
1233     }
1234 
1235     *p_sdp = sdp;
1236     return PJ_SUCCESS;
1237 }
1238 
verify_request(const pjsua_call * call,pjsip_rx_data * rdata,pj_bool_t use_tmp_sdp,int * sip_err_code,pjsip_tx_data ** response)1239 static pj_status_t verify_request(const pjsua_call *call,
1240 				  pjsip_rx_data *rdata,
1241 				  pj_bool_t use_tmp_sdp,
1242 				  int *sip_err_code,
1243 				  pjsip_tx_data **response)
1244 {
1245     const pjmedia_sdp_session *offer = NULL;
1246     pjmedia_sdp_session *answer;
1247     int err_code = 0;
1248     pj_status_t status;
1249 
1250     /* Get remote SDP offer (if any). */
1251     if (call->inv->neg)
1252     {
1253 	pjmedia_sdp_neg_get_neg_remote(call->inv->neg, &offer);
1254     }
1255 
1256     if (use_tmp_sdp) {
1257 	if (offer == NULL)
1258 	    return PJ_SUCCESS;
1259 
1260 	/* Create temporary SDP to check for codec support and capability
1261 	 * to handle the required SIP extensions.
1262 	 */
1263 	status = create_temp_sdp(call->inv->pool_prov, offer, &answer);
1264 
1265 	if (status != PJ_SUCCESS) {
1266 	    err_code = PJSIP_SC_INTERNAL_SERVER_ERROR;
1267 	    pjsua_perror(THIS_FILE, "Error creating SDP answer", status);
1268 	}
1269     } else {
1270 	status = pjsua_media_channel_create_sdp(call->index,
1271 						call->async_call.dlg->pool,
1272 						offer, &answer, sip_err_code);
1273 
1274 	if (status != PJ_SUCCESS) {
1275 	    err_code = *sip_err_code;
1276 	    pjsua_perror(THIS_FILE, "Error creating SDP answer", status);
1277 	} else {
1278 	    status = pjsip_inv_set_local_sdp(call->inv, answer);
1279 	    if (status != PJ_SUCCESS) {
1280 		err_code = PJSIP_SC_NOT_ACCEPTABLE_HERE;
1281 		pjsua_perror(THIS_FILE, "Error setting local SDP", status);
1282 	    }
1283 	}
1284     }
1285 
1286     if (status == PJ_SUCCESS) {
1287 	unsigned options = 0;
1288 
1289 	/* Verify that we can handle the request. */
1290 	status = pjsip_inv_verify_request3(rdata,
1291 					   call->inv->pool_prov, &options,
1292 					   offer, answer, NULL,
1293 					   pjsua_var.endpt, response);
1294 	if (status != PJ_SUCCESS) {
1295 	    /*
1296 	     * No we can't handle the incoming INVITE request.
1297 	     */
1298 	    pjsua_perror(THIS_FILE, "Request verification failed", status);
1299 
1300 	    if (response)
1301 		err_code = (*response)->msg->line.status.code;
1302 	    else
1303 		err_code = PJSIP_SC_NOT_ACCEPTABLE_HERE;
1304 	}
1305     }
1306 
1307     if (sip_err_code && status != PJ_SUCCESS)
1308 	*sip_err_code = err_code? err_code:PJSIP_ERRNO_TO_SIP_STATUS(status);
1309 
1310     return status;
1311 }
1312 
1313 /* Incoming call callback when media transport creation is completed. */
1314 static pj_status_t
on_incoming_call_med_tp_complete2(pjsua_call_id call_id,const pjsua_med_tp_state_info * info,pjsip_rx_data * rdata,int * sip_err_code,pjsip_tx_data ** tdata)1315 on_incoming_call_med_tp_complete2(pjsua_call_id call_id,
1316 				  const pjsua_med_tp_state_info *info,
1317 				  pjsip_rx_data *rdata,
1318 				  int *sip_err_code,
1319 				  pjsip_tx_data **tdata)
1320 {
1321     pjsua_call *call = &pjsua_var.calls[call_id];
1322     pjsip_dialog *dlg = call->async_call.dlg;
1323     pj_status_t status = (info? info->status: PJ_SUCCESS);
1324     int err_code = (info? info->sip_err_code: 0);
1325     pjsip_tx_data *response = NULL;
1326 
1327     PJSUA_LOCK();
1328 
1329     /* Increment the dialog's lock to prevent it to be destroyed prematurely,
1330      * such as in case of transport error.
1331      */
1332     pjsip_dlg_inc_lock(dlg);
1333 
1334     /* Decrement dialog session. */
1335     pjsip_dlg_dec_session(dlg, &pjsua_var.mod);
1336 
1337     if (status != PJ_SUCCESS) {
1338 	pjsua_perror(THIS_FILE, "Error initializing media channel", status);
1339         goto on_return;
1340     }
1341 
1342     /* pjsua_media_channel_deinit() has been called. */
1343     if (call->async_call.med_ch_deinit) {
1344         pjsua_media_channel_deinit(call->index);
1345         call->med_ch_cb = NULL;
1346         pjsip_dlg_dec_lock(dlg);
1347         PJSUA_UNLOCK();
1348         return PJ_SUCCESS;
1349     }
1350 
1351     status = verify_request(call, rdata, PJ_FALSE, &err_code, &response);
1352 
1353 on_return:
1354     if (status != PJ_SUCCESS) {
1355 	if (err_code == 0)
1356 	    err_code = PJSIP_ERRNO_TO_SIP_STATUS(status);
1357 
1358 	if (sip_err_code)
1359 	    *sip_err_code = err_code;
1360 
1361         /* If the callback is called from pjsua_call_on_incoming(), the
1362          * invite's state is PJSIP_INV_STATE_NULL, so the invite session
1363          * will be terminated later, otherwise we end the session here.
1364          */
1365         if (call->inv->state > PJSIP_INV_STATE_NULL) {
1366             pj_status_t status_ = PJ_SUCCESS;
1367 
1368 	    if (response == NULL) {
1369 		status_ = pjsip_inv_end_session(call->inv, err_code, NULL,
1370 						&response);
1371 	    }
1372 
1373 	    if (status_ == PJ_SUCCESS && response)
1374 	        status_ = pjsip_inv_send_msg(call->inv, response);
1375 	}
1376         pjsua_media_channel_deinit(call->index);
1377     }
1378 
1379     /* Set the callback to NULL to indicate that the async operation
1380      * has completed.
1381      */
1382     call->med_ch_cb = NULL;
1383 
1384     /* Finish any pending process */
1385     if (status == PJ_SUCCESS) {
1386 	if (call->async_call.call_var.inc_call.replaced_dlg) {
1387 	    /* Process pending call replace */
1388 	    pjsip_dialog *replaced_dlg =
1389 			call->async_call.call_var.inc_call.replaced_dlg;
1390 	    process_incoming_call_replace(call, replaced_dlg);
1391 	} else {
1392 	    /* Process pending call answers */
1393 	    process_pending_call_answer(call);
1394 	}
1395     }
1396 
1397     pjsip_dlg_dec_lock(dlg);
1398 
1399     if (tdata)
1400 	*tdata = response;
1401 
1402     PJSUA_UNLOCK();
1403     return status;
1404 }
1405 
1406 static pj_status_t
on_incoming_call_med_tp_complete(pjsua_call_id call_id,const pjsua_med_tp_state_info * info)1407 on_incoming_call_med_tp_complete(pjsua_call_id call_id,
1408 				 const pjsua_med_tp_state_info *info)
1409 {
1410     return on_incoming_call_med_tp_complete2(call_id, info, NULL, NULL, NULL);
1411 }
1412 
1413 
1414 /**
1415  * Handle incoming INVITE request.
1416  * Called by pjsua_core.c
1417  */
pjsua_call_on_incoming(pjsip_rx_data * rdata)1418 pj_bool_t pjsua_call_on_incoming(pjsip_rx_data *rdata)
1419 {
1420     pj_str_t contact;
1421     pjsip_dialog *dlg = pjsip_rdata_get_dlg(rdata);
1422     pjsip_dialog *replaced_dlg = NULL;
1423     pjsip_transaction *tsx = pjsip_rdata_get_tsx(rdata);
1424     pjsip_msg *msg = rdata->msg_info.msg;
1425     pjsip_tx_data *response = NULL;
1426     unsigned options = 0;
1427     pjsip_inv_session *inv = NULL;
1428     int acc_id;
1429     pjsua_call *call = NULL;
1430     int call_id = -1;
1431     int sip_err_code = PJSIP_SC_INTERNAL_SERVER_ERROR;
1432     pjmedia_sdp_session *offer=NULL;
1433     pj_bool_t should_dec_dlg = PJ_FALSE;
1434     pj_status_t status;
1435 
1436     /* Don't want to handle anything but INVITE */
1437     if (msg->line.req.method.id != PJSIP_INVITE_METHOD)
1438 	return PJ_FALSE;
1439 
1440     /* Don't want to handle anything that's already associated with
1441      * existing dialog or transaction.
1442      */
1443     if (dlg || tsx)
1444 	return PJ_FALSE;
1445 
1446     /* Don't want to accept the call if shutdown is in progress */
1447     if (pjsua_var.thread_quit_flag) {
1448 	pjsip_endpt_respond_stateless(pjsua_var.endpt, rdata,
1449 				      PJSIP_SC_TEMPORARILY_UNAVAILABLE, NULL,
1450 				      NULL, NULL);
1451 	return PJ_TRUE;
1452     }
1453 
1454     PJ_LOG(4,(THIS_FILE, "Incoming %s", rdata->msg_info.info));
1455     pj_log_push_indent();
1456 
1457     PJSUA_LOCK();
1458 
1459     /* Find free call slot. */
1460     call_id = alloc_call_id();
1461 
1462     if (call_id == PJSUA_INVALID_ID) {
1463 	pjsip_endpt_respond_stateless(pjsua_var.endpt, rdata,
1464 				      PJSIP_SC_BUSY_HERE, NULL,
1465 				      NULL, NULL);
1466 	PJ_LOG(2,(THIS_FILE,
1467 		  "Unable to accept incoming call (too many calls)"));
1468 	goto on_return;
1469     }
1470 
1471     /* Clear call descriptor */
1472     reset_call(call_id);
1473 
1474     call = &pjsua_var.calls[call_id];
1475 
1476     /* Generate per-session RTCP CNAME, according to RFC 7022. */
1477     pj_create_random_string(call->cname_buf, call->cname.slen);
1478 
1479     /* Mark call start time. */
1480     pj_gettimeofday(&call->start_time);
1481 
1482     /* Check INVITE request for Replaces header. If Replaces header is
1483      * present, the function will make sure that we can handle the request.
1484      */
1485     status = pjsip_replaces_verify_request(rdata, &replaced_dlg, PJ_FALSE,
1486 					   &response);
1487     if (status != PJ_SUCCESS) {
1488 	/*
1489 	 * Something wrong with the Replaces header.
1490 	 */
1491 	if (response) {
1492 	    pjsip_response_addr res_addr;
1493 
1494 	    pjsip_get_response_addr(response->pool, rdata, &res_addr);
1495 	    pjsip_endpt_send_response(pjsua_var.endpt, &res_addr, response,
1496 				      NULL, NULL);
1497 
1498 	} else {
1499 
1500 	    /* Respond with 500 (Internal Server Error) */
1501 	    pjsip_endpt_respond_stateless(pjsua_var.endpt, rdata, 500, NULL,
1502 					  NULL, NULL);
1503 	}
1504 
1505 	goto on_return;
1506     }
1507 
1508     /* If this INVITE request contains Replaces header, notify application
1509      * about the request so that application can do subsequent checking
1510      * if it wants to.
1511      */
1512     if (replaced_dlg != NULL &&
1513 	(pjsua_var.ua_cfg.cb.on_call_replace_request ||
1514 	 pjsua_var.ua_cfg.cb.on_call_replace_request2))
1515     {
1516 	pjsua_call *replaced_call;
1517 	int st_code = 200;
1518 	pj_str_t st_text = { "OK", 2 };
1519 
1520 	/* Get the replaced call instance */
1521 	replaced_call = (pjsua_call*) replaced_dlg->mod_data[pjsua_var.mod.id];
1522 
1523 	/* Copy call setting from the replaced call */
1524 	call->opt = replaced_call->opt;
1525 	pjsua_call_cleanup_flag(&call->opt);
1526 
1527 	/* Notify application */
1528 	if (!replaced_call->hanging_up &&
1529 	    pjsua_var.ua_cfg.cb.on_call_replace_request)
1530 	{
1531 	    pjsua_var.ua_cfg.cb.on_call_replace_request(replaced_call->index,
1532 							rdata,
1533 							&st_code, &st_text);
1534 	}
1535 
1536 	if (!replaced_call->hanging_up &&
1537 	    pjsua_var.ua_cfg.cb.on_call_replace_request2)
1538 	{
1539 	    pjsua_var.ua_cfg.cb.on_call_replace_request2(replaced_call->index,
1540 							 rdata,
1541 							 &st_code, &st_text,
1542 							 &call->opt);
1543 	}
1544 
1545 	/* Must specify final response */
1546 	PJ_ASSERT_ON_FAIL(st_code >= 200, st_code = 200);
1547 
1548 	/* Check if application rejects this request. */
1549 	if (st_code >= 300) {
1550 
1551 	    if (st_text.slen == 2)
1552 		st_text = *pjsip_get_status_text(st_code);
1553 
1554 	    pjsip_endpt_respond(pjsua_var.endpt, NULL, rdata,
1555 				st_code, &st_text, NULL, NULL, NULL);
1556 	    goto on_return;
1557 	}
1558     }
1559 
1560     if (!replaced_dlg) {
1561 	/* Clone rdata. */
1562 	pjsip_rx_data_clone(rdata, 0, &call->incoming_data);
1563     }
1564 
1565     /*
1566      * Get which account is most likely to be associated with this incoming
1567      * call. We need the account to find which contact URI to put for
1568      * the call.
1569      */
1570     acc_id = call->acc_id = pjsua_acc_find_for_incoming(rdata);
1571     if (acc_id == PJSUA_INVALID_ID) {
1572 	pjsip_endpt_respond_stateless(pjsua_var.endpt, rdata,
1573 				      PJSIP_SC_TEMPORARILY_UNAVAILABLE, NULL,
1574 				      NULL, NULL);
1575 
1576 	PJ_LOG(2,(THIS_FILE,
1577 		  "Unable to accept incoming call (no available account)"));
1578 
1579 	goto on_return;
1580     }
1581     call->call_hold_type = pjsua_var.acc[acc_id].cfg.call_hold_type;
1582 
1583     /* Get call's secure level */
1584     if (PJSIP_URI_SCHEME_IS_SIPS(rdata->msg_info.msg->line.req.uri))
1585 	call->secure_level = 2;
1586     else if (PJSIP_TRANSPORT_IS_SECURE(rdata->tp_info.transport))
1587 	call->secure_level = 1;
1588     else
1589 	call->secure_level = 0;
1590 
1591     /* Parse SDP from incoming request */
1592     if (rdata->msg_info.msg->body) {
1593 	pjsip_rdata_sdp_info *sdp_info;
1594 
1595 	sdp_info = pjsip_rdata_get_sdp_info(rdata);
1596 	offer = sdp_info->sdp;
1597 
1598 	status = sdp_info->sdp_err;
1599 	if (status==PJ_SUCCESS && sdp_info->sdp==NULL &&
1600 	    !PJSIP_INV_ACCEPT_UNKNOWN_BODY)
1601 	{
1602 	    if (sdp_info->body.ptr == NULL) {
1603 		status = PJSIP_ERRNO_FROM_SIP_STATUS(
1604 					       PJSIP_SC_UNSUPPORTED_MEDIA_TYPE);
1605 	    } else {
1606 		status = PJSIP_ERRNO_FROM_SIP_STATUS(PJSIP_SC_NOT_ACCEPTABLE);
1607 	    }
1608 	}
1609 
1610 	if (status != PJ_SUCCESS) {
1611 	    pjsip_hdr hdr_list;
1612 
1613 	    /* Check if body really contains SDP. */
1614 	    if (sdp_info->body.ptr == NULL) {
1615 		/* Couldn't find "application/sdp" */
1616 		pjsip_accept_hdr *acc;
1617 
1618 		pjsua_perror(THIS_FILE, "Unknown Content-Type in incoming "\
1619 		             "INVITE", status);
1620 
1621 		/* Add Accept header to response */
1622 		acc = pjsip_accept_hdr_create(rdata->tp_info.pool);
1623 		PJ_ASSERT_RETURN(acc, PJ_ENOMEM);
1624 		acc->values[acc->count++] = pj_str("application/sdp");
1625 		pj_list_init(&hdr_list);
1626 		pj_list_push_back(&hdr_list, acc);
1627 
1628 		pjsip_endpt_respond(pjsua_var.endpt, NULL, rdata,
1629 				    PJSIP_SC_UNSUPPORTED_MEDIA_TYPE,
1630 				    NULL, &hdr_list, NULL, NULL);
1631 	    } else {
1632 		const pj_str_t reason = pj_str("Bad SDP");
1633 		pjsip_warning_hdr *w;
1634 
1635 		pjsua_perror(THIS_FILE, "Bad SDP in incoming INVITE",
1636 			     status);
1637 
1638 		w = pjsip_warning_hdr_create_from_status(rdata->tp_info.pool,
1639 					      pjsip_endpt_name(pjsua_var.endpt),
1640 					      status);
1641 		pj_list_init(&hdr_list);
1642 		pj_list_push_back(&hdr_list, w);
1643 
1644 		pjsip_endpt_respond(pjsua_var.endpt, NULL, rdata, 400,
1645 				    &reason, &hdr_list, NULL, NULL);
1646 	    }
1647 	    goto on_return;
1648 	}
1649 
1650 	/* Do quick checks on SDP before passing it to transports. More elabore
1651 	 * checks will be done in pjsip_inv_verify_request2() below.
1652 	 */
1653 	if ((offer) && (offer->media_count==0)) {
1654 	    const pj_str_t reason = pj_str("Missing media in SDP");
1655 	    pjsip_endpt_respond(pjsua_var.endpt, NULL, rdata, 400, &reason,
1656 				NULL, NULL, NULL);
1657 	    goto on_return;
1658 	}
1659 
1660     } else {
1661 	offer = NULL;
1662     }
1663 
1664     /* Verify that we can handle the request. */
1665     options |= PJSIP_INV_SUPPORT_100REL;
1666     options |= PJSIP_INV_SUPPORT_TIMER;
1667     if (pjsua_var.acc[acc_id].cfg.require_100rel == PJSUA_100REL_MANDATORY)
1668 	options |= PJSIP_INV_REQUIRE_100REL;
1669     if (pjsua_var.acc[acc_id].cfg.ice_cfg.enable_ice) {
1670 	options |= PJSIP_INV_SUPPORT_ICE;
1671 	if (pjsua_var.acc[acc_id].cfg.ice_cfg.ice_opt.trickle !=
1672 	    PJ_ICE_SESS_TRICKLE_DISABLED)
1673 	{
1674 	    options |= PJSIP_INV_SUPPORT_TRICKLE_ICE;
1675 	}
1676     }
1677     if (pjsua_var.acc[acc_id].cfg.use_timer == PJSUA_SIP_TIMER_REQUIRED)
1678 	options |= PJSIP_INV_REQUIRE_TIMER;
1679     else if (pjsua_var.acc[acc_id].cfg.use_timer == PJSUA_SIP_TIMER_ALWAYS)
1680 	options |= PJSIP_INV_ALWAYS_USE_TIMER;
1681 
1682     status = pjsip_inv_verify_request2(rdata, &options, offer, NULL, NULL,
1683 				       pjsua_var.endpt, &response);
1684     if (status != PJ_SUCCESS) {
1685 
1686 	/*
1687 	 * No we can't handle the incoming INVITE request.
1688 	 */
1689 	if (response) {
1690 	    pjsip_response_addr res_addr;
1691 
1692 	    pjsip_get_response_addr(response->pool, rdata, &res_addr);
1693 	    pjsip_endpt_send_response(pjsua_var.endpt, &res_addr, response,
1694 				      NULL, NULL);
1695 
1696 	} else {
1697 	    /* Respond with 500 (Internal Server Error) */
1698 	    pjsip_endpt_respond(pjsua_var.endpt, NULL, rdata, 500, NULL,
1699 				NULL, NULL, NULL);
1700 	}
1701 
1702 	goto on_return;
1703     }
1704 
1705     /* Get suitable Contact header */
1706     if (pjsua_var.acc[acc_id].contact.slen) {
1707 	contact = pjsua_var.acc[acc_id].contact;
1708     } else {
1709 	status = pjsua_acc_create_uas_contact(rdata->tp_info.pool, &contact,
1710 					      acc_id, rdata);
1711 	if (status != PJ_SUCCESS) {
1712 	    pjsua_perror(THIS_FILE, "Unable to generate Contact header",
1713 			 status);
1714 	    pjsip_endpt_respond_stateless(pjsua_var.endpt, rdata, 500, NULL,
1715 					  NULL, NULL);
1716 	    goto on_return;
1717 	}
1718     }
1719 
1720     /* Create dialog: */
1721     status = pjsip_dlg_create_uas_and_inc_lock( pjsip_ua_instance(), rdata,
1722 				   		&contact, &dlg);
1723     if (status != PJ_SUCCESS) {
1724 	pjsip_endpt_respond_stateless(pjsua_var.endpt, rdata, 500, NULL,
1725 				      NULL, NULL);
1726 	goto on_return;
1727     }
1728 
1729     if (pjsua_var.acc[acc_id].cfg.allow_via_rewrite &&
1730         pjsua_var.acc[acc_id].via_addr.host.slen > 0)
1731     {
1732         pjsip_dlg_set_via_sent_by(dlg, &pjsua_var.acc[acc_id].via_addr,
1733                                   pjsua_var.acc[acc_id].via_tp);
1734     } else if (!pjsua_sip_acc_is_using_stun(acc_id)) {
1735 	/* Choose local interface to use in Via if acc is not using
1736 	 * STUN. See https://trac.pjsip.org/repos/ticket/1804
1737 	 */
1738 	char target_buf[PJSIP_MAX_URL_SIZE];
1739 	pj_str_t target;
1740 	pjsip_host_port via_addr;
1741 	const void *via_tp;
1742 
1743 	target.ptr = target_buf;
1744 	target.slen = pjsip_uri_print(PJSIP_URI_IN_REQ_URI,
1745 	                              dlg->target,
1746 	                              target_buf, sizeof(target_buf));
1747 	if (target.slen < 0) target.slen = 0;
1748 
1749 	if (pjsua_acc_get_uac_addr(acc_id, dlg->pool, &target,
1750 				   &via_addr, NULL, NULL,
1751 				   &via_tp) == PJ_SUCCESS)
1752 	{
1753 	    pjsip_dlg_set_via_sent_by(dlg, &via_addr,
1754 				      (pjsip_transport*)via_tp);
1755 	}
1756     }
1757 
1758     /* Set credentials */
1759     if (pjsua_var.acc[acc_id].cred_cnt) {
1760 	pjsip_auth_clt_set_credentials(&dlg->auth_sess,
1761 				       pjsua_var.acc[acc_id].cred_cnt,
1762 				       pjsua_var.acc[acc_id].cred);
1763     }
1764 
1765     /* Set preference */
1766     pjsip_auth_clt_set_prefs(&dlg->auth_sess,
1767 			     &pjsua_var.acc[acc_id].cfg.auth_pref);
1768 
1769     /* Disable Session Timers if not prefered and the incoming INVITE request
1770      * did not require it.
1771      */
1772     if (pjsua_var.acc[acc_id].cfg.use_timer == PJSUA_SIP_TIMER_INACTIVE &&
1773 	(options & PJSIP_INV_REQUIRE_TIMER) == 0)
1774     {
1775 	options &= ~(PJSIP_INV_SUPPORT_TIMER);
1776     }
1777 
1778     /* If 100rel is optional and UAC supports it, use it. */
1779     if ((options & PJSIP_INV_REQUIRE_100REL)==0 &&
1780 	pjsua_var.acc[acc_id].cfg.require_100rel == PJSUA_100REL_OPTIONAL)
1781     {
1782 	const pj_str_t token = { "100rel", 6};
1783 	pjsip_dialog_cap_status cap_status;
1784 
1785 	cap_status = pjsip_dlg_remote_has_cap(dlg, PJSIP_H_SUPPORTED, NULL,
1786 	                                      &token);
1787 	if (cap_status == PJSIP_DIALOG_CAP_SUPPORTED)
1788 	    options |= PJSIP_INV_REQUIRE_100REL;
1789     }
1790 
1791     /* Create invite session: */
1792     status = pjsip_inv_create_uas( dlg, rdata, NULL, options, &inv);
1793     if (status != PJ_SUCCESS) {
1794 	pjsip_hdr hdr_list;
1795 	pjsip_warning_hdr *w;
1796 
1797 	w = pjsip_warning_hdr_create_from_status(dlg->pool,
1798 						 pjsip_endpt_name(pjsua_var.endpt),
1799 						 status);
1800 	pj_list_init(&hdr_list);
1801 	pj_list_push_back(&hdr_list, w);
1802 
1803 	pjsip_dlg_respond(dlg, rdata, 500, NULL, &hdr_list, NULL);
1804 
1805 	/* Can't terminate dialog because transaction is in progress.
1806 	pjsip_dlg_terminate(dlg);
1807 	 */
1808 	goto on_return;
1809     }
1810 
1811     /* If account is locked to specific transport, then lock dialog
1812      * to this transport too.
1813      */
1814     if (pjsua_var.acc[acc_id].cfg.transport_id != PJSUA_INVALID_ID) {
1815 	pjsip_tpselector tp_sel;
1816 
1817 	pjsua_init_tpselector(pjsua_var.acc[acc_id].cfg.transport_id, &tp_sel);
1818 	pjsip_dlg_set_transport(dlg, &tp_sel);
1819     }
1820 
1821     /* Create and attach pjsua_var data to the dialog */
1822     call->inv = inv;
1823 
1824     /* Store variables required for the callback after the async
1825      * media transport creation is completed.
1826      */
1827     call->async_call.dlg = dlg;
1828     pj_list_init(&call->async_call.call_var.inc_call.answers);
1829 
1830     pjsip_dlg_inc_session(dlg, &pjsua_var.mod);
1831     should_dec_dlg = PJ_TRUE;
1832 
1833     /* Init media channel, only when there is offer or call replace request.
1834      * For incoming call without SDP offer, media channel init will be done
1835      * in pjsua_call_answer(), see ticket #1526.
1836      */
1837     if (offer || replaced_dlg) {
1838 
1839 	/* This is only for initial verification, it will check the SDP for
1840 	 * codec support and the capability to handle the required
1841 	 * SIP extensions.
1842 	 */
1843 	status = verify_request(call, rdata, PJ_TRUE, &sip_err_code,
1844 				&response);
1845 
1846 	if (status != PJ_SUCCESS) {
1847 	    pjsip_dlg_inc_lock(dlg);
1848 
1849 	    if (response) {
1850 		pjsip_dlg_send_response(dlg, call->inv->invite_tsx, response);
1851 	    } else {
1852 		pjsip_dlg_respond(dlg, rdata, sip_err_code, NULL, NULL, NULL);
1853 	    }
1854 
1855 	    if (call->inv && call->inv->dlg) {
1856 		pjsip_inv_terminate(call->inv, sip_err_code, PJ_FALSE);
1857 	    }
1858 	    pjsip_dlg_dec_lock(dlg);
1859 
1860 	    call->inv = NULL;
1861 	    call->async_call.dlg = NULL;
1862 	    goto on_return;
1863 	}
1864 	status = pjsua_media_channel_init(call->index, PJSIP_ROLE_UAS,
1865 					  call->secure_level,
1866 					  rdata->tp_info.pool,
1867 					  offer,
1868 					  &sip_err_code, PJ_TRUE,
1869 					  &on_incoming_call_med_tp_complete);
1870 	if (status == PJ_EPENDING) {
1871 	    /* on_incoming_call_med_tp_complete() will call
1872 	     * pjsip_dlg_dec_session().
1873 	     */
1874 	    should_dec_dlg = PJ_FALSE;
1875 	} else  if (status == PJ_SUCCESS) {
1876 	    /* on_incoming_call_med_tp_complete2() will call
1877 	     * pjsip_dlg_dec_session().
1878 	     */
1879 	    should_dec_dlg = PJ_FALSE;
1880 
1881 	    status = on_incoming_call_med_tp_complete2(call_id, NULL,
1882 						       rdata, &sip_err_code,
1883 						       &response);
1884 	    if (status != PJ_SUCCESS) {
1885 		/* Since the call invite's state is still PJSIP_INV_STATE_NULL,
1886 		 * the invite session was not ended in
1887 		 * on_incoming_call_med_tp_complete(), so we need to send
1888 		 * a response message and terminate the invite here.
1889 		 */
1890 		pjsip_dlg_inc_lock(dlg);
1891 
1892 		if (response) {
1893 		    pjsip_dlg_send_response(dlg, call->inv->invite_tsx,
1894 					    response);
1895 
1896 		} else {
1897 		    pjsip_dlg_respond(dlg, rdata, sip_err_code, NULL, NULL,
1898 				      NULL);
1899 		}
1900 
1901 		if (call->inv && call->inv->dlg) {
1902 		    pjsip_inv_terminate(call->inv, sip_err_code, PJ_FALSE);
1903 		}
1904 		pjsip_dlg_dec_lock(dlg);
1905 
1906 		call->inv = NULL;
1907 		call->async_call.dlg = NULL;
1908 		goto on_return;
1909 	    }
1910 	} else if (status != PJ_EPENDING) {
1911 	    pjsua_perror(THIS_FILE, "Error initializing media channel", status);
1912 
1913 	    pjsip_dlg_inc_lock(dlg);
1914 	    pjsip_dlg_respond(dlg, rdata, sip_err_code, NULL, NULL, NULL);
1915 	    if (call->inv && call->inv->dlg) {
1916 		pjsip_inv_terminate(call->inv, sip_err_code, PJ_FALSE);
1917 	    }
1918 	    pjsip_dlg_dec_lock(dlg);
1919 
1920 	    call->inv = NULL;
1921 	    call->async_call.dlg = NULL;
1922 	    goto on_return;
1923 	}
1924     }
1925 
1926     /* Create answer */
1927 /*
1928     status = pjsua_media_channel_create_sdp(call->index, rdata->tp_info.pool,
1929 					    offer, &answer, &sip_err_code);
1930     if (status != PJ_SUCCESS) {
1931 	pjsua_perror(THIS_FILE, "Error creating SDP answer", status);
1932 	pjsip_endpt_respond(pjsua_var.endpt, NULL, rdata,
1933 			    sip_err_code, NULL, NULL, NULL, NULL);
1934 	goto on_return;
1935     }
1936 */
1937 
1938     /* Init Session Timers */
1939     status = pjsip_timer_init_session(inv,
1940 				    &pjsua_var.acc[acc_id].cfg.timer_setting);
1941     if (status != PJ_SUCCESS) {
1942 	pjsua_perror(THIS_FILE, "Session Timer init failed", status);
1943         pjsip_dlg_respond(dlg, rdata, PJSIP_SC_INTERNAL_SERVER_ERROR, NULL, NULL, NULL);
1944 	pjsip_inv_terminate(inv, PJSIP_SC_INTERNAL_SERVER_ERROR, PJ_FALSE);
1945 
1946 	pjsua_media_channel_deinit(call->index);
1947 	call->inv = NULL;
1948 	call->async_call.dlg = NULL;
1949 
1950 	goto on_return;
1951     }
1952 
1953     /* Update NAT type of remote endpoint, only when there is SDP in
1954      * incoming INVITE!
1955      */
1956     if (pjsua_var.ua_cfg.nat_type_in_sdp && inv->neg &&
1957 	pjmedia_sdp_neg_get_state(inv->neg) > PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER)
1958     {
1959 	const pjmedia_sdp_session *remote_sdp;
1960 
1961 	if (pjmedia_sdp_neg_get_neg_remote(inv->neg, &remote_sdp)==PJ_SUCCESS)
1962 	    update_remote_nat_type(call, remote_sdp);
1963     }
1964 
1965     /* Must answer with some response to initial INVITE. We'll do this before
1966      * attaching the call to the invite session/dialog, so that the application
1967      * will not get notification about this event (on another scenario, it is
1968      * also possible that inv_send_msg() fails and causes the invite session to
1969      * be disconnected. If we have the call attached at this time, this will
1970      * cause the disconnection callback to be called before on_incoming_call()
1971      * callback is called, which is not right).
1972      */
1973     status = pjsip_inv_initial_answer(inv, rdata,
1974 				      100, NULL, NULL, &response);
1975     if (status != PJ_SUCCESS) {
1976 	if (response == NULL) {
1977 	    pjsua_perror(THIS_FILE, "Unable to send answer to incoming INVITE",
1978 			 status);
1979 	    pjsip_dlg_respond(dlg, rdata, 500, NULL, NULL, NULL);
1980 	    pjsip_inv_terminate(inv, 500, PJ_FALSE);
1981 	} else {
1982 	    pjsip_inv_send_msg(inv, response);
1983 	    pjsip_inv_terminate(inv, response->msg->line.status.code,
1984 				PJ_FALSE);
1985 	}
1986 	pjsua_media_channel_deinit(call->index);
1987 	call->inv = NULL;
1988 	call->async_call.dlg = NULL;
1989 	goto on_return;
1990 
1991     } else {
1992 #if !PJSUA_DISABLE_AUTO_SEND_100
1993 	status = pjsip_inv_send_msg(inv, response);
1994 	if (status != PJ_SUCCESS) {
1995 	    pjsua_perror(THIS_FILE, "Unable to send 100 response", status);
1996 	    pjsua_media_channel_deinit(call->index);
1997 	    call->inv = NULL;
1998 	    call->async_call.dlg = NULL;
1999 	    goto on_return;
2000 	}
2001 #endif
2002     }
2003 
2004     /* Only do this after sending 100/Trying (really! see the long comment
2005      * above)
2006      */
2007     if (dlg->mod_data[pjsua_var.mod.id] == NULL) {
2008 	/* In PJSUA2, on_incoming_call() may be called from
2009 	 * on_media_transport_created() hence this might already set
2010 	 * to allow notification about fail events via on_call_state() and
2011 	 * on_call_tsx_state().
2012 	 */
2013 	dlg->mod_data[pjsua_var.mod.id] = call;
2014 	inv->mod_data[pjsua_var.mod.id] = call;
2015 	++pjsua_var.call_cnt;
2016     }
2017 
2018     /* Check if this request should replace existing call */
2019     if (replaced_dlg) {
2020 	/* Process call replace. If the media channel init has been completed,
2021 	 * just process now, otherwise, just queue the replaced dialog so
2022 	 * it will be processed once the media channel async init is finished
2023 	 * successfully.
2024 	 */
2025 	if (call->med_ch_cb == NULL) {
2026 	    process_incoming_call_replace(call, replaced_dlg);
2027 	} else {
2028 	    call->async_call.call_var.inc_call.replaced_dlg = replaced_dlg;
2029 	}
2030     } else {
2031 	/* Notify application if on_incoming_call() is overriden,
2032 	 * otherwise hangup the call with 480
2033 	 */
2034 	if (pjsua_var.ua_cfg.cb.on_incoming_call) {
2035 	    pjsua_var.ua_cfg.cb.on_incoming_call(acc_id, call_id, rdata);
2036 
2037             /* Notes:
2038              * - the call might be reset when it's rejected or hangup
2039              * by application from the callback.
2040 	     * - onIncomingCall() may be simulated by onCreateMediaTransport()
2041 	     * when media init is done synchrounously (see #1916). And if app
2042 	     * happens to answer/hangup the call from the callback, the
2043 	     * answer/hangup should have been delayed (see #1923),
2044 	     * so let's process the answer/hangup now.
2045 	     */
2046 	    if (call->async_call.call_var.inc_call.hangup) {
2047 		pjsua_call_hangup(call_id, call->last_code, &call->last_text,
2048 				  NULL);
2049 	    } else if (call->med_ch_cb == NULL && call->inv) {
2050 		process_pending_call_answer(call);
2051 	    }
2052 	} else {
2053 	    pjsua_call_hangup(call_id, PJSIP_SC_TEMPORARILY_UNAVAILABLE,
2054 			      NULL, NULL);
2055 	}
2056     }
2057 
2058 
2059     /* This INVITE request has been handled. */
2060 on_return:
2061     if (dlg) {
2062 	if (should_dec_dlg)
2063 	    pjsip_dlg_dec_session(dlg, &pjsua_var.mod);
2064 
2065         pjsip_dlg_dec_lock(dlg);
2066     }
2067 
2068     if (call && call->incoming_data) {
2069 	pjsip_rx_data_free_cloned(call->incoming_data);
2070 	call->incoming_data = NULL;
2071     }
2072 
2073     pj_log_pop_indent();
2074     PJSUA_UNLOCK();
2075     return PJ_TRUE;
2076 }
2077 
2078 
2079 
2080 /*
2081  * Check if the specified call has active INVITE session and the INVITE
2082  * session has not been disconnected.
2083  */
pjsua_call_is_active(pjsua_call_id call_id)2084 PJ_DEF(pj_bool_t) pjsua_call_is_active(pjsua_call_id call_id)
2085 {
2086     PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
2087 		     PJ_EINVAL);
2088     return !pjsua_var.calls[call_id].hanging_up &&
2089     	   pjsua_var.calls[call_id].inv != NULL &&
2090 	   pjsua_var.calls[call_id].inv->state != PJSIP_INV_STATE_DISCONNECTED;
2091 }
2092 
2093 
2094 /* Acquire lock to the specified call_id */
acquire_call(const char * title,pjsua_call_id call_id,pjsua_call ** p_call,pjsip_dialog ** p_dlg)2095 pj_status_t acquire_call(const char *title,
2096 				pjsua_call_id call_id,
2097 				pjsua_call **p_call,
2098 				pjsip_dialog **p_dlg)
2099 {
2100     unsigned retry;
2101     pjsua_call *call = NULL;
2102     pj_bool_t has_pjsua_lock = PJ_FALSE;
2103     pj_status_t status = PJ_SUCCESS;
2104     pj_time_val time_start, timeout;
2105     pjsip_dialog *dlg = NULL;
2106 
2107     pj_gettimeofday(&time_start);
2108     timeout.sec = 0;
2109     timeout.msec = PJSUA_ACQUIRE_CALL_TIMEOUT;
2110     pj_time_val_normalize(&timeout);
2111 
2112     for (retry=0; ; ++retry) {
2113 
2114         if (retry % 10 == 9) {
2115             pj_time_val dtime;
2116 
2117             pj_gettimeofday(&dtime);
2118             PJ_TIME_VAL_SUB(dtime, time_start);
2119             if (!PJ_TIME_VAL_LT(dtime, timeout))
2120                 break;
2121         }
2122 
2123 	has_pjsua_lock = PJ_FALSE;
2124 
2125 	status = PJSUA_TRY_LOCK();
2126 	if (status != PJ_SUCCESS) {
2127 	    pj_thread_sleep(retry/10);
2128 	    continue;
2129 	}
2130 
2131 	has_pjsua_lock = PJ_TRUE;
2132 	call = &pjsua_var.calls[call_id];
2133         if (call->inv)
2134             dlg = call->inv->dlg;
2135         else
2136             dlg = call->async_call.dlg;
2137 
2138 	if (dlg == NULL) {
2139 	    PJSUA_UNLOCK();
2140 	    PJ_LOG(3,(THIS_FILE, "Invalid call_id %d in %s", call_id, title));
2141 	    return PJSIP_ESESSIONTERMINATED;
2142 	}
2143 
2144 	status = pjsip_dlg_try_inc_lock(dlg);
2145 	if (status != PJ_SUCCESS) {
2146 	    PJSUA_UNLOCK();
2147 	    pj_thread_sleep(retry/10);
2148 	    continue;
2149 	}
2150 
2151 	PJSUA_UNLOCK();
2152 
2153 	break;
2154     }
2155 
2156     if (status != PJ_SUCCESS) {
2157 	if (has_pjsua_lock == PJ_FALSE)
2158 	    PJ_LOG(1,(THIS_FILE, "Timed-out trying to acquire PJSUA mutex "
2159 				 "(possibly system has deadlocked) in %s",
2160 				 title));
2161 	else
2162 	    PJ_LOG(1,(THIS_FILE, "Timed-out trying to acquire dialog mutex "
2163 				 "(possibly system has deadlocked) in %s",
2164 				 title));
2165 	return PJ_ETIMEDOUT;
2166     }
2167 
2168     *p_call = call;
2169     *p_dlg = dlg;
2170 
2171     return PJ_SUCCESS;
2172 }
2173 
2174 
2175 /*
2176  * Obtain detail information about the specified call.
2177  */
pjsua_call_get_info(pjsua_call_id call_id,pjsua_call_info * info)2178 PJ_DEF(pj_status_t) pjsua_call_get_info( pjsua_call_id call_id,
2179 					 pjsua_call_info *info)
2180 {
2181     pjsua_call *call;
2182     pjsip_dialog *dlg;
2183     unsigned mi;
2184 
2185     PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
2186 		     PJ_EINVAL);
2187 
2188     pj_bzero(info, sizeof(*info));
2189 
2190     /* Use PJSUA_LOCK() instead of acquire_call():
2191      *  https://trac.pjsip.org/repos/ticket/1371
2192      */
2193     PJSUA_LOCK();
2194 
2195     call = &pjsua_var.calls[call_id];
2196     dlg = (call->inv ? call->inv->dlg : call->async_call.dlg);
2197     if (!dlg) {
2198 	PJSUA_UNLOCK();
2199 	return PJSIP_ESESSIONTERMINATED;
2200     }
2201 
2202     /* id and role */
2203     info->id = call_id;
2204     info->role = dlg->role;
2205     info->acc_id = call->acc_id;
2206 
2207     /* local info */
2208     info->local_info.ptr = info->buf_.local_info;
2209     pj_strncpy(&info->local_info, &dlg->local.info_str,
2210 	       sizeof(info->buf_.local_info));
2211 
2212     /* local contact */
2213     info->local_contact.ptr = info->buf_.local_contact;
2214     info->local_contact.slen = pjsip_uri_print(PJSIP_URI_IN_CONTACT_HDR,
2215 					       dlg->local.contact->uri,
2216 					       info->local_contact.ptr,
2217 					       sizeof(info->buf_.local_contact));
2218     if (info->local_contact.slen < 0)
2219 	info->local_contact.slen = 0;
2220 
2221     /* remote info */
2222     info->remote_info.ptr = info->buf_.remote_info;
2223     pj_strncpy(&info->remote_info, &dlg->remote.info_str,
2224 	       sizeof(info->buf_.remote_info));
2225 
2226     /* remote contact */
2227     if (dlg->remote.contact) {
2228 	int len;
2229 	info->remote_contact.ptr = info->buf_.remote_contact;
2230 	len = pjsip_uri_print(PJSIP_URI_IN_CONTACT_HDR,
2231 			      dlg->remote.contact->uri,
2232 			      info->remote_contact.ptr,
2233 			      sizeof(info->buf_.remote_contact));
2234 	if (len < 0) len = 0;
2235 	info->remote_contact.slen = len;
2236     } else {
2237 	info->remote_contact.slen = 0;
2238     }
2239 
2240     /* call id */
2241     info->call_id.ptr = info->buf_.call_id;
2242     pj_strncpy(&info->call_id, &dlg->call_id->id,
2243 	       sizeof(info->buf_.call_id));
2244 
2245     /* call setting */
2246     pj_memcpy(&info->setting, &call->opt, sizeof(call->opt));
2247 
2248     /* state, state_text */
2249     if (call->hanging_up) {
2250         info->state = PJSIP_INV_STATE_DISCONNECTED;
2251     } else if (call->inv) {
2252         info->state = call->inv->state;
2253         if (call->inv->role == PJSIP_ROLE_UAS &&
2254             info->state == PJSIP_INV_STATE_NULL)
2255         {
2256             info->state = PJSIP_INV_STATE_INCOMING;
2257         }
2258     } else if (call->async_call.dlg && call->last_code==0) {
2259         info->state = PJSIP_INV_STATE_NULL;
2260     } else {
2261         info->state = PJSIP_INV_STATE_DISCONNECTED;
2262     }
2263     info->state_text = pj_str((char*)pjsip_inv_state_name(info->state));
2264 
2265     /* If call is disconnected, set the last_status from the cause code */
2266     if (call->inv && call->inv->state >= PJSIP_INV_STATE_DISCONNECTED) {
2267 	/* last_status, last_status_text */
2268 	info->last_status = call->inv->cause;
2269 
2270 	info->last_status_text.ptr = info->buf_.last_status_text;
2271 	pj_strncpy(&info->last_status_text, &call->inv->cause_text,
2272 		   sizeof(info->buf_.last_status_text));
2273     } else {
2274 	/* last_status, last_status_text */
2275 	info->last_status = call->last_code;
2276 
2277 	info->last_status_text.ptr = info->buf_.last_status_text;
2278 	pj_strncpy(&info->last_status_text, &call->last_text,
2279 		   sizeof(info->buf_.last_status_text));
2280     }
2281 
2282     /* Audio & video count offered by remote */
2283     info->rem_offerer   = call->rem_offerer;
2284     if (call->rem_offerer) {
2285 	info->rem_aud_cnt = call->rem_aud_cnt;
2286 	info->rem_vid_cnt = call->rem_vid_cnt;
2287     }
2288 
2289     /* Build array of active media info */
2290     info->media_cnt = 0;
2291     for (mi=0; mi < call->med_cnt &&
2292 	       info->media_cnt < PJ_ARRAY_SIZE(info->media); ++mi)
2293     {
2294 	pjsua_call_media *call_med = &call->media[mi];
2295 
2296 	info->media[info->media_cnt].index = mi;
2297 	info->media[info->media_cnt].status = call_med->state;
2298 	info->media[info->media_cnt].dir = call_med->dir;
2299 	info->media[info->media_cnt].type = call_med->type;
2300 
2301 	if (call_med->type == PJMEDIA_TYPE_AUDIO) {
2302 	    info->media[info->media_cnt].stream.aud.conf_slot =
2303 						call_med->strm.a.conf_slot;
2304 	} else if (call_med->type == PJMEDIA_TYPE_VIDEO) {
2305 	    pjmedia_vid_dev_index cap_dev = PJMEDIA_VID_INVALID_DEV;
2306 
2307 	    info->media[info->media_cnt].stream.vid.win_in =
2308 						call_med->strm.v.rdr_win_id;
2309 
2310 	    info->media[info->media_cnt].stream.vid.dec_slot =
2311 						call_med->strm.v.strm_dec_slot;
2312 	    info->media[info->media_cnt].stream.vid.enc_slot =
2313 						call_med->strm.v.strm_enc_slot;
2314 
2315 	    if (call_med->strm.v.cap_win_id != PJSUA_INVALID_ID) {
2316 		cap_dev = call_med->strm.v.cap_dev;
2317 	    }
2318 	    info->media[info->media_cnt].stream.vid.cap_dev = cap_dev;
2319 	} else {
2320 	    continue;
2321 	}
2322 	++info->media_cnt;
2323     }
2324 
2325     if (call->audio_idx != -1) {
2326 	info->media_status = call->media[call->audio_idx].state;
2327 	info->media_dir = call->media[call->audio_idx].dir;
2328 	info->conf_slot = call->media[call->audio_idx].strm.a.conf_slot;
2329     }
2330 
2331     /* Build array of provisional media info */
2332     info->prov_media_cnt = 0;
2333     for (mi=0; mi < call->med_prov_cnt &&
2334 	       info->prov_media_cnt < PJ_ARRAY_SIZE(info->prov_media); ++mi)
2335     {
2336 	pjsua_call_media *call_med = &call->media_prov[mi];
2337 
2338 	info->prov_media[info->prov_media_cnt].index = mi;
2339 	info->prov_media[info->prov_media_cnt].status = call_med->state;
2340 	info->prov_media[info->prov_media_cnt].dir = call_med->dir;
2341 	info->prov_media[info->prov_media_cnt].type = call_med->type;
2342 	if (call_med->type == PJMEDIA_TYPE_AUDIO) {
2343 	    info->prov_media[info->prov_media_cnt].stream.aud.conf_slot =
2344 						call_med->strm.a.conf_slot;
2345 	} else if (call_med->type == PJMEDIA_TYPE_VIDEO) {
2346 	    pjmedia_vid_dev_index cap_dev = PJMEDIA_VID_INVALID_DEV;
2347 
2348 	    info->prov_media[info->prov_media_cnt].stream.vid.win_in =
2349 						call_med->strm.v.rdr_win_id;
2350 
2351 	    if (call_med->strm.v.cap_win_id != PJSUA_INVALID_ID) {
2352 		cap_dev = call_med->strm.v.cap_dev;
2353 	    }
2354 	    info->prov_media[info->prov_media_cnt].stream.vid.cap_dev=cap_dev;
2355 	} else {
2356 	    continue;
2357 	}
2358 	++info->prov_media_cnt;
2359     }
2360 
2361     /* calculate duration */
2362     if (info->state >= PJSIP_INV_STATE_DISCONNECTED) {
2363 
2364 	info->total_duration = call->dis_time;
2365 	PJ_TIME_VAL_SUB(info->total_duration, call->start_time);
2366 
2367 	if (call->conn_time.sec) {
2368 	    info->connect_duration = call->dis_time;
2369 	    PJ_TIME_VAL_SUB(info->connect_duration, call->conn_time);
2370 	}
2371 
2372     } else if (info->state == PJSIP_INV_STATE_CONFIRMED) {
2373 
2374 	pj_gettimeofday(&info->total_duration);
2375 	PJ_TIME_VAL_SUB(info->total_duration, call->start_time);
2376 
2377 	pj_gettimeofday(&info->connect_duration);
2378 	PJ_TIME_VAL_SUB(info->connect_duration, call->conn_time);
2379 
2380     } else {
2381 	pj_gettimeofday(&info->total_duration);
2382 	PJ_TIME_VAL_SUB(info->total_duration, call->start_time);
2383     }
2384 
2385     PJSUA_UNLOCK();
2386 
2387     return PJ_SUCCESS;
2388 }
2389 
2390 /*
2391  * Check if call remote peer support the specified capability.
2392  */
pjsua_call_remote_has_cap(pjsua_call_id call_id,int htype,const pj_str_t * hname,const pj_str_t * token)2393 PJ_DEF(pjsip_dialog_cap_status) pjsua_call_remote_has_cap(
2394 						    pjsua_call_id call_id,
2395 						    int htype,
2396 						    const pj_str_t *hname,
2397 						    const pj_str_t *token)
2398 {
2399     pjsua_call *call;
2400     pjsip_dialog *dlg;
2401     pj_status_t status;
2402     pjsip_dialog_cap_status cap_status;
2403 
2404     status = acquire_call("pjsua_call_peer_has_cap()", call_id, &call, &dlg);
2405     if (status != PJ_SUCCESS)
2406 	return PJSIP_DIALOG_CAP_UNKNOWN;
2407 
2408     cap_status = pjsip_dlg_remote_has_cap(dlg, htype, hname, token);
2409 
2410     pjsip_dlg_dec_lock(dlg);
2411 
2412     return cap_status;
2413 }
2414 
2415 
2416 /*
2417  * Attach application specific data to the call.
2418  */
pjsua_call_set_user_data(pjsua_call_id call_id,void * user_data)2419 PJ_DEF(pj_status_t) pjsua_call_set_user_data( pjsua_call_id call_id,
2420 					      void *user_data)
2421 {
2422     PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
2423 		     PJ_EINVAL);
2424     pjsua_var.calls[call_id].user_data = user_data;
2425 
2426     return PJ_SUCCESS;
2427 }
2428 
2429 
2430 /*
2431  * Get user data attached to the call.
2432  */
pjsua_call_get_user_data(pjsua_call_id call_id)2433 PJ_DEF(void*) pjsua_call_get_user_data(pjsua_call_id call_id)
2434 {
2435     PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
2436 		     NULL);
2437     return pjsua_var.calls[call_id].user_data;
2438 }
2439 
2440 
2441 /*
2442  * Get remote's NAT type.
2443  */
pjsua_call_get_rem_nat_type(pjsua_call_id call_id,pj_stun_nat_type * p_type)2444 PJ_DEF(pj_status_t) pjsua_call_get_rem_nat_type(pjsua_call_id call_id,
2445 						pj_stun_nat_type *p_type)
2446 {
2447     PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
2448 		     PJ_EINVAL);
2449     PJ_ASSERT_RETURN(p_type != NULL, PJ_EINVAL);
2450 
2451     *p_type = pjsua_var.calls[call_id].rem_nat_type;
2452     return PJ_SUCCESS;
2453 }
2454 
2455 
2456 /*
2457  * Get media transport info for the specified media index.
2458  */
2459 PJ_DEF(pj_status_t)
pjsua_call_get_med_transport_info(pjsua_call_id call_id,unsigned med_idx,pjmedia_transport_info * t)2460 pjsua_call_get_med_transport_info(pjsua_call_id call_id,
2461                                   unsigned med_idx,
2462                                   pjmedia_transport_info *t)
2463 {
2464     pjsua_call *call;
2465     pjsua_call_media *call_med;
2466     pj_status_t status;
2467 
2468     PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
2469 		     PJ_EINVAL);
2470     PJ_ASSERT_RETURN(t, PJ_EINVAL);
2471 
2472     PJSUA_LOCK();
2473 
2474     call = &pjsua_var.calls[call_id];
2475 
2476     if (med_idx >= call->med_cnt) {
2477 	PJSUA_UNLOCK();
2478 	return PJ_EINVAL;
2479     }
2480 
2481     call_med = &call->media[med_idx];
2482 
2483     pjmedia_transport_info_init(t);
2484     status = pjmedia_transport_get_info(call_med->tp, t);
2485 
2486     PJSUA_UNLOCK();
2487     return status;
2488 }
2489 
2490 
2491 /* Media channel init callback for pjsua_call_answer(). */
2492 static pj_status_t
on_answer_call_med_tp_complete(pjsua_call_id call_id,const pjsua_med_tp_state_info * info)2493 on_answer_call_med_tp_complete(pjsua_call_id call_id,
2494                                const pjsua_med_tp_state_info *info)
2495 {
2496     pjsua_call *call = &pjsua_var.calls[call_id];
2497     pjmedia_sdp_session *sdp;
2498     int sip_err_code = (info? info->sip_err_code: 0);
2499     pj_status_t status = (info? info->status: PJ_SUCCESS);
2500 
2501     PJSUA_LOCK();
2502 
2503     if (status != PJ_SUCCESS) {
2504 	pjsua_perror(THIS_FILE, "Error initializing media channel", status);
2505         goto on_return;
2506     }
2507 
2508     /* pjsua_media_channel_deinit() has been called. */
2509     if (call->async_call.med_ch_deinit) {
2510         pjsua_media_channel_deinit(call->index);
2511         call->med_ch_cb = NULL;
2512         PJSUA_UNLOCK();
2513         return PJ_SUCCESS;
2514     }
2515 
2516     status = pjsua_media_channel_create_sdp(call_id,
2517                                             call->async_call.dlg->pool,
2518 					    NULL, &sdp, &sip_err_code);
2519     if (status != PJ_SUCCESS) {
2520 	pjsua_perror(THIS_FILE, "Error creating SDP answer", status);
2521         goto on_return;
2522     }
2523 
2524     status = pjsip_inv_set_local_sdp(call->inv, sdp);
2525     if (status != PJ_SUCCESS) {
2526 	pjsua_perror(THIS_FILE, "Error setting local SDP", status);
2527         sip_err_code = PJSIP_SC_NOT_ACCEPTABLE_HERE;
2528         goto on_return;
2529     }
2530 
2531 on_return:
2532     if (status != PJ_SUCCESS) {
2533         /* If the callback is called from pjsua_call_on_incoming(), the
2534          * invite's state is PJSIP_INV_STATE_NULL, so the invite session
2535          * will be terminated later, otherwise we end the session here.
2536          */
2537         if (call->inv->state > PJSIP_INV_STATE_NULL) {
2538             pjsip_tx_data *tdata;
2539             pj_status_t status_;
2540 
2541 	    if (sip_err_code == 0)
2542 		sip_err_code = PJSIP_ERRNO_TO_SIP_STATUS(status);
2543 
2544 	    status_ = pjsip_inv_end_session(call->inv, sip_err_code, NULL,
2545                                             &tdata);
2546 	    if (status_ == PJ_SUCCESS && tdata)
2547 	        status_ = pjsip_inv_send_msg(call->inv, tdata);
2548         }
2549 
2550         pjsua_media_channel_deinit(call->index);
2551     }
2552 
2553     /* Set the callback to NULL to indicate that the async operation
2554      * has completed.
2555      */
2556     call->med_ch_cb = NULL;
2557 
2558     /* Finish any pending process */
2559     if (status == PJ_SUCCESS) {
2560 	/* Process pending call answers */
2561 	process_pending_call_answer(call);
2562     }
2563 
2564     PJSUA_UNLOCK();
2565     return status;
2566 }
2567 
2568 
2569 /*
2570  * Send response to incoming INVITE request.
2571  */
pjsua_call_answer(pjsua_call_id call_id,unsigned code,const pj_str_t * reason,const pjsua_msg_data * msg_data)2572 PJ_DEF(pj_status_t) pjsua_call_answer( pjsua_call_id call_id,
2573 				       unsigned code,
2574 				       const pj_str_t *reason,
2575 				       const pjsua_msg_data *msg_data)
2576 {
2577     return pjsua_call_answer2(call_id, NULL, code, reason, msg_data);
2578 }
2579 
2580 
2581 /*
2582  * Send response to incoming INVITE request.
2583  */
pjsua_call_answer2(pjsua_call_id call_id,const pjsua_call_setting * opt,unsigned code,const pj_str_t * reason,const pjsua_msg_data * msg_data)2584 PJ_DEF(pj_status_t) pjsua_call_answer2(pjsua_call_id call_id,
2585 				       const pjsua_call_setting *opt,
2586 				       unsigned code,
2587 				       const pj_str_t *reason,
2588 				       const pjsua_msg_data *msg_data)
2589 {
2590     pjsua_call *call;
2591     pjsip_dialog *dlg = NULL;
2592     pjsip_tx_data *tdata;
2593     pj_status_t status;
2594 
2595     PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
2596 		     PJ_EINVAL);
2597 
2598     PJ_LOG(4,(THIS_FILE, "Answering call %d: code=%d", call_id, code));
2599     pj_log_push_indent();
2600 
2601     status = acquire_call("pjsua_call_answer()", call_id, &call, &dlg);
2602     if (status != PJ_SUCCESS)
2603 	goto on_return;
2604 
2605     /* Apply call setting, only if status code is 1xx or 2xx. */
2606     if (opt && code < 300) {
2607 	/* Check if it has not been set previously or it is different to
2608 	 * the previous one.
2609 	 */
2610 	if (!call->opt_inited) {
2611 	    call->opt_inited = PJ_TRUE;
2612 	    apply_call_setting(call, opt, NULL);
2613 	} else if (pj_memcmp(opt, &call->opt, sizeof(*opt)) != 0) {
2614 	    /* Warn application about call setting inconsistency */
2615 	    PJ_LOG(2,(THIS_FILE, "The call setting changes is ignored."));
2616 	}
2617     }
2618 
2619     PJSUA_LOCK();
2620 
2621     /* Ticket #1526: When the incoming call contains no SDP offer, the media
2622      * channel may have not been initialized at this stage. The media channel
2623      * will be initialized here (along with SDP local offer generation) when
2624      * the following conditions are met:
2625      * - no pending media channel init
2626      * - local SDP has not been generated
2627      * - call setting has just been set, or SDP offer needs to be sent, i.e:
2628      *   answer code 183 or 2xx is issued
2629      */
2630     if (!call->med_ch_cb &&
2631 	(call->opt_inited || (code==183 || code/100==2)) &&
2632 	(!call->inv->neg ||
2633 	 pjmedia_sdp_neg_get_state(call->inv->neg) ==
2634 		PJMEDIA_SDP_NEG_STATE_NULL))
2635     {
2636 	/* Mark call setting as initialized as it is just about to be used
2637 	 * for initializing the media channel.
2638 	 */
2639 	call->opt_inited = PJ_TRUE;
2640 
2641 	status = pjsua_media_channel_init(call->index, PJSIP_ROLE_UAC,
2642 					  call->secure_level,
2643 					  dlg->pool,
2644 					  NULL, NULL, PJ_TRUE,
2645 					  &on_answer_call_med_tp_complete);
2646 	if (status == PJ_SUCCESS) {
2647 	    status = on_answer_call_med_tp_complete(call->index, NULL);
2648 	    if (status != PJ_SUCCESS) {
2649 		PJSUA_UNLOCK();
2650 		goto on_return;
2651 	    }
2652 	} else if (status != PJ_EPENDING) {
2653 	    PJSUA_UNLOCK();
2654 	    pjsua_perror(THIS_FILE, "Error initializing media channel", status);
2655 	    goto on_return;
2656 	}
2657     }
2658 
2659     /* If media transport creation is not yet completed, we will answer
2660      * the call in the media transport creation callback instead.
2661      * Or if initial answer is not sent yet, we will answer the call after
2662      * initial answer is sent (see #1923).
2663      */
2664     if (call->med_ch_cb || !call->inv->last_answer) {
2665         struct call_answer *answer;
2666 
2667         PJ_LOG(4,(THIS_FILE, "Pending answering call %d upon completion "
2668                              "of media transport", call_id));
2669 
2670         answer = PJ_POOL_ZALLOC_T(call->inv->pool_prov, struct call_answer);
2671         answer->code = code;
2672 	if (opt) {
2673 	    answer->opt = PJ_POOL_ZALLOC_T(call->inv->pool_prov,
2674 					   pjsua_call_setting);
2675 	    *answer->opt = *opt;
2676 	}
2677         if (reason) {
2678 	    answer->reason = PJ_POOL_ZALLOC_T(call->inv->pool_prov, pj_str_t);
2679             pj_strdup(call->inv->pool_prov, answer->reason, reason);
2680         }
2681         if (msg_data) {
2682             answer->msg_data = pjsua_msg_data_clone(call->inv->pool_prov,
2683                                                     msg_data);
2684         }
2685         pj_list_push_back(&call->async_call.call_var.inc_call.answers,
2686                           answer);
2687 
2688         PJSUA_UNLOCK();
2689         if (dlg) pjsip_dlg_dec_lock(dlg);
2690         pj_log_pop_indent();
2691         return status;
2692     }
2693 
2694     PJSUA_UNLOCK();
2695 
2696     if (call->res_time.sec == 0)
2697 	pj_gettimeofday(&call->res_time);
2698 
2699     if (reason && reason->slen == 0)
2700 	reason = NULL;
2701 
2702     /* Create response message */
2703     status = pjsip_inv_answer(call->inv, code, reason, NULL, &tdata);
2704     if (status != PJ_SUCCESS) {
2705 	pjsua_perror(THIS_FILE, "Error creating response",
2706 		     status);
2707 	goto on_return;
2708     }
2709 
2710     /* Call might have been disconnected if application is answering with
2711      * 200/OK and the media failed to start.
2712      */
2713     if (call->inv == NULL)
2714 	goto on_return;
2715 
2716     /* Add additional headers etc */
2717     pjsua_process_msg_data( tdata, msg_data);
2718 
2719     /* Send the message */
2720     status = pjsip_inv_send_msg(call->inv, tdata);
2721     if (status != PJ_SUCCESS)
2722 	pjsua_perror(THIS_FILE, "Error sending response",
2723 		     status);
2724 
2725 on_return:
2726     if (dlg) pjsip_dlg_dec_lock(dlg);
2727     pj_log_pop_indent();
2728     return status;
2729 }
2730 
2731 
2732 /*
2733  * Send response to incoming INVITE request.
2734  */
2735 PJ_DEF(pj_status_t)
pjsua_call_answer_with_sdp(pjsua_call_id call_id,const pjmedia_sdp_session * sdp,const pjsua_call_setting * opt,unsigned code,const pj_str_t * reason,const pjsua_msg_data * msg_data)2736 pjsua_call_answer_with_sdp(pjsua_call_id call_id,
2737 			   const pjmedia_sdp_session *sdp,
2738 			   const pjsua_call_setting *opt,
2739 			   unsigned code,
2740 			   const pj_str_t *reason,
2741 			   const pjsua_msg_data *msg_data)
2742 {
2743     pjsua_call *call;
2744     pjsip_dialog *dlg = NULL;
2745     pj_status_t status;
2746 
2747     PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
2748 		     PJ_EINVAL);
2749 
2750     status = acquire_call("pjsua_call_answer_with_sdp()",
2751     			  call_id, &call, &dlg);
2752     if (status != PJ_SUCCESS)
2753 	return status;
2754 
2755     status = pjsip_inv_set_sdp_answer(call->inv, sdp);
2756 
2757     pjsip_dlg_dec_lock(dlg);
2758 
2759     if (status != PJ_SUCCESS)
2760     	return status;
2761 
2762     return pjsua_call_answer2(call_id, opt, code, reason, msg_data);
2763 }
2764 
2765 
call_inv_end_session(pjsua_call * call,unsigned code,const pj_str_t * reason,const pjsua_msg_data * msg_data)2766 static pj_status_t call_inv_end_session(pjsua_call *call,
2767 					unsigned code,
2768 				        const pj_str_t *reason,
2769 				        const pjsua_msg_data *msg_data)
2770 {
2771     pjsip_tx_data *tdata;
2772     pj_status_t status;
2773 
2774     if (code==0) {
2775 	if (call->inv->state == PJSIP_INV_STATE_CONFIRMED)
2776 	    code = PJSIP_SC_OK;
2777 	else if (call->inv->role == PJSIP_ROLE_UAS)
2778 	    code = PJSIP_SC_DECLINE;
2779 	else
2780 	    code = PJSIP_SC_REQUEST_TERMINATED;
2781     }
2782 
2783     /* Stop hangup timer, if it is active. */
2784     if (call->hangup_timer.id) {
2785 	pjsua_cancel_timer(&call->hangup_timer);
2786 	call->hangup_timer.id = PJ_FALSE;
2787     }
2788 
2789     status = pjsip_inv_end_session(call->inv, code, reason, &tdata);
2790     if (status != PJ_SUCCESS) {
2791 	pjsua_perror(THIS_FILE,
2792 		     "Failed to create end session message",
2793 		     status);
2794 	goto on_return;
2795     }
2796 
2797     /* pjsip_inv_end_session may return PJ_SUCCESS with NULL
2798      * as p_tdata when INVITE transaction has not been answered
2799      * with any provisional responses.
2800      */
2801     if (tdata == NULL) {
2802 	goto on_return;
2803     }
2804 
2805     /* Add additional headers etc */
2806     pjsua_process_msg_data( tdata, msg_data);
2807 
2808     /* Send the message */
2809     status = pjsip_inv_send_msg(call->inv, tdata);
2810     if (status != PJ_SUCCESS) {
2811 	pjsua_perror(THIS_FILE,
2812 		     "Failed to send end session message",
2813 		     status);
2814 	goto on_return;
2815     }
2816 
2817 on_return:
2818     if (status != PJ_SUCCESS) {
2819     	pj_time_val delay;
2820 
2821     	/* Schedule a retry */
2822     	if (call->hangup_retry >= CALL_HANGUP_MAX_RETRY) {
2823     	    /* Forcefully terminate the invite session. */
2824     	    pjsip_inv_terminate(call->inv, call->hangup_code, PJ_TRUE);
2825     	    return PJ_SUCCESS;
2826     	}
2827 
2828     	if (call->hangup_retry == 0) {
2829     	    pj_timer_entry_init(&call->hangup_timer, PJ_FALSE,
2830 				(void*)call, &hangup_timer_cb);
2831 
2832     	    call->hangup_code = code;
2833     	    if (reason) {
2834     	    	pj_strdup(call->inv->pool_prov, &call->hangup_reason,
2835     	    	    	  reason);
2836     	    }
2837     	    if (msg_data) {
2838     	     	call->hangup_msg_data = pjsua_msg_data_clone(
2839     	     				    call->inv->pool_prov,
2840     	     				    msg_data);
2841     	    }
2842     	}
2843 
2844 	delay.sec = 0;
2845     	delay.msec = CALL_HANGUP_RETRY_INTERVAL;
2846     	pj_time_val_normalize(&delay);
2847     	call->hangup_timer.id = PJ_TRUE;
2848     	pjsua_schedule_timer(&call->hangup_timer, &delay);
2849     	call->hangup_retry++;
2850 
2851        	PJ_LOG(4, (THIS_FILE, "Will retry call %d hangup in %d msec",
2852                               call->index, CALL_HANGUP_RETRY_INTERVAL));
2853     }
2854 
2855     return PJ_SUCCESS;
2856 }
2857 
2858 /* Timer callback to hangup call */
hangup_timer_cb(pj_timer_heap_t * th,pj_timer_entry * entry)2859 static void hangup_timer_cb(pj_timer_heap_t *th, pj_timer_entry *entry)
2860 {
2861     pjsua_call* call = (pjsua_call *)entry->user_data;
2862     pjsip_dialog *dlg;
2863     pj_status_t status;
2864 
2865     PJ_UNUSED_ARG(th);
2866 
2867     pj_log_push_indent();
2868 
2869     status = acquire_call("hangup_timer_cb()", call->index, &call, &dlg);
2870     if (status != PJ_SUCCESS) {
2871 	pj_log_pop_indent();
2872 	return;
2873     }
2874 
2875     call->hangup_timer.id = PJ_FALSE;
2876     call_inv_end_session(call, call->hangup_code, &call->hangup_reason,
2877     			 call->hangup_msg_data);
2878 
2879     pjsip_dlg_dec_lock(dlg);
2880 
2881     pj_log_pop_indent();
2882 }
2883 
2884 /*
2885  * Hangup call by using method that is appropriate according to the
2886  * call state.
2887  */
pjsua_call_hangup(pjsua_call_id call_id,unsigned code,const pj_str_t * reason,const pjsua_msg_data * msg_data)2888 PJ_DEF(pj_status_t) pjsua_call_hangup(pjsua_call_id call_id,
2889 				      unsigned code,
2890 				      const pj_str_t *reason,
2891 				      const pjsua_msg_data *msg_data)
2892 {
2893     pjsua_call *call;
2894     pjsip_dialog *dlg = NULL;
2895     pj_status_t status;
2896 
2897     if (call_id<0 || call_id>=(int)pjsua_var.ua_cfg.max_calls) {
2898 	PJ_LOG(1,(THIS_FILE, "pjsua_call_hangup(): invalid call id %d",
2899 			     call_id));
2900     }
2901 
2902     PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
2903 		     PJ_EINVAL);
2904 
2905     PJ_LOG(4,(THIS_FILE, "Call %d hanging up: code=%d..", call_id, code));
2906     pj_log_push_indent();
2907 
2908     status = acquire_call("pjsua_call_hangup()", call_id, &call, &dlg);
2909     if (status != PJ_SUCCESS)
2910 	goto on_return;
2911 
2912     if (!call->hanging_up) {
2913 	pjsip_event user_event;
2914 
2915 	pj_gettimeofday(&call->dis_time);
2916 	if (call->res_time.sec == 0)
2917 	    pj_gettimeofday(&call->res_time);
2918 
2919     	if (code==0) {
2920 	    if (call->inv && call->inv->state == PJSIP_INV_STATE_CONFIRMED)
2921 	        code = PJSIP_SC_OK;
2922 	    else if (call->inv && call->inv->role == PJSIP_ROLE_UAS)
2923 	    	code = PJSIP_SC_DECLINE;
2924 	    else
2925 	    	code = PJSIP_SC_REQUEST_TERMINATED;
2926     	}
2927 
2928 	call->last_code = code;
2929 	pj_strncpy(&call->last_text,
2930 	    	   pjsip_get_status_text(call->last_code),
2931 		   sizeof(call->last_text_buf_));
2932 
2933     	/* Stop reinvite timer, if it is active. */
2934     	if (call->reinv_timer.id) {
2935 	    pjsua_cancel_timer(&call->reinv_timer);
2936 	    call->reinv_timer.id = PJ_FALSE;
2937     	}
2938 
2939     	/* If media transport creation is not yet completed, we will continue
2940     	 * from the media transport creation callback instead.
2941          */
2942     	if ((call->med_ch_cb && !call->inv) ||
2943 	    ((call->inv != NULL) &&
2944 	     (call->inv->state == PJSIP_INV_STATE_NULL)))
2945     	{
2946             PJ_LOG(4,(THIS_FILE, "Will continue call %d hangup upon "
2947                              	 "completion of media transport", call_id));
2948 
2949 	    if (call->inv && call->inv->role == PJSIP_ROLE_UAS)
2950 	    	call->async_call.call_var.inc_call.hangup = PJ_TRUE;
2951 	    else
2952 	    	call->async_call.call_var.out_call.hangup = PJ_TRUE;
2953 
2954             if (reason) {
2955             	pj_strncpy(&call->last_text, reason,
2956 		       	   sizeof(call->last_text_buf_));
2957             }
2958 
2959 	    call->hanging_up = PJ_TRUE;
2960     	} else {
2961     	    /* Destroy media session. */
2962     	    pjsua_media_channel_deinit(call_id);
2963 
2964 	    call->hanging_up = PJ_TRUE;
2965 	    pjsua_check_snd_dev_idle();
2966 	}
2967 
2968     	/* Call callback which will report DISCONNECTED state.
2969     	 * Use user event rather than NULL to avoid crash in
2970 	 * unsuspecting app.
2971 	 */
2972 	PJSIP_EVENT_INIT_USER(user_event, 0, 0, 0, 0);
2973     	if (pjsua_var.ua_cfg.cb.on_call_state) {
2974 	    (*pjsua_var.ua_cfg.cb.on_call_state)(call->index,
2975 	    					 &user_event);
2976 	}
2977 
2978     }
2979 
2980     if (call->inv)
2981     	call_inv_end_session(call, code, reason, msg_data);
2982 
2983 on_return:
2984     if (dlg) pjsip_dlg_dec_lock(dlg);
2985     pj_log_pop_indent();
2986     return status;
2987 }
2988 
2989 
2990 /*
2991  * Accept or reject redirection.
2992  */
pjsua_call_process_redirect(pjsua_call_id call_id,pjsip_redirect_op cmd)2993 PJ_DEF(pj_status_t) pjsua_call_process_redirect( pjsua_call_id call_id,
2994 						 pjsip_redirect_op cmd)
2995 {
2996     pjsua_call *call;
2997     pjsip_dialog *dlg;
2998     pj_status_t status;
2999 
3000     PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
3001 		     PJ_EINVAL);
3002 
3003     status = acquire_call("pjsua_call_process_redirect()", call_id,
3004 			  &call, &dlg);
3005     if (status != PJ_SUCCESS)
3006 	return status;
3007 
3008     status = pjsip_inv_process_redirect(call->inv, cmd, NULL);
3009 
3010     pjsip_dlg_dec_lock(dlg);
3011 
3012     return status;
3013 }
3014 
3015 
3016 /*
3017  * Put the specified call on hold.
3018  */
pjsua_call_set_hold(pjsua_call_id call_id,const pjsua_msg_data * msg_data)3019 PJ_DEF(pj_status_t) pjsua_call_set_hold(pjsua_call_id call_id,
3020 					const pjsua_msg_data *msg_data)
3021 {
3022     return pjsua_call_set_hold2(call_id, 0, msg_data);
3023 }
3024 
pjsua_call_set_hold2(pjsua_call_id call_id,unsigned options,const pjsua_msg_data * msg_data)3025 PJ_DEF(pj_status_t) pjsua_call_set_hold2(pjsua_call_id call_id,
3026                                          unsigned options,
3027 					 const pjsua_msg_data *msg_data)
3028 {
3029     pjmedia_sdp_session *sdp;
3030     pjsua_call *call;
3031     pjsip_dialog *dlg = NULL;
3032     pjsip_tx_data *tdata;
3033     pj_str_t *new_contact = NULL;
3034     pj_status_t status;
3035 
3036     PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
3037 		     PJ_EINVAL);
3038 
3039     PJ_LOG(4,(THIS_FILE, "Putting call %d on hold", call_id));
3040     pj_log_push_indent();
3041 
3042     status = acquire_call("pjsua_call_set_hold()", call_id, &call, &dlg);
3043     if (status != PJ_SUCCESS)
3044 	goto on_return;
3045 
3046     if (call->inv->state != PJSIP_INV_STATE_CONFIRMED) {
3047 	PJ_LOG(3,(THIS_FILE, "Can not hold call that is not confirmed"));
3048 	status = PJSIP_ESESSIONSTATE;
3049 	goto on_return;
3050     }
3051 
3052     /* We may need to re-initialize media before creating SDP */
3053     if (call->med_prov_cnt == 0) {
3054     	status = apply_call_setting(call, &call->opt, NULL);
3055     	if (status != PJ_SUCCESS)
3056 	    goto on_return;
3057     }
3058 
3059     status = create_sdp_of_call_hold(call, &sdp);
3060     if (status != PJ_SUCCESS)
3061 	goto on_return;
3062 
3063     if ((options & PJSUA_CALL_UPDATE_CONTACT) &&
3064 	pjsua_acc_is_valid(call->acc_id))
3065     {
3066 	call_update_contact(call, &new_contact);
3067     }
3068 
3069     if ((options & PJSUA_CALL_UPDATE_VIA) &&
3070 	pjsua_acc_is_valid(call->acc_id))
3071     {
3072     	dlg_set_via(call->inv->dlg, &pjsua_var.acc[call->acc_id]);
3073     }
3074 
3075     if ((call->opt.flag & PJSUA_CALL_UPDATE_TARGET) &&
3076 	msg_data && msg_data->target_uri.slen)
3077     {
3078 	status = dlg_set_target(dlg, &msg_data->target_uri);
3079 	if (status != PJ_SUCCESS) {
3080 	    pjsua_perror(THIS_FILE, "Unable to set new target", status);
3081 	    goto on_return;
3082 	}
3083     }
3084 
3085     /* Create re-INVITE with new offer */
3086     status = pjsip_inv_reinvite( call->inv, new_contact, sdp, &tdata);
3087     if (status != PJ_SUCCESS) {
3088 	pjsua_perror(THIS_FILE, "Unable to create re-INVITE", status);
3089 	goto on_return;
3090     }
3091 
3092     /* Add additional headers etc */
3093     pjsua_process_msg_data( tdata, msg_data);
3094 
3095     /* Record the tx_data to keep track the operation */
3096     call->hold_msg = (void*) tdata;
3097 
3098     /* Send the request */
3099     status = pjsip_inv_send_msg( call->inv, tdata);
3100     if (status != PJ_SUCCESS) {
3101 	pjsua_perror(THIS_FILE, "Unable to send re-INVITE", status);
3102 	call->hold_msg = NULL;
3103 	goto on_return;
3104     }
3105 
3106     /* Set flag that local put the call on hold */
3107     call->local_hold = PJ_TRUE;
3108 
3109     /* Clear unhold flag */
3110     call->opt.flag &= ~PJSUA_CALL_UNHOLD;
3111 
3112 on_return:
3113     if (dlg) pjsip_dlg_dec_lock(dlg);
3114     pj_log_pop_indent();
3115     return status;
3116 }
3117 
3118 
3119 /*
3120  * Send re-INVITE (to release hold).
3121  */
pjsua_call_reinvite(pjsua_call_id call_id,unsigned options,const pjsua_msg_data * msg_data)3122 PJ_DEF(pj_status_t) pjsua_call_reinvite( pjsua_call_id call_id,
3123                                          unsigned options,
3124 					 const pjsua_msg_data *msg_data)
3125 {
3126     pjsua_call *call;
3127     pjsip_dialog *dlg = NULL;
3128     pj_status_t status;
3129 
3130     status = acquire_call("pjsua_call_reinvite()", call_id, &call, &dlg);
3131     if (status != PJ_SUCCESS)
3132 	goto on_return;
3133 
3134     if (options != call->opt.flag)
3135 	call->opt.flag = options;
3136 
3137     status = pjsua_call_reinvite2(call_id, &call->opt, msg_data);
3138 
3139 on_return:
3140     if (dlg) pjsip_dlg_dec_lock(dlg);
3141     return status;
3142 }
3143 
3144 
3145 /*
3146  * Send re-INVITE (to release hold).
3147  */
pjsua_call_reinvite2(pjsua_call_id call_id,const pjsua_call_setting * opt,const pjsua_msg_data * msg_data)3148 PJ_DEF(pj_status_t) pjsua_call_reinvite2(pjsua_call_id call_id,
3149                                          const pjsua_call_setting *opt,
3150 					 const pjsua_msg_data *msg_data)
3151 {
3152     pjmedia_sdp_session *sdp = NULL;
3153     pj_str_t *new_contact = NULL;
3154     pjsip_tx_data *tdata;
3155     pjsua_call *call;
3156     pjsip_dialog *dlg = NULL;
3157     pj_status_t status;
3158 
3159 
3160     PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
3161 		     PJ_EINVAL);
3162 
3163     PJ_LOG(4,(THIS_FILE, "Sending re-INVITE on call %d", call_id));
3164     pj_log_push_indent();
3165 
3166     status = acquire_call("pjsua_call_reinvite2()", call_id, &call, &dlg);
3167     if (status != PJ_SUCCESS)
3168 	goto on_return;
3169 
3170     if (pjsua_call_media_is_changing(call)) {
3171 	PJ_LOG(1,(THIS_FILE, "Unable to reinvite" ERR_MEDIA_CHANGING));
3172 	status = PJ_EINVALIDOP;
3173 	goto on_return;
3174     }
3175 
3176     if (call->inv->state != PJSIP_INV_STATE_CONFIRMED) {
3177 	PJ_LOG(3,(THIS_FILE, "Can not re-INVITE call that is not confirmed"));
3178 	status = PJSIP_ESESSIONSTATE;
3179 	goto on_return;
3180     }
3181 
3182     status = apply_call_setting(call, opt, NULL);
3183     if (status != PJ_SUCCESS) {
3184 	pjsua_perror(THIS_FILE, "Failed to apply call setting", status);
3185 	goto on_return;
3186     }
3187 
3188     /* Create SDP */
3189     if (call->local_hold && (call->opt.flag & PJSUA_CALL_UNHOLD)==0) {
3190 	status = create_sdp_of_call_hold(call, &sdp);
3191     } else if ((call->opt.flag & PJSUA_CALL_NO_SDP_OFFER) == 0) {
3192 	status = pjsua_media_channel_create_sdp(call->index,
3193 						call->inv->pool_prov,
3194 						NULL, &sdp, NULL);
3195     }
3196     if (status != PJ_SUCCESS) {
3197 	pjsua_perror(THIS_FILE, "Unable to get SDP from media endpoint",
3198 		     status);
3199 	goto on_return;
3200     }
3201 
3202     if ((call->opt.flag & PJSUA_CALL_UPDATE_CONTACT) &&
3203 	    pjsua_acc_is_valid(call->acc_id))
3204     {
3205 	call_update_contact(call, &new_contact);
3206     }
3207 
3208     if ((call->opt.flag & PJSUA_CALL_UPDATE_VIA) &&
3209 	pjsua_acc_is_valid(call->acc_id))
3210     {
3211     	dlg_set_via(call->inv->dlg, &pjsua_var.acc[call->acc_id]);
3212     }
3213 
3214     if ((call->opt.flag & PJSUA_CALL_UPDATE_TARGET) &&
3215 	msg_data && msg_data->target_uri.slen)
3216     {
3217 	status = dlg_set_target(dlg, &msg_data->target_uri);
3218 	if (status != PJ_SUCCESS) {
3219 	    pjsua_perror(THIS_FILE, "Unable to set new target", status);
3220 	    goto on_return;
3221 	}
3222     }
3223 
3224     /* Create re-INVITE with new offer */
3225     status = pjsip_inv_reinvite( call->inv, new_contact, sdp, &tdata);
3226     if (status != PJ_SUCCESS) {
3227 	pjsua_perror(THIS_FILE, "Unable to create re-INVITE", status);
3228 	goto on_return;
3229     }
3230 
3231     /* Add additional headers etc */
3232     pjsua_process_msg_data( tdata, msg_data);
3233 
3234     /* Send the request */
3235     call->med_update_success = PJ_FALSE;
3236     status = pjsip_inv_send_msg( call->inv, tdata);
3237     if (status == PJ_SUCCESS &&
3238         ((call->opt.flag & PJSUA_CALL_UNHOLD) &&
3239          (call->opt.flag & PJSUA_CALL_NO_SDP_OFFER) == 0))
3240     {
3241     	call->local_hold = PJ_FALSE;
3242     } else if (status != PJ_SUCCESS) {
3243 	pjsua_perror(THIS_FILE, "Unable to send re-INVITE", status);
3244 	goto on_return;
3245     }
3246 
3247 on_return:
3248     if (dlg) pjsip_dlg_dec_lock(dlg);
3249     pj_log_pop_indent();
3250     return status;
3251 }
3252 
3253 
3254 /*
3255  * Send UPDATE request.
3256  */
pjsua_call_update(pjsua_call_id call_id,unsigned options,const pjsua_msg_data * msg_data)3257 PJ_DEF(pj_status_t) pjsua_call_update( pjsua_call_id call_id,
3258 				       unsigned options,
3259 				       const pjsua_msg_data *msg_data)
3260 {
3261     pjsua_call *call;
3262     pjsip_dialog *dlg = NULL;
3263     pj_status_t status;
3264 
3265     status = acquire_call("pjsua_call_update()", call_id, &call, &dlg);
3266     if (status != PJ_SUCCESS)
3267 	goto on_return;
3268 
3269     if (options != call->opt.flag)
3270 	call->opt.flag = options;
3271 
3272     status = pjsua_call_update2(call_id, &call->opt, msg_data);
3273 
3274 on_return:
3275     if (dlg) pjsip_dlg_dec_lock(dlg);
3276     return status;
3277 }
3278 
3279 
3280 /*
3281  * Send UPDATE request.
3282  */
pjsua_call_update2(pjsua_call_id call_id,const pjsua_call_setting * opt,const pjsua_msg_data * msg_data)3283 PJ_DEF(pj_status_t) pjsua_call_update2(pjsua_call_id call_id,
3284 				       const pjsua_call_setting *opt,
3285 				       const pjsua_msg_data *msg_data)
3286 {
3287     pjmedia_sdp_session *sdp = NULL;
3288     pj_str_t *new_contact = NULL;
3289     pjsip_tx_data *tdata;
3290     pjsua_call *call;
3291     pjsip_dialog *dlg = NULL;
3292     pj_status_t status;
3293 
3294     PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
3295 		     PJ_EINVAL);
3296 
3297     PJ_LOG(4,(THIS_FILE, "Sending UPDATE on call %d", call_id));
3298     pj_log_push_indent();
3299 
3300     status = acquire_call("pjsua_call_update2()", call_id, &call, &dlg);
3301     if (status != PJ_SUCCESS)
3302 	goto on_return;
3303 
3304     /* Don't check media changing if UPDATE is sent without SDP */
3305     if (pjsua_call_media_is_changing(call) &&
3306 	(opt && opt->flag & PJSUA_CALL_NO_SDP_OFFER) == 0)
3307     {
3308 	PJ_LOG(1,(THIS_FILE, "Unable to send UPDATE" ERR_MEDIA_CHANGING));
3309 	status = PJ_EINVALIDOP;
3310 	goto on_return;
3311     }
3312 
3313     status = apply_call_setting(call, opt, NULL);
3314     if (status != PJ_SUCCESS) {
3315 	pjsua_perror(THIS_FILE, "Failed to apply call setting", status);
3316 	goto on_return;
3317     }
3318 
3319     /* Create SDP */
3320     if (call->local_hold && (call->opt.flag & PJSUA_CALL_UNHOLD)==0) {
3321 	status = create_sdp_of_call_hold(call, &sdp);
3322     } else if ((call->opt.flag & PJSUA_CALL_NO_SDP_OFFER) == 0) {
3323 	status = pjsua_media_channel_create_sdp(call->index,
3324 						call->inv->pool_prov,
3325 						NULL, &sdp, NULL);
3326     }
3327 
3328     if (status != PJ_SUCCESS) {
3329 	pjsua_perror(THIS_FILE, "Unable to get SDP from media endpoint",
3330 		     status);
3331 	goto on_return;
3332     }
3333 
3334     if ((call->opt.flag & PJSUA_CALL_UPDATE_CONTACT) &&
3335 	    pjsua_acc_is_valid(call->acc_id))
3336     {
3337 	call_update_contact(call, &new_contact);
3338     }
3339 
3340     if ((call->opt.flag & PJSUA_CALL_UPDATE_VIA) &&
3341 	pjsua_acc_is_valid(call->acc_id))
3342     {
3343 	dlg_set_via(call->inv->dlg, &pjsua_var.acc[call->acc_id]);
3344     }
3345 
3346     if ((call->opt.flag & PJSUA_CALL_UPDATE_TARGET) &&
3347 	msg_data && msg_data->target_uri.slen)
3348     {
3349 	status = dlg_set_target(dlg, &msg_data->target_uri);
3350 	if (status != PJ_SUCCESS) {
3351 	    pjsua_perror(THIS_FILE, "Unable to set new target", status);
3352 	    goto on_return;
3353 	}
3354     }
3355 
3356     /* Create UPDATE with new offer */
3357     status = pjsip_inv_update(call->inv, new_contact, sdp, &tdata);
3358     if (status != PJ_SUCCESS) {
3359 	pjsua_perror(THIS_FILE, "Unable to create UPDATE request", status);
3360 	goto on_return;
3361     }
3362 
3363     /* Add additional headers etc */
3364     pjsua_process_msg_data( tdata, msg_data);
3365 
3366     /* Send the request */
3367     call->med_update_success = PJ_FALSE;
3368     status = pjsip_inv_send_msg( call->inv, tdata);
3369     if (status == PJ_SUCCESS &&
3370         ((call->opt.flag & PJSUA_CALL_UNHOLD) &&
3371          (call->opt.flag & PJSUA_CALL_NO_SDP_OFFER) == 0))
3372     {
3373     	call->local_hold = PJ_FALSE;
3374     } else if (status != PJ_SUCCESS) {
3375 	pjsua_perror(THIS_FILE, "Unable to send UPDATE request", status);
3376 	goto on_return;
3377     }
3378 
3379 on_return:
3380     if (dlg) pjsip_dlg_dec_lock(dlg);
3381     pj_log_pop_indent();
3382     return status;
3383 }
3384 
3385 
3386 /*
3387  * Initiate call transfer to the specified address.
3388  */
pjsua_call_xfer(pjsua_call_id call_id,const pj_str_t * dest,const pjsua_msg_data * msg_data)3389 PJ_DEF(pj_status_t) pjsua_call_xfer( pjsua_call_id call_id,
3390 				     const pj_str_t *dest,
3391 				     const pjsua_msg_data *msg_data)
3392 {
3393     pjsip_evsub *sub;
3394     pjsip_tx_data *tdata;
3395     pjsua_call *call;
3396     pjsip_dialog *dlg = NULL;
3397     pjsip_generic_string_hdr *gs_hdr;
3398     const pj_str_t str_ref_by = { "Referred-By", 11 };
3399     struct pjsip_evsub_user xfer_cb;
3400     pj_status_t status;
3401 
3402 
3403     PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls &&
3404                      dest, PJ_EINVAL);
3405 
3406     PJ_LOG(4,(THIS_FILE, "Transferring call %d to %.*s", call_id,
3407 			 (int)dest->slen, dest->ptr));
3408     pj_log_push_indent();
3409 
3410     status = acquire_call("pjsua_call_xfer()", call_id, &call, &dlg);
3411     if (status != PJ_SUCCESS)
3412 	goto on_return;
3413 
3414     /* Create xfer client subscription. */
3415     pj_bzero(&xfer_cb, sizeof(xfer_cb));
3416     xfer_cb.on_evsub_state = &xfer_client_on_evsub_state;
3417 
3418     status = pjsip_xfer_create_uac(call->inv->dlg, &xfer_cb, &sub);
3419     if (status != PJ_SUCCESS) {
3420 	pjsua_perror(THIS_FILE, "Unable to create xfer", status);
3421 	goto on_return;
3422     }
3423 
3424     /* Associate this call with the client subscription */
3425     pjsip_evsub_set_mod_data(sub, pjsua_var.mod.id, call);
3426 
3427     /*
3428      * Create REFER request.
3429      */
3430     status = pjsip_xfer_initiate(sub, dest, &tdata);
3431     if (status != PJ_SUCCESS) {
3432 	pjsua_perror(THIS_FILE, "Unable to create REFER request", status);
3433 	goto on_return;
3434     }
3435 
3436     /* Add Referred-By header */
3437     gs_hdr = pjsip_generic_string_hdr_create(tdata->pool, &str_ref_by,
3438 					     &dlg->local.info_str);
3439     pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)gs_hdr);
3440 
3441 
3442     /* Add additional headers etc */
3443     pjsua_process_msg_data( tdata, msg_data);
3444 
3445     /* Send. */
3446     status = pjsip_xfer_send_request(sub, tdata);
3447     if (status != PJ_SUCCESS) {
3448 	pjsua_perror(THIS_FILE, "Unable to send REFER request", status);
3449 	goto on_return;
3450     }
3451 
3452     /* For simplicity (that's what this program is intended to be!),
3453      * leave the original invite session as it is. More advanced application
3454      * may want to hold the INVITE, or terminate the invite, or whatever.
3455      */
3456 on_return:
3457     if (dlg) pjsip_dlg_dec_lock(dlg);
3458     pj_log_pop_indent();
3459     return status;
3460 
3461 }
3462 
3463 
3464 /*
3465  * Initiate attended call transfer to the specified address.
3466  */
pjsua_call_xfer_replaces(pjsua_call_id call_id,pjsua_call_id dest_call_id,unsigned options,const pjsua_msg_data * msg_data)3467 PJ_DEF(pj_status_t) pjsua_call_xfer_replaces( pjsua_call_id call_id,
3468 					      pjsua_call_id dest_call_id,
3469 					      unsigned options,
3470 					      const pjsua_msg_data *msg_data)
3471 {
3472     pjsua_call *dest_call;
3473     pjsip_dialog *dest_dlg;
3474     char str_dest_buf[PJSIP_MAX_URL_SIZE*2];
3475     pj_str_t str_dest;
3476     int len;
3477     char call_id_dest_buf[PJSIP_MAX_URL_SIZE * 2];
3478     int call_id_len;
3479     pjsip_uri *uri;
3480     pj_status_t status;
3481     const pjsip_parser_const_t *pconst;
3482 
3483 
3484     PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
3485 		     PJ_EINVAL);
3486     PJ_ASSERT_RETURN(dest_call_id>=0 &&
3487 		      dest_call_id<(int)pjsua_var.ua_cfg.max_calls,
3488 		     PJ_EINVAL);
3489 
3490     PJ_LOG(4,(THIS_FILE, "Transferring call %d replacing with call %d",
3491 			 call_id, dest_call_id));
3492     pj_log_push_indent();
3493 
3494     status = acquire_call("pjsua_call_xfer_replaces()", dest_call_id,
3495 			  &dest_call, &dest_dlg);
3496     if (status != PJ_SUCCESS) {
3497 	pj_log_pop_indent();
3498 	return status;
3499     }
3500 
3501     /*
3502      * Create REFER destination URI with Replaces field.
3503      */
3504 
3505     /* Make sure we have sufficient buffer's length */
3506     PJ_ASSERT_ON_FAIL(dest_dlg->remote.info_str.slen +
3507 		      dest_dlg->call_id->id.slen +
3508 		      dest_dlg->remote.info->tag.slen +
3509 		      dest_dlg->local.info->tag.slen + 32
3510 		      < (long)sizeof(str_dest_buf),
3511 		      { status=PJSIP_EURITOOLONG; goto on_error; });
3512 
3513     /* Print URI */
3514     str_dest_buf[0] = '<';
3515     str_dest.slen = 1;
3516 
3517     uri = (pjsip_uri*) pjsip_uri_get_uri(dest_dlg->remote.info->uri);
3518     len = pjsip_uri_print(PJSIP_URI_IN_REQ_URI, uri,
3519 		          str_dest_buf+1, sizeof(str_dest_buf)-1);
3520     if (len < 0) {
3521 	status = PJSIP_EURITOOLONG;
3522 	goto on_error;
3523     }
3524 
3525     str_dest.slen += len;
3526 
3527     /* This uses the the same scanner definition used for SIP parsing
3528      * to escape the call-id in the refer.
3529      *
3530      * A common pattern for call-ids is: name@domain. The '@' character,
3531      * when used in a URL parameter, throws off many SIP parsers.
3532      * URL escape it based off of the allowed characters for header values.
3533     */
3534     pconst = pjsip_parser_const();
3535     call_id_len = (int)pj_strncpy2_escape(call_id_dest_buf, &dest_dlg->call_id->id,
3536      					  PJ_ARRAY_SIZE(call_id_dest_buf),
3537      					  &pconst->pjsip_HDR_CHAR_SPEC);
3538     if (call_id_len < 0) {
3539     	status = PJSIP_EURITOOLONG;
3540     	goto on_error;
3541     }
3542 
3543     /* Build the URI */
3544     len = pj_ansi_snprintf(str_dest_buf + str_dest.slen,
3545 			   sizeof(str_dest_buf) - str_dest.slen,
3546 			   "?%s"
3547 			   "Replaces=%.*s"
3548 			   "%%3Bto-tag%%3D%.*s"
3549 			   "%%3Bfrom-tag%%3D%.*s>",
3550 			   ((options&PJSUA_XFER_NO_REQUIRE_REPLACES) ?
3551 			    "" : "Require=replaces&"),
3552 			   call_id_len,
3553 			   call_id_dest_buf,
3554 			   (int)dest_dlg->remote.info->tag.slen,
3555 			   dest_dlg->remote.info->tag.ptr,
3556 			   (int)dest_dlg->local.info->tag.slen,
3557 			   dest_dlg->local.info->tag.ptr);
3558 
3559     PJ_ASSERT_ON_FAIL(len > 0 && len <= (int)sizeof(str_dest_buf)-str_dest.slen,
3560 		      { status=PJSIP_EURITOOLONG; goto on_error; });
3561 
3562     str_dest.ptr = str_dest_buf;
3563     str_dest.slen += len;
3564 
3565     pjsip_dlg_dec_lock(dest_dlg);
3566 
3567     status = pjsua_call_xfer(call_id, &str_dest, msg_data);
3568 
3569     pj_log_pop_indent();
3570     return status;
3571 
3572 on_error:
3573     if (dest_dlg) pjsip_dlg_dec_lock(dest_dlg);
3574     pj_log_pop_indent();
3575     return status;
3576 }
3577 
3578 /*
3579  * Send DTMF digits to remote.
3580  */
pjsua_call_send_dtmf(pjsua_call_id call_id,const pjsua_call_send_dtmf_param * param)3581 PJ_DEF(pj_status_t) pjsua_call_send_dtmf(pjsua_call_id call_id,
3582  				       const pjsua_call_send_dtmf_param *param)
3583 {
3584     pj_status_t status = PJ_EINVAL;
3585 
3586     PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls &&
3587 		     param, PJ_EINVAL);
3588 
3589     PJ_LOG(4,(THIS_FILE, "Call %d sending DTMF %.*s using %s method",
3590     		       call_id, (int)param->digits.slen, param->digits.ptr,
3591 		       get_dtmf_method_name(param->method)));
3592 
3593     if (param->method == PJSUA_DTMF_METHOD_RFC2833) {
3594 	status = pjsua_call_dial_dtmf(call_id, &param->digits);
3595     } else if (param->method == PJSUA_DTMF_METHOD_SIP_INFO) {
3596 	const pj_str_t SIP_INFO = pj_str("INFO");
3597 	int i;
3598 
3599 	for (i = 0; i < param->digits.slen; ++i) {
3600 	    char body[80];
3601 	    pjsua_msg_data msg_data_;
3602 
3603 	    pjsua_msg_data_init(&msg_data_);
3604 	    msg_data_.content_type = pj_str("application/dtmf-relay");
3605 
3606 	    pj_ansi_snprintf(body, sizeof(body),
3607 			     "Signal=%c\r\n"
3608 			     "Duration=%d",
3609 			     param->digits.ptr[i], param->duration);
3610 	    msg_data_.msg_body = pj_str(body);
3611 
3612 	    status = pjsua_call_send_request(call_id, &SIP_INFO, &msg_data_);
3613 	}
3614     }
3615 
3616     return status;
3617 }
3618 
3619 /**
3620  * Send instant messaging inside INVITE session.
3621  */
pjsua_call_send_im(pjsua_call_id call_id,const pj_str_t * mime_type,const pj_str_t * content,const pjsua_msg_data * msg_data,void * user_data)3622 PJ_DEF(pj_status_t) pjsua_call_send_im( pjsua_call_id call_id,
3623 					const pj_str_t *mime_type,
3624 					const pj_str_t *content,
3625 					const pjsua_msg_data *msg_data,
3626 					void *user_data)
3627 {
3628     pjsua_call *call;
3629     pjsip_dialog *dlg = NULL;
3630     const pj_str_t mime_text_plain = pj_str("text/plain");
3631     pjsip_media_type ctype;
3632     pjsua_im_data *im_data;
3633     pjsip_tx_data *tdata;
3634     pj_bool_t content_in_msg_data;
3635     pj_status_t status;
3636 
3637     content_in_msg_data = msg_data && (msg_data->msg_body.slen ||
3638 				       msg_data->multipart_ctype.type.slen);
3639 
3640     PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
3641 		     PJ_EINVAL);
3642 
3643     /* Message body must be specified. */
3644     PJ_ASSERT_RETURN(content || content_in_msg_data, PJ_EINVAL);
3645 
3646     if (content) {
3647 	PJ_LOG(4,(THIS_FILE, "Call %d sending %d bytes MESSAGE..",
3648         		      call_id, (int)content->slen));
3649     } else {
3650 	PJ_LOG(4,(THIS_FILE, "Call %d sending MESSAGE..",
3651         		      call_id));
3652     }
3653 
3654     pj_log_push_indent();
3655 
3656     status = acquire_call("pjsua_call_send_im()", call_id, &call, &dlg);
3657     if (status != PJ_SUCCESS)
3658 	goto on_return;
3659 
3660     /* Create request message. */
3661     status = pjsip_dlg_create_request( call->inv->dlg, &pjsip_message_method,
3662 				       -1, &tdata);
3663     if (status != PJ_SUCCESS) {
3664 	pjsua_perror(THIS_FILE, "Unable to create MESSAGE request", status);
3665 	goto on_return;
3666     }
3667 
3668     /* Add accept header. */
3669     pjsip_msg_add_hdr( tdata->msg,
3670 		       (pjsip_hdr*)pjsua_im_create_accept(tdata->pool));
3671 
3672     /* Add message body, if content is set */
3673     if (content) {
3674 	/* Set default media type if none is specified */
3675 	if (mime_type == NULL) {
3676 	    mime_type = &mime_text_plain;
3677 	}
3678 
3679 	/* Parse MIME type */
3680 	pjsua_parse_media_type(tdata->pool, mime_type, &ctype);
3681 
3682 	/* Create "text/plain" message body. */
3683 	tdata->msg->body = pjsip_msg_body_create( tdata->pool, &ctype.type,
3684 						  &ctype.subtype, content);
3685 	if (tdata->msg->body == NULL) {
3686 	    pjsua_perror(THIS_FILE, "Unable to create msg body", PJ_ENOMEM);
3687 	    pjsip_tx_data_dec_ref(tdata);
3688 	    goto on_return;
3689 	}
3690     }
3691 
3692     /* Add additional headers etc */
3693     pjsua_process_msg_data( tdata, msg_data);
3694 
3695     /* Create IM data and attach to the request. */
3696     im_data = PJ_POOL_ZALLOC_T(tdata->pool, pjsua_im_data);
3697     im_data->acc_id = call->acc_id;
3698     im_data->call_id = call_id;
3699     im_data->to = call->inv->dlg->remote.info_str;
3700     if (content)
3701 	pj_strdup_with_null(tdata->pool, &im_data->body, content);
3702     im_data->user_data = user_data;
3703 
3704 
3705     /* Send the request. */
3706     status = pjsip_dlg_send_request( call->inv->dlg, tdata,
3707 				     pjsua_var.mod.id, im_data);
3708     if (status != PJ_SUCCESS) {
3709 	pjsua_perror(THIS_FILE, "Unable to send MESSAGE request", status);
3710 	goto on_return;
3711     }
3712 
3713 on_return:
3714     if (dlg) pjsip_dlg_dec_lock(dlg);
3715     pj_log_pop_indent();
3716     return status;
3717 }
3718 
3719 
3720 /*
3721  * Send IM typing indication inside INVITE session.
3722  */
pjsua_call_send_typing_ind(pjsua_call_id call_id,pj_bool_t is_typing,const pjsua_msg_data * msg_data)3723 PJ_DEF(pj_status_t) pjsua_call_send_typing_ind( pjsua_call_id call_id,
3724 						pj_bool_t is_typing,
3725 						const pjsua_msg_data*msg_data)
3726 {
3727     pjsua_call *call;
3728     pjsip_dialog *dlg = NULL;
3729     pjsip_tx_data *tdata;
3730     pj_status_t status;
3731 
3732     PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
3733 		     PJ_EINVAL);
3734 
3735     PJ_LOG(4,(THIS_FILE, "Call %d sending typing indication..",
3736             	          call_id));
3737     pj_log_push_indent();
3738 
3739     status = acquire_call("pjsua_call_send_typing_ind", call_id, &call, &dlg);
3740     if (status != PJ_SUCCESS)
3741 	goto on_return;
3742 
3743     /* Create request message. */
3744     status = pjsip_dlg_create_request( call->inv->dlg, &pjsip_message_method,
3745 				       -1, &tdata);
3746     if (status != PJ_SUCCESS) {
3747 	pjsua_perror(THIS_FILE, "Unable to create MESSAGE request", status);
3748 	goto on_return;
3749     }
3750 
3751     /* Create "application/im-iscomposing+xml" msg body. */
3752     tdata->msg->body = pjsip_iscomposing_create_body(tdata->pool, is_typing,
3753 						     NULL, NULL, -1);
3754 
3755     /* Add additional headers etc */
3756     pjsua_process_msg_data( tdata, msg_data);
3757 
3758     /* Send the request. */
3759     status = pjsip_dlg_send_request( call->inv->dlg, tdata, -1, NULL);
3760     if (status != PJ_SUCCESS) {
3761 	pjsua_perror(THIS_FILE, "Unable to send MESSAGE request", status);
3762 	goto on_return;
3763     }
3764 
3765 on_return:
3766     if (dlg) pjsip_dlg_dec_lock(dlg);
3767     pj_log_pop_indent();
3768     return status;
3769 }
3770 
3771 
3772 /*
3773  * Send arbitrary request.
3774  */
pjsua_call_send_request(pjsua_call_id call_id,const pj_str_t * method_str,const pjsua_msg_data * msg_data)3775 PJ_DEF(pj_status_t) pjsua_call_send_request(pjsua_call_id call_id,
3776 					    const pj_str_t *method_str,
3777 					    const pjsua_msg_data *msg_data)
3778 {
3779     pjsua_call *call;
3780     pjsip_dialog *dlg = NULL;
3781     pjsip_method method;
3782     pjsip_tx_data *tdata;
3783     pj_status_t status;
3784 
3785     PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
3786 		     PJ_EINVAL);
3787 
3788     PJ_LOG(4,(THIS_FILE, "Call %d sending %.*s request..",
3789             	          call_id, (int)method_str->slen, method_str->ptr));
3790     pj_log_push_indent();
3791 
3792     status = acquire_call("pjsua_call_send_request", call_id, &call, &dlg);
3793     if (status != PJ_SUCCESS)
3794 	goto on_return;
3795 
3796     /* Init method */
3797     pjsip_method_init_np(&method, (pj_str_t*)method_str);
3798 
3799     /* Create request message. */
3800     status = pjsip_dlg_create_request( call->inv->dlg, &method, -1, &tdata);
3801     if (status != PJ_SUCCESS) {
3802 	pjsua_perror(THIS_FILE, "Unable to create request", status);
3803 	goto on_return;
3804     }
3805 
3806     /* Add additional headers etc */
3807     pjsua_process_msg_data( tdata, msg_data);
3808 
3809     /* Send the request. */
3810     status = pjsip_dlg_send_request( call->inv->dlg, tdata, -1, NULL);
3811     if (status != PJ_SUCCESS) {
3812 	pjsua_perror(THIS_FILE, "Unable to send request", status);
3813 	goto on_return;
3814     }
3815 
3816 on_return:
3817     if (dlg) pjsip_dlg_dec_lock(dlg);
3818     pj_log_pop_indent();
3819     return status;
3820 }
3821 
3822 
3823 /*
3824  * Terminate all calls.
3825  */
pjsua_call_hangup_all(void)3826 PJ_DEF(void) pjsua_call_hangup_all(void)
3827 {
3828     unsigned i;
3829 
3830     PJ_LOG(4,(THIS_FILE, "Hangup all calls.."));
3831     pj_log_push_indent();
3832 
3833     // This may deadlock, see https://trac.pjsip.org/repos/ticket/1305
3834     //PJSUA_LOCK();
3835 
3836     for (i=0; i<pjsua_var.ua_cfg.max_calls; ++i) {
3837 	if (pjsua_var.calls[i].inv)
3838 	    pjsua_call_hangup(i, 0, NULL, NULL);
3839     }
3840 
3841     //PJSUA_UNLOCK();
3842     pj_log_pop_indent();
3843 }
3844 
3845 
3846 /* Timer callback to send re-INVITE/UPDATE to lock codec or ICE update */
reinv_timer_cb(pj_timer_heap_t * th,pj_timer_entry * entry)3847 static void reinv_timer_cb(pj_timer_heap_t *th, pj_timer_entry *entry)
3848 {
3849     pjsua_call_id call_id = (pjsua_call_id)(pj_size_t)entry->user_data;
3850     pjsip_dialog *dlg;
3851     pjsua_call *call;
3852     pj_status_t status;
3853 
3854     PJ_UNUSED_ARG(th);
3855 
3856     pjsua_var.calls[call_id].reinv_timer.id = PJ_FALSE;
3857 
3858     pj_log_push_indent();
3859 
3860     status = acquire_call("reinv_timer_cb()", call_id, &call, &dlg);
3861     if (status != PJ_SUCCESS) {
3862 	pj_log_pop_indent();
3863 	return;
3864     }
3865 
3866     process_pending_reinvite(call);
3867 
3868     pjsip_dlg_dec_lock(dlg);
3869 
3870     pj_log_pop_indent();
3871 }
3872 
3873 
3874 /* Check if the specified format can be skipped in counting codecs */
is_non_av_fmt(const pjmedia_sdp_media * m,const pj_str_t * fmt)3875 static pj_bool_t is_non_av_fmt(const pjmedia_sdp_media *m,
3876 			       const pj_str_t *fmt)
3877 {
3878     const pj_str_t STR_TEL = {"telephone-event", 15};
3879     unsigned pt;
3880 
3881     pt = pj_strtoul(fmt);
3882 
3883     /* Check for comfort noise */
3884     if (pt == PJMEDIA_RTP_PT_CN)
3885 	return PJ_TRUE;
3886 
3887     /* Dynamic PT, check the format name */
3888     if (pt >= 96) {
3889 	pjmedia_sdp_attr *a;
3890 	pjmedia_sdp_rtpmap rtpmap;
3891 
3892 	/* Get the format name */
3893 	a = pjmedia_sdp_attr_find2(m->attr_count, m->attr, "rtpmap", fmt);
3894 	if (a && pjmedia_sdp_attr_get_rtpmap(a, &rtpmap)==PJ_SUCCESS) {
3895 	    /* Check for telephone-event */
3896 	    if (pj_stricmp(&rtpmap.enc_name, &STR_TEL)==0)
3897 		return PJ_TRUE;
3898 	} else {
3899 	    /* Invalid SDP, should not reach here */
3900 	    pj_assert(!"SDP should have been validated!");
3901 	    return PJ_TRUE;
3902 	}
3903     }
3904 
3905     return PJ_FALSE;
3906 }
3907 
3908 
3909 /* Schedule check for the need of re-INVITE/UPDATE after media update, cases:
3910  * - lock codec if remote answerer has given us more than one codecs
3911  * - update ICE default transport address if it has changed after ICE
3912  *   connectivity check.
3913  */
pjsua_call_schedule_reinvite_check(pjsua_call * call,unsigned delay_ms)3914 void pjsua_call_schedule_reinvite_check(pjsua_call *call, unsigned delay_ms)
3915 {
3916     pj_time_val delay;
3917 
3918     /* Stop reinvite timer, if it is active */
3919     if (call->reinv_timer.id)
3920 	pjsua_cancel_timer(&call->reinv_timer);
3921 
3922     delay.sec = 0;
3923     delay.msec = delay_ms;
3924     pj_time_val_normalize(&delay);
3925     call->reinv_timer.id = PJ_TRUE;
3926     pjsua_schedule_timer(&call->reinv_timer, &delay);
3927 }
3928 
3929 
3930 /* Check if lock codec is needed */
check_lock_codec(pjsua_call * call)3931 static pj_bool_t check_lock_codec(pjsua_call *call)
3932 {
3933     const pjmedia_sdp_session *local_sdp, *remote_sdp;
3934     pj_bool_t has_mult_fmt = PJ_FALSE;
3935     unsigned i;
3936     pj_status_t status;
3937 
3938     /* Check if lock codec is disabled */
3939     if (!pjsua_var.acc[call->acc_id].cfg.lock_codec)
3940 	return PJ_FALSE;
3941 
3942     /* Check lock codec retry count */
3943     if (call->lock_codec.retry_cnt >= LOCK_CODEC_MAX_RETRY)
3944         return PJ_FALSE;
3945 
3946     /* Check if we are the answerer, we shouldn't need to lock codec */
3947     if (!call->inv->neg || !pjmedia_sdp_neg_was_answer_remote(call->inv->neg))
3948         return PJ_FALSE;
3949 
3950     /* Check if remote answerer has given us more than one codecs. */
3951     status = pjmedia_sdp_neg_get_active_local(call->inv->neg, &local_sdp);
3952     if (status != PJ_SUCCESS)
3953 	return PJ_FALSE;
3954     status = pjmedia_sdp_neg_get_active_remote(call->inv->neg, &remote_sdp);
3955     if (status != PJ_SUCCESS)
3956 	return PJ_FALSE;
3957 
3958     for (i = 0; i < call->med_cnt && !has_mult_fmt; ++i) {
3959 	pjsua_call_media *call_med = &call->media[i];
3960 	const pjmedia_sdp_media *rem_m, *loc_m;
3961 	unsigned codec_cnt = 0;
3962 	unsigned j;
3963 
3964 	/* Skip this if the media is inactive or error */
3965 	if (call_med->state == PJSUA_CALL_MEDIA_NONE ||
3966 	    call_med->state == PJSUA_CALL_MEDIA_ERROR ||
3967 	    call_med->dir == PJMEDIA_DIR_NONE)
3968 	{
3969 	    continue;
3970 	}
3971 
3972 	/* Remote may answer with less media lines. */
3973 	if (i >= remote_sdp->media_count)
3974 	    continue;
3975 
3976 	rem_m = remote_sdp->media[i];
3977 	loc_m = local_sdp->media[i];
3978 
3979 	/* Verify that media must be active. */
3980 	pj_assert(loc_m->desc.port && rem_m->desc.port);
3981 	PJ_UNUSED_ARG(loc_m);
3982 
3983 	/* Count the formats in the answer. */
3984 	for (j=0; j<rem_m->desc.fmt_count && codec_cnt <= 1; ++j) {
3985 	    if (!is_non_av_fmt(rem_m, &rem_m->desc.fmt[j]) && ++codec_cnt > 1)
3986 		has_mult_fmt = PJ_TRUE;
3987 	}
3988     }
3989 
3990     /* Reset retry count when remote answer has one codec */
3991     if (!has_mult_fmt)
3992 	call->lock_codec.retry_cnt = 0;
3993 
3994     return has_mult_fmt;
3995 }
3996 
3997 /* Check if ICE setup is complete and if it needs to send reinvite */
check_ice_complete(pjsua_call * call,pj_bool_t * need_reinv)3998 static pj_bool_t check_ice_complete(pjsua_call *call, pj_bool_t *need_reinv)
3999 {
4000     pj_bool_t ice_need_reinv = PJ_FALSE;
4001     pj_bool_t ice_complete = PJ_TRUE;
4002     unsigned i;
4003 
4004     /* Check if ICE setup is complete and if it needs reinvite */
4005     for (i = 0; i < call->med_cnt; ++i) {
4006 	pjsua_call_media *call_med = &call->media[i];
4007 	pjmedia_transport_info tpinfo;
4008 	pjmedia_ice_transport_info *ice_info;
4009 
4010 	if (call_med->tp_st == PJSUA_MED_TP_NULL ||
4011 	    call_med->tp_st == PJSUA_MED_TP_DISABLED ||
4012 	    call_med->state == PJSUA_CALL_MEDIA_ERROR)
4013 	{
4014 	    continue;
4015 	}
4016 
4017 	pjmedia_transport_info_init(&tpinfo);
4018 	pjmedia_transport_get_info(call_med->tp, &tpinfo);
4019 	ice_info = (pjmedia_ice_transport_info*)
4020 		   pjmedia_transport_info_get_spc_info(
4021 					&tpinfo, PJMEDIA_TRANSPORT_TYPE_ICE);
4022 
4023 	/* Check if ICE is active */
4024 	if (!ice_info || !ice_info->active)
4025 	    continue;
4026 
4027 	/* Check if ICE setup not completed yet */
4028 	if (ice_info->sess_state < PJ_ICE_STRANS_STATE_RUNNING)	{
4029 	    ice_complete = PJ_FALSE;
4030 	    break;
4031 	}
4032 
4033 	/* Check if ICE needs to send reinvite */
4034 	if (!ice_need_reinv &&
4035 	    ice_info->sess_state == PJ_ICE_STRANS_STATE_RUNNING &&
4036 	    ice_info->role == PJ_ICE_SESS_ROLE_CONTROLLING)
4037 	{
4038 	    pjsua_ice_config *cfg=&pjsua_var.acc[call->acc_id].cfg.ice_cfg;
4039 	    if ((cfg->ice_always_update && !call->reinv_ice_sent) ||
4040 		pj_sockaddr_cmp(&tpinfo.sock_info.rtp_addr_name,
4041 				&call_med->rtp_addr))
4042 	    {
4043 		ice_need_reinv = PJ_TRUE;
4044 	    }
4045 	}
4046     }
4047 
4048     if (ice_complete && need_reinv)
4049 	*need_reinv = ice_need_reinv;
4050 
4051     return ice_complete;
4052 }
4053 
4054 /* Check and send reinvite for lock codec and ICE update */
process_pending_reinvite(pjsua_call * call)4055 static pj_status_t process_pending_reinvite(pjsua_call *call)
4056 {
4057     const pj_str_t ST_UPDATE = {"UPDATE", 6};
4058     pj_pool_t *pool = call->inv->pool_prov;
4059     pjsip_inv_session *inv = call->inv;
4060     pj_bool_t ice_need_reinv;
4061     pj_bool_t ice_completed;
4062     pj_bool_t need_lock_codec;
4063     pj_bool_t rem_can_update;
4064     pjmedia_sdp_session *new_offer;
4065     pjsip_tx_data *tdata;
4066     unsigned i;
4067     pj_status_t status;
4068 
4069     /* Verify if another SDP negotiation is in progress, e.g: session timer
4070      * or another re-INVITE.
4071      */
4072     if (inv==NULL || inv->neg==NULL ||
4073 	pjmedia_sdp_neg_get_state(inv->neg)!=PJMEDIA_SDP_NEG_STATE_DONE)
4074     {
4075 	return PJMEDIA_SDPNEG_EINSTATE;
4076     }
4077 
4078     /* Don't do this if call is disconnecting! */
4079     if (inv->state > PJSIP_INV_STATE_CONFIRMED || inv->cause >= 200)
4080     {
4081 	return PJ_EINVALIDOP;
4082     }
4083 
4084     /* Delay this when the SDP negotiation done in call state EARLY and
4085      * remote does not support UPDATE method.
4086      */
4087     if (inv->state == PJSIP_INV_STATE_EARLY &&
4088 	pjsip_dlg_remote_has_cap(inv->dlg, PJSIP_H_ALLOW, NULL, &ST_UPDATE)!=
4089 	PJSIP_DIALOG_CAP_SUPPORTED)
4090     {
4091         call->reinv_pending = PJ_TRUE;
4092         return PJ_EPENDING;
4093     }
4094 
4095     /* Check if ICE setup is complete and if it needs reinvite */
4096     ice_completed = check_ice_complete(call, &ice_need_reinv);
4097     if (!ice_completed)
4098 	return PJ_EPENDING;
4099 
4100     /* Check if we need to lock codec */
4101     need_lock_codec = check_lock_codec(call);
4102 
4103     /* Check if reinvite is really needed */
4104     if (!need_lock_codec && !ice_need_reinv)
4105 	return PJ_SUCCESS;
4106 
4107 
4108     /* Okay! So we need to send re-INVITE/UPDATE */
4109 
4110     /* Check if remote support UPDATE */
4111     rem_can_update = pjsip_dlg_remote_has_cap(inv->dlg, PJSIP_H_ALLOW, NULL,
4112 					      &ST_UPDATE) ==
4113 						PJSIP_DIALOG_CAP_SUPPORTED;
4114 
4115     /* Logging stuff */
4116     {
4117 	const char *ST_ICE_UPDATE = "ICE transport address after "
4118 				    "ICE negotiation";
4119 	const char *ST_LOCK_CODEC = "media session to use only one codec";
4120 	PJ_LOG(4,(THIS_FILE, "Call %d sending %s for updating %s%s%s",
4121 		  call->index,
4122 		  (rem_can_update? "UPDATE" : "re-INVITE"),
4123 		  (ice_need_reinv? ST_ICE_UPDATE : ST_LOCK_CODEC),
4124 		  (ice_need_reinv && need_lock_codec? " and " : ""),
4125 		  (ice_need_reinv && need_lock_codec? ST_LOCK_CODEC : "")
4126 		  ));
4127     }
4128 
4129     /* Generate SDP re-offer */
4130     status = pjsua_media_channel_create_sdp(call->index, pool, NULL,
4131 					    &new_offer, NULL);
4132     if (status != PJ_SUCCESS) {
4133 	pjsua_perror(THIS_FILE, "Unable to create local SDP", status);
4134 	return status;
4135     }
4136 
4137     /* Update the new offer so it contains only a codec. Note that
4138      * SDP nego has removed unmatched codecs from the offer and the codec
4139      * order in the offer has been matched to the answer, so we'll override
4140      * the codecs in the just generated SDP with the ones from the active
4141      * local SDP and leave just one codec for the next SDP re-offer.
4142      */
4143     if (need_lock_codec) {
4144 	const pjmedia_sdp_session *ref_sdp;
4145 
4146 	/* Get local active SDP as reference */
4147 	status = pjmedia_sdp_neg_get_active_local(call->inv->neg, &ref_sdp);
4148 	if (status != PJ_SUCCESS)
4149 	    return status;
4150 
4151 	/* Verify media count. Note that remote may add/remove media line
4152 	 * in the answer. When answer has less media, it must have been
4153 	 * handled by pjsua_media_channel_update() as disabled media.
4154 	 * When answer has more media, it must have been ignored (treated
4155 	 * as non-exist) anywhere. Local media count should not be updated
4156 	 * at this point, as modifying media count operation (i.e: reinvite,
4157 	 * update, vid_set_strm) is currently blocking, protected with
4158 	 * dialog mutex, and eventually reset SDP nego state to LOCAL OFFER.
4159 	 */
4160 	if (call->med_cnt != ref_sdp->media_count ||
4161 	    ref_sdp->media_count != new_offer->media_count)
4162 	{
4163 	    /* Anyway, just in case, let's just return error */
4164 	    return PJMEDIA_SDPNEG_EINSTATE;
4165 	}
4166 
4167 	for (i = 0; i < call->med_cnt; ++i) {
4168 	    unsigned j, codec_cnt = 0;
4169 	    const pjmedia_sdp_media *ref_m = ref_sdp->media[i];
4170 	    pjmedia_sdp_media *m = new_offer->media[i];
4171 	    pjsua_call_media *call_med = &call->media[i];
4172 
4173 	    /* Verify if media is deactivated */
4174 	    if (call_med->state == PJSUA_CALL_MEDIA_NONE ||
4175 		call_med->state == PJSUA_CALL_MEDIA_ERROR ||
4176 		call_med->dir == PJMEDIA_DIR_NONE)
4177 	    {
4178 		continue;
4179 	    }
4180 
4181 	    /* Reset formats */
4182 	    m->desc.fmt_count = 0;
4183 	    pjmedia_sdp_attr_remove_all(&m->attr_count, m->attr, "rtpmap");
4184 	    pjmedia_sdp_attr_remove_all(&m->attr_count, m->attr, "fmtp");
4185 
4186 	    /* Copy only the first format + any non-AV formats from
4187 	     * the active local SDP.
4188 	     */
4189 	    for (j = 0; j < ref_m->desc.fmt_count; ++j) {
4190 		const pj_str_t *fmt = &ref_m->desc.fmt[j];
4191 
4192 		if (is_non_av_fmt(ref_m, fmt) || (++codec_cnt == 1)) {
4193 		    pjmedia_sdp_attr *a;
4194 
4195 		    m->desc.fmt[m->desc.fmt_count++] = *fmt;
4196 		    a = pjmedia_sdp_attr_find2(ref_m->attr_count, ref_m->attr,
4197 					       "rtpmap", fmt);
4198 		    if (a) {
4199 		        pjmedia_sdp_attr_add(&m->attr_count, m->attr,
4200 		    			     pjmedia_sdp_attr_clone(pool, a));
4201 		    }
4202 		    a = pjmedia_sdp_attr_find2(ref_m->attr_count, ref_m->attr,
4203 					       "fmtp", fmt);
4204 		    if (a) {
4205 		        pjmedia_sdp_attr_add(&m->attr_count, m->attr,
4206 		        		     pjmedia_sdp_attr_clone(pool, a));
4207 		    }
4208 		}
4209 	    }
4210 	}
4211     }
4212 
4213     /* Put back original direction and "c=0.0.0.0" line */
4214     {
4215 	const pjmedia_sdp_session *cur_sdp;
4216 
4217 	/* Get local active SDP */
4218 	status = pjmedia_sdp_neg_get_active_local(call->inv->neg, &cur_sdp);
4219 	if (status != PJ_SUCCESS)
4220 	    return status;
4221 
4222 	/* Make sure media count has not been changed */
4223 	if (call->med_cnt != cur_sdp->media_count)
4224 	    return PJMEDIA_SDPNEG_EINSTATE;
4225 
4226 	for (i = 0; i < call->med_cnt; ++i) {
4227 	    const pjmedia_sdp_media *m = cur_sdp->media[i];
4228 	    pjmedia_sdp_media *new_m = new_offer->media[i];
4229 	    pjsua_call_media *call_med = &call->media[i];
4230 	    pjmedia_sdp_attr *a = NULL;
4231 
4232 	    /* Update direction to the current dir */
4233 	    pjmedia_sdp_media_remove_all_attr(new_m, "sendrecv");
4234 	    pjmedia_sdp_media_remove_all_attr(new_m, "sendonly");
4235 	    pjmedia_sdp_media_remove_all_attr(new_m, "recvonly");
4236 	    pjmedia_sdp_media_remove_all_attr(new_m, "inactive");
4237 
4238 	    if (call_med->dir == PJMEDIA_DIR_ENCODING_DECODING) {
4239 		a = pjmedia_sdp_attr_create(pool, "sendrecv", NULL);
4240 	    } else if (call_med->dir == PJMEDIA_DIR_ENCODING) {
4241 		a = pjmedia_sdp_attr_create(pool, "sendonly", NULL);
4242 	    } else if (call_med->dir == PJMEDIA_DIR_DECODING) {
4243 		a = pjmedia_sdp_attr_create(pool, "recvonly", NULL);
4244 	    } else {
4245 		const pjmedia_sdp_conn *conn;
4246 		a = pjmedia_sdp_attr_create(pool, "inactive", NULL);
4247 
4248 		/* Also check if the original c= line address is zero */
4249 		conn = m->conn;
4250 		if (!conn)
4251 		    conn = cur_sdp->conn;
4252 		if (pj_strcmp2(&conn->addr, "0.0.0.0")==0 ||
4253 		    pj_strcmp2(&conn->addr, "0")==0)
4254 		{
4255 		    if (!new_m->conn) {
4256 			new_m->conn = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_conn);
4257 		    }
4258 
4259 		    if (pj_strcmp2(&new_m->conn->addr, "0.0.0.0")) {
4260 			new_m->conn->net_type = pj_str("IN");
4261 			new_m->conn->addr_type = pj_str("IP4");
4262 			new_m->conn->addr = pj_str("0.0.0.0");
4263 		    }
4264 		}
4265 	    }
4266 
4267 	    pj_assert(a);
4268 	    pjmedia_sdp_media_add_attr(new_m, a);
4269 	}
4270     }
4271 
4272 
4273     if (rem_can_update) {
4274 	status = pjsip_inv_update(inv, NULL, new_offer, &tdata);
4275     } else {
4276 	status = pjsip_inv_reinvite(inv, NULL, new_offer, &tdata);
4277     }
4278 
4279     if (status==PJ_EINVALIDOP &&
4280 	++call->lock_codec.retry_cnt < LOCK_CODEC_MAX_RETRY)
4281     {
4282 	/* Ups, let's reschedule again */
4283 	pjsua_call_schedule_reinvite_check(call, LOCK_CODEC_RETRY_INTERVAL);
4284 	return PJ_SUCCESS;
4285     } else if (status != PJ_SUCCESS) {
4286 	pjsua_perror(THIS_FILE, "Error creating UPDATE/re-INVITE",
4287 		     status);
4288 	return status;
4289     }
4290 
4291     /* Send the UPDATE/re-INVITE request */
4292     status = pjsip_inv_send_msg(inv, tdata);
4293     if (status != PJ_SUCCESS) {
4294 	pjsua_perror(THIS_FILE, "Error sending UPDATE/re-INVITE",
4295 		     status);
4296 	return status;
4297     }
4298 
4299     /* Update flags */
4300     if (ice_need_reinv)
4301 	call->reinv_ice_sent = PJ_TRUE;
4302     if (need_lock_codec)
4303 	++call->lock_codec.retry_cnt;
4304 
4305     return PJ_SUCCESS;
4306 }
4307 
4308 
trickle_ice_retrans_18x(pj_timer_heap_t * th,struct pj_timer_entry * te)4309 static void trickle_ice_retrans_18x(pj_timer_heap_t *th,
4310 				    struct pj_timer_entry *te)
4311 {
4312     pjsua_call *call = (pjsua_call*)te->user_data;
4313     pjsip_tx_data *tdata = NULL;
4314     pj_time_val delay;
4315 
4316     PJ_UNUSED_ARG(th);
4317 
4318     /* If trickling has been started or dialog has been established on
4319      * both sides, stop 18x retransmission.
4320      */
4321     if (call->trickle_ice.trickling >= PJSUA_OP_STATE_RUNNING ||
4322 	call->trickle_ice.remote_dlg_est)
4323     {
4324 	return;
4325     }
4326 
4327     /* Make sure last tdata is 18x response */
4328     if (call->inv->invite_tsx)
4329 	tdata = call->inv->invite_tsx->last_tx;
4330     if (!tdata || tdata->msg->type != PJSIP_RESPONSE_MSG ||
4331 	tdata->msg->line.status.code/10 != 18)
4332     {
4333 	return;
4334     }
4335 
4336     /* Retransmit 18x */
4337     ++call->trickle_ice.retrans18x_count;
4338     PJ_LOG(4,(THIS_FILE,
4339 	      "Call %d: ICE trickle retransmitting 18x (retrans #%d)",
4340 	      call->index, call->trickle_ice.retrans18x_count));
4341 
4342     pjsip_tx_data_add_ref(tdata);
4343     pjsip_tsx_retransmit_no_state(call->inv->invite_tsx, tdata);
4344 
4345     /* Schedule next retransmission */
4346     if (call->trickle_ice.retrans18x_count < 6) {
4347 	pj_uint32_t tmp;
4348 	tmp = (1 << call->trickle_ice.retrans18x_count) * pjsip_cfg()->tsx.t1;
4349 	delay.sec = 0;
4350 	delay.msec = tmp;
4351 	pj_time_val_normalize(&delay);
4352     } else {
4353 	delay.sec = 1;
4354 	delay.msec = 500;
4355     }
4356     pjsua_schedule_timer(te, &delay);
4357 }
4358 
4359 
trickle_ice_recv_sip_info(pjsua_call * call,pjsip_rx_data * rdata)4360 static void trickle_ice_recv_sip_info(pjsua_call *call, pjsip_rx_data *rdata)
4361 {
4362     pjsip_media_type med_type;
4363     pjsip_rdata_sdp_info *sdp_info;
4364     pj_status_t status;
4365     unsigned i, j, med_cnt;
4366     pj_bool_t use_med_prov;
4367 
4368     pjsip_media_type_init2(&med_type, "application", "trickle-ice-sdpfrag");
4369 
4370     /* Parse the SDP */
4371     sdp_info = pjsip_rdata_get_sdp_info2(rdata, &med_type);
4372     if (!sdp_info->sdp) {
4373 	pj_status_t err = sdp_info->body.ptr? sdp_info->sdp_err:PJ_ENOTFOUND;
4374 	pjsua_perror(THIS_FILE, "Failed to parse trickle ICE SDP in "
4375 				"incoming INFO", err);
4376 	return;
4377     }
4378 
4379     PJSUA_LOCK();
4380 
4381     /* Retrieve the candidates from the SDP */
4382     use_med_prov = call->med_prov_cnt > call->med_cnt;
4383     med_cnt = use_med_prov? call->med_prov_cnt : call->med_cnt;
4384     for (i = 0; i < sdp_info->sdp->media_count; ++i) {
4385 	pjmedia_transport *tp = NULL;
4386 	pj_str_t mid, ufrag, pwd;
4387 	unsigned cand_cnt = PJ_ICE_ST_MAX_CAND;
4388 	pj_ice_sess_cand cand[PJ_ICE_ST_MAX_CAND];
4389 	pj_bool_t end_of_cand;
4390 
4391 	status = pjmedia_ice_trickle_decode_sdp(sdp_info->sdp, i, &mid,
4392 						&ufrag, &pwd,
4393 						&cand_cnt, cand,
4394 						&end_of_cand);
4395 	if (status != PJ_SUCCESS) {
4396 	    pjsua_perror(THIS_FILE, "Failed to retrive ICE candidates from "
4397 				    "SDP in incoming INFO", status);
4398 	    continue;
4399 	}
4400 
4401 	for (j = 0; j < med_cnt; ++j) {
4402 	    pjsua_call_media *cm = use_med_prov? &call->media_prov[j] :
4403 						 &call->media[j];
4404 	    tp = cm->tp_orig;
4405 
4406 	    if (tp && tp->type == PJMEDIA_TRANSPORT_TYPE_ICE &&
4407 		pj_strcmp(&cm->rem_mid, &mid) == 0)
4408 	    {
4409 		break;
4410 	    }
4411 	}
4412 
4413 	if (j == med_cnt) {
4414 	    pjsua_perror(THIS_FILE, "Cannot add remote candidates from SDP in "
4415 			 "incoming INFO because media ID (SDP a=mid) is not "
4416 			 "recognized",
4417 			 PJ_EIGNORED);
4418 	    continue;
4419 	}
4420 
4421 	/* Update ICE checklist */
4422 	status = pjmedia_ice_trickle_update(tp, &ufrag, &pwd, cand_cnt, cand,
4423 					    end_of_cand);
4424 	if (status != PJ_SUCCESS) {
4425 	    pjsua_perror(THIS_FILE, "Failed to update ICE checklist from "
4426 				    "incoming INFO", status);
4427 	}
4428     }
4429 
4430     PJSUA_UNLOCK();
4431 }
4432 
4433 
trickle_ice_send_sip_info(pj_timer_heap_t * th,struct pj_timer_entry * te)4434 static void trickle_ice_send_sip_info(pj_timer_heap_t *th,
4435 				      struct pj_timer_entry *te)
4436 {
4437     pjsua_call *call = (pjsua_call*)te->user_data;
4438     pj_pool_t *tmp_pool = NULL;
4439     pj_bool_t all_end_of_cand, use_med_prov;
4440     pjmedia_sdp_session *sdp;
4441     unsigned i, med_cnt;
4442     pjsua_msg_data msg_data;
4443     pjsip_generic_string_hdr hdr1, hdr2;
4444     pj_status_t status = PJ_SUCCESS;
4445     pj_bool_t forced, need_send = PJ_FALSE;
4446     pj_sockaddr orig_addr;
4447 
4448     pj_str_t SIP_INFO		= {"INFO", 4};
4449     pj_str_t CONTENT_DISP_STR	= {"Content-Disposition", 19};
4450     pj_str_t INFO_PKG_STR	= {"Info-Package", 12};
4451     pj_str_t TRICKLE_ICE_STR	= {"trickle-ice", 11};
4452 
4453     PJ_UNUSED_ARG(th);
4454 
4455     PJSUA_LOCK();
4456 
4457     /* Check provisional media or active media to use */
4458     use_med_prov = call->med_prov_cnt > call->med_cnt;
4459     med_cnt = use_med_prov? call->med_prov_cnt : call->med_cnt;
4460 
4461     /* Check if any pending INFO already */
4462     if (call->trickle_ice.pending_info)
4463 	goto on_return;
4464 
4465     /* Check if any new candidate, if not forced */
4466     forced = (te->id == 2);
4467     if (!forced) {
4468 	for (i = 0; i < med_cnt; ++i) {
4469 	    pjsua_call_media *cm = use_med_prov? &call->media_prov[i] :
4470 						 &call->media[i];
4471 	    pjmedia_transport *tp = cm->tp_orig;
4472 
4473 	    if (!tp || tp->type != PJMEDIA_TRANSPORT_TYPE_ICE)
4474 		continue;
4475 
4476 	    if (pjmedia_ice_trickle_has_new_cand(tp))
4477 		break;
4478 	}
4479 
4480 	/* No new local candidate */
4481 	if (i == med_cnt)
4482 	    goto on_return;
4483     }
4484 
4485     PJ_LOG(4,(THIS_FILE, "Call %d: ICE trickle sending SIP INFO%s",
4486 	      call->index, (forced? " (forced)":"")));
4487 
4488     /* Create temporary pool */
4489     tmp_pool = pjsua_pool_create("tmp_ice", 128, 128);
4490 
4491     /* Create empty SDP */
4492     pj_sockaddr_init(pj_AF_INET(), &orig_addr, NULL, 0);
4493     status = pjmedia_endpt_create_base_sdp(pjsua_var.med_endpt, tmp_pool,
4494 					   NULL, &orig_addr, &sdp);
4495     if (status != PJ_SUCCESS)
4496 	goto on_return;
4497 
4498     /* Generate SDP for SIP INFO */
4499     all_end_of_cand = PJ_TRUE;
4500     for (i = 0; i < med_cnt; ++i) {
4501 	pjsua_call_media *cm = use_med_prov? &call->media_prov[i] :
4502 					     &call->media[i];
4503 	pjmedia_transport *tp = cm->tp_orig;
4504 	pj_bool_t end_of_cand = PJ_FALSE;
4505 
4506 	if (!tp || tp->type != PJMEDIA_TRANSPORT_TYPE_ICE)
4507 	    continue;
4508 
4509 	status = pjmedia_ice_trickle_send_local_cand(tp, tmp_pool, sdp,
4510 						     &end_of_cand);
4511 	if (status != PJ_SUCCESS || !end_of_cand)
4512 	    all_end_of_cand = PJ_FALSE;
4513 
4514 	need_send |= (status==PJ_SUCCESS);
4515     }
4516 
4517     if (!need_send)
4518 	goto on_return;
4519 
4520     /* Generate and send SIP INFO */
4521     pjsua_msg_data_init(&msg_data);
4522 
4523     pjsip_generic_string_hdr_init2(&hdr1, &INFO_PKG_STR, &TRICKLE_ICE_STR);
4524     pj_list_push_back(&msg_data.hdr_list, &hdr1);
4525     pjsip_generic_string_hdr_init2(&hdr2, &CONTENT_DISP_STR, &INFO_PKG_STR);
4526     pj_list_push_back(&msg_data.hdr_list, &hdr2);
4527 
4528     msg_data.content_type = pj_str("application/trickle-ice-sdpfrag");
4529     msg_data.msg_body.ptr = pj_pool_alloc(tmp_pool, PJSIP_MAX_PKT_LEN);
4530     msg_data.msg_body.slen = pjmedia_sdp_print(sdp, msg_data.msg_body.ptr,
4531 					       PJSIP_MAX_PKT_LEN);
4532     if (msg_data.msg_body.slen == -1) {
4533 	PJ_LOG(3,(THIS_FILE,
4534 		  "Warning! Call %d: ICE trickle failed to print SDP for "
4535 		  "SIP INFO due to insufficient buffer", call->index));
4536 	goto on_return;
4537     }
4538 
4539     status = pjsua_call_send_request(call->index, &SIP_INFO, &msg_data);
4540     if (status != PJ_SUCCESS)
4541 	goto on_return;
4542 
4543     /* Set flag for pending SIP INFO */
4544     call->trickle_ice.pending_info = PJ_TRUE;
4545 
4546     /* Stop trickling if local candidate gathering for all media is done */
4547     if (all_end_of_cand) {
4548 	PJ_LOG(4,(THIS_FILE, "Call %d: ICE trickle stopped trickling "
4549 			     "as local candidate gathering completed",
4550 			     call->index));
4551 	call->trickle_ice.trickling = PJSUA_OP_STATE_DONE;
4552     }
4553 
4554     /* Update ICE checklist after conveying local candidates. */
4555     for (i = 0; i < med_cnt; ++i) {
4556 	pjsua_call_media *cm = use_med_prov? &call->media_prov[i] :
4557 					     &call->media[i];
4558 	pjmedia_transport *tp = cm->tp_orig;
4559 	if (!tp || tp->type != PJMEDIA_TRANSPORT_TYPE_ICE)
4560 	    continue;
4561 
4562 	pjmedia_ice_trickle_update(tp, NULL, NULL, 0, NULL, PJ_FALSE);
4563     }
4564 
4565 on_return:
4566     if (tmp_pool)
4567 	pj_pool_release(tmp_pool);
4568 
4569     /* Reschedule if we are trickling */
4570     if (call->trickle_ice.trickling == PJSUA_OP_STATE_RUNNING) {
4571 	pj_time_val delay = {0, PJSUA_TRICKLE_ICE_NEW_CAND_CHECK_INTERVAL};
4572 
4573 	/* Reset forced mode after successfully sending forced SIP INFO */
4574 	te->id = (status==PJ_SUCCESS? 0 : 2);
4575 
4576 	pj_time_val_normalize(&delay);
4577 	pjsua_schedule_timer(te, &delay);
4578     }
4579 
4580     PJSUA_UNLOCK();
4581 }
4582 
4583 
4584 /* Before sending INFO can be started, UA needs to confirm these:
4585  * 1. dialog is established (perhaps early) at both sides,
4586  * 2. trickle ICE is supported by peer.
4587  *
4588  * This function needs to be called when:
4589  * - UAS sending 18x, to start 18x retrans
4590  * - UAC receiving 18x, to forcefully send SIP INFO & start trickling
4591  * - UAS receiving INFO, to cease 18x retrans & start trickling
4592  * - UAS receiving PRACK, to start trickling
4593  * - UAC/UAS receiving remote SDP (and check for trickle ICE support),
4594  *   to start trickling.
4595  */
pjsua_ice_check_start_trickling(pjsua_call * call,pj_bool_t forceful,pjsip_event * e)4596 void pjsua_ice_check_start_trickling(pjsua_call *call,
4597 				     pj_bool_t forceful,
4598 				     pjsip_event *e)
4599 {
4600     pjsip_inv_session *inv = call->inv;
4601 
4602     /* Make sure trickling/sending-INFO has not been started */
4603     if (!forceful && call->trickle_ice.trickling >= PJSUA_OP_STATE_RUNNING)
4604 	return;
4605 
4606     /* Make sure trickle ICE is enabled */
4607     if (!call->trickle_ice.enabled)
4608 	return;
4609 
4610     /* Make sure the dialog state is established */
4611     if (!inv || inv->dlg->state != PJSIP_DIALOG_STATE_ESTABLISHED)
4612 	return;
4613 
4614     /* First, make sure remote dialog is also established. */
4615     if (inv->state == PJSIP_INV_STATE_CONFIRMED) {
4616 	/* Set flag indicating remote dialog is established */
4617 	call->trickle_ice.remote_dlg_est = PJ_TRUE;
4618     } else if (inv->state > PJSIP_INV_STATE_CONFIRMED) {
4619 	/* Call is terminating/terminated (just trying to be safe) */
4620 	call->trickle_ice.remote_dlg_est = PJ_FALSE;
4621     } else if (!call->trickle_ice.remote_dlg_est && e) {
4622 	/* Call is being initialized */
4623 	pjsip_msg *msg = NULL;
4624 	pjsip_rx_data *rdata = NULL;
4625 	pjsip_tx_data *tdata = NULL;
4626 	pj_bool_t has_100rel = (inv->options & PJSIP_INV_REQUIRE_100REL);
4627 	pj_timer_entry *te = &call->trickle_ice.timer;
4628 
4629 	if (e->type == PJSIP_EVENT_TSX_STATE &&
4630 	    e->body.tsx_state.type == PJSIP_EVENT_RX_MSG)
4631 	{
4632 	    rdata = e->body.tsx_state.src.rdata;
4633 	} else if (e->type == PJSIP_EVENT_TSX_STATE &&
4634 		   e->body.tsx_state.type == PJSIP_EVENT_TX_MSG)
4635 	{
4636 	    tdata = e->body.tsx_state.src.tdata;
4637 	} else {
4638 	    return;
4639 	}
4640 
4641 	/* UAC must have received 18x at this point, so dialog must have been
4642 	 * established at the remote side.
4643 	 */
4644 	if (inv->role == PJSIP_ROLE_UAC) {
4645 	    /* UAC needs to send SIP INFO when receiving 18x and 100rel is not
4646 	     * active.
4647 	     * Note that 18x may not have SDP (so we don't know if remote
4648 	     * supports trickle ICE), but we should send INFO anyway, as the
4649 	     * draft allows start trickling without answer.
4650 	     */
4651 	    if (!has_100rel && rdata &&
4652 		rdata->msg_info.msg->type == PJSIP_RESPONSE_MSG &&
4653 		rdata->msg_info.msg->line.status.code/10 == 18)
4654 	    {
4655 		pjsip_rdata_sdp_info *sdp_info;
4656 		sdp_info = pjsip_rdata_get_sdp_info(rdata);
4657 		if (sdp_info->sdp) {
4658 		    unsigned i;
4659 		    for (i = 0; i < sdp_info->sdp->media_count; ++i) {
4660 			if (pjmedia_ice_sdp_has_trickle(sdp_info->sdp, i)) {
4661 			    call->trickle_ice.remote_sup = PJ_TRUE;
4662 			    break;
4663 			}
4664 		    }
4665 		} else {
4666 		    /* Start sending SIP INFO forcefully */
4667 		    forceful = PJ_TRUE;
4668 		}
4669 
4670 		if (forceful || call->trickle_ice.remote_sup) {
4671 		    PJ_LOG(4,(THIS_FILE,
4672 			      "Call %d: ICE trickle started after UAC "
4673 			      "receiving 18x (with%s SDP)",
4674 			      call->index, sdp_info->sdp?"":"out"));
4675 		}
4676 	    }
4677 	}
4678 
4679 	/* But if we are the UAS, we need to wait for SIP PRACK or INFO to
4680 	 * confirm dialog state at remote. And while waiting, 18x needs to be
4681 	 * retransmitted.
4682 	 */
4683 	else {
4684 
4685 	    if (tdata && e->body.tsx_state.tsx == inv->invite_tsx &&
4686 		call->trickle_ice.retrans18x_count == 0)
4687 	    {
4688 		/* Ignite 18x retransmission */
4689 		msg = tdata->msg;
4690 		if (msg->type == PJSIP_RESPONSE_MSG &&
4691 		    msg->line.status.code/10 == 18)
4692 		{
4693 		    pj_time_val delay;
4694 		    delay.sec = pjsip_cfg()->tsx.t1 / 1000;
4695 		    delay.msec = pjsip_cfg()->tsx.t1 % 1000;
4696 		    pj_assert(!pj_timer_entry_running(te));
4697 		    te->cb = &trickle_ice_retrans_18x;
4698 		    pjsua_schedule_timer(te, &delay);
4699 
4700 		    PJ_LOG(4,(THIS_FILE,
4701 			      "Call %d: ICE trickle start retransmitting 18x",
4702 			      call->index));
4703 		}
4704 		return;
4705 	    }
4706 
4707 	    /* Check for incoming PRACK or INFO to stop 18x retransmission */
4708 	    if (!rdata)
4709 		return;
4710 
4711 	    msg = rdata->msg_info.msg;
4712 	    if (has_100rel) {
4713 		/* With 100rel, has received PRACK? */
4714 		if (msg->type != PJSIP_REQUEST_MSG ||
4715 		    pjsip_method_cmp(&msg->line.req.method,
4716 				     pjsip_get_prack_method()))
4717 		{
4718 		    return;
4719 		}
4720 	    } else {
4721 		pj_str_t INFO_PKG_STR = {"Info-Package", 12};
4722 		pjsip_generic_string_hdr *hdr;
4723 
4724 		/* Without 100rel, has received INFO? */
4725 		if (msg->type != PJSIP_REQUEST_MSG ||
4726 		    pjsip_method_cmp(&msg->line.req.method,
4727 				     &pjsip_info_method))
4728 		{
4729 		    return;
4730 		}
4731 
4732 		/* With Info-Package header containing 'trickle-ice' */
4733 		hdr = (pjsip_generic_string_hdr*)
4734 		      pjsip_msg_find_hdr_by_name(msg, &INFO_PKG_STR, NULL);
4735 		if (!hdr || pj_strcmp2(&hdr->hvalue, "trickle-ice"))
4736 		    return;
4737 
4738 		/* Set the flag indicating remote supports trickle ICE */
4739 		call->trickle_ice.remote_sup = PJ_TRUE;
4740 	    }
4741 	    PJ_LOG(4,(THIS_FILE,
4742 		      "Call %d: ICE trickle stop retransmitting 18x after "
4743 		      "receiving %s",
4744 		      call->index, (has_100rel?"PRACK":"INFO")));
4745 	}
4746 
4747 	/* Set flag indicating remote dialog is established.
4748 	 * Any 18x retransmission should be ceased automatically.
4749 	 */
4750 	call->trickle_ice.remote_dlg_est = PJ_TRUE;
4751     }
4752 
4753     /* Check if ICE trickling can be started */
4754     if (!forceful &&
4755 	(!call->trickle_ice.remote_dlg_est || !call->trickle_ice.remote_sup))
4756     {
4757 	return;
4758     }
4759 
4760     /* Let's start trickling (or sending SIP INFO) */
4761     if (forceful || call->trickle_ice.trickling < PJSUA_OP_STATE_RUNNING)
4762     {
4763 	pj_timer_entry *te = &call->trickle_ice.timer;
4764 	pj_time_val delay = {0,0};
4765 
4766 	if (call->trickle_ice.trickling < PJSUA_OP_STATE_RUNNING)
4767 	    call->trickle_ice.trickling = PJSUA_OP_STATE_RUNNING;
4768 
4769 	pjsua_cancel_timer(te);
4770 	te->id = forceful? 2 : 0;
4771 	te->cb = &trickle_ice_send_sip_info;
4772 	pjsua_schedule_timer(te, &delay);
4773 
4774 	PJ_LOG(4,(THIS_FILE,
4775 		  "Call %d: ICE trickle start trickling",
4776 		  call->index));
4777     }
4778 }
4779 
4780 
4781 /*
4782  * This callback receives notification from invite session when the
4783  * session state has changed.
4784  */
pjsua_call_on_state_changed(pjsip_inv_session * inv,pjsip_event * e)4785 static void pjsua_call_on_state_changed(pjsip_inv_session *inv,
4786 					pjsip_event *e)
4787 {
4788     pjsua_call *call;
4789     unsigned num_locks = 0;
4790 
4791     pj_log_push_indent();
4792 
4793     call = (pjsua_call*) inv->dlg->mod_data[pjsua_var.mod.id];
4794 
4795     if (!call) {
4796 	pj_log_pop_indent();
4797 	return;
4798     }
4799 
4800 
4801     /* Get call times */
4802     switch (inv->state) {
4803 	case PJSIP_INV_STATE_EARLY:
4804 	case PJSIP_INV_STATE_CONNECTING:
4805 	    if (call->res_time.sec == 0)
4806 		pj_gettimeofday(&call->res_time);
4807 	    call->last_code = (pjsip_status_code)
4808 	    		      e->body.tsx_state.tsx->status_code;
4809 	    pj_strncpy(&call->last_text,
4810 		       &e->body.tsx_state.tsx->status_text,
4811 		       sizeof(call->last_text_buf_));
4812 	    break;
4813 	case PJSIP_INV_STATE_CONFIRMED:
4814 	    pj_gettimeofday(&call->conn_time);
4815 
4816 	    if (call->trickle_ice.enabled) {
4817 		call->trickle_ice.remote_dlg_est = PJ_TRUE;
4818 		pjsua_ice_check_start_trickling(call, PJ_FALSE, NULL);
4819 	    }
4820 
4821             /* See if auto reinvite was pended as media update was done in the
4822              * EARLY state and remote does not support UPDATE.
4823              */
4824             if (call->reinv_pending) {
4825 		call->reinv_pending = PJ_FALSE;
4826 		pjsua_call_schedule_reinvite_check(call, 0);
4827 	    }
4828 	    break;
4829 	case PJSIP_INV_STATE_DISCONNECTED:
4830 	    pj_gettimeofday(&call->dis_time);
4831 	    if (call->res_time.sec == 0)
4832 		pj_gettimeofday(&call->res_time);
4833 	    if (e->type == PJSIP_EVENT_TSX_STATE &&
4834 		e->body.tsx_state.tsx->status_code > call->last_code)
4835 	    {
4836 		call->last_code = (pjsip_status_code)
4837 				  e->body.tsx_state.tsx->status_code;
4838 		pj_strncpy(&call->last_text,
4839 			   &e->body.tsx_state.tsx->status_text,
4840 			   sizeof(call->last_text_buf_));
4841 	    } else {
4842 		call->last_code = PJSIP_SC_REQUEST_TERMINATED;
4843 		pj_strncpy(&call->last_text,
4844 			   pjsip_get_status_text(call->last_code),
4845 			   sizeof(call->last_text_buf_));
4846 	    }
4847 
4848 	    /* Stop reinvite timer, if it is active */
4849 	    if (call->reinv_timer.id) {
4850 		pjsua_cancel_timer(&call->reinv_timer);
4851 		call->reinv_timer.id = PJ_FALSE;
4852 	    }
4853 	    break;
4854 	default:
4855 	    call->last_code = (pjsip_status_code)
4856 	    		      e->body.tsx_state.tsx->status_code;
4857 	    pj_strncpy(&call->last_text,
4858 		       &e->body.tsx_state.tsx->status_text,
4859 		       sizeof(call->last_text_buf_));
4860 	    break;
4861     }
4862 
4863     /* If this is an outgoing INVITE that was created because of
4864      * REFER/transfer, send NOTIFY to transferer.
4865      */
4866     if (call->xfer_sub && e->type==PJSIP_EVENT_TSX_STATE)  {
4867 	int st_code = -1;
4868 	pjsip_evsub_state ev_state = PJSIP_EVSUB_STATE_ACTIVE;
4869 
4870 
4871 	switch (call->inv->state) {
4872 	case PJSIP_INV_STATE_NULL:
4873 	case PJSIP_INV_STATE_CALLING:
4874 	    /* Do nothing */
4875 	    break;
4876 
4877 	case PJSIP_INV_STATE_EARLY:
4878 	case PJSIP_INV_STATE_CONNECTING:
4879 	    st_code = e->body.tsx_state.tsx->status_code;
4880 	    if (call->inv->state == PJSIP_INV_STATE_CONNECTING)
4881 		ev_state = PJSIP_EVSUB_STATE_TERMINATED;
4882 	    else
4883 		ev_state = PJSIP_EVSUB_STATE_ACTIVE;
4884 	    break;
4885 
4886 	case PJSIP_INV_STATE_CONFIRMED:
4887 #if 0
4888 /* We don't need this, as we've terminated the subscription in
4889  * CONNECTING state.
4890  */
4891 	    /* When state is confirmed, send the final 200/OK and terminate
4892 	     * subscription.
4893 	     */
4894 	    st_code = e->body.tsx_state.tsx->status_code;
4895 	    ev_state = PJSIP_EVSUB_STATE_TERMINATED;
4896 #endif
4897 	    break;
4898 
4899 	case PJSIP_INV_STATE_DISCONNECTED:
4900 	    st_code = e->body.tsx_state.tsx->status_code;
4901 	    ev_state = PJSIP_EVSUB_STATE_TERMINATED;
4902 	    break;
4903 
4904 	case PJSIP_INV_STATE_INCOMING:
4905 	    /* Nothing to do. Just to keep gcc from complaining about
4906 	     * unused enums.
4907 	     */
4908 	    break;
4909 	}
4910 
4911 	if (st_code != -1) {
4912 	    pjsip_tx_data *tdata;
4913 	    pj_status_t status;
4914 
4915 	    status = pjsip_xfer_notify( call->xfer_sub,
4916 					ev_state, st_code,
4917 					NULL, &tdata);
4918 	    if (status != PJ_SUCCESS) {
4919 		pjsua_perror(THIS_FILE, "Unable to create NOTIFY", status);
4920 	    } else {
4921 		status = pjsip_xfer_send_request(call->xfer_sub, tdata);
4922 		if (status != PJ_SUCCESS) {
4923 		    pjsua_perror(THIS_FILE, "Unable to send NOTIFY", status);
4924 		}
4925 	    }
4926 	}
4927     }
4928 
4929     /* Destroy media session when invite session is disconnected. */
4930     if (inv->state == PJSIP_INV_STATE_DISCONNECTED) {
4931 	PJSUA_LOCK();
4932 
4933 	if (!call->hanging_up)
4934 	    pjsua_media_channel_deinit(call->index);
4935 
4936 	PJSUA_UNLOCK();
4937     }
4938 
4939     /* Release locks before calling callbacks, to avoid deadlock. */
4940     while (PJSUA_LOCK_IS_LOCKED()) {
4941     	num_locks++;
4942     	PJSUA_UNLOCK();
4943     }
4944 
4945     /* Ticket #1627: Invoke on_call_tsx_state() when call is disconnected. */
4946     if (inv->state == PJSIP_INV_STATE_DISCONNECTED &&
4947 	e->type == PJSIP_EVENT_TSX_STATE &&
4948 	!call->hanging_up && call->inv &&
4949 	pjsua_var.ua_cfg.cb.on_call_tsx_state)
4950     {
4951 	(*pjsua_var.ua_cfg.cb.on_call_tsx_state)(call->index,
4952 						 e->body.tsx_state.tsx, e);
4953     }
4954 
4955     if (!call->hanging_up && pjsua_var.ua_cfg.cb.on_call_state)
4956 	(*pjsua_var.ua_cfg.cb.on_call_state)(call->index, e);
4957 
4958     /* Re-acquire the locks. */
4959     for (;num_locks > 0; num_locks--)
4960     	PJSUA_LOCK();
4961 
4962     /* call->inv may be NULL now */
4963 
4964     /* Finally, free call when invite session is disconnected. */
4965     if (inv->state == PJSIP_INV_STATE_DISCONNECTED) {
4966 
4967 	PJSUA_LOCK();
4968 
4969 	/* Free call */
4970 	call->inv = NULL;
4971 
4972 	pj_assert(pjsua_var.call_cnt > 0);
4973 	--pjsua_var.call_cnt;
4974 
4975 	/* Reset call */
4976 	reset_call(call->index);
4977 
4978 	pjsua_check_snd_dev_idle();
4979 
4980 	PJSUA_UNLOCK();
4981     }
4982     pj_log_pop_indent();
4983 }
4984 
4985 /*
4986  * This callback is called by invite session framework when UAC session
4987  * has forked.
4988  */
pjsua_call_on_forked(pjsip_inv_session * inv,pjsip_event * e)4989 static void pjsua_call_on_forked( pjsip_inv_session *inv,
4990 				  pjsip_event *e)
4991 {
4992     PJ_UNUSED_ARG(inv);
4993     PJ_UNUSED_ARG(e);
4994 
4995     PJ_TODO(HANDLE_FORKED_DIALOG);
4996 }
4997 
4998 
4999 /*
5000  * Callback from UA layer when forked dialog response is received.
5001  */
on_dlg_forked(pjsip_dialog * dlg,pjsip_rx_data * res)5002 pjsip_dialog* on_dlg_forked(pjsip_dialog *dlg, pjsip_rx_data *res)
5003 {
5004     if (dlg->uac_has_2xx &&
5005 	res->msg_info.cseq->method.id == PJSIP_INVITE_METHOD &&
5006 	pjsip_rdata_get_tsx(res) == NULL &&
5007 	res->msg_info.msg->line.status.code/100 == 2)
5008     {
5009 	pjsip_dialog *forked_dlg;
5010 	pjsip_tx_data *bye;
5011 	pj_status_t status;
5012 
5013 	/* Create forked dialog */
5014 	status = pjsip_dlg_fork(dlg, res, &forked_dlg);
5015 	if (status != PJ_SUCCESS)
5016 	    return NULL;
5017 
5018 	pjsip_dlg_inc_lock(forked_dlg);
5019 
5020 	/* Disconnect the call */
5021 	status = pjsip_dlg_create_request(forked_dlg, pjsip_get_bye_method(),
5022 					  -1, &bye);
5023 	if (status == PJ_SUCCESS) {
5024 	    status = pjsip_dlg_send_request(forked_dlg, bye, -1, NULL);
5025 	}
5026 
5027 	pjsip_dlg_dec_lock(forked_dlg);
5028 
5029 	if (status != PJ_SUCCESS) {
5030 	    return NULL;
5031 	}
5032 
5033 	return forked_dlg;
5034 
5035     } else {
5036 	return dlg;
5037     }
5038 }
5039 
5040 /*
5041  * Disconnect call upon error.
5042  */
call_disconnect(pjsip_inv_session * inv,int code)5043 static void call_disconnect( pjsip_inv_session *inv,
5044 			     int code )
5045 {
5046     pjsip_tx_data *tdata;
5047     pj_status_t status;
5048 
5049     status = pjsip_inv_end_session(inv, code, NULL, &tdata);
5050     if (status != PJ_SUCCESS)
5051 	return;
5052 
5053 #if DISABLED_FOR_TICKET_1185
5054     pjsua_call *call;
5055 
5056     /* Add SDP in 488 status */
5057     call = (pjsua_call*) inv->dlg->mod_data[pjsua_var.mod.id];
5058 
5059     if (call && call->tp && tdata->msg->type==PJSIP_RESPONSE_MSG &&
5060 	code==PJSIP_SC_NOT_ACCEPTABLE_HERE)
5061     {
5062 	pjmedia_sdp_session *local_sdp;
5063 	pjmedia_transport_info ti;
5064 
5065 	pjmedia_transport_info_init(&ti);
5066 	pjmedia_transport_get_info(call->med_tp, &ti);
5067 	status = pjmedia_endpt_create_sdp(pjsua_var.med_endpt, tdata->pool,
5068 					  1, &ti.sock_info, &local_sdp);
5069 	if (status == PJ_SUCCESS) {
5070 	    pjsip_create_sdp_body(tdata->pool, local_sdp,
5071 				  &tdata->msg->body);
5072 	}
5073     }
5074 #endif
5075 
5076     pjsip_inv_send_msg(inv, tdata);
5077 }
5078 
5079 /*
5080  * Callback to be called when SDP offer/answer negotiation has just completed
5081  * in the session. This function will start/update media if negotiation
5082  * has succeeded.
5083  */
pjsua_call_on_media_update(pjsip_inv_session * inv,pj_status_t status)5084 static void pjsua_call_on_media_update(pjsip_inv_session *inv,
5085 				       pj_status_t status)
5086 {
5087     pjsua_call *call;
5088     const pjmedia_sdp_session *local_sdp;
5089     const pjmedia_sdp_session *remote_sdp;
5090     //const pj_str_t st_update = {"UPDATE", 6};
5091 
5092     pj_log_push_indent();
5093 
5094     call = (pjsua_call*) inv->dlg->mod_data[pjsua_var.mod.id];
5095 
5096     if (call->hanging_up)
5097         goto on_return;
5098 
5099     if (status != PJ_SUCCESS) {
5100 
5101 	pjsua_perror(THIS_FILE, "SDP negotiation has failed", status);
5102 
5103 	/* Revert back provisional media. */
5104 	pjsua_media_prov_revert(call->index);
5105 
5106 	/* Do not deinitialize media since this may be a re-INVITE or
5107 	 * UPDATE (which in this case the media should not get affected
5108 	 * by the failed re-INVITE/UPDATE). The media will be shutdown
5109 	 * when call is disconnected anyway.
5110 	 */
5111 	/* Stop/destroy media, if any */
5112 	/*pjsua_media_channel_deinit(call->index);*/
5113 
5114 	/* Disconnect call if we're not in the middle of initializing an
5115 	 * UAS dialog and if this is not a re-INVITE
5116 	 */
5117 	if (inv->state != PJSIP_INV_STATE_NULL &&
5118 	    inv->state != PJSIP_INV_STATE_CONFIRMED)
5119 	{
5120 	    call_disconnect(inv, PJSIP_SC_UNSUPPORTED_MEDIA_TYPE);
5121 	}
5122 
5123 	goto on_return;
5124     }
5125 
5126 
5127     /* Get local and remote SDP */
5128     status = pjmedia_sdp_neg_get_active_local(call->inv->neg, &local_sdp);
5129     if (status != PJ_SUCCESS) {
5130 	pjsua_perror(THIS_FILE,
5131 		     "Unable to retrieve currently active local SDP",
5132 		     status);
5133 	//call_disconnect(inv, PJSIP_SC_UNSUPPORTED_MEDIA_TYPE);
5134 	goto on_return;
5135     }
5136 
5137     status = pjmedia_sdp_neg_get_active_remote(call->inv->neg, &remote_sdp);
5138     if (status != PJ_SUCCESS) {
5139 	pjsua_perror(THIS_FILE,
5140 		     "Unable to retrieve currently active remote SDP",
5141 		     status);
5142 	//call_disconnect(inv, PJSIP_SC_UNSUPPORTED_MEDIA_TYPE);
5143 	goto on_return;
5144     }
5145 
5146     call->med_update_success = (status == PJ_SUCCESS);
5147 
5148     /* Trickle ICE tasks:
5149      * - Check remote SDP for trickle ICE support & start sending SIP INFO.
5150      */
5151     {
5152 	unsigned i;
5153 	for (i = 0; i < remote_sdp->media_count; ++i) {
5154 	    if (pjmedia_ice_sdp_has_trickle(remote_sdp, i))
5155 		break;
5156 	}
5157 	call->trickle_ice.remote_sup = (i < remote_sdp->media_count);
5158 	if (call->trickle_ice.remote_sup)
5159 	    pjsua_ice_check_start_trickling(call, PJ_FALSE, NULL);
5160     }
5161 
5162     /* Update remote's NAT type */
5163     if (pjsua_var.ua_cfg.nat_type_in_sdp) {
5164 	update_remote_nat_type(call, remote_sdp);
5165     }
5166 
5167     /* Update media channel with the new SDP */
5168     status = pjsua_media_channel_update(call->index, local_sdp, remote_sdp);
5169 
5170     /* If this is not the initial INVITE, don't disconnect call due to
5171      * no media after SDP negotiation.
5172      */
5173     if (status == PJMEDIA_SDPNEG_ENOMEDIA &&
5174 	call->inv->state == PJSIP_INV_STATE_CONFIRMED)
5175     {
5176 	status = PJ_SUCCESS;
5177     }
5178 
5179     /* Disconnect call after failure in media channel update */
5180     if (status != PJ_SUCCESS) {
5181 	pjsua_perror(THIS_FILE, "Unable to create media session",
5182 		     status);
5183 	call_disconnect(inv, PJSIP_SC_NOT_ACCEPTABLE_HERE);
5184 	/* No need to deinitialize; media will be shutdown when call
5185 	 * state is disconnected anyway.
5186 	 */
5187 	/*pjsua_media_channel_deinit(call->index);*/
5188 	goto on_return;
5189     }
5190 
5191     /* Ticket #476: make sure only one codec is specified in the answer. */
5192     pjsua_call_schedule_reinvite_check(call, 0);
5193 
5194     /* Call application callback, if any */
5195     if (!call->hanging_up && pjsua_var.ua_cfg.cb.on_call_media_state)
5196 	pjsua_var.ua_cfg.cb.on_call_media_state(call->index);
5197 
5198 on_return:
5199     pj_log_pop_indent();
5200 }
5201 
5202 
5203 /* Modify SDP for call hold. */
modify_sdp_of_call_hold(pjsua_call * call,pj_pool_t * pool,pjmedia_sdp_session * sdp,pj_bool_t as_answerer)5204 static pj_status_t modify_sdp_of_call_hold(pjsua_call *call,
5205 					   pj_pool_t *pool,
5206 					   pjmedia_sdp_session *sdp,
5207 					   pj_bool_t as_answerer)
5208 {
5209     unsigned mi;
5210 
5211     /* Call-hold is done by set the media direction to 'sendonly'
5212      * (PJMEDIA_DIR_ENCODING), except when current media direction is
5213      * 'inactive' (PJMEDIA_DIR_NONE).
5214      * (See RFC 3264 Section 8.4 and RFC 4317 Section 3.1)
5215      */
5216     /* http://trac.pjsip.org/repos/ticket/880
5217        if (call->dir != PJMEDIA_DIR_ENCODING) {
5218      */
5219     /* https://trac.pjsip.org/repos/ticket/1142:
5220      *  configuration to use c=0.0.0.0 for call hold.
5221      */
5222 
5223     for (mi=0; mi<sdp->media_count; ++mi) {
5224 	pjmedia_sdp_media *m = sdp->media[mi];
5225 
5226 	if (call->call_hold_type == PJSUA_CALL_HOLD_TYPE_RFC2543) {
5227 	    pjmedia_sdp_conn *conn;
5228 	    pjmedia_sdp_attr *attr;
5229 
5230 	    /* Get SDP media connection line */
5231 	    conn = m->conn;
5232 	    if (!conn)
5233 		conn = sdp->conn;
5234 
5235 	    /* Modify address */
5236 	    conn->addr = pj_str("0.0.0.0");
5237 
5238 	    /* Remove existing directions attributes */
5239 	    pjmedia_sdp_media_remove_all_attr(m, "sendrecv");
5240 	    pjmedia_sdp_media_remove_all_attr(m, "sendonly");
5241 	    pjmedia_sdp_media_remove_all_attr(m, "recvonly");
5242 	    pjmedia_sdp_media_remove_all_attr(m, "inactive");
5243 
5244 	    /* Add inactive attribute */
5245 	    attr = pjmedia_sdp_attr_create(pool, "inactive", NULL);
5246 	    pjmedia_sdp_media_add_attr(m, attr);
5247 
5248 
5249 	} else {
5250 	    pjmedia_sdp_attr *attr;
5251 
5252 	    /* Remove existing directions attributes */
5253 	    pjmedia_sdp_media_remove_all_attr(m, "sendrecv");
5254 	    pjmedia_sdp_media_remove_all_attr(m, "sendonly");
5255 	    pjmedia_sdp_media_remove_all_attr(m, "recvonly");
5256 	    pjmedia_sdp_media_remove_all_attr(m, "inactive");
5257 
5258 	    /* When as answerer, just simply set dir to "sendonly", note that
5259 	     * if the offer uses "sendonly" or "inactive", the SDP negotiator
5260 	     * will change our answer dir to "inactive".
5261 	     */
5262 	    if (as_answerer || (call->media[mi].dir & PJMEDIA_DIR_ENCODING)) {
5263 		/* Add sendonly attribute */
5264 		attr = pjmedia_sdp_attr_create(pool, "sendonly", NULL);
5265 		pjmedia_sdp_media_add_attr(m, attr);
5266 	    } else {
5267 		/* Add inactive attribute */
5268 		attr = pjmedia_sdp_attr_create(pool, "inactive", NULL);
5269 		pjmedia_sdp_media_add_attr(m, attr);
5270 	    }
5271 	}
5272     }
5273 
5274     return PJ_SUCCESS;
5275 }
5276 
5277 /* Create SDP for call hold. */
create_sdp_of_call_hold(pjsua_call * call,pjmedia_sdp_session ** p_sdp)5278 static pj_status_t create_sdp_of_call_hold(pjsua_call *call,
5279 					   pjmedia_sdp_session **p_sdp)
5280 {
5281     pj_status_t status;
5282     pj_pool_t *pool;
5283     pjmedia_sdp_session *sdp;
5284 
5285     /* Use call's provisional pool */
5286     pool = call->inv->pool_prov;
5287 
5288     /* Create new offer */
5289     status = pjsua_media_channel_create_sdp(call->index, pool, NULL, &sdp,
5290 					    NULL);
5291     if (status != PJ_SUCCESS) {
5292 	pjsua_perror(THIS_FILE, "Unable to create local SDP", status);
5293 	return status;
5294     }
5295 
5296     status = modify_sdp_of_call_hold(call, pool, sdp, PJ_FALSE);
5297     if (status != PJ_SUCCESS)
5298 	return status;
5299 
5300     *p_sdp = sdp;
5301 
5302     return PJ_SUCCESS;
5303 }
5304 
5305 /*
5306  * Called when session received new offer.
5307  */
pjsua_call_on_rx_offer(pjsip_inv_session * inv,struct pjsip_inv_on_rx_offer_cb_param * param)5308 static void pjsua_call_on_rx_offer(pjsip_inv_session *inv,
5309 				struct pjsip_inv_on_rx_offer_cb_param *param)
5310 {
5311     pjsua_call *call;
5312     pjmedia_sdp_session *answer;
5313     unsigned i;
5314     pj_status_t status;
5315     const pjmedia_sdp_session *offer = param->offer;
5316     pjsua_call_setting opt;
5317     pj_bool_t async = PJ_FALSE;
5318 
5319     call = (pjsua_call*) inv->dlg->mod_data[pjsua_var.mod.id];
5320     if (call->hanging_up)
5321      	return;
5322 
5323     /* Supply candidate answer */
5324     PJ_LOG(4,(THIS_FILE, "Call %d: received updated media offer",
5325 	      call->index));
5326 
5327     pj_log_push_indent();
5328 
5329     if (pjsua_call_media_is_changing(call)) {
5330 	PJ_LOG(1,(THIS_FILE, "Unable to process offer" ERR_MEDIA_CHANGING));
5331 	goto on_return;
5332     }
5333 
5334     pjsua_call_cleanup_flag(&call->opt);
5335     opt = call->opt;
5336 
5337     if (pjsua_var.ua_cfg.cb.on_call_rx_reinvite &&
5338         param->rdata->msg_info.msg->type == PJSIP_REQUEST_MSG &&
5339         param->rdata->msg_info.msg->line.req.method.id == PJSIP_INVITE_METHOD)
5340     {
5341         pjsip_status_code code = PJSIP_SC_OK;
5342 
5343     	/* If on_call_rx_reinvite() callback is implemented,
5344     	 * call it first.
5345     	 */
5346 	(*pjsua_var.ua_cfg.cb.on_call_rx_reinvite)(
5347 						call->index, offer,
5348 						(pjsip_rx_data *)param->rdata,
5349 						NULL, &async, &code, &opt);
5350 	if (async) {
5351     	    pjsip_tx_data *response;
5352 
5353     	    status = pjsip_inv_initial_answer(inv,
5354     	    				      (pjsip_rx_data *)param->rdata,
5355 				      	      100, NULL, NULL, &response);
5356     	    if (status != PJ_SUCCESS) {
5357 		PJ_PERROR(3, (THIS_FILE, status,
5358 			      "Failed to create initial answer"));
5359     	    	goto on_return;
5360     	    }
5361 
5362 	    status = pjsip_inv_send_msg(inv, response);
5363     	    if (status != PJ_SUCCESS) {
5364 		PJ_PERROR(3, (THIS_FILE, status,
5365 			      "Failed to send initial answer"));
5366     	    	goto on_return;
5367     	    }
5368 
5369 	    PJ_LOG(4,(THIS_FILE, "App will manually answer the re-INVITE "
5370 	    			 "on call %d", call->index));
5371 	}
5372 	if (code != PJSIP_SC_OK) {
5373 	    PJ_LOG(4,(THIS_FILE, "Rejecting re-INVITE updated media offer "
5374 	    			 "on call %d", call->index));
5375 	    goto on_return;
5376 	}
5377 
5378 	call->opt = opt;
5379     }
5380 
5381     if (pjsua_var.ua_cfg.cb.on_call_rx_offer && !async) {
5382 	pjsip_status_code code = PJSIP_SC_OK;
5383 
5384 	(*pjsua_var.ua_cfg.cb.on_call_rx_offer)(call->index, offer, NULL,
5385 						&code, &opt);
5386 
5387 	if (code != PJSIP_SC_OK) {
5388 	    PJ_LOG(4,(THIS_FILE, "Rejecting updated media offer on call %d",
5389 		      call->index));
5390 	    goto on_return;
5391 	}
5392 
5393 	call->opt = opt;
5394     }
5395 
5396     /* Re-init media for the new remote offer before creating SDP */
5397     status = apply_call_setting(call, &call->opt, offer);
5398     if (status != PJ_SUCCESS)
5399 	goto on_return;
5400 
5401     status = pjsua_media_channel_create_sdp(call->index,
5402 					    call->inv->pool_prov,
5403 					    offer, &answer, NULL);
5404     if (status != PJ_SUCCESS) {
5405 	pjsua_perror(THIS_FILE, "Unable to create local SDP", status);
5406 	goto on_return;
5407     }
5408 
5409     if (async) {
5410 	call->rx_reinv_async = async;
5411 	goto on_return;
5412     }
5413 
5414     /* Validate media count in the generated answer */
5415     pj_assert(answer->media_count == offer->media_count);
5416 
5417     /* Check if offer's conn address is zero */
5418     for (i = 0; i < answer->media_count; ++i) {
5419 	pjmedia_sdp_conn *conn;
5420 
5421 	conn = offer->media[i]->conn;
5422 	if (!conn)
5423 	    conn = offer->conn;
5424 
5425 	if (pj_strcmp2(&conn->addr, "0.0.0.0")==0 ||
5426 	    pj_strcmp2(&conn->addr, "0")==0)
5427 	{
5428 	    pjmedia_sdp_conn *a_conn = answer->media[i]->conn;
5429 
5430 	    /* Modify answer address */
5431 	    if (a_conn) {
5432 		a_conn->addr = pj_str("0.0.0.0");
5433 	    } else if (answer->conn == NULL ||
5434 		       pj_strcmp2(&answer->conn->addr, "0.0.0.0") != 0)
5435 	    {
5436 		a_conn = PJ_POOL_ZALLOC_T(call->inv->pool_prov,
5437 					  pjmedia_sdp_conn);
5438 		a_conn->net_type = pj_str("IN");
5439 		a_conn->addr_type = pj_str("IP4");
5440 		a_conn->addr = pj_str("0.0.0.0");
5441 		answer->media[i]->conn = a_conn;
5442 	    }
5443 	}
5444     }
5445 
5446     /* Check if call is on-hold */
5447     if (call->local_hold) {
5448 	modify_sdp_of_call_hold(call, call->inv->pool_prov, answer, PJ_TRUE);
5449     }
5450 
5451     status = pjsip_inv_set_sdp_answer(call->inv, answer);
5452     if (status != PJ_SUCCESS) {
5453 	pjsua_perror(THIS_FILE, "Unable to set answer", status);
5454 	goto on_return;
5455     }
5456 
5457 on_return:
5458     pj_log_pop_indent();
5459 }
5460 
5461 
5462 /*
5463  * Called when receiving re-INVITE.
5464  */
pjsua_call_on_rx_reinvite(pjsip_inv_session * inv,const pjmedia_sdp_session * offer,pjsip_rx_data * rdata)5465 static pj_status_t pjsua_call_on_rx_reinvite(pjsip_inv_session *inv,
5466     		                  	     const pjmedia_sdp_session *offer,
5467                                   	     pjsip_rx_data *rdata)
5468 {
5469     pjsua_call *call;
5470     pj_bool_t async;
5471 
5472     PJ_UNUSED_ARG(offer);
5473     PJ_UNUSED_ARG(rdata);
5474 
5475     call = (pjsua_call*) inv->dlg->mod_data[pjsua_var.mod.id];
5476     async = call->rx_reinv_async;
5477     call->rx_reinv_async = PJ_FALSE;
5478 
5479     return (async? PJ_SUCCESS: !PJ_SUCCESS);
5480 }
5481 
5482 
5483 /*
5484  * Called to generate new offer.
5485  */
pjsua_call_on_create_offer(pjsip_inv_session * inv,pjmedia_sdp_session ** offer)5486 static void pjsua_call_on_create_offer(pjsip_inv_session *inv,
5487 				       pjmedia_sdp_session **offer)
5488 {
5489     pjsua_call *call;
5490     pj_status_t status;
5491     unsigned mi;
5492 
5493     pj_log_push_indent();
5494 
5495     call = (pjsua_call*) inv->dlg->mod_data[pjsua_var.mod.id];
5496     if (call->hanging_up || pjsua_call_media_is_changing(call)) {
5497 	*offer = NULL;
5498 	PJ_LOG(1,(THIS_FILE, "Unable to create offer%s",
5499  		  call->hanging_up? ", call hanging up":
5500  		  ERR_MEDIA_CHANGING));
5501 	goto on_return;
5502     }
5503 
5504 #if RESTART_ICE_ON_REINVITE
5505 
5506     /* Ticket #1783, RFC 5245 section 12.5:
5507      * If an agent receives a mid-dialog re-INVITE that contains no offer,
5508      * it MUST restart ICE for each media stream and go through the process
5509      * of gathering new candidates.
5510      */
5511     for (mi=0; mi<call->med_cnt; ++mi) {
5512 	pjsua_call_media *call_med = &call->media[mi];
5513 	pjmedia_transport_info tpinfo;
5514 	pjmedia_ice_transport_info *ice_info;
5515 
5516         /* Check if the media is using ICE */
5517         pjmedia_transport_info_init(&tpinfo);
5518 	pjmedia_transport_get_info(call_med->tp, &tpinfo);
5519 	ice_info = (pjmedia_ice_transport_info*)
5520                     pjmedia_transport_info_get_spc_info(
5521                         &tpinfo, PJMEDIA_TRANSPORT_TYPE_ICE);
5522         if (!ice_info)
5523 	    continue;
5524 
5525         /* Stop and re-init ICE stream transport.
5526          * According to RFC 5245 section 9.1.1.1, during ICE restart,
5527          * media can continue to be sent to the previously validated pair.
5528          */
5529         pjmedia_transport_media_stop(call_med->tp);
5530         pjmedia_transport_media_create(call_med->tp, call->inv->pool_prov,
5531                                        (call_med->enable_rtcp_mux?
5532             			    	PJMEDIA_TPMED_RTCP_MUX: 0),
5533             			       NULL, mi);
5534 
5535         PJ_LOG(4, (THIS_FILE, "Restarting ICE for media %d", mi));
5536     }
5537 #endif
5538 
5539     pjsua_call_cleanup_flag(&call->opt);
5540 
5541     if (pjsua_var.ua_cfg.cb.on_call_tx_offer) {
5542 	(*pjsua_var.ua_cfg.cb.on_call_tx_offer)(call->index, NULL,
5543 						&call->opt);
5544     }
5545 
5546     /* We may need to re-initialize media before creating SDP */
5547     if (call->med_prov_cnt == 0 || pjsua_var.ua_cfg.cb.on_call_tx_offer) {
5548     	status = apply_call_setting(call, &call->opt, NULL);
5549     	if (status != PJ_SUCCESS)
5550 	    goto on_return;
5551     }
5552 
5553     /* See if we've put call on hold. */
5554     if (call->local_hold) {
5555 	PJ_LOG(4,(THIS_FILE,
5556 		  "Call %d: call is on-hold locally, creating call-hold SDP ",
5557 		  call->index));
5558 	status = create_sdp_of_call_hold( call, offer );
5559     } else {
5560 	PJ_LOG(4,(THIS_FILE, "Call %d: asked to send a new offer",
5561 		  call->index));
5562 
5563 	status = pjsua_media_channel_create_sdp(call->index,
5564 						call->inv->pool_prov,
5565 					        NULL, offer, NULL);
5566     }
5567 
5568     if (status != PJ_SUCCESS) {
5569 	pjsua_perror(THIS_FILE, "Unable to create local SDP", status);
5570 	goto on_return;
5571     }
5572 
5573 on_return:
5574     pj_log_pop_indent();
5575 }
5576 
5577 
5578 /*
5579  * Callback called by event framework when the xfer subscription state
5580  * has changed.
5581  */
xfer_client_on_evsub_state(pjsip_evsub * sub,pjsip_event * event)5582 static void xfer_client_on_evsub_state( pjsip_evsub *sub, pjsip_event *event)
5583 {
5584 
5585     PJ_UNUSED_ARG(event);
5586 
5587     pj_log_push_indent();
5588 
5589     /*
5590      * When subscription is accepted (got 200/OK to REFER), check if
5591      * subscription suppressed.
5592      */
5593     if (pjsip_evsub_get_state(sub) == PJSIP_EVSUB_STATE_ACCEPTED) {
5594 
5595 	pjsip_rx_data *rdata;
5596 	pjsip_generic_string_hdr *refer_sub;
5597 	const pj_str_t REFER_SUB = { "Refer-Sub", 9 };
5598 	pjsua_call *call;
5599 
5600 	call = (pjsua_call*) pjsip_evsub_get_mod_data(sub, pjsua_var.mod.id);
5601 
5602 	/* Must be receipt of response message */
5603 	pj_assert(event->type == PJSIP_EVENT_TSX_STATE &&
5604 		  event->body.tsx_state.type == PJSIP_EVENT_RX_MSG);
5605 	rdata = event->body.tsx_state.src.rdata;
5606 
5607 	/* Find Refer-Sub header */
5608 	refer_sub = (pjsip_generic_string_hdr*)
5609 		    pjsip_msg_find_hdr_by_name(rdata->msg_info.msg,
5610 					       &REFER_SUB, NULL);
5611 
5612 	/* Check if subscription is suppressed */
5613 	if (refer_sub && pj_stricmp2(&refer_sub->hvalue, "false")==0) {
5614 	    /* Since no subscription is desired, assume that call has been
5615 	     * transferred successfully.
5616 	     */
5617 	    if (call && !call->hanging_up &&
5618 	        pjsua_var.ua_cfg.cb.on_call_transfer_status)
5619 	    {
5620 		const pj_str_t ACCEPTED = { "Accepted", 8 };
5621 		pj_bool_t cont = PJ_FALSE;
5622 		(*pjsua_var.ua_cfg.cb.on_call_transfer_status)(call->index,
5623 							       200,
5624 							       &ACCEPTED,
5625 							       PJ_TRUE,
5626 							       &cont);
5627 	    }
5628 
5629 	    /* Yes, subscription is suppressed.
5630 	     * Terminate our subscription now.
5631 	     */
5632 	    PJ_LOG(4,(THIS_FILE, "Xfer subscription suppressed, terminating "
5633 				 "event subcription..."));
5634 	    pjsip_evsub_terminate(sub, PJ_TRUE);
5635 
5636 	} else {
5637 	    /* Notify application about call transfer progress.
5638 	     * Initially notify with 100/Accepted status.
5639 	     */
5640 	    if (call && !call->hanging_up &&
5641 	        pjsua_var.ua_cfg.cb.on_call_transfer_status)
5642 	    {
5643 		const pj_str_t ACCEPTED = { "Accepted", 8 };
5644 		pj_bool_t cont = PJ_FALSE;
5645 		(*pjsua_var.ua_cfg.cb.on_call_transfer_status)(call->index,
5646 							       100,
5647 							       &ACCEPTED,
5648 							       PJ_FALSE,
5649 							       &cont);
5650 	    }
5651 	}
5652     }
5653     /*
5654      * On incoming NOTIFY or an error response, notify application about call
5655      * transfer progress.
5656      */
5657     else if (pjsip_evsub_get_state(sub) == PJSIP_EVSUB_STATE_ACTIVE ||
5658 	     pjsip_evsub_get_state(sub) == PJSIP_EVSUB_STATE_TERMINATED)
5659     {
5660 	pjsua_call *call;
5661 	pjsip_msg *msg;
5662 	pjsip_msg_body *body;
5663 	pjsip_status_line status_line;
5664 	pj_bool_t is_last;
5665 	pj_bool_t cont;
5666 	pj_status_t status;
5667 
5668 	call = (pjsua_call*) pjsip_evsub_get_mod_data(sub, pjsua_var.mod.id);
5669 
5670 	/* When subscription is terminated, clear the xfer_sub member of
5671 	 * the inv_data.
5672 	 */
5673 	if (pjsip_evsub_get_state(sub) == PJSIP_EVSUB_STATE_TERMINATED) {
5674 	    pjsip_evsub_set_mod_data(sub, pjsua_var.mod.id, NULL);
5675 	    PJ_LOG(4,(THIS_FILE, "Xfer client subscription terminated"));
5676 
5677 	}
5678 
5679 	if (!call || call->hanging_up || !event ||
5680 	    !pjsua_var.ua_cfg.cb.on_call_transfer_status)
5681 	{
5682 	    /* Application is not interested with call progress status */
5683 	    goto on_return;
5684 	}
5685 
5686 	if (event->type == PJSIP_EVENT_TSX_STATE &&
5687 	    event->body.tsx_state.type == PJSIP_EVENT_RX_MSG)
5688 	{
5689 	    pjsip_rx_data *rdata;
5690 
5691 	    rdata = event->body.tsx_state.src.rdata;
5692 	    msg = rdata->msg_info.msg;
5693 
5694 	    /* This better be a NOTIFY request */
5695 	    if (pjsip_method_cmp(&msg->line.req.method,
5696 				 pjsip_get_notify_method()) == 0)
5697 	    {
5698 		/* Check if there's body */
5699 		body = msg->body;
5700 		if (!body) {
5701 		    PJ_LOG(2, (THIS_FILE,
5702 			       "Warning: received NOTIFY without message "
5703 			       "body"));
5704 		    goto on_return;
5705 		}
5706 
5707 		/* Check for appropriate content */
5708 		if (pj_stricmp2(&body->content_type.type, "message") != 0 ||
5709 		    pj_stricmp2(&body->content_type.subtype, "sipfrag") != 0)
5710 		{
5711 		    PJ_LOG(2, (THIS_FILE,
5712 			       "Warning: received NOTIFY with non "
5713 			       "message/sipfrag content"));
5714 		    goto on_return;
5715 		}
5716 
5717 		/* Try to parse the content */
5718 		status = pjsip_parse_status_line((char*)body->data, body->len,
5719 						 &status_line);
5720 		if (status != PJ_SUCCESS) {
5721 		    PJ_LOG(2, (THIS_FILE,
5722 			       "Warning: received NOTIFY with invalid "
5723 			       "message/sipfrag content"));
5724 		    goto on_return;
5725 		}
5726 	    } else {
5727 		status_line.code = msg->line.status.code;
5728 		status_line.reason = msg->line.status.reason;
5729 	    }
5730 	} else {
5731 	    status_line.code = 500;
5732 	    status_line.reason = *pjsip_get_status_text(500);
5733 	}
5734 
5735 	/* Notify application */
5736 	is_last = (pjsip_evsub_get_state(sub)==PJSIP_EVSUB_STATE_TERMINATED);
5737 	cont = !is_last;
5738 	(*pjsua_var.ua_cfg.cb.on_call_transfer_status)(call->index,
5739 						       status_line.code,
5740 						       &status_line.reason,
5741 						       is_last, &cont);
5742 
5743 	if (!cont) {
5744 	    pjsip_evsub_set_mod_data(sub, pjsua_var.mod.id, NULL);
5745 	}
5746 
5747 	/* If the call transfer has completed but the subscription is
5748 	 * not terminated, terminate it now.
5749 	 */
5750 	if (status_line.code/100 == 2 && !is_last) {
5751 	    pjsip_tx_data *tdata;
5752 
5753 	    status = pjsip_evsub_initiate(sub, pjsip_get_subscribe_method(),
5754 					  0, &tdata);
5755 	    if (status == PJ_SUCCESS)
5756 		status = pjsip_evsub_send_request(sub, tdata);
5757 	}
5758     }
5759 
5760 on_return:
5761     pj_log_pop_indent();
5762 }
5763 
5764 
5765 /*
5766  * Callback called by event framework when the xfer subscription state
5767  * has changed.
5768  */
xfer_server_on_evsub_state(pjsip_evsub * sub,pjsip_event * event)5769 static void xfer_server_on_evsub_state( pjsip_evsub *sub, pjsip_event *event)
5770 {
5771     PJ_UNUSED_ARG(event);
5772 
5773     pj_log_push_indent();
5774 
5775     /*
5776      * When subscription is terminated, clear the xfer_sub member of
5777      * the inv_data.
5778      */
5779     if (pjsip_evsub_get_state(sub) == PJSIP_EVSUB_STATE_TERMINATED) {
5780 	pjsua_call *call;
5781 
5782 	call = (pjsua_call*) pjsip_evsub_get_mod_data(sub, pjsua_var.mod.id);
5783 	if (!call)
5784 	    goto on_return;
5785 
5786 	pjsip_evsub_set_mod_data(sub, pjsua_var.mod.id, NULL);
5787 	call->xfer_sub = NULL;
5788 
5789 	PJ_LOG(4,(THIS_FILE, "Xfer server subscription terminated"));
5790     }
5791 
5792 on_return:
5793     pj_log_pop_indent();
5794 }
5795 
5796 
5797 /*
5798  * Follow transfer (REFER) request.
5799  */
on_call_transferred(pjsip_inv_session * inv,pjsip_rx_data * rdata)5800 static void on_call_transferred( pjsip_inv_session *inv,
5801 			        pjsip_rx_data *rdata )
5802 {
5803     pj_status_t status;
5804     pjsip_tx_data *tdata;
5805     pjsua_call *existing_call;
5806     int new_call;
5807     const pj_str_t str_refer_to = { "Refer-To", 8};
5808     const pj_str_t str_refer_sub = { "Refer-Sub", 9 };
5809     const pj_str_t str_ref_by = { "Referred-By", 11 };
5810     pjsip_generic_string_hdr *refer_to;
5811     pjsip_generic_string_hdr *refer_sub;
5812     pjsip_hdr *ref_by_hdr;
5813     pj_bool_t no_refer_sub = PJ_FALSE;
5814     char *uri;
5815     pjsua_msg_data msg_data;
5816     pj_str_t tmp;
5817     pjsip_status_code code;
5818     pjsip_evsub *sub;
5819     pjsua_call_setting call_opt;
5820 
5821     pj_log_push_indent();
5822 
5823     existing_call = (pjsua_call*) inv->dlg->mod_data[pjsua_var.mod.id];
5824     if (existing_call->hanging_up) {
5825 	pjsip_dlg_respond( inv->dlg, rdata, 487, NULL, NULL, NULL);
5826     	goto on_return;
5827     }
5828 
5829     /* Find the Refer-To header */
5830     refer_to = (pjsip_generic_string_hdr*)
5831 	pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &str_refer_to, NULL);
5832 
5833     if (refer_to == NULL) {
5834 	/* Invalid Request.
5835 	 * No Refer-To header!
5836 	 */
5837 	PJ_LOG(4,(THIS_FILE, "Received REFER without Refer-To header!"));
5838 	pjsip_dlg_respond( inv->dlg, rdata, 400, NULL, NULL, NULL);
5839 	goto on_return;
5840     }
5841 
5842     /* Find optional Refer-Sub header */
5843     refer_sub = (pjsip_generic_string_hdr*)
5844 	pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &str_refer_sub, NULL);
5845 
5846     if (refer_sub) {
5847 	if (pj_strnicmp2(&refer_sub->hvalue, "true", 4)!=0)
5848 	    no_refer_sub = PJ_TRUE;
5849     }
5850 
5851     /* Find optional Referred-By header (to be copied onto outgoing INVITE
5852      * request.
5853      */
5854     ref_by_hdr = (pjsip_hdr*)
5855 		 pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &str_ref_by,
5856 					    NULL);
5857 
5858     /* Notify callback */
5859     code = PJSIP_SC_ACCEPTED;
5860     if (pjsua_var.ua_cfg.cb.on_call_transfer_request) {
5861 	(*pjsua_var.ua_cfg.cb.on_call_transfer_request)(existing_call->index,
5862 							&refer_to->hvalue,
5863 							&code);
5864     }
5865 
5866     pjsua_call_cleanup_flag(&existing_call->opt);
5867     call_opt = existing_call->opt;
5868     if (pjsua_var.ua_cfg.cb.on_call_transfer_request2) {
5869 	(*pjsua_var.ua_cfg.cb.on_call_transfer_request2)(existing_call->index,
5870 							 &refer_to->hvalue,
5871 							 &code,
5872 							 &call_opt);
5873     }
5874 
5875     if (code < 200)
5876 	code = PJSIP_SC_ACCEPTED;
5877     if (code >= 300) {
5878 	/* Application rejects call transfer request */
5879 	pjsip_dlg_respond( inv->dlg, rdata, code, NULL, NULL, NULL);
5880 	goto on_return;
5881     }
5882 
5883     PJ_LOG(3,(THIS_FILE, "Call to %.*s is being transferred to %.*s",
5884 	      (int)inv->dlg->remote.info_str.slen,
5885 	      inv->dlg->remote.info_str.ptr,
5886 	      (int)refer_to->hvalue.slen,
5887 	      refer_to->hvalue.ptr));
5888 
5889     if (no_refer_sub) {
5890 	/*
5891 	 * Always answer with 2xx.
5892 	 */
5893 	pjsip_tx_data *tdata2;
5894 	const pj_str_t str_false = { "false", 5};
5895 	pjsip_hdr *hdr;
5896 
5897 	status = pjsip_dlg_create_response(inv->dlg, rdata, code, NULL,
5898 					   &tdata2);
5899 	if (status != PJ_SUCCESS) {
5900 	    pjsua_perror(THIS_FILE, "Unable to create 2xx response to REFER",
5901 			 status);
5902 	    goto on_return;
5903 	}
5904 
5905 	/* Add Refer-Sub header */
5906 	hdr = (pjsip_hdr*)
5907 	       pjsip_generic_string_hdr_create(tdata2->pool, &str_refer_sub,
5908 					      &str_false);
5909 	pjsip_msg_add_hdr(tdata2->msg, hdr);
5910 
5911 
5912 	/* Send answer */
5913 	status = pjsip_dlg_send_response(inv->dlg, pjsip_rdata_get_tsx(rdata),
5914 					 tdata2);
5915 	if (status != PJ_SUCCESS) {
5916 	    pjsua_perror(THIS_FILE, "Unable to create 2xx response to REFER",
5917 			 status);
5918 	    goto on_return;
5919 	}
5920 
5921 	/* Don't have subscription */
5922 	sub = NULL;
5923 
5924     } else {
5925 	struct pjsip_evsub_user xfer_cb;
5926 	pjsip_hdr hdr_list;
5927 
5928 	/* Init callback */
5929 	pj_bzero(&xfer_cb, sizeof(xfer_cb));
5930 	xfer_cb.on_evsub_state = &xfer_server_on_evsub_state;
5931 
5932 	/* Init additional header list to be sent with REFER response */
5933 	pj_list_init(&hdr_list);
5934 
5935 	/* Create transferee event subscription */
5936 	status = pjsip_xfer_create_uas( inv->dlg, &xfer_cb, rdata, &sub);
5937 	if (status != PJ_SUCCESS) {
5938 	    pjsua_perror(THIS_FILE, "Unable to create xfer uas", status);
5939 	    pjsip_dlg_respond( inv->dlg, rdata, 500, NULL, NULL, NULL);
5940 	    goto on_return;
5941 	}
5942 
5943 	/* If there's Refer-Sub header and the value is "true", send back
5944 	 * Refer-Sub in the response with value "true" too.
5945 	 */
5946 	if (refer_sub) {
5947 	    const pj_str_t str_true = { "true", 4 };
5948 	    pjsip_hdr *hdr;
5949 
5950 	    hdr = (pjsip_hdr*)
5951 		   pjsip_generic_string_hdr_create(inv->dlg->pool,
5952 						   &str_refer_sub,
5953 						   &str_true);
5954 	    pj_list_push_back(&hdr_list, hdr);
5955 
5956 	}
5957 
5958 	/* Accept the REFER request, send 2xx. */
5959 	pjsip_xfer_accept(sub, rdata, code, &hdr_list);
5960 
5961 	/* Create initial NOTIFY request */
5962 	status = pjsip_xfer_notify( sub, PJSIP_EVSUB_STATE_ACTIVE,
5963 				    100, NULL, &tdata);
5964 	if (status != PJ_SUCCESS) {
5965 	    pjsua_perror(THIS_FILE, "Unable to create NOTIFY to REFER",
5966 			 status);
5967 	    goto on_return;
5968 	}
5969 
5970 	/* Send initial NOTIFY request */
5971 	status = pjsip_xfer_send_request( sub, tdata);
5972 	if (status != PJ_SUCCESS) {
5973 	    pjsua_perror(THIS_FILE, "Unable to send NOTIFY to REFER", status);
5974 	    goto on_return;
5975 	}
5976     }
5977 
5978     /* We're cheating here.
5979      * We need to get a null terminated string from a pj_str_t.
5980      * So grab the pointer from the hvalue and NULL terminate it, knowing
5981      * that the NULL position will be occupied by a newline.
5982      */
5983     uri = refer_to->hvalue.ptr;
5984     uri[refer_to->hvalue.slen] = '\0';
5985 
5986     /* Init msg_data */
5987     pjsua_msg_data_init(&msg_data);
5988 
5989     /* If Referred-By header is present in the REFER request, copy this
5990      * to the outgoing INVITE request.
5991      */
5992     if (ref_by_hdr != NULL) {
5993 	pjsip_hdr *dup = (pjsip_hdr*)
5994 			 pjsip_hdr_clone(rdata->tp_info.pool, ref_by_hdr);
5995 	pj_list_push_back(&msg_data.hdr_list, dup);
5996     }
5997 
5998     /* Now make the outgoing call. */
5999     tmp = pj_str(uri);
6000     status = pjsua_call_make_call(existing_call->acc_id, &tmp, &call_opt,
6001 				  existing_call->user_data, &msg_data,
6002 				  &new_call);
6003     if (status != PJ_SUCCESS) {
6004 
6005 	/* Notify xferer about the error (if we have subscription) */
6006 	if (sub) {
6007 	    status = pjsip_xfer_notify(sub, PJSIP_EVSUB_STATE_TERMINATED,
6008 				       500, NULL, &tdata);
6009 	    if (status != PJ_SUCCESS) {
6010 		pjsua_perror(THIS_FILE, "Unable to create NOTIFY to REFER",
6011 			      status);
6012 		goto on_return;
6013 	    }
6014 	    status = pjsip_xfer_send_request(sub, tdata);
6015 	    if (status != PJ_SUCCESS) {
6016 		pjsua_perror(THIS_FILE, "Unable to send NOTIFY to REFER",
6017 			      status);
6018 		goto on_return;
6019 	    }
6020 	}
6021 	goto on_return;
6022     }
6023 
6024     if (sub) {
6025 	/* Put the server subscription in inv_data.
6026 	 * Subsequent state changed in pjsua_inv_on_state_changed() will be
6027 	 * reported back to the server subscription.
6028 	 */
6029 	pjsua_var.calls[new_call].xfer_sub = sub;
6030 
6031 	/* Put the invite_data in the subscription. */
6032 	pjsip_evsub_set_mod_data(sub, pjsua_var.mod.id,
6033 				 &pjsua_var.calls[new_call]);
6034     }
6035 
6036 on_return:
6037     pj_log_pop_indent();
6038 }
6039 
6040 
6041 
6042 /*
6043  * This callback is called when transaction state has changed in INVITE
6044  * session. We use this to trap:
6045  *  - incoming REFER request.
6046  *  - incoming MESSAGE request.
6047  */
pjsua_call_on_tsx_state_changed(pjsip_inv_session * inv,pjsip_transaction * tsx,pjsip_event * e)6048 static void pjsua_call_on_tsx_state_changed(pjsip_inv_session *inv,
6049 					    pjsip_transaction *tsx,
6050 					    pjsip_event *e)
6051 {
6052     /* Incoming INFO request for media control, DTMF, trickle ICE, etc. */
6053     const pj_str_t STR_APPLICATION	 = { "application", 11};
6054     const pj_str_t STR_MEDIA_CONTROL_XML = { "media_control+xml", 17 };
6055     const pj_str_t STR_DTMF_RELAY	 = { "dtmf-relay", 10 };
6056     const pj_str_t STR_TRICKLE_ICE_SDP	 = { "trickle-ice-sdpfrag", 19 };
6057 
6058     pjsua_call *call;
6059 
6060     pj_log_push_indent();
6061 
6062     call = (pjsua_call*) inv->dlg->mod_data[pjsua_var.mod.id];
6063 
6064     if (call == NULL)
6065 	goto on_return;
6066 
6067     if (call->inv == NULL || call->hanging_up) {
6068 	/* Call has been disconnected. */
6069 	goto on_return;
6070     }
6071 
6072     /* https://trac.pjsip.org/repos/ticket/1452:
6073      *    If a request is retried due to 401/407 challenge, don't process the
6074      *    transaction first but wait until we've retried it.
6075      */
6076     if (tsx->role == PJSIP_ROLE_UAC &&
6077 	(tsx->status_code==401 || tsx->status_code==407) &&
6078 	tsx->last_tx && tsx->last_tx->auth_retry)
6079     {
6080 	goto on_return;
6081     }
6082 
6083     /* Notify application callback first */
6084     if (pjsua_var.ua_cfg.cb.on_call_tsx_state) {
6085 	(*pjsua_var.ua_cfg.cb.on_call_tsx_state)(call->index, tsx, e);
6086     }
6087 
6088     if (tsx->role==PJSIP_ROLE_UAS &&
6089 	tsx->state==PJSIP_TSX_STATE_TRYING &&
6090 	pjsip_method_cmp(&tsx->method, pjsip_get_refer_method())==0)
6091     {
6092 	/*
6093 	 * Incoming REFER request.
6094 	 */
6095 	on_call_transferred(call->inv, e->body.tsx_state.src.rdata);
6096 
6097     }
6098     else if (tsx->role==PJSIP_ROLE_UAS &&
6099 	     tsx->state==PJSIP_TSX_STATE_TRYING &&
6100 	     pjsip_method_cmp(&tsx->method, &pjsip_message_method)==0)
6101     {
6102 	/*
6103 	 * Incoming MESSAGE request!
6104 	 */
6105 	pjsip_rx_data *rdata;
6106 	pjsip_accept_hdr *accept_hdr;
6107 
6108 	rdata = e->body.tsx_state.src.rdata;
6109 
6110 	/* Request MUST have message body, with Content-Type equal to
6111 	 * "text/plain".
6112 	 */
6113 	if (pjsua_im_accept_pager(rdata, &accept_hdr) == PJ_FALSE) {
6114 
6115 	    pjsip_hdr hdr_list;
6116 
6117 	    pj_list_init(&hdr_list);
6118 	    pj_list_push_back(&hdr_list, accept_hdr);
6119 
6120 	    pjsip_dlg_respond( inv->dlg, rdata, PJSIP_SC_NOT_ACCEPTABLE_HERE,
6121 			       NULL, &hdr_list, NULL );
6122 	    goto on_return;
6123 	}
6124 
6125 	/* Respond with 200 first, so that remote doesn't retransmit in case
6126 	 * the UI takes too long to process the message.
6127 	 */
6128 	pjsip_dlg_respond( inv->dlg, rdata, 200, NULL, NULL, NULL);
6129 
6130 	/* Process MESSAGE request */
6131 	pjsua_im_process_pager(call->index, &inv->dlg->remote.info_str,
6132 			       &inv->dlg->local.info_str, rdata);
6133 
6134     }
6135     else if (e->type == PJSIP_EVENT_TSX_STATE &&
6136             tsx->role == PJSIP_ROLE_UAC &&
6137             pjsip_method_cmp(&tsx->method, &pjsip_message_method)==0 &&
6138             (tsx->state == PJSIP_TSX_STATE_COMPLETED ||
6139             (tsx->state == PJSIP_TSX_STATE_TERMINATED &&
6140             e->body.tsx_state.prev_state != PJSIP_TSX_STATE_COMPLETED)))
6141     {
6142         /* Handle outgoing pager status */
6143         if (tsx->status_code >= 200) {
6144             pjsua_im_data *im_data;
6145 
6146             im_data = (pjsua_im_data*) tsx->mod_data[pjsua_var.mod.id];
6147             /* im_data can be NULL if this is typing indication */
6148 
6149             if (im_data) {
6150                 pj_str_t im_body = im_data->body;
6151                 if (im_body.slen==0) {
6152                     pjsip_msg_body *body = tsx->last_tx->msg->body;
6153                     pj_strset(&im_body, body->data, body->len);
6154                 }
6155 
6156                 if (pjsua_var.ua_cfg.cb.on_pager_status) {
6157                         pjsua_var.ua_cfg.cb.on_pager_status(im_data->call_id,
6158                                                             &im_data->to,
6159                                                             &im_body,
6160                                                             im_data->user_data,
6161                                                             (pjsip_status_code)
6162                                                             tsx->status_code,
6163                                                             &tsx->status_text);
6164                 }
6165 
6166                 if (pjsua_var.ua_cfg.cb.on_pager_status2) {
6167                     pjsip_rx_data* rdata;
6168 
6169                     if (e->body.tsx_state.type == PJSIP_EVENT_RX_MSG)
6170                     rdata = e->body.tsx_state.src.rdata;
6171                     else
6172                     rdata = NULL;
6173 
6174                     pjsua_var.ua_cfg.cb.on_pager_status2(im_data->call_id,
6175                                                         &im_data->to,
6176                                                         &im_body,
6177                                                         im_data->user_data,
6178                                                         (pjsip_status_code)
6179                                                             tsx->status_code,
6180                                                         &tsx->status_text,
6181                                                         tsx->last_tx,
6182                                                         rdata, im_data->acc_id);
6183                 }
6184             }
6185         }
6186     } else if (tsx->role == PJSIP_ROLE_UAC &&
6187                pjsip_method_cmp(&tsx->method, pjsip_get_invite_method())==0 &&
6188                tsx->state >= PJSIP_TSX_STATE_COMPLETED &&
6189 	       e->body.tsx_state.prev_state < PJSIP_TSX_STATE_COMPLETED &&
6190                (!PJSIP_IS_STATUS_IN_CLASS(tsx->status_code, 300) &&
6191                 tsx->status_code!=401 && tsx->status_code!=407 &&
6192                 tsx->status_code!=422))
6193     {
6194         if (tsx->status_code/100 == 2) {
6195             /* If we have sent CANCEL and the original INVITE returns a 2xx,
6196              * we then send BYE.
6197              */
6198             if (call->hanging_up) {
6199                 PJ_LOG(3,(THIS_FILE, "Unsuccessful in cancelling the original "
6200 	        	  "INVITE for call %d due to %d response, sending BYE "
6201 	        	  "instead", call->index, tsx->status_code));
6202 		call_disconnect(call->inv, PJSIP_SC_OK);
6203             }
6204         } else {
6205             /* Monitor the status of call hold/unhold request */
6206             if (tsx->last_tx == (pjsip_tx_data*)call->hold_msg) {
6207 	        /* Outgoing call hold failed */
6208 	        call->local_hold = PJ_FALSE;
6209 	        PJ_LOG(3,(THIS_FILE, "Error putting call %d on hold "
6210 	        	  "(reason=%d)", call->index, tsx->status_code));
6211             } else if (call->opt.flag & PJSUA_CALL_UNHOLD) {
6212 	        /* Call unhold failed */
6213             	call->local_hold = PJ_TRUE;
6214 	    	PJ_LOG(3,(THIS_FILE, "Error releasing hold on call %d "
6215 	    		  "(reason=%d)", call->index, tsx->status_code));
6216 	    }
6217         }
6218 
6219         if (tsx->last_tx == (pjsip_tx_data*)call->hold_msg) {
6220             call->hold_msg = NULL;
6221         }
6222 
6223         if (tsx->last_tx->msg->body &&
6224             (tsx->status_code/100 != 2 || !call->med_update_success))
6225         {
6226             /* Either we get non-2xx or media update failed,
6227              * revert back provisional media.
6228              */
6229 	    pjsua_media_prov_revert(call->index);
6230         }
6231     } else if (tsx->role == PJSIP_ROLE_UAC &&
6232                pjsip_method_cmp(&tsx->method, &pjsip_update_method)==0 &&
6233                tsx->state >= PJSIP_TSX_STATE_COMPLETED &&
6234 	       e->body.tsx_state.prev_state < PJSIP_TSX_STATE_COMPLETED &&
6235                (!PJSIP_IS_STATUS_IN_CLASS(tsx->status_code, 300) &&
6236                 tsx->status_code!=401 && tsx->status_code!=407 &&
6237                 tsx->status_code!=422))
6238     {
6239         if (tsx->last_tx->msg->body &&
6240             (tsx->status_code/100 != 2 || !call->med_update_success))
6241         {
6242             /* Either we get non-2xx or media update failed,
6243              * revert back provisional media.
6244              */
6245 	    pjsua_media_prov_revert(call->index);
6246         }
6247     } else if (tsx->role==PJSIP_ROLE_UAS &&
6248 	       tsx->state==PJSIP_TSX_STATE_TRYING &&
6249 	       pjsip_method_cmp(&tsx->method, &pjsip_info_method)==0)
6250     {
6251 	pjsip_rx_data *rdata = e->body.tsx_state.src.rdata;
6252 	pjsip_msg_body *body = rdata->msg_info.msg->body;
6253 
6254 	/* Check Media Control content in the INFO message */
6255 	if (body && body->len &&
6256 	    pj_stricmp(&body->content_type.type, &STR_APPLICATION)==0 &&
6257 	    pj_stricmp(&body->content_type.subtype, &STR_MEDIA_CONTROL_XML)==0)
6258 	{
6259 	    pjsip_tx_data *tdata;
6260 	    pj_str_t control_st;
6261 	    pj_status_t status;
6262 
6263 	    /* Apply and answer the INFO request */
6264 	    pj_strset(&control_st, (char*)body->data, body->len);
6265 	    status = pjsua_media_apply_xml_control(call->index, &control_st);
6266 	    if (status == PJ_SUCCESS) {
6267 		status = pjsip_endpt_create_response(tsx->endpt, rdata,
6268 						     200, NULL, &tdata);
6269 		if (status == PJ_SUCCESS)
6270 		    status = pjsip_tsx_send_msg(tsx, tdata);
6271 	    } else {
6272 		status = pjsip_endpt_create_response(tsx->endpt, rdata,
6273 						     400, NULL, &tdata);
6274 		if (status == PJ_SUCCESS)
6275 		    status = pjsip_tsx_send_msg(tsx, tdata);
6276 	    }
6277 	}
6278 
6279 	/* Check DTMF content in the INFO message */
6280 	else if (body && body->len &&
6281 		 pj_stricmp(&body->content_type.type, &STR_APPLICATION)==0 &&
6282 		 pj_stricmp(&body->content_type.subtype, &STR_DTMF_RELAY)==0)
6283 	{
6284 	    pjsip_tx_data *tdata;
6285 	    pj_status_t status;
6286 	    pj_bool_t is_handled = PJ_FALSE;
6287 
6288 	    if (pjsua_var.ua_cfg.cb.on_dtmf_digit2 ||
6289                 pjsua_var.ua_cfg.cb.on_dtmf_event)
6290             {
6291 		pjsua_dtmf_info info = {0};
6292 		pj_str_t delim, token, input;
6293 		pj_ssize_t found_idx;
6294 
6295 		delim = pj_str("\r\n");
6296 		input = pj_str(rdata->msg_info.msg->body->data);
6297 		found_idx = pj_strtok(&input, &delim, &token, 0);
6298 		if (found_idx != input.slen) {
6299 		    /* Get signal/digit */
6300 		    const pj_str_t STR_SIGNAL = { "Signal", 6 };
6301 		    const pj_str_t STR_DURATION = { "Duration", 8 };
6302 		    char *val;
6303 		    pj_ssize_t count_equal_sign;
6304 
6305 		    val = pj_strstr(&input, &STR_SIGNAL);
6306 		    if (val) {
6307 			char* p = val + STR_SIGNAL.slen;
6308 			count_equal_sign = 0;
6309 			while ((p - input.ptr < input.slen) && (*p == ' ' || *p == '=')) {
6310 			    if(*p == '=')
6311 				count_equal_sign++;
6312 			    ++p;
6313 			}
6314 
6315 			if (count_equal_sign == 1 && (p - input.ptr < input.slen)) {
6316 			    info.digit = *p;
6317 			    is_handled = PJ_TRUE;
6318 			} else {
6319 			    PJ_LOG(2, (THIS_FILE, "Invalid dtmf-relay format"));
6320 			}
6321 
6322 			/* Get duration */
6323 			input.ptr += token.slen + 2;
6324 			input.slen -= (token.slen + 2);
6325 
6326 			val = pj_strstr(&input, &STR_DURATION);
6327 			if (val && is_handled) {
6328 			    pj_str_t val_str;
6329 			    char* ptr = val + STR_DURATION.slen;
6330 			    count_equal_sign = 0;
6331 			    while ((ptr - input.ptr < input.slen) &&
6332                                    (*ptr == ' ' || *ptr == '='))
6333                             {
6334 				if (*ptr == '=')
6335 				    count_equal_sign++;
6336 			        ++ptr;
6337 			    }
6338 
6339 			    if ((count_equal_sign == 1) &&
6340                                 (ptr - input.ptr < input.slen))
6341                             {
6342 			        val_str.ptr = ptr;
6343 			        val_str.slen = input.slen - (ptr - input.ptr);
6344 			        info.duration = pj_strtoul(&val_str);
6345 			    } else {
6346                                 info.duration = PJSUA_UNKNOWN_DTMF_DURATION;
6347 				is_handled = PJ_FALSE;
6348 				PJ_LOG(2, (THIS_FILE,
6349                                            "Invalid dtmf-relay format"));
6350 			    }
6351 			}
6352 
6353 			if (is_handled) {
6354 			    info.method = PJSUA_DTMF_METHOD_SIP_INFO;
6355                             if (pjsua_var.ua_cfg.cb.on_dtmf_event) {
6356 		                pjsua_dtmf_event evt;
6357                                 pj_timestamp begin_of_time, timestamp;
6358                                 /* Use the current instant as the events start
6359                                  * time.
6360                                  */
6361                                 begin_of_time.u64 = 0;
6362                                 pj_get_timestamp(&timestamp);
6363                                 evt.method = info.method;
6364                                 evt.timestamp = pj_elapsed_msec(&begin_of_time,
6365                                                                 &timestamp);
6366                                 evt.digit = info.digit;
6367                                 evt.duration = info.duration;
6368                                 /* There is only one message indicating the full
6369                                  * duration of the digit.
6370                                  */
6371                                 evt.flags = PJMEDIA_STREAM_DTMF_IS_END;
6372                                 (*pjsua_var.ua_cfg.cb.on_dtmf_event)(call->index,
6373                                                                      &evt);
6374                             } else {
6375 			        (*pjsua_var.ua_cfg.cb.on_dtmf_digit2)(call->index,
6376 							              &info);
6377                             }
6378 
6379 			    status = pjsip_endpt_create_response(tsx->endpt, rdata,
6380 				200, NULL, &tdata);
6381 			    if (status == PJ_SUCCESS)
6382 				status = pjsip_tsx_send_msg(tsx, tdata);
6383 			}
6384 		    }
6385 		}
6386 	    }
6387 
6388 	    if (!is_handled) {
6389 		status = pjsip_endpt_create_response(tsx->endpt, rdata,
6390 						     400, NULL, &tdata);
6391 		if (status == PJ_SUCCESS)
6392 		    status = pjsip_tsx_send_msg(tsx, tdata);
6393 	    }
6394 	}
6395 
6396 	/* Check Trickle ICE content in the INFO message */
6397 	else if (body && body->len &&
6398 		 pj_stricmp(&body->content_type.type, &STR_APPLICATION)==0 &&
6399 		 pj_stricmp(&body->content_type.subtype,
6400 			    &STR_TRICKLE_ICE_SDP)==0)
6401 	{
6402 	    pjsip_tx_data *tdata;
6403 	    pj_status_t status;
6404 
6405 	    /* Trickle ICE tasks:
6406 	     * - UAS receiving INFO, cease 18x retrans & start trickling
6407 	     */
6408 	    if (call->trickle_ice.enabled) {
6409 		pjsua_ice_check_start_trickling(call, PJ_FALSE, e);
6410 
6411 		/* Process the SIP INFO content */
6412 		trickle_ice_recv_sip_info(call, rdata);
6413 
6414 		/* Send 200 response, regardless */
6415 		status = pjsip_endpt_create_response(tsx->endpt, rdata,
6416 						     200, NULL, &tdata);
6417 	    } else {
6418 		/* Trickle ICE not enabled, send 400 response */
6419 		status = pjsip_endpt_create_response(tsx->endpt, rdata,
6420 						     400, NULL, &tdata);
6421 	    }
6422 	    if (status == PJ_SUCCESS)
6423 		status = pjsip_tsx_send_msg(tsx, tdata);
6424 	}
6425 
6426     } else if (tsx->role == PJSIP_ROLE_UAC &&
6427 	       pjsip_method_cmp(&tsx->method, &pjsip_info_method)==0 &&
6428 	       (tsx->state == PJSIP_TSX_STATE_COMPLETED ||
6429 	       (tsx->state == PJSIP_TSX_STATE_TERMINATED &&
6430 	        e->body.tsx_state.prev_state != PJSIP_TSX_STATE_COMPLETED)))
6431     {
6432 	pjsip_msg_body *body = NULL;
6433 
6434 	if (e->body.tsx_state.type == PJSIP_EVENT_TX_MSG)
6435 	    body = e->body.tsx_state.src.tdata->msg->body;
6436 	else
6437 	    body = e->body.tsx_state.tsx->last_tx->msg->body;
6438 
6439 	/* Check DTMF content in the INFO message */
6440 	if (body && body->len &&
6441 	    pj_stricmp(&body->content_type.type, &STR_APPLICATION)==0 &&
6442 	    pj_stricmp(&body->content_type.subtype, &STR_DTMF_RELAY)==0)
6443 	{
6444 	    /* Status of outgoing INFO request */
6445 	    if (tsx->status_code >= 200 && tsx->status_code < 300) {
6446 		PJ_LOG(4,(THIS_FILE,
6447 			  "Call %d: DTMF sent successfully with INFO",
6448 			  call->index));
6449 	    } else if (tsx->status_code >= 300) {
6450 		PJ_LOG(4,(THIS_FILE,
6451 			  "Call %d: Failed to send DTMF with INFO: %d/%.*s",
6452 			  call->index,
6453 		          tsx->status_code,
6454 			  (int)tsx->status_text.slen,
6455 			  tsx->status_text.ptr));
6456 	    }
6457 	}
6458 
6459 	/* Check Trickle ICE content in the INFO message */
6460 	else if (body && body->len &&
6461 		 pj_stricmp(&body->content_type.type, &STR_APPLICATION)==0 &&
6462 		 pj_stricmp(&body->content_type.subtype,
6463 			    &STR_TRICKLE_ICE_SDP)==0)
6464 	{
6465 	    /* Reset pending SIP INFO for Trickle ICE */
6466 	    call->trickle_ice.pending_info = PJ_FALSE;
6467 	}
6468     } else if (inv->state < PJSIP_INV_STATE_CONFIRMED &&
6469 	       pjsip_method_cmp(&tsx->method, pjsip_get_invite_method())==0 &&
6470 	       tsx->state == PJSIP_TSX_STATE_PROCEEDING &&
6471 	       tsx->status_code/10 == 18)
6472     {
6473 	/* Trickle ICE tasks:
6474 	 * - UAS sending 18x, start 18x retrans
6475 	 * - UAC receiving 18x, forcefully send SIP INFO & start trickling
6476 	 */
6477 	pj_bool_t force = call->trickle_ice.trickling<PJSUA_OP_STATE_RUNNING;
6478 	pjsua_ice_check_start_trickling(call, force, e);
6479     } else if (tsx->role == PJSIP_ROLE_UAS &&
6480 	       pjsip_method_cmp(&tsx->method, pjsip_get_prack_method())==0 &&
6481 	       tsx->state==PJSIP_TSX_STATE_TRYING)
6482     {
6483 	/* Trickle ICE tasks:
6484 	 * - UAS receiving PRACK, start trickling
6485 	 */
6486 	pjsua_ice_check_start_trickling(call, PJ_FALSE, e);
6487     }
6488 
6489 on_return:
6490     pj_log_pop_indent();
6491 }
6492 
6493 
6494 /* Redirection handler */
pjsua_call_on_redirected(pjsip_inv_session * inv,const pjsip_uri * target,const pjsip_event * e)6495 static pjsip_redirect_op pjsua_call_on_redirected(pjsip_inv_session *inv,
6496 						  const pjsip_uri *target,
6497 						  const pjsip_event *e)
6498 {
6499     pjsua_call *call = (pjsua_call*) inv->dlg->mod_data[pjsua_var.mod.id];
6500     pjsip_redirect_op op;
6501 
6502     pj_log_push_indent();
6503 
6504     if (!call->hanging_up && pjsua_var.ua_cfg.cb.on_call_redirected) {
6505 	op = (*pjsua_var.ua_cfg.cb.on_call_redirected)(call->index,
6506 							 target, e);
6507     } else {
6508 	if (!call->hanging_up) {
6509 	    PJ_LOG(4,(THIS_FILE, "Unhandled redirection for call %d "
6510 		      "(callback not implemented by application). "
6511 		      "Disconnecting call.",
6512 		      call->index));
6513 	}
6514 	op = PJSIP_REDIRECT_STOP;
6515     }
6516 
6517     pj_log_pop_indent();
6518 
6519     return op;
6520 }
6521 
6522