~ubuntu-branches/ubuntu/wily/sflphone/wily

« back to all changes in this revision

Viewing changes to daemon/libs/pjproject-2.1.0/pjsip/src/pjsua-lib/pjsua_call.c

  • Committer: Package Import Robot
  • Author(s): Mark Purcell
  • Date: 2014-01-28 18:23:36 UTC
  • mfrom: (1.1.11)
  • mto: This revision was merged to the branch mainline in revision 24.
  • Revision ID: package-import@ubuntu.com-20140128182336-3xenud1kbnwmf3mz
* New upstream release 
  - Fixes "New Upstream Release" (Closes: #735846)
  - Fixes "Ringtone does not stop" (Closes: #727164)
  - Fixes "[sflphone-kde] crash on startup" (Closes: #718178)
  - Fixes "sflphone GUI crashes when call is hung up" (Closes: #736583)
* Build-Depends: ensure GnuTLS 2.6
  - libucommon-dev (>= 6.0.7-1.1), libccrtp-dev (>= 2.0.6-3)
  - Fixes "FTBFS Build-Depends libgnutls{26,28}-dev" (Closes: #722040)
* Fix "boost 1.49 is going away" unversioned Build-Depends: (Closes: #736746)
* Add Build-Depends: libsndfile-dev, nepomuk-core-dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Id: pjsua_call.c 4411 2013-03-04 04:34:38Z nanang $ */
 
2
/* 
 
3
 * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
 
4
 * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
 
5
 *
 
6
 * This program is free software; you can redistribute it and/or modify
 
7
 * it under the terms of the GNU General Public License as published by
 
8
 * the Free Software Foundation; either version 2 of the License, or
 
9
 * (at your option) any later version.
 
10
 *
 
11
 * This program is distributed in the hope that it will be useful,
 
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
 * GNU General Public License for more details.
 
15
 *
 
16
 * You should have received a copy of the GNU General Public License
 
17
 * along with this program; if not, write to the Free Software
 
18
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 
19
 */
 
20
#include <pjsua-lib/pjsua.h>
 
21
#include <pjsua-lib/pjsua_internal.h>
 
22
 
 
23
 
 
24
#define THIS_FILE               "pjsua_call.c"
 
25
 
 
26
 
 
27
/* Retry interval of sending re-INVITE for locking a codec when remote
 
28
 * SDP answer contains multiple codec, in milliseconds.
 
29
 */
 
30
#define LOCK_CODEC_RETRY_INTERVAL   200
 
31
 
 
32
/*
 
33
 * Max UPDATE/re-INVITE retry to lock codec
 
34
 */
 
35
#define LOCK_CODEC_MAX_RETRY         5
 
36
 
 
37
 
 
38
/*
 
39
 * The INFO method.
 
40
 */
 
41
const pjsip_method pjsip_info_method = 
 
42
{
 
43
    PJSIP_OTHER_METHOD,
 
44
    { "INFO", 4 }
 
45
};
 
46
 
 
47
 
 
48
/* This callback receives notification from invite session when the
 
49
 * session state has changed.
 
50
 */
 
51
static void pjsua_call_on_state_changed(pjsip_inv_session *inv, 
 
52
                                        pjsip_event *e);
 
53
 
 
54
/* This callback is called by invite session framework when UAC session
 
55
 * has forked.
 
56
 */
 
57
static void pjsua_call_on_forked( pjsip_inv_session *inv, 
 
58
                                  pjsip_event *e);
 
59
 
 
60
/*
 
61
 * Callback to be called when SDP offer/answer negotiation has just completed
 
62
 * in the session. This function will start/update media if negotiation
 
63
 * has succeeded.
 
64
 */
 
65
static void pjsua_call_on_media_update(pjsip_inv_session *inv,
 
66
                                       pj_status_t status);
 
67
 
 
68
/*
 
69
 * Called when session received new offer.
 
70
 */
 
71
static void pjsua_call_on_rx_offer(pjsip_inv_session *inv,
 
72
                                   const pjmedia_sdp_session *offer);
 
73
 
 
74
/*
 
75
 * Called to generate new offer.
 
76
 */
 
77
static void pjsua_call_on_create_offer(pjsip_inv_session *inv,
 
78
                                       pjmedia_sdp_session **offer);
 
79
 
 
80
/*
 
81
 * This callback is called when transaction state has changed in INVITE
 
82
 * session. We use this to trap:
 
83
 *  - incoming REFER request.
 
84
 *  - incoming MESSAGE request.
 
85
 */
 
86
static void pjsua_call_on_tsx_state_changed(pjsip_inv_session *inv,
 
87
                                            pjsip_transaction *tsx,
 
88
                                            pjsip_event *e);
 
89
 
 
90
/*
 
91
 * Redirection handler.
 
92
 */
 
93
static pjsip_redirect_op pjsua_call_on_redirected(pjsip_inv_session *inv,
 
94
                                                  const pjsip_uri *target,
 
95
                                                  const pjsip_event *e);
 
96
 
 
97
 
 
98
/* Create SDP for call hold. */
 
99
static pj_status_t create_sdp_of_call_hold(pjsua_call *call,
 
100
                                           pjmedia_sdp_session **p_sdp);
 
101
 
 
102
/*
 
103
 * Callback called by event framework when the xfer subscription state
 
104
 * has changed.
 
105
 */
 
106
static void xfer_client_on_evsub_state( pjsip_evsub *sub, pjsip_event *event);
 
107
static void xfer_server_on_evsub_state( pjsip_evsub *sub, pjsip_event *event);
 
108
 
 
109
/* Timer callback to send re-INVITE/UPDATE to lock codec or ICE update */
 
110
static void reinv_timer_cb(pj_timer_heap_t *th, pj_timer_entry *entry);
 
111
 
 
112
/* Check and send reinvite for lock codec and ICE update */
 
113
static pj_status_t process_pending_reinvite(pjsua_call *call);
 
114
 
 
115
/*
 
116
 * Reset call descriptor.
 
117
 */
 
118
static void reset_call(pjsua_call_id id)
 
119
{
 
120
    pjsua_call *call = &pjsua_var.calls[id];
 
121
    unsigned i;
 
122
 
 
123
    pj_bzero(call, sizeof(*call));
 
124
    call->index = id;
 
125
    call->last_text.ptr = call->last_text_buf_;
 
126
    for (i=0; i<PJ_ARRAY_SIZE(call->media); ++i) {
 
127
        pjsua_call_media *call_med = &call->media[i];
 
128
        call_med->ssrc = pj_rand();
 
129
        call_med->strm.a.conf_slot = PJSUA_INVALID_ID;
 
130
        call_med->strm.v.cap_win_id = PJSUA_INVALID_ID;
 
131
        call_med->strm.v.rdr_win_id = PJSUA_INVALID_ID;
 
132
        call_med->call = call;
 
133
        call_med->idx = i;
 
134
        call_med->tp_auto_del = PJ_TRUE;
 
135
    }
 
136
    pjsua_call_setting_default(&call->opt);
 
137
    pj_timer_entry_init(&call->reinv_timer, PJ_FALSE,
 
138
                        (void*)(pj_size_t)id, &reinv_timer_cb);
 
139
}
 
140
 
 
141
 
 
142
/*
 
143
 * Init call subsystem.
 
144
 */
 
145
pj_status_t pjsua_call_subsys_init(const pjsua_config *cfg)
 
146
{
 
147
    pjsip_inv_callback inv_cb;
 
148
    unsigned i;
 
149
    const pj_str_t str_norefersub = { "norefersub", 10 };
 
150
    pj_status_t status;
 
151
 
 
152
    /* Init calls array. */
 
153
    for (i=0; i<PJ_ARRAY_SIZE(pjsua_var.calls); ++i)
 
154
        reset_call(i);
 
155
 
 
156
    /* Copy config */
 
157
    pjsua_config_dup(pjsua_var.pool, &pjsua_var.ua_cfg, cfg);
 
158
 
 
159
    /* Verify settings */
 
160
    if (pjsua_var.ua_cfg.max_calls >= PJSUA_MAX_CALLS) {
 
161
        pjsua_var.ua_cfg.max_calls = PJSUA_MAX_CALLS;
 
162
    }
 
163
 
 
164
    /* Check the route URI's and force loose route if required */
 
165
    for (i=0; i<pjsua_var.ua_cfg.outbound_proxy_cnt; ++i) {
 
166
        status = normalize_route_uri(pjsua_var.pool, 
 
167
                                     &pjsua_var.ua_cfg.outbound_proxy[i]);
 
168
        if (status != PJ_SUCCESS)
 
169
            return status;
 
170
    }
 
171
 
 
172
    /* Initialize invite session callback. */
 
173
    pj_bzero(&inv_cb, sizeof(inv_cb));
 
174
    inv_cb.on_state_changed = &pjsua_call_on_state_changed;
 
175
    inv_cb.on_new_session = &pjsua_call_on_forked;
 
176
    inv_cb.on_media_update = &pjsua_call_on_media_update;
 
177
    inv_cb.on_rx_offer = &pjsua_call_on_rx_offer;
 
178
    inv_cb.on_create_offer = &pjsua_call_on_create_offer;
 
179
    inv_cb.on_tsx_state_changed = &pjsua_call_on_tsx_state_changed;
 
180
    inv_cb.on_redirected = &pjsua_call_on_redirected;
 
181
 
 
182
    /* Initialize invite session module: */
 
183
    status = pjsip_inv_usage_init(pjsua_var.endpt, &inv_cb);
 
184
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
 
185
 
 
186
    /* Add "norefersub" in Supported header */
 
187
    pjsip_endpt_add_capability(pjsua_var.endpt, NULL, PJSIP_H_SUPPORTED,
 
188
                               NULL, 1, &str_norefersub);
 
189
 
 
190
    /* Add "INFO" in Allow header, for DTMF and video key frame request. */
 
191
    pjsip_endpt_add_capability(pjsua_var.endpt, NULL, PJSIP_H_ALLOW,
 
192
                               NULL, 1, &pjsip_info_method.name);
 
193
 
 
194
    return status;
 
195
}
 
196
 
 
197
 
 
198
/*
 
199
 * Start call subsystem.
 
200
 */
 
201
pj_status_t pjsua_call_subsys_start(void)
 
202
{
 
203
    /* Nothing to do */
 
204
    return PJ_SUCCESS;
 
205
}
 
206
 
 
207
 
 
208
/*
 
209
 * Get maximum number of calls configured in pjsua.
 
210
 */
 
211
PJ_DEF(unsigned) pjsua_call_get_max_count(void)
 
212
{
 
213
    return pjsua_var.ua_cfg.max_calls;
 
214
}
 
215
 
 
216
 
 
217
/*
 
218
 * Get number of currently active calls.
 
219
 */
 
220
PJ_DEF(unsigned) pjsua_call_get_count(void)
 
221
{
 
222
    return pjsua_var.call_cnt;
 
223
}
 
224
 
 
225
 
 
226
/*
 
227
 * Enum calls.
 
228
 */
 
229
PJ_DEF(pj_status_t) pjsua_enum_calls( pjsua_call_id ids[],
 
230
                                      unsigned *count)
 
231
{
 
232
    unsigned i, c;
 
233
 
 
234
    PJ_ASSERT_RETURN(ids && *count, PJ_EINVAL);
 
235
 
 
236
    PJSUA_LOCK();
 
237
 
 
238
    for (i=0, c=0; c<*count && i<pjsua_var.ua_cfg.max_calls; ++i) {
 
239
        if (!pjsua_var.calls[i].inv)
 
240
            continue;
 
241
        ids[c] = i;
 
242
        ++c;
 
243
    }
 
244
 
 
245
    *count = c;
 
246
 
 
247
    PJSUA_UNLOCK();
 
248
 
 
249
    return PJ_SUCCESS;
 
250
}
 
251
 
 
252
 
 
253
/* Allocate one call id */
 
254
static pjsua_call_id alloc_call_id(void)
 
255
{
 
256
    pjsua_call_id cid;
 
257
 
 
258
#if 1
 
259
    /* New algorithm: round-robin */
 
260
    if (pjsua_var.next_call_id >= (int)pjsua_var.ua_cfg.max_calls || 
 
261
        pjsua_var.next_call_id < 0)
 
262
    {
 
263
        pjsua_var.next_call_id = 0;
 
264
    }
 
265
 
 
266
    for (cid=pjsua_var.next_call_id; 
 
267
         cid<(int)pjsua_var.ua_cfg.max_calls; 
 
268
         ++cid) 
 
269
    {
 
270
        if (pjsua_var.calls[cid].inv == NULL &&
 
271
            pjsua_var.calls[cid].async_call.dlg == NULL)
 
272
        {
 
273
            ++pjsua_var.next_call_id;
 
274
            return cid;
 
275
        }
 
276
    }
 
277
 
 
278
    for (cid=0; cid < pjsua_var.next_call_id; ++cid) {
 
279
        if (pjsua_var.calls[cid].inv == NULL &&
 
280
            pjsua_var.calls[cid].async_call.dlg == NULL)
 
281
        {
 
282
            ++pjsua_var.next_call_id;
 
283
            return cid;
 
284
        }
 
285
    }
 
286
 
 
287
#else
 
288
    /* Old algorithm */
 
289
    for (cid=0; cid<(int)pjsua_var.ua_cfg.max_calls; ++cid) {
 
290
        if (pjsua_var.calls[cid].inv == NULL)
 
291
            return cid;
 
292
    }
 
293
#endif
 
294
 
 
295
    return PJSUA_INVALID_ID;
 
296
}
 
297
 
 
298
/* Get signaling secure level.
 
299
 * Return:
 
300
 *  0: if signaling is not secure
 
301
 *  1: if TLS transport is used for immediate hop
 
302
 *  2: if end-to-end signaling is secure.
 
303
 */
 
304
static int get_secure_level(pjsua_acc_id acc_id, const pj_str_t *dst_uri)
 
305
{
 
306
    const pj_str_t tls = pj_str(";transport=tls");
 
307
    const pj_str_t sips = pj_str("sips:");
 
308
    pjsua_acc *acc = &pjsua_var.acc[acc_id];
 
309
 
 
310
    if (pj_stristr(dst_uri, &sips))
 
311
        return 2;
 
312
    
 
313
    if (!pj_list_empty(&acc->route_set)) {
 
314
        pjsip_route_hdr *r = acc->route_set.next;
 
315
        pjsip_uri *uri = r->name_addr.uri;
 
316
        pjsip_sip_uri *sip_uri;
 
317
        
 
318
        sip_uri = (pjsip_sip_uri*)pjsip_uri_get_uri(uri);
 
319
        if (pj_stricmp2(&sip_uri->transport_param, "tls")==0)
 
320
            return 1;
 
321
 
 
322
    } else {
 
323
        if (pj_stristr(dst_uri, &tls))
 
324
            return 1;
 
325
    }
 
326
 
 
327
    return 0;
 
328
}
 
329
 
 
330
/*
 
331
static int call_get_secure_level(pjsua_call *call)
 
332
{
 
333
    if (call->inv->dlg->secure)
 
334
        return 2;
 
335
 
 
336
    if (!pj_list_empty(&call->inv->dlg->route_set)) {
 
337
        pjsip_route_hdr *r = call->inv->dlg->route_set.next;
 
338
        pjsip_uri *uri = r->name_addr.uri;
 
339
        pjsip_sip_uri *sip_uri;
 
340
        
 
341
        sip_uri = (pjsip_sip_uri*)pjsip_uri_get_uri(uri);
 
342
        if (pj_stricmp2(&sip_uri->transport_param, "tls")==0)
 
343
            return 1;
 
344
 
 
345
    } else {
 
346
        pjsip_sip_uri *sip_uri;
 
347
 
 
348
        if (PJSIP_URI_SCHEME_IS_SIPS(call->inv->dlg->target))
 
349
            return 2;
 
350
        if (!PJSIP_URI_SCHEME_IS_SIP(call->inv->dlg->target))
 
351
            return 0;
 
352
 
 
353
        sip_uri = (pjsip_sip_uri*) pjsip_uri_get_uri(call->inv->dlg->target);
 
354
        if (pj_stricmp2(&sip_uri->transport_param, "tls")==0)
 
355
            return 1;
 
356
    }
 
357
 
 
358
    return 0;
 
359
}
 
360
*/
 
361
 
 
362
/* Outgoing call callback when media transport creation is completed. */
 
363
static pj_status_t
 
364
on_make_call_med_tp_complete(pjsua_call_id call_id,
 
365
                             const pjsua_med_tp_state_info *info)
 
366
{
 
367
    pjmedia_sdp_session *offer;
 
368
    pjsip_inv_session *inv = NULL;
 
369
    pjsua_call *call = &pjsua_var.calls[call_id];
 
370
    pjsua_acc *acc = &pjsua_var.acc[call->acc_id];
 
371
    pjsip_dialog *dlg = call->async_call.dlg;
 
372
    unsigned options = 0;
 
373
    pjsip_tx_data *tdata;
 
374
    pj_bool_t cb_called = PJ_FALSE;
 
375
    pj_status_t status = (info? info->status: PJ_SUCCESS);
 
376
 
 
377
    PJSUA_LOCK();
 
378
 
 
379
    /* Increment the dialog's lock otherwise when invite session creation
 
380
     * fails the dialog will be destroyed prematurely.
 
381
     */
 
382
    pjsip_dlg_inc_lock(dlg);
 
383
 
 
384
    /* Decrement dialog session. */
 
385
    pjsip_dlg_dec_session(dlg, &pjsua_var.mod);
 
386
 
 
387
    if (status != PJ_SUCCESS) {
 
388
        pj_str_t err_str;
 
389
        int title_len;
 
390
 
 
391
        call->last_code = PJSIP_SC_TEMPORARILY_UNAVAILABLE;
 
392
        pj_strcpy2(&call->last_text, "Media init error: ");
 
393
 
 
394
        title_len = call->last_text.slen;
 
395
        err_str = pj_strerror(status, call->last_text_buf_ + title_len,
 
396
                              sizeof(call->last_text_buf_) - title_len);
 
397
        call->last_text.slen += err_str.slen;
 
398
 
 
399
        pjsua_perror(THIS_FILE, "Error initializing media channel", status);
 
400
        goto on_error;
 
401
    }
 
402
 
 
403
    /* pjsua_media_channel_deinit() has been called or
 
404
     * call has been hung up.
 
405
     */
 
406
    if (call->async_call.med_ch_deinit ||
 
407
        call->async_call.call_var.out_call.hangup)
 
408
    {
 
409
        PJ_LOG(4,(THIS_FILE, "Call has been hung up or media channel has "
 
410
                             "been deinitialized"));
 
411
        goto on_error;
 
412
    }
 
413
 
 
414
    /* Create offer */
 
415
    status = pjsua_media_channel_create_sdp(call->index, dlg->pool, NULL,
 
416
                                            &offer, NULL);
 
417
    if (status != PJ_SUCCESS) {
 
418
        pjsua_perror(THIS_FILE, "Error initializing media channel", status);
 
419
        goto on_error;
 
420
    }
 
421
 
 
422
    /* Create the INVITE session: */
 
423
    options |= PJSIP_INV_SUPPORT_100REL;
 
424
    if (acc->cfg.require_100rel)
 
425
        options |= PJSIP_INV_REQUIRE_100REL;
 
426
    if (acc->cfg.use_timer != PJSUA_SIP_TIMER_INACTIVE) {
 
427
        options |= PJSIP_INV_SUPPORT_TIMER;
 
428
        if (acc->cfg.use_timer == PJSUA_SIP_TIMER_REQUIRED)
 
429
            options |= PJSIP_INV_REQUIRE_TIMER;
 
430
        else if (acc->cfg.use_timer == PJSUA_SIP_TIMER_ALWAYS)
 
431
            options |= PJSIP_INV_ALWAYS_USE_TIMER;
 
432
    }
 
433
 
 
434
    status = pjsip_inv_create_uac( dlg, offer, options, &inv);
 
435
    if (status != PJ_SUCCESS) {
 
436
        pjsua_perror(THIS_FILE, "Invite session creation failed", status);
 
437
        goto on_error;
 
438
    }
 
439
 
 
440
    /* Init Session Timers */
 
441
    status = pjsip_timer_init_session(inv, &acc->cfg.timer_setting);
 
442
    if (status != PJ_SUCCESS) {
 
443
        pjsua_perror(THIS_FILE, "Session Timer init failed", status);
 
444
        goto on_error;
 
445
    }
 
446
 
 
447
    /* Create and associate our data in the session. */
 
448
    call->inv = inv;
 
449
 
 
450
    dlg->mod_data[pjsua_var.mod.id] = call;
 
451
    inv->mod_data[pjsua_var.mod.id] = call;
 
452
 
 
453
    /* If account is locked to specific transport, then lock dialog
 
454
     * to this transport too.
 
455
     */
 
456
    if (acc->cfg.transport_id != PJSUA_INVALID_ID) {
 
457
        pjsip_tpselector tp_sel;
 
458
 
 
459
        pjsua_init_tpselector(acc->cfg.transport_id, &tp_sel);
 
460
        pjsip_dlg_set_transport(dlg, &tp_sel);
 
461
    }
 
462
 
 
463
    /* Set dialog Route-Set: */
 
464
    if (!pj_list_empty(&acc->route_set))
 
465
        pjsip_dlg_set_route_set(dlg, &acc->route_set);
 
466
 
 
467
 
 
468
    /* Set credentials: */
 
469
    if (acc->cred_cnt) {
 
470
        pjsip_auth_clt_set_credentials( &dlg->auth_sess, 
 
471
                                        acc->cred_cnt, acc->cred);
 
472
    }
 
473
 
 
474
    /* Set authentication preference */
 
475
    pjsip_auth_clt_set_prefs(&dlg->auth_sess, &acc->cfg.auth_pref);
 
476
 
 
477
    /* Create initial INVITE: */
 
478
 
 
479
    status = pjsip_inv_invite(inv, &tdata);
 
480
    if (status != PJ_SUCCESS) {
 
481
        pjsua_perror(THIS_FILE, "Unable to create initial INVITE request", 
 
482
                     status);
 
483
        goto on_error;
 
484
    }
 
485
 
 
486
 
 
487
    /* Add additional headers etc */
 
488
 
 
489
    pjsua_process_msg_data( tdata,
 
490
                            call->async_call.call_var.out_call.msg_data);
 
491
 
 
492
    /* Must increment call counter now */
 
493
    ++pjsua_var.call_cnt;
 
494
 
 
495
    /* Send initial INVITE: */
 
496
 
 
497
    status = pjsip_inv_send_msg(inv, tdata);
 
498
    if (status != PJ_SUCCESS) {
 
499
        cb_called = PJ_TRUE;
 
500
 
 
501
        /* Upon failure to send first request, the invite 
 
502
         * session would have been cleared.
 
503
         */
 
504
        inv = NULL;
 
505
        goto on_error;
 
506
    }
 
507
 
 
508
    /* Done. */
 
509
    call->med_ch_cb = NULL;
 
510
 
 
511
    pjsip_dlg_dec_lock(dlg);
 
512
    PJSUA_UNLOCK();
 
513
 
 
514
    return PJ_SUCCESS;
 
515
 
 
516
on_error:
 
517
    if (inv == NULL && call_id != -1 && !cb_called &&
 
518
        pjsua_var.ua_cfg.cb.on_call_state)
 
519
    {
 
520
        (*pjsua_var.ua_cfg.cb.on_call_state)(call_id, NULL);
 
521
    }
 
522
 
 
523
    if (dlg) {
 
524
        /* This may destroy the dialog */
 
525
        pjsip_dlg_dec_lock(dlg);
 
526
    }
 
527
 
 
528
    if (inv != NULL) {
 
529
        pjsip_inv_terminate(inv, PJSIP_SC_OK, PJ_FALSE);
 
530
    }
 
531
 
 
532
    if (call_id != -1) {
 
533
        reset_call(call_id);
 
534
        pjsua_media_channel_deinit(call_id);
 
535
    }
 
536
 
 
537
    call->med_ch_cb = NULL;
 
538
 
 
539
    pjsua_check_snd_dev_idle();
 
540
 
 
541
    PJSUA_UNLOCK();
 
542
    return status;
 
543
}
 
544
 
 
545
 
 
546
/*
 
547
 * Initialize call settings based on account ID.
 
548
 */
 
549
PJ_DEF(void) pjsua_call_setting_default(pjsua_call_setting *opt)
 
550
{
 
551
    pj_assert(opt);
 
552
 
 
553
    pj_bzero(opt, sizeof(*opt));
 
554
    opt->flag = PJSUA_CALL_INCLUDE_DISABLED_MEDIA;
 
555
    opt->aud_cnt = 1;
 
556
 
 
557
#if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0)
 
558
    opt->vid_cnt = 1;
 
559
    opt->req_keyframe_method = PJSUA_VID_REQ_KEYFRAME_SIP_INFO |
 
560
                             PJSUA_VID_REQ_KEYFRAME_RTCP_PLI;
 
561
#endif
 
562
}
 
563
 
 
564
static pj_status_t apply_call_setting(pjsua_call *call,
 
565
                                      const pjsua_call_setting *opt,
 
566
                                      const pjmedia_sdp_session *rem_sdp)
 
567
{
 
568
    pj_assert(call);
 
569
 
 
570
    if (!opt)
 
571
        return PJ_SUCCESS;
 
572
 
 
573
#if !PJMEDIA_HAS_VIDEO
 
574
    pj_assert(opt->vid_cnt == 0);
 
575
#endif
 
576
 
 
577
    call->opt = *opt;
 
578
 
 
579
    /* If call is established, reinit media channel */
 
580
    if (call->inv && call->inv->state == PJSIP_INV_STATE_CONFIRMED) {
 
581
        pjsip_role_e role = rem_sdp? PJSIP_ROLE_UAS : PJSIP_ROLE_UAC;
 
582
        pj_status_t status;
 
583
 
 
584
        status = pjsua_media_channel_init(call->index, role,
 
585
                                          call->secure_level,
 
586
                                          call->inv->pool_prov,
 
587
                                          rem_sdp, NULL,
 
588
                                          PJ_FALSE, NULL);
 
589
        if (status != PJ_SUCCESS) {
 
590
            pjsua_perror(THIS_FILE, "Error re-initializing media channel",
 
591
                         status);
 
592
            return status;
 
593
        }
 
594
    }
 
595
 
 
596
    return PJ_SUCCESS;
 
597
}
 
598
 
 
599
/*
 
600
 * Make outgoing call to the specified URI using the specified account.
 
601
 */
 
602
PJ_DEF(pj_status_t) pjsua_call_make_call(pjsua_acc_id acc_id,
 
603
                                         const pj_str_t *dest_uri,
 
604
                                         const pjsua_call_setting *opt,
 
605
                                         void *user_data,
 
606
                                         const pjsua_msg_data *msg_data,
 
607
                                         pjsua_call_id *p_call_id)
 
608
{
 
609
    pj_pool_t *tmp_pool = NULL;
 
610
    pjsip_dialog *dlg = NULL;
 
611
    pjsua_acc *acc;
 
612
    pjsua_call *call;
 
613
    int call_id = -1;
 
614
    pj_str_t contact;
 
615
    pj_status_t status;
 
616
 
 
617
 
 
618
    /* Check that account is valid */
 
619
    PJ_ASSERT_RETURN(acc_id>=0 || acc_id<(int)PJ_ARRAY_SIZE(pjsua_var.acc), 
 
620
                     PJ_EINVAL);
 
621
 
 
622
    /* Check arguments */
 
623
    PJ_ASSERT_RETURN(dest_uri, PJ_EINVAL);
 
624
 
 
625
    PJ_LOG(4,(THIS_FILE, "Making call with acc #%d to %.*s", acc_id,
 
626
              (int)dest_uri->slen, dest_uri->ptr));
 
627
 
 
628
    pj_log_push_indent();
 
629
 
 
630
    PJSUA_LOCK();
 
631
 
 
632
    /* Create sound port if none is instantiated, to check if sound device
 
633
     * can be used. But only do this with the conference bridge, as with 
 
634
     * audio switchboard (i.e. APS-Direct), we can only open the sound 
 
635
     * device once the correct format has been known
 
636
     */
 
637
    if (!pjsua_var.is_mswitch && pjsua_var.snd_port==NULL && 
 
638
        pjsua_var.null_snd==NULL && !pjsua_var.no_snd) 
 
639
    {
 
640
        status = pjsua_set_snd_dev(pjsua_var.cap_dev, pjsua_var.play_dev);
 
641
        if (status != PJ_SUCCESS)
 
642
            goto on_error;
 
643
    }
 
644
 
 
645
    acc = &pjsua_var.acc[acc_id];
 
646
    if (!acc->valid) {
 
647
        pjsua_perror(THIS_FILE, "Unable to make call because account "
 
648
                     "is not valid", PJ_EINVALIDOP);
 
649
        status = PJ_EINVALIDOP;
 
650
        goto on_error;
 
651
    }
 
652
 
 
653
    /* Find free call slot. */
 
654
    call_id = alloc_call_id();
 
655
 
 
656
    if (call_id == PJSUA_INVALID_ID) {
 
657
        pjsua_perror(THIS_FILE, "Error making call", PJ_ETOOMANY);
 
658
        status = PJ_ETOOMANY;
 
659
        goto on_error;
 
660
    }
 
661
 
 
662
    call = &pjsua_var.calls[call_id];
 
663
 
 
664
    /* Associate session with account */
 
665
    call->acc_id = acc_id;
 
666
    call->call_hold_type = acc->cfg.call_hold_type;
 
667
 
 
668
    /* Apply call setting */
 
669
    status = apply_call_setting(call, opt, NULL);
 
670
    if (status != PJ_SUCCESS) {
 
671
        pjsua_perror(THIS_FILE, "Failed to apply call setting", status);
 
672
        goto on_error;
 
673
    }
 
674
 
 
675
    /* Create temporary pool */
 
676
    tmp_pool = pjsua_pool_create("tmpcall10", 512, 256);
 
677
 
 
678
    /* Verify that destination URI is valid before calling 
 
679
     * pjsua_acc_create_uac_contact, or otherwise there  
 
680
     * a misleading "Invalid Contact URI" error will be printed
 
681
     * when pjsua_acc_create_uac_contact() fails.
 
682
     */
 
683
    if (1) {
 
684
        pjsip_uri *uri;
 
685
        pj_str_t dup;
 
686
 
 
687
        pj_strdup_with_null(tmp_pool, &dup, dest_uri);
 
688
        uri = pjsip_parse_uri(tmp_pool, dup.ptr, dup.slen, 0);
 
689
 
 
690
        if (uri == NULL) {
 
691
            pjsua_perror(THIS_FILE, "Unable to make call", 
 
692
                         PJSIP_EINVALIDREQURI);
 
693
            status = PJSIP_EINVALIDREQURI;
 
694
            goto on_error;
 
695
        }
 
696
    }
 
697
 
 
698
    /* Mark call start time. */
 
699
    pj_gettimeofday(&call->start_time);
 
700
 
 
701
    /* Reset first response time */
 
702
    call->res_time.sec = 0;
 
703
 
 
704
    /* Create suitable Contact header unless a Contact header has been
 
705
     * set in the account.
 
706
     */
 
707
    if (acc->contact.slen) {
 
708
        contact = acc->contact;
 
709
    } else {
 
710
        status = pjsua_acc_create_uac_contact(tmp_pool, &contact,
 
711
                                              acc_id, dest_uri);
 
712
        if (status != PJ_SUCCESS) {
 
713
            pjsua_perror(THIS_FILE, "Unable to generate Contact header", 
 
714
                         status);
 
715
            goto on_error;
 
716
        }
 
717
    }
 
718
 
 
719
    /* Create outgoing dialog: */
 
720
    status = pjsip_dlg_create_uac( pjsip_ua_instance(), 
 
721
                                   &acc->cfg.id, &contact,
 
722
                                   dest_uri, dest_uri, &dlg);
 
723
    if (status != PJ_SUCCESS) {
 
724
        pjsua_perror(THIS_FILE, "Dialog creation failed", status);
 
725
        goto on_error;
 
726
    }
 
727
 
 
728
    /* Increment the dialog's lock otherwise when invite session creation
 
729
     * fails the dialog will be destroyed prematurely.
 
730
     */
 
731
    pjsip_dlg_inc_lock(dlg);
 
732
 
 
733
    if (acc->cfg.allow_via_rewrite && acc->via_addr.host.slen > 0)
 
734
        pjsip_dlg_set_via_sent_by(dlg, &acc->via_addr, acc->via_tp);
 
735
 
 
736
    /* Calculate call's secure level */
 
737
    call->secure_level = get_secure_level(acc_id, dest_uri);
 
738
 
 
739
    /* Attach user data */
 
740
    call->user_data = user_data;
 
741
    
 
742
    /* Store variables required for the callback after the async
 
743
     * media transport creation is completed.
 
744
     */
 
745
    if (msg_data) {
 
746
        call->async_call.call_var.out_call.msg_data = pjsua_msg_data_clone(
 
747
                                                          dlg->pool, msg_data);
 
748
    }
 
749
    call->async_call.dlg = dlg;
 
750
 
 
751
    /* Temporarily increment dialog session. Without this, dialog will be
 
752
     * prematurely destroyed if dec_lock() is called on the dialog before
 
753
     * the invite session is created.
 
754
     */
 
755
    pjsip_dlg_inc_session(dlg, &pjsua_var.mod);
 
756
 
 
757
    /* Init media channel */
 
758
    status = pjsua_media_channel_init(call->index, PJSIP_ROLE_UAC, 
 
759
                                      call->secure_level, dlg->pool,
 
760
                                      NULL, NULL, PJ_TRUE,
 
761
                                      &on_make_call_med_tp_complete);
 
762
    if (status == PJ_SUCCESS) {
 
763
        status = on_make_call_med_tp_complete(call->index, NULL);
 
764
        if (status != PJ_SUCCESS)
 
765
            goto on_error;
 
766
    } else if (status != PJ_EPENDING) {
 
767
        pjsua_perror(THIS_FILE, "Error initializing media channel", status);
 
768
        pjsip_dlg_dec_session(dlg, &pjsua_var.mod);
 
769
        goto on_error;
 
770
    }
 
771
 
 
772
    /* Done. */
 
773
 
 
774
    if (p_call_id)
 
775
        *p_call_id = call_id;
 
776
 
 
777
    pjsip_dlg_dec_lock(dlg);
 
778
    pj_pool_release(tmp_pool);
 
779
    PJSUA_UNLOCK();
 
780
 
 
781
    pj_log_pop_indent();
 
782
 
 
783
    return PJ_SUCCESS;
 
784
 
 
785
 
 
786
on_error:
 
787
    if (dlg) {
 
788
        /* This may destroy the dialog */
 
789
        pjsip_dlg_dec_lock(dlg);
 
790
    }
 
791
 
 
792
    if (call_id != -1) {
 
793
        reset_call(call_id);
 
794
        pjsua_media_channel_deinit(call_id);
 
795
    }
 
796
 
 
797
    if (tmp_pool)
 
798
        pj_pool_release(tmp_pool);
 
799
    PJSUA_UNLOCK();
 
800
 
 
801
    pj_log_pop_indent();
 
802
    return status;
 
803
}
 
804
 
 
805
 
 
806
/* Get the NAT type information in remote's SDP */
 
807
static void update_remote_nat_type(pjsua_call *call, 
 
808
                                   const pjmedia_sdp_session *sdp)
 
809
{
 
810
    const pjmedia_sdp_attr *xnat;
 
811
 
 
812
    xnat = pjmedia_sdp_attr_find2(sdp->attr_count, sdp->attr, "X-nat", NULL);
 
813
    if (xnat) {
 
814
        call->rem_nat_type = (pj_stun_nat_type) (xnat->value.ptr[0] - '0');
 
815
    } else {
 
816
        call->rem_nat_type = PJ_STUN_NAT_TYPE_UNKNOWN;
 
817
    }
 
818
 
 
819
    PJ_LOG(5,(THIS_FILE, "Call %d: remote NAT type is %d (%s)", call->index,
 
820
              call->rem_nat_type, pj_stun_get_nat_name(call->rem_nat_type)));
 
821
}
 
822
 
 
823
 
 
824
static pj_status_t process_incoming_call_replace(pjsua_call *call,
 
825
                                                 pjsip_dialog *replaced_dlg)
 
826
{
 
827
    pjsip_inv_session *replaced_inv;
 
828
    struct pjsua_call *replaced_call;
 
829
    pjsip_tx_data *tdata = NULL;
 
830
    pj_status_t status = PJ_SUCCESS;
 
831
 
 
832
    /* Get the invite session in the dialog */
 
833
    replaced_inv = pjsip_dlg_get_inv_session(replaced_dlg);
 
834
 
 
835
    /* Get the replaced call instance */
 
836
    replaced_call = (pjsua_call*) replaced_dlg->mod_data[pjsua_var.mod.id];
 
837
 
 
838
    /* Notify application */
 
839
    if (pjsua_var.ua_cfg.cb.on_call_replaced)
 
840
        pjsua_var.ua_cfg.cb.on_call_replaced(replaced_call->index,
 
841
                                             call->index);
 
842
 
 
843
    if (replaced_call->inv->state <= PJSIP_INV_STATE_EARLY &&
 
844
        replaced_call->inv->role != PJSIP_ROLE_UAC)
 
845
    {
 
846
        if (replaced_call->last_code > 100 && replaced_call->last_code < 200)
 
847
        {
 
848
            pjsip_status_code code = replaced_call->last_code;
 
849
            pj_str_t *text = &replaced_call->last_text;
 
850
 
 
851
            PJ_LOG(4,(THIS_FILE, "Answering replacement call %d with %d/%.*s",
 
852
                                 call->index, code, text->slen, text->ptr));
 
853
 
 
854
            /* Answer the new call with last response in the replaced call */
 
855
            status = pjsip_inv_answer(call->inv, code, text, NULL, &tdata);
 
856
        }
 
857
    } else {
 
858
        PJ_LOG(4,(THIS_FILE, "Answering replacement call %d with 200/OK",
 
859
                             call->index));
 
860
 
 
861
        /* Answer the new call with 200 response */
 
862
        status = pjsip_inv_answer(call->inv, 200, NULL, NULL, &tdata);
 
863
    }
 
864
 
 
865
    if (status == PJ_SUCCESS && tdata)
 
866
        status = pjsip_inv_send_msg(call->inv, tdata);
 
867
 
 
868
    if (status != PJ_SUCCESS)
 
869
        pjsua_perror(THIS_FILE, "Error answering session", status);
 
870
 
 
871
    /* Note that inv may be invalid if 200/OK has caused error in
 
872
     * starting the media.
 
873
     */
 
874
 
 
875
    PJ_LOG(4,(THIS_FILE, "Disconnecting replaced call %d",
 
876
                         replaced_call->index));
 
877
 
 
878
    /* Disconnect replaced invite session */
 
879
    status = pjsip_inv_end_session(replaced_inv, PJSIP_SC_GONE, NULL,
 
880
                                   &tdata);
 
881
    if (status == PJ_SUCCESS && tdata)
 
882
        status = pjsip_inv_send_msg(replaced_inv, tdata);
 
883
 
 
884
    if (status != PJ_SUCCESS)
 
885
        pjsua_perror(THIS_FILE, "Error terminating session", status);
 
886
 
 
887
    return status;
 
888
}
 
889
 
 
890
 
 
891
static void process_pending_call_answer(pjsua_call *call)
 
892
{
 
893
    struct call_answer *answer, *next;
 
894
    
 
895
    answer = call->async_call.call_var.inc_call.answers.next;
 
896
    while (answer != &call->async_call.call_var.inc_call.answers) {
 
897
        next = answer->next;
 
898
        pjsua_call_answer2(call->index, answer->opt, answer->code,
 
899
                           answer->reason, answer->msg_data);
 
900
        
 
901
        /* Call might have been disconnected if application is answering
 
902
         * with 200/OK and the media failed to start.
 
903
         * See pjsua_call_answer() below.
 
904
         */
 
905
        if (!call->inv || !call->inv->pool_prov)
 
906
            break;
 
907
 
 
908
        pj_list_erase(answer);
 
909
        answer = next;
 
910
    }
 
911
}
 
912
 
 
913
 
 
914
/* Incoming call callback when media transport creation is completed. */
 
915
static pj_status_t
 
916
on_incoming_call_med_tp_complete(pjsua_call_id call_id,
 
917
                                 const pjsua_med_tp_state_info *info)
 
918
{
 
919
    pjsua_call *call = &pjsua_var.calls[call_id];
 
920
    const pjmedia_sdp_session *offer=NULL;
 
921
    pjmedia_sdp_session *answer;
 
922
    pjsip_tx_data *response = NULL;
 
923
    unsigned options = 0;
 
924
    int sip_err_code = (info? info->sip_err_code: 0);
 
925
    pj_status_t status = (info? info->status: PJ_SUCCESS);
 
926
 
 
927
    PJSUA_LOCK();
 
928
 
 
929
    if (status != PJ_SUCCESS) {
 
930
        pjsua_perror(THIS_FILE, "Error initializing media channel", status);
 
931
        goto on_return;
 
932
    }
 
933
 
 
934
    /* pjsua_media_channel_deinit() has been called. */
 
935
    if (call->async_call.med_ch_deinit) {
 
936
        pjsua_media_channel_deinit(call->index);
 
937
        call->med_ch_cb = NULL;
 
938
        PJSUA_UNLOCK();
 
939
        return PJ_SUCCESS;
 
940
    }
 
941
 
 
942
    /* Get remote SDP offer (if any). */
 
943
    if (call->inv->neg)
 
944
        pjmedia_sdp_neg_get_neg_remote(call->inv->neg, &offer);
 
945
 
 
946
    status = pjsua_media_channel_create_sdp(call_id,
 
947
                                            call->async_call.dlg->pool, 
 
948
                                            offer, &answer, &sip_err_code);
 
949
    if (status != PJ_SUCCESS) {
 
950
        pjsua_perror(THIS_FILE, "Error creating SDP answer", status);
 
951
        goto on_return;
 
952
    }
 
953
 
 
954
    status = pjsip_inv_set_local_sdp(call->inv, answer);
 
955
    if (status != PJ_SUCCESS) {
 
956
        pjsua_perror(THIS_FILE, "Error setting local SDP", status);
 
957
        sip_err_code = PJSIP_SC_NOT_ACCEPTABLE_HERE;
 
958
        goto on_return;
 
959
    }
 
960
 
 
961
    /* Verify that we can handle the request. */
 
962
    status = pjsip_inv_verify_request3(NULL,
 
963
                                       call->inv->pool_prov, &options, offer,
 
964
                                       answer, NULL, pjsua_var.endpt, &response);
 
965
    if (status != PJ_SUCCESS) {
 
966
        /*
 
967
         * No we can't handle the incoming INVITE request.
 
968
         */
 
969
        sip_err_code = PJSIP_ERRNO_TO_SIP_STATUS(status);
 
970
        goto on_return;
 
971
    } 
 
972
 
 
973
on_return:
 
974
    if (status != PJ_SUCCESS) {
 
975
        /* If the callback is called from pjsua_call_on_incoming(), the
 
976
         * invite's state is PJSIP_INV_STATE_NULL, so the invite session
 
977
         * will be terminated later, otherwise we end the session here.
 
978
         */
 
979
        if (call->inv->state > PJSIP_INV_STATE_NULL) {
 
980
            pjsip_tx_data *tdata;
 
981
            pj_status_t status_;
 
982
 
 
983
            status_ = pjsip_inv_end_session(call->inv, sip_err_code, NULL,
 
984
                                            &tdata);
 
985
            if (status_ == PJ_SUCCESS && tdata)
 
986
                status_ = pjsip_inv_send_msg(call->inv, tdata);
 
987
        }
 
988
 
 
989
        pjsua_media_channel_deinit(call->index);
 
990
    }
 
991
 
 
992
    /* Set the callback to NULL to indicate that the async operation
 
993
     * has completed.
 
994
     */
 
995
    call->med_ch_cb = NULL;
 
996
 
 
997
    /* Finish any pending process */
 
998
    if (status == PJ_SUCCESS) {
 
999
        if (call->async_call.call_var.inc_call.replaced_dlg) {
 
1000
            /* Process pending call replace */
 
1001
            pjsip_dialog *replaced_dlg = 
 
1002
                        call->async_call.call_var.inc_call.replaced_dlg;
 
1003
            process_incoming_call_replace(call, replaced_dlg);
 
1004
        } else {
 
1005
            /* Process pending call answers */
 
1006
            process_pending_call_answer(call);
 
1007
        }
 
1008
    }
 
1009
 
 
1010
    PJSUA_UNLOCK();
 
1011
    return status;
 
1012
}
 
1013
 
 
1014
 
 
1015
/**
 
1016
 * Handle incoming INVITE request.
 
1017
 * Called by pjsua_core.c
 
1018
 */
 
1019
pj_bool_t pjsua_call_on_incoming(pjsip_rx_data *rdata)
 
1020
{
 
1021
    pj_str_t contact;
 
1022
    pjsip_dialog *dlg = pjsip_rdata_get_dlg(rdata);
 
1023
    pjsip_dialog *replaced_dlg = NULL;
 
1024
    pjsip_transaction *tsx = pjsip_rdata_get_tsx(rdata);
 
1025
    pjsip_msg *msg = rdata->msg_info.msg;
 
1026
    pjsip_tx_data *response = NULL;
 
1027
    unsigned options = 0;
 
1028
    pjsip_inv_session *inv = NULL;
 
1029
    int acc_id;
 
1030
    pjsua_call *call;
 
1031
    int call_id = -1;
 
1032
    int sip_err_code = PJSIP_SC_INTERNAL_SERVER_ERROR;
 
1033
    pjmedia_sdp_session *offer=NULL;
 
1034
    pj_status_t status;
 
1035
 
 
1036
    /* Don't want to handle anything but INVITE */
 
1037
    if (msg->line.req.method.id != PJSIP_INVITE_METHOD)
 
1038
        return PJ_FALSE;
 
1039
 
 
1040
    /* Don't want to handle anything that's already associated with
 
1041
     * existing dialog or transaction.
 
1042
     */
 
1043
    if (dlg || tsx)
 
1044
        return PJ_FALSE;
 
1045
 
 
1046
    /* Don't want to accept the call if shutdown is in progress */
 
1047
    if (pjsua_var.thread_quit_flag) {
 
1048
        pjsip_endpt_respond_stateless(pjsua_var.endpt, rdata, 
 
1049
                                      PJSIP_SC_TEMPORARILY_UNAVAILABLE, NULL,
 
1050
                                      NULL, NULL);
 
1051
        return PJ_TRUE;
 
1052
    }
 
1053
 
 
1054
    PJ_LOG(4,(THIS_FILE, "Incoming %s", rdata->msg_info.info));
 
1055
    pj_log_push_indent();
 
1056
 
 
1057
    PJSUA_LOCK();
 
1058
 
 
1059
    /* Find free call slot. */
 
1060
    call_id = alloc_call_id();
 
1061
 
 
1062
    if (call_id == PJSUA_INVALID_ID) {
 
1063
        pjsip_endpt_respond_stateless(pjsua_var.endpt, rdata, 
 
1064
                                      PJSIP_SC_BUSY_HERE, NULL,
 
1065
                                      NULL, NULL);
 
1066
        PJ_LOG(2,(THIS_FILE, 
 
1067
                  "Unable to accept incoming call (too many calls)"));
 
1068
        goto on_return;
 
1069
    }
 
1070
 
 
1071
    /* Clear call descriptor */
 
1072
    reset_call(call_id);
 
1073
 
 
1074
    call = &pjsua_var.calls[call_id];
 
1075
 
 
1076
    /* Mark call start time. */
 
1077
    pj_gettimeofday(&call->start_time);
 
1078
 
 
1079
    /* Check INVITE request for Replaces header. If Replaces header is
 
1080
     * present, the function will make sure that we can handle the request.
 
1081
     */
 
1082
    status = pjsip_replaces_verify_request(rdata, &replaced_dlg, PJ_FALSE,
 
1083
                                           &response);
 
1084
    if (status != PJ_SUCCESS) {
 
1085
        /*
 
1086
         * Something wrong with the Replaces header.
 
1087
         */
 
1088
        if (response) {
 
1089
            pjsip_response_addr res_addr;
 
1090
 
 
1091
            pjsip_get_response_addr(response->pool, rdata, &res_addr);
 
1092
            pjsip_endpt_send_response(pjsua_var.endpt, &res_addr, response, 
 
1093
                                      NULL, NULL);
 
1094
 
 
1095
        } else {
 
1096
 
 
1097
            /* Respond with 500 (Internal Server Error) */
 
1098
            pjsip_endpt_respond_stateless(pjsua_var.endpt, rdata, 500, NULL,
 
1099
                                          NULL, NULL);
 
1100
        }
 
1101
 
 
1102
        goto on_return;
 
1103
    }
 
1104
 
 
1105
    /* If this INVITE request contains Replaces header, notify application
 
1106
     * about the request so that application can do subsequent checking
 
1107
     * if it wants to.
 
1108
     */
 
1109
    if (replaced_dlg != NULL &&
 
1110
        (pjsua_var.ua_cfg.cb.on_call_replace_request ||
 
1111
         pjsua_var.ua_cfg.cb.on_call_replace_request2))
 
1112
    {
 
1113
        pjsua_call *replaced_call;
 
1114
        int st_code = 200;
 
1115
        pj_str_t st_text = { "OK", 2 };
 
1116
 
 
1117
        /* Get the replaced call instance */
 
1118
        replaced_call = (pjsua_call*) replaced_dlg->mod_data[pjsua_var.mod.id];
 
1119
 
 
1120
        /* Copy call setting from the replaced call */
 
1121
        call->opt = replaced_call->opt;
 
1122
 
 
1123
        /* Notify application */
 
1124
        if (pjsua_var.ua_cfg.cb.on_call_replace_request) {
 
1125
            pjsua_var.ua_cfg.cb.on_call_replace_request(replaced_call->index,
 
1126
                                                        rdata,
 
1127
                                                        &st_code, &st_text);
 
1128
        }
 
1129
 
 
1130
        if (pjsua_var.ua_cfg.cb.on_call_replace_request2) {
 
1131
            pjsua_var.ua_cfg.cb.on_call_replace_request2(replaced_call->index,
 
1132
                                                         rdata,
 
1133
                                                         &st_code, &st_text,
 
1134
                                                         &call->opt);
 
1135
        }
 
1136
 
 
1137
        /* Must specify final response */
 
1138
        PJ_ASSERT_ON_FAIL(st_code >= 200, st_code = 200);
 
1139
 
 
1140
        /* Check if application rejects this request. */
 
1141
        if (st_code >= 300) {
 
1142
 
 
1143
            if (st_text.slen == 2)
 
1144
                st_text = *pjsip_get_status_text(st_code);
 
1145
 
 
1146
            pjsip_endpt_respond(pjsua_var.endpt, NULL, rdata, 
 
1147
                                st_code, &st_text, NULL, NULL, NULL);
 
1148
            goto on_return;
 
1149
        }
 
1150
    }
 
1151
 
 
1152
    /* 
 
1153
     * Get which account is most likely to be associated with this incoming
 
1154
     * call. We need the account to find which contact URI to put for
 
1155
     * the call.
 
1156
     */
 
1157
    acc_id = call->acc_id = pjsua_acc_find_for_incoming(rdata);
 
1158
    call->call_hold_type = pjsua_var.acc[acc_id].cfg.call_hold_type;
 
1159
 
 
1160
    /* Get call's secure level */
 
1161
    if (PJSIP_URI_SCHEME_IS_SIPS(rdata->msg_info.msg->line.req.uri))
 
1162
        call->secure_level = 2;
 
1163
    else if (PJSIP_TRANSPORT_IS_SECURE(rdata->tp_info.transport))
 
1164
        call->secure_level = 1;
 
1165
    else
 
1166
        call->secure_level = 0;
 
1167
 
 
1168
    /* Parse SDP from incoming request */
 
1169
    if (rdata->msg_info.msg->body) {
 
1170
        pjsip_rdata_sdp_info *sdp_info;
 
1171
 
 
1172
        sdp_info = pjsip_rdata_get_sdp_info(rdata);
 
1173
        offer = sdp_info->sdp;
 
1174
 
 
1175
        status = sdp_info->sdp_err;
 
1176
        if (status==PJ_SUCCESS && sdp_info->sdp==NULL)
 
1177
            status = PJSIP_ERRNO_FROM_SIP_STATUS(PJSIP_SC_NOT_ACCEPTABLE);
 
1178
 
 
1179
        if (status != PJ_SUCCESS) {
 
1180
            const pj_str_t reason = pj_str("Bad SDP");
 
1181
            pjsip_hdr hdr_list;
 
1182
            pjsip_warning_hdr *w;
 
1183
 
 
1184
            pjsua_perror(THIS_FILE, "Bad SDP in incoming INVITE", 
 
1185
                         status);
 
1186
 
 
1187
            w = pjsip_warning_hdr_create_from_status(rdata->tp_info.pool, 
 
1188
                                             pjsip_endpt_name(pjsua_var.endpt),
 
1189
                                             status);
 
1190
            pj_list_init(&hdr_list);
 
1191
            pj_list_push_back(&hdr_list, w);
 
1192
 
 
1193
            pjsip_endpt_respond(pjsua_var.endpt, NULL, rdata, 400, 
 
1194
                                &reason, &hdr_list, NULL, NULL);
 
1195
            goto on_return;
 
1196
        }
 
1197
 
 
1198
        /* Do quick checks on SDP before passing it to transports. More elabore 
 
1199
         * checks will be done in pjsip_inv_verify_request2() below.
 
1200
         */
 
1201
        if (offer->media_count==0) {
 
1202
            const pj_str_t reason = pj_str("Missing media in SDP");
 
1203
            pjsip_endpt_respond(pjsua_var.endpt, NULL, rdata, 400, &reason, 
 
1204
                                NULL, NULL, NULL);
 
1205
            goto on_return;
 
1206
        }
 
1207
 
 
1208
    } else {
 
1209
        offer = NULL;
 
1210
    }
 
1211
 
 
1212
    /* Verify that we can handle the request. */
 
1213
    options |= PJSIP_INV_SUPPORT_100REL;
 
1214
    options |= PJSIP_INV_SUPPORT_TIMER;
 
1215
    if (pjsua_var.acc[acc_id].cfg.require_100rel == PJSUA_100REL_MANDATORY)
 
1216
        options |= PJSIP_INV_REQUIRE_100REL;
 
1217
    if (pjsua_var.acc[acc_id].cfg.ice_cfg.enable_ice)
 
1218
        options |= PJSIP_INV_SUPPORT_ICE;
 
1219
    if (pjsua_var.acc[acc_id].cfg.use_timer == PJSUA_SIP_TIMER_REQUIRED)
 
1220
        options |= PJSIP_INV_REQUIRE_TIMER;
 
1221
    else if (pjsua_var.acc[acc_id].cfg.use_timer == PJSUA_SIP_TIMER_ALWAYS)
 
1222
        options |= PJSIP_INV_ALWAYS_USE_TIMER;
 
1223
 
 
1224
    status = pjsip_inv_verify_request2(rdata, &options, offer, NULL, NULL,
 
1225
                                       pjsua_var.endpt, &response);
 
1226
    if (status != PJ_SUCCESS) {
 
1227
 
 
1228
        /*
 
1229
         * No we can't handle the incoming INVITE request.
 
1230
         */
 
1231
        if (response) {
 
1232
            pjsip_response_addr res_addr;
 
1233
 
 
1234
            pjsip_get_response_addr(response->pool, rdata, &res_addr);
 
1235
            pjsip_endpt_send_response(pjsua_var.endpt, &res_addr, response, 
 
1236
                                      NULL, NULL);
 
1237
 
 
1238
        } else {
 
1239
            /* Respond with 500 (Internal Server Error) */
 
1240
            pjsip_endpt_respond(pjsua_var.endpt, NULL, rdata, 500, NULL,
 
1241
                                NULL, NULL, NULL);
 
1242
        }
 
1243
 
 
1244
        goto on_return;
 
1245
    } 
 
1246
 
 
1247
    /* Get suitable Contact header */
 
1248
    if (pjsua_var.acc[acc_id].contact.slen) {
 
1249
        contact = pjsua_var.acc[acc_id].contact;
 
1250
    } else {
 
1251
        status = pjsua_acc_create_uas_contact(rdata->tp_info.pool, &contact,
 
1252
                                              acc_id, rdata);
 
1253
        if (status != PJ_SUCCESS) {
 
1254
            pjsua_perror(THIS_FILE, "Unable to generate Contact header", 
 
1255
                         status);
 
1256
            pjsip_endpt_respond_stateless(pjsua_var.endpt, rdata, 500, NULL,
 
1257
                                          NULL, NULL);
 
1258
            goto on_return;
 
1259
        }
 
1260
    }
 
1261
 
 
1262
    /* Create dialog: */
 
1263
    status = pjsip_dlg_create_uas( pjsip_ua_instance(), rdata,
 
1264
                                   &contact, &dlg);
 
1265
    if (status != PJ_SUCCESS) {
 
1266
        pjsip_endpt_respond_stateless(pjsua_var.endpt, rdata, 500, NULL,
 
1267
                                      NULL, NULL);
 
1268
        goto on_return;
 
1269
    }
 
1270
 
 
1271
    if (pjsua_var.acc[acc_id].cfg.allow_via_rewrite &&
 
1272
        pjsua_var.acc[acc_id].via_addr.host.slen > 0)
 
1273
    {
 
1274
        pjsip_dlg_set_via_sent_by(dlg, &pjsua_var.acc[acc_id].via_addr,
 
1275
                                  pjsua_var.acc[acc_id].via_tp);
 
1276
    }
 
1277
 
 
1278
    /* Set credentials */
 
1279
    if (pjsua_var.acc[acc_id].cred_cnt) {
 
1280
        pjsip_auth_clt_set_credentials(&dlg->auth_sess, 
 
1281
                                       pjsua_var.acc[acc_id].cred_cnt,
 
1282
                                       pjsua_var.acc[acc_id].cred);
 
1283
    }
 
1284
 
 
1285
    /* Set preference */
 
1286
    pjsip_auth_clt_set_prefs(&dlg->auth_sess, 
 
1287
                             &pjsua_var.acc[acc_id].cfg.auth_pref);
 
1288
 
 
1289
    /* Disable Session Timers if not prefered and the incoming INVITE request
 
1290
     * did not require it.
 
1291
     */
 
1292
    if (pjsua_var.acc[acc_id].cfg.use_timer == PJSUA_SIP_TIMER_INACTIVE && 
 
1293
        (options & PJSIP_INV_REQUIRE_TIMER) == 0)
 
1294
    {
 
1295
        options &= ~(PJSIP_INV_SUPPORT_TIMER);
 
1296
    }
 
1297
 
 
1298
    /* If 100rel is optional and UAC supports it, use it. */
 
1299
    if ((options & PJSIP_INV_REQUIRE_100REL)==0 &&
 
1300
        pjsua_var.acc[acc_id].cfg.require_100rel == PJSUA_100REL_OPTIONAL)
 
1301
    {
 
1302
        const pj_str_t token = { "100rel", 6};
 
1303
        pjsip_dialog_cap_status cap_status;
 
1304
 
 
1305
        cap_status = pjsip_dlg_remote_has_cap(dlg, PJSIP_H_SUPPORTED, NULL,
 
1306
                                              &token);
 
1307
        if (cap_status == PJSIP_DIALOG_CAP_SUPPORTED)
 
1308
            options |= PJSIP_INV_REQUIRE_100REL;
 
1309
    }
 
1310
 
 
1311
    /* Create invite session: */
 
1312
    status = pjsip_inv_create_uas( dlg, rdata, NULL, options, &inv);
 
1313
    if (status != PJ_SUCCESS) {
 
1314
        pjsip_hdr hdr_list;
 
1315
        pjsip_warning_hdr *w;
 
1316
 
 
1317
        w = pjsip_warning_hdr_create_from_status(dlg->pool, 
 
1318
                                                 pjsip_endpt_name(pjsua_var.endpt),
 
1319
                                                 status);
 
1320
        pj_list_init(&hdr_list);
 
1321
        pj_list_push_back(&hdr_list, w);
 
1322
 
 
1323
        pjsip_dlg_respond(dlg, rdata, 500, NULL, &hdr_list, NULL);
 
1324
 
 
1325
        /* Can't terminate dialog because transaction is in progress.
 
1326
        pjsip_dlg_terminate(dlg);
 
1327
         */
 
1328
        goto on_return;
 
1329
    }
 
1330
 
 
1331
    /* If account is locked to specific transport, then lock dialog
 
1332
     * to this transport too.
 
1333
     */
 
1334
    if (pjsua_var.acc[acc_id].cfg.transport_id != PJSUA_INVALID_ID) {
 
1335
        pjsip_tpselector tp_sel;
 
1336
 
 
1337
        pjsua_init_tpselector(pjsua_var.acc[acc_id].cfg.transport_id, &tp_sel);
 
1338
        pjsip_dlg_set_transport(dlg, &tp_sel);
 
1339
    }
 
1340
 
 
1341
    /* Create and attach pjsua_var data to the dialog */
 
1342
    call->inv = inv;
 
1343
 
 
1344
    /* Store variables required for the callback after the async
 
1345
     * media transport creation is completed.
 
1346
     */
 
1347
    call->async_call.dlg = dlg;
 
1348
    pj_list_init(&call->async_call.call_var.inc_call.answers);
 
1349
 
 
1350
    /* Init media channel, only when there is offer or call replace request.
 
1351
     * For incoming call without SDP offer, media channel init will be done
 
1352
     * in pjsua_call_answer(), see ticket #1526.
 
1353
     */
 
1354
    if (offer || replaced_dlg) {
 
1355
        status = pjsua_media_channel_init(call->index, PJSIP_ROLE_UAS, 
 
1356
                                          call->secure_level, 
 
1357
                                          rdata->tp_info.pool,
 
1358
                                          offer,
 
1359
                                          &sip_err_code, PJ_TRUE,
 
1360
                                          &on_incoming_call_med_tp_complete);
 
1361
        if (status == PJ_SUCCESS) {
 
1362
            status = on_incoming_call_med_tp_complete(call_id, NULL);
 
1363
            if (status != PJ_SUCCESS) {
 
1364
                sip_err_code = PJSIP_SC_NOT_ACCEPTABLE;
 
1365
                /* Since the call invite's state is still PJSIP_INV_STATE_NULL,
 
1366
                 * the invite session was not ended in
 
1367
                 * on_incoming_call_med_tp_complete(), so we need to send
 
1368
                 * a response message and terminate the invite here.
 
1369
                 */
 
1370
                pjsip_dlg_respond(dlg, rdata, sip_err_code, NULL, NULL, NULL);
 
1371
                pjsip_inv_terminate(call->inv, sip_err_code, PJ_FALSE); 
 
1372
                call->inv = NULL; 
 
1373
                goto on_return;
 
1374
            }
 
1375
        } else if (status != PJ_EPENDING) {
 
1376
            pjsua_perror(THIS_FILE, "Error initializing media channel", status);
 
1377
            pjsip_dlg_respond(dlg, rdata, sip_err_code, NULL, NULL, NULL);
 
1378
            pjsip_inv_terminate(call->inv, sip_err_code, PJ_FALSE); 
 
1379
            call->inv = NULL; 
 
1380
            goto on_return;
 
1381
        }
 
1382
    }
 
1383
 
 
1384
    /* Create answer */
 
1385
/*  
 
1386
    status = pjsua_media_channel_create_sdp(call->index, rdata->tp_info.pool, 
 
1387
                                            offer, &answer, &sip_err_code);
 
1388
    if (status != PJ_SUCCESS) {
 
1389
        pjsua_perror(THIS_FILE, "Error creating SDP answer", status);
 
1390
        pjsip_endpt_respond(pjsua_var.endpt, NULL, rdata,
 
1391
                            sip_err_code, NULL, NULL, NULL, NULL);
 
1392
        goto on_return;
 
1393
    }
 
1394
*/
 
1395
 
 
1396
    /* Init Session Timers */
 
1397
    status = pjsip_timer_init_session(inv, 
 
1398
                                    &pjsua_var.acc[acc_id].cfg.timer_setting);
 
1399
    if (status != PJ_SUCCESS) {
 
1400
        pjsua_perror(THIS_FILE, "Session Timer init failed", status);
 
1401
        pjsip_dlg_respond(dlg, rdata, PJSIP_SC_INTERNAL_SERVER_ERROR, NULL, NULL, NULL);
 
1402
        pjsip_inv_terminate(inv, PJSIP_SC_INTERNAL_SERVER_ERROR, PJ_FALSE);
 
1403
 
 
1404
        pjsua_media_channel_deinit(call->index);
 
1405
        call->inv = NULL;
 
1406
 
 
1407
        goto on_return;
 
1408
    }
 
1409
 
 
1410
    /* Update NAT type of remote endpoint, only when there is SDP in
 
1411
     * incoming INVITE! 
 
1412
     */
 
1413
    if (pjsua_var.ua_cfg.nat_type_in_sdp && inv->neg &&
 
1414
        pjmedia_sdp_neg_get_state(inv->neg) > PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER) 
 
1415
    {
 
1416
        const pjmedia_sdp_session *remote_sdp;
 
1417
 
 
1418
        if (pjmedia_sdp_neg_get_neg_remote(inv->neg, &remote_sdp)==PJ_SUCCESS)
 
1419
            update_remote_nat_type(call, remote_sdp);
 
1420
    }
 
1421
 
 
1422
    /* Must answer with some response to initial INVITE. We'll do this before
 
1423
     * attaching the call to the invite session/dialog, so that the application
 
1424
     * will not get notification about this event (on another scenario, it is
 
1425
     * also possible that inv_send_msg() fails and causes the invite session to
 
1426
     * be disconnected. If we have the call attached at this time, this will
 
1427
     * cause the disconnection callback to be called before on_incoming_call()
 
1428
     * callback is called, which is not right).
 
1429
     */
 
1430
    status = pjsip_inv_initial_answer(inv, rdata,
 
1431
                                      100, NULL, NULL, &response);
 
1432
    if (status != PJ_SUCCESS) {
 
1433
        if (response == NULL) {
 
1434
            pjsua_perror(THIS_FILE, "Unable to send answer to incoming INVITE",
 
1435
                         status);
 
1436
            pjsip_dlg_respond(dlg, rdata, 500, NULL, NULL, NULL);
 
1437
            pjsip_inv_terminate(inv, 500, PJ_FALSE);
 
1438
        } else {
 
1439
            pjsip_inv_send_msg(inv, response);
 
1440
            pjsip_inv_terminate(inv, response->msg->line.status.code,
 
1441
                                PJ_FALSE);
 
1442
        }
 
1443
        pjsua_media_channel_deinit(call->index);
 
1444
        call->inv = NULL;
 
1445
        goto on_return;
 
1446
 
 
1447
    } else {
 
1448
        status = pjsip_inv_send_msg(inv, response);
 
1449
        if (status != PJ_SUCCESS) {
 
1450
            pjsua_perror(THIS_FILE, "Unable to send 100 response", status);
 
1451
            pjsua_media_channel_deinit(call->index);
 
1452
            call->inv = NULL;
 
1453
            goto on_return;
 
1454
        }
 
1455
    }
 
1456
 
 
1457
    /* Only do this after sending 100/Trying (really! see the long comment
 
1458
     * above)
 
1459
     */
 
1460
    dlg->mod_data[pjsua_var.mod.id] = call;
 
1461
    inv->mod_data[pjsua_var.mod.id] = call;
 
1462
 
 
1463
    ++pjsua_var.call_cnt;
 
1464
 
 
1465
    /* Check if this request should replace existing call */
 
1466
    if (replaced_dlg) {
 
1467
        /* Process call replace. If the media channel init has been completed,
 
1468
         * just process now, otherwise, just queue the replaced dialog so
 
1469
         * it will be processed once the media channel async init is finished
 
1470
         * successfully.
 
1471
         */
 
1472
        if (call->med_ch_cb == NULL) {
 
1473
            process_incoming_call_replace(call, replaced_dlg);
 
1474
        } else {
 
1475
            call->async_call.call_var.inc_call.replaced_dlg = replaced_dlg;
 
1476
        }
 
1477
    } else {
 
1478
        /* Notify application if on_incoming_call() is overriden, 
 
1479
         * otherwise hangup the call with 480
 
1480
         */
 
1481
        if (pjsua_var.ua_cfg.cb.on_incoming_call) {
 
1482
            pjsua_var.ua_cfg.cb.on_incoming_call(acc_id, call_id, rdata);
 
1483
        } else {
 
1484
            pjsua_call_hangup(call_id, PJSIP_SC_TEMPORARILY_UNAVAILABLE, 
 
1485
                              NULL, NULL);
 
1486
        }
 
1487
    }
 
1488
 
 
1489
 
 
1490
    /* This INVITE request has been handled. */
 
1491
on_return:
 
1492
    pj_log_pop_indent();
 
1493
    PJSUA_UNLOCK();
 
1494
    return PJ_TRUE;
 
1495
}
 
1496
 
 
1497
 
 
1498
 
 
1499
/*
 
1500
 * Check if the specified call has active INVITE session and the INVITE
 
1501
 * session has not been disconnected.
 
1502
 */
 
1503
PJ_DEF(pj_bool_t) pjsua_call_is_active(pjsua_call_id call_id)
 
1504
{
 
1505
    PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
 
1506
                     PJ_EINVAL);
 
1507
    return pjsua_var.calls[call_id].inv != NULL &&
 
1508
           pjsua_var.calls[call_id].inv->state != PJSIP_INV_STATE_DISCONNECTED;
 
1509
}
 
1510
 
 
1511
 
 
1512
/* Acquire lock to the specified call_id */
 
1513
pj_status_t acquire_call(const char *title,
 
1514
                                pjsua_call_id call_id,
 
1515
                                pjsua_call **p_call,
 
1516
                                pjsip_dialog **p_dlg)
 
1517
{
 
1518
    unsigned retry;
 
1519
    pjsua_call *call = NULL;
 
1520
    pj_bool_t has_pjsua_lock = PJ_FALSE;
 
1521
    pj_status_t status = PJ_SUCCESS;
 
1522
    pj_time_val time_start, timeout;
 
1523
    pjsip_dialog *dlg = NULL;
 
1524
 
 
1525
    pj_gettimeofday(&time_start);
 
1526
    timeout.sec = 0;
 
1527
    timeout.msec = PJSUA_ACQUIRE_CALL_TIMEOUT;
 
1528
    pj_time_val_normalize(&timeout);
 
1529
 
 
1530
    for (retry=0; ; ++retry) {
 
1531
 
 
1532
        if (retry % 10 == 9) {
 
1533
            pj_time_val dtime;
 
1534
 
 
1535
            pj_gettimeofday(&dtime);
 
1536
            PJ_TIME_VAL_SUB(dtime, time_start);
 
1537
            if (!PJ_TIME_VAL_LT(dtime, timeout))
 
1538
                break;
 
1539
        }
 
1540
        
 
1541
        has_pjsua_lock = PJ_FALSE;
 
1542
 
 
1543
        status = PJSUA_TRY_LOCK();
 
1544
        if (status != PJ_SUCCESS) {
 
1545
            pj_thread_sleep(retry/10);
 
1546
            continue;
 
1547
        }
 
1548
 
 
1549
        has_pjsua_lock = PJ_TRUE;
 
1550
        call = &pjsua_var.calls[call_id];
 
1551
        if (call->inv)
 
1552
            dlg = call->inv->dlg;
 
1553
        else
 
1554
            dlg = call->async_call.dlg;
 
1555
 
 
1556
        if (dlg == NULL) {
 
1557
            PJSUA_UNLOCK();
 
1558
            PJ_LOG(3,(THIS_FILE, "Invalid call_id %d in %s", call_id, title));
 
1559
            return PJSIP_ESESSIONTERMINATED;
 
1560
        }
 
1561
 
 
1562
        status = pjsip_dlg_try_inc_lock(dlg);
 
1563
        if (status != PJ_SUCCESS) {
 
1564
            PJSUA_UNLOCK();
 
1565
            pj_thread_sleep(retry/10);
 
1566
            continue;
 
1567
        }
 
1568
 
 
1569
        PJSUA_UNLOCK();
 
1570
 
 
1571
        break;
 
1572
    }
 
1573
 
 
1574
    if (status != PJ_SUCCESS) {
 
1575
        if (has_pjsua_lock == PJ_FALSE)
 
1576
            PJ_LOG(1,(THIS_FILE, "Timed-out trying to acquire PJSUA mutex "
 
1577
                                 "(possibly system has deadlocked) in %s",
 
1578
                                 title));
 
1579
        else
 
1580
            PJ_LOG(1,(THIS_FILE, "Timed-out trying to acquire dialog mutex "
 
1581
                                 "(possibly system has deadlocked) in %s",
 
1582
                                 title));
 
1583
        return PJ_ETIMEDOUT;
 
1584
    }
 
1585
    
 
1586
    *p_call = call;
 
1587
    *p_dlg = dlg;
 
1588
 
 
1589
    return PJ_SUCCESS;
 
1590
}
 
1591
 
 
1592
 
 
1593
/*
 
1594
 * Obtain detail information about the specified call.
 
1595
 */
 
1596
PJ_DEF(pj_status_t) pjsua_call_get_info( pjsua_call_id call_id,
 
1597
                                         pjsua_call_info *info)
 
1598
{
 
1599
    pjsua_call *call;
 
1600
    pjsip_dialog *dlg;
 
1601
    unsigned mi;
 
1602
 
 
1603
    PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
 
1604
                     PJ_EINVAL);
 
1605
 
 
1606
    pj_bzero(info, sizeof(*info));
 
1607
 
 
1608
    /* Use PJSUA_LOCK() instead of acquire_call():
 
1609
     *  https://trac.pjsip.org/repos/ticket/1371
 
1610
     */
 
1611
    PJSUA_LOCK();
 
1612
 
 
1613
    call = &pjsua_var.calls[call_id];
 
1614
    dlg = (call->inv ? call->inv->dlg : call->async_call.dlg);
 
1615
    if (!dlg) {
 
1616
        PJSUA_UNLOCK();
 
1617
        return PJSIP_ESESSIONTERMINATED;
 
1618
    }
 
1619
 
 
1620
    /* id and role */
 
1621
    info->id = call_id;
 
1622
    info->role = dlg->role;
 
1623
    info->acc_id = call->acc_id;
 
1624
 
 
1625
    /* local info */
 
1626
    info->local_info.ptr = info->buf_.local_info;
 
1627
    pj_strncpy(&info->local_info, &dlg->local.info_str,
 
1628
               sizeof(info->buf_.local_info));
 
1629
 
 
1630
    /* local contact */
 
1631
    info->local_contact.ptr = info->buf_.local_contact;
 
1632
    info->local_contact.slen = pjsip_uri_print(PJSIP_URI_IN_CONTACT_HDR,
 
1633
                                               dlg->local.contact->uri,
 
1634
                                               info->local_contact.ptr,
 
1635
                                               sizeof(info->buf_.local_contact));
 
1636
 
 
1637
    /* remote info */
 
1638
    info->remote_info.ptr = info->buf_.remote_info;
 
1639
    pj_strncpy(&info->remote_info, &dlg->remote.info_str,
 
1640
               sizeof(info->buf_.remote_info));
 
1641
 
 
1642
    /* remote contact */
 
1643
    if (dlg->remote.contact) {
 
1644
        int len;
 
1645
        info->remote_contact.ptr = info->buf_.remote_contact;
 
1646
        len = pjsip_uri_print(PJSIP_URI_IN_CONTACT_HDR,
 
1647
                              dlg->remote.contact->uri,
 
1648
                              info->remote_contact.ptr,
 
1649
                              sizeof(info->buf_.remote_contact));
 
1650
        if (len < 0) len = 0;
 
1651
        info->remote_contact.slen = len;
 
1652
    } else {
 
1653
        info->remote_contact.slen = 0;
 
1654
    }
 
1655
 
 
1656
    /* call id */
 
1657
    info->call_id.ptr = info->buf_.call_id;
 
1658
    pj_strncpy(&info->call_id, &dlg->call_id->id,
 
1659
               sizeof(info->buf_.call_id));
 
1660
 
 
1661
    /* call setting */
 
1662
    pj_memcpy(&info->setting, &call->opt, sizeof(call->opt));
 
1663
 
 
1664
    /* state, state_text */
 
1665
    if (call->inv) {
 
1666
        info->state = call->inv->state;
 
1667
    } else if (call->async_call.dlg && call->last_code==0) {
 
1668
        info->state = PJSIP_INV_STATE_NULL;
 
1669
    } else {
 
1670
        info->state = PJSIP_INV_STATE_DISCONNECTED;
 
1671
    }
 
1672
    info->state_text = pj_str((char*)pjsip_inv_state_name(info->state));
 
1673
 
 
1674
    /* If call is disconnected, set the last_status from the cause code */
 
1675
    if (call->inv && call->inv->state >= PJSIP_INV_STATE_DISCONNECTED) {
 
1676
        /* last_status, last_status_text */
 
1677
        info->last_status = call->inv->cause;
 
1678
 
 
1679
        info->last_status_text.ptr = info->buf_.last_status_text;
 
1680
        pj_strncpy(&info->last_status_text, &call->inv->cause_text,
 
1681
                   sizeof(info->buf_.last_status_text));
 
1682
    } else {
 
1683
        /* last_status, last_status_text */
 
1684
        info->last_status = call->last_code;
 
1685
 
 
1686
        info->last_status_text.ptr = info->buf_.last_status_text;
 
1687
        pj_strncpy(&info->last_status_text, &call->last_text,
 
1688
                   sizeof(info->buf_.last_status_text));
 
1689
    }
 
1690
    
 
1691
    /* Audio & video count offered by remote */
 
1692
    info->rem_offerer   = call->rem_offerer;
 
1693
    if (call->rem_offerer) {
 
1694
        info->rem_aud_cnt = call->rem_aud_cnt;
 
1695
        info->rem_vid_cnt = call->rem_vid_cnt;
 
1696
    }
 
1697
 
 
1698
    /* Build array of active media info */
 
1699
    info->media_cnt = 0;
 
1700
    for (mi=0; mi < call->med_cnt &&
 
1701
               info->media_cnt < PJ_ARRAY_SIZE(info->media); ++mi)
 
1702
    {
 
1703
        pjsua_call_media *call_med = &call->media[mi];
 
1704
 
 
1705
        info->media[info->media_cnt].index = mi;
 
1706
        info->media[info->media_cnt].status = call_med->state;
 
1707
        info->media[info->media_cnt].dir = call_med->dir;
 
1708
        info->media[info->media_cnt].type = call_med->type;
 
1709
 
 
1710
        if (call_med->type == PJMEDIA_TYPE_AUDIO) {
 
1711
            info->media[info->media_cnt].stream.aud.conf_slot =
 
1712
                                                call_med->strm.a.conf_slot;
 
1713
        } else if (call_med->type == PJMEDIA_TYPE_VIDEO) {
 
1714
            pjmedia_vid_dev_index cap_dev = PJMEDIA_VID_INVALID_DEV;
 
1715
 
 
1716
            info->media[info->media_cnt].stream.vid.win_in = 
 
1717
                                                call_med->strm.v.rdr_win_id;
 
1718
 
 
1719
            if (call_med->strm.v.cap_win_id != PJSUA_INVALID_ID) {
 
1720
                cap_dev = call_med->strm.v.cap_dev;
 
1721
            }
 
1722
            info->media[info->media_cnt].stream.vid.cap_dev = cap_dev;
 
1723
        } else {
 
1724
            continue;
 
1725
        }
 
1726
        ++info->media_cnt;
 
1727
    }
 
1728
 
 
1729
    if (call->audio_idx != -1) {
 
1730
        info->media_status = call->media[call->audio_idx].state;
 
1731
        info->media_dir = call->media[call->audio_idx].dir;
 
1732
        info->conf_slot = call->media[call->audio_idx].strm.a.conf_slot;
 
1733
    }
 
1734
 
 
1735
    /* Build array of provisional media info */
 
1736
    info->prov_media_cnt = 0;
 
1737
    for (mi=0; mi < call->med_prov_cnt &&
 
1738
               info->prov_media_cnt < PJ_ARRAY_SIZE(info->prov_media); ++mi)
 
1739
    {
 
1740
        pjsua_call_media *call_med = &call->media_prov[mi];
 
1741
 
 
1742
        info->prov_media[info->prov_media_cnt].index = mi;
 
1743
        info->prov_media[info->prov_media_cnt].status = call_med->state;
 
1744
        info->prov_media[info->prov_media_cnt].dir = call_med->dir;
 
1745
        info->prov_media[info->prov_media_cnt].type = call_med->type;
 
1746
        if (call_med->type == PJMEDIA_TYPE_AUDIO) {
 
1747
            info->prov_media[info->prov_media_cnt].stream.aud.conf_slot =
 
1748
                                                call_med->strm.a.conf_slot;
 
1749
        } else if (call_med->type == PJMEDIA_TYPE_VIDEO) {
 
1750
            pjmedia_vid_dev_index cap_dev = PJMEDIA_VID_INVALID_DEV;
 
1751
 
 
1752
            info->prov_media[info->prov_media_cnt].stream.vid.win_in = 
 
1753
                                                call_med->strm.v.rdr_win_id;
 
1754
 
 
1755
            if (call_med->strm.v.cap_win_id != PJSUA_INVALID_ID) {
 
1756
                cap_dev = call_med->strm.v.cap_dev;
 
1757
            }
 
1758
            info->prov_media[info->prov_media_cnt].stream.vid.cap_dev=cap_dev;
 
1759
        } else {
 
1760
            continue;
 
1761
        }
 
1762
        ++info->prov_media_cnt;
 
1763
    }
 
1764
 
 
1765
    /* calculate duration */
 
1766
    if (info->state >= PJSIP_INV_STATE_DISCONNECTED) {
 
1767
 
 
1768
        info->total_duration = call->dis_time;
 
1769
        PJ_TIME_VAL_SUB(info->total_duration, call->start_time);
 
1770
 
 
1771
        if (call->conn_time.sec) {
 
1772
            info->connect_duration = call->dis_time;
 
1773
            PJ_TIME_VAL_SUB(info->connect_duration, call->conn_time);
 
1774
        }
 
1775
 
 
1776
    } else if (info->state == PJSIP_INV_STATE_CONFIRMED) {
 
1777
 
 
1778
        pj_gettimeofday(&info->total_duration);
 
1779
        PJ_TIME_VAL_SUB(info->total_duration, call->start_time);
 
1780
 
 
1781
        pj_gettimeofday(&info->connect_duration);
 
1782
        PJ_TIME_VAL_SUB(info->connect_duration, call->conn_time);
 
1783
 
 
1784
    } else {
 
1785
        pj_gettimeofday(&info->total_duration);
 
1786
        PJ_TIME_VAL_SUB(info->total_duration, call->start_time);
 
1787
    }
 
1788
 
 
1789
    PJSUA_UNLOCK();
 
1790
 
 
1791
    return PJ_SUCCESS;
 
1792
}
 
1793
 
 
1794
/*
 
1795
 * Check if call remote peer support the specified capability.
 
1796
 */
 
1797
PJ_DEF(pjsip_dialog_cap_status) pjsua_call_remote_has_cap(
 
1798
                                                    pjsua_call_id call_id,
 
1799
                                                    int htype,
 
1800
                                                    const pj_str_t *hname,
 
1801
                                                    const pj_str_t *token)
 
1802
{
 
1803
    pjsua_call *call;
 
1804
    pjsip_dialog *dlg;
 
1805
    pj_status_t status;
 
1806
    pjsip_dialog_cap_status cap_status;
 
1807
 
 
1808
    status = acquire_call("pjsua_call_peer_has_cap()", call_id, &call, &dlg);
 
1809
    if (status != PJ_SUCCESS)
 
1810
        return PJSIP_DIALOG_CAP_UNKNOWN;
 
1811
 
 
1812
    cap_status = pjsip_dlg_remote_has_cap(dlg, htype, hname, token);
 
1813
 
 
1814
    pjsip_dlg_dec_lock(dlg);
 
1815
 
 
1816
    return cap_status;
 
1817
}
 
1818
 
 
1819
 
 
1820
/*
 
1821
 * Attach application specific data to the call.
 
1822
 */
 
1823
PJ_DEF(pj_status_t) pjsua_call_set_user_data( pjsua_call_id call_id,
 
1824
                                              void *user_data)
 
1825
{
 
1826
    PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
 
1827
                     PJ_EINVAL);
 
1828
    pjsua_var.calls[call_id].user_data = user_data;
 
1829
 
 
1830
    return PJ_SUCCESS;
 
1831
}
 
1832
 
 
1833
 
 
1834
/*
 
1835
 * Get user data attached to the call.
 
1836
 */
 
1837
PJ_DEF(void*) pjsua_call_get_user_data(pjsua_call_id call_id)
 
1838
{
 
1839
    PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
 
1840
                     NULL);
 
1841
    return pjsua_var.calls[call_id].user_data;
 
1842
}
 
1843
 
 
1844
 
 
1845
/*
 
1846
 * Get remote's NAT type.
 
1847
 */
 
1848
PJ_DEF(pj_status_t) pjsua_call_get_rem_nat_type(pjsua_call_id call_id,
 
1849
                                                pj_stun_nat_type *p_type)
 
1850
{
 
1851
    PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
 
1852
                     PJ_EINVAL);
 
1853
    PJ_ASSERT_RETURN(p_type != NULL, PJ_EINVAL);
 
1854
 
 
1855
    *p_type = pjsua_var.calls[call_id].rem_nat_type;
 
1856
    return PJ_SUCCESS;
 
1857
}
 
1858
 
 
1859
 
 
1860
/*
 
1861
 * Get media transport info for the specified media index.
 
1862
 */
 
1863
PJ_DEF(pj_status_t) 
 
1864
pjsua_call_get_med_transport_info(pjsua_call_id call_id,
 
1865
                                  unsigned med_idx,
 
1866
                                  pjmedia_transport_info *t)
 
1867
{
 
1868
    pjsua_call *call;
 
1869
    pjsua_call_media *call_med;
 
1870
    pj_status_t status;
 
1871
 
 
1872
    PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
 
1873
                     PJ_EINVAL);
 
1874
    PJ_ASSERT_RETURN(t, PJ_EINVAL);
 
1875
 
 
1876
    PJSUA_LOCK();
 
1877
 
 
1878
    call = &pjsua_var.calls[call_id];
 
1879
    
 
1880
    if (med_idx >= call->med_cnt) {
 
1881
        PJSUA_UNLOCK();
 
1882
        return PJ_EINVAL;
 
1883
    }
 
1884
 
 
1885
    call_med = &call->media[med_idx];
 
1886
 
 
1887
    pjmedia_transport_info_init(t);
 
1888
    status = pjmedia_transport_get_info(call_med->tp, t);
 
1889
    
 
1890
    PJSUA_UNLOCK();
 
1891
    return status;
 
1892
}
 
1893
 
 
1894
 
 
1895
/* Media channel init callback for pjsua_call_answer(). */
 
1896
static pj_status_t
 
1897
on_answer_call_med_tp_complete(pjsua_call_id call_id,
 
1898
                               const pjsua_med_tp_state_info *info)
 
1899
{
 
1900
    pjsua_call *call = &pjsua_var.calls[call_id];
 
1901
    pjmedia_sdp_session *sdp;
 
1902
    int sip_err_code = (info? info->sip_err_code: 0);
 
1903
    pj_status_t status = (info? info->status: PJ_SUCCESS);
 
1904
 
 
1905
    PJSUA_LOCK();
 
1906
 
 
1907
    if (status != PJ_SUCCESS) {
 
1908
        pjsua_perror(THIS_FILE, "Error initializing media channel", status);
 
1909
        goto on_return;
 
1910
    }
 
1911
 
 
1912
    /* pjsua_media_channel_deinit() has been called. */
 
1913
    if (call->async_call.med_ch_deinit) {
 
1914
        pjsua_media_channel_deinit(call->index);
 
1915
        call->med_ch_cb = NULL;
 
1916
        PJSUA_UNLOCK();
 
1917
        return PJ_SUCCESS;
 
1918
    }
 
1919
 
 
1920
    status = pjsua_media_channel_create_sdp(call_id,
 
1921
                                            call->async_call.dlg->pool, 
 
1922
                                            NULL, &sdp, &sip_err_code);
 
1923
    if (status != PJ_SUCCESS) {
 
1924
        pjsua_perror(THIS_FILE, "Error creating SDP answer", status);
 
1925
        goto on_return;
 
1926
    }
 
1927
 
 
1928
    status = pjsip_inv_set_local_sdp(call->inv, sdp);
 
1929
    if (status != PJ_SUCCESS) {
 
1930
        pjsua_perror(THIS_FILE, "Error setting local SDP", status);
 
1931
        sip_err_code = PJSIP_SC_NOT_ACCEPTABLE_HERE;
 
1932
        goto on_return;
 
1933
    }
 
1934
 
 
1935
on_return:
 
1936
    if (status != PJ_SUCCESS) {
 
1937
        /* If the callback is called from pjsua_call_on_incoming(), the
 
1938
         * invite's state is PJSIP_INV_STATE_NULL, so the invite session
 
1939
         * will be terminated later, otherwise we end the session here.
 
1940
         */
 
1941
        if (call->inv->state > PJSIP_INV_STATE_NULL) {
 
1942
            pjsip_tx_data *tdata;
 
1943
            pj_status_t status_;
 
1944
 
 
1945
            status_ = pjsip_inv_end_session(call->inv, sip_err_code, NULL,
 
1946
                                            &tdata);
 
1947
            if (status_ == PJ_SUCCESS && tdata)
 
1948
                status_ = pjsip_inv_send_msg(call->inv, tdata);
 
1949
        }
 
1950
 
 
1951
        pjsua_media_channel_deinit(call->index);
 
1952
    }
 
1953
 
 
1954
    /* Set the callback to NULL to indicate that the async operation
 
1955
     * has completed.
 
1956
     */
 
1957
    call->med_ch_cb = NULL;
 
1958
 
 
1959
    /* Finish any pending process */
 
1960
    if (status == PJ_SUCCESS) {
 
1961
        /* Process pending call answers */
 
1962
        process_pending_call_answer(call);
 
1963
    }
 
1964
 
 
1965
    PJSUA_UNLOCK();
 
1966
    return status;
 
1967
}
 
1968
 
 
1969
 
 
1970
/*
 
1971
 * Send response to incoming INVITE request.
 
1972
 */
 
1973
PJ_DEF(pj_status_t) pjsua_call_answer( pjsua_call_id call_id, 
 
1974
                                       unsigned code,
 
1975
                                       const pj_str_t *reason,
 
1976
                                       const pjsua_msg_data *msg_data)
 
1977
{
 
1978
    return pjsua_call_answer2(call_id, NULL, code, reason, msg_data);
 
1979
}
 
1980
 
 
1981
 
 
1982
/*
 
1983
 * Send response to incoming INVITE request.
 
1984
 */
 
1985
PJ_DEF(pj_status_t) pjsua_call_answer2(pjsua_call_id call_id,
 
1986
                                       const pjsua_call_setting *opt,
 
1987
                                       unsigned code,
 
1988
                                       const pj_str_t *reason,
 
1989
                                       const pjsua_msg_data *msg_data)
 
1990
{
 
1991
    pjsua_call *call;
 
1992
    pjsip_dialog *dlg = NULL;
 
1993
    pjsip_tx_data *tdata;
 
1994
    pj_status_t status;
 
1995
 
 
1996
    PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
 
1997
                     PJ_EINVAL);
 
1998
 
 
1999
    PJ_LOG(4,(THIS_FILE, "Answering call %d: code=%d", call_id, code));
 
