1
/* $Id: pjsua_call.c 4779 2014-03-06 01:00:11Z ming $ */
3
* Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
4
* Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
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.
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.
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
20
#include <pjsua-lib/pjsua.h>
21
#include <pjsua-lib/pjsua_internal.h>
24
#define THIS_FILE "pjsua_call.c"
27
/* Retry interval of sending re-INVITE for locking a codec when remote
28
* SDP answer contains multiple codec, in milliseconds.
30
#define LOCK_CODEC_RETRY_INTERVAL 200
33
* Max UPDATE/re-INVITE retry to lock codec
35
#define LOCK_CODEC_MAX_RETRY 5
40
const pjsip_method pjsip_info_method =
47
/* This callback receives notification from invite session when the
48
* session state has changed.
50
static void pjsua_call_on_state_changed(pjsip_inv_session *inv,
53
/* This callback is called by invite session framework when UAC session
56
static void pjsua_call_on_forked( pjsip_inv_session *inv,
60
* Callback to be called when SDP offer/answer negotiation has just completed
61
* in the session. This function will start/update media if negotiation
64
static void pjsua_call_on_media_update(pjsip_inv_session *inv,
68
* Called when session received new offer.
70
static void pjsua_call_on_rx_offer(pjsip_inv_session *inv,
71
const pjmedia_sdp_session *offer);
74
* Called to generate new offer.
76
static void pjsua_call_on_create_offer(pjsip_inv_session *inv,
77
pjmedia_sdp_session **offer);
80
* This callback is called when transaction state has changed in INVITE
81
* session. We use this to trap:
82
* - incoming REFER request.
83
* - incoming MESSAGE request.
85
static void pjsua_call_on_tsx_state_changed(pjsip_inv_session *inv,
86
pjsip_transaction *tsx,
90
* Redirection handler.
92
static pjsip_redirect_op pjsua_call_on_redirected(pjsip_inv_session *inv,
93
const pjsip_uri *target,
94
const pjsip_event *e);
97
/* Create SDP for call hold. */
98
static pj_status_t create_sdp_of_call_hold(pjsua_call *call,
99
pjmedia_sdp_session **p_sdp);
102
* Callback called by event framework when the xfer subscription state
105
static void xfer_client_on_evsub_state( pjsip_evsub *sub, pjsip_event *event);
106
static void xfer_server_on_evsub_state( pjsip_evsub *sub, pjsip_event *event);
108
/* Timer callback to send re-INVITE/UPDATE to lock codec or ICE update */
109
static void reinv_timer_cb(pj_timer_heap_t *th, pj_timer_entry *entry);
111
/* Check and send reinvite for lock codec and ICE update */
112
static pj_status_t process_pending_reinvite(pjsua_call *call);
115
* Reset call descriptor.
117
static void reset_call(pjsua_call_id id)
119
pjsua_call *call = &pjsua_var.calls[id];
122
pj_bzero(call, sizeof(*call));
124
call->last_text.ptr = call->last_text_buf_;
125
for (i=0; i<PJ_ARRAY_SIZE(call->media); ++i) {
126
pjsua_call_media *call_med = &call->media[i];
127
call_med->ssrc = pj_rand();
128
call_med->strm.a.conf_slot = PJSUA_INVALID_ID;
129
call_med->strm.v.cap_win_id = PJSUA_INVALID_ID;
130
call_med->strm.v.rdr_win_id = PJSUA_INVALID_ID;
131
call_med->call = call;
133
call_med->tp_auto_del = PJ_TRUE;
135
pjsua_call_setting_default(&call->opt);
136
pj_timer_entry_init(&call->reinv_timer, PJ_FALSE,
137
(void*)(pj_size_t)id, &reinv_timer_cb);
142
* Init call subsystem.
144
pj_status_t pjsua_call_subsys_init(const pjsua_config *cfg)
146
pjsip_inv_callback inv_cb;
148
const pj_str_t str_norefersub = { "norefersub", 10 };
151
/* Init calls array. */
152
for (i=0; i<PJ_ARRAY_SIZE(pjsua_var.calls); ++i)
156
pjsua_config_dup(pjsua_var.pool, &pjsua_var.ua_cfg, cfg);
158
/* Verify settings */
159
if (pjsua_var.ua_cfg.max_calls >= PJSUA_MAX_CALLS) {
160
pjsua_var.ua_cfg.max_calls = PJSUA_MAX_CALLS;
163
/* Check the route URI's and force loose route if required */
164
for (i=0; i<pjsua_var.ua_cfg.outbound_proxy_cnt; ++i) {
165
status = normalize_route_uri(pjsua_var.pool,
166
&pjsua_var.ua_cfg.outbound_proxy[i]);
167
if (status != PJ_SUCCESS)
171
/* Initialize invite session callback. */
172
pj_bzero(&inv_cb, sizeof(inv_cb));
173
inv_cb.on_state_changed = &pjsua_call_on_state_changed;
174
inv_cb.on_new_session = &pjsua_call_on_forked;
175
inv_cb.on_media_update = &pjsua_call_on_media_update;
176
inv_cb.on_rx_offer = &pjsua_call_on_rx_offer;
177
inv_cb.on_create_offer = &pjsua_call_on_create_offer;
178
inv_cb.on_tsx_state_changed = &pjsua_call_on_tsx_state_changed;
179
inv_cb.on_redirected = &pjsua_call_on_redirected;
181
/* Initialize invite session module: */
182
status = pjsip_inv_usage_init(pjsua_var.endpt, &inv_cb);
183
PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
185
/* Add "norefersub" in Supported header */
186
pjsip_endpt_add_capability(pjsua_var.endpt, NULL, PJSIP_H_SUPPORTED,
187
NULL, 1, &str_norefersub);
189
/* Add "INFO" in Allow header, for DTMF and video key frame request. */
190
pjsip_endpt_add_capability(pjsua_var.endpt, NULL, PJSIP_H_ALLOW,
191
NULL, 1, &pjsip_info_method.name);
198
* Start call subsystem.
200
pj_status_t pjsua_call_subsys_start(void)
208
* Get maximum number of calls configured in pjsua.
210
PJ_DEF(unsigned) pjsua_call_get_max_count(void)
212
return pjsua_var.ua_cfg.max_calls;
217
* Get number of currently active calls.
219
PJ_DEF(unsigned) pjsua_call_get_count(void)
221
return pjsua_var.call_cnt;
228
PJ_DEF(pj_status_t) pjsua_enum_calls( pjsua_call_id ids[],
233
PJ_ASSERT_RETURN(ids && *count, PJ_EINVAL);
237
for (i=0, c=0; c<*count && i<pjsua_var.ua_cfg.max_calls; ++i) {
238
if (!pjsua_var.calls[i].inv)
252
/* Allocate one call id */
253
static pjsua_call_id alloc_call_id(void)
258
/* New algorithm: round-robin */
259
if (pjsua_var.next_call_id >= (int)pjsua_var.ua_cfg.max_calls ||
260
pjsua_var.next_call_id < 0)
262
pjsua_var.next_call_id = 0;
265
for (cid=pjsua_var.next_call_id;
266
cid<(int)pjsua_var.ua_cfg.max_calls;
269
if (pjsua_var.calls[cid].inv == NULL &&
270
pjsua_var.calls[cid].async_call.dlg == NULL)
272
++pjsua_var.next_call_id;
277
for (cid=0; cid < pjsua_var.next_call_id; ++cid) {
278
if (pjsua_var.calls[cid].inv == NULL &&
279
pjsua_var.calls[cid].async_call.dlg == NULL)
281
++pjsua_var.next_call_id;
288
for (cid=0; cid<(int)pjsua_var.ua_cfg.max_calls; ++cid) {
289
if (pjsua_var.calls[cid].inv == NULL)
294
return PJSUA_INVALID_ID;
297
/* Get signaling secure level.
299
* 0: if signaling is not secure
300
* 1: if TLS transport is used for immediate hop
301
* 2: if end-to-end signaling is secure.
303
static int get_secure_level(pjsua_acc_id acc_id, const pj_str_t *dst_uri)
305
const pj_str_t tls = pj_str(";transport=tls");
306
const pj_str_t sips = pj_str("sips:");
307
pjsua_acc *acc = &pjsua_var.acc[acc_id];
309
if (pj_stristr(dst_uri, &sips))
312
if (!pj_list_empty(&acc->route_set)) {
313
pjsip_route_hdr *r = acc->route_set.next;
314
pjsip_uri *uri = r->name_addr.uri;
315
pjsip_sip_uri *sip_uri;
317
sip_uri = (pjsip_sip_uri*)pjsip_uri_get_uri(uri);
318
if (pj_stricmp2(&sip_uri->transport_param, "tls")==0)
322
if (pj_stristr(dst_uri, &tls))
330
static int call_get_secure_level(pjsua_call *call)
332
if (call->inv->dlg->secure)
335
if (!pj_list_empty(&call->inv->dlg->route_set)) {
336
pjsip_route_hdr *r = call->inv->dlg->route_set.next;
337
pjsip_uri *uri = r->name_addr.uri;
338
pjsip_sip_uri *sip_uri;
340
sip_uri = (pjsip_sip_uri*)pjsip_uri_get_uri(uri);
341
if (pj_stricmp2(&sip_uri->transport_param, "tls")==0)
345
pjsip_sip_uri *sip_uri;
347
if (PJSIP_URI_SCHEME_IS_SIPS(call->inv->dlg->target))
349
if (!PJSIP_URI_SCHEME_IS_SIP(call->inv->dlg->target))
352
sip_uri = (pjsip_sip_uri*) pjsip_uri_get_uri(call->inv->dlg->target);
353
if (pj_stricmp2(&sip_uri->transport_param, "tls")==0)
361
/* Outgoing call callback when media transport creation is completed. */
363
on_make_call_med_tp_complete(pjsua_call_id call_id,
364
const pjsua_med_tp_state_info *info)
366
pjmedia_sdp_session *offer;
367
pjsip_inv_session *inv = NULL;
368
pjsua_call *call = &pjsua_var.calls[call_id];
369
pjsua_acc *acc = &pjsua_var.acc[call->acc_id];
370
pjsip_dialog *dlg = call->async_call.dlg;
371
unsigned options = 0;
372
pjsip_tx_data *tdata;
373
pj_bool_t cb_called = PJ_FALSE;
374
pj_status_t status = (info? info->status: PJ_SUCCESS);
378
/* Increment the dialog's lock otherwise when invite session creation
379
* fails the dialog will be destroyed prematurely.
381
pjsip_dlg_inc_lock(dlg);
383
/* Decrement dialog session. */
384
pjsip_dlg_dec_session(dlg, &pjsua_var.mod);
386
if (status != PJ_SUCCESS) {
388
pj_ssize_t title_len;
390
call->last_code = PJSIP_SC_TEMPORARILY_UNAVAILABLE;
391
pj_strcpy2(&call->last_text, "Media init error: ");
393
title_len = call->last_text.slen;
394
err_str = pj_strerror(status, call->last_text_buf_ + title_len,
395
sizeof(call->last_text_buf_) - title_len);
396
call->last_text.slen += err_str.slen;
398
pjsua_perror(THIS_FILE, "Error initializing media channel", status);
402
/* pjsua_media_channel_deinit() has been called or
403
* call has been hung up.
405
if (call->async_call.med_ch_deinit ||
406
call->async_call.call_var.out_call.hangup)
408
PJ_LOG(4,(THIS_FILE, "Call has been hung up or media channel has "
409
"been deinitialized"));
414
status = pjsua_media_channel_create_sdp(call->index, dlg->pool, NULL,
416
if (status != PJ_SUCCESS) {
417
pjsua_perror(THIS_FILE, "Error initializing media channel", status);
421
/* Create the INVITE session: */
422
options |= PJSIP_INV_SUPPORT_100REL;
423
if (acc->cfg.require_100rel == PJSUA_100REL_MANDATORY)
424
options |= PJSIP_INV_REQUIRE_100REL;
425
if (acc->cfg.use_timer != PJSUA_SIP_TIMER_INACTIVE) {
426
options |= PJSIP_INV_SUPPORT_TIMER;
427
if (acc->cfg.use_timer == PJSUA_SIP_TIMER_REQUIRED)
428
options |= PJSIP_INV_REQUIRE_TIMER;
429
else if (acc->cfg.use_timer == PJSUA_SIP_TIMER_ALWAYS)
430
options |= PJSIP_INV_ALWAYS_USE_TIMER;
433
status = pjsip_inv_create_uac( dlg, offer, options, &inv);
434
if (status != PJ_SUCCESS) {
435
pjsua_perror(THIS_FILE, "Invite session creation failed", status);
439
/* Init Session Timers */
440
status = pjsip_timer_init_session(inv, &acc->cfg.timer_setting);
441
if (status != PJ_SUCCESS) {
442
pjsua_perror(THIS_FILE, "Session Timer init failed", status);
446
/* Create and associate our data in the session. */
449
dlg->mod_data[pjsua_var.mod.id] = call;
450
inv->mod_data[pjsua_var.mod.id] = call;
452
/* If account is locked to specific transport, then lock dialog
453
* to this transport too.
455
if (acc->cfg.transport_id != PJSUA_INVALID_ID) {
456
pjsip_tpselector tp_sel;
458
pjsua_init_tpselector(acc->cfg.transport_id, &tp_sel);
459
pjsip_dlg_set_transport(dlg, &tp_sel);
462
/* Set dialog Route-Set: */
463
if (!pj_list_empty(&acc->route_set))
464
pjsip_dlg_set_route_set(dlg, &acc->route_set);
467
/* Set credentials: */
469
pjsip_auth_clt_set_credentials( &dlg->auth_sess,
470
acc->cred_cnt, acc->cred);
473
/* Set authentication preference */
474
pjsip_auth_clt_set_prefs(&dlg->auth_sess, &acc->cfg.auth_pref);
476
/* Create initial INVITE: */
478
status = pjsip_inv_invite(inv, &tdata);
479
if (status != PJ_SUCCESS) {
480
pjsua_perror(THIS_FILE, "Unable to create initial INVITE request",
486
/* Add additional headers etc */
488
pjsua_process_msg_data( tdata,
489
call->async_call.call_var.out_call.msg_data);
491
/* Must increment call counter now */
492
++pjsua_var.call_cnt;
494
/* Send initial INVITE: */
496
status = pjsip_inv_send_msg(inv, tdata);
497
if (status != PJ_SUCCESS) {
500
/* Upon failure to send first request, the invite
501
* session would have been cleared.
508
call->med_ch_cb = NULL;
510
pjsip_dlg_dec_lock(dlg);
516
if (inv == NULL && call_id != -1 && !cb_called &&
517
pjsua_var.ua_cfg.cb.on_call_state)
519
(*pjsua_var.ua_cfg.cb.on_call_state)(call_id, NULL);
523
/* This may destroy the dialog */
524
pjsip_dlg_dec_lock(dlg);
528
pjsip_inv_terminate(inv, PJSIP_SC_OK, PJ_FALSE);
532
pjsua_media_channel_deinit(call_id);
536
call->med_ch_cb = NULL;
538
pjsua_check_snd_dev_idle();
546
* Initialize call settings based on account ID.
548
PJ_DEF(void) pjsua_call_setting_default(pjsua_call_setting *opt)
552
pj_bzero(opt, sizeof(*opt));
553
opt->flag = PJSUA_CALL_INCLUDE_DISABLED_MEDIA;
556
#if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0)
558
opt->req_keyframe_method = PJSUA_VID_REQ_KEYFRAME_SIP_INFO |
559
PJSUA_VID_REQ_KEYFRAME_RTCP_PLI;
563
static pj_status_t apply_call_setting(pjsua_call *call,
564
const pjsua_call_setting *opt,
565
const pjmedia_sdp_session *rem_sdp)
572
#if !PJMEDIA_HAS_VIDEO
573
pj_assert(opt->vid_cnt == 0);
578
/* If call is established, reinit media channel */
579
if (call->inv && call->inv->state == PJSIP_INV_STATE_CONFIRMED) {
580
pjsip_role_e role = rem_sdp? PJSIP_ROLE_UAS : PJSIP_ROLE_UAC;
583
status = pjsua_media_channel_init(call->index, role,
585
call->inv->pool_prov,
588
if (status != PJ_SUCCESS) {
589
pjsua_perror(THIS_FILE, "Error re-initializing media channel",
599
* Make outgoing call to the specified URI using the specified account.
601
PJ_DEF(pj_status_t) pjsua_call_make_call(pjsua_acc_id acc_id,
602
const pj_str_t *dest_uri,
603
const pjsua_call_setting *opt,
605
const pjsua_msg_data *msg_data,
606
pjsua_call_id *p_call_id)
608
pj_pool_t *tmp_pool = NULL;
609
pjsip_dialog *dlg = NULL;
617
/* Check that account is valid */
618
PJ_ASSERT_RETURN(acc_id>=0 || acc_id<(int)PJ_ARRAY_SIZE(pjsua_var.acc),
621
/* Check arguments */
622
PJ_ASSERT_RETURN(dest_uri, PJ_EINVAL);
624
PJ_LOG(4,(THIS_FILE, "Making call with acc #%d to %.*s", acc_id,
625
(int)dest_uri->slen, dest_uri->ptr));
627
pj_log_push_indent();
631
/* Create sound port if none is instantiated, to check if sound device
632
* can be used. But only do this with the conference bridge, as with
633
* audio switchboard (i.e. APS-Direct), we can only open the sound
634
* device once the correct format has been known
636
if (!pjsua_var.is_mswitch && pjsua_var.snd_port==NULL &&
637
pjsua_var.null_snd==NULL && !pjsua_var.no_snd)
639
status = pjsua_set_snd_dev(pjsua_var.cap_dev, pjsua_var.play_dev);
640
if (status != PJ_SUCCESS)
644
acc = &pjsua_var.acc[acc_id];
646
pjsua_perror(THIS_FILE, "Unable to make call because account "
647
"is not valid", PJ_EINVALIDOP);
648
status = PJ_EINVALIDOP;
652
/* Find free call slot. */
653
call_id = alloc_call_id();
655
if (call_id == PJSUA_INVALID_ID) {
656
pjsua_perror(THIS_FILE, "Error making call", PJ_ETOOMANY);
657
status = PJ_ETOOMANY;
661
/* Clear call descriptor */
664
call = &pjsua_var.calls[call_id];
666
/* Associate session with account */
667
call->acc_id = acc_id;
668
call->call_hold_type = acc->cfg.call_hold_type;
670
/* Apply call setting */
671
status = apply_call_setting(call, opt, NULL);
672
if (status != PJ_SUCCESS) {
673
pjsua_perror(THIS_FILE, "Failed to apply call setting", status);
677
/* Create temporary pool */
678
tmp_pool = pjsua_pool_create("tmpcall10", 512, 256);
680
/* Verify that destination URI is valid before calling
681
* pjsua_acc_create_uac_contact, or otherwise there
682
* a misleading "Invalid Contact URI" error will be printed
683
* when pjsua_acc_create_uac_contact() fails.
689
pj_strdup_with_null(tmp_pool, &dup, dest_uri);
690
uri = pjsip_parse_uri(tmp_pool, dup.ptr, dup.slen, 0);
693
pjsua_perror(THIS_FILE, "Unable to make call",
694
PJSIP_EINVALIDREQURI);
695
status = PJSIP_EINVALIDREQURI;
700
/* Mark call start time. */
701
pj_gettimeofday(&call->start_time);
703
/* Reset first response time */
704
call->res_time.sec = 0;
706
/* Create suitable Contact header unless a Contact header has been
707
* set in the account.
709
if (acc->contact.slen) {
710
contact = acc->contact;
712
status = pjsua_acc_create_uac_contact(tmp_pool, &contact,
714
if (status != PJ_SUCCESS) {
715
pjsua_perror(THIS_FILE, "Unable to generate Contact header",
721
/* Create outgoing dialog: */
722
status = pjsip_dlg_create_uac( pjsip_ua_instance(),
723
&acc->cfg.id, &contact,
725
(msg_data && msg_data->target_uri.slen?
726
&msg_data->target_uri: dest_uri),
728
if (status != PJ_SUCCESS) {
729
pjsua_perror(THIS_FILE, "Dialog creation failed", status);
733
/* Increment the dialog's lock otherwise when invite session creation
734
* fails the dialog will be destroyed prematurely.
736
pjsip_dlg_inc_lock(dlg);
738
if (acc->cfg.allow_via_rewrite && acc->via_addr.host.slen > 0)
739
pjsip_dlg_set_via_sent_by(dlg, &acc->via_addr, acc->via_tp);
741
/* Calculate call's secure level */
742
call->secure_level = get_secure_level(acc_id, dest_uri);
744
/* Attach user data */
745
call->user_data = user_data;
747
/* Store variables required for the callback after the async
748
* media transport creation is completed.
751
call->async_call.call_var.out_call.msg_data = pjsua_msg_data_clone(
752
dlg->pool, msg_data);
754
call->async_call.dlg = dlg;
756
/* Temporarily increment dialog session. Without this, dialog will be
757
* prematurely destroyed if dec_lock() is called on the dialog before
758
* the invite session is created.
760
pjsip_dlg_inc_session(dlg, &pjsua_var.mod);
762
/* Init media channel */
763
status = pjsua_media_channel_init(call->index, PJSIP_ROLE_UAC,
764
call->secure_level, dlg->pool,
766
&on_make_call_med_tp_complete);
767
if (status == PJ_SUCCESS) {
768
status = on_make_call_med_tp_complete(call->index, NULL);
769
if (status != PJ_SUCCESS)
771
} else if (status != PJ_EPENDING) {
772
pjsua_perror(THIS_FILE, "Error initializing media channel", status);
773
pjsip_dlg_dec_session(dlg, &pjsua_var.mod);
780
*p_call_id = call_id;
782
pjsip_dlg_dec_lock(dlg);
783
pj_pool_release(tmp_pool);
793
/* This may destroy the dialog */
794
pjsip_dlg_dec_lock(dlg);
798
pjsua_media_channel_deinit(call_id);
802
pjsua_check_snd_dev_idle();
805
pj_pool_release(tmp_pool);
813
/* Get the NAT type information in remote's SDP */
814
static void update_remote_nat_type(pjsua_call *call,
815
const pjmedia_sdp_session *sdp)
817
const pjmedia_sdp_attr *xnat;
819
xnat = pjmedia_sdp_attr_find2(sdp->attr_count, sdp->attr, "X-nat", NULL);
821
call->rem_nat_type = (pj_stun_nat_type) (xnat->value.ptr[0] - '0');
823
call->rem_nat_type = PJ_STUN_NAT_TYPE_UNKNOWN;
826
PJ_LOG(5,(THIS_FILE, "Call %d: remote NAT type is %d (%s)", call->index,
827
call->rem_nat_type, pj_stun_get_nat_name(call->rem_nat_type)));
831
static pj_status_t process_incoming_call_replace(pjsua_call *call,
832
pjsip_dialog *replaced_dlg)
834
pjsip_inv_session *replaced_inv;
835
struct pjsua_call *replaced_call;
836
pjsip_tx_data *tdata = NULL;
837
pj_status_t status = PJ_SUCCESS;
839
/* Get the invite session in the dialog */
840
replaced_inv = pjsip_dlg_get_inv_session(replaced_dlg);
842
/* Get the replaced call instance */
843
replaced_call = (pjsua_call*) replaced_dlg->mod_data[pjsua_var.mod.id];
845
/* Notify application */
846
if (pjsua_var.ua_cfg.cb.on_call_replaced)
847
pjsua_var.ua_cfg.cb.on_call_replaced(replaced_call->index,
850
if (replaced_call->inv->state <= PJSIP_INV_STATE_EARLY &&
851
replaced_call->inv->role != PJSIP_ROLE_UAC)
853
if (replaced_call->last_code > 100 && replaced_call->last_code < 200)
855
pjsip_status_code code = replaced_call->last_code;
856
pj_str_t *text = &replaced_call->last_text;
858
PJ_LOG(4,(THIS_FILE, "Answering replacement call %d with %d/%.*s",
859
call->index, code, text->slen, text->ptr));
861
/* Answer the new call with last response in the replaced call */
862
status = pjsip_inv_answer(call->inv, code, text, NULL, &tdata);
865
PJ_LOG(4,(THIS_FILE, "Answering replacement call %d with 200/OK",
868
/* Answer the new call with 200 response */
869
status = pjsip_inv_answer(call->inv, 200, NULL, NULL, &tdata);
872
if (status == PJ_SUCCESS && tdata)
873
status = pjsip_inv_send_msg(call->inv, tdata);
875
if (status != PJ_SUCCESS)
876
pjsua_perror(THIS_FILE, "Error answering session", status);
878
/* Note that inv may be invalid if 200/OK has caused error in
879
* starting the media.
882
PJ_LOG(4,(THIS_FILE, "Disconnecting replaced call %d",
883
replaced_call->index));
885
/* Disconnect replaced invite session */
886
status = pjsip_inv_end_session(replaced_inv, PJSIP_SC_GONE, NULL,
888
if (status == PJ_SUCCESS && tdata)
889
status = pjsip_inv_send_msg(replaced_inv, tdata);
891
if (status != PJ_SUCCESS)
892
pjsua_perror(THIS_FILE, "Error terminating session", status);
898
static void process_pending_call_answer(pjsua_call *call)
900
struct call_answer *answer, *next;
902
answer = call->async_call.call_var.inc_call.answers.next;
903
while (answer != &call->async_call.call_var.inc_call.answers) {
905
pjsua_call_answer2(call->index, answer->opt, answer->code,
906
answer->reason, answer->msg_data);
908
/* Call might have been disconnected if application is answering
909
* with 200/OK and the media failed to start.
910
* See pjsua_call_answer() below.
912
if (!call->inv || !call->inv->pool_prov)
915
pj_list_erase(answer);
921
/* Incoming call callback when media transport creation is completed. */
923
on_incoming_call_med_tp_complete(pjsua_call_id call_id,
924
const pjsua_med_tp_state_info *info)
926
pjsua_call *call = &pjsua_var.calls[call_id];
927
const pjmedia_sdp_session *offer=NULL;
928
pjmedia_sdp_session *answer;
929
pjsip_tx_data *response = NULL;
930
unsigned options = 0;
931
int sip_err_code = (info? info->sip_err_code: 0);
932
pj_status_t status = (info? info->status: PJ_SUCCESS);
936
if (status != PJ_SUCCESS) {
937
pjsua_perror(THIS_FILE, "Error initializing media channel", status);
941
/* pjsua_media_channel_deinit() has been called. */
942
if (call->async_call.med_ch_deinit) {
943
pjsua_media_channel_deinit(call->index);
944
call->med_ch_cb = NULL;
949
/* Get remote SDP offer (if any). */
951
pjmedia_sdp_neg_get_neg_remote(call->inv->neg, &offer);
953
status = pjsua_media_channel_create_sdp(call_id,
954
call->async_call.dlg->pool,
955
offer, &answer, &sip_err_code);
956
if (status != PJ_SUCCESS) {
957
pjsua_perror(THIS_FILE, "Error creating SDP answer", status);
961
status = pjsip_inv_set_local_sdp(call->inv, answer);
962
if (status != PJ_SUCCESS) {
963
pjsua_perror(THIS_FILE, "Error setting local SDP", status);
964
sip_err_code = PJSIP_SC_NOT_ACCEPTABLE_HERE;
968
/* Verify that we can handle the request. */
969
status = pjsip_inv_verify_request3(NULL,
970
call->inv->pool_prov, &options, offer,
971
answer, NULL, pjsua_var.endpt, &response);
972
if (status != PJ_SUCCESS) {
974
* No we can't handle the incoming INVITE request.
976
sip_err_code = PJSIP_ERRNO_TO_SIP_STATUS(status);
981
if (status != PJ_SUCCESS) {
982
/* If the callback is called from pjsua_call_on_incoming(), the
983
* invite's state is PJSIP_INV_STATE_NULL, so the invite session
984
* will be terminated later, otherwise we end the session here.
986
if (call->inv->state > PJSIP_INV_STATE_NULL) {
987
pjsip_tx_data *tdata;
990
status_ = pjsip_inv_end_session(call->inv, sip_err_code, NULL,
992
if (status_ == PJ_SUCCESS && tdata)
993
status_ = pjsip_inv_send_msg(call->inv, tdata);
996
pjsua_media_channel_deinit(call->index);
999
/* Set the callback to NULL to indicate that the async operation
1002
call->med_ch_cb = NULL;
1004
/* Finish any pending process */
1005
if (status == PJ_SUCCESS) {
1006
if (call->async_call.call_var.inc_call.replaced_dlg) {
1007
/* Process pending call replace */
1008
pjsip_dialog *replaced_dlg =
1009
call->async_call.call_var.inc_call.replaced_dlg;
1010
process_incoming_call_replace(call, replaced_dlg);
1012
/* Process pending call answers */
1013
process_pending_call_answer(call);
1023
* Handle incoming INVITE request.
1024
* Called by pjsua_core.c
1026
pj_bool_t pjsua_call_on_incoming(pjsip_rx_data *rdata)
1029
pjsip_dialog *dlg = pjsip_rdata_get_dlg(rdata);
1030
pjsip_dialog *replaced_dlg = NULL;
1031
pjsip_transaction *tsx = pjsip_rdata_get_tsx(rdata);
1032
pjsip_msg *msg = rdata->msg_info.msg;
1033
pjsip_tx_data *response = NULL;
1034
unsigned options = 0;
1035
pjsip_inv_session *inv = NULL;
1039
int sip_err_code = PJSIP_SC_INTERNAL_SERVER_ERROR;
1040
pjmedia_sdp_session *offer=NULL;
1043
/* Don't want to handle anything but INVITE */
1044
if (msg->line.req.method.id != PJSIP_INVITE_METHOD)
1047
/* Don't want to handle anything that's already associated with
1048
* existing dialog or transaction.
1053
/* Don't want to accept the call if shutdown is in progress */
1054
if (pjsua_var.thread_quit_flag) {
1055
pjsip_endpt_respond_stateless(pjsua_var.endpt, rdata,
1056
PJSIP_SC_TEMPORARILY_UNAVAILABLE, NULL,
1061
PJ_LOG(4,(THIS_FILE, "Incoming %s", rdata->msg_info.info));
1062
pj_log_push_indent();
1066
/* Find free call slot. */
1067
call_id = alloc_call_id();
1069
if (call_id == PJSUA_INVALID_ID) {
1070
pjsip_endpt_respond_stateless(pjsua_var.endpt, rdata,
1071
PJSIP_SC_BUSY_HERE, NULL,
1073
PJ_LOG(2,(THIS_FILE,
1074
"Unable to accept incoming call (too many calls)"));
1078
/* Clear call descriptor */
1079
reset_call(call_id);
1081
call = &pjsua_var.calls[call_id];
1083
/* Mark call start time. */
1084
pj_gettimeofday(&call->start_time);
1086
/* Check INVITE request for Replaces header. If Replaces header is
1087
* present, the function will make sure that we can handle the request.
1089
status = pjsip_replaces_verify_request(rdata, &replaced_dlg, PJ_FALSE,
1091
if (status != PJ_SUCCESS) {
1093
* Something wrong with the Replaces header.
1096
pjsip_response_addr res_addr;
1098
pjsip_get_response_addr(response->pool, rdata, &res_addr);
1099
pjsip_endpt_send_response(pjsua_var.endpt, &res_addr, response,
1104
/* Respond with 500 (Internal Server Error) */
1105
pjsip_endpt_respond_stateless(pjsua_var.endpt, rdata, 500, NULL,
1112
/* If this INVITE request contains Replaces header, notify application
1113
* about the request so that application can do subsequent checking
1116
if (replaced_dlg != NULL &&
1117
(pjsua_var.ua_cfg.cb.on_call_replace_request ||
1118
pjsua_var.ua_cfg.cb.on_call_replace_request2))
1120
pjsua_call *replaced_call;
1122
pj_str_t st_text = { "OK", 2 };
1124
/* Get the replaced call instance */
1125
replaced_call = (pjsua_call*) replaced_dlg->mod_data[pjsua_var.mod.id];
1127
/* Copy call setting from the replaced call */
1128
call->opt = replaced_call->opt;
1130
/* Notify application */
1131
if (pjsua_var.ua_cfg.cb.on_call_replace_request) {
1132
pjsua_var.ua_cfg.cb.on_call_replace_request(replaced_call->index,
1134
&st_code, &st_text);
1137
if (pjsua_var.ua_cfg.cb.on_call_replace_request2) {
1138
pjsua_var.ua_cfg.cb.on_call_replace_request2(replaced_call->index,
1144
/* Must specify final response */
1145
PJ_ASSERT_ON_FAIL(st_code >= 200, st_code = 200);
1147
/* Check if application rejects this request. */
1148
if (st_code >= 300) {
1150
if (st_text.slen == 2)
1151
st_text = *pjsip_get_status_text(st_code);
1153
pjsip_endpt_respond(pjsua_var.endpt, NULL, rdata,
1154
st_code, &st_text, NULL, NULL, NULL);
1160
* Get which account is most likely to be associated with this incoming
1161
* call. We need the account to find which contact URI to put for
1164
acc_id = call->acc_id = pjsua_acc_find_for_incoming(rdata);
1165
call->call_hold_type = pjsua_var.acc[acc_id].cfg.call_hold_type;
1167
/* Get call's secure level */
1168
if (PJSIP_URI_SCHEME_IS_SIPS(rdata->msg_info.msg->line.req.uri))
1169
call->secure_level = 2;
1170
else if (PJSIP_TRANSPORT_IS_SECURE(rdata->tp_info.transport))
1171
call->secure_level = 1;
1173
call->secure_level = 0;
1175
/* Parse SDP from incoming request */
1176
if (rdata->msg_info.msg->body) {
1177
pjsip_rdata_sdp_info *sdp_info;
1179
sdp_info = pjsip_rdata_get_sdp_info(rdata);
1180
offer = sdp_info->sdp;
1182
status = sdp_info->sdp_err;
1183
if (status==PJ_SUCCESS && sdp_info->sdp==NULL)
1184
status = PJSIP_ERRNO_FROM_SIP_STATUS(PJSIP_SC_NOT_ACCEPTABLE);
1186
if (status != PJ_SUCCESS) {
1187
const pj_str_t reason = pj_str("Bad SDP");
1189
pjsip_warning_hdr *w;
1191
pjsua_perror(THIS_FILE, "Bad SDP in incoming INVITE",
1194
w = pjsip_warning_hdr_create_from_status(rdata->tp_info.pool,
1195
pjsip_endpt_name(pjsua_var.endpt),
1197
pj_list_init(&hdr_list);
1198
pj_list_push_back(&hdr_list, w);
1200
pjsip_endpt_respond(pjsua_var.endpt, NULL, rdata, 400,
1201
&reason, &hdr_list, NULL, NULL);
1205
/* Do quick checks on SDP before passing it to transports. More elabore
1206
* checks will be done in pjsip_inv_verify_request2() below.
1208
if (offer->media_count==0) {
1209
const pj_str_t reason = pj_str("Missing media in SDP");
1210
pjsip_endpt_respond(pjsua_var.endpt, NULL, rdata, 400, &reason,
1219
/* Verify that we can handle the request. */
1220
options |= PJSIP_INV_SUPPORT_100REL;
1221
options |= PJSIP_INV_SUPPORT_TIMER;
1222
if (pjsua_var.acc[acc_id].cfg.require_100rel == PJSUA_100REL_MANDATORY)
1223
options |= PJSIP_INV_REQUIRE_100REL;
1224
if (pjsua_var.acc[acc_id].cfg.ice_cfg.enable_ice)
1225
options |= PJSIP_INV_SUPPORT_ICE;
1226
if (pjsua_var.acc[acc_id].cfg.use_timer == PJSUA_SIP_TIMER_REQUIRED)
1227
options |= PJSIP_INV_REQUIRE_TIMER;
1228
else if (pjsua_var.acc[acc_id].cfg.use_timer == PJSUA_SIP_TIMER_ALWAYS)
1229
options |= PJSIP_INV_ALWAYS_USE_TIMER;
1231
status = pjsip_inv_verify_request2(rdata, &options, offer, NULL, NULL,
1232
pjsua_var.endpt, &response);
1233
if (status != PJ_SUCCESS) {
1236
* No we can't handle the incoming INVITE request.
1239
pjsip_response_addr res_addr;
1241
pjsip_get_response_addr(response->pool, rdata, &res_addr);
1242
pjsip_endpt_send_response(pjsua_var.endpt, &res_addr, response,
1246
/* Respond with 500 (Internal Server Error) */
1247
pjsip_endpt_respond(pjsua_var.endpt, NULL, rdata, 500, NULL,
1254
/* Get suitable Contact header */
1255
if (pjsua_var.acc[acc_id].contact.slen) {
1256
contact = pjsua_var.acc[acc_id].contact;
1258
status = pjsua_acc_create_uas_contact(rdata->tp_info.pool, &contact,
1260
if (status != PJ_SUCCESS) {
1261
pjsua_perror(THIS_FILE, "Unable to generate Contact header",
1263
pjsip_endpt_respond_stateless(pjsua_var.endpt, rdata, 500, NULL,
1269
/* Create dialog: */
1270
status = pjsip_dlg_create_uas( pjsip_ua_instance(), rdata,
1272
if (status != PJ_SUCCESS) {
1273
pjsip_endpt_respond_stateless(pjsua_var.endpt, rdata, 500, NULL,
1278
if (pjsua_var.acc[acc_id].cfg.allow_via_rewrite &&
1279
pjsua_var.acc[acc_id].via_addr.host.slen > 0)
1281
pjsip_dlg_set_via_sent_by(dlg, &pjsua_var.acc[acc_id].via_addr,
1282
pjsua_var.acc[acc_id].via_tp);
1285
/* Set credentials */
1286
if (pjsua_var.acc[acc_id].cred_cnt) {
1287
pjsip_auth_clt_set_credentials(&dlg->auth_sess,
1288
pjsua_var.acc[acc_id].cred_cnt,
1289
pjsua_var.acc[acc_id].cred);
1292
/* Set preference */
1293
pjsip_auth_clt_set_prefs(&dlg->auth_sess,
1294
&pjsua_var.acc[acc_id].cfg.auth_pref);
1296
/* Disable Session Timers if not prefered and the incoming INVITE request
1297
* did not require it.
1299
if (pjsua_var.acc[acc_id].cfg.use_timer == PJSUA_SIP_TIMER_INACTIVE &&
1300
(options & PJSIP_INV_REQUIRE_TIMER) == 0)
1302
options &= ~(PJSIP_INV_SUPPORT_TIMER);
1305
/* If 100rel is optional and UAC supports it, use it. */
1306
if ((options & PJSIP_INV_REQUIRE_100REL)==0 &&
1307
pjsua_var.acc[acc_id].cfg.require_100rel == PJSUA_100REL_OPTIONAL)
1309
const pj_str_t token = { "100rel", 6};
1310
pjsip_dialog_cap_status cap_status;
1312
cap_status = pjsip_dlg_remote_has_cap(dlg, PJSIP_H_SUPPORTED, NULL,
1314
if (cap_status == PJSIP_DIALOG_CAP_SUPPORTED)
1315
options |= PJSIP_INV_REQUIRE_100REL;
1318
/* Create invite session: */
1319
status = pjsip_inv_create_uas( dlg, rdata, NULL, options, &inv);
1320
if (status != PJ_SUCCESS) {
1322
pjsip_warning_hdr *w;
1324
w = pjsip_warning_hdr_create_from_status(dlg->pool,
1325
pjsip_endpt_name(pjsua_var.endpt),
1327
pj_list_init(&hdr_list);
1328
pj_list_push_back(&hdr_list, w);
1330
pjsip_dlg_respond(dlg, rdata, 500, NULL, &hdr_list, NULL);
1332
/* Can't terminate dialog because transaction is in progress.
1333
pjsip_dlg_terminate(dlg);
1338
/* If account is locked to specific transport, then lock dialog
1339
* to this transport too.
1341
if (pjsua_var.acc[acc_id].cfg.transport_id != PJSUA_INVALID_ID) {
1342
pjsip_tpselector tp_sel;
1344
pjsua_init_tpselector(pjsua_var.acc[acc_id].cfg.transport_id, &tp_sel);
1345
pjsip_dlg_set_transport(dlg, &tp_sel);
1348
/* Create and attach pjsua_var data to the dialog */
1351
/* Store variables required for the callback after the async
1352
* media transport creation is completed.
1354
call->async_call.dlg = dlg;
1355
pj_list_init(&call->async_call.call_var.inc_call.answers);
1357
/* Init media channel, only when there is offer or call replace request.
1358
* For incoming call without SDP offer, media channel init will be done
1359
* in pjsua_call_answer(), see ticket #1526.
1361
if (offer || replaced_dlg) {
1362
status = pjsua_media_channel_init(call->index, PJSIP_ROLE_UAS,
1364
rdata->tp_info.pool,
1366
&sip_err_code, PJ_TRUE,
1367
&on_incoming_call_med_tp_complete);
1368
if (status == PJ_SUCCESS) {
1369
status = on_incoming_call_med_tp_complete(call_id, NULL);
1370
if (status != PJ_SUCCESS) {
1371
sip_err_code = PJSIP_SC_NOT_ACCEPTABLE;
1372
/* Since the call invite's state is still PJSIP_INV_STATE_NULL,
1373
* the invite session was not ended in
1374
* on_incoming_call_med_tp_complete(), so we need to send
1375
* a response message and terminate the invite here.
1377
pjsip_dlg_respond(dlg, rdata, sip_err_code, NULL, NULL, NULL);
1378
pjsip_inv_terminate(call->inv, sip_err_code, PJ_FALSE);
1380
call->async_call.dlg = NULL;
1383
} else if (status != PJ_EPENDING) {
1384
pjsua_perror(THIS_FILE, "Error initializing media channel", status);
1385
pjsip_dlg_respond(dlg, rdata, sip_err_code, NULL, NULL, NULL);
1386
pjsip_inv_terminate(call->inv, sip_err_code, PJ_FALSE);
1388
call->async_call.dlg = NULL;
1395
status = pjsua_media_channel_create_sdp(call->index, rdata->tp_info.pool,
1396
offer, &answer, &sip_err_code);
1397
if (status != PJ_SUCCESS) {
1398
pjsua_perror(THIS_FILE, "Error creating SDP answer", status);
1399
pjsip_endpt_respond(pjsua_var.endpt, NULL, rdata,
1400
sip_err_code, NULL, NULL, NULL, NULL);
1405
/* Init Session Timers */
1406
status = pjsip_timer_init_session(inv,
1407
&pjsua_var.acc[acc_id].cfg.timer_setting);
1408
if (status != PJ_SUCCESS) {
1409
pjsua_perror(THIS_FILE, "Session Timer init failed", status);
1410
pjsip_dlg_respond(dlg, rdata, PJSIP_SC_INTERNAL_SERVER_ERROR, NULL, NULL, NULL);
1411
pjsip_inv_terminate(inv, PJSIP_SC_INTERNAL_SERVER_ERROR, PJ_FALSE);
1413
pjsua_media_channel_deinit(call->index);
1415
call->async_call.dlg = NULL;
1420
/* Update NAT type of remote endpoint, only when there is SDP in
1423
if (pjsua_var.ua_cfg.nat_type_in_sdp && inv->neg &&
1424
pjmedia_sdp_neg_get_state(inv->neg) > PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER)
1426
const pjmedia_sdp_session *remote_sdp;
1428
if (pjmedia_sdp_neg_get_neg_remote(inv->neg, &remote_sdp)==PJ_SUCCESS)
1429
update_remote_nat_type(call, remote_sdp);
1432
/* Must answer with some response to initial INVITE. We'll do this before
1433
* attaching the call to the invite session/dialog, so that the application
1434
* will not get notification about this event (on another scenario, it is
1435
* also possible that inv_send_msg() fails and causes the invite session to
1436
* be disconnected. If we have the call attached at this time, this will
1437
* cause the disconnection callback to be called before on_incoming_call()
1438
* callback is called, which is not right).
1440
status = pjsip_inv_initial_answer(inv, rdata,
1441
100, NULL, NULL, &response);
1442
if (status != PJ_SUCCESS) {
1443
if (response == NULL) {
1444
pjsua_perror(THIS_FILE, "Unable to send answer to incoming INVITE",
1446
pjsip_dlg_respond(dlg, rdata, 500, NULL, NULL, NULL);
1447
pjsip_inv_terminate(inv, 500, PJ_FALSE);
1449
pjsip_inv_send_msg(inv, response);
1450
pjsip_inv_terminate(inv, response->msg->line.status.code,
1453
pjsua_media_channel_deinit(call->index);
1455
call->async_call.dlg = NULL;
1459
status = pjsip_inv_send_msg(inv, response);
1460
if (status != PJ_SUCCESS) {
1461
pjsua_perror(THIS_FILE, "Unable to send 100 response", status);
1462
pjsua_media_channel_deinit(call->index);
1464
call->async_call.dlg = NULL;
1469
/* Only do this after sending 100/Trying (really! see the long comment
1472
dlg->mod_data[pjsua_var.mod.id] = call;
1473
inv->mod_data[pjsua_var.mod.id] = call;
1475
++pjsua_var.call_cnt;
1477
/* Check if this request should replace existing call */
1479
/* Process call replace. If the media channel init has been completed,
1480
* just process now, otherwise, just queue the replaced dialog so
1481
* it will be processed once the media channel async init is finished
1484
if (call->med_ch_cb == NULL) {
1485
process_incoming_call_replace(call, replaced_dlg);
1487
call->async_call.call_var.inc_call.replaced_dlg = replaced_dlg;
1490
/* Notify application if on_incoming_call() is overriden,
1491
* otherwise hangup the call with 480
1493
if (pjsua_var.ua_cfg.cb.on_incoming_call) {
1494
pjsua_var.ua_cfg.cb.on_incoming_call(acc_id, call_id, rdata);
1496
pjsua_call_hangup(call_id, PJSIP_SC_TEMPORARILY_UNAVAILABLE,
1502
/* This INVITE request has been handled. */
1504
pj_log_pop_indent();
1512
* Check if the specified call has active INVITE session and the INVITE
1513
* session has not been disconnected.
1515
PJ_DEF(pj_bool_t) pjsua_call_is_active(pjsua_call_id call_id)
1517
PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
1519
return pjsua_var.calls[call_id].inv != NULL &&
1520
pjsua_var.calls[call_id].inv->state != PJSIP_INV_STATE_DISCONNECTED;
1524
/* Acquire lock to the specified call_id */
1525
pj_status_t acquire_call(const char *title,
1526
pjsua_call_id call_id,
1527
pjsua_call **p_call,
1528
pjsip_dialog **p_dlg)
1531
pjsua_call *call = NULL;
1532
pj_bool_t has_pjsua_lock = PJ_FALSE;
1533
pj_status_t status = PJ_SUCCESS;
1534
pj_time_val time_start, timeout;
1535
pjsip_dialog *dlg = NULL;
1537
pj_gettimeofday(&time_start);
1539
timeout.msec = PJSUA_ACQUIRE_CALL_TIMEOUT;
1540
pj_time_val_normalize(&timeout);
1542
for (retry=0; ; ++retry) {
1544
if (retry % 10 == 9) {
1547
pj_gettimeofday(&dtime);
1548
PJ_TIME_VAL_SUB(dtime, time_start);
1549
if (!PJ_TIME_VAL_LT(dtime, timeout))
1553
has_pjsua_lock = PJ_FALSE;
1555
status = PJSUA_TRY_LOCK();
1556
if (status != PJ_SUCCESS) {
1557
pj_thread_sleep(retry/10);
1561
has_pjsua_lock = PJ_TRUE;
1562
call = &pjsua_var.calls[call_id];
1564
dlg = call->inv->dlg;
1566
dlg = call->async_call.dlg;
1570
PJ_LOG(3,(THIS_FILE, "Invalid call_id %d in %s", call_id, title));
1571
return PJSIP_ESESSIONTERMINATED;
1574
status = pjsip_dlg_try_inc_lock(dlg);
1575
if (status != PJ_SUCCESS) {
1577
pj_thread_sleep(retry/10);
1586
if (status != PJ_SUCCESS) {
1587
if (has_pjsua_lock == PJ_FALSE)
1588
PJ_LOG(1,(THIS_FILE, "Timed-out trying to acquire PJSUA mutex "
1589
"(possibly system has deadlocked) in %s",
1592
PJ_LOG(1,(THIS_FILE, "Timed-out trying to acquire dialog mutex "
1593
"(possibly system has deadlocked) in %s",
1595
return PJ_ETIMEDOUT;
1606
* Obtain detail information about the specified call.
1608
PJ_DEF(pj_status_t) pjsua_call_get_info( pjsua_call_id call_id,
1609
pjsua_call_info *info)
1615
PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
1618
pj_bzero(info, sizeof(*info));
1620
/* Use PJSUA_LOCK() instead of acquire_call():
1621
* https://trac.pjsip.org/repos/ticket/1371
1625
call = &pjsua_var.calls[call_id];
1626
dlg = (call->inv ? call->inv->dlg : call->async_call.dlg);
1629
return PJSIP_ESESSIONTERMINATED;
1634
info->role = dlg->role;
1635
info->acc_id = call->acc_id;
1638
info->local_info.ptr = info->buf_.local_info;
1639
pj_strncpy(&info->local_info, &dlg->local.info_str,
1640
sizeof(info->buf_.local_info));
1643
info->local_contact.ptr = info->buf_.local_contact;
1644
info->local_contact.slen = pjsip_uri_print(PJSIP_URI_IN_CONTACT_HDR,
1645
dlg->local.contact->uri,
1646
info->local_contact.ptr,
1647
sizeof(info->buf_.local_contact));
1650
info->remote_info.ptr = info->buf_.remote_info;
1651
pj_strncpy(&info->remote_info, &dlg->remote.info_str,
1652
sizeof(info->buf_.remote_info));
1654
/* remote contact */
1655
if (dlg->remote.contact) {
1657
info->remote_contact.ptr = info->buf_.remote_contact;
1658
len = pjsip_uri_print(PJSIP_URI_IN_CONTACT_HDR,
1659
dlg->remote.contact->uri,
1660
info->remote_contact.ptr,
1661
sizeof(info->buf_.remote_contact));
1662
if (len < 0) len = 0;
1663
info->remote_contact.slen = len;
1665
info->remote_contact.slen = 0;
1669
info->call_id.ptr = info->buf_.call_id;
1670
pj_strncpy(&info->call_id, &dlg->call_id->id,
1671
sizeof(info->buf_.call_id));
1674
pj_memcpy(&info->setting, &call->opt, sizeof(call->opt));
1676
/* state, state_text */
1678
info->state = call->inv->state;
1679
} else if (call->async_call.dlg && call->last_code==0) {
1680
info->state = PJSIP_INV_STATE_NULL;
1682
info->state = PJSIP_INV_STATE_DISCONNECTED;
1684
info->state_text = pj_str((char*)pjsip_inv_state_name(info->state));
1686
/* If call is disconnected, set the last_status from the cause code */
1687
if (call->inv && call->inv->state >= PJSIP_INV_STATE_DISCONNECTED) {
1688
/* last_status, last_status_text */
1689
info->last_status = call->inv->cause;
1691
info->last_status_text.ptr = info->buf_.last_status_text;
1692
pj_strncpy(&info->last_status_text, &call->inv->cause_text,
1693
sizeof(info->buf_.last_status_text));
1695
/* last_status, last_status_text */
1696
info->last_status = call->last_code;
1698
info->last_status_text.ptr = info->buf_.last_status_text;
1699
pj_strncpy(&info->last_status_text, &call->last_text,
1700
sizeof(info->buf_.last_status_text));
1703
/* Audio & video count offered by remote */
1704
info->rem_offerer = call->rem_offerer;
1705
if (call->rem_offerer) {
1706
info->rem_aud_cnt = call->rem_aud_cnt;
1707
info->rem_vid_cnt = call->rem_vid_cnt;
1710
/* Build array of active media info */
1711
info->media_cnt = 0;
1712
for (mi=0; mi < call->med_cnt &&
1713
info->media_cnt < PJ_ARRAY_SIZE(info->media); ++mi)
1715
pjsua_call_media *call_med = &call->media[mi];
1717
info->media[info->media_cnt].index = mi;
1718
info->media[info->media_cnt].status = call_med->state;
1719
info->media[info->media_cnt].dir = call_med->dir;
1720
info->media[info->media_cnt].type = call_med->type;
1722
if (call_med->type == PJMEDIA_TYPE_AUDIO) {
1723
info->media[info->media_cnt].stream.aud.conf_slot =
1724
call_med->strm.a.conf_slot;
1725
} else if (call_med->type == PJMEDIA_TYPE_VIDEO) {
1726
pjmedia_vid_dev_index cap_dev = PJMEDIA_VID_INVALID_DEV;
1728
info->media[info->media_cnt].stream.vid.win_in =
1729
call_med->strm.v.rdr_win_id;
1731
if (call_med->strm.v.cap_win_id != PJSUA_INVALID_ID) {
1732
cap_dev = call_med->strm.v.cap_dev;
1734
info->media[info->media_cnt].stream.vid.cap_dev = cap_dev;
1741
if (call->audio_idx != -1) {
1742
info->media_status = call->media[call->audio_idx].state;
1743
info->media_dir = call->media[call->audio_idx].dir;
1744
info->conf_slot = call->media[call->audio_idx].strm.a.conf_slot;
1747
/* Build array of provisional media info */
1748
info->prov_media_cnt = 0;
1749
for (mi=0; mi < call->med_prov_cnt &&
1750
info->prov_media_cnt < PJ_ARRAY_SIZE(info->prov_media); ++mi)
1752
pjsua_call_media *call_med = &call->media_prov[mi];
1754
info->prov_media[info->prov_media_cnt].index = mi;
1755
info->prov_media[info->prov_media_cnt].status = call_med->state;
1756
info->prov_media[info->prov_media_cnt].dir = call_med->dir;
1757
info->prov_media[info->prov_media_cnt].type = call_med->type;
1758
if (call_med->type == PJMEDIA_TYPE_AUDIO) {
1759
info->prov_media[info->prov_media_cnt].stream.aud.conf_slot =
1760
call_med->strm.a.conf_slot;
1761
} else if (call_med->type == PJMEDIA_TYPE_VIDEO) {
1762
pjmedia_vid_dev_index cap_dev = PJMEDIA_VID_INVALID_DEV;
1764
info->prov_media[info->prov_media_cnt].stream.vid.win_in =
1765
call_med->strm.v.rdr_win_id;
1767
if (call_med->strm.v.cap_win_id != PJSUA_INVALID_ID) {
1768
cap_dev = call_med->strm.v.cap_dev;
1770
info->prov_media[info->prov_media_cnt].stream.vid.cap_dev=cap_dev;
1774
++info->prov_media_cnt;
1777
/* calculate duration */
1778
if (info->state >= PJSIP_INV_STATE_DISCONNECTED) {
1780
info->total_duration = call->dis_time;
1781
PJ_TIME_VAL_SUB(info->total_duration, call->start_time);
1783
if (call->conn_time.sec) {
1784
info->connect_duration = call->dis_time;
1785
PJ_TIME_VAL_SUB(info->connect_duration, call->conn_time);
1788
} else if (info->state == PJSIP_INV_STATE_CONFIRMED) {
1790
pj_gettimeofday(&info->total_duration);
1791
PJ_TIME_VAL_SUB(info->total_duration, call->start_time);
1793
pj_gettimeofday(&info->connect_duration);
1794
PJ_TIME_VAL_SUB(info->connect_duration, call->conn_time);
1797
pj_gettimeofday(&info->total_duration);
1798
PJ_TIME_VAL_SUB(info->total_duration, call->start_time);
1807
* Check if call remote peer support the specified capability.
1809
PJ_DEF(pjsip_dialog_cap_status) pjsua_call_remote_has_cap(
1810
pjsua_call_id call_id,
1812
const pj_str_t *hname,
1813
const pj_str_t *token)
1818
pjsip_dialog_cap_status cap_status;
1820
status = acquire_call("pjsua_call_peer_has_cap()", call_id, &call, &dlg);
1821
if (status != PJ_SUCCESS)
1822
return PJSIP_DIALOG_CAP_UNKNOWN;
1824
cap_status = pjsip_dlg_remote_has_cap(dlg, htype, hname, token);
1826
pjsip_dlg_dec_lock(dlg);
1833
* Attach application specific data to the call.
1835
PJ_DEF(pj_status_t) pjsua_call_set_user_data( pjsua_call_id call_id,
1838
PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
1840
pjsua_var.calls[call_id].user_data = user_data;
1847
* Get user data attached to the call.
1849
PJ_DEF(void*) pjsua_call_get_user_data(pjsua_call_id call_id)
1851
PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
1853
return pjsua_var.calls[call_id].user_data;
1858
* Get remote's NAT type.
1860
PJ_DEF(pj_status_t) pjsua_call_get_rem_nat_type(pjsua_call_id call_id,
1861
pj_stun_nat_type *p_type)
1863
PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
1865
PJ_ASSERT_RETURN(p_type != NULL, PJ_EINVAL);
1867
*p_type = pjsua_var.calls[call_id].rem_nat_type;
1873
* Get media transport info for the specified media index.
1876
pjsua_call_get_med_transport_info(pjsua_call_id call_id,
1878
pjmedia_transport_info *t)
1881
pjsua_call_media *call_med;
1884
PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
1886
PJ_ASSERT_RETURN(t, PJ_EINVAL);
1890
call = &pjsua_var.calls[call_id];
1892
if (med_idx >= call->med_cnt) {
1897
call_med = &call->media[med_idx];
1899
pjmedia_transport_info_init(t);
1900
status = pjmedia_transport_get_info(call_med->tp, t);
1907
/* Media channel init callback for pjsua_call_answer(). */
1909
on_answer_call_med_tp_complete(pjsua_call_id call_id,
1910
const pjsua_med_tp_state_info *info)
1912
pjsua_call *call = &pjsua_var.calls[call_id];
1913
pjmedia_sdp_session *sdp;
1914
int sip_err_code = (info? info->sip_err_code: 0);
1915
pj_status_t status = (info? info->status: PJ_SUCCESS);
1919
if (status != PJ_SUCCESS) {
1920
pjsua_perror(THIS_FILE, "Error initializing media channel", status);
1924
/* pjsua_media_channel_deinit() has been called. */
1925
if (call->async_call.med_ch_deinit) {
1926
pjsua_media_channel_deinit(call->index);
1927
call->med_ch_cb = NULL;
1932
status = pjsua_media_channel_create_sdp(call_id,
1933
call->async_call.dlg->pool,
1934
NULL, &sdp, &sip_err_code);
1935
if (status != PJ_SUCCESS) {
1936
pjsua_perror(THIS_FILE, "Error creating SDP answer", status);
1940
status = pjsip_inv_set_local_sdp(call->inv, sdp);
1941
if (status != PJ_SUCCESS) {
1942
pjsua_perror(THIS_FILE, "Error setting local SDP", status);
1943
sip_err_code = PJSIP_SC_NOT_ACCEPTABLE_HERE;
1948
if (status != PJ_SUCCESS) {
1949
/* If the callback is called from pjsua_call_on_incoming(), the
1950
* invite's state is PJSIP_INV_STATE_NULL, so the invite session
1951
* will be terminated later, otherwise we end the session here.
1953
if (call->inv->state > PJSIP_INV_STATE_NULL) {
1954
pjsip_tx_data *tdata;
1955
pj_status_t status_;
1957
status_ = pjsip_inv_end_session(call->inv, sip_err_code, NULL,
1959
if (status_ == PJ_SUCCESS && tdata)
1960
status_ = pjsip_inv_send_msg(call->inv, tdata);
1963
pjsua_media_channel_deinit(call->index);
1966
/* Set the callback to NULL to indicate that the async operation
1969
call->med_ch_cb = NULL;
1971
/* Finish any pending process */
1972
if (status == PJ_SUCCESS) {
1973
/* Process pending call answers */
1974
process_pending_call_answer(call);
1983
* Send response to incoming INVITE request.
1985
PJ_DEF(pj_status_t) pjsua_call_answer( pjsua_call_id call_id,
1987
const pj_str_t *reason,
1988
const pjsua_msg_data *msg_data)
1990
return pjsua_call_answer2(call_id, NULL, code, reason, msg_data);
1995
* Send response to incoming INVITE request.
1997
PJ_DEF(pj_status_t) pjsua_call_answer2(pjsua_call_id call_id,
1998
const pjsua_call_setting *opt,
2000
const pj_str_t *reason,
2001
const pjsua_msg_data *msg_data)
2004
pjsip_dialog *dlg = NULL;
2005
pjsip_tx_data *tdata;
2008
PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
2011
PJ_LOG(4,(THIS_FILE, "Answering call %d: code=%d", call_id, code));
2012
pj_log_push_indent();
2014
status = acquire_call("pjsua_call_answer()", call_id, &call, &dlg);
2015
if (status != PJ_SUCCESS)
2018
/* Apply call setting, only if status code is 1xx or 2xx. */
2019
if (opt && code < 300) {
2020
/* Check if it has not been set previously or it is different to
2023
if (!call->opt_inited) {
2024
call->opt_inited = PJ_TRUE;
2025
apply_call_setting(call, opt, NULL);
2026
} else if (pj_memcmp(opt, &call->opt, sizeof(*opt)) != 0) {
2027
/* Warn application about call setting inconsistency */
2028
PJ_LOG(2,(THIS_FILE, "The call setting changes is ignored."));
2034
/* Ticket #1526: When the incoming call contains no SDP offer, the media
2035
* channel may have not been initialized at this stage. The media channel
2036
* will be initialized here (along with SDP local offer generation) when
2037
* the following conditions are met:
2038
* - no pending media channel init
2039
* - local SDP has not been generated
2040
* - call setting has just been set, or SDP offer needs to be sent, i.e:
2041
* answer code 183 or 2xx is issued
2043
if (!call->med_ch_cb &&
2044
(call->opt_inited || (code==183 || code/100==2)) &&
2046
pjmedia_sdp_neg_get_state(call->inv->neg) ==
2047
PJMEDIA_SDP_NEG_STATE_NULL))
2049
/* Mark call setting as initialized as it is just about to be used
2050
* for initializing the media channel.
2052
call->opt_inited = PJ_TRUE;
2054
status = pjsua_media_channel_init(call->index, PJSIP_ROLE_UAC,
2057
NULL, NULL, PJ_TRUE,
2058
&on_answer_call_med_tp_complete);
2059
if (status == PJ_SUCCESS) {
2060
status = on_answer_call_med_tp_complete(call->index, NULL);
2061
if (status != PJ_SUCCESS) {
2065
} else if (status != PJ_EPENDING) {
2067
pjsua_perror(THIS_FILE, "Error initializing media channel", status);
2072
/* If media transport creation is not yet completed, we will answer
2073
* the call in the media transport creation callback instead.
2075
if (call->med_ch_cb) {
2076
struct call_answer *answer;
2078
PJ_LOG(4,(THIS_FILE, "Pending answering call %d upon completion "
2079
"of media transport", call_id));
2081
answer = PJ_POOL_ZALLOC_T(call->inv->pool_prov, struct call_answer);
2082
answer->code = code;
2084
answer->opt = PJ_POOL_ZALLOC_T(call->inv->pool_prov,
2085
pjsua_call_setting);
2086
*answer->opt = *opt;
2089
pj_strdup(call->inv->pool_prov, answer->reason, reason);
2092
answer->msg_data = pjsua_msg_data_clone(call->inv->pool_prov,
2095
pj_list_push_back(&call->async_call.call_var.inc_call.answers,
2099
if (dlg) pjsip_dlg_dec_lock(dlg);
2100
pj_log_pop_indent();
2106
if (call->res_time.sec == 0)
2107
pj_gettimeofday(&call->res_time);
2109
if (reason && reason->slen == 0)
2112
/* Create response message */
2113
status = pjsip_inv_answer(call->inv, code, reason, NULL, &tdata);
2114
if (status != PJ_SUCCESS) {
2115
pjsua_perror(THIS_FILE, "Error creating response",
2120
/* Call might have been disconnected if application is answering with
2121
* 200/OK and the media failed to start.
2123
if (call->inv == NULL)
2126
/* Add additional headers etc */
2127
pjsua_process_msg_data( tdata, msg_data);
2129
/* Send the message */
2130
status = pjsip_inv_send_msg(call->inv, tdata);
2131
if (status != PJ_SUCCESS)
2132
pjsua_perror(THIS_FILE, "Error sending response",
2136
if (dlg) pjsip_dlg_dec_lock(dlg);
2137
pj_log_pop_indent();
2143
* Hangup call by using method that is appropriate according to the
2146
PJ_DEF(pj_status_t) pjsua_call_hangup(pjsua_call_id call_id,
2148
const pj_str_t *reason,
2149
const pjsua_msg_data *msg_data)
2152
pjsip_dialog *dlg = NULL;
2154
pjsip_tx_data *tdata;
2157
if (call_id<0 || call_id>=(int)pjsua_var.ua_cfg.max_calls) {
2158
PJ_LOG(1,(THIS_FILE, "pjsua_call_hangup(): invalid call id %d",
2162
PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
2165
PJ_LOG(4,(THIS_FILE, "Call %d hanging up: code=%d..", call_id, code));
2166
pj_log_push_indent();
2168
status = acquire_call("pjsua_call_hangup()", call_id, &call, &dlg);
2169
if (status != PJ_SUCCESS)
2172
/* If media transport creation is not yet completed, we will hangup
2173
* the call in the media transport creation callback instead.
2175
if (call->med_ch_cb && !call->inv) {
2176
PJ_LOG(4,(THIS_FILE, "Pending call %d hangup upon completion "
2177
"of media transport", call_id));
2178
call->async_call.call_var.out_call.hangup = PJ_TRUE;
2180
call->last_code = PJSIP_SC_REQUEST_TERMINATED;
2182
call->last_code = (pjsip_status_code)code;
2184
pj_strncpy(&call->last_text, reason,
2185
sizeof(call->last_text_buf_));
2192
if (call->inv->state == PJSIP_INV_STATE_CONFIRMED)
2194
else if (call->inv->role == PJSIP_ROLE_UAS)
2195
code = PJSIP_SC_DECLINE;
2197
code = PJSIP_SC_REQUEST_TERMINATED;
2200
status = pjsip_inv_end_session(call->inv, code, reason, &tdata);
2201
if (status != PJ_SUCCESS) {
2202
pjsua_perror(THIS_FILE,
2203
"Failed to create end session message",
2208
/* pjsip_inv_end_session may return PJ_SUCCESS with NULL
2209
* as p_tdata when INVITE transaction has not been answered
2210
* with any provisional responses.
2215
/* Add additional headers etc */
2216
pjsua_process_msg_data( tdata, msg_data);
2218
/* Send the message */
2219
status = pjsip_inv_send_msg(call->inv, tdata);
2220
if (status != PJ_SUCCESS) {
2221
pjsua_perror(THIS_FILE,
2222
"Failed to send end session message",
2227
/* Stop reinvite timer, if it is active */
2228
if (call->reinv_timer.id) {
2229
pjsua_cancel_timer(&call->reinv_timer);
2230
call->reinv_timer.id = PJ_FALSE;
2234
if (dlg) pjsip_dlg_dec_lock(dlg);
2235
pj_log_pop_indent();
2241
* Accept or reject redirection.
2243
PJ_DEF(pj_status_t) pjsua_call_process_redirect( pjsua_call_id call_id,
2244
pjsip_redirect_op cmd)
2250
PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
2253
status = acquire_call("pjsua_call_process_redirect()", call_id,
2255
if (status != PJ_SUCCESS)
2258
status = pjsip_inv_process_redirect(call->inv, cmd, NULL);
2260
pjsip_dlg_dec_lock(dlg);
2267
* Put the specified call on hold.
2269
PJ_DEF(pj_status_t) pjsua_call_set_hold(pjsua_call_id call_id,
2270
const pjsua_msg_data *msg_data)
2272
return pjsua_call_set_hold2(call_id, 0, msg_data);
2275
PJ_DEF(pj_status_t) pjsua_call_set_hold2(pjsua_call_id call_id,
2277
const pjsua_msg_data *msg_data)
2279
pjmedia_sdp_session *sdp;
2281
pjsip_dialog *dlg = NULL;
2282
pjsip_tx_data *tdata;
2283
pj_str_t *new_contact = NULL;
2286
PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
2289
PJ_LOG(4,(THIS_FILE, "Putting call %d on hold", call_id));
2290
pj_log_push_indent();
2292
status = acquire_call("pjsua_call_set_hold()", call_id, &call, &dlg);
2293
if (status != PJ_SUCCESS)
2296
if (call->inv->state != PJSIP_INV_STATE_CONFIRMED) {
2297
PJ_LOG(3,(THIS_FILE, "Can not hold call that is not confirmed"));
2298
status = PJSIP_ESESSIONSTATE;
2302
status = create_sdp_of_call_hold(call, &sdp);
2303
if (status != PJ_SUCCESS)
2306
if ((options & PJSUA_CALL_UPDATE_CONTACT) &&
2307
pjsua_acc_is_valid(call->acc_id))
2309
new_contact = &pjsua_var.acc[call->acc_id].contact;
2312
/* Create re-INVITE with new offer */
2313
status = pjsip_inv_reinvite( call->inv, new_contact, sdp, &tdata);
2314
if (status != PJ_SUCCESS) {
2315
pjsua_perror(THIS_FILE, "Unable to create re-INVITE", status);
2319
/* Add additional headers etc */
2320
pjsua_process_msg_data( tdata, msg_data);
2322
/* Record the tx_data to keep track the operation */
2323
call->hold_msg = (void*) tdata;
2325
/* Send the request */
2326
status = pjsip_inv_send_msg( call->inv, tdata);
2327
if (status != PJ_SUCCESS) {
2328
pjsua_perror(THIS_FILE, "Unable to send re-INVITE", status);
2329
call->hold_msg = NULL;
2333
/* Set flag that local put the call on hold */
2334
call->local_hold = PJ_TRUE;
2337
if (dlg) pjsip_dlg_dec_lock(dlg);
2338
pj_log_pop_indent();
2344
* Send re-INVITE (to release hold).
2346
PJ_DEF(pj_status_t) pjsua_call_reinvite( pjsua_call_id call_id,
2348
const pjsua_msg_data *msg_data)
2351
pjsip_dialog *dlg = NULL;
2354
status = acquire_call("pjsua_call_reinvite()", call_id, &call, &dlg);
2355
if (status != PJ_SUCCESS)
2358
if (options != call->opt.flag)
2359
call->opt.flag = options;
2361
status = pjsua_call_reinvite2(call_id, NULL, msg_data);
2364
if (dlg) pjsip_dlg_dec_lock(dlg);
2370
* Send re-INVITE (to release hold).
2372
PJ_DEF(pj_status_t) pjsua_call_reinvite2(pjsua_call_id call_id,
2373
const pjsua_call_setting *opt,
2374
const pjsua_msg_data *msg_data)
2376
pjmedia_sdp_session *sdp;
2377
pj_str_t *new_contact = NULL;
2378
pjsip_tx_data *tdata;
2380
pjsip_dialog *dlg = NULL;
2384
PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
2387
PJ_LOG(4,(THIS_FILE, "Sending re-INVITE on call %d", call_id));
2388
pj_log_push_indent();
2390
status = acquire_call("pjsua_call_reinvite2()", call_id, &call, &dlg);
2391
if (status != PJ_SUCCESS)
2394
if (pjsua_call_media_is_changing(call)) {
2395
PJ_LOG(1,(THIS_FILE, "Unable to reinvite" ERR_MEDIA_CHANGING));
2396
status = PJ_EINVALIDOP;
2400
if (call->inv->state != PJSIP_INV_STATE_CONFIRMED) {
2401
PJ_LOG(3,(THIS_FILE, "Can not re-INVITE call that is not confirmed"));
2402
status = PJSIP_ESESSIONSTATE;
2406
status = apply_call_setting(call, opt, NULL);
2407
if (status != PJ_SUCCESS) {
2408
pjsua_perror(THIS_FILE, "Failed to apply call setting", status);
2413
if (call->local_hold && (call->opt.flag & PJSUA_CALL_UNHOLD)==0) {
2414
status = create_sdp_of_call_hold(call, &sdp);
2416
status = pjsua_media_channel_create_sdp(call->index,
2417
call->inv->pool_prov,
2419
call->local_hold = PJ_FALSE;
2421
if (status != PJ_SUCCESS) {
2422
pjsua_perror(THIS_FILE, "Unable to get SDP from media endpoint",
2427
if ((call->opt.flag & PJSUA_CALL_UPDATE_CONTACT) &&
2428
pjsua_acc_is_valid(call->acc_id))
2430
new_contact = &pjsua_var.acc[call->acc_id].contact;
2433
/* Create re-INVITE with new offer */
2434
status = pjsip_inv_reinvite( call->inv, new_contact, sdp, &tdata);
2435
if (status != PJ_SUCCESS) {
2436
pjsua_perror(THIS_FILE, "Unable to create re-INVITE", status);
2440
/* Add additional headers etc */
2441
pjsua_process_msg_data( tdata, msg_data);
2443
/* Send the request */
2444
status = pjsip_inv_send_msg( call->inv, tdata);
2445
if (status != PJ_SUCCESS) {
2446
pjsua_perror(THIS_FILE, "Unable to send re-INVITE", status);
2451
if (dlg) pjsip_dlg_dec_lock(dlg);
2452
pj_log_pop_indent();
2458
* Send UPDATE request.
2460
PJ_DEF(pj_status_t) pjsua_call_update( pjsua_call_id call_id,
2462
const pjsua_msg_data *msg_data)
2465
pjsip_dialog *dlg = NULL;
2468
status = acquire_call("pjsua_call_update()", call_id, &call, &dlg);
2469
if (status != PJ_SUCCESS)
2472
if (options != call->opt.flag)
2473
call->opt.flag = options;
2475
status = pjsua_call_update2(call_id, NULL, msg_data);
2478
if (dlg) pjsip_dlg_dec_lock(dlg);
2484
* Send UPDATE request.
2486
PJ_DEF(pj_status_t) pjsua_call_update2(pjsua_call_id call_id,
2487
const pjsua_call_setting *opt,
2488
const pjsua_msg_data *msg_data)
2490
pjmedia_sdp_session *sdp;
2491
pj_str_t *new_contact = NULL;
2492
pjsip_tx_data *tdata;
2494
pjsip_dialog *dlg = NULL;
2497
PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
2500
PJ_LOG(4,(THIS_FILE, "Sending UPDATE on call %d", call_id));
2501
pj_log_push_indent();
2503
status = acquire_call("pjsua_call_update2()", call_id, &call, &dlg);
2504
if (status != PJ_SUCCESS)
2507
if (pjsua_call_media_is_changing(call)) {
2508
PJ_LOG(1,(THIS_FILE, "Unable to send UPDATE" ERR_MEDIA_CHANGING));
2509
status = PJ_EINVALIDOP;
2513
status = apply_call_setting(call, opt, NULL);
2514
if (status != PJ_SUCCESS) {
2515
pjsua_perror(THIS_FILE, "Failed to apply call setting", status);
2520
if (call->local_hold && (call->opt.flag & PJSUA_CALL_UNHOLD)==0) {
2521
status = create_sdp_of_call_hold(call, &sdp);
2523
status = pjsua_media_channel_create_sdp(call->index,
2524
call->inv->pool_prov,
2526
call->local_hold = PJ_FALSE;
2529
if (status != PJ_SUCCESS) {
2530
pjsua_perror(THIS_FILE, "Unable to get SDP from media endpoint",
2535
if ((call->opt.flag & PJSUA_CALL_UPDATE_CONTACT) &&
2536
pjsua_acc_is_valid(call->acc_id))
2538
new_contact = &pjsua_var.acc[call->acc_id].contact;
2541
/* Create UPDATE with new offer */
2542
status = pjsip_inv_update(call->inv, new_contact, sdp, &tdata);
2543
if (status != PJ_SUCCESS) {
2544
pjsua_perror(THIS_FILE, "Unable to create UPDATE request", status);
2548
/* Add additional headers etc */
2549
pjsua_process_msg_data( tdata, msg_data);
2551
/* Send the request */
2552
status = pjsip_inv_send_msg( call->inv, tdata);
2553
if (status != PJ_SUCCESS) {
2554
pjsua_perror(THIS_FILE, "Unable to send UPDATE request", status);
2559
if (dlg) pjsip_dlg_dec_lock(dlg);
2560
pj_log_pop_indent();
2566
* Initiate call transfer to the specified address.
2568
PJ_DEF(pj_status_t) pjsua_call_xfer( pjsua_call_id call_id,
2569
const pj_str_t *dest,
2570
const pjsua_msg_data *msg_data)
2573
pjsip_tx_data *tdata;
2575
pjsip_dialog *dlg = NULL;
2576
pjsip_generic_string_hdr *gs_hdr;
2577
const pj_str_t str_ref_by = { "Referred-By", 11 };
2578
struct pjsip_evsub_user xfer_cb;
2582
PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls &&
2585
PJ_LOG(4,(THIS_FILE, "Transferring call %d to %.*s", call_id,
2586
(int)dest->slen, dest->ptr));
2587
pj_log_push_indent();
2589
status = acquire_call("pjsua_call_xfer()", call_id, &call, &dlg);
2590
if (status != PJ_SUCCESS)
2593
/* Create xfer client subscription. */
2594
pj_bzero(&xfer_cb, sizeof(xfer_cb));
2595
xfer_cb.on_evsub_state = &xfer_client_on_evsub_state;
2597
status = pjsip_xfer_create_uac(call->inv->dlg, &xfer_cb, &sub);
2598
if (status != PJ_SUCCESS) {
2599
pjsua_perror(THIS_FILE, "Unable to create xfer", status);
2603
/* Associate this call with the client subscription */
2604
pjsip_evsub_set_mod_data(sub, pjsua_var.mod.id, call);
2607
* Create REFER request.
2609
status = pjsip_xfer_initiate(sub, dest, &tdata);
2610
if (status != PJ_SUCCESS) {
2611
pjsua_perror(THIS_FILE, "Unable to create REFER request", status);
2615
/* Add Referred-By header */
2616
gs_hdr = pjsip_generic_string_hdr_create(tdata->pool, &str_ref_by,
2617
&dlg->local.info_str);
2618
pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)gs_hdr);
2621
/* Add additional headers etc */
2622
pjsua_process_msg_data( tdata, msg_data);
2625
status = pjsip_xfer_send_request(sub, tdata);
2626
if (status != PJ_SUCCESS) {
2627
pjsua_perror(THIS_FILE, "Unable to send REFER request", status);
2631
/* For simplicity (that's what this program is intended to be!),
2632
* leave the original invite session as it is. More advanced application
2633
* may want to hold the INVITE, or terminate the invite, or whatever.
2636
if (dlg) pjsip_dlg_dec_lock(dlg);
2637
pj_log_pop_indent();
2644
* Initiate attended call transfer to the specified address.
2646
PJ_DEF(pj_status_t) pjsua_call_xfer_replaces( pjsua_call_id call_id,
2647
pjsua_call_id dest_call_id,
2649
const pjsua_msg_data *msg_data)
2651
pjsua_call *dest_call;
2652
pjsip_dialog *dest_dlg;
2653
char str_dest_buf[PJSIP_MAX_URL_SIZE*2];
2660
PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
2662
PJ_ASSERT_RETURN(dest_call_id>=0 &&
2663
dest_call_id<(int)pjsua_var.ua_cfg.max_calls,
2666
PJ_LOG(4,(THIS_FILE, "Transferring call %d replacing with call %d",
2667
call_id, dest_call_id));
2668
pj_log_push_indent();
2670
status = acquire_call("pjsua_call_xfer_replaces()", dest_call_id,
2671
&dest_call, &dest_dlg);
2672
if (status != PJ_SUCCESS) {
2673
pj_log_pop_indent();
2678
* Create REFER destination URI with Replaces field.
2681
/* Make sure we have sufficient buffer's length */
2682
PJ_ASSERT_ON_FAIL(dest_dlg->remote.info_str.slen +
2683
dest_dlg->call_id->id.slen +
2684
dest_dlg->remote.info->tag.slen +
2685
dest_dlg->local.info->tag.slen + 32
2686
< (long)sizeof(str_dest_buf),
2687
{ status=PJSIP_EURITOOLONG; goto on_error; });
2690
str_dest_buf[0] = '<';
2693
uri = (pjsip_uri*) pjsip_uri_get_uri(dest_dlg->remote.info->uri);
2694
len = pjsip_uri_print(PJSIP_URI_IN_REQ_URI, uri,
2695
str_dest_buf+1, sizeof(str_dest_buf)-1);
2697
status = PJSIP_EURITOOLONG;
2701
str_dest.slen += len;
2705
len = pj_ansi_snprintf(str_dest_buf + str_dest.slen,
2706
sizeof(str_dest_buf) - str_dest.slen,
2709
"%%3Bto-tag%%3D%.*s"
2710
"%%3Bfrom-tag%%3D%.*s>",
2711
((options&PJSUA_XFER_NO_REQUIRE_REPLACES) ?
2712
"" : "Require=replaces&"),
2713
(int)dest_dlg->call_id->id.slen,
2714
dest_dlg->call_id->id.ptr,
2715
(int)dest_dlg->remote.info->tag.slen,
2716
dest_dlg->remote.info->tag.ptr,
2717
(int)dest_dlg->local.info->tag.slen,
2718
dest_dlg->local.info->tag.ptr);
2720
PJ_ASSERT_ON_FAIL(len > 0 && len <= (int)sizeof(str_dest_buf)-str_dest.slen,
2721
{ status=PJSIP_EURITOOLONG; goto on_error; });
2723
str_dest.ptr = str_dest_buf;
2724
str_dest.slen += len;
2726
pjsip_dlg_dec_lock(dest_dlg);
2728
status = pjsua_call_xfer(call_id, &str_dest, msg_data);
2730
pj_log_pop_indent();
2734
if (dest_dlg) pjsip_dlg_dec_lock(dest_dlg);
2735
pj_log_pop_indent();
2741
* Send instant messaging inside INVITE session.
2743
PJ_DEF(pj_status_t) pjsua_call_send_im( pjsua_call_id call_id,
2744
const pj_str_t *mime_type,
2745
const pj_str_t *content,
2746
const pjsua_msg_data *msg_data,
2750
pjsip_dialog *dlg = NULL;
2751
const pj_str_t mime_text_plain = pj_str("text/plain");
2752
pjsip_media_type ctype;
2753
pjsua_im_data *im_data;
2754
pjsip_tx_data *tdata;
2757
PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
2760
PJ_LOG(4,(THIS_FILE, "Call %d sending %d bytes MESSAGE..",
2761
call_id, (int)content->slen));
2762
pj_log_push_indent();
2764
status = acquire_call("pjsua_call_send_im()", call_id, &call, &dlg);
2765
if (status != PJ_SUCCESS)
2768
/* Set default media type if none is specified */
2769
if (mime_type == NULL) {
2770
mime_type = &mime_text_plain;
2773
/* Create request message. */
2774
status = pjsip_dlg_create_request( call->inv->dlg, &pjsip_message_method,
2776
if (status != PJ_SUCCESS) {
2777
pjsua_perror(THIS_FILE, "Unable to create MESSAGE request", status);
2781
/* Add accept header. */
2782
pjsip_msg_add_hdr( tdata->msg,
2783
(pjsip_hdr*)pjsua_im_create_accept(tdata->pool));
2785
/* Parse MIME type */
2786
pjsua_parse_media_type(tdata->pool, mime_type, &ctype);
2788
/* Create "text/plain" message body. */
2789
tdata->msg->body = pjsip_msg_body_create( tdata->pool, &ctype.type,
2790
&ctype.subtype, content);
2791
if (tdata->msg->body == NULL) {
2792
pjsua_perror(THIS_FILE, "Unable to create msg body", PJ_ENOMEM);
2793
pjsip_tx_data_dec_ref(tdata);
2797
/* Add additional headers etc */
2798
pjsua_process_msg_data( tdata, msg_data);
2800
/* Create IM data and attach to the request. */
2801
im_data = PJ_POOL_ZALLOC_T(tdata->pool, pjsua_im_data);
2802
im_data->acc_id = call->acc_id;
2803
im_data->call_id = call_id;
2804
im_data->to = call->inv->dlg->remote.info_str;
2805
pj_strdup_with_null(tdata->pool, &im_data->body, content);
2806
im_data->user_data = user_data;
2809
/* Send the request. */
2810
status = pjsip_dlg_send_request( call->inv->dlg, tdata,
2811
pjsua_var.mod.id, im_data);
2812
if (status != PJ_SUCCESS) {
2813
pjsua_perror(THIS_FILE, "Unable to send MESSAGE request", status);
2818
if (dlg) pjsip_dlg_dec_lock(dlg);
2819
pj_log_pop_indent();
2825
* Send IM typing indication inside INVITE session.
2827
PJ_DEF(pj_status_t) pjsua_call_send_typing_ind( pjsua_call_id call_id,
2828
pj_bool_t is_typing,
2829
const pjsua_msg_data*msg_data)
2832
pjsip_dialog *dlg = NULL;
2833
pjsip_tx_data *tdata;
2836
PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
2839
PJ_LOG(4,(THIS_FILE, "Call %d sending typing indication..",
2841
pj_log_push_indent();
2843
status = acquire_call("pjsua_call_send_typing_ind", call_id, &call, &dlg);
2844
if (status != PJ_SUCCESS)
2847
/* Create request message. */
2848
status = pjsip_dlg_create_request( call->inv->dlg, &pjsip_message_method,
2850
if (status != PJ_SUCCESS) {
2851
pjsua_perror(THIS_FILE, "Unable to create MESSAGE request", status);
2855
/* Create "application/im-iscomposing+xml" msg body. */
2856
tdata->msg->body = pjsip_iscomposing_create_body(tdata->pool, is_typing,
2859
/* Add additional headers etc */
2860
pjsua_process_msg_data( tdata, msg_data);
2862
/* Send the request. */
2863
status = pjsip_dlg_send_request( call->inv->dlg, tdata, -1, NULL);
2864
if (status != PJ_SUCCESS) {
2865
pjsua_perror(THIS_FILE, "Unable to send MESSAGE request", status);
2870
if (dlg) pjsip_dlg_dec_lock(dlg);
2871
pj_log_pop_indent();
2877
* Send arbitrary request.
2879
PJ_DEF(pj_status_t) pjsua_call_send_request(pjsua_call_id call_id,
2880
const pj_str_t *method_str,
2881
const pjsua_msg_data *msg_data)
2884
pjsip_dialog *dlg = NULL;
2885
pjsip_method method;
2886
pjsip_tx_data *tdata;
2889
PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
2892
PJ_LOG(4,(THIS_FILE, "Call %d sending %.*s request..",
2893
call_id, (int)method_str->slen, method_str->ptr));
2894
pj_log_push_indent();
2896
status = acquire_call("pjsua_call_send_request", call_id, &call, &dlg);
2897
if (status != PJ_SUCCESS)
2901
pjsip_method_init_np(&method, (pj_str_t*)method_str);
2903
/* Create request message. */
2904
status = pjsip_dlg_create_request( call->inv->dlg, &method, -1, &tdata);
2905
if (status != PJ_SUCCESS) {
2906
pjsua_perror(THIS_FILE, "Unable to create request", status);
2910
/* Add additional headers etc */
2911
pjsua_process_msg_data( tdata, msg_data);
2913
/* Send the request. */
2914
status = pjsip_dlg_send_request( call->inv->dlg, tdata, -1, NULL);
2915
if (status != PJ_SUCCESS) {
2916
pjsua_perror(THIS_FILE, "Unable to send request", status);
2921
if (dlg) pjsip_dlg_dec_lock(dlg);
2922
pj_log_pop_indent();
2928
* Terminate all calls.
2930
PJ_DEF(void) pjsua_call_hangup_all(void)
2934
PJ_LOG(4,(THIS_FILE, "Hangup all calls.."));
2935
pj_log_push_indent();
2937
// This may deadlock, see https://trac.pjsip.org/repos/ticket/1305
2940
for (i=0; i<pjsua_var.ua_cfg.max_calls; ++i) {
2941
if (pjsua_var.calls[i].inv)
2942
pjsua_call_hangup(i, 0, NULL, NULL);
2946
pj_log_pop_indent();
2950
/* Timer callback to send re-INVITE/UPDATE to lock codec or ICE update */
2951
static void reinv_timer_cb(pj_timer_heap_t *th, pj_timer_entry *entry)
2953
pjsua_call_id call_id = (pjsua_call_id)(pj_size_t)entry->user_data;
2960
pjsua_var.calls[call_id].reinv_timer.id = PJ_FALSE;
2962
pj_log_push_indent();
2964
status = acquire_call("reinv_timer_cb()", call_id, &call, &dlg);
2965
if (status != PJ_SUCCESS) {
2966
pj_log_pop_indent();
2970
process_pending_reinvite(call);
2972
pjsip_dlg_dec_lock(dlg);
2974
pj_log_pop_indent();
2978
/* Check if the specified format can be skipped in counting codecs */
2979
static pj_bool_t is_non_av_fmt(const pjmedia_sdp_media *m,
2980
const pj_str_t *fmt)
2982
const pj_str_t STR_TEL = {"telephone-event", 15};
2985
pt = pj_strtoul(fmt);
2987
/* Check for comfort noise */
2988
if (pt == PJMEDIA_RTP_PT_CN)
2991
/* Dynamic PT, check the format name */
2993
pjmedia_sdp_attr *a;
2994
pjmedia_sdp_rtpmap rtpmap;
2996
/* Get the format name */
2997
a = pjmedia_sdp_attr_find2(m->attr_count, m->attr, "rtpmap", fmt);
2998
if (a && pjmedia_sdp_attr_get_rtpmap(a, &rtpmap)==PJ_SUCCESS) {
2999
/* Check for telephone-event */
3000
if (pj_stricmp(&rtpmap.enc_name, &STR_TEL)==0)
3003
/* Invalid SDP, should not reach here */
3004
pj_assert(!"SDP should have been validated!");
3013
/* Schedule check for the need of re-INVITE/UPDATE after media update, cases:
3014
* - lock codec if remote answerer has given us more than one codecs
3015
* - update ICE default transport address if it has changed after ICE
3016
* connectivity check.
3018
void pjsua_call_schedule_reinvite_check(pjsua_call *call, unsigned delay_ms)
3022
/* Stop reinvite timer, if it is active */
3023
if (call->reinv_timer.id)
3024
pjsua_cancel_timer(&call->reinv_timer);
3027
delay.msec = delay_ms;
3028
pj_time_val_normalize(&delay);
3029
call->reinv_timer.id = PJ_TRUE;
3030
pjsua_schedule_timer(&call->reinv_timer, &delay);
3034
/* Check if lock codec is needed */
3035
static pj_bool_t check_lock_codec(pjsua_call *call)
3037
const pjmedia_sdp_session *local_sdp, *remote_sdp;
3038
pj_bool_t has_mult_fmt = PJ_FALSE;
3042
/* Check if lock codec is disabled */
3043
if (!pjsua_var.acc[call->acc_id].cfg.lock_codec)
3046
/* Check lock codec retry count */
3047
if (call->lock_codec.retry_cnt >= LOCK_CODEC_MAX_RETRY)
3050
/* Check if we are the answerer, we shouldn't need to lock codec */
3051
if (!call->inv->neg || !pjmedia_sdp_neg_was_answer_remote(call->inv->neg))
3054
/* Check if remote answerer has given us more than one codecs. */
3055
status = pjmedia_sdp_neg_get_active_local(call->inv->neg, &local_sdp);
3056
if (status != PJ_SUCCESS)
3058
status = pjmedia_sdp_neg_get_active_remote(call->inv->neg, &remote_sdp);
3059
if (status != PJ_SUCCESS)
3062
for (i = 0; i < call->med_cnt && !has_mult_fmt; ++i) {
3063
pjsua_call_media *call_med = &call->media[i];
3064
const pjmedia_sdp_media *rem_m, *loc_m;
3065
unsigned codec_cnt = 0;
3068
/* Skip this if the media is inactive or error */
3069
if (call_med->state == PJSUA_CALL_MEDIA_NONE ||
3070
call_med->state == PJSUA_CALL_MEDIA_ERROR ||
3071
call_med->dir == PJMEDIA_DIR_NONE)
3076
/* Remote may answer with less media lines. */
3077
if (i >= remote_sdp->media_count)
3080
rem_m = remote_sdp->media[i];
3081
loc_m = local_sdp->media[i];
3083
/* Verify that media must be active. */
3084
pj_assert(loc_m->desc.port && rem_m->desc.port);
3086
/* Count the formats in the answer. */
3087
for (j=0; j<rem_m->desc.fmt_count && codec_cnt <= 1; ++j) {
3088
if (!is_non_av_fmt(rem_m, &rem_m->desc.fmt[j]) && ++codec_cnt > 1)
3089
has_mult_fmt = PJ_TRUE;
3093
/* Reset retry count when remote answer has one codec */
3095
call->lock_codec.retry_cnt = 0;
3097
return has_mult_fmt;
3100
/* Check if ICE setup is complete and if it needs to send reinvite */
3101
static pj_bool_t check_ice_complete(pjsua_call *call, pj_bool_t *need_reinv)
3103
pj_bool_t ice_need_reinv = PJ_FALSE;
3104
pj_bool_t ice_complete = PJ_TRUE;
3107
/* Check if ICE setup is complete and if it needs reinvite */
3108
for (i = 0; i < call->med_cnt; ++i) {
3109
pjsua_call_media *call_med = &call->media[i];
3110
pjmedia_transport_info tpinfo;
3111
pjmedia_ice_transport_info *ice_info;
3113
if (call_med->tp_st == PJSUA_MED_TP_NULL ||
3114
call_med->tp_st == PJSUA_MED_TP_DISABLED ||
3115
call_med->state == PJSUA_CALL_MEDIA_ERROR)
3120
pjmedia_transport_info_init(&tpinfo);
3121
pjmedia_transport_get_info(call_med->tp, &tpinfo);
3122
ice_info = (pjmedia_ice_transport_info*)
3123
pjmedia_transport_info_get_spc_info(
3124
&tpinfo, PJMEDIA_TRANSPORT_TYPE_ICE);
3126
/* Check if ICE is active */
3127
if (!ice_info || !ice_info->active)
3130
/* Check if ICE setup not completed yet */
3131
if (ice_info->sess_state < PJ_ICE_STRANS_STATE_RUNNING) {
3132
ice_complete = PJ_FALSE;
3136
/* Check if ICE needs to send reinvite */
3137
if (!ice_need_reinv &&
3138
ice_info->sess_state == PJ_ICE_STRANS_STATE_RUNNING &&
3139
ice_info->role == PJ_ICE_SESS_ROLE_CONTROLLING)
3141
pjsua_ice_config *cfg=&pjsua_var.acc[call->acc_id].cfg.ice_cfg;
3142
if ((cfg->ice_always_update && !call->reinv_ice_sent) ||
3143
pj_sockaddr_cmp(&tpinfo.sock_info.rtp_addr_name,
3144
&call_med->rtp_addr))
3146
ice_need_reinv = PJ_TRUE;
3151
if (ice_complete && need_reinv)
3152
*need_reinv = ice_need_reinv;
3154
return ice_complete;
3157
/* Check and send reinvite for lock codec and ICE update */
3158
static pj_status_t process_pending_reinvite(pjsua_call *call)
3160
const pj_str_t ST_UPDATE = {"UPDATE", 6};
3161
pj_pool_t *pool = call->inv->pool_prov;
3162
pjsip_inv_session *inv = call->inv;
3163
pj_bool_t ice_need_reinv;
3164
pj_bool_t ice_completed;
3165
pj_bool_t need_lock_codec;
3166
pj_bool_t rem_can_update;
3167
pjmedia_sdp_session *new_offer;
3168
pjsip_tx_data *tdata;
3172
/* Verify if another SDP negotiation is in progress, e.g: session timer
3173
* or another re-INVITE.
3175
if (inv==NULL || inv->neg==NULL ||
3176
pjmedia_sdp_neg_get_state(inv->neg)!=PJMEDIA_SDP_NEG_STATE_DONE)
3178
return PJMEDIA_SDPNEG_EINSTATE;
3181
/* Don't do this if call is disconnecting! */
3182
if (inv->state > PJSIP_INV_STATE_CONFIRMED || inv->cause >= 200)
3184
return PJ_EINVALIDOP;
3187
/* Delay this when the SDP negotiation done in call state EARLY and
3188
* remote does not support UPDATE method.
3190
if (inv->state == PJSIP_INV_STATE_EARLY &&
3191
pjsip_dlg_remote_has_cap(inv->dlg, PJSIP_H_ALLOW, NULL, &ST_UPDATE)!=
3192
PJSIP_DIALOG_CAP_SUPPORTED)
3194
call->reinv_pending = PJ_TRUE;
3198
/* Check if ICE setup is complete and if it needs reinvite */
3199
ice_completed = check_ice_complete(call, &ice_need_reinv);
3203
/* Check if we need to lock codec */
3204
need_lock_codec = check_lock_codec(call);
3206
/* Check if reinvite is really needed */
3207
if (!need_lock_codec && !ice_need_reinv)
3211
/* Okay! So we need to send re-INVITE/UPDATE */
3213
/* Check if remote support UPDATE */
3214
rem_can_update = pjsip_dlg_remote_has_cap(inv->dlg, PJSIP_H_ALLOW, NULL,
3216
PJSIP_DIALOG_CAP_SUPPORTED;
3220
const char *ST_ICE_UPDATE = "ICE transport address after "
3222
const char *ST_LOCK_CODEC = "media session to use only one codec";
3223
PJ_LOG(4,(THIS_FILE, "Call %d sending %s for updating %s%s%s",
3225
(rem_can_update? "UPDATE" : "re-INVITE"),
3226
(ice_need_reinv? ST_ICE_UPDATE : ST_LOCK_CODEC),
3227
(ice_need_reinv && need_lock_codec? " and " : ""),
3228
(ice_need_reinv && need_lock_codec? ST_LOCK_CODEC : "")
3232
/* Generate SDP re-offer */
3233
status = pjsua_media_channel_create_sdp(call->index, pool, NULL,
3235
if (status != PJ_SUCCESS) {
3236
pjsua_perror(THIS_FILE, "Unable to create local SDP", status);
3240
/* Update the new offer so it contains only a codec. Note that
3241
* SDP nego has removed unmatched codecs from the offer and the codec
3242
* order in the offer has been matched to the answer, so we'll override
3243
* the codecs in the just generated SDP with the ones from the active
3244
* local SDP and leave just one codec for the next SDP re-offer.
3246
if (need_lock_codec) {
3247
const pjmedia_sdp_session *ref_sdp;
3249
/* Get local active SDP as reference */
3250
status = pjmedia_sdp_neg_get_active_local(call->inv->neg, &ref_sdp);
3251
if (status != PJ_SUCCESS)
3254
/* Verify media count. Note that remote may add/remove media line
3255
* in the answer. When answer has less media, it must have been
3256
* handled by pjsua_media_channel_update() as disabled media.
3257
* When answer has more media, it must have been ignored (treated
3258
* as non-exist) anywhere. Local media count should not be updated
3259
* at this point, as modifying media count operation (i.e: reinvite,
3260
* update, vid_set_strm) is currently blocking, protected with
3261
* dialog mutex, and eventually reset SDP nego state to LOCAL OFFER.
3263
if (call->med_cnt != ref_sdp->media_count ||
3264
ref_sdp->media_count != new_offer->media_count)
3266
/* Anyway, just in case, let's just return error */
3267
return PJMEDIA_SDPNEG_EINSTATE;
3270
for (i = 0; i < call->med_cnt; ++i) {
3271
unsigned j, codec_cnt = 0;
3272
const pjmedia_sdp_media *ref_m = ref_sdp->media[i];
3273
pjmedia_sdp_media *m = new_offer->media[i];
3274
pjsua_call_media *call_med = &call->media[i];
3276
/* Verify if media is deactivated */
3277
if (call_med->state == PJSUA_CALL_MEDIA_NONE ||
3278
call_med->state == PJSUA_CALL_MEDIA_ERROR ||
3279
call_med->dir == PJMEDIA_DIR_NONE)
3285
m->desc.fmt_count = 0;
3286
pjmedia_sdp_attr_remove_all(&m->attr_count, m->attr, "rtpmap");
3287
pjmedia_sdp_attr_remove_all(&m->attr_count, m->attr, "fmtp");
3289
/* Copy only the first format + any non-AV formats from
3290
* the active local SDP.
3292
for (j = 0; j < ref_m->desc.fmt_count; ++j) {
3293
const pj_str_t *fmt = &ref_m->desc.fmt[j];
3295
if (is_non_av_fmt(ref_m, fmt) || (++codec_cnt == 1)) {
3296
pjmedia_sdp_attr *a;
3298
m->desc.fmt[m->desc.fmt_count++] = *fmt;
3299
a = pjmedia_sdp_attr_find2(ref_m->attr_count, ref_m->attr,
3301
if (a) pjmedia_sdp_attr_add(&m->attr_count, m->attr, a);
3302
a = pjmedia_sdp_attr_find2(ref_m->attr_count, ref_m->attr,
3304
if (a) pjmedia_sdp_attr_add(&m->attr_count, m->attr, a);
3310
/* Put back original direction and "c=0.0.0.0" line */
3312
const pjmedia_sdp_session *cur_sdp;
3314
/* Get local active SDP */
3315
status = pjmedia_sdp_neg_get_active_local(call->inv->neg, &cur_sdp);
3316
if (status != PJ_SUCCESS)
3319
/* Make sure media count has not been changed */
3320
if (call->med_cnt != cur_sdp->media_count)
3321
return PJMEDIA_SDPNEG_EINSTATE;
3323
for (i = 0; i < call->med_cnt; ++i) {
3324
const pjmedia_sdp_media *m = cur_sdp->media[i];
3325
pjmedia_sdp_media *new_m = new_offer->media[i];
3326
pjsua_call_media *call_med = &call->media[i];
3327
pjmedia_sdp_attr *a = NULL;
3329
/* Update direction to the current dir */
3330
pjmedia_sdp_media_remove_all_attr(new_m, "sendrecv");
3331
pjmedia_sdp_media_remove_all_attr(new_m, "sendonly");
3332
pjmedia_sdp_media_remove_all_attr(new_m, "recvonly");
3333
pjmedia_sdp_media_remove_all_attr(new_m, "inactive");
3335
if (call_med->dir == PJMEDIA_DIR_ENCODING_DECODING) {
3336
a = pjmedia_sdp_attr_create(pool, "sendrecv", NULL);
3337
} else if (call_med->dir == PJMEDIA_DIR_ENCODING) {
3338
a = pjmedia_sdp_attr_create(pool, "sendonly", NULL);
3339
} else if (call_med->dir == PJMEDIA_DIR_DECODING) {
3340
a = pjmedia_sdp_attr_create(pool, "recvonly", NULL);
3342
const pjmedia_sdp_conn *conn;
3343
a = pjmedia_sdp_attr_create(pool, "inactive", NULL);
3345
/* Also check if the original c= line address is zero */
3348
conn = cur_sdp->conn;
3349
if (pj_strcmp2(&conn->addr, "0.0.0.0")==0 ||
3350
pj_strcmp2(&conn->addr, "0")==0)
3353
new_m->conn = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_conn);
3356
if (pj_strcmp2(&new_m->conn->addr, "0.0.0.0")) {
3357
new_m->conn->net_type = pj_str("IN");
3358
new_m->conn->addr_type = pj_str("IP4");
3359
new_m->conn->addr = pj_str("0.0.0.0");
3365
pjmedia_sdp_media_add_attr(new_m, a);
3370
if (rem_can_update) {
3371
status = pjsip_inv_update(inv, NULL, new_offer, &tdata);
3373
status = pjsip_inv_reinvite(inv, NULL, new_offer, &tdata);
3376
if (status==PJ_EINVALIDOP &&
3377
++call->lock_codec.retry_cnt < LOCK_CODEC_MAX_RETRY)
3379
/* Ups, let's reschedule again */
3380
pjsua_call_schedule_reinvite_check(call, LOCK_CODEC_RETRY_INTERVAL);
3382
} else if (status != PJ_SUCCESS) {
3383
pjsua_perror(THIS_FILE, "Error creating UPDATE/re-INVITE",
3388
/* Send the UPDATE/re-INVITE request */
3389
status = pjsip_inv_send_msg(inv, tdata);
3390
if (status != PJ_SUCCESS) {
3391
pjsua_perror(THIS_FILE, "Error sending UPDATE/re-INVITE",
3398
call->reinv_ice_sent = PJ_TRUE;
3399
if (need_lock_codec)
3400
++call->lock_codec.retry_cnt;
3407
* This callback receives notification from invite session when the
3408
* session state has changed.
3410
static void pjsua_call_on_state_changed(pjsip_inv_session *inv,
3415
pj_log_push_indent();
3417
call = (pjsua_call*) inv->dlg->mod_data[pjsua_var.mod.id];
3420
pj_log_pop_indent();
3425
/* Get call times */
3426
switch (inv->state) {
3427
case PJSIP_INV_STATE_EARLY:
3428
case PJSIP_INV_STATE_CONNECTING:
3429
if (call->res_time.sec == 0)
3430
pj_gettimeofday(&call->res_time);
3431
call->last_code = (pjsip_status_code)
3432
e->body.tsx_state.tsx->status_code;
3433
pj_strncpy(&call->last_text,
3434
&e->body.tsx_state.tsx->status_text,
3435
sizeof(call->last_text_buf_));
3437
case PJSIP_INV_STATE_CONFIRMED:
3438
pj_gettimeofday(&call->conn_time);
3440
/* See if auto reinvite was pended as media update was done in the
3441
* EARLY state and remote does not support UPDATE.
3443
if (call->reinv_pending) {
3444
call->reinv_pending = PJ_FALSE;
3445
pjsua_call_schedule_reinvite_check(call, 0);
3448
case PJSIP_INV_STATE_DISCONNECTED:
3449
pj_gettimeofday(&call->dis_time);
3450
if (call->res_time.sec == 0)
3451
pj_gettimeofday(&call->res_time);
3452
if (e->type == PJSIP_EVENT_TSX_STATE &&
3453
e->body.tsx_state.tsx->status_code > call->last_code)
3455
call->last_code = (pjsip_status_code)
3456
e->body.tsx_state.tsx->status_code;
3457
pj_strncpy(&call->last_text,
3458
&e->body.tsx_state.tsx->status_text,
3459
sizeof(call->last_text_buf_));
3461
call->last_code = PJSIP_SC_REQUEST_TERMINATED;
3462
pj_strncpy(&call->last_text,
3463
pjsip_get_status_text(call->last_code),
3464
sizeof(call->last_text_buf_));
3467
/* Stop reinvite timer, if it is active */
3468
if (call->reinv_timer.id) {
3469
pjsua_cancel_timer(&call->reinv_timer);
3470
call->reinv_timer.id = PJ_FALSE;
3474
call->last_code = (pjsip_status_code)
3475
e->body.tsx_state.tsx->status_code;
3476
pj_strncpy(&call->last_text,
3477
&e->body.tsx_state.tsx->status_text,
3478
sizeof(call->last_text_buf_));
3482
/* If this is an outgoing INVITE that was created because of
3483
* REFER/transfer, send NOTIFY to transferer.
3485
if (call->xfer_sub && e->type==PJSIP_EVENT_TSX_STATE) {
3487
pjsip_evsub_state ev_state = PJSIP_EVSUB_STATE_ACTIVE;
3490
switch (call->inv->state) {
3491
case PJSIP_INV_STATE_NULL:
3492
case PJSIP_INV_STATE_CALLING:
3496
case PJSIP_INV_STATE_EARLY:
3497
case PJSIP_INV_STATE_CONNECTING:
3498
st_code = e->body.tsx_state.tsx->status_code;
3499
if (call->inv->state == PJSIP_INV_STATE_CONNECTING)
3500
ev_state = PJSIP_EVSUB_STATE_TERMINATED;
3502
ev_state = PJSIP_EVSUB_STATE_ACTIVE;
3505
case PJSIP_INV_STATE_CONFIRMED:
3507
/* We don't need this, as we've terminated the subscription in
3510
/* When state is confirmed, send the final 200/OK and terminate
3513
st_code = e->body.tsx_state.tsx->status_code;
3514
ev_state = PJSIP_EVSUB_STATE_TERMINATED;
3518
case PJSIP_INV_STATE_DISCONNECTED:
3519
st_code = e->body.tsx_state.tsx->status_code;
3520
ev_state = PJSIP_EVSUB_STATE_TERMINATED;
3523
case PJSIP_INV_STATE_INCOMING:
3524
/* Nothing to do. Just to keep gcc from complaining about
3530
if (st_code != -1) {
3531
pjsip_tx_data *tdata;
3534
status = pjsip_xfer_notify( call->xfer_sub,
3537
if (status != PJ_SUCCESS) {
3538
pjsua_perror(THIS_FILE, "Unable to create NOTIFY", status);
3540
status = pjsip_xfer_send_request(call->xfer_sub, tdata);
3541
if (status != PJ_SUCCESS) {
3542
pjsua_perror(THIS_FILE, "Unable to send NOTIFY", status);
3548
/* Ticket #1627: Invoke on_call_tsx_state() when call is disconnected. */
3549
if (inv->state == PJSIP_INV_STATE_DISCONNECTED &&
3550
e->type == PJSIP_EVENT_TSX_STATE &&
3552
pjsua_var.ua_cfg.cb.on_call_tsx_state)
3554
(*pjsua_var.ua_cfg.cb.on_call_tsx_state)(call->index,
3555
e->body.tsx_state.tsx, e);
3558
if (pjsua_var.ua_cfg.cb.on_call_state)
3559
(*pjsua_var.ua_cfg.cb.on_call_state)(call->index, e);
3561
/* call->inv may be NULL now */
3563
/* Destroy media session when invite session is disconnected. */
3564
if (inv->state == PJSIP_INV_STATE_DISCONNECTED) {
3568
pjsua_media_channel_deinit(call->index);
3573
pj_assert(pjsua_var.call_cnt > 0);
3574
--pjsua_var.call_cnt;
3577
reset_call(call->index);
3579
pjsua_check_snd_dev_idle();
3583
pj_log_pop_indent();
3587
* This callback is called by invite session framework when UAC session
3590
static void pjsua_call_on_forked( pjsip_inv_session *inv,
3596
PJ_TODO(HANDLE_FORKED_DIALOG);
3601
* Callback from UA layer when forked dialog response is received.
3603
pjsip_dialog* on_dlg_forked(pjsip_dialog *dlg, pjsip_rx_data *res)
3605
if (dlg->uac_has_2xx &&
3606
res->msg_info.cseq->method.id == PJSIP_INVITE_METHOD &&
3607
pjsip_rdata_get_tsx(res) == NULL &&
3608
res->msg_info.msg->line.status.code/100 == 2)
3610
pjsip_dialog *forked_dlg;
3614
/* Create forked dialog */
3615
status = pjsip_dlg_fork(dlg, res, &forked_dlg);
3616
if (status != PJ_SUCCESS)
3619
pjsip_dlg_inc_lock(forked_dlg);
3621
/* Disconnect the call */
3622
status = pjsip_dlg_create_request(forked_dlg, &pjsip_bye_method,
3624
if (status == PJ_SUCCESS) {
3625
status = pjsip_dlg_send_request(forked_dlg, bye, -1, NULL);
3628
pjsip_dlg_dec_lock(forked_dlg);
3630
if (status != PJ_SUCCESS) {
3642
* Disconnect call upon error.
3644
static void call_disconnect( pjsip_inv_session *inv,
3647
pjsip_tx_data *tdata;
3650
status = pjsip_inv_end_session(inv, code, NULL, &tdata);
3651
if (status != PJ_SUCCESS)
3654
#if DISABLED_FOR_TICKET_1185
3657
/* Add SDP in 488 status */
3658
call = (pjsua_call*) inv->dlg->mod_data[pjsua_var.mod.id];
3660
if (call && call->tp && tdata->msg->type==PJSIP_RESPONSE_MSG &&
3661
code==PJSIP_SC_NOT_ACCEPTABLE_HERE)
3663
pjmedia_sdp_session *local_sdp;
3664
pjmedia_transport_info ti;
3666
pjmedia_transport_info_init(&ti);
3667
pjmedia_transport_get_info(call->med_tp, &ti);
3668
status = pjmedia_endpt_create_sdp(pjsua_var.med_endpt, tdata->pool,
3669
1, &ti.sock_info, &local_sdp);
3670
if (status == PJ_SUCCESS) {
3671
pjsip_create_sdp_body(tdata->pool, local_sdp,
3677
pjsip_inv_send_msg(inv, tdata);
3681
* Callback to be called when SDP offer/answer negotiation has just completed
3682
* in the session. This function will start/update media if negotiation
3685
static void pjsua_call_on_media_update(pjsip_inv_session *inv,
3689
const pjmedia_sdp_session *local_sdp;
3690
const pjmedia_sdp_session *remote_sdp;
3691
//const pj_str_t st_update = {"UPDATE", 6};
3693
pj_log_push_indent();
3695
call = (pjsua_call*) inv->dlg->mod_data[pjsua_var.mod.id];
3697
if (status != PJ_SUCCESS) {
3699
pjsua_perror(THIS_FILE, "SDP negotiation has failed", status);
3701
/* Clean up provisional media */
3702
pjsua_media_prov_clean_up(call->index);
3704
/* Do not deinitialize media since this may be a re-INVITE or
3705
* UPDATE (which in this case the media should not get affected
3706
* by the failed re-INVITE/UPDATE). The media will be shutdown
3707
* when call is disconnected anyway.
3709
/* Stop/destroy media, if any */
3710
/*pjsua_media_channel_deinit(call->index);*/
3712
/* Disconnect call if we're not in the middle of initializing an
3713
* UAS dialog and if this is not a re-INVITE
3715
if (inv->state != PJSIP_INV_STATE_NULL &&
3716
inv->state != PJSIP_INV_STATE_CONFIRMED)
3718
call_disconnect(inv, PJSIP_SC_UNSUPPORTED_MEDIA_TYPE);
3725
/* Get local and remote SDP */
3726
status = pjmedia_sdp_neg_get_active_local(call->inv->neg, &local_sdp);
3727
if (status != PJ_SUCCESS) {
3728
pjsua_perror(THIS_FILE,
3729
"Unable to retrieve currently active local SDP",
3731
//call_disconnect(inv, PJSIP_SC_UNSUPPORTED_MEDIA_TYPE);
3735
status = pjmedia_sdp_neg_get_active_remote(call->inv->neg, &remote_sdp);
3736
if (status != PJ_SUCCESS) {
3737
pjsua_perror(THIS_FILE,
3738
"Unable to retrieve currently active remote SDP",
3740
//call_disconnect(inv, PJSIP_SC_UNSUPPORTED_MEDIA_TYPE);
3744
/* Update remote's NAT type */
3745
if (pjsua_var.ua_cfg.nat_type_in_sdp) {
3746
update_remote_nat_type(call, remote_sdp);
3749
/* Update media channel with the new SDP */
3750
status = pjsua_media_channel_update(call->index, local_sdp, remote_sdp);
3751
if (status != PJ_SUCCESS) {
3752
pjsua_perror(THIS_FILE, "Unable to create media session",
3754
call_disconnect(inv, PJSIP_SC_NOT_ACCEPTABLE_HERE);
3755
/* No need to deinitialize; media will be shutdown when call
3756
* state is disconnected anyway.
3758
/*pjsua_media_channel_deinit(call->index);*/
3762
/* Ticket #476: make sure only one codec is specified in the answer. */
3763
pjsua_call_schedule_reinvite_check(call, 0);
3765
/* Call application callback, if any */
3766
if (pjsua_var.ua_cfg.cb.on_call_media_state)
3767
pjsua_var.ua_cfg.cb.on_call_media_state(call->index);
3770
pj_log_pop_indent();
3774
/* Modify SDP for call hold. */
3775
static pj_status_t modify_sdp_of_call_hold(pjsua_call *call,
3777
pjmedia_sdp_session *sdp,
3778
pj_bool_t as_answerer)
3782
/* Call-hold is done by set the media direction to 'sendonly'
3783
* (PJMEDIA_DIR_ENCODING), except when current media direction is
3784
* 'inactive' (PJMEDIA_DIR_NONE).
3785
* (See RFC 3264 Section 8.4 and RFC 4317 Section 3.1)
3787
/* http://trac.pjsip.org/repos/ticket/880
3788
if (call->dir != PJMEDIA_DIR_ENCODING) {
3790
/* https://trac.pjsip.org/repos/ticket/1142:
3791
* configuration to use c=0.0.0.0 for call hold.
3794
for (mi=0; mi<sdp->media_count; ++mi) {
3795
pjmedia_sdp_media *m = sdp->media[mi];
3797
if (call->call_hold_type == PJSUA_CALL_HOLD_TYPE_RFC2543) {
3798
pjmedia_sdp_conn *conn;
3799
pjmedia_sdp_attr *attr;
3801
/* Get SDP media connection line */
3806
/* Modify address */
3807
conn->addr = pj_str("0.0.0.0");
3809
/* Remove existing directions attributes */
3810
pjmedia_sdp_media_remove_all_attr(m, "sendrecv");
3811
pjmedia_sdp_media_remove_all_attr(m, "sendonly");
3812
pjmedia_sdp_media_remove_all_attr(m, "recvonly");
3813
pjmedia_sdp_media_remove_all_attr(m, "inactive");
3815
/* Add inactive attribute */
3816
attr = pjmedia_sdp_attr_create(pool, "inactive", NULL);
3817
pjmedia_sdp_media_add_attr(m, attr);
3821
pjmedia_sdp_attr *attr;
3823
/* Remove existing directions attributes */
3824
pjmedia_sdp_media_remove_all_attr(m, "sendrecv");
3825
pjmedia_sdp_media_remove_all_attr(m, "sendonly");
3826
pjmedia_sdp_media_remove_all_attr(m, "recvonly");
3827
pjmedia_sdp_media_remove_all_attr(m, "inactive");
3829
/* When as answerer, just simply set dir to "sendonly", note that
3830
* if the offer uses "sendonly" or "inactive", the SDP negotiator
3831
* will change our answer dir to "inactive".
3833
if (as_answerer || (call->media[mi].dir & PJMEDIA_DIR_ENCODING)) {
3834
/* Add sendonly attribute */
3835
attr = pjmedia_sdp_attr_create(pool, "sendonly", NULL);
3836
pjmedia_sdp_media_add_attr(m, attr);
3838
/* Add inactive attribute */
3839
attr = pjmedia_sdp_attr_create(pool, "inactive", NULL);
3840
pjmedia_sdp_media_add_attr(m, attr);
3848
/* Create SDP for call hold. */
3849
static pj_status_t create_sdp_of_call_hold(pjsua_call *call,
3850
pjmedia_sdp_session **p_sdp)
3854
pjmedia_sdp_session *sdp;
3856
/* Use call's provisional pool */
3857
pool = call->inv->pool_prov;
3859
/* Create new offer */
3860
status = pjsua_media_channel_create_sdp(call->index, pool, NULL, &sdp,
3862
if (status != PJ_SUCCESS) {
3863
pjsua_perror(THIS_FILE, "Unable to create local SDP", status);
3867
status = modify_sdp_of_call_hold(call, pool, sdp, PJ_FALSE);
3868
if (status != PJ_SUCCESS)
3877
* Called when session received new offer.
3879
static void pjsua_call_on_rx_offer(pjsip_inv_session *inv,
3880
const pjmedia_sdp_session *offer)
3883
pjmedia_sdp_session *answer;
3887
call = (pjsua_call*) inv->dlg->mod_data[pjsua_var.mod.id];
3889
/* Supply candidate answer */
3890
PJ_LOG(4,(THIS_FILE, "Call %d: received updated media offer",
3893
pj_log_push_indent();
3895
if (pjsua_call_media_is_changing(call)) {
3896
PJ_LOG(1,(THIS_FILE, "Unable to process offer" ERR_MEDIA_CHANGING));
3900
if (pjsua_var.ua_cfg.cb.on_call_rx_offer) {
3901
pjsip_status_code code = PJSIP_SC_OK;
3902
pjsua_call_setting opt = call->opt;
3904
(*pjsua_var.ua_cfg.cb.on_call_rx_offer)(call->index, offer, NULL,
3907
if (code != PJSIP_SC_OK) {
3908
PJ_LOG(4,(THIS_FILE, "Rejecting updated media offer on call %d",
3916
/* Re-init media for the new remote offer before creating SDP */
3917
status = apply_call_setting(call, &call->opt, offer);
3918
if (status != PJ_SUCCESS)
3921
status = pjsua_media_channel_create_sdp(call->index,
3922
call->inv->pool_prov,
3923
offer, &answer, NULL);
3924
if (status != PJ_SUCCESS) {
3925
pjsua_perror(THIS_FILE, "Unable to create local SDP", status);
3929
/* Validate media count in the generated answer */
3930
pj_assert(answer->media_count == offer->media_count);
3932
/* Check if offer's conn address is zero */
3933
for (i = 0; i < answer->media_count; ++i) {
3934
pjmedia_sdp_conn *conn;
3936
conn = offer->media[i]->conn;
3940
if (pj_strcmp2(&conn->addr, "0.0.0.0")==0 ||
3941
pj_strcmp2(&conn->addr, "0")==0)
3943
pjmedia_sdp_conn *a_conn = answer->media[i]->conn;
3945
/* Modify answer address */
3947
a_conn->addr = pj_str("0.0.0.0");
3948
} else if (answer->conn == NULL ||
3949
pj_strcmp2(&answer->conn->addr, "0.0.0.0") != 0)
3951
a_conn = PJ_POOL_ZALLOC_T(call->inv->pool_prov,
3953
a_conn->net_type = pj_str("IN");
3954
a_conn->addr_type = pj_str("IP4");
3955
a_conn->addr = pj_str("0.0.0.0");
3956
answer->media[i]->conn = a_conn;
3961
/* Check if call is on-hold */
3962
if (call->local_hold) {
3963
modify_sdp_of_call_hold(call, call->inv->pool_prov, answer, PJ_TRUE);
3966
status = pjsip_inv_set_sdp_answer(call->inv, answer);
3967
if (status != PJ_SUCCESS) {
3968
pjsua_perror(THIS_FILE, "Unable to set answer", status);
3973
pj_log_pop_indent();
3978
* Called to generate new offer.
3980
static void pjsua_call_on_create_offer(pjsip_inv_session *inv,
3981
pjmedia_sdp_session **offer)
3986
pj_log_push_indent();
3988
call = (pjsua_call*) inv->dlg->mod_data[pjsua_var.mod.id];
3989
if (pjsua_call_media_is_changing(call)) {
3991
PJ_LOG(1,(THIS_FILE, "Unable to create offer" ERR_MEDIA_CHANGING));
3995
/* See if we've put call on hold. */
3996
if (call->local_hold) {
3997
PJ_LOG(4,(THIS_FILE,
3998
"Call %d: call is on-hold locally, creating call-hold SDP ",
4000
status = create_sdp_of_call_hold( call, offer );
4002
PJ_LOG(4,(THIS_FILE, "Call %d: asked to send a new offer",
4005
status = pjsua_media_channel_create_sdp(call->index,
4006
call->inv->pool_prov,
4010
if (status != PJ_SUCCESS) {
4011
pjsua_perror(THIS_FILE, "Unable to create local SDP", status);
4016
pj_log_pop_indent();
4021
* Callback called by event framework when the xfer subscription state
4024
static void xfer_client_on_evsub_state( pjsip_evsub *sub, pjsip_event *event)
4027
PJ_UNUSED_ARG(event);
4029
pj_log_push_indent();
4032
* When subscription is accepted (got 200/OK to REFER), check if
4033
* subscription suppressed.
4035
if (pjsip_evsub_get_state(sub) == PJSIP_EVSUB_STATE_ACCEPTED) {
4037
pjsip_rx_data *rdata;
4038
pjsip_generic_string_hdr *refer_sub;
4039
const pj_str_t REFER_SUB = { "Refer-Sub", 9 };
4042
call = (pjsua_call*) pjsip_evsub_get_mod_data(sub, pjsua_var.mod.id);
4044
/* Must be receipt of response message */
4045
pj_assert(event->type == PJSIP_EVENT_TSX_STATE &&
4046
event->body.tsx_state.type == PJSIP_EVENT_RX_MSG);
4047
rdata = event->body.tsx_state.src.rdata;
4049
/* Find Refer-Sub header */
4050
refer_sub = (pjsip_generic_string_hdr*)
4051
pjsip_msg_find_hdr_by_name(rdata->msg_info.msg,
4054
/* Check if subscription is suppressed */
4055
if (refer_sub && pj_stricmp2(&refer_sub->hvalue, "false")==0) {
4056
/* Since no subscription is desired, assume that call has been
4057
* transferred successfully.
4059
if (call && pjsua_var.ua_cfg.cb.on_call_transfer_status) {
4060
const pj_str_t ACCEPTED = { "Accepted", 8 };
4061
pj_bool_t cont = PJ_FALSE;
4062
(*pjsua_var.ua_cfg.cb.on_call_transfer_status)(call->index,
4069
/* Yes, subscription is suppressed.
4070
* Terminate our subscription now.
4072
PJ_LOG(4,(THIS_FILE, "Xfer subscription suppressed, terminating "
4073
"event subcription..."));
4074
pjsip_evsub_terminate(sub, PJ_TRUE);
4077
/* Notify application about call transfer progress.
4078
* Initially notify with 100/Accepted status.
4080
if (call && pjsua_var.ua_cfg.cb.on_call_transfer_status) {
4081
const pj_str_t ACCEPTED = { "Accepted", 8 };
4082
pj_bool_t cont = PJ_FALSE;
4083
(*pjsua_var.ua_cfg.cb.on_call_transfer_status)(call->index,
4092
* On incoming NOTIFY, notify application about call transfer progress.
4094
else if (pjsip_evsub_get_state(sub) == PJSIP_EVSUB_STATE_ACTIVE ||
4095
pjsip_evsub_get_state(sub) == PJSIP_EVSUB_STATE_TERMINATED)
4099
pjsip_msg_body *body;
4100
pjsip_status_line status_line;
4105
call = (pjsua_call*) pjsip_evsub_get_mod_data(sub, pjsua_var.mod.id);
4107
/* When subscription is terminated, clear the xfer_sub member of
4110
if (pjsip_evsub_get_state(sub) == PJSIP_EVSUB_STATE_TERMINATED) {
4111
pjsip_evsub_set_mod_data(sub, pjsua_var.mod.id, NULL);
4112
PJ_LOG(4,(THIS_FILE, "Xfer client subscription terminated"));
4116
if (!call || !event || !pjsua_var.ua_cfg.cb.on_call_transfer_status) {
4117
/* Application is not interested with call progress status */
4121
/* This better be a NOTIFY request */
4122
if (event->type == PJSIP_EVENT_TSX_STATE &&
4123
event->body.tsx_state.type == PJSIP_EVENT_RX_MSG)
4125
pjsip_rx_data *rdata;
4127
rdata = event->body.tsx_state.src.rdata;
4129
/* Check if there's body */
4130
msg = rdata->msg_info.msg;
4133
PJ_LOG(2,(THIS_FILE,
4134
"Warning: received NOTIFY without message body"));
4138
/* Check for appropriate content */
4139
if (pj_stricmp2(&body->content_type.type, "message") != 0 ||
4140
pj_stricmp2(&body->content_type.subtype, "sipfrag") != 0)
4142
PJ_LOG(2,(THIS_FILE,
4143
"Warning: received NOTIFY with non message/sipfrag "
4148
/* Try to parse the content */
4149
status = pjsip_parse_status_line((char*)body->data, body->len,
4151
if (status != PJ_SUCCESS) {
4152
PJ_LOG(2,(THIS_FILE,
4153
"Warning: received NOTIFY with invalid "
4154
"message/sipfrag content"));
4159
status_line.code = 500;
4160
status_line.reason = *pjsip_get_status_text(500);
4163
/* Notify application */
4164
is_last = (pjsip_evsub_get_state(sub)==PJSIP_EVSUB_STATE_TERMINATED);
4166
(*pjsua_var.ua_cfg.cb.on_call_transfer_status)(call->index,
4168
&status_line.reason,
4172
pjsip_evsub_set_mod_data(sub, pjsua_var.mod.id, NULL);
4175
/* If the call transfer has completed but the subscription is
4176
* not terminated, terminate it now.
4178
if (status_line.code/100 == 2 && !is_last) {
4179
pjsip_tx_data *tdata;
4181
status = pjsip_evsub_initiate(sub, &pjsip_subscribe_method,
4183
if (status == PJ_SUCCESS)
4184
status = pjsip_evsub_send_request(sub, tdata);
4189
pj_log_pop_indent();
4194
* Callback called by event framework when the xfer subscription state
4197
static void xfer_server_on_evsub_state( pjsip_evsub *sub, pjsip_event *event)
4199
PJ_UNUSED_ARG(event);
4201
pj_log_push_indent();
4204
* When subscription is terminated, clear the xfer_sub member of
4207
if (pjsip_evsub_get_state(sub) == PJSIP_EVSUB_STATE_TERMINATED) {
4210
call = (pjsua_call*) pjsip_evsub_get_mod_data(sub, pjsua_var.mod.id);
4214
pjsip_evsub_set_mod_data(sub, pjsua_var.mod.id, NULL);
4215
call->xfer_sub = NULL;
4217
PJ_LOG(4,(THIS_FILE, "Xfer server subscription terminated"));
4221
pj_log_pop_indent();
4226
* Follow transfer (REFER) request.
4228
static void on_call_transferred( pjsip_inv_session *inv,
4229
pjsip_rx_data *rdata )
4232
pjsip_tx_data *tdata;
4233
pjsua_call *existing_call;
4235
const pj_str_t str_refer_to = { "Refer-To", 8};
4236
const pj_str_t str_refer_sub = { "Refer-Sub", 9 };
4237
const pj_str_t str_ref_by = { "Referred-By", 11 };
4238
pjsip_generic_string_hdr *refer_to;
4239
pjsip_generic_string_hdr *refer_sub;
4240
pjsip_hdr *ref_by_hdr;
4241
pj_bool_t no_refer_sub = PJ_FALSE;
4243
pjsua_msg_data msg_data;
4245
pjsip_status_code code;
4247
pjsua_call_setting call_opt;
4249
pj_log_push_indent();
4251
existing_call = (pjsua_call*) inv->dlg->mod_data[pjsua_var.mod.id];
4253
/* Find the Refer-To header */
4254
refer_to = (pjsip_generic_string_hdr*)
4255
pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &str_refer_to, NULL);
4257
if (refer_to == NULL) {
4259
* No Refer-To header!
4261
PJ_LOG(4,(THIS_FILE, "Received REFER without Refer-To header!"));
4262
pjsip_dlg_respond( inv->dlg, rdata, 400, NULL, NULL, NULL);
4266
/* Find optional Refer-Sub header */
4267
refer_sub = (pjsip_generic_string_hdr*)
4268
pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &str_refer_sub, NULL);
4271
if (!pj_strnicmp2(&refer_sub->hvalue, "true", 4)==0)
4272
no_refer_sub = PJ_TRUE;
4275
/* Find optional Referred-By header (to be copied onto outgoing INVITE
4278
ref_by_hdr = (pjsip_hdr*)
4279
pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &str_ref_by,
4282
/* Notify callback */
4283
code = PJSIP_SC_ACCEPTED;
4284
if (pjsua_var.ua_cfg.cb.on_call_transfer_request) {
4285
(*pjsua_var.ua_cfg.cb.on_call_transfer_request)(existing_call->index,
4290
call_opt = existing_call->opt;
4291
if (pjsua_var.ua_cfg.cb.on_call_transfer_request2) {
4292
(*pjsua_var.ua_cfg.cb.on_call_transfer_request2)(existing_call->index,
4299
code = PJSIP_SC_ACCEPTED;
4301
/* Application rejects call transfer request */
4302
pjsip_dlg_respond( inv->dlg, rdata, code, NULL, NULL, NULL);
4306
PJ_LOG(3,(THIS_FILE, "Call to %.*s is being transferred to %.*s",
4307
(int)inv->dlg->remote.info_str.slen,
4308
inv->dlg->remote.info_str.ptr,
4309
(int)refer_to->hvalue.slen,
4310
refer_to->hvalue.ptr));
4314
* Always answer with 2xx.
4316
pjsip_tx_data *tdata;
4317
const pj_str_t str_false = { "false", 5};
4320
status = pjsip_dlg_create_response(inv->dlg, rdata, code, NULL,
4322
if (status != PJ_SUCCESS) {
4323
pjsua_perror(THIS_FILE, "Unable to create 2xx response to REFER",
4328
/* Add Refer-Sub header */
4330
pjsip_generic_string_hdr_create(tdata->pool, &str_refer_sub,
4332
pjsip_msg_add_hdr(tdata->msg, hdr);
4336
status = pjsip_dlg_send_response(inv->dlg, pjsip_rdata_get_tsx(rdata),
4338
if (status != PJ_SUCCESS) {
4339
pjsua_perror(THIS_FILE, "Unable to create 2xx response to REFER",
4344
/* Don't have subscription */
4348
struct pjsip_evsub_user xfer_cb;
4352
pj_bzero(&xfer_cb, sizeof(xfer_cb));
4353
xfer_cb.on_evsub_state = &xfer_server_on_evsub_state;
4355
/* Init additional header list to be sent with REFER response */
4356
pj_list_init(&hdr_list);
4358
/* Create transferee event subscription */
4359
status = pjsip_xfer_create_uas( inv->dlg, &xfer_cb, rdata, &sub);
4360
if (status != PJ_SUCCESS) {
4361
pjsua_perror(THIS_FILE, "Unable to create xfer uas", status);
4362
pjsip_dlg_respond( inv->dlg, rdata, 500, NULL, NULL, NULL);
4366
/* If there's Refer-Sub header and the value is "true", send back
4367
* Refer-Sub in the response with value "true" too.
4370
const pj_str_t str_true = { "true", 4 };
4374
pjsip_generic_string_hdr_create(inv->dlg->pool,
4377
pj_list_push_back(&hdr_list, hdr);
4381
/* Accept the REFER request, send 2xx. */
4382
pjsip_xfer_accept(sub, rdata, code, &hdr_list);
4384
/* Create initial NOTIFY request */
4385
status = pjsip_xfer_notify( sub, PJSIP_EVSUB_STATE_ACTIVE,
4387
if (status != PJ_SUCCESS) {
4388
pjsua_perror(THIS_FILE, "Unable to create NOTIFY to REFER",
4393
/* Send initial NOTIFY request */
4394
status = pjsip_xfer_send_request( sub, tdata);
4395
if (status != PJ_SUCCESS) {
4396
pjsua_perror(THIS_FILE, "Unable to send NOTIFY to REFER", status);
4401
/* We're cheating here.
4402
* We need to get a null terminated string from a pj_str_t.
4403
* So grab the pointer from the hvalue and NULL terminate it, knowing
4404
* that the NULL position will be occupied by a newline.
4406
uri = refer_to->hvalue.ptr;
4407
uri[refer_to->hvalue.slen] = '\0';
4410
pjsua_msg_data_init(&msg_data);
4412
/* If Referred-By header is present in the REFER request, copy this
4413
* to the outgoing INVITE request.
4415
if (ref_by_hdr != NULL) {
4416
pjsip_hdr *dup = (pjsip_hdr*)
4417
pjsip_hdr_clone(rdata->tp_info.pool, ref_by_hdr);
4418
pj_list_push_back(&msg_data.hdr_list, dup);
4421
/* Now make the outgoing call. */
4423
status = pjsua_call_make_call(existing_call->acc_id, &tmp, &call_opt,
4424
existing_call->user_data, &msg_data,
4426
if (status != PJ_SUCCESS) {
4428
/* Notify xferer about the error (if we have subscription) */
4430
status = pjsip_xfer_notify(sub, PJSIP_EVSUB_STATE_TERMINATED,
4432
if (status != PJ_SUCCESS) {
4433
pjsua_perror(THIS_FILE, "Unable to create NOTIFY to REFER",
4437
status = pjsip_xfer_send_request(sub, tdata);
4438
if (status != PJ_SUCCESS) {
4439
pjsua_perror(THIS_FILE, "Unable to send NOTIFY to REFER",
4448
/* Put the server subscription in inv_data.
4449
* Subsequent state changed in pjsua_inv_on_state_changed() will be
4450
* reported back to the server subscription.
4452
pjsua_var.calls[new_call].xfer_sub = sub;
4454
/* Put the invite_data in the subscription. */
4455
pjsip_evsub_set_mod_data(sub, pjsua_var.mod.id,
4456
&pjsua_var.calls[new_call]);
4460
pj_log_pop_indent();
4466
* This callback is called when transaction state has changed in INVITE
4467
* session. We use this to trap:
4468
* - incoming REFER request.
4469
* - incoming MESSAGE request.
4471
static void pjsua_call_on_tsx_state_changed(pjsip_inv_session *inv,
4472
pjsip_transaction *tsx,
4477
pj_log_push_indent();
4479
call = (pjsua_call*) inv->dlg->mod_data[pjsua_var.mod.id];
4484
if (call->inv == NULL) {
4485
/* Call has been disconnected. */
4489
/* https://trac.pjsip.org/repos/ticket/1452:
4490
* If a request is retried due to 401/407 challenge, don't process the
4491
* transaction first but wait until we've retried it.
4493
if (tsx->role == PJSIP_ROLE_UAC &&
4494
(tsx->status_code==401 || tsx->status_code==407) &&
4495
tsx->last_tx && tsx->last_tx->auth_retry)
4500
/* Notify application callback first */
4501
if (pjsua_var.ua_cfg.cb.on_call_tsx_state) {
4502
(*pjsua_var.ua_cfg.cb.on_call_tsx_state)(call->index, tsx, e);
4505
if (tsx->role==PJSIP_ROLE_UAS &&
4506
tsx->state==PJSIP_TSX_STATE_TRYING &&
4507
pjsip_method_cmp(&tsx->method, pjsip_get_refer_method())==0)
4510
* Incoming REFER request.
4512
on_call_transferred(call->inv, e->body.tsx_state.src.rdata);
4515
else if (tsx->role==PJSIP_ROLE_UAS &&
4516
tsx->state==PJSIP_TSX_STATE_TRYING &&
4517
pjsip_method_cmp(&tsx->method, &pjsip_message_method)==0)
4520
* Incoming MESSAGE request!
4522
pjsip_rx_data *rdata;
4523
pjsip_accept_hdr *accept_hdr;
4525
rdata = e->body.tsx_state.src.rdata;
4527
/* Request MUST have message body, with Content-Type equal to
4530
if (pjsua_im_accept_pager(rdata, &accept_hdr) == PJ_FALSE) {
4534
pj_list_init(&hdr_list);
4535
pj_list_push_back(&hdr_list, accept_hdr);
4537
pjsip_dlg_respond( inv->dlg, rdata, PJSIP_SC_NOT_ACCEPTABLE_HERE,
4538
NULL, &hdr_list, NULL );
4542
/* Respond with 200 first, so that remote doesn't retransmit in case
4543
* the UI takes too long to process the message.
4545
pjsip_dlg_respond( inv->dlg, rdata, 200, NULL, NULL, NULL);
4547
/* Process MESSAGE request */
4548
pjsua_im_process_pager(call->index, &inv->dlg->remote.info_str,
4549
&inv->dlg->local.info_str, rdata);
4552
else if (tsx->role == PJSIP_ROLE_UAC &&
4553
pjsip_method_cmp(&tsx->method, &pjsip_message_method)==0)
4555
/* Handle outgoing pager status */
4556
if (tsx->status_code >= 200) {
4557
pjsua_im_data *im_data;
4559
im_data = (pjsua_im_data*) tsx->mod_data[pjsua_var.mod.id];
4560
/* im_data can be NULL if this is typing indication */
4562
if (im_data && pjsua_var.ua_cfg.cb.on_pager_status) {
4563
pjsua_var.ua_cfg.cb.on_pager_status(im_data->call_id,
4572
} else if (tsx->role == PJSIP_ROLE_UAC &&
4573
tsx->last_tx == (pjsip_tx_data*)call->hold_msg &&
4574
tsx->state >= PJSIP_TSX_STATE_COMPLETED)
4576
/* Monitor the status of call hold request */
4577
call->hold_msg = NULL;
4578
if (tsx->status_code/100 != 2) {
4579
/* Outgoing call hold failed */
4580
call->local_hold = PJ_FALSE;
4581
PJ_LOG(3,(THIS_FILE, "Error putting call %d on hold (reason=%d)",
4582
call->index, tsx->status_code));
4584
} else if (tsx->role == PJSIP_ROLE_UAC &&
4585
(call->opt.flag & PJSUA_CALL_UNHOLD) &&
4586
tsx->state >= PJSIP_TSX_STATE_COMPLETED)
4588
/* Monitor the status of call unhold request */
4589
if (tsx->status_code/100 != 2 &&
4590
(tsx->status_code!=401 && tsx->status_code!=407))
4592
/* Call unhold failed */
4593
call->opt.flag &= ~PJSUA_CALL_UNHOLD;
4594
call->local_hold = PJ_TRUE;
4595
PJ_LOG(3,(THIS_FILE, "Error releasing hold on call %d (reason=%d)",
4596
call->index, tsx->status_code));
4598
} else if (tsx->role==PJSIP_ROLE_UAS &&
4599
tsx->state==PJSIP_TSX_STATE_TRYING &&
4600
pjsip_method_cmp(&tsx->method, &pjsip_info_method)==0)
4603
* Incoming INFO request for media control.
4605
const pj_str_t STR_APPLICATION = { "application", 11};
4606
const pj_str_t STR_MEDIA_CONTROL_XML = { "media_control+xml", 17 };
4607
pjsip_rx_data *rdata = e->body.tsx_state.src.rdata;
4608
pjsip_msg_body *body = rdata->msg_info.msg->body;
4610
if (body && body->len &&
4611
pj_stricmp(&body->content_type.type, &STR_APPLICATION)==0 &&
4612
pj_stricmp(&body->content_type.subtype, &STR_MEDIA_CONTROL_XML)==0)
4614
pjsip_tx_data *tdata;
4615
pj_str_t control_st;
4618
/* Apply and answer the INFO request */
4619
pj_strset(&control_st, (char*)body->data, body->len);
4620
status = pjsua_media_apply_xml_control(call->index, &control_st);
4621
if (status == PJ_SUCCESS) {
4622
status = pjsip_endpt_create_response(tsx->endpt, rdata,
4624
if (status == PJ_SUCCESS)
4625
status = pjsip_tsx_send_msg(tsx, tdata);
4627
status = pjsip_endpt_create_response(tsx->endpt, rdata,
4629
if (status == PJ_SUCCESS)
4630
status = pjsip_tsx_send_msg(tsx, tdata);
4636
pj_log_pop_indent();
4640
/* Redirection handler */
4641
static pjsip_redirect_op pjsua_call_on_redirected(pjsip_inv_session *inv,
4642
const pjsip_uri *target,
4643
const pjsip_event *e)
4645
pjsua_call *call = (pjsua_call*) inv->dlg->mod_data[pjsua_var.mod.id];
4646
pjsip_redirect_op op;
4648
pj_log_push_indent();
4650
if (pjsua_var.ua_cfg.cb.on_call_redirected) {
4651
op = (*pjsua_var.ua_cfg.cb.on_call_redirected)(call->index,
4654
PJ_LOG(4,(THIS_FILE, "Unhandled redirection for call %d "
4655
"(callback not implemented by application). Disconnecting "
4658
op = PJSIP_REDIRECT_STOP;
4661
pj_log_pop_indent();