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

« back to all changes in this revision

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

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2015-01-07 14:51:16 UTC
  • mfrom: (4.3.5 sid)
  • Revision ID: package-import@ubuntu.com-20150107145116-yxnafinf4lrdvrmx
Tags: 1.4.1-0.1ubuntu1
* Merge with Debian, remaining changes:
 - Drop soprano, nepomuk build-dep
* Drop ubuntu patches, now upstream

Show diffs side-by-side

added added

removed removed

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