2000
    pj_log_push_indent();
 
2001
 
 
2002
    status = acquire_call("pjsua_call_answer()", call_id, &call, &dlg);
 
2003
    if (status != PJ_SUCCESS)
 
2004
        goto on_return;
 
2005
 
 
2006
    /* Apply call setting, only if status code is 1xx or 2xx. */
 
2007
    if (opt && code < 300) {
 
2008
        /* Check if it has not been set previously or it is different to
 
2009
         * the previous one.
 
2010
         */
 
2011
        if (!call->opt_inited) {
 
2012
            call->opt_inited = PJ_TRUE;
 
2013
            apply_call_setting(call, opt, NULL);
 
2014
        } else if (pj_memcmp(opt, &call->opt, sizeof(*opt)) != 0) {
 
2015
            /* Warn application about call setting inconsistency */
 
2016
            PJ_LOG(2,(THIS_FILE, "The call setting changes is ignored."));
 
2017
        }
 
2018
    }
 
2019
 
 
2020
    PJSUA_LOCK();
 
2021
 
 
2022
    /* Ticket #1526: When the incoming call contains no SDP offer, the media
 
2023
     * channel may have not been initialized at this stage. The media channel
 
2024
     * will be initialized here (along with SDP local offer generation) when
 
2025
     * the following conditions are met:
 
2026
     * - no pending media channel init
 
2027
     * - local SDP has not been generated
 
2028
     * - call setting has just been set, or SDP offer needs to be sent, i.e:
 
2029
     *   answer code 183 or 2xx is issued
 
2030
     */
 
2031
    if (!call->med_ch_cb && 
 
2032
        (call->opt_inited || (code==183 || code/100==2)) &&
 
2033
        (!call->inv->neg ||
 
2034
         pjmedia_sdp_neg_get_state(call->inv->neg) == 
 
2035
                PJMEDIA_SDP_NEG_STATE_NULL))
 
2036
    {
 
2037
        /* Mark call setting as initialized as it is just about to be used
 
2038
         * for initializing the media channel.
 
2039
         */
 
2040
        call->opt_inited = PJ_TRUE;
 
2041
 
 
2042
        status = pjsua_media_channel_init(call->index, PJSIP_ROLE_UAC,
 
2043
                                          call->secure_level,
 
2044
                                          dlg->pool,
 
2045
                                          NULL, NULL, PJ_TRUE,
 
2046
                                          &on_answer_call_med_tp_complete);
 
2047
        if (status == PJ_SUCCESS) {
 
2048
            status = on_answer_call_med_tp_complete(call->index, NULL);
 
2049
            if (status != PJ_SUCCESS) {
 
2050
                PJSUA_UNLOCK();
 
2051
                goto on_return;
 
2052
            }
 
2053
        } else if (status != PJ_EPENDING) {
 
2054
            PJSUA_UNLOCK();
 
2055
            pjsua_perror(THIS_FILE, "Error initializing media channel", status);
 
2056
            goto on_return;
 
2057
        }
 
2058
    }
 
2059
 
 
2060
    /* If media transport creation is not yet completed, we will answer
 
2061
     * the call in the media transport creation callback instead.
 
2062
     */
 
2063
    if (call->med_ch_cb) {
 
2064
        struct call_answer *answer;
 
2065
        
 
2066
        PJ_LOG(4,(THIS_FILE, "Pending answering call %d upon completion "
 
2067
                             "of media transport", call_id));
 
2068
 
 
2069
        answer = PJ_POOL_ZALLOC_T(call->inv->pool_prov, struct call_answer);
 
2070
        answer->code = code;
 
2071
        if (opt) {
 
2072
            answer->opt = PJ_POOL_ZALLOC_T(call->inv->pool_prov,
 
2073
                                           pjsua_call_setting);
 
2074
            *answer->opt = *opt;
 
2075
        }
 
2076
        if (reason) {
 
2077
            pj_strdup(call->inv->pool_prov, answer->reason, reason);
 
2078
        }
 
2079
        if (msg_data) {
 
2080
            answer->msg_data = pjsua_msg_data_clone(call->inv->pool_prov,
 
2081
                                                    msg_data);
 
2082
        }
 
2083
        pj_list_push_back(&call->async_call.call_var.inc_call.answers,
 
2084
                          answer);
 
2085
 
 
2086
        PJSUA_UNLOCK();
 
2087
        if (dlg) pjsip_dlg_dec_lock(dlg);
 
2088
        pj_log_pop_indent();
 
2089
        return status;
 
2090
    }
 
2091
 
 
2092
    PJSUA_UNLOCK();
 
2093
 
 
2094
    if (call->res_time.sec == 0)
 
2095
        pj_gettimeofday(&call->res_time);
 
2096
 
 
2097
    if (reason && reason->slen == 0)
 
2098
        reason = NULL;
 
2099
 
 
2100
    /* Create response message */
 
2101
    status = pjsip_inv_answer(call->inv, code, reason, NULL, &tdata);
 
2102
    if (status != PJ_SUCCESS) {
 
2103
        pjsua_perror(THIS_FILE, "Error creating response", 
 
2104
                     status);
 
2105
        goto on_return;
 
2106
    }
 
2107
 
 
2108
    /* Call might have been disconnected if application is answering with
 
2109
     * 200/OK and the media failed to start.
 
2110
     */
 
2111
    if (call->inv == NULL)
 
2112
        goto on_return;
 
2113
 
 
2114
    /* Add additional headers etc */
 
2115
    pjsua_process_msg_data( tdata, msg_data);
 
2116
 
 
2117
    /* Send the message */
 
2118
    status = pjsip_inv_send_msg(call->inv, tdata);
 
2119
    if (status != PJ_SUCCESS)
 
2120
        pjsua_perror(THIS_FILE, "Error sending response", 
 
2121
                     status);
 
2122
 
 
2123
on_return:
 
2124
    if (dlg) pjsip_dlg_dec_lock(dlg);
 
2125
    pj_log_pop_indent();
 
2126
    return status;
 
2127
}
 
2128
 
 
2129
 
 
2130
/*
 
2131
 * Hangup call by using method that is appropriate according to the
 
2132
 * call state.
 
2133
 */
 
2134
PJ_DEF(pj_status_t) pjsua_call_hangup(pjsua_call_id call_id,
 
2135
                                      unsigned code,
 
2136
                                      const pj_str_t *reason,
 
2137
                                      const pjsua_msg_data *msg_data)
 
2138
{
 
2139
    pjsua_call *call;
 
2140
    pjsip_dialog *dlg = NULL;
 
2141
    pj_status_t status;
 
2142
    pjsip_tx_data *tdata;
 
2143
 
 
2144
 
 
2145
    if (call_id<0 || call_id>=(int)pjsua_var.ua_cfg.max_calls) {
 
2146
        PJ_LOG(1,(THIS_FILE, "pjsua_call_hangup(): invalid call id %d",
 
2147
                             call_id));
 
2148
    }
 
2149
    
 
2150
    PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
 
2151
                     PJ_EINVAL);
 
2152
 
 
2153
    PJ_LOG(4,(THIS_FILE, "Call %d hanging up: code=%d..", call_id, code));
 
2154
    pj_log_push_indent();
 
2155
 
 
2156
    status = acquire_call("pjsua_call_hangup()", call_id, &call, &dlg);
 
2157
    if (status != PJ_SUCCESS)
 
2158
        goto on_return;
 
2159
 
 
2160
    /* If media transport creation is not yet completed, we will hangup
 
2161
     * the call in the media transport creation callback instead.
 
2162
     */
 
2163
    if (call->med_ch_cb && !call->inv) {
 
2164
        PJ_LOG(4,(THIS_FILE, "Pending call %d hangup upon completion "
 
2165
                             "of media transport", call_id));
 
2166
        call->async_call.call_var.out_call.hangup = PJ_TRUE;
 
2167
        if (code == 0)
 
2168
            call->last_code = PJSIP_SC_REQUEST_TERMINATED;
 
2169
        else
 
2170
            call->last_code = (pjsip_status_code)code;
 
2171
        if (reason) {
 
2172
            pj_strncpy(&call->last_text, reason,
 
2173
                       sizeof(call->last_text_buf_));
 
2174
        }
 
2175
        
 
2176
        goto on_return;
 
2177
    }
 
2178
 
 
2179
    if (code==0) {
 
2180
        if (call->inv->state == PJSIP_INV_STATE_CONFIRMED)
 
2181
            code = PJSIP_SC_OK;
 
2182
        else if (call->inv->role == PJSIP_ROLE_UAS)
 
2183
            code = PJSIP_SC_DECLINE;
 
2184
        else
 
2185
            code = PJSIP_SC_REQUEST_TERMINATED;
 
2186
    }
 
2187
 
 
2188
    status = pjsip_inv_end_session(call->inv, code, reason, &tdata);
 
2189
    if (status != PJ_SUCCESS) {
 
2190
        pjsua_perror(THIS_FILE, 
 
2191
                     "Failed to create end session message", 
 
2192
                     status);
 
2193
        goto on_return;
 
2194
    }
 
2195
 
 
2196
    /* pjsip_inv_end_session may return PJ_SUCCESS with NULL 
 
2197
     * as p_tdata when INVITE transaction has not been answered
 
2198
     * with any provisional responses.
 
2199
     */
 
2200
    if (tdata == NULL)
 
2201
        goto on_return;
 
2202
 
 
2203
    /* Add additional headers etc */
 
2204
    pjsua_process_msg_data( tdata, msg_data);
 
2205
 
 
2206
    /* Send the message */
 
2207
    status = pjsip_inv_send_msg(call->inv, tdata);
 
2208
    if (status != PJ_SUCCESS) {
 
2209
        pjsua_perror(THIS_FILE, 
 
2210
                     "Failed to send end session message", 
 
2211
                     status);
 
2212
        goto on_return;
 
2213
    }
 
2214
 
 
2215
    /* Stop reinvite timer, if it is active */
 
2216
    if (call->reinv_timer.id) {
 
2217
        pjsua_cancel_timer(&call->reinv_timer);
 
2218
        call->reinv_timer.id = PJ_FALSE;
 
2219
    }
 
2220
 
 
2221
on_return:
 
2222
    if (dlg) pjsip_dlg_dec_lock(dlg);
 
2223
    pj_log_pop_indent();
 
2224
    return status;
 
2225
}
 
2226
 
 
2227
 
 
2228
/*
 
2229
 * Accept or reject redirection.
 
2230
 */
 
2231
PJ_DEF(pj_status_t) pjsua_call_process_redirect( pjsua_call_id call_id,
 
2232
                                                 pjsip_redirect_op cmd)
 
2233
{
 
2234
    pjsua_call *call;
 
2235
    pjsip_dialog *dlg;
 
2236
    pj_status_t status;
 
2237
 
 
2238
    PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
 
2239
                     PJ_EINVAL);
 
2240
 
 
2241
    status = acquire_call("pjsua_call_process_redirect()", call_id, 
 
2242
                          &call, &dlg);
 
2243
    if (status != PJ_SUCCESS)
 
2244
        return status;
 
2245
 
 
2246
    status = pjsip_inv_process_redirect(call->inv, cmd, NULL);
 
2247
 
 
2248
    pjsip_dlg_dec_lock(dlg);
 
2249
 
 
2250
    return status;
 
2251
}
 
2252
 
 
2253
 
 
2254
/*
 
2255
 * Put the specified call on hold.
 
2256
 */
 
2257
PJ_DEF(pj_status_t) pjsua_call_set_hold(pjsua_call_id call_id,
 
2258
                                        const pjsua_msg_data *msg_data)
 
2259
{
 
2260
    pjmedia_sdp_session *sdp;
 
2261
    pjsua_call *call;
 
2262
    pjsip_dialog *dlg = NULL;
 
2263
    pjsip_tx_data *tdata;
 
2264
    pj_status_t status;
 
2265
 
 
2266
    PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
 
2267
                     PJ_EINVAL);
 
2268
 
 
2269
    PJ_LOG(4,(THIS_FILE, "Putting call %d on hold", call_id));
 
2270
    pj_log_push_indent();
 
2271
 
 
2272
    status = acquire_call("pjsua_call_set_hold()", call_id, &call, &dlg);
 
2273
    if (status != PJ_SUCCESS)
 
2274
        goto on_return;
 
2275
 
 
2276
    if (call->inv->state != PJSIP_INV_STATE_CONFIRMED) {
 
2277
        PJ_LOG(3,(THIS_FILE, "Can not hold call that is not confirmed"));
 
2278
        status = PJSIP_ESESSIONSTATE;
 
2279
        goto on_return;
 
2280
    }
 
2281
 
 
2282
    status = create_sdp_of_call_hold(call, &sdp);
 
2283
    if (status != PJ_SUCCESS)
 
2284
        goto on_return;
 
2285
 
 
2286
    /* Create re-INVITE with new offer */
 
2287
    status = pjsip_inv_reinvite( call->inv, NULL, sdp, &tdata);
 
2288
    if (status != PJ_SUCCESS) {
 
2289
        pjsua_perror(THIS_FILE, "Unable to create re-INVITE", status);
 
2290
        goto on_return;
 
2291
    }
 
2292
 
 
2293
    /* Add additional headers etc */
 
2294
    pjsua_process_msg_data( tdata, msg_data);
 
2295
 
 
2296
    /* Record the tx_data to keep track the operation */
 
2297
    call->hold_msg = (void*) tdata;
 
2298
 
 
2299
    /* Send the request */
 
2300
    status = pjsip_inv_send_msg( call->inv, tdata);
 
2301
    if (status != PJ_SUCCESS) {
 
2302
        pjsua_perror(THIS_FILE, "Unable to send re-INVITE", status);
 
2303
        call->hold_msg = NULL;
 
2304
        goto on_return;
 
2305
    }
 
2306
 
 
2307
    /* Set flag that local put the call on hold */
 
2308
    call->local_hold = PJ_TRUE;
 
2309
 
 
2310
on_return:
 
2311
    if (dlg) pjsip_dlg_dec_lock(dlg);
 
2312
    pj_log_pop_indent();
 
2313
    return status;
 
2314
}
 
2315
 
 
2316
 
 
2317
/*
 
2318
 * Send re-INVITE (to release hold).
 
2319
 */
 
2320
PJ_DEF(pj_status_t) pjsua_call_reinvite( pjsua_call_id call_id,
 
2321
                                         unsigned options,
 
2322
                                         const pjsua_msg_data *msg_data)
 
2323
{
 
2324
    pjsua_call *call;
 
2325
    pjsip_dialog *dlg = NULL;
 
2326
    pj_status_t status;
 
2327
 
 
2328
    status = acquire_call("pjsua_call_reinvite()", call_id, &call, &dlg);
 
2329
    if (status != PJ_SUCCESS)
 
2330
        goto on_return;
 
2331
 
 
2332
    if (options != call->opt.flag)
 
2333
        call->opt.flag = options;
 
2334
 
 
2335
    status = pjsua_call_reinvite2(call_id, NULL, msg_data);
 
2336
 
 
2337
on_return:
 
2338
    if (dlg) pjsip_dlg_dec_lock(dlg);
 
2339
    return status;
 
2340
}
 
