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, ¶m->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(×tamp);
6363 evt.method = info.method;
6364 evt.timestamp = pj_elapsed_msec(&begin_of_time,
6365 ×tamp);
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