2341
 
 
2342
 
 
2343
/*
 
2344
 * Send re-INVITE (to release hold).
 
2345
 */
 
2346
PJ_DEF(pj_status_t) pjsua_call_reinvite2(pjsua_call_id call_id,
 
2347
                                         const pjsua_call_setting *opt,
 
2348
                                         const pjsua_msg_data *msg_data)
 
2349
{
 
2350
    pjmedia_sdp_session *sdp;
 
2351
    pj_str_t *new_contact = NULL;
 
2352
    pjsip_tx_data *tdata;
 
2353
    pjsua_call *call;
 
2354
    pjsip_dialog *dlg = NULL;
 
2355
    pj_status_t status;
 
2356
 
 
2357
 
 
2358
    PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
 
2359
                     PJ_EINVAL);
 
2360
 
 
2361
    PJ_LOG(4,(THIS_FILE, "Sending re-INVITE on call %d", call_id));
 
2362
    pj_log_push_indent();
 
2363
 
 
2364
    status = acquire_call("pjsua_call_reinvite2()", call_id, &call, &dlg);
 
2365
    if (status != PJ_SUCCESS)
 
2366
        goto on_return;
 
2367
 
 
2368
    if (call->inv->state != PJSIP_INV_STATE_CONFIRMED) {
 
2369
        PJ_LOG(3,(THIS_FILE, "Can not re-INVITE call that is not confirmed"));
 
2370
        status = PJSIP_ESESSIONSTATE;
 
2371
        goto on_return;
 
2372
    }
 
2373
 
 
2374
    status = apply_call_setting(call, opt, NULL);
 
2375
    if (status != PJ_SUCCESS) {
 
2376
        pjsua_perror(THIS_FILE, "Failed to apply call setting", status);
 
2377
        goto on_return;
 
2378
    }
 
2379
 
 
2380
    /* Create SDP */
 
2381
    if (call->local_hold && (call->opt.flag & PJSUA_CALL_UNHOLD)==0) {
 
2382
        status = create_sdp_of_call_hold(call, &sdp);
 
2383
    } else {
 
2384
        status = pjsua_media_channel_create_sdp(call->index, 
 
2385
                                                call->inv->pool_prov,
 
2386
                                                NULL, &sdp, NULL);
 
2387
        call->local_hold = PJ_FALSE;
 
2388
    }
 
2389
    if (status != PJ_SUCCESS) {
 
2390
        pjsua_perror(THIS_FILE, "Unable to get SDP from media endpoint", 
 
2391
                     status);
 
2392
        goto on_return;
 
2393
    }
 
2394
 
 
2395
    if ((call->opt.flag & PJSUA_CALL_UPDATE_CONTACT) &&
 
2396
            pjsua_acc_is_valid(call->acc_id))
 
2397
    {
 
2398
        new_contact = &pjsua_var.acc[call->acc_id].contact;
 
2399
    }
 
2400
 
 
2401
    /* Create re-INVITE with new offer */
 
2402
    status = pjsip_inv_reinvite( call->inv, new_contact, sdp, &tdata);
 
2403
    if (status != PJ_SUCCESS) {
 
2404
        pjsua_perror(THIS_FILE, "Unable to create re-INVITE", status);
 
2405
        goto on_return;
 
2406
    }
 
2407
 
 
2408
    /* Add additional headers etc */
 
2409
    pjsua_process_msg_data( tdata, msg_data);
 
2410
 
 
2411
    /* Send the request */
 
2412
    status = pjsip_inv_send_msg( call->inv, tdata);
 
2413
    if (status != PJ_SUCCESS) {
 
2414
        pjsua_perror(THIS_FILE, "Unable to send re-INVITE", status);
 
2415
        goto on_return;
 
2416
    }
 
2417
 
 
2418
on_return:
 
2419
    if (dlg) pjsip_dlg_dec_lock(dlg);
 
2420
    pj_log_pop_indent();
 
2421
    return status;
 
2422
}
 
2423
 
 
2424
 
 
2425
/*
 
2426
 * Send UPDATE request.
 
2427
 */
 
2428
PJ_DEF(pj_status_t) pjsua_call_update( pjsua_call_id call_id,
 
2429
                                       unsigned options,
 
2430
                                       const pjsua_msg_data *msg_data)
 
2431
{
 
2432
    pjsua_call *call;
 
2433
    pjsip_dialog *dlg = NULL;
 
2434
    pj_status_t status;
 
2435
 
 
2436
    status = acquire_call("pjsua_call_update()", call_id, &call, &dlg);
 
2437
    if (status != PJ_SUCCESS)
 
2438
        goto on_return;
 
2439
 
 
2440
    if (options != call->opt.flag)
 
2441
        call->opt.flag = options;
 
2442
 
 
2443
    status = pjsua_call_update2(call_id, NULL, msg_data);
 
2444
 
 
2445
on_return:
 
2446
    if (dlg) pjsip_dlg_dec_lock(dlg);
 
2447
    return status;
 
2448
}
 
2449
 
 
2450
 
 
2451
/*
 
2452
 * Send UPDATE request.
 
2453
 */
 
2454
PJ_DEF(pj_status_t) pjsua_call_update2(pjsua_call_id call_id,
 
2455
                                       const pjsua_call_setting *opt,
 
2456
                                       const pjsua_msg_data *msg_data)
 
2457
{
 
2458
    pjmedia_sdp_session *sdp;
 
2459
    pj_str_t *new_contact = NULL;
 
2460
    pjsip_tx_data *tdata;
 
2461
    pjsua_call *call;
 
2462
    pjsip_dialog *dlg = NULL;
 
2463
    pj_status_t status;
 
2464
 
 
2465
    PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
 
2466
                     PJ_EINVAL);
 
2467
 
 
2468
    PJ_LOG(4,(THIS_FILE, "Sending UPDATE on call %d", call_id));
 
2469
    pj_log_push_indent();
 
2470
 
 
2471
    status = acquire_call("pjsua_call_update2()", call_id, &call, &dlg);
 
2472
    if (status != PJ_SUCCESS)
 
2473
        goto on_return;
 
2474
 
 
2475
    status = apply_call_setting(call, opt, NULL);
 
2476
    if (status != PJ_SUCCESS) {
 
2477
        pjsua_perror(THIS_FILE, "Failed to apply call setting", status);
 
2478
        goto on_return;
 
2479
    }
 
2480
 
 
2481
    /* Create SDP */
 
2482
    status = pjsua_media_channel_create_sdp(call->index, 
 
2483
                                            call->inv->pool_prov, 
 
2484
                                            NULL, &sdp, NULL);
 
2485
    if (status != PJ_SUCCESS) {
 
2486
        pjsua_perror(THIS_FILE, "Unable to get SDP from media endpoint", 
 
2487
                     status);
 
2488
        goto on_return;
 
2489
    }
 
2490
 
 
2491
    if ((call->opt.flag & PJSUA_CALL_UPDATE_CONTACT) &&
 
2492
            pjsua_acc_is_valid(call->acc_id))
 
2493
    {
 
2494
        new_contact = &pjsua_var.acc[call->acc_id].contact;
 
2495
    }
 
2496
 
 
2497
    /* Create UPDATE with new offer */
 
2498
    status = pjsip_inv_update(call->inv, new_contact, sdp, &tdata);
 
2499
    if (status != PJ_SUCCESS) {
 
2500
        pjsua_perror(THIS_FILE, "Unable to create UPDATE request", status);
 
2501
        goto on_return;
 
2502
    }
 
2503
 
 
2504
    /* Add additional headers etc */
 
2505
    pjsua_process_msg_data( tdata, msg_data);
 
2506
 
 
2507
    /* Send the request */
 
2508
    status = pjsip_inv_send_msg( call->inv, tdata);
 
2509
    if (status != PJ_SUCCESS) {
 
2510
        pjsua_perror(THIS_FILE, "Unable to send UPDATE request", status);
 
2511
        goto on_return;
 
2512
    }
 
2513
 
 
2514
    call->local_hold = PJ_FALSE;
 
2515
 
 
2516
on_return:
 
2517
    if (dlg) pjsip_dlg_dec_lock(dlg);
 
2518
    pj_log_pop_indent();
 
2519
    return status;
 
2520
}
 
2521
 
 
2522
 
 
2523
/*
 
2524
 * Initiate call transfer to the specified address.
 
2525
 */
 
2526
PJ_DEF(pj_status_t) pjsua_call_xfer( pjsua_call_id call_id, 
 
2527
                                     const pj_str_t *dest,
 
2528
                                     const pjsua_msg_data *msg_data)
 
2529
{
 
2530
    pjsip_evsub *sub;
 
2531
    pjsip_tx_data *tdata;
 
2532
    pjsua_call *call;
 
2533
    pjsip_dialog *dlg = NULL;
 
2534
    pjsip_generic_string_hdr *gs_hdr;
 
2535
    const pj_str_t str_ref_by = { "Referred-By", 11 };
 
2536
    struct pjsip_evsub_user xfer_cb;
 
2537
    pj_status_t status;
 
2538
 
 
2539
 
 
2540
    PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls &&
 
2541
                     dest, PJ_EINVAL);
 
2542
    
 
2543
    PJ_LOG(4,(THIS_FILE, "Transfering call %d to %.*s", call_id,
 
2544
                         (int)dest->slen, dest->ptr));
 
2545
    pj_log_push_indent();
 
2546
 
 
2547
    status = acquire_call("pjsua_call_xfer()", call_id, &call, &dlg);
 
2548
    if (status != PJ_SUCCESS)
 
2549
        goto on_return;
 
2550
   
 
2551
    /* Create xfer client subscription. */
 
2552
    pj_bzero(&xfer_cb, sizeof(xfer_cb));
 
2553
    xfer_cb.on_evsub_state = &xfer_client_on_evsub_state;
 
2554
 
 
2555
    status = pjsip_xfer_create_uac(call->inv->dlg, &xfer_cb, &sub);
 
2556
    if (status != PJ_SUCCESS) {
 
2557
        pjsua_perror(THIS_FILE, "Unable to create xfer", status);
 
2558
        goto on_return;
 
2559
    }
 
2560
 
 
2561
    /* Associate this call with the client subscription */
 
2562
    pjsip_evsub_set_mod_data(sub, pjsua_var.mod.id, call);
 
2563
 
 
2564
    /*
 
2565
     * Create REFER request.
 
2566
     */
 
2567
    status = pjsip_xfer_initiate(sub, dest, &tdata);
 
2568
    if (status != PJ_SUCCESS) {
 
2569
        pjsua_perror(THIS_FILE, "Unable to create REFER request", status);
 
2570
        goto on_return;
 
2571
    }
 
2572
 
 
2573
    /* Add Referred-By header */
 
2574
    gs_hdr = pjsip_generic_string_hdr_create(tdata->pool, &str_ref_by,
 
2575
                                             &dlg->local.info_str);
 
2576
    pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)gs_hdr);
 
2577
 
 
2578
 
 
2579
    /* Add additional headers etc */
 
2580
    pjsua_process_msg_data( tdata, msg_data);
 
2581
 
 
2582
    /* Send. */
 
2583
    status = pjsip_xfer_send_request(sub, tdata);
 
2584
    if (status != PJ_SUCCESS) {
 
2585
        pjsua_perror(THIS_FILE, "Unable to send REFER request", status);
 
2586
        goto on_return;
 
2587
    }
 
2588
 
 
2589
    /* For simplicity (that's what this program is intended to be!), 
 
2590
     * leave the original invite session as it is. More advanced application
 
2591
     * may want to hold the INVITE, or terminate the invite, or whatever.
 
2592
     */
 
2593
on_return:
 
2594
    if (dlg) pjsip_dlg_dec_lock(dlg);
 
2595
    pj_log_pop_indent();
 
2596
    return status;
 
2597
 
 
2598
}
 
2599
 
 
2600
 
 
2601
/*
 
2602
 * Initiate attended call transfer to the specified address.
 
2603
 */
 
2604
PJ_DEF(pj_status_t) pjsua_call_xfer_replaces( pjsua_call_id call_id, 
 
2605
                                              pjsua_call_id dest_call_id,
 
2606
                                              unsigned options,
 
2607
                                              const pjsua_msg_data *msg_data)
 
2608
{
 
2609
    pjsua_call *dest_call;
 
2610
    pjsip_dialog *dest_dlg;
 
2611
    char str_dest_buf[PJSIP_MAX_URL_SIZE*2];
 
2612
    pj_str_t str_dest;
 
2613
    int len;
 
2614
    pjsip_uri *uri;
 
2615
    pj_status_t status;
 
2616
    
 
2617
 
 
2618
    PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
 
2619
                     PJ_EINVAL);
 
2620
    PJ_ASSERT_RETURN(dest_call_id>=0 && 
 
2621
                      dest_call_id<(int)pjsua_var.ua_cfg.max_calls,
 
2622
                     PJ_EINVAL);
 
2623
    
 
2624
    PJ_LOG(4,(THIS_FILE, "Transfering call %d replacing with call %d",
 
2625
                         call_id, dest_call_id));
 
2626
    pj_log_push_indent();
 
2627
 
 
2628
    status = acquire_call("pjsua_call_xfer_replaces()", dest_call_id, 
 
2629
                          &dest_call, &dest_dlg);
 
2630
    if (status != PJ_SUCCESS) {
 
2631
        pj_log_pop_indent();
 
2632
        return status;
 
2633
    }
 
2634
        
 
2635
    /* 
 
2636
     * Create REFER destination URI with Replaces field.
 
2637
     */
 
2638
 
 
2639
    /* Make sure we have sufficient buffer's length */
 
2640
    PJ_ASSERT_ON_FAIL(dest_dlg->remote.info_str.slen +
 
2641
                      dest_dlg->call_id->id.slen +
 
2642
                      dest_dlg->remote.info->tag.slen +
 
2643
                      dest_dlg->local.info->tag.slen + 32 
 
2644
                      < (long)sizeof(str_dest_buf),
 
2645
                      { status=PJSIP_EURITOOLONG; goto on_error; });
 
2646
 
 
2647
    /* Print URI */
 
2648
    str_dest_buf[0] = '<';
 
2649
    str_dest.slen = 1;
 
2650
 
 
2651
    uri = (pjsip_uri*) pjsip_uri_get_uri(dest_dlg->remote.info->uri);
 
2652
    len = pjsip_uri_print(PJSIP_URI_IN_REQ_URI, uri, 
 
2653
                          str_dest_buf+1, sizeof(str_dest_buf)-1);
 
2654
    if (len < 0) {
 
2655
        status = PJSIP_EURITOOLONG;
 
2656
        goto on_error;
 
2657
    }
 
2658
 
 
2659
    str_dest.slen += len;
 
2660
 
 
2661
 
 
2662
    /* Build the URI */
 
2663
    len = pj_ansi_snprintf(str_dest_buf + str_dest.slen, 
 
2664
                           sizeof(str_dest_buf) - str_dest.slen,
 
2665
                           "?%s"
 
2666
                           "Replaces=%.*s"
 
2667
                           "%%3Bto-tag%%3D%.*s"
 
2668
                           "%%3Bfrom-tag%%3D%.*s>",
 
2669
                           ((options&PJSUA_XFER_NO_REQUIRE_REPLACES) ?
 
2670
                            "" : "Require=replaces&"),
 
2671
                           (int)dest_dlg->call_id->id.slen,
 
2672
                           dest_dlg->call_id->id.ptr,
 
2673
                           (int)dest_dlg->remote.info->tag.slen,
 
2674
                           dest_dlg->remote.info->tag.ptr,
 
2675
                           (int)dest_dlg->local.info->tag.slen,
 
2676
                           dest_dlg->local.info->tag.ptr);
 
2677
 
 
2678
    PJ_ASSERT_ON_FAIL(len > 0 && len <= (int)sizeof(str_dest_buf)-str_dest.slen,
 
2679
                      { status=PJSIP_EURITOOLONG; goto on_error; });
 
2680
    
 
2681
    str_dest.ptr = str_dest_buf;
 
2682
    str_dest.slen += len;
 
2683
 
 
2684
    pjsip_dlg_dec_lock(dest_dlg);
 
2685
    
 
2686
    status = pjsua_call_xfer(call_id, &str_dest, msg_data);
 
2687
 
 
2688
    pj_log_pop_indent();
 
2689
    return status;
 
2690
 
 
2691
on_error:
 
2692
    if (dest_dlg) pjsip_dlg_dec_lock(dest_dlg);
 
2693
    pj_log_pop_indent();
 
2694
    return status;
 
2695
}
 
2696
 
 
2697
 
 
2698
/**
 
2699
 * Send instant messaging inside INVITE session.
 
2700
 */
 
2701
PJ_DEF(pj_status_t) pjsua_call_send_im( pjsua_call_id call_id, 
 
2702
                                        const pj_str_t *mime_type,
 
2703
                                        const pj_str_t *content,
 
2704
                                        const pjsua_msg_data *msg_data,
 
2705
                                        void *user_data)
 
2706
{
 
2707
    pjsua_call *call;
 
2708
    pjsip_dialog *dlg = NULL;
 
2709
    const pj_str_t mime_text_plain = pj_str("text/plain");
 
2710
    pjsip_media_type ctype;
 
2711
    pjsua_im_data *im_data;
 
2712
    pjsip_tx_data *tdata;
 
2713
    pj_status_t status;
 
2714
 
 
2715
    PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
 
2716
                     PJ_EINVAL);
 
2717
 
 
2718
    PJ_LOG(4,(THIS_FILE, "Call %d sending %d bytes MESSAGE..",
 
2719
                          call_id, (int)content->slen));
 
2720
    pj_log_push_indent();
 
2721
 
 
2722
    status = acquire_call("pjsua_call_send_im()", call_id, &call, &dlg);
 
2723
    if (status != PJ_SUCCESS)
 
2724
        goto on_return;
 
2725
    
 
2726
    /* Set default media type if none is specified */
 
2727
    if (mime_type == NULL) {
 
2728
        mime_type = &mime_text_plain;
 
2729
    }
 
2730
 
 
2731
    /* Create request message. */
 
2732
    status = pjsip_dlg_create_request( call->inv->dlg, &pjsip_message_method,
 
2733
                                       -1, &tdata);
 
2734
    if (status != PJ_SUCCESS) {
 
2735
        pjsua_perror(THIS_FILE, "Unable to create MESSAGE request", status);
 
2736
        goto on_return;
 
2737
    }
 
2738
 
 
2739
    /* Add accept header. */
 
2740
    pjsip_msg_add_hdr( tdata->msg, 
 
2741
                       (pjsip_hdr*)pjsua_im_create_accept(tdata->pool));
 
2742
 
 
2743
    /* Parse MIME type */
 
2744
    pjsua_parse_media_type(tdata->pool, mime_type, &ctype);
 
2745
 
 
2746
    /* Create "text/plain" message body. */
 
2747
    tdata->msg->body = pjsip_msg_body_create( tdata->pool, &ctype.type,
 
2748
                                              &ctype.subtype, content);
 
2749
    if (tdata->msg->body == NULL) {
 
2750
        pjsua_perror(THIS_FILE, "Unable to create msg body", PJ_ENOMEM);
 
2751
        pjsip_tx_data_dec_ref(tdata);
 
2752
        goto on_return;
 
2753
    }
 
2754
 
 
2755
    /* Add additional headers etc */
 
2756
    pjsua_process_msg_data( tdata, msg_data);
 
2757
 
 
2758
    /* Create IM data and attach to the request. */
 
2759
    im_data = PJ_POOL_ZALLOC_T(tdata->pool, pjsua_im_data);
 
2760
    im_data->acc_id = call->acc_id;
 
2761
    im_data->call_id = call_id;
 
2762
    im_data->to = call->inv->dlg->remote.info_str;
 
2763
    pj_strdup_with_null(tdata->pool, &im_data->body, content);
 
2764
    im_data->user_data = user_data;
 
2765
 
 
2766
 
 
2767
    /* Send the request. */
 
2768
    status = pjsip_dlg_send_request( call->inv->dlg, tdata, 
 
2769
                                     pjsua_var.mod.id, im_data);
 
2770
    if (status != PJ_SUCCESS) {
 
2771
        pjsua_perror(THIS_FILE, "Unable to send MESSAGE request", status);
 
2772
        goto on_return;
 
2773
    }
 
2774
 
 
2775
on_return:
 
2776
    if (dlg) pjsip_dlg_dec_lock(dlg);
 
2777
    pj_log_pop_indent();
 
2778
    return status;
 
2779
}
 
2780
 
 
2781
 
 
2782
/*
 
2783
 * Send IM typing indication inside INVITE session.
 
2784
 */
 
2785
PJ_DEF(pj_status_t) pjsua_call_send_typing_ind( pjsua_call_id call_id, 
 
2786
                                                pj_bool_t is_typing,
 
2787
                                                const pjsua_msg_data*msg_data)
 
2788
{
 
2789
    pjsua_call *call;
 
2790
    pjsip_dialog *dlg = NULL;
 
2791
    pjsip_tx_data *tdata;
 
2792
    pj_status_t status;
 
2793
 
 
2794
    PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
 
2795
                     PJ_EINVAL);
 
2796
 
 
2797
    PJ_LOG(4,(THIS_FILE, "Call %d sending typing indication..",
 
2798
                          call_id));
 
2799
    pj_log_push_indent();
 
2800
 
 
2801
    status = acquire_call("pjsua_call_send_typing_ind", call_id, &call, &dlg);
 
2802
    if (status != PJ_SUCCESS)
 
2803
        goto on_return;
 
2804
 
 
2805
    /* Create request message. */
 
2806
    status = pjsip_dlg_create_request( call->inv->dlg, &pjsip_message_method,
 
2807
                                       -1, &tdata);
 
2808
    if (status != PJ_SUCCESS) {
 
2809
        pjsua_perror(THIS_FILE, "Unable to create MESSAGE request", status);
 
2810
        goto on_return;
 
2811
    }
 
2812
 
 
2813
    /* Create "application/im-iscomposing+xml" msg body. */
 
2814
    tdata->msg->body = pjsip_iscomposing_create_body(tdata->pool, is_typing,
 
2815
                                                     NULL, NULL, -1);
 
2816
 
 
2817
    /* Add additional headers etc */
 
2818
    pjsua_process_msg_data( tdata, msg_data);
 
2819
 
 
2820
    /* Send the request. */
 
2821
    status = pjsip_dlg_send_request( call->inv->dlg, tdata, -1, NULL);
 
2822
    if (status != PJ_SUCCESS) {
 
2823
        pjsua_perror(THIS_FILE, "Unable to send MESSAGE request", status);
 
2824
        goto on_return;
 
2825
    }
 
2826
 
 
2827
on_return:
 
2828
    if (dlg) pjsip_dlg_dec_lock(dlg);
 
2829
    pj_log_pop_indent();
 
2830
    return status;
 
2831
}
 
2832
 
 
2833
 
 
2834
/*
 
2835
 * Send arbitrary request.
 
2836
 */
 
2837
PJ_DEF(pj_status_t) pjsua_call_send_request(pjsua_call_id call_id,
 
2838
                                            const pj_str_t *method_str,
 
2839
                                            const pjsua_msg_data *msg_data)
 
2840
{
 
2841
    pjsua_call *call;
 
2842
    pjsip_dialog *dlg = NULL;
 
2843
    pjsip_method method;
 
2844
    pjsip_tx_data *tdata;
 
2845
    pj_status_t status;
 
2846
 
 
2847
    PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
 
2848
                     PJ_EINVAL);
 
2849
 
 
2850
    PJ_LOG(4,(THIS_FILE, "Call %d sending %.*s request..",
 
2851
                          call_id, (int)method_str->slen, method_str->ptr));
 
2852
    pj_log_push_indent();
 
2853
 
 
2854
    status = acquire_call("pjsua_call_send_request", call_id, &call, &dlg);
 
2855
    if (status != PJ_SUCCESS)
 
2856
        goto on_return;
 
2857
 
 
2858
    /* Init method */
 
2859
    pjsip_method_init_np(&method, (pj_str_t*)method_str);
 
2860
 
 
2861
    /* Create request message. */
 
2862
    status = pjsip_dlg_create_request( call->inv->dlg, &method, -1, &tdata);
 
2863
    if (status != PJ_SUCCESS) {
 
2864
        pjsua_perror(THIS_FILE, "Unable to create request", status);
 
2865
        goto on_return;
 
2866
    }
 
2867
 
 
2868
    /* Add additional headers etc */
 
2869
    pjsua_process_msg_data( tdata, msg_data);
 
2870
 
 
2871
    /* Send the request. */
 
2872
    status = pjsip_dlg_send_request( call->inv->dlg, tdata, -1, NULL);
 
2873
    if (status != PJ_SUCCESS) {
 
2874
        pjsua_perror(THIS_FILE, "Unable to send request", status);
 
2875
        goto on_return;
 
2876
    }
 
2877
 
 
2878
on_return:
 
2879
    if (dlg) pjsip_dlg_dec_lock(dlg);
 
2880
    pj_log_pop_indent();
 
2881
    return status;
 
2882
}
 
2883
 
 
2884
 
 
2885
/*
 
2886
 * Terminate all calls.
 
2887
 */
 
2888
PJ_DEF(void) pjsua_call_hangup_all(void)
 
2889
{
 
2890
    unsigned i;
 
2891
 
 
2892
    PJ_LOG(4,(THIS_FILE, "Hangup all calls.."));
 
2893
    pj_log_push_indent();
 
2894
 
 
2895
    // This may deadlock, see https://trac.pjsip.org/repos/ticket/1305
 
2896
    //PJSUA_LOCK();
 
2897
 
 
2898
    for (i=0; i<pjsua_var.ua_cfg.max_calls; ++i) {
 
2899
        if (pjsua_var.calls[i].inv)
 
2900
            pjsua_call_hangup(i, 0, NULL, NULL);
 
2901
    }
 
2902
 
 
2903
    //PJSUA_UNLOCK();
 
2904
    pj_log_pop_indent();
 
2905
}
 
2906
 
 
2907
 
 
2908
/* Timer callback to send re-INVITE/UPDATE to lock codec or ICE update */
 
2909
static void reinv_timer_cb(pj_timer_heap_t *th, pj_timer_entry *entry)
 
2910
{
 
2911
    pjsua_call_id call_id = (pjsua_call_id)(pj_size_t)entry->user_data;
 
2912
    pjsip_dialog *dlg;
 
2913
    pjsua_call *call;
 
2914
    pj_status_t status;
 
2915
 
 
2916
    PJ_UNUSED_ARG(th);
 
2917
 
 
2918
    pjsua_var.calls[call_id].reinv_timer.id = PJ_FALSE;
 
2919
 
 
2920
    pj_log_push_indent();
 
2921
 
 
2922
    status = acquire_call("reinv_timer_cb()", call_id, &call, &dlg);
 
2923
    if (status != PJ_SUCCESS) {
 
2924
        pj_log_pop_indent();
 
2925
        return;
 
2926
    }
 
2927
 
 
2928
    process_pending_reinvite(call);
 
2929
 
 
2930
    pjsip_dlg_dec_lock(dlg);
 
2931
 
 
2932
    pj_log_pop_indent();
 
2933
}
 
2934
 
 
2935
 
 
2936
/* Check if the specified format can be skipped in counting codecs */
 
2937
static pj_bool_t is_non_av_fmt(const pjmedia_sdp_media *m,
 
2938
                               const pj_str_t *fmt)
 
2939
{
 
2940
    const pj_str_t STR_TEL = {"telephone-event", 15};
 
2941
    unsigned pt;
 
2942
 
 
2943
    pt = pj_strtoul(fmt);
 
2944
 
 
2945
    /* Check for comfort noise */
 
2946
    if (pt == PJMEDIA_RTP_PT_CN)
 
2947
        return PJ_TRUE;
 
2948
 
 
2949
    /* Dynamic PT, check the format name */
 
2950
    if (pt >= 96) {
 
2951
        pjmedia_sdp_attr *a;
 
2952
        pjmedia_sdp_rtpmap rtpmap;
 
2953
 
 
2954
        /* Get the format name */
 
2955
        a = pjmedia_sdp_attr_find2(m->attr_count, m->attr, "rtpmap", fmt);
 
2956
        if (a && pjmedia_sdp_attr_get_rtpmap(a, &rtpmap)==PJ_SUCCESS) {
 
2957
            /* Check for telephone-event */
 
2958
            if (pj_stricmp(&rtpmap.enc_name, &STR_TEL)==0)
 
2959
                return PJ_TRUE;
 
2960
        } else {
 
2961
            /* Invalid SDP, should not reach here */
 
2962
            pj_assert(!"SDP should have been validated!");
 
2963
            return PJ_TRUE;
 
2964
        }
 
2965
    }
 
2966
 
 
2967
    return PJ_FALSE;
 
2968
}
 
2969
 
 
2970
 
 
2971
/* Schedule check for the need of re-INVITE/UPDATE after media update, cases:
 
2972
 * - lock codec if remote answerer has given us more than one codecs
 
2973
 * - update ICE default transport address if it has changed after ICE
 
2974
 *   connectivity check.
 
2975
 */
 
2976
void pjsua_call_schedule_reinvite_check(pjsua_call *call, unsigned delay_ms)
 
2977
{
 
2978
    pj_time_val delay;
 
2979
 
 
2980
    /* Stop reinvite timer, if it is active */
 
2981
    if (call->reinv_timer.id)
 
2982
        pjsua_cancel_timer(&call->reinv_timer);
 
2983
 
 
2984
    delay.sec = 0;
 
2985
    delay.msec = delay_ms;
 
2986
    pj_time_val_normalize(&delay);
 
2987
    call->reinv_timer.id = PJ_TRUE;
 
2988
    pjsua_schedule_timer(&call->reinv_timer, &delay);
 
2989
}
 
2990
 
 
2991
 
 
2992
/* Check if lock codec is needed */
 
2993
static pj_bool_t check_lock_codec(pjsua_call *call)
 
2994
{
 
2995
    const pjmedia_sdp_session *local_sdp, *remote_sdp;
 
2996
    pj_bool_t has_mult_fmt = PJ_FALSE;
 
2997
    unsigned i;
 
2998
    pj_status_t status;
 
2999
 
 
3000
    /* Check if lock codec is disabled */
 
3001
    if (!pjsua_var.acc[call->acc_id].cfg.lock_codec)
 
3002
        return PJ_FALSE;
 
3003
 
 
3004
    /* Check lock codec retry count */
 
3005
    if (call->lock_codec.retry_cnt >= LOCK_CODEC_MAX_RETRY)
 
3006
        return PJ_FALSE;
 
3007
 
 
3008
    /* Check if we are the answerer, we shouldn't need to lock codec */
 
3009
    if (!call->inv->neg || !pjmedia_sdp_neg_was_answer_remote(call->inv->neg))
 
3010
        return PJ_FALSE;
 
3011
 
 
3012
    /* Check if remote answerer has given us more than one codecs. */
 
3013
    status = pjmedia_sdp_neg_get_active_local(call->inv->neg, &local_sdp);
 
3014
    if (status != PJ_SUCCESS)
 
3015
        return PJ_FALSE;
 
3016
    status = pjmedia_sdp_neg_get_active_remote(call->inv->neg, &remote_sdp);
 
3017
    if (status != PJ_SUCCESS)
 
3018
        return PJ_FALSE;
 
3019
 
 
3020
    for (i = 0; i < call->med_cnt && !has_mult_fmt; ++i) {
 
3021
        pjsua_call_media *call_med = &call->media[i];
 
3022
        const pjmedia_sdp_media *rem_m, *loc_m;
 
3023
        unsigned codec_cnt = 0;
 
3024
        unsigned j;
 
3025
 
 
3026
        /* Skip this if the media is inactive or error */
 
3027
        if (call_med->state == PJSUA_CALL_MEDIA_NONE ||
 
3028
            call_med->state == PJSUA_CALL_MEDIA_ERROR ||
 
3029
            call_med->dir == PJMEDIA_DIR_NONE)
 
3030
        {
 
3031
            continue;
 
3032
        }
 
3033
 
 
3034
        /* Remote may answer with less media lines. */
 
3035
        if (i >= remote_sdp->media_count)
 
3036
            continue;
 
3037
 
 
3038
        rem_m = remote_sdp->media[i];
 
3039
        loc_m = local_sdp->media[i];
 
3040
 
 
3041
        /* Verify that media must be active. */
 
3042
        pj_assert(loc_m->desc.port && rem_m->desc.port);
 
3043
 
 
3044
        /* Count the formats in the answer. */
 
3045
        for (j=0; j<rem_m->desc.fmt_count && codec_cnt <= 1; ++j) {
 
3046
            if (!is_non_av_fmt(rem_m, &rem_m->desc.fmt[j]) && ++codec_cnt > 1)
 
3047
                has_mult_fmt = PJ_TRUE;
 
3048
        }
 
3049
    }
 
3050
 
 
3051
    /* Reset retry count when remote answer has one codec */
 
3052
    if (!has_mult_fmt)
 
3053
        call->lock_codec.retry_cnt = 0;
 
3054
 
 
3055
    return has_mult_fmt;
 
3056
}
 
3057
 
 
3058
/* Check if ICE setup is complete and if it needs to send reinvite */
 
3059
static pj_bool_t check_ice_complete(pjsua_call *call, pj_bool_t *need_reinv)
 
3060
{
 
3061
    pj_bool_t ice_need_reinv = PJ_FALSE;
 
3062
    pj_bool_t ice_complete = PJ_TRUE;
 
3063
    unsigned i;
 
3064
 
 
3065
    /* Check if ICE setup is complete and if it needs reinvite */
 
3066
    for (i = 0; i < call->med_cnt; ++i) {
 
3067
        pjsua_call_media *call_med = &call->media[i];
 
3068
        pjmedia_transport_info tpinfo;
 
3069
        pjmedia_ice_transport_info *ice_info;
 
3070
        
 
3071
        if (call_med->tp_st == PJSUA_MED_TP_NULL ||
 
3072
            call_med->tp_st == PJSUA_MED_TP_DISABLED ||
 
3073
            call_med->state == PJSUA_CALL_MEDIA_ERROR)
 
3074
        {
 
3075
            continue;
 
3076
        }
 
3077
        
 
3078
        pjmedia_transport_info_init(&tpinfo);
 
3079
        pjmedia_transport_get_info(call_med->tp, &tpinfo);
 
3080
        ice_info = (pjmedia_ice_transport_info*)
 
3081
                   pjmedia_transport_info_get_spc_info(
 
3082
                                        &tpinfo, PJMEDIA_TRANSPORT_TYPE_ICE);
 
3083
 
 
3084
        /* Check if ICE is active */
 
3085
        if (!ice_info || !ice_info->active)
 
3086
            continue;
 
3087
 
 
3088
        /* Check if ICE setup not completed yet */
 
3089
        if (ice_info->sess_state < PJ_ICE_STRANS_STATE_RUNNING) {
 
3090
            ice_complete = PJ_FALSE;
 
3091
            break;
 
3092
        }
 
3093
        
 
3094
        /* Check if ICE needs to send reinvite */
 
3095
        if (!ice_need_reinv &&
 
3096
            ice_info->sess_state == PJ_ICE_STRANS_STATE_RUNNING &&
 
3097
            ice_info->role == PJ_ICE_SESS_ROLE_CONTROLLING)
 
3098
        {
 
3099
            pjsua_ice_config *cfg=&pjsua_var.acc[call->acc_id].cfg.ice_cfg;
 
3100
            if ((cfg->ice_always_update && !call->reinv_ice_sent) ||
 
3101
                pj_sockaddr_cmp(&tpinfo.sock_info.rtp_addr_name,
 
3102
                                &call_med->rtp_addr))
 
3103
            {
 
3104
                ice_need_reinv = PJ_TRUE;
 
3105
            }
 
3106
        }
 
3107
    }
 
3108
    
 
3109
    if (ice_complete && need_reinv)
 
3110
        *need_reinv = ice_need_reinv;
 
3111
    
 
3112
    return ice_complete;
 
3113
}
 
3114
 
 
3115
/* Check and send reinvite for lock codec and ICE update */
 
3116
static pj_status_t process_pending_reinvite(pjsua_call *call)
 
3117
{
 
3118
    const pj_str_t ST_UPDATE = {"UPDATE", 6};
 
3119
    pj_pool_t *pool = call->inv->pool_prov;
 
3120
    pjsip_inv_session *inv = call->inv;
 
3121
    pj_bool_t ice_need_reinv;
 
3122
    pj_bool_t ice_completed;
 
3123
    pj_bool_t need_lock_codec;
 
3124
    pj_bool_t rem_can_update;
 
3125
    pjmedia_sdp_session *new_offer;
 
3126
    pjsip_tx_data *tdata;
 
3127
    unsigned i;
 
3128
    pj_status_t status;
 
3129
 
 
3130
    /* Verify if another SDP negotiation is in progress, e.g: session timer
 
3131
     * or another re-INVITE.
 
3132
     */
 
3133
    if (inv==NULL || inv->neg==NULL ||
 
3134
        pjmedia_sdp_neg_get_state(inv->neg)!=PJMEDIA_SDP_NEG_STATE_DONE)
 
3135
    {
 
3136
        return PJMEDIA_SDPNEG_EINSTATE;
 
3137
    }
 
3138
 
 
3139
    /* Don't do this if call is disconnecting! */
 
3140
    if (inv->state > PJSIP_INV_STATE_CONFIRMED || inv->cause >= 200)
 
3141
    {
 
3142
        return PJ_EINVALIDOP;
 
3143
    }
 
3144
 
 
3145
    /* Delay this when the SDP negotiation done in call state EARLY and
 
3146
     * remote does not support UPDATE method.
 
3147
     */
 
3148
    if (inv->state == PJSIP_INV_STATE_EARLY && 
 
3149
        pjsip_dlg_remote_has_cap(inv->dlg, PJSIP_H_ALLOW, NULL, &ST_UPDATE)!=
 
3150
        PJSIP_DIALOG_CAP_SUPPORTED)
 
3151
    {
 
3152
        call->reinv_pending = PJ_TRUE;
 
3153
        return PJ_EPENDING;
 
3154
    }
 
3155
 
 
3156
    /* Check if ICE setup is complete and if it needs reinvite */
 
3157
    ice_completed = check_ice_complete(call, &ice_need_reinv);
 
3158
    if (!ice_completed)
 
3159
        return PJ_EPENDING;
 
3160
 
 
3161
    /* Check if we need to lock codec */
 
3162
    need_lock_codec = check_lock_codec(call);
 
3163
 
 
3164
    /* Check if reinvite is really needed */
 
3165
    if (!need_lock_codec && !ice_need_reinv)
 
3166
        return PJ_SUCCESS;
 
3167
 
 
3168
    
 
3169
    /* Okay! So we need to send re-INVITE/UPDATE */
 
3170
 
 
3171
    /* Check if remote support UPDATE */
 
3172
    rem_can_update = pjsip_dlg_remote_has_cap(inv->dlg, PJSIP_H_ALLOW, NULL,
 
3173
                                              &ST_UPDATE) ==
 
3174
                                                PJSIP_DIALOG_CAP_SUPPORTED;
 
3175
 
 
3176
    /* Logging stuff */
 
3177
    {
 
3178
        const char *ST_ICE_UPDATE = "ICE transport address after "
 
3179
                                    "ICE negotiation";
 
3180
        const char *ST_LOCK_CODEC = "media session to use only one codec";
 
3181
        PJ_LOG(4,(THIS_FILE, "Call %d sending %s for updating %s%s%s",
 
3182
                  call->index,
 
3183
                  (rem_can_update? "UPDATE" : "re-INVITE"),
 
3184
                  (ice_need_reinv? ST_ICE_UPDATE : ST_LOCK_CODEC),
 
3185
                  (ice_need_reinv && need_lock_codec? " and " : ""),
 
3186
                  (ice_need_reinv && need_lock_codec? ST_LOCK_CODEC : "")
 
3187
                  ));
 
3188
    }
 
3189
    
 
3190
    /* Generate SDP re-offer */
 
3191
    status = pjsua_media_channel_create_sdp(call->index, pool, NULL,
 
3192
                                            &new_offer, NULL);
 
3193
    if (status != PJ_SUCCESS) {
 
3194
        pjsua_perror(THIS_FILE, "Unable to create local SDP", status);
 
3195
        return status;
 
3196
    }
 
3197
 
 
3198
    /* Update the new offer so it contains only a codec. Note that
 
3199
     * SDP nego has removed unmatched codecs from the offer and the codec
 
3200
     * order in the offer has been matched to the answer, so we'll override
 
3201
     * the codecs in the just generated SDP with the ones from the active
 
3202
     * local SDP and leave just one codec for the next SDP re-offer.
 
3203
     */
 
3204
    if (need_lock_codec) {
 
3205
        const pjmedia_sdp_session *ref_sdp;
 
3206
        
 
3207
        /* Get local active SDP as reference */
 
3208
        status = pjmedia_sdp_neg_get_active_local(call->inv->neg, &ref_sdp);
 
3209
        if (status != PJ_SUCCESS)
 
3210
            return status;
 
3211
        
 
3212
        /* Verify media count. Note that remote may add/remove media line
 
3213
         * in the answer. When answer has less media, it must have been
 
3214
         * handled by pjsua_media_channel_update() as disabled media.
 
3215
         * When answer has more media, it must have been ignored (treated
 
3216
         * as non-exist) anywhere. Local media count should not be updated
 
3217
         * at this point, as modifying media count operation (i.e: reinvite,
 
3218
         * update, vid_set_strm) is currently blocking, protected with
 
3219
         * dialog mutex, and eventually reset SDP nego state to LOCAL OFFER.
 
3220
         */
 
3221
        if (call->med_cnt != ref_sdp->media_count ||
 
3222
            ref_sdp->media_count != new_offer->media_count)
 
3223
        {
 
3224
            /* Anyway, just in case, let's just return error */
 
3225
            return PJMEDIA_SDPNEG_EINSTATE;
 
3226
        }
 
3227
 
 
3228
        for (i = 0; i < call->med_cnt; ++i) {
 
3229
            unsigned j, codec_cnt = 0;
 
3230
            const pjmedia_sdp_media *ref_m = ref_sdp->media[i];
 
3231
            pjmedia_sdp_media *m = new_offer->media[i];
 
3232
            pjsua_call_media *call_med = &call->media[i];
 
3233
    
 
3234
            /* Verify if media is deactivated */
 
3235
            if (call_med->state == PJSUA_CALL_MEDIA_NONE ||
 
3236
                call_med->state == PJSUA_CALL_MEDIA_ERROR ||
 
3237
                call_med->dir == PJMEDIA_DIR_NONE)
 
3238
            {
 
3239
                continue;
 
3240
            }
 
3241
    
 
3242
            /* Reset formats */
 
3243
            m->desc.fmt_count = 0;
 
3244
            pjmedia_sdp_attr_remove_all(&m->attr_count, m->attr, "rtpmap");
 
3245
            pjmedia_sdp_attr_remove_all(&m->attr_count, m->attr, "fmtp");
 
3246
            
 
3247
            /* Copy only the first format + any non-AV formats from
 
3248
             * the active local SDP.
 
3249
             */
 
3250
            for (j = 0; j < ref_m->desc.fmt_count; ++j) {
 
3251
                const pj_str_t *fmt = &ref_m->desc.fmt[j];
 
3252
 
 
3253
                if (is_non_av_fmt(ref_m, fmt) || (++codec_cnt == 1)) {
 
3254
                    pjmedia_sdp_attr *a;
 
3255
                    
 
3256
                    m->desc.fmt[m->desc.fmt_count++] = *fmt;
 
3257
                    a = pjmedia_sdp_attr_find2(ref_m->attr_count, ref_m->attr,
 
3258
                                               "rtpmap", fmt);
 
3259
                    if (a) pjmedia_sdp_attr_add(&m->attr_count, m->attr, a);
 
3260
                    a = pjmedia_sdp_attr_find2(ref_m->attr_count, ref_m->attr,
 
3261
                                               "fmtp", fmt);
 
3262
                    if (a) pjmedia_sdp_attr_add(&m->attr_count, m->attr, a);
 
3263
                }
 
3264
            }
 
3265
        }
 
3266
    }
 
3267
 
 
3268
    /* Put back original direction and "c=0.0.0.0" line */
 
3269
    {
 
3270
        const pjmedia_sdp_session *cur_sdp;
 
3271
        
 
3272
        /* Get local active SDP */
 
3273
        status = pjmedia_sdp_neg_get_active_local(call->inv->neg, &cur_sdp);
 
3274
        if (status != PJ_SUCCESS)
 
3275
            return status;
 
3276
 
 
3277
        /* Make sure media count has not been changed */
 
3278
        if (call->med_cnt != cur_sdp->media_count)
 
3279
            return PJMEDIA_SDPNEG_EINSTATE;
 
3280
 
 
3281
        for (i = 0; i < call->med_cnt; ++i) {
 
3282
            const pjmedia_sdp_media *m = cur_sdp->media[i];
 
3283
            pjmedia_sdp_media *new_m = new_offer->media[i];
 
3284
            pjsua_call_media *call_med = &call->media[i];
 
3285
            pjmedia_sdp_attr *a = NULL;
 
3286
 
 
3287
            /* Update direction to the current dir */
 
3288
            pjmedia_sdp_media_remove_all_attr(new_m, "sendrecv");
 
3289
            pjmedia_sdp_media_remove_all_attr(new_m, "sendonly");
 
3290
            pjmedia_sdp_media_remove_all_attr(new_m, "recvonly");
 
3291
            pjmedia_sdp_media_remove_all_attr(new_m, "inactive");
 
3292
 
 
3293
            if (call_med->dir == PJMEDIA_DIR_ENCODING_DECODING) {
 
3294
                a = pjmedia_sdp_attr_create(pool, "sendrecv", NULL);
 
3295
            } else if (call_med->dir == PJMEDIA_DIR_ENCODING) {
 
3296
                a = pjmedia_sdp_attr_create(pool, "sendonly", NULL);
 
3297
            } else if (call_med->dir == PJMEDIA_DIR_DECODING) {
 
3298
                a = pjmedia_sdp_attr_create(pool, "recvonly", NULL);
 
3299
            } else {
 
3300
                const pjmedia_sdp_conn *conn;
 
3301
                a = pjmedia_sdp_attr_create(pool, "inactive", NULL);
 
3302
 
 
3303
                /* Also check if the original c= line address is zero */
 
3304
                conn = m->conn;
 
3305
                if (!conn)
 
3306
                    conn = cur_sdp->conn;
 
3307
                if (pj_strcmp2(&conn->addr, "0.0.0.0")==0 ||
 
3308
                    pj_strcmp2(&conn->addr, "0")==0)
 
3309
                {
 
3310
                    if (!new_m->conn) {
 
3311
                        new_m->conn = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_conn);
 
3312
                    }
 
3313
 
 
3314
                    if (pj_strcmp2(&new_m->conn->addr, "0.0.0.0")) {
 
3315
                        new_m->conn->net_type = pj_str("IN");
 
3316
                        new_m->conn->addr_type = pj_str("IP4");
 
3317
                        new_m->conn->addr = pj_str("0.0.0.0");
 
3318
                    }
 
3319
                }
 
3320
            }
 
3321
 
 
3322
            pj_assert(a);
 
3323
            pjmedia_sdp_media_add_attr(new_m, a);
 
3324
        }
 
3325
    }
 
3326
 
 
3327
    
 
3328
    if (rem_can_update) {
 
3329
        status = pjsip_inv_update(inv, NULL, new_offer, &tdata);
 
3330
    } else {
 
3331
        status = pjsip_inv_reinvite(inv, NULL, new_offer, &tdata);
 
3332
    }
 
3333
 
 
3334
    if (status==PJ_EINVALIDOP &&
 
3335
        ++call->lock_codec.retry_cnt < LOCK_CODEC_MAX_RETRY)
 
3336
    {
 
3337
        /* Ups, let's reschedule again */
 
3338
        pjsua_call_schedule_reinvite_check(call, LOCK_CODEC_RETRY_INTERVAL);
 
3339
        return PJ_SUCCESS;
 
3340
    } else if (status != PJ_SUCCESS) {
 
3341
        pjsua_perror(THIS_FILE, "Error creating UPDATE/re-INVITE",
 
3342
                     status);
 
3343
        return status;
 
3344
    }
 
3345
 
 
3346
    /* Send the UPDATE/re-INVITE request */
 
3347
    status = pjsip_inv_send_msg(inv, tdata);
 
3348
    if (status != PJ_SUCCESS) {
 
3349
        pjsua_perror(THIS_FILE, "Error sending UPDATE/re-INVITE",
 
3350
                     status);
 
3351
        return status;
 
3352
    }
 
3353
 
 
3354
    /* Update flags */
 
3355
    if (ice_need_reinv)
 
3356
        call->reinv_ice_sent = PJ_TRUE;
 
3357
    if (need_lock_codec)
 
3358
        ++call->lock_codec.retry_cnt;
 
3359
    
 
3360
    return PJ_SUCCESS;
 
3361
}
 
3362
 
 
3363
 
 
3364
/*
 
3365
 * This callback receives notification from invite session when the
 
3366
 * session state has changed.
 
3367
 */
 
3368
static void pjsua_call_on_state_changed(pjsip_inv_session *inv, 
 
3369
                                        pjsip_event *e)
 
3370
{
 
3371
    pjsua_call *call;
 
3372
 
 
3373
    pj_log_push_indent();
 
3374
 
 
3375
    call = (pjsua_call*) inv->dlg->mod_data[pjsua_var.mod.id];
 
3376
 
 
3377
    if (!call) {
 
3378
        pj_log_pop_indent();
 
3379
        return;
 
3380
    }
 
3381
 
 
3382
 
 
3383
    /* Get call times */
 
3384
    switch (inv->state) {
 
3385
        case PJSIP_INV_STATE_EARLY:
 
3386
        case PJSIP_INV_STATE_CONNECTING:
 
3387
            if (call->res_time.sec == 0)
 
3388
                pj_gettimeofday(&call->res_time);
 
3389
            call->last_code = (pjsip_status_code) 
 
3390
                              e->body.tsx_state.tsx->status_code;
 
3391
            pj_strncpy(&call->last_text, 
 
3392
                       &e->body.tsx_state.tsx->status_text,
 
3393
                       sizeof(call->last_text_buf_));
 
3394
            break;
 
3395
        case PJSIP_INV_STATE_CONFIRMED:
 
3396
            pj_gettimeofday(&call->conn_time);
 
3397
 
 
3398
            /* See if auto reinvite was pended as media update was done in the
 
3399
             * EARLY state and remote does not support UPDATE.
 
3400
             */
 
3401
            if (call->reinv_pending) {
 
3402
                call->reinv_pending = PJ_FALSE;
 
3403
                pjsua_call_schedule_reinvite_check(call, 0);
 
3404
            }
 
3405
            break;
 
3406
        case PJSIP_INV_STATE_DISCONNECTED:
 
3407
            pj_gettimeofday(&call->dis_time);
 
3408
            if (call->res_time.sec == 0)
 
3409
                pj_gettimeofday(&call->res_time);
 
3410
            if (e->type == PJSIP_EVENT_TSX_STATE && 
 
3411
                e->body.tsx_state.tsx->status_code > call->last_code) 
 
3412
            {
 
3413
                call->last_code = (pjsip_status_code) 
 
3414
                                  e->body.tsx_state.tsx->status_code;
 
3415
                pj_strncpy(&call->last_text, 
 
3416
                           &e->body.tsx_state.tsx->status_text,
 
3417
                           sizeof(call->last_text_buf_));
 
3418
            } else {
 
3419
                call->last_code = PJSIP_SC_REQUEST_TERMINATED;
 
3420
                pj_strncpy(&call->last_text,
 
3421
                           pjsip_get_status_text(call->last_code),
 
3422
                           sizeof(call->last_text_buf_));
 
3423
            }
 
3424
 
 
3425
            /* Stop reinvite timer, if it is active */
 
3426
            if (call->reinv_timer.id) {
 
3427
                pjsua_cancel_timer(&call->reinv_timer);
 
3428
                call->reinv_timer.id = PJ_FALSE;
 
3429
            }
 
3430
            break;
 
3431
        default:
 
3432
            call->last_code = (pjsip_status_code) 
 
3433
                              e->body.tsx_state.tsx->status_code;
 
3434
            pj_strncpy(&call->last_text, 
 
3435
                       &e->body.tsx_state.tsx->status_text,
 
3436
                       sizeof(call->last_text_buf_));
 
3437
            break;
 
3438
    }
 
3439
 
 
3440
    /* If this is an outgoing INVITE that was created because of
 
3441
     * REFER/transfer, send NOTIFY to transferer.
 
3442
     */
 
3443
    if (call->xfer_sub && e->type==PJSIP_EVENT_TSX_STATE)  {
 
3444
        int st_code = -1;
 
3445
        pjsip_evsub_state ev_state = PJSIP_EVSUB_STATE_ACTIVE;
 
3446
        
 
3447
 
 
3448
        switch (call->inv->state) {
 
3449
        case PJSIP_INV_STATE_NULL:
 
3450
        case PJSIP_INV_STATE_CALLING:
 
3451
            /* Do nothing */
 
3452
            break;
 
3453
 
 
3454
        case PJSIP_INV_STATE_EARLY:
 
3455
        case PJSIP_INV_STATE_CONNECTING:
 
3456
            st_code = e->body.tsx_state.tsx->status_code;
 
3457
            if (call->inv->state == PJSIP_INV_STATE_CONNECTING)
 
3458
                ev_state = PJSIP_EVSUB_STATE_TERMINATED;
 
3459
            else
 
3460
                ev_state = PJSIP_EVSUB_STATE_ACTIVE;
 
3461
            break;
 
3462
 
 
3463
        case PJSIP_INV_STATE_CONFIRMED:
 
3464
#if 0
 
3465
/* We don't need this, as we've terminated the subscription in
 
3466
 * CONNECTING state.
 
3467
 */
 
3468
            /* When state is confirmed, send the final 200/OK and terminate
 
3469
             * subscription.
 
3470
             */
 
3471
            st_code = e->body.tsx_state.tsx->status_code;
 
3472
            ev_state = PJSIP_EVSUB_STATE_TERMINATED;
 
3473
#endif
 
3474
            break;
 
3475
 
 
3476
        case PJSIP_INV_STATE_DISCONNECTED:
 
3477
            st_code = e->body.tsx_state.tsx->status_code;
 
3478
            ev_state = PJSIP_EVSUB_STATE_TERMINATED;
 
3479
            break;
 
3480
 
 
3481
        case PJSIP_INV_STATE_INCOMING:
 
3482
            /* Nothing to do. Just to keep gcc from complaining about
 
3483
             * unused enums.
 
3484
             */
 
3485
            break;
 
3486
        }
 
3487
 
 
3488
        if (st_code != -1) {
 
3489
            pjsip_tx_data *tdata;
 
3490
            pj_status_t status;
 
3491
 
 
3492
            status = pjsip_xfer_notify( call->xfer_sub,
 
3493
                                        ev_state, st_code,
 
3494
                                        NULL, &tdata);
 
3495
            if (status != PJ_SUCCESS) {
 
3496
                pjsua_perror(THIS_FILE, "Unable to create NOTIFY", status);
 
3497
            } else {
 
3498
                status = pjsip_xfer_send_request(call->xfer_sub, tdata);
 
3499
                if (status != PJ_SUCCESS) {
 
3500
                    pjsua_perror(THIS_FILE, "Unable to send NOTIFY", status);
 
3501
                }
 
3502
            }
 
3503
        }
 
3504
    }
 
3505
 
 
3506
    /* Ticket #1627: Invoke on_call_tsx_state() when call is disconnected. */
 
3507
    if (inv->state == PJSIP_INV_STATE_DISCONNECTED &&
 
3508
        e->type == PJSIP_EVENT_TSX_STATE &&
 
3509
        call->inv &&
 
3510
        pjsua_var.ua_cfg.cb.on_call_tsx_state)
 
3511
    {
 
3512
        (*pjsua_var.ua_cfg.cb.on_call_tsx_state)(call->index,
 
3513
                                                 e->body.tsx_state.tsx, e);
 
3514
    }
 
3515
 
 
3516
    if (pjsua_var.ua_cfg.cb.on_call_state)
 
3517
        (*pjsua_var.ua_cfg.cb.on_call_state)(call->index, e);
 
3518
 
 
3519
    /* call->inv may be NULL now */
 
3520
 
 
3521
    /* Destroy media session when invite session is disconnected. */
 
3522
    if (inv->state == PJSIP_INV_STATE_DISCONNECTED) {
 
3523
 
 
3524
        PJSUA_LOCK();
 
3525
        
 
3526
        pjsua_media_channel_deinit(call->index);
 
3527
 
 
3528
        /* Free call */
 
3529
        call->inv = NULL;
 
3530
 
 
3531
        pj_assert(pjsua_var.call_cnt > 0);
 
3532
        --pjsua_var.call_cnt;
 
3533
 
 
3534
        /* Reset call */
 
3535
        reset_call(call->index);
 
3536
 
 
3537
        pjsua_check_snd_dev_idle();
 
3538
 
 
3539
        PJSUA_UNLOCK();
 
3540
    }
 
3541
    pj_log_pop_indent();
 
3542
}
 
3543
 
 
3544
/*
 
3545
 * This callback is called by invite session framework when UAC session
 
3546
 * has forked.
 
3547
 */
 
3548
static void pjsua_call_on_forked( pjsip_inv_session *inv, 
 
3549
                                  pjsip_event *e)
 
3550
{
 
3551
    PJ_UNUSED_ARG(inv);
 
3552
    PJ_UNUSED_ARG(e);
 
3553
 
 
3554
    PJ_TODO(HANDLE_FORKED_DIALOG);
 
3555
}
 
3556
 
 
3557
 
 
3558
/*
 
3559
 * Callback from UA layer when forked dialog response is received.
 
3560
 */
 
3561
pjsip_dialog* on_dlg_forked(pjsip_dialog *dlg, pjsip_rx_data *res)
 
3562
{
 
3563
    if (dlg->uac_has_2xx && 
 
3564
        res->msg_info.cseq->method.id == PJSIP_INVITE_METHOD &&
 
3565
        pjsip_rdata_get_tsx(res) == NULL &&
 
3566
        res->msg_info.msg->line.status.code/100 == 2) 
 
3567
    {
 
3568
        pjsip_dialog *forked_dlg;
 
3569
        pjsip_tx_data *bye;
 
3570
        pj_status_t status;
 
3571
 
 
3572
        /* Create forked dialog */
 
3573
        status = pjsip_dlg_fork(dlg, res, &forked_dlg);
 
3574
        if (status != PJ_SUCCESS)
 
3575
            return NULL;
 
3576
 
 
3577
        pjsip_dlg_inc_lock(forked_dlg);
 
3578
 
 
3579
        /* Disconnect the call */
 
3580
        status = pjsip_dlg_create_request(forked_dlg, &pjsip_bye_method,
 
3581
                                          -1, &bye);
 
3582
        if (status == PJ_SUCCESS) {
 
3583
            status = pjsip_dlg_send_request(forked_dlg, bye, -1, NULL);
 
3584
        }
 
3585
 
 
3586
        pjsip_dlg_dec_lock(forked_dlg);
 
3587
 
 
3588
        if (status != PJ_SUCCESS) {
 
3589
            return NULL;
 
3590
        }
 
3591
 
 
3592
        return forked_dlg;
 
3593
 
 
3594
    } else {
 
3595
        return dlg;
 
3596
    }
 
3597
}
 
3598
 
 
3599
/*
 
3600
 * Disconnect call upon error.
 
3601
 */
 
3602
static void call_disconnect( pjsip_inv_session *inv, 
 
3603
                             int code )
 
3604
{
 
3605
    pjsua_call *call;
 
3606
    pjsip_tx_data *tdata;
 
3607
    pj_status_t status;
 
3608
 
 
3609
    call = (pjsua_call*) inv->dlg->mod_data[pjsua_var.mod.id];
 
3610
 
 
3611
    status = pjsip_inv_end_session(inv, code, NULL, &tdata);
 
3612
    if (status != PJ_SUCCESS)
 
3613
        return;
 
3614
 
 
3615
    /* Add SDP in 488 status */
 
3616
#if DISABLED_FOR_TICKET_1185
 
3617
    if (call && call->tp && tdata->msg->type==PJSIP_RESPONSE_MSG &&
 
3618
        code==PJSIP_SC_NOT_ACCEPTABLE_HERE) 
 
3619
    {
 
3620
        pjmedia_sdp_session *local_sdp;
 
3621
        pjmedia_transport_info ti;
 
3622
 
 
3623
        pjmedia_transport_info_init(&ti);
 
3624
        pjmedia_transport_get_info(call->med_tp, &ti);
 
3625
        status = pjmedia_endpt_create_sdp(pjsua_var.med_endpt, tdata->pool, 
 
3626
                                          1, &ti.sock_info, &local_sdp);
 
3627
        if (status == PJ_SUCCESS) {
 
3628
            pjsip_create_sdp_body(tdata->pool, local_sdp,
 
3629
                                  &tdata->msg->body);
 
3630
        }
 
3631
    }
 
3632
#endif
 
3633
 
 
3634
    pjsip_inv_send_msg(inv, tdata);
 
3635
}
 
3636
 
 
3637
/*
 
3638
 * Callback to be called when SDP offer/answer negotiation has just completed
 
3639
 * in the session. This function will start/update media if negotiation
 
3640
 * has succeeded.
 
3641
 */
 
3642
static void pjsua_call_on_media_update(pjsip_inv_session *inv,
 
3643
                                       pj_status_t status)
 
3644
{
 
3645
    pjsua_call *call;
 
3646
    const pjmedia_sdp_session *local_sdp;
 
3647
    const pjmedia_sdp_session *remote_sdp;
 
3648
    //const pj_str_t st_update = {"UPDATE", 6};
 
3649
 
 
3650
    pj_log_push_indent();
 
3651
 
 
3652
    call = (pjsua_call*) inv->dlg->mod_data[pjsua_var.mod.id];
 
3653
 
 
3654
    if (status != PJ_SUCCESS) {
 
3655
 
 
3656
        pjsua_perror(THIS_FILE, "SDP negotiation has failed", status);
 
3657
 
 
3658
        /* Clean up provisional media */
 
3659
        pjsua_media_prov_clean_up(call->index);
 
3660
 
 
3661
        /* Do not deinitialize media since this may be a re-INVITE or
 
3662
         * UPDATE (which in this case the media should not get affected
 
3663
         * by the failed re-INVITE/UPDATE). The media will be shutdown
 
3664
         * when call is disconnected anyway.
 
3665
         */
 
3666
        /* Stop/destroy media, if any */
 
3667
        /*pjsua_media_channel_deinit(call->index);*/
 
3668
 
 
3669
        /* Disconnect call if we're not in the middle of initializing an
 
3670
         * UAS dialog and if this is not a re-INVITE 
 
3671
         */
 
3672
        if (inv->state != PJSIP_INV_STATE_NULL &&
 
3673
            inv->state != PJSIP_INV_STATE_CONFIRMED) 
 
3674
        {
 
3675
            call_disconnect(inv, PJSIP_SC_UNSUPPORTED_MEDIA_TYPE);
 
3676
        }
 
3677
 
 
3678
        goto on_return;
 
3679
    }
 
3680
 
 
3681
 
 
3682
    /* Get local and remote SDP */
 
3683
    status = pjmedia_sdp_neg_get_active_local(call->inv->neg, &local_sdp);
 
3684
    if (status != PJ_SUCCESS) {
 
3685
        pjsua_perror(THIS_FILE, 
 
3686
                     "Unable to retrieve currently active local SDP", 
 
3687
                     status);
 
3688
        //call_disconnect(inv, PJSIP_SC_UNSUPPORTED_MEDIA_TYPE);
 
3689
        goto on_return;
 
3690
    }
 
3691
 
 
3692
    status = pjmedia_sdp_neg_get_active_remote(call->inv->neg, &remote_sdp);
 
3693
    if (status != PJ_SUCCESS) {
 
3694
        pjsua_perror(THIS_FILE, 
 
3695
                     "Unable to retrieve currently active remote SDP", 
 
3696
                     status);
 
3697
        //call_disconnect(inv, PJSIP_SC_UNSUPPORTED_MEDIA_TYPE);
 
3698
        goto on_return;
 
3699
    }
 
3700
 
 
3701
    /* Update remote's NAT type */
 
3702
    if (pjsua_var.ua_cfg.nat_type_in_sdp) {
 
3703
        update_remote_nat_type(call, remote_sdp);
 
3704
    }
 
3705
 
 
3706
    /* Update media channel with the new SDP */
 
3707
    status = pjsua_media_channel_update(call->index, local_sdp, remote_sdp);
 
3708
    if (status != PJ_SUCCESS) {
 
3709
        pjsua_perror(THIS_FILE, "Unable to create media session", 
 
3710
                     status);
 
3711
        call_disconnect(inv, PJSIP_SC_NOT_ACCEPTABLE_HERE);
 
3712
        /* No need to deinitialize; media will be shutdown when call
 
3713
         * state is disconnected anyway.
 
3714
         */
 
3715
        /*pjsua_media_channel_deinit(call->index);*/
 
3716
        goto on_return;
 
3717
    }
 
3718
 
 
3719
    /* Ticket #476: make sure only one codec is specified in the answer. */
 
3720
    pjsua_call_schedule_reinvite_check(call, 0);
 
3721
 
 
3722
    /* Call application callback, if any */
 
3723
    if (pjsua_var.ua_cfg.cb.on_call_media_state)
 
3724
        pjsua_var.ua_cfg.cb.on_call_media_state(call->index);
 
3725
 
 
3726
on_return:
 
3727
    pj_log_pop_indent();
 
3728
}
 
3729
 
 
3730
 
 
3731
/* Modify SDP for call hold. */
 
3732
static pj_status_t modify_sdp_of_call_hold(pjsua_call *call,
 
3733
                                           pj_pool_t *pool,
 
3734
                                           pjmedia_sdp_session *sdp)
 
3735
{
 
3736
    unsigned mi;
 
3737
 
 
3738
    /* Call-hold is done by set the media direction to 'sendonly' 
 
3739
     * (PJMEDIA_DIR_ENCODING), except when current media direction is 
 
3740
     * 'inactive' (PJMEDIA_DIR_NONE).
 
3741
     * (See RFC 3264 Section 8.4 and RFC 4317 Section 3.1)
 
3742
     */
 
3743
    /* http://trac.pjsip.org/repos/ticket/880 
 
3744
       if (call->dir != PJMEDIA_DIR_ENCODING) {
 
3745
     */
 
3746
    /* https://trac.pjsip.org/repos/ticket/1142:
 
3747
     *  configuration to use c=0.0.0.0 for call hold.
 
3748
     */
 
3749
 
 
3750
    for (mi=0; mi<sdp->media_count; ++mi) {
 
3751
        pjmedia_sdp_media *m = sdp->media[mi];
 
3752
 
 
3753
        if (call->call_hold_type == PJSUA_CALL_HOLD_TYPE_RFC2543) {
 
3754
            pjmedia_sdp_conn *conn;
 
3755
            pjmedia_sdp_attr *attr;
 
3756
 
 
3757
            /* Get SDP media connection line */
 
3758
            conn = m->conn;
 
3759
            if (!conn)
 
3760
                conn = sdp->conn;
 
3761
 
 
3762
            /* Modify address */
 
3763
            conn->addr = pj_str("0.0.0.0");
 
3764
 
 
3765
            /* Remove existing directions attributes */
 
3766
            pjmedia_sdp_media_remove_all_attr(m, "sendrecv");
 
3767
            pjmedia_sdp_media_remove_all_attr(m, "sendonly");
 
3768
            pjmedia_sdp_media_remove_all_attr(m, "recvonly");
 
3769
            pjmedia_sdp_media_remove_all_attr(m, "inactive");
 
3770
 
 
3771
            /* Add inactive attribute */
 
3772
            attr = pjmedia_sdp_attr_create(pool, "inactive", NULL);
 
3773
            pjmedia_sdp_media_add_attr(m, attr);
 
3774
 
 
3775
 
 
3776
        } else {
 
3777
            pjmedia_sdp_attr *attr;
 
3778
 
 
3779
            /* Remove existing directions attributes */
 
3780
            pjmedia_sdp_media_remove_all_attr(m, "sendrecv");
 
3781
            pjmedia_sdp_media_remove_all_attr(m, "sendonly");
 
3782
            pjmedia_sdp_media_remove_all_attr(m, "recvonly");
 
3783
            pjmedia_sdp_media_remove_all_attr(m, "inactive");
 
3784
 
 
3785
            if (call->media[mi].dir & PJMEDIA_DIR_ENCODING) {
 
3786
                /* Add sendonly attribute */
 
3787
                attr = pjmedia_sdp_attr_create(pool, "sendonly", NULL);
 
3788
                pjmedia_sdp_media_add_attr(m, attr);
 
3789
            } else {
 
3790
                /* Add inactive attribute */
 
3791
                attr = pjmedia_sdp_attr_create(pool, "inactive", NULL);
 
3792
                pjmedia_sdp_media_add_attr(m, attr);
 
3793
            }
 
3794
        }
 
3795
    }
 
3796
 
 
3797
    return PJ_SUCCESS;
 
3798
}
 
3799
 
 
3800
/* Create SDP for call hold. */
 
3801
static pj_status_t create_sdp_of_call_hold(pjsua_call *call,
 
3802
                                           pjmedia_sdp_session **p_sdp)
 
3803
{
 
3804
    pj_status_t status;
 
3805
    pj_pool_t *pool;
 
3806
    pjmedia_sdp_session *sdp;
 
3807
 
 
3808
    /* Use call's provisional pool */
 
3809
    pool = call->inv->pool_prov;
 
3810
 
 
3811
    /* Create new offer */
 
3812
    status = pjsua_media_channel_create_sdp(call->index, pool, NULL, &sdp,
 
3813
                                            NULL);
 
3814
    if (status != PJ_SUCCESS) {
 
3815
        pjsua_perror(THIS_FILE, "Unable to create local SDP", status);
 
3816
        return status;
 
3817
    }
 
3818
 
 
3819
    status = modify_sdp_of_call_hold(call, pool, sdp);
 
3820
    if (status != PJ_SUCCESS)
 
3821
        return status;
 
3822
 
 
3823
    *p_sdp = sdp;
 
3824
 
 
3825
    return PJ_SUCCESS;
 
3826
}
 
3827
 
 
3828
/*
 
3829
 * Called when session received new offer.
 
3830
 */
 
3831
static void pjsua_call_on_rx_offer(pjsip_inv_session *inv,
 
3832
                                   const pjmedia_sdp_session *offer)
 
3833
{
 
3834
    pjsua_call *call;
 
3835
    pjmedia_sdp_session *answer;
 
3836
    unsigned i;
 
3837
    pj_status_t status;
 
3838
 
 
3839
    call = (pjsua_call*) inv->dlg->mod_data[pjsua_var.mod.id];
 
3840
 
 
3841
    /* Supply candidate answer */
 
3842
    PJ_LOG(4,(THIS_FILE, "Call %d: received updated media offer",
 
3843
              call->index));
 
3844
    pj_log_push_indent();
 
3845
 
 
3846
    if (pjsua_var.ua_cfg.cb.on_call_rx_offer) {
 
3847
        pjsip_status_code code = PJSIP_SC_OK;
 
3848
        pjsua_call_setting opt = call->opt;
 
3849
        
 
3850
        (*pjsua_var.ua_cfg.cb.on_call_rx_offer)(call->index, offer, NULL,
 
3851
                                                &code, &opt);
 
3852
 
 
3853
        if (code != PJSIP_SC_OK) {
 
3854
            PJ_LOG(4,(THIS_FILE, "Rejecting updated media offer on call %d",
 
3855
                      call->index));
 
3856
            goto on_return;
 
3857
        }
 
3858
 
 
3859
        call->opt = opt;
 
3860
    }
 
3861
    
 
3862
    /* Re-init media for the new remote offer before creating SDP */
 
3863
    status = apply_call_setting(call, &call->opt, offer);
 
3864
    if (status != PJ_SUCCESS)
 
3865
        goto on_return;
 
3866
 
 
3867
    status = pjsua_media_channel_create_sdp(call->index, 
 
3868
                                            call->inv->pool_prov, 
 
3869
                                            offer, &answer, NULL);
 
3870
    if (status != PJ_SUCCESS) {
 
3871
        pjsua_perror(THIS_FILE, "Unable to create local SDP", status);
 
3872
        goto on_return;
 
3873
    }
 
3874
 
 
3875
    /* Validate media count in the generated answer */
 
3876
    pj_assert(answer->media_count == offer->media_count);
 
3877
 
 
3878
    /* Check if offer's conn address is zero */
 
3879
    for (i = 0; i < answer->media_count; ++i) {
 
3880
        pjmedia_sdp_conn *conn;
 
3881
 
 
3882
        conn = offer->media[i]->conn;
 
3883
        if (!conn)
 
3884
            conn = offer->conn;
 
3885
 
 
3886
        if (pj_strcmp2(&conn->addr, "0.0.0.0")==0 ||
 
3887
            pj_strcmp2(&conn->addr, "0")==0)
 
3888
        {
 
3889
            pjmedia_sdp_conn *a_conn = answer->media[i]->conn;
 
3890
 
 
3891
            /* Modify answer address */
 
3892
            if (a_conn) {
 
3893
                a_conn->addr = pj_str("0.0.0.0");
 
3894
            } else if (answer->conn == NULL ||
 
3895
                       pj_strcmp2(&answer->conn->addr, "0.0.0.0") != 0)
 
3896
            {
 
3897
                a_conn = PJ_POOL_ZALLOC_T(call->inv->pool_prov,
 
3898
                                          pjmedia_sdp_conn);
 
3899
                a_conn->net_type = pj_str("IN");
 
3900
                a_conn->addr_type = pj_str("IP4");
 
3901
                a_conn->addr = pj_str("0.0.0.0");
 
3902
                answer->media[i]->conn = a_conn;
 
3903
            }
 
3904
        }
 
3905
    }
 
3906
 
 
3907
    /* Check if call is on-hold */
 
3908
    if (call->local_hold) {
 
3909
        modify_sdp_of_call_hold(call, call->inv->pool_prov, answer);
 
3910
    }
 
3911
 
 
3912
    status = pjsip_inv_set_sdp_answer(call->inv, answer);
 
3913
    if (status != PJ_SUCCESS) {
 
3914
        pjsua_perror(THIS_FILE, "Unable to set answer", status);
 
3915
        goto on_return;
 
3916
    }
 
3917
 
 
3918
on_return:
 
3919
    pj_log_pop_indent();
 
3920
}
 
3921
 
 
3922
 
 
3923
/*
 
3924
 * Called to generate new offer.
 
3925
 */
 
3926
static void pjsua_call_on_create_offer(pjsip_inv_session *inv,
 
3927
                                       pjmedia_sdp_session **offer)
 
3928
{
 
3929
    pjsua_call *call;
 
3930
    pj_status_t status;
 
3931
 
 
3932
    pj_log_push_indent();
 
3933
 
 
3934
    call = (pjsua_call*) inv->dlg->mod_data[pjsua_var.mod.id];
 
3935
 
 
3936
    /* See if we've put call on hold. */
 
3937
    if (call->local_hold) {
 
3938
        PJ_LOG(4,(THIS_FILE, 
 
3939
                  "Call %d: call is on-hold locally, creating call-hold SDP ",
 
3940
                  call->index));
 
3941
        status = create_sdp_of_call_hold( call, offer );
 
3942
    } else {
 
3943
        PJ_LOG(4,(THIS_FILE, "Call %d: asked to send a new offer",
 
3944
                  call->index));
 
3945
 
 
3946
        status = pjsua_media_channel_create_sdp(call->index, 
 
3947
                                                call->inv->pool_prov, 
 
3948
                                                NULL, offer, NULL);
 
3949
    }
 
3950
 
 
3951
    if (status != PJ_SUCCESS) {
 
3952
        pjsua_perror(THIS_FILE, "Unable to create local SDP", status);
 
3953
        goto on_return;
 
3954
    }
 
3955
 
 
3956
on_return:
 
3957
    pj_log_pop_indent();
 
3958
}
 
3959
 
 
3960
 
 
3961
/*
 
3962
 * Callback called by event framework when the xfer subscription state
 
3963
 * has changed.
 
3964
 */
 
3965
static void xfer_client_on_evsub_state( pjsip_evsub *sub, pjsip_event *event)
 
3966
{
 
3967
    
 
3968
    PJ_UNUSED_ARG(event);
 
3969
 
 
3970
    pj_log_push_indent();
 
3971
 
 
3972
    /*
 
3973
     * When subscription is accepted (got 200/OK to REFER), check if 
 
3974
     * subscription suppressed.
 
3975
     */
 
3976
    if (pjsip_evsub_get_state(sub) == PJSIP_EVSUB_STATE_ACCEPTED) {
 
3977
 
 
3978
        pjsip_rx_data *rdata;
 
3979
        pjsip_generic_string_hdr *refer_sub;
 
3980
        const pj_str_t REFER_SUB = { "Refer-Sub", 9 };
 
3981
        pjsua_call *call;
 
3982
 
 
3983
        call = (pjsua_call*) pjsip_evsub_get_mod_data(sub, pjsua_var.mod.id);
 
3984
 
 
3985
        /* Must be receipt of response message */
 
3986
        pj_assert(event->type == PJSIP_EVENT_TSX_STATE && 
 
3987
                  event->body.tsx_state.type == PJSIP_EVENT_RX_MSG);
 
3988
        rdata = event->body.tsx_state.src.rdata;
 
3989
 
 
3990
        /* Find Refer-Sub header */
 
3991
        refer_sub = (pjsip_generic_string_hdr*)
 
3992
                    pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, 
 
3993
                                               &REFER_SUB, NULL);
 
3994
 
 
3995
        /* Check if subscription is suppressed */
 
3996
        if (refer_sub && pj_stricmp2(&refer_sub->hvalue, "false")==0) {
 
3997
            /* Since no subscription is desired, assume that call has been
 
3998
             * transfered successfully.
 
3999
             */
 
4000
            if (call && pjsua_var.ua_cfg.cb.on_call_transfer_status) {
 
4001
                const pj_str_t ACCEPTED = { "Accepted", 8 };
 
4002
                pj_bool_t cont = PJ_FALSE;
 
4003
                (*pjsua_var.ua_cfg.cb.on_call_transfer_status)(call->index, 
 
4004
                                                               200,
 
4005
                                                               &ACCEPTED,
 
4006
                                                               PJ_TRUE,
 
4007
                                                               &cont);
 
4008
            }
 
4009
 
 
4010
            /* Yes, subscription is suppressed.
 
4011
             * Terminate our subscription now.
 
4012
             */
 
4013
            PJ_LOG(4,(THIS_FILE, "Xfer subscription suppressed, terminating "
 
4014
                                 "event subcription..."));
 
4015
            pjsip_evsub_terminate(sub, PJ_TRUE);
 
4016
 
 
4017
        } else {
 
4018
            /* Notify application about call transfer progress. 
 
4019
             * Initially notify with 100/Accepted status.
 
4020
             */
 
4021
            if (call && pjsua_var.ua_cfg.cb.on_call_transfer_status) {
 
4022
                const pj_str_t ACCEPTED = { "Accepted", 8 };
 
4023
                pj_bool_t cont = PJ_FALSE;
 
4024
                (*pjsua_var.ua_cfg.cb.on_call_transfer_status)(call->index, 
 
4025
                                                               100,
 
4026
                                                               &ACCEPTED,
 
4027
                                                               PJ_FALSE,
 
4028
                                                               &cont);
 
4029
            }
 
4030
        }
 
4031
    }
 
4032
    /*
 
4033
     * On incoming NOTIFY, notify application about call transfer progress.
 
4034
     */
 
4035
    else if (pjsip_evsub_get_state(sub) == PJSIP_EVSUB_STATE_ACTIVE ||
 
4036
             pjsip_evsub_get_state(sub) == PJSIP_EVSUB_STATE_TERMINATED) 
 
4037
    {
 
4038
        pjsua_call *call;
 
4039
        pjsip_msg *msg;
 
4040
        pjsip_msg_body *body;
 
4041
        pjsip_status_line status_line;
 
4042
        pj_bool_t is_last;
 
4043
        pj_bool_t cont;
 
4044
        pj_status_t status;
 
4045
 
 
4046
        call = (pjsua_call*) pjsip_evsub_get_mod_data(sub, pjsua_var.mod.id);
 
4047
 
 
4048
        /* When subscription is terminated, clear the xfer_sub member of 
 
4049
         * the inv_data.
 
4050
         */
 
4051
        if (pjsip_evsub_get_state(sub) == PJSIP_EVSUB_STATE_TERMINATED) {
 
4052
            pjsip_evsub_set_mod_data(sub, pjsua_var.mod.id, NULL);
 
4053
            PJ_LOG(4,(THIS_FILE, "Xfer client subscription terminated"));
 
4054
 
 
4055
        }
 
4056
 
 
4057
        if (!call || !event || !pjsua_var.ua_cfg.cb.on_call_transfer_status) {
 
4058
            /* Application is not interested with call progress status */
 
4059
            goto on_return;
 
4060
        }
 
4061
 
 
4062
        /* This better be a NOTIFY request */
 
4063
        if (event->type == PJSIP_EVENT_TSX_STATE &&
 
4064
            event->body.tsx_state.type == PJSIP_EVENT_RX_MSG)
 
4065
        {
 
4066
            pjsip_rx_data *rdata;
 
4067
 
 
4068
            rdata = event->body.tsx_state.src.rdata;
 
4069
 
 
4070
            /* Check if there's body */
 
4071
            msg = rdata->msg_info.msg;
 
4072
            body = msg->body;
 
4073
            if (!body) {
 
4074
                PJ_LOG(2,(THIS_FILE, 
 
4075
                          "Warning: received NOTIFY without message body"));
 
4076
                goto on_return;
 
4077
            }
 
4078
 
 
4079
            /* Check for appropriate content */
 
4080
            if (pj_stricmp2(&body->content_type.type, "message") != 0 ||
 
4081
                pj_stricmp2(&body->content_type.subtype, "sipfrag") != 0)
 
4082
            {
 
4083
                PJ_LOG(2,(THIS_FILE, 
 
4084
                          "Warning: received NOTIFY with non message/sipfrag "
 
4085
                          "content"));
 
4086
                goto on_return;
 
4087
            }
 
4088
 
 
4089
            /* Try to parse the content */
 
4090
            status = pjsip_parse_status_line((char*)body->data, body->len, 
 
4091
                                             &status_line);
 
4092
            if (status != PJ_SUCCESS) {
 
4093
                PJ_LOG(2,(THIS_FILE, 
 
4094
                          "Warning: received NOTIFY with invalid "
 
4095
                          "message/sipfrag content"));
 
4096
                goto on_return;
 
4097
            }
 
4098
 
 
4099
        } else {
 
4100
            status_line.code = 500;
 
4101
            status_line.reason = *pjsip_get_status_text(500);
 
4102
        }
 
4103
 
 
4104
        /* Notify application */
 
4105
        is_last = (pjsip_evsub_get_state(sub)==PJSIP_EVSUB_STATE_TERMINATED);
 
4106
        cont = !is_last;
 
4107
        (*pjsua_var.ua_cfg.cb.on_call_transfer_status)(call->index, 
 
4108
                                                       status_line.code,
 
4109
                                                       &status_line.reason,
 
4110
                                                       is_last, &cont);
 
4111
 
 
4112
        if (!cont) {
 
4113
            pjsip_evsub_set_mod_data(sub, pjsua_var.mod.id, NULL);
 
4114
        }
 
4115
 
 
4116
        /* If the call transfer has completed but the subscription is
 
4117
         * not terminated, terminate it now.
 
4118
         */
 
4119
        if (status_line.code/100 == 2 && !is_last) {
 
4120
            pjsip_tx_data *tdata;
 
4121
 
 
4122
            status = pjsip_evsub_initiate(sub, &pjsip_subscribe_method, 
 
4123
                                          0, &tdata);
 
4124
            if (status == PJ_SUCCESS)
 
4125
                status = pjsip_evsub_send_request(sub, tdata);
 
4126
        }
 
4127
    }
 
4128
 
 
4129
on_return:
 
4130
    pj_log_pop_indent();
 
4131
}
 
4132
 
 
4133
 
 
4134
/*
 
4135
 * Callback called by event framework when the xfer subscription state
 
4136
 * has changed.
 
4137
 */
 
4138
static void xfer_server_on_evsub_state( pjsip_evsub *sub, pjsip_event *event)
 
4139
{
 
4140
    PJ_UNUSED_ARG(event);
 
4141
 
 
4142
    pj_log_push_indent();
 
4143
 
 
4144
    /*
 
4145
     * When subscription is terminated, clear the xfer_sub member of 
 
4146
     * the inv_data.
 
4147
     */
 
4148
    if (pjsip_evsub_get_state(sub) == PJSIP_EVSUB_STATE_TERMINATED) {
 
4149
        pjsua_call *call;
 
4150
 
 
4151
        call = (pjsua_call*) pjsip_evsub_get_mod_data(sub, pjsua_var.mod.id);
 
4152
        if (!call)
 
4153
            goto on_return;
 
4154
 
 
4155
        pjsip_evsub_set_mod_data(sub, pjsua_var.mod.id, NULL);
 
4156
        call->xfer_sub = NULL;
 
4157
 
 
4158
        PJ_LOG(4,(THIS_FILE, "Xfer server subscription terminated"));
 
4159
    }
 
4160
 
 
4161
on_return:
 
4162
    pj_log_pop_indent();
 
4163
}
 
4164
 
 
4165
 
 
4166
/*
 
4167
 * Follow transfer (REFER) request.
 
4168
 */
 
4169
static void on_call_transfered( pjsip_inv_session *inv,
 
4170
                                pjsip_rx_data *rdata )
 
4171
{
 
4172
    pj_status_t status;
 
4173
    pjsip_tx_data *tdata;
 
4174
    pjsua_call *existing_call;
 
4175
    int new_call;
 
4176
    const pj_str_t str_refer_to = { "Refer-To", 8};
 
4177
    const pj_str_t str_refer_sub = { "Refer-Sub", 9 };
 
4178
    const pj_str_t str_ref_by = { "Referred-By", 11 };
 
4179
    pjsip_generic_string_hdr *refer_to;
 
4180
    pjsip_generic_string_hdr *refer_sub;
 
4181
    pjsip_hdr *ref_by_hdr;
 
4182
    pj_bool_t no_refer_sub = PJ_FALSE;
 
4183
    char *uri;
 
4184
    pjsua_msg_data msg_data;
 
4185
    pj_str_t tmp;
 
4186
    pjsip_status_code code;
 
4187
    pjsip_evsub *sub;
 
4188
    pjsua_call_setting call_opt;
 
4189
 
 
4190
    pj_log_push_indent();
 
4191
 
 
4192
    existing_call = (pjsua_call*) inv->dlg->mod_data[pjsua_var.mod.id];
 
4193
 
 
4194
    /* Find the Refer-To header */
 
4195
    refer_to = (pjsip_generic_string_hdr*)
 
4196
        pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &str_refer_to, NULL);
 
4197
 
 
4198
    if (refer_to == NULL) {
 
4199
        /* Invalid Request.
 
4200
         * No Refer-To header!
 
4201
         */
 
4202
        PJ_LOG(4,(THIS_FILE, "Received REFER without Refer-To header!"));
 
4203
        pjsip_dlg_respond( inv->dlg, rdata, 400, NULL, NULL, NULL);
 
4204
        goto on_return;
 
4205
    }
 
4206
 
 
4207
    /* Find optional Refer-Sub header */
 
4208
    refer_sub = (pjsip_generic_string_hdr*)
 
4209
        pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &str_refer_sub, NULL);
 
4210
 
 
4211
    if (refer_sub) {
 
4212
        if (!pj_strnicmp2(&refer_sub->hvalue, "true", 4)==0)
 
4213
            no_refer_sub = PJ_TRUE;
 
4214
    }
 
4215
 
 
4216
    /* Find optional Referred-By header (to be copied onto outgoing INVITE
 
4217
     * request.
 
4218
     */
 
4219
    ref_by_hdr = (pjsip_hdr*)
 
4220
                 pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &str_ref_by, 
 
4221
                                            NULL);
 
4222
 
 
4223
    /* Notify callback */
 
4224
    code = PJSIP_SC_ACCEPTED;
 
4225
    if (pjsua_var.ua_cfg.cb.on_call_transfer_request) {
 
4226
        (*pjsua_var.ua_cfg.cb.on_call_transfer_request)(existing_call->index,
 
4227
                                                        &refer_to->hvalue, 
 
4228
                                                        &code);
 
4229
    }
 
4230
 
 
4231
    call_opt = existing_call->opt;
 
4232
    if (pjsua_var.ua_cfg.cb.on_call_transfer_request2) {
 
4233
        (*pjsua_var.ua_cfg.cb.on_call_transfer_request2)(existing_call->index,
 
4234
                                                         &refer_to->hvalue, 
 
4235
                                                         &code,
 
4236
                                                         &call_opt);
 
4237
    }
 
4238
 
 
4239
    if (code < 200)
 
4240
        code = PJSIP_SC_ACCEPTED;
 
4241
    if (code >= 300) {
 
4242
        /* Application rejects call transfer request */
 
4243
        pjsip_dlg_respond( inv->dlg, rdata, code, NULL, NULL, NULL);
 
4244
        goto on_return;
 
4245
    }
 
4246
 
 
4247
    PJ_LOG(3,(THIS_FILE, "Call to %.*s is being transfered to %.*s",
 
4248
              (int)inv->dlg->remote.info_str.slen,
 
4249
              inv->dlg->remote.info_str.ptr,
 
4250
              (int)refer_to->hvalue.slen, 
 
4251
              refer_to->hvalue.ptr));
 
4252
 
 
4253
    if (no_refer_sub) {
 
4254
        /*
 
4255
         * Always answer with 2xx.
 
4256
         */
 
4257
        pjsip_tx_data *tdata;
 
4258
        const pj_str_t str_false = { "false", 5};
 
4259
        pjsip_hdr *hdr;
 
4260
 
 
4261
        status = pjsip_dlg_create_response(inv->dlg, rdata, code, NULL, 
 
4262
                                           &tdata);
 
4263
        if (status != PJ_SUCCESS) {
 
4264
            pjsua_perror(THIS_FILE, "Unable to create 2xx response to REFER",
 
4265
                         status);
 
4266
            goto on_return;
 
4267
        }
 
4268
 
 
4269
        /* Add Refer-Sub header */
 
4270
        hdr = (pjsip_hdr*) 
 
4271
               pjsip_generic_string_hdr_create(tdata->pool, &str_refer_sub,
 
4272
                                              &str_false);
 
4273
        pjsip_msg_add_hdr(tdata->msg, hdr);
 
4274
 
 
4275
 
 
4276
        /* Send answer */
 
4277
        status = pjsip_dlg_send_response(inv->dlg, pjsip_rdata_get_tsx(rdata),
 
4278
                                         tdata);
 
4279
        if (status != PJ_SUCCESS) {
 
4280
            pjsua_perror(THIS_FILE, "Unable to create 2xx response to REFER",
 
4281
                         status);
 
4282
            goto on_return;
 
4283
        }
 
4284
 
 
4285
        /* Don't have subscription */
 
4286
        sub = NULL;
 
4287
 
 
4288
    } else {
 
4289
        struct pjsip_evsub_user xfer_cb;
 
4290
        pjsip_hdr hdr_list;
 
4291
 
 
4292
        /* Init callback */
 
4293
        pj_bzero(&xfer_cb, sizeof(xfer_cb));
 
4294
        xfer_cb.on_evsub_state = &xfer_server_on_evsub_state;
 
4295
 
 
4296
        /* Init additional header list to be sent with REFER response */
 
4297
        pj_list_init(&hdr_list);
 
4298
 
 
4299
        /* Create transferee event subscription */
 
4300
        status = pjsip_xfer_create_uas( inv->dlg, &xfer_cb, rdata, &sub);
 
4301
        if (status != PJ_SUCCESS) {
 
4302
            pjsua_perror(THIS_FILE, "Unable to create xfer uas", status);
 
4303
            pjsip_dlg_respond( inv->dlg, rdata, 500, NULL, NULL, NULL);
 
4304
            goto on_return;
 
4305
        }
 
4306
 
 
4307
        /* If there's Refer-Sub header and the value is "true", send back
 
4308
         * Refer-Sub in the response with value "true" too.
 
4309
         */
 
4310
        if (refer_sub) {
 
4311
            const pj_str_t str_true = { "true", 4 };
 
4312
            pjsip_hdr *hdr;
 
4313
 
 
4314
            hdr = (pjsip_hdr*) 
 
4315
                   pjsip_generic_string_hdr_create(inv->dlg->pool, 
 
4316
                                                   &str_refer_sub,
 
4317
                                                   &str_true);
 
4318
            pj_list_push_back(&hdr_list, hdr);
 
4319
 
 
4320
        }
 
4321
 
 
4322
        /* Accept the REFER request, send 2xx. */
 
4323
        pjsip_xfer_accept(sub, rdata, code, &hdr_list);
 
4324
 
 
4325
        /* Create initial NOTIFY request */
 
4326
        status = pjsip_xfer_notify( sub, PJSIP_EVSUB_STATE_ACTIVE,
 
4327
                                    100, NULL, &tdata);
 
4328
        if (status != PJ_SUCCESS) {
 
4329
            pjsua_perror(THIS_FILE, "Unable to create NOTIFY to REFER", 
 
4330
                         status);
 
4331
            goto on_return;
 
4332
        }
 
4333
 
 
4334
        /* Send initial NOTIFY request */
 
4335
        status = pjsip_xfer_send_request( sub, tdata);
 
4336
        if (status != PJ_SUCCESS) {
 
4337
            pjsua_perror(THIS_FILE, "Unable to send NOTIFY to REFER", status);
 
4338
            goto on_return;
 
4339
        }
 
4340
    }
 
4341
 
 
4342
    /* We're cheating here.
 
4343
     * We need to get a null terminated string from a pj_str_t.
 
4344
     * So grab the pointer from the hvalue and NULL terminate it, knowing
 
4345
     * that the NULL position will be occupied by a newline. 
 
4346
     */
 
4347
    uri = refer_to->hvalue.ptr;
 
4348
    uri[refer_to->hvalue.slen] = '\0';
 
4349
 
 
4350
    /* Init msg_data */
 
4351
    pjsua_msg_data_init(&msg_data);
 
4352
 
 
4353
    /* If Referred-By header is present in the REFER request, copy this
 
4354
     * to the outgoing INVITE request.
 
4355
     */
 
4356
    if (ref_by_hdr != NULL) {
 
4357
        pjsip_hdr *dup = (pjsip_hdr*)
 
4358
                         pjsip_hdr_clone(rdata->tp_info.pool, ref_by_hdr);
 
4359
        pj_list_push_back(&msg_data.hdr_list, dup);
 
4360
    }
 
4361
 
 
4362
    /* Now make the outgoing call. */
 
4363
    tmp = pj_str(uri);
 
4364
    status = pjsua_call_make_call(existing_call->acc_id, &tmp, &call_opt,
 
4365
                                  existing_call->user_data, &msg_data, 
 
4366
                                  &new_call);
 
4367
    if (status != PJ_SUCCESS) {
 
4368
 
 
4369
        /* Notify xferer about the error (if we have subscription) */
 
4370
        if (sub) {
 
4371
            status = pjsip_xfer_notify(sub, PJSIP_EVSUB_STATE_TERMINATED,
 
4372
                                       500, NULL, &tdata);
 
4373
            if (status != PJ_SUCCESS) {
 
4374
                pjsua_perror(THIS_FILE, "Unable to create NOTIFY to REFER", 
 
4375
                              status);
 
4376
                goto on_return;
 
4377
            }
 
4378
            status = pjsip_xfer_send_request(sub, tdata);
 
4379
            if (status != PJ_SUCCESS) {
 
4380
                pjsua_perror(THIS_FILE, "Unable to send NOTIFY to REFER", 
 
4381
                              status);
 
4382
                goto on_return;
 
4383
            }
 
4384
        }
 
4385
        goto on_return;
 
4386
    }
 
4387
 
 
4388
    if (sub) {
 
4389
        /* Put the server subscription in inv_data.
 
4390
         * Subsequent state changed in pjsua_inv_on_state_changed() will be
 
4391
         * reported back to the server subscription.
 
4392
         */
 
4393
        pjsua_var.calls[new_call].xfer_sub = sub;
 
4394
 
 
4395
        /* Put the invite_data in the subscription. */
 
4396
        pjsip_evsub_set_mod_data(sub, pjsua_var.mod.id, 
 
4397
                                 &pjsua_var.calls[new_call]);
 
4398
    }
 
4399
 
 
4400
on_return:
 
4401
    pj_log_pop_indent();
 
4402
}
 
4403
 
 
4404
 
 
4405
 
 
4406
/*
 
4407
 * This callback is called when transaction state has changed in INVITE
 
4408
 * session. We use this to trap:
 
4409
 *  - incoming REFER request.
 
4410
 *  - incoming MESSAGE request.
 
4411
 */
 
4412
static void pjsua_call_on_tsx_state_changed(pjsip_inv_session *inv,
 
4413
                                            pjsip_transaction *tsx,
 
4414
                                            pjsip_event *e)
 
4415
{
 
4416
    pjsua_call *call;
 
4417
 
 
4418
    pj_log_push_indent();
 
4419
 
 
4420
    call = (pjsua_call*) inv->dlg->mod_data[pjsua_var.mod.id];
 
4421
 
 
4422
    if (call == NULL)
 
4423
        goto on_return;
 
4424
 
 
4425
    if (call->inv == NULL) {
 
4426
        /* Call has been disconnected. */
 
4427
        goto on_return;
 
4428
    }
 
4429
 
 
4430
    /* https://trac.pjsip.org/repos/ticket/1452:
 
4431
     *    If a request is retried due to 401/407 challenge, don't process the
 
4432
     *    transaction first but wait until we've retried it.
 
4433
     */
 
4434
    if (tsx->role == PJSIP_ROLE_UAC &&
 
4435
        (tsx->status_code==401 || tsx->status_code==407) &&
 
4436
        tsx->last_tx && tsx->last_tx->auth_retry)
 
4437
    {
 
4438
        goto on_return;
 
4439
    }
 
4440
 
 
4441
    /* Notify application callback first */
 
4442
    if (pjsua_var.ua_cfg.cb.on_call_tsx_state) {
 
4443
        (*pjsua_var.ua_cfg.cb.on_call_tsx_state)(call->index, tsx, e);
 
4444
    }
 
4445
 
 
4446
    if (tsx->role==PJSIP_ROLE_UAS &&
 
4447
        tsx->state==PJSIP_TSX_STATE_TRYING &&
 
4448
        pjsip_method_cmp(&tsx->method, pjsip_get_refer_method())==0)
 
4449
    {
 
4450
        /*
 
4451
         * Incoming REFER request.
 
4452
         */
 
4453
        on_call_transfered(call->inv, e->body.tsx_state.src.rdata);
 
4454
 
 
4455
    }
 
4456
    else if (tsx->role==PJSIP_ROLE_UAS &&
 
4457
             tsx->state==PJSIP_TSX_STATE_TRYING &&
 
4458
             pjsip_method_cmp(&tsx->method, &pjsip_message_method)==0)
 
4459
    {
 
4460
        /*
 
4461
         * Incoming MESSAGE request!
 
4462
         */
 
4463
        pjsip_rx_data *rdata;
 
4464
        pjsip_msg *msg;
 
4465
        pjsip_accept_hdr *accept_hdr;
 
4466
        pj_status_t status;
 
4467
 
 
4468
        rdata = e->body.tsx_state.src.rdata;
 
4469
        msg = rdata->msg_info.msg;
 
4470
 
 
4471
        /* Request MUST have message body, with Content-Type equal to
 
4472
         * "text/plain".
 
4473
         */
 
4474
        if (pjsua_im_accept_pager(rdata, &accept_hdr) == PJ_FALSE) {
 
4475
 
 
4476
            pjsip_hdr hdr_list;
 
4477
 
 
4478
            pj_list_init(&hdr_list);
 
4479
            pj_list_push_back(&hdr_list, accept_hdr);
 
4480
 
 
4481
            pjsip_dlg_respond( inv->dlg, rdata, PJSIP_SC_NOT_ACCEPTABLE_HERE, 
 
4482
                               NULL, &hdr_list, NULL );
 
4483
            goto on_return;
 
4484
        }
 
4485
 
 
4486
        /* Respond with 200 first, so that remote doesn't retransmit in case
 
4487
         * the UI takes too long to process the message. 
 
4488
         */
 
4489
        status = pjsip_dlg_respond( inv->dlg, rdata, 200, NULL, NULL, NULL);
 
4490
 
 
4491
        /* Process MESSAGE request */
 
4492
        pjsua_im_process_pager(call->index, &inv->dlg->remote.info_str,
 
4493
                               &inv->dlg->local.info_str, rdata);
 
4494
 
 
4495
    }
 
4496
    else if (tsx->role == PJSIP_ROLE_UAC &&
 
4497
             pjsip_method_cmp(&tsx->method, &pjsip_message_method)==0)
 
4498
    {
 
4499
        /* Handle outgoing pager status */
 
4500
        if (tsx->status_code >= 200) {
 
4501
            pjsua_im_data *im_data;
 
4502
 
 
4503
            im_data = (pjsua_im_data*) tsx->mod_data[pjsua_var.mod.id];
 
4504
            /* im_data can be NULL if this is typing indication */
 
4505
 
 
4506
            if (im_data && pjsua_var.ua_cfg.cb.on_pager_status) {
 
4507
                pjsua_var.ua_cfg.cb.on_pager_status(im_data->call_id,
 
4508
                                                    &im_data->to,
 
4509
                                                    &im_data->body,
 
4510
                                                    im_data->user_data,
 
4511
                                                    (pjsip_status_code)
 
4512
                                                        tsx->status_code,
 
4513
                                                    &tsx->status_text);
 
4514
            }
 
4515
        }
 
4516
    } else if (tsx->role == PJSIP_ROLE_UAC &&
 
4517
               tsx->last_tx == (pjsip_tx_data*)call->hold_msg &&
 
4518
               tsx->state >= PJSIP_TSX_STATE_COMPLETED)
 
4519
    {
 
4520
        /* Monitor the status of call hold request */
 
4521
        call->hold_msg = NULL;
 
4522
        if (tsx->status_code/100 != 2) {
 
4523
            /* Outgoing call hold failed */
 
4524
            call->local_hold = PJ_FALSE;
 
4525
            PJ_LOG(3,(THIS_FILE, "Error putting call %d on hold (reason=%d)",
 
4526
                      call->index, tsx->status_code));
 
4527
        }
 
4528
    } else if (tsx->role==PJSIP_ROLE_UAS &&
 
4529
        tsx->state==PJSIP_TSX_STATE_TRYING &&
 
4530
        pjsip_method_cmp(&tsx->method, &pjsip_info_method)==0)
 
4531
    {
 
4532
        /*
 
4533
         * Incoming INFO request for media control.
 
4534
         */
 
4535
        const pj_str_t STR_APPLICATION       = { "application", 11};
 
4536
        const pj_str_t STR_MEDIA_CONTROL_XML = { "media_control+xml", 17 };
 
4537
        pjsip_rx_data *rdata = e->body.tsx_state.src.rdata;
 
4538
        pjsip_msg_body *body = rdata->msg_info.msg->body;
 
4539
 
 
4540
        if (body && body->len &&
 
4541
            pj_stricmp(&body->content_type.type, &STR_APPLICATION)==0 &&
 
4542
            pj_stricmp(&body->content_type.subtype, &STR_MEDIA_CONTROL_XML)==0)
 
4543
        {
 
4544
            pjsip_tx_data *tdata;
 
4545
            pj_str_t control_st;
 
4546
            pj_status_t status;
 
4547
 
 
4548
            /* Apply and answer the INFO request */
 
4549
            pj_strset(&control_st, (char*)body->data, body->len);
 
4550
            status = pjsua_media_apply_xml_control(call->index, &control_st);
 
4551
            if (status == PJ_SUCCESS) {
 
4552
                status = pjsip_endpt_create_response(tsx->endpt, rdata,
 
4553
                                                     200, NULL, &tdata);
 
4554
                if (status == PJ_SUCCESS)
 
4555
                    status = pjsip_tsx_send_msg(tsx, tdata);
 
4556
            } else {
 
4557
                status = pjsip_endpt_create_response(tsx->endpt, rdata,
 
4558
                                                     400, NULL, &tdata);
 
4559
                if (status == PJ_SUCCESS)
 
4560
                    status = pjsip_tsx_send_msg(tsx, tdata);
 
4561
            }
 
4562
        }
 
4563
    }
 
4564
 
 
4565
on_return:
 
4566
    pj_log_pop_indent();
 
4567
}
 
4568
 
 
4569
 
 
4570
/* Redirection handler */
 
4571
static pjsip_redirect_op pjsua_call_on_redirected(pjsip_inv_session *inv,
 
4572
                                                  const pjsip_uri *target,
 
4573
                                                  const pjsip_event *e)
 
4574
{
 
4575
    pjsua_call *call = (pjsua_call*) inv->dlg->mod_data[pjsua_var.mod.id];
 
4576
    pjsip_redirect_op op;
 
4577
 
 
4578
    pj_log_push_indent();
 
4579
 
 
4580
    if (pjsua_var.ua_cfg.cb.on_call_redirected) {
 
4581
        op = (*pjsua_var.ua_cfg.cb.on_call_redirected)(call->index, 
 
4582
                                                         target, e);
 
4583
    } else {
 
4584
        PJ_LOG(4,(THIS_FILE, "Unhandled redirection for call %d "
 
4585
                  "(callback not implemented by application). Disconnecting "
 
4586
                  "call.",
 
4587
                  call->index));
 
4588
        op = PJSIP_REDIRECT_STOP;
 
4589
    }
 
4590
 
 
4591
    pj_log_pop_indent();
 
4592
 
 
4593
    return op;
 
4594
}
 
4595