/* $Id$ */
/* 
 * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
 * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 */
#include <pjsua-lib/pjsua.h>
#include <pjsua-lib/pjsua_internal.h>


#define THIS_FILE		"pjsua_call.c"


/* Retry interval of sending re-INVITE for locking a codec when remote
 * SDP answer contains multiple codec, in milliseconds.
 */
#define LOCK_CODEC_RETRY_INTERVAL   200

/*
 * Max UPDATE/re-INVITE retry to lock codec
 */
#define LOCK_CODEC_MAX_RETRY	     5


/*
 * The INFO method.
 */
const pjsip_method pjsip_info_method = 
{
    PJSIP_OTHER_METHOD,
    { "INFO", 4 }
};


/* This callback receives notification from invite session when the
 * session state has changed.
 */
static void pjsua_call_on_state_changed(pjsip_inv_session *inv, 
					pjsip_event *e);

/* This callback is called by invite session framework when UAC session
 * has forked.
 */
static void pjsua_call_on_forked( pjsip_inv_session *inv, 
				  pjsip_event *e);

/*
 * Callback to be called when SDP offer/answer negotiation has just completed
 * in the session. This function will start/update media if negotiation
 * has succeeded.
 */
static void pjsua_call_on_media_update(pjsip_inv_session *inv,
				       pj_status_t status);

/*
 * Called when session received new offer.
 */
static void pjsua_call_on_rx_offer(pjsip_inv_session *inv,
				   const pjmedia_sdp_session *offer);

/*
 * Called to generate new offer.
 */
static void pjsua_call_on_create_offer(pjsip_inv_session *inv,
				       pjmedia_sdp_session **offer);

/*
 * This callback is called when transaction state has changed in INVITE
 * session. We use this to trap:
 *  - incoming REFER request.
 *  - incoming MESSAGE request.
 */
static void pjsua_call_on_tsx_state_changed(pjsip_inv_session *inv,
					    pjsip_transaction *tsx,
					    pjsip_event *e);

/*
 * Redirection handler.
 */
static pjsip_redirect_op pjsua_call_on_redirected(pjsip_inv_session *inv,
						  const pjsip_uri *target,
						  const pjsip_event *e);


/* Create SDP for call hold. */
static pj_status_t create_sdp_of_call_hold(pjsua_call *call,
					   pjmedia_sdp_session **p_sdp);

/*
 * Callback called by event framework when the xfer subscription state
 * has changed.
 */
static void xfer_client_on_evsub_state( pjsip_evsub *sub, pjsip_event *event);
static void xfer_server_on_evsub_state( pjsip_evsub *sub, pjsip_event *event);

/* Timer callback to send re-INVITE/UPDATE to lock codec or ICE update */
static void reinv_timer_cb(pj_timer_heap_t *th, pj_timer_entry *entry);

/* Check and send reinvite for lock codec and ICE update */
static pj_status_t process_pending_reinvite(pjsua_call *call);

/*
 * Reset call descriptor.
 */
static void reset_call(pjsua_call_id id)
{
    pjsua_call *call = &pjsua_var.calls[id];
    unsigned i;

    pj_bzero(call, sizeof(*call));
    call->index = id;
    call->last_text.ptr = call->last_text_buf_;
    for (i=0; i<PJ_ARRAY_SIZE(call->media); ++i) {
	pjsua_call_media *call_med = &call->media[i];
	call_med->ssrc = pj_rand();
	call_med->strm.a.conf_slot = PJSUA_INVALID_ID;
	call_med->strm.v.cap_win_id = PJSUA_INVALID_ID;
	call_med->strm.v.rdr_win_id = PJSUA_INVALID_ID;
	call_med->call = call;
	call_med->idx = i;
	call_med->tp_auto_del = PJ_TRUE;
    }
    pjsua_call_setting_default(&call->opt);
    pj_timer_entry_init(&call->reinv_timer, PJ_FALSE,
			(void*)(pj_size_t)id, &reinv_timer_cb);
}


/*
 * Init call subsystem.
 */
pj_status_t pjsua_call_subsys_init(const pjsua_config *cfg)
{
    pjsip_inv_callback inv_cb;
    unsigned i;
    const pj_str_t str_norefersub = { "norefersub", 10 };
    pj_status_t status;

    /* Init calls array. */
    for (i=0; i<PJ_ARRAY_SIZE(pjsua_var.calls); ++i)
	reset_call(i);

    /* Copy config */
    pjsua_config_dup(pjsua_var.pool, &pjsua_var.ua_cfg, cfg);

    /* Verify settings */
    if (pjsua_var.ua_cfg.max_calls >= PJSUA_MAX_CALLS) {
	pjsua_var.ua_cfg.max_calls = PJSUA_MAX_CALLS;
    }

    /* Check the route URI's and force loose route if required */
    for (i=0; i<pjsua_var.ua_cfg.outbound_proxy_cnt; ++i) {
	status = normalize_route_uri(pjsua_var.pool, 
				     &pjsua_var.ua_cfg.outbound_proxy[i]);
	if (status != PJ_SUCCESS)
	    return status;
    }

    /* Initialize invite session callback. */
    pj_bzero(&inv_cb, sizeof(inv_cb));
    inv_cb.on_state_changed = &pjsua_call_on_state_changed;
    inv_cb.on_new_session = &pjsua_call_on_forked;
    inv_cb.on_media_update = &pjsua_call_on_media_update;
    inv_cb.on_rx_offer = &pjsua_call_on_rx_offer;
    inv_cb.on_create_offer = &pjsua_call_on_create_offer;
    inv_cb.on_tsx_state_changed = &pjsua_call_on_tsx_state_changed;
    inv_cb.on_redirected = &pjsua_call_on_redirected;

    /* Initialize invite session module: */
    status = pjsip_inv_usage_init(pjsua_var.endpt, &inv_cb);
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);

    /* Add "norefersub" in Supported header */
    pjsip_endpt_add_capability(pjsua_var.endpt, NULL, PJSIP_H_SUPPORTED,
			       NULL, 1, &str_norefersub);

    /* Add "INFO" in Allow header, for DTMF and video key frame request. */
    pjsip_endpt_add_capability(pjsua_var.endpt, NULL, PJSIP_H_ALLOW,
			       NULL, 1, &pjsip_info_method.name);

    return status;
}


/*
 * Start call subsystem.
 */
pj_status_t pjsua_call_subsys_start(void)
{
    /* Nothing to do */
    return PJ_SUCCESS;
}


/*
 * Get maximum number of calls configured in pjsua.
 */
PJ_DEF(unsigned) pjsua_call_get_max_count(void)
{
    return pjsua_var.ua_cfg.max_calls;
}


/*
 * Get number of currently active calls.
 */
PJ_DEF(unsigned) pjsua_call_get_count(void)
{
    return pjsua_var.call_cnt;
}


/*
 * Enum calls.
 */
PJ_DEF(pj_status_t) pjsua_enum_calls( pjsua_call_id ids[],
				      unsigned *count)
{
    unsigned i, c;

    PJ_ASSERT_RETURN(ids && *count, PJ_EINVAL);

    PJSUA_LOCK();

    for (i=0, c=0; c<*count && i<pjsua_var.ua_cfg.max_calls; ++i) {
	if (!pjsua_var.calls[i].inv)
	    continue;
	ids[c] = i;
	++c;
    }

    *count = c;

    PJSUA_UNLOCK();

    return PJ_SUCCESS;
}


/* Allocate one call id */
static pjsua_call_id alloc_call_id(void)
{
    pjsua_call_id cid;

#if 1
    /* New algorithm: round-robin */
    if (pjsua_var.next_call_id >= (int)pjsua_var.ua_cfg.max_calls || 
	pjsua_var.next_call_id < 0)
    {
	pjsua_var.next_call_id = 0;
    }

    for (cid=pjsua_var.next_call_id; 
	 cid<(int)pjsua_var.ua_cfg.max_calls; 
	 ++cid) 
    {
	if (pjsua_var.calls[cid].inv == NULL &&
            pjsua_var.calls[cid].async_call.dlg == NULL)
        {
	    ++pjsua_var.next_call_id;
	    return cid;
	}
    }

    for (cid=0; cid < pjsua_var.next_call_id; ++cid) {
	if (pjsua_var.calls[cid].inv == NULL &&
            pjsua_var.calls[cid].async_call.dlg == NULL)
        {
	    ++pjsua_var.next_call_id;
	    return cid;
	}
    }

#else
    /* Old algorithm */
    for (cid=0; cid<(int)pjsua_var.ua_cfg.max_calls; ++cid) {
	if (pjsua_var.calls[cid].inv == NULL)
	    return cid;
    }
#endif

    return PJSUA_INVALID_ID;
}

/* Get signaling secure level.
 * Return:
 *  0: if signaling is not secure
 *  1: if TLS transport is used for immediate hop
 *  2: if end-to-end signaling is secure.
 */
static int get_secure_level(pjsua_acc_id acc_id, const pj_str_t *dst_uri)
{
    const pj_str_t tls = pj_str(";transport=tls");
    const pj_str_t sips = pj_str("sips:");
    pjsua_acc *acc = &pjsua_var.acc[acc_id];

    if (pj_stristr(dst_uri, &sips))
	return 2;
    
    if (!pj_list_empty(&acc->route_set)) {
	pjsip_route_hdr *r = acc->route_set.next;
	pjsip_uri *uri = r->name_addr.uri;
	pjsip_sip_uri *sip_uri;
	
	sip_uri = (pjsip_sip_uri*)pjsip_uri_get_uri(uri);
	if (pj_stricmp2(&sip_uri->transport_param, "tls")==0)
	    return 1;

    } else {
	if (pj_stristr(dst_uri, &tls))
	    return 1;
    }

    return 0;
}

/*
static int call_get_secure_level(pjsua_call *call)
{
    if (call->inv->dlg->secure)
	return 2;

    if (!pj_list_empty(&call->inv->dlg->route_set)) {
	pjsip_route_hdr *r = call->inv->dlg->route_set.next;
	pjsip_uri *uri = r->name_addr.uri;
	pjsip_sip_uri *sip_uri;
	
	sip_uri = (pjsip_sip_uri*)pjsip_uri_get_uri(uri);
	if (pj_stricmp2(&sip_uri->transport_param, "tls")==0)
	    return 1;

    } else {
	pjsip_sip_uri *sip_uri;

	if (PJSIP_URI_SCHEME_IS_SIPS(call->inv->dlg->target))
	    return 2;
	if (!PJSIP_URI_SCHEME_IS_SIP(call->inv->dlg->target))
	    return 0;

	sip_uri = (pjsip_sip_uri*) pjsip_uri_get_uri(call->inv->dlg->target);
	if (pj_stricmp2(&sip_uri->transport_param, "tls")==0)
	    return 1;
    }

    return 0;
}
*/

/* Outgoing call callback when media transport creation is completed. */
static pj_status_t
on_make_call_med_tp_complete(pjsua_call_id call_id,
                             const pjsua_med_tp_state_info *info)
{
    pjmedia_sdp_session *offer;
    pjsip_inv_session *inv = NULL;
    pjsua_call *call = &pjsua_var.calls[call_id];
    pjsua_acc *acc = &pjsua_var.acc[call->acc_id];
    pjsip_dialog *dlg = call->async_call.dlg;
    unsigned options = 0;
    pjsip_tx_data *tdata;
    pj_bool_t cb_called = PJ_FALSE;
    pj_status_t status = (info? info->status: PJ_SUCCESS);

    PJSUA_LOCK();

    /* Increment the dialog's lock otherwise when invite session creation
     * fails the dialog will be destroyed prematurely.
     */
    pjsip_dlg_inc_lock(dlg);

    /* Decrement dialog session. */
    pjsip_dlg_dec_session(dlg, &pjsua_var.mod);

    if (status != PJ_SUCCESS) {
	pj_str_t err_str;
	pj_ssize_t title_len;

	call->last_code = PJSIP_SC_TEMPORARILY_UNAVAILABLE;
	pj_strcpy2(&call->last_text, "Media init error: ");

	title_len = call->last_text.slen;
	err_str = pj_strerror(status, call->last_text_buf_ + title_len,
	                      sizeof(call->last_text_buf_) - title_len);
	call->last_text.slen += err_str.slen;

	pjsua_perror(THIS_FILE, "Error initializing media channel", status);
	goto on_error;
    }

    /* pjsua_media_channel_deinit() has been called or
     * call has been hung up.
     */
    if (call->async_call.med_ch_deinit ||
        call->async_call.call_var.out_call.hangup)
    {
        PJ_LOG(4,(THIS_FILE, "Call has been hung up or media channel has "
                             "been deinitialized"));
        goto on_error;
    }

    /* Create offer */
    status = pjsua_media_channel_create_sdp(call->index, dlg->pool, NULL,
					    &offer, NULL);
    if (status != PJ_SUCCESS) {
	pjsua_perror(THIS_FILE, "Error initializing media channel", status);
	goto on_error;
    }

    /* Create the INVITE session: */
    options |= PJSIP_INV_SUPPORT_100REL;
    if (acc->cfg.require_100rel)
	options |= PJSIP_INV_REQUIRE_100REL;
    if (acc->cfg.use_timer != PJSUA_SIP_TIMER_INACTIVE) {
	options |= PJSIP_INV_SUPPORT_TIMER;
	if (acc->cfg.use_timer == PJSUA_SIP_TIMER_REQUIRED)
	    options |= PJSIP_INV_REQUIRE_TIMER;
	else if (acc->cfg.use_timer == PJSUA_SIP_TIMER_ALWAYS)
	    options |= PJSIP_INV_ALWAYS_USE_TIMER;
    }

    status = pjsip_inv_create_uac( dlg, offer, options, &inv);
    if (status != PJ_SUCCESS) {
	pjsua_perror(THIS_FILE, "Invite session creation failed", status);
	goto on_error;
    }

    /* Init Session Timers */
    status = pjsip_timer_init_session(inv, &acc->cfg.timer_setting);
    if (status != PJ_SUCCESS) {
	pjsua_perror(THIS_FILE, "Session Timer init failed", status);
	goto on_error;
    }

    /* Create and associate our data in the session. */
    call->inv = inv;

    dlg->mod_data[pjsua_var.mod.id] = call;
    inv->mod_data[pjsua_var.mod.id] = call;

    /* If account is locked to specific transport, then lock dialog
     * to this transport too.
     */
    if (acc->cfg.transport_id != PJSUA_INVALID_ID) {
	pjsip_tpselector tp_sel;

	pjsua_init_tpselector(acc->cfg.transport_id, &tp_sel);
	pjsip_dlg_set_transport(dlg, &tp_sel);
    }

    /* Set dialog Route-Set: */
    if (!pj_list_empty(&acc->route_set))
	pjsip_dlg_set_route_set(dlg, &acc->route_set);


    /* Set credentials: */
    if (acc->cred_cnt) {
	pjsip_auth_clt_set_credentials( &dlg->auth_sess, 
					acc->cred_cnt, acc->cred);
    }

    /* Set authentication preference */
    pjsip_auth_clt_set_prefs(&dlg->auth_sess, &acc->cfg.auth_pref);

    /* Create initial INVITE: */

    status = pjsip_inv_invite(inv, &tdata);
    if (status != PJ_SUCCESS) {
	pjsua_perror(THIS_FILE, "Unable to create initial INVITE request", 
		     status);
	goto on_error;
    }


    /* Add additional headers etc */

    pjsua_process_msg_data( tdata,
                            call->async_call.call_var.out_call.msg_data);

    /* Must increment call counter now */
    ++pjsua_var.call_cnt;

    /* Send initial INVITE: */

    status = pjsip_inv_send_msg(inv, tdata);
    if (status != PJ_SUCCESS) {
	cb_called = PJ_TRUE;

	/* Upon failure to send first request, the invite 
	 * session would have been cleared.
	 */
	inv = NULL;
	goto on_error;
    }

    /* Done. */
    call->med_ch_cb = NULL;

    pjsip_dlg_dec_lock(dlg);
    PJSUA_UNLOCK();

    return PJ_SUCCESS;

on_error:
    if (inv == NULL && call_id != -1 && !cb_called &&
	pjsua_var.ua_cfg.cb.on_call_state)
    {
        (*pjsua_var.ua_cfg.cb.on_call_state)(call_id, NULL);
    }

    if (dlg) {
	/* This may destroy the dialog */
	pjsip_dlg_dec_lock(dlg);
    }

    if (inv != NULL) {
	pjsip_inv_terminate(inv, PJSIP_SC_OK, PJ_FALSE);
    }

    if (call_id != -1) {
	pjsua_media_channel_deinit(call_id);
	reset_call(call_id);
    }

    call->med_ch_cb = NULL;

    pjsua_check_snd_dev_idle();

    PJSUA_UNLOCK();
    return status;
}


/*
 * Initialize call settings based on account ID.
 */
PJ_DEF(void) pjsua_call_setting_default(pjsua_call_setting *opt)
{
    pj_assert(opt);

    pj_bzero(opt, sizeof(*opt));
    opt->flag = PJSUA_CALL_INCLUDE_DISABLED_MEDIA;
    opt->aud_cnt = 1;

#if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0)
    opt->vid_cnt = 1;
    opt->req_keyframe_method = PJSUA_VID_REQ_KEYFRAME_SIP_INFO |
			     PJSUA_VID_REQ_KEYFRAME_RTCP_PLI;
#endif
}

static pj_status_t apply_call_setting(pjsua_call *call,
				      const pjsua_call_setting *opt,
				      const pjmedia_sdp_session *rem_sdp)
{
    pj_assert(call);

    if (!opt)
	return PJ_SUCCESS;

#if !PJMEDIA_HAS_VIDEO
    pj_assert(opt->vid_cnt == 0);
#endif

    call->opt = *opt;

    /* If call is established, reinit media channel */
    if (call->inv && call->inv->state == PJSIP_INV_STATE_CONFIRMED) {
	pjsip_role_e role = rem_sdp? PJSIP_ROLE_UAS : PJSIP_ROLE_UAC;
	pj_status_t status;

	status = pjsua_media_channel_init(call->index, role,
					  call->secure_level,
					  call->inv->pool_prov,
					  rem_sdp, NULL,
					  PJ_FALSE, NULL);
	if (status != PJ_SUCCESS) {
	    pjsua_perror(THIS_FILE, "Error re-initializing media channel",
			 status);
	    return status;
	}
    }

    return PJ_SUCCESS;
}

/*
 * Make outgoing call to the specified URI using the specified account.
 */
PJ_DEF(pj_status_t) pjsua_call_make_call(pjsua_acc_id acc_id,
					 const pj_str_t *dest_uri,
					 const pjsua_call_setting *opt,
					 void *user_data,
					 const pjsua_msg_data *msg_data,
					 pjsua_call_id *p_call_id)
{
    pj_pool_t *tmp_pool = NULL;
    pjsip_dialog *dlg = NULL;
    pjsua_acc *acc;
    pjsua_call *call;
    int call_id = -1;
    pj_str_t contact;
    pj_status_t status;


    /* Check that account is valid */
    PJ_ASSERT_RETURN(acc_id>=0 || acc_id<(int)PJ_ARRAY_SIZE(pjsua_var.acc), 
		     PJ_EINVAL);

    /* Check arguments */
    PJ_ASSERT_RETURN(dest_uri, PJ_EINVAL);

    PJ_LOG(4,(THIS_FILE, "Making call with acc #%d to %.*s", acc_id,
	      (int)dest_uri->slen, dest_uri->ptr));

    pj_log_push_indent();

    PJSUA_LOCK();

    /* Create sound port if none is instantiated, to check if sound device
     * can be used. But only do this with the conference bridge, as with 
     * audio switchboard (i.e. APS-Direct), we can only open the sound 
     * device once the correct format has been known
     */
    if (!pjsua_var.is_mswitch && pjsua_var.snd_port==NULL && 
	pjsua_var.null_snd==NULL && !pjsua_var.no_snd) 
    {
	status = pjsua_set_snd_dev(pjsua_var.cap_dev, pjsua_var.play_dev);
	if (status != PJ_SUCCESS)
	    goto on_error;
    }

    acc = &pjsua_var.acc[acc_id];
    if (!acc->valid) {
	pjsua_perror(THIS_FILE, "Unable to make call because account "
		     "is not valid", PJ_EINVALIDOP);
	status = PJ_EINVALIDOP;
	goto on_error;
    }

    /* Find free call slot. */
    call_id = alloc_call_id();

    if (call_id == PJSUA_INVALID_ID) {
	pjsua_perror(THIS_FILE, "Error making call", PJ_ETOOMANY);
	status = PJ_ETOOMANY;
	goto on_error;
    }

    /* Clear call descriptor */
    reset_call(call_id);

    call = &pjsua_var.calls[call_id];

    /* Associate session with account */
    call->acc_id = acc_id;
    call->call_hold_type = acc->cfg.call_hold_type;

    /* Apply call setting */
    status = apply_call_setting(call, opt, NULL);
    if (status != PJ_SUCCESS) {
	pjsua_perror(THIS_FILE, "Failed to apply call setting", status);
	goto on_error;
    }

    /* Create temporary pool */
    tmp_pool = pjsua_pool_create("tmpcall10", 512, 256);

    /* Verify that destination URI is valid before calling 
     * pjsua_acc_create_uac_contact, or otherwise there  
     * a misleading "Invalid Contact URI" error will be printed
     * when pjsua_acc_create_uac_contact() fails.
     */
    if (1) {
	pjsip_uri *uri;
	pj_str_t dup;

	pj_strdup_with_null(tmp_pool, &dup, dest_uri);
	uri = pjsip_parse_uri(tmp_pool, dup.ptr, dup.slen, 0);

	if (uri == NULL) {
	    pjsua_perror(THIS_FILE, "Unable to make call", 
			 PJSIP_EINVALIDREQURI);
	    status = PJSIP_EINVALIDREQURI;
	    goto on_error;
	}
    }

    /* Mark call start time. */
    pj_gettimeofday(&call->start_time);

    /* Reset first response time */
    call->res_time.sec = 0;

    /* Create suitable Contact header unless a Contact header has been
     * set in the account.
     */
    if (acc->contact.slen) {
	contact = acc->contact;
    } else {
	status = pjsua_acc_create_uac_contact(tmp_pool, &contact,
					      acc_id, dest_uri);
	if (status != PJ_SUCCESS) {
	    pjsua_perror(THIS_FILE, "Unable to generate Contact header", 
			 status);
	    goto on_error;
	}
    }

    /* Create outgoing dialog: */
    status = pjsip_dlg_create_uac( pjsip_ua_instance(), 
				   &acc->cfg.id, &contact,
				   dest_uri,
                                   (msg_data && msg_data->target_uri.slen?
                                    &msg_data->target_uri: dest_uri),
                                   &dlg);
    if (status != PJ_SUCCESS) {
	pjsua_perror(THIS_FILE, "Dialog creation failed", status);
	goto on_error;
    }

    /* Increment the dialog's lock otherwise when invite session creation
     * fails the dialog will be destroyed prematurely.
     */
    pjsip_dlg_inc_lock(dlg);

    if (acc->cfg.allow_via_rewrite && acc->via_addr.host.slen > 0)
        pjsip_dlg_set_via_sent_by(dlg, &acc->via_addr, acc->via_tp);

    /* Calculate call's secure level */
    call->secure_level = get_secure_level(acc_id, dest_uri);

    /* Attach user data */
    call->user_data = user_data;
    
    /* Store variables required for the callback after the async
     * media transport creation is completed.
     */
    if (msg_data) {
	call->async_call.call_var.out_call.msg_data = pjsua_msg_data_clone(
                                                          dlg->pool, msg_data);
    }
    call->async_call.dlg = dlg;

    /* Temporarily increment dialog session. Without this, dialog will be
     * prematurely destroyed if dec_lock() is called on the dialog before
     * the invite session is created.
     */
    pjsip_dlg_inc_session(dlg, &pjsua_var.mod);

    /* Init media channel */
    status = pjsua_media_channel_init(call->index, PJSIP_ROLE_UAC, 
				      call->secure_level, dlg->pool,
				      NULL, NULL, PJ_TRUE,
                                      &on_make_call_med_tp_complete);
    if (status == PJ_SUCCESS) {
        status = on_make_call_med_tp_complete(call->index, NULL);
        if (status != PJ_SUCCESS)
	    goto on_error;
    } else if (status != PJ_EPENDING) {
	pjsua_perror(THIS_FILE, "Error initializing media channel", status);
        pjsip_dlg_dec_session(dlg, &pjsua_var.mod);
	goto on_error;
    }

    /* Done. */

    if (p_call_id)
	*p_call_id = call_id;

    pjsip_dlg_dec_lock(dlg);
    pj_pool_release(tmp_pool);
    PJSUA_UNLOCK();

    pj_log_pop_indent();

    return PJ_SUCCESS;


on_error:
    if (dlg) {
	/* This may destroy the dialog */
	pjsip_dlg_dec_lock(dlg);
    }

    if (call_id != -1) {
	pjsua_media_channel_deinit(call_id);
	reset_call(call_id);
    }

    pjsua_check_snd_dev_idle();

    if (tmp_pool)
	pj_pool_release(tmp_pool);
    PJSUA_UNLOCK();

    pj_log_pop_indent();
    return status;
}


/* Get the NAT type information in remote's SDP */
static void update_remote_nat_type(pjsua_call *call, 
				   const pjmedia_sdp_session *sdp)
{
    const pjmedia_sdp_attr *xnat;

    xnat = pjmedia_sdp_attr_find2(sdp->attr_count, sdp->attr, "X-nat", NULL);
    if (xnat) {
	call->rem_nat_type = (pj_stun_nat_type) (xnat->value.ptr[0] - '0');
    } else {
	call->rem_nat_type = PJ_STUN_NAT_TYPE_UNKNOWN;
    }

    PJ_LOG(5,(THIS_FILE, "Call %d: remote NAT type is %d (%s)", call->index,
	      call->rem_nat_type, pj_stun_get_nat_name(call->rem_nat_type)));
}


static pj_status_t process_incoming_call_replace(pjsua_call *call,
						 pjsip_dialog *replaced_dlg)
{
    pjsip_inv_session *replaced_inv;
    struct pjsua_call *replaced_call;
    pjsip_tx_data *tdata = NULL;
    pj_status_t status = PJ_SUCCESS;

    /* Get the invite session in the dialog */
    replaced_inv = pjsip_dlg_get_inv_session(replaced_dlg);

    /* Get the replaced call instance */
    replaced_call = (pjsua_call*) replaced_dlg->mod_data[pjsua_var.mod.id];

    /* Notify application */
    if (pjsua_var.ua_cfg.cb.on_call_replaced)
	pjsua_var.ua_cfg.cb.on_call_replaced(replaced_call->index,
					     call->index);

    if (replaced_call->inv->state <= PJSIP_INV_STATE_EARLY &&
	replaced_call->inv->role != PJSIP_ROLE_UAC)
    {
	if (replaced_call->last_code > 100 && replaced_call->last_code < 200)
	{
	    pjsip_status_code code = replaced_call->last_code;
	    pj_str_t *text = &replaced_call->last_text;

    	    PJ_LOG(4,(THIS_FILE, "Answering replacement call %d with %d/%.*s",
				 call->index, code, text->slen, text->ptr));

	    /* Answer the new call with last response in the replaced call */
	    status = pjsip_inv_answer(call->inv, code, text, NULL, &tdata);
	}
    } else {
    	PJ_LOG(4,(THIS_FILE, "Answering replacement call %d with 200/OK",
			     call->index));

	/* Answer the new call with 200 response */
	status = pjsip_inv_answer(call->inv, 200, NULL, NULL, &tdata);
    }

    if (status == PJ_SUCCESS && tdata)
	status = pjsip_inv_send_msg(call->inv, tdata);

    if (status != PJ_SUCCESS)
	pjsua_perror(THIS_FILE, "Error answering session", status);

    /* Note that inv may be invalid if 200/OK has caused error in
     * starting the media.
     */

    PJ_LOG(4,(THIS_FILE, "Disconnecting replaced call %d",
			 replaced_call->index));

    /* Disconnect replaced invite session */
    status = pjsip_inv_end_session(replaced_inv, PJSIP_SC_GONE, NULL,
				   &tdata);
    if (status == PJ_SUCCESS && tdata)
	status = pjsip_inv_send_msg(replaced_inv, tdata);

    if (status != PJ_SUCCESS)
	pjsua_perror(THIS_FILE, "Error terminating session", status);

    return status;
}


static void process_pending_call_answer(pjsua_call *call)
{
    struct call_answer *answer, *next;
    
    answer = call->async_call.call_var.inc_call.answers.next;
    while (answer != &call->async_call.call_var.inc_call.answers) {
        next = answer->next;
	pjsua_call_answer2(call->index, answer->opt, answer->code,
			   answer->reason, answer->msg_data);
        
        /* Call might have been disconnected if application is answering
         * with 200/OK and the media failed to start.
         * See pjsua_call_answer() below.
         */
        if (!call->inv || !call->inv->pool_prov)
            break;

        pj_list_erase(answer);
        answer = next;
    }
}


/* Incoming call callback when media transport creation is completed. */
static pj_status_t
on_incoming_call_med_tp_complete(pjsua_call_id call_id,
                                 const pjsua_med_tp_state_info *info)
{
    pjsua_call *call = &pjsua_var.calls[call_id];
    const pjmedia_sdp_session *offer=NULL;
    pjmedia_sdp_session *answer;
    pjsip_tx_data *response = NULL;
    unsigned options = 0;
    int sip_err_code = (info? info->sip_err_code: 0);
    pj_status_t status = (info? info->status: PJ_SUCCESS);

    PJSUA_LOCK();

    if (status != PJ_SUCCESS) {
	pjsua_perror(THIS_FILE, "Error initializing media channel", status);
        goto on_return;
    }

    /* pjsua_media_channel_deinit() has been called. */
    if (call->async_call.med_ch_deinit) {
        pjsua_media_channel_deinit(call->index);
        call->med_ch_cb = NULL;
        PJSUA_UNLOCK();
        return PJ_SUCCESS;
    }

    /* Get remote SDP offer (if any). */
    if (call->inv->neg)
        pjmedia_sdp_neg_get_neg_remote(call->inv->neg, &offer);

    status = pjsua_media_channel_create_sdp(call_id,
                                            call->async_call.dlg->pool, 
					    offer, &answer, &sip_err_code);
    if (status != PJ_SUCCESS) {
	pjsua_perror(THIS_FILE, "Error creating SDP answer", status);
        goto on_return;
    }

    status = pjsip_inv_set_local_sdp(call->inv, answer);
    if (status != PJ_SUCCESS) {
	pjsua_perror(THIS_FILE, "Error setting local SDP", status);
        sip_err_code = PJSIP_SC_NOT_ACCEPTABLE_HERE;
        goto on_return;
    }

    /* Verify that we can handle the request. */
    status = pjsip_inv_verify_request3(NULL,
                                       call->inv->pool_prov, &options, offer,
                                       answer, NULL, pjsua_var.endpt, &response);
    if (status != PJ_SUCCESS) {
	/*
	 * No we can't handle the incoming INVITE request.
	 */
        sip_err_code = PJSIP_ERRNO_TO_SIP_STATUS(status);
	goto on_return;
    } 

on_return:
    if (status != PJ_SUCCESS) {
        /* If the callback is called from pjsua_call_on_incoming(), the
         * invite's state is PJSIP_INV_STATE_NULL, so the invite session
         * will be terminated later, otherwise we end the session here.
         */
        if (call->inv->state > PJSIP_INV_STATE_NULL) {
            pjsip_tx_data *tdata;
            pj_status_t status_;

	    status_ = pjsip_inv_end_session(call->inv, sip_err_code, NULL,
                                            &tdata);
	    if (status_ == PJ_SUCCESS && tdata)
	        status_ = pjsip_inv_send_msg(call->inv, tdata);
        }

        pjsua_media_channel_deinit(call->index);
    }

    /* Set the callback to NULL to indicate that the async operation
     * has completed.
     */
    call->med_ch_cb = NULL;

    /* Finish any pending process */
    if (status == PJ_SUCCESS) {
	if (call->async_call.call_var.inc_call.replaced_dlg) {
	    /* Process pending call replace */
	    pjsip_dialog *replaced_dlg = 
			call->async_call.call_var.inc_call.replaced_dlg;
	    process_incoming_call_replace(call, replaced_dlg);
	} else {
	    /* Process pending call answers */
	    process_pending_call_answer(call);
	}
    }

    PJSUA_UNLOCK();
    return status;
}


/**
 * Handle incoming INVITE request.
 * Called by pjsua_core.c
 */
pj_bool_t pjsua_call_on_incoming(pjsip_rx_data *rdata)
{
    pj_str_t contact;
    pjsip_dialog *dlg = pjsip_rdata_get_dlg(rdata);
    pjsip_dialog *replaced_dlg = NULL;
    pjsip_transaction *tsx = pjsip_rdata_get_tsx(rdata);
    pjsip_msg *msg = rdata->msg_info.msg;
    pjsip_tx_data *response = NULL;
    unsigned options = 0;
    pjsip_inv_session *inv = NULL;
    int acc_id;
    pjsua_call *call;
    int call_id = -1;
    int sip_err_code = PJSIP_SC_INTERNAL_SERVER_ERROR;
    pjmedia_sdp_session *offer=NULL;
    pj_status_t status;

    /* Don't want to handle anything but INVITE */
    if (msg->line.req.method.id != PJSIP_INVITE_METHOD)
	return PJ_FALSE;

    /* Don't want to handle anything that's already associated with
     * existing dialog or transaction.
     */
    if (dlg || tsx)
	return PJ_FALSE;

    /* Don't want to accept the call if shutdown is in progress */
    if (pjsua_var.thread_quit_flag) {
	pjsip_endpt_respond_stateless(pjsua_var.endpt, rdata, 
				      PJSIP_SC_TEMPORARILY_UNAVAILABLE, NULL,
				      NULL, NULL);
	return PJ_TRUE;
    }

    PJ_LOG(4,(THIS_FILE, "Incoming %s", rdata->msg_info.info));
    pj_log_push_indent();

    PJSUA_LOCK();

    /* Find free call slot. */
    call_id = alloc_call_id();

    if (call_id == PJSUA_INVALID_ID) {
	pjsip_endpt_respond_stateless(pjsua_var.endpt, rdata, 
				      PJSIP_SC_BUSY_HERE, NULL,
				      NULL, NULL);
	PJ_LOG(2,(THIS_FILE, 
		  "Unable to accept incoming call (too many calls)"));
	goto on_return;
    }

    /* Clear call descriptor */
    reset_call(call_id);

    call = &pjsua_var.calls[call_id];

    /* Mark call start time. */
    pj_gettimeofday(&call->start_time);

    /* Check INVITE request for Replaces header. If Replaces header is
     * present, the function will make sure that we can handle the request.
     */
    status = pjsip_replaces_verify_request(rdata, &replaced_dlg, PJ_FALSE,
					   &response);
    if (status != PJ_SUCCESS) {
	/*
	 * Something wrong with the Replaces header.
	 */
	if (response) {
	    pjsip_response_addr res_addr;

	    pjsip_get_response_addr(response->pool, rdata, &res_addr);
	    pjsip_endpt_send_response(pjsua_var.endpt, &res_addr, response, 
				      NULL, NULL);

	} else {

	    /* Respond with 500 (Internal Server Error) */
	    pjsip_endpt_respond_stateless(pjsua_var.endpt, rdata, 500, NULL,
					  NULL, NULL);
	}

	goto on_return;
    }

    /* If this INVITE request contains Replaces header, notify application
     * about the request so that application can do subsequent checking
     * if it wants to.
     */
    if (replaced_dlg != NULL &&
	(pjsua_var.ua_cfg.cb.on_call_replace_request ||
	 pjsua_var.ua_cfg.cb.on_call_replace_request2))
    {
	pjsua_call *replaced_call;
	int st_code = 200;
	pj_str_t st_text = { "OK", 2 };

	/* Get the replaced call instance */
	replaced_call = (pjsua_call*) replaced_dlg->mod_data[pjsua_var.mod.id];

	/* Copy call setting from the replaced call */
	call->opt = replaced_call->opt;

	/* Notify application */
	if (pjsua_var.ua_cfg.cb.on_call_replace_request) {
	    pjsua_var.ua_cfg.cb.on_call_replace_request(replaced_call->index,
							rdata,
							&st_code, &st_text);
	}

	if (pjsua_var.ua_cfg.cb.on_call_replace_request2) {
	    pjsua_var.ua_cfg.cb.on_call_replace_request2(replaced_call->index,
							 rdata,
							 &st_code, &st_text,
							 &call->opt);
	}

	/* Must specify final response */
	PJ_ASSERT_ON_FAIL(st_code >= 200, st_code = 200);

	/* Check if application rejects this request. */
	if (st_code >= 300) {

	    if (st_text.slen == 2)
		st_text = *pjsip_get_status_text(st_code);

	    pjsip_endpt_respond(pjsua_var.endpt, NULL, rdata, 
				st_code, &st_text, NULL, NULL, NULL);
	    goto on_return;
	}
    }

    /* 
     * Get which account is most likely to be associated with this incoming
     * call. We need the account to find which contact URI to put for
     * the call.
     */
    acc_id = call->acc_id = pjsua_acc_find_for_incoming(rdata);
    call->call_hold_type = pjsua_var.acc[acc_id].cfg.call_hold_type;

    /* Get call's secure level */
    if (PJSIP_URI_SCHEME_IS_SIPS(rdata->msg_info.msg->line.req.uri))
	call->secure_level = 2;
    else if (PJSIP_TRANSPORT_IS_SECURE(rdata->tp_info.transport))
	call->secure_level = 1;
    else
	call->secure_level = 0;

    /* Parse SDP from incoming request */
    if (rdata->msg_info.msg->body) {
	pjsip_rdata_sdp_info *sdp_info;

	sdp_info = pjsip_rdata_get_sdp_info(rdata);
	offer = sdp_info->sdp;

	status = sdp_info->sdp_err;
	if (status==PJ_SUCCESS && sdp_info->sdp==NULL)
	    status = PJSIP_ERRNO_FROM_SIP_STATUS(PJSIP_SC_NOT_ACCEPTABLE);

	if (status != PJ_SUCCESS) {
	    const pj_str_t reason = pj_str("Bad SDP");
	    pjsip_hdr hdr_list;
	    pjsip_warning_hdr *w;

	    pjsua_perror(THIS_FILE, "Bad SDP in incoming INVITE", 
			 status);

	    w = pjsip_warning_hdr_create_from_status(rdata->tp_info.pool, 
					     pjsip_endpt_name(pjsua_var.endpt),
					     status);
	    pj_list_init(&hdr_list);
	    pj_list_push_back(&hdr_list, w);

	    pjsip_endpt_respond(pjsua_var.endpt, NULL, rdata, 400, 
				&reason, &hdr_list, NULL, NULL);
	    goto on_return;
	}

	/* Do quick checks on SDP before passing it to transports. More elabore 
	 * checks will be done in pjsip_inv_verify_request2() below.
	 */
	if (offer->media_count==0) {
	    const pj_str_t reason = pj_str("Missing media in SDP");
	    pjsip_endpt_respond(pjsua_var.endpt, NULL, rdata, 400, &reason, 
				NULL, NULL, NULL);
	    goto on_return;
	}

    } else {
	offer = NULL;
    }

    /* Verify that we can handle the request. */
    options |= PJSIP_INV_SUPPORT_100REL;
    options |= PJSIP_INV_SUPPORT_TIMER;
    if (pjsua_var.acc[acc_id].cfg.require_100rel == PJSUA_100REL_MANDATORY)
	options |= PJSIP_INV_REQUIRE_100REL;
    if (pjsua_var.acc[acc_id].cfg.ice_cfg.enable_ice)
	options |= PJSIP_INV_SUPPORT_ICE;
    if (pjsua_var.acc[acc_id].cfg.use_timer == PJSUA_SIP_TIMER_REQUIRED)
	options |= PJSIP_INV_REQUIRE_TIMER;
    else if (pjsua_var.acc[acc_id].cfg.use_timer == PJSUA_SIP_TIMER_ALWAYS)
	options |= PJSIP_INV_ALWAYS_USE_TIMER;

    status = pjsip_inv_verify_request2(rdata, &options, offer, NULL, NULL,
				       pjsua_var.endpt, &response);
    if (status != PJ_SUCCESS) {

	/*
	 * No we can't handle the incoming INVITE request.
	 */
	if (response) {
	    pjsip_response_addr res_addr;

	    pjsip_get_response_addr(response->pool, rdata, &res_addr);
	    pjsip_endpt_send_response(pjsua_var.endpt, &res_addr, response, 
				      NULL, NULL);

	} else {
	    /* Respond with 500 (Internal Server Error) */
	    pjsip_endpt_respond(pjsua_var.endpt, NULL, rdata, 500, NULL,
				NULL, NULL, NULL);
	}

	goto on_return;
    } 

    /* Get suitable Contact header */
    if (pjsua_var.acc[acc_id].contact.slen) {
	contact = pjsua_var.acc[acc_id].contact;
    } else {
	status = pjsua_acc_create_uas_contact(rdata->tp_info.pool, &contact,
					      acc_id, rdata);
	if (status != PJ_SUCCESS) {
	    pjsua_perror(THIS_FILE, "Unable to generate Contact header", 
			 status);
	    pjsip_endpt_respond_stateless(pjsua_var.endpt, rdata, 500, NULL,
					  NULL, NULL);
	    goto on_return;
	}
    }

    /* Create dialog: */
    status = pjsip_dlg_create_uas( pjsip_ua_instance(), rdata,
				   &contact, &dlg);
    if (status != PJ_SUCCESS) {
	pjsip_endpt_respond_stateless(pjsua_var.endpt, rdata, 500, NULL,
				      NULL, NULL);
	goto on_return;
    }

    if (pjsua_var.acc[acc_id].cfg.allow_via_rewrite &&
        pjsua_var.acc[acc_id].via_addr.host.slen > 0)
    {
        pjsip_dlg_set_via_sent_by(dlg, &pjsua_var.acc[acc_id].via_addr,
                                  pjsua_var.acc[acc_id].via_tp);
    }

    /* Set credentials */
    if (pjsua_var.acc[acc_id].cred_cnt) {
	pjsip_auth_clt_set_credentials(&dlg->auth_sess, 
				       pjsua_var.acc[acc_id].cred_cnt,
				       pjsua_var.acc[acc_id].cred);
    }

    /* Set preference */
    pjsip_auth_clt_set_prefs(&dlg->auth_sess, 
			     &pjsua_var.acc[acc_id].cfg.auth_pref);

    /* Disable Session Timers if not prefered and the incoming INVITE request
     * did not require it.
     */
    if (pjsua_var.acc[acc_id].cfg.use_timer == PJSUA_SIP_TIMER_INACTIVE && 
	(options & PJSIP_INV_REQUIRE_TIMER) == 0)
    {
	options &= ~(PJSIP_INV_SUPPORT_TIMER);
    }

    /* If 100rel is optional and UAC supports it, use it. */
    if ((options & PJSIP_INV_REQUIRE_100REL)==0 &&
	pjsua_var.acc[acc_id].cfg.require_100rel == PJSUA_100REL_OPTIONAL)
    {
	const pj_str_t token = { "100rel", 6};
	pjsip_dialog_cap_status cap_status;

	cap_status = pjsip_dlg_remote_has_cap(dlg, PJSIP_H_SUPPORTED, NULL,
	                                      &token);
	if (cap_status == PJSIP_DIALOG_CAP_SUPPORTED)
	    options |= PJSIP_INV_REQUIRE_100REL;
    }

    /* Create invite session: */
    status = pjsip_inv_create_uas( dlg, rdata, NULL, options, &inv);
    if (status != PJ_SUCCESS) {
	pjsip_hdr hdr_list;
	pjsip_warning_hdr *w;

	w = pjsip_warning_hdr_create_from_status(dlg->pool, 
						 pjsip_endpt_name(pjsua_var.endpt),
						 status);
	pj_list_init(&hdr_list);
	pj_list_push_back(&hdr_list, w);

	pjsip_dlg_respond(dlg, rdata, 500, NULL, &hdr_list, NULL);

	/* Can't terminate dialog because transaction is in progress.
	pjsip_dlg_terminate(dlg);
	 */
	goto on_return;
    }

    /* If account is locked to specific transport, then lock dialog
     * to this transport too.
     */
    if (pjsua_var.acc[acc_id].cfg.transport_id != PJSUA_INVALID_ID) {
	pjsip_tpselector tp_sel;

	pjsua_init_tpselector(pjsua_var.acc[acc_id].cfg.transport_id, &tp_sel);
	pjsip_dlg_set_transport(dlg, &tp_sel);
    }

    /* Create and attach pjsua_var data to the dialog */
    call->inv = inv;

    /* Store variables required for the callback after the async
     * media transport creation is completed.
     */
    call->async_call.dlg = dlg;
    pj_list_init(&call->async_call.call_var.inc_call.answers);

    /* Init media channel, only when there is offer or call replace request.
     * For incoming call without SDP offer, media channel init will be done
     * in pjsua_call_answer(), see ticket #1526.
     */
    if (offer || replaced_dlg) {
	status = pjsua_media_channel_init(call->index, PJSIP_ROLE_UAS, 
					  call->secure_level, 
					  rdata->tp_info.pool,
					  offer,
					  &sip_err_code, PJ_TRUE,
					  &on_incoming_call_med_tp_complete);
	if (status == PJ_SUCCESS) {
	    status = on_incoming_call_med_tp_complete(call_id, NULL);
	    if (status != PJ_SUCCESS) {
		sip_err_code = PJSIP_SC_NOT_ACCEPTABLE;
		/* Since the call invite's state is still PJSIP_INV_STATE_NULL,
		 * the invite session was not ended in
		 * on_incoming_call_med_tp_complete(), so we need to send
		 * a response message and terminate the invite here.
		 */
		pjsip_dlg_respond(dlg, rdata, sip_err_code, NULL, NULL, NULL);
		pjsip_inv_terminate(call->inv, sip_err_code, PJ_FALSE); 
		call->inv = NULL;
		call->async_call.dlg = NULL;
		goto on_return;
	    }
	} else if (status != PJ_EPENDING) {
	    pjsua_perror(THIS_FILE, "Error initializing media channel", status);
	    pjsip_dlg_respond(dlg, rdata, sip_err_code, NULL, NULL, NULL);
	    pjsip_inv_terminate(call->inv, sip_err_code, PJ_FALSE); 
	    call->inv = NULL; 
	    call->async_call.dlg = NULL;
	    goto on_return;
	}
    }

    /* Create answer */
/*  
    status = pjsua_media_channel_create_sdp(call->index, rdata->tp_info.pool, 
					    offer, &answer, &sip_err_code);
    if (status != PJ_SUCCESS) {
	pjsua_perror(THIS_FILE, "Error creating SDP answer", status);
	pjsip_endpt_respond(pjsua_var.endpt, NULL, rdata,
			    sip_err_code, NULL, NULL, NULL, NULL);
	goto on_return;
    }
*/

    /* Init Session Timers */
    status = pjsip_timer_init_session(inv, 
				    &pjsua_var.acc[acc_id].cfg.timer_setting);
    if (status != PJ_SUCCESS) {
	pjsua_perror(THIS_FILE, "Session Timer init failed", status);
        pjsip_dlg_respond(dlg, rdata, PJSIP_SC_INTERNAL_SERVER_ERROR, NULL, NULL, NULL);
	pjsip_inv_terminate(inv, PJSIP_SC_INTERNAL_SERVER_ERROR, PJ_FALSE);

	pjsua_media_channel_deinit(call->index);
	call->inv = NULL;
	call->async_call.dlg = NULL;

	goto on_return;
    }

    /* Update NAT type of remote endpoint, only when there is SDP in
     * incoming INVITE! 
     */
    if (pjsua_var.ua_cfg.nat_type_in_sdp && inv->neg &&
	pjmedia_sdp_neg_get_state(inv->neg) > PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER) 
    {
	const pjmedia_sdp_session *remote_sdp;

	if (pjmedia_sdp_neg_get_neg_remote(inv->neg, &remote_sdp)==PJ_SUCCESS)
	    update_remote_nat_type(call, remote_sdp);
    }

    /* Must answer with some response to initial INVITE. We'll do this before
     * attaching the call to the invite session/dialog, so that the application
     * will not get notification about this event (on another scenario, it is
     * also possible that inv_send_msg() fails and causes the invite session to
     * be disconnected. If we have the call attached at this time, this will
     * cause the disconnection callback to be called before on_incoming_call()
     * callback is called, which is not right).
     */
    status = pjsip_inv_initial_answer(inv, rdata,
				      100, NULL, NULL, &response);
    if (status != PJ_SUCCESS) {
	if (response == NULL) {
	    pjsua_perror(THIS_FILE, "Unable to send answer to incoming INVITE",
			 status);
	    pjsip_dlg_respond(dlg, rdata, 500, NULL, NULL, NULL);
	    pjsip_inv_terminate(inv, 500, PJ_FALSE);
	} else {
	    pjsip_inv_send_msg(inv, response);
	    pjsip_inv_terminate(inv, response->msg->line.status.code,
				PJ_FALSE);
	}
	pjsua_media_channel_deinit(call->index);
	call->inv = NULL;
	call->async_call.dlg = NULL;
	goto on_return;

    } else {
	status = pjsip_inv_send_msg(inv, response);
	if (status != PJ_SUCCESS) {
	    pjsua_perror(THIS_FILE, "Unable to send 100 response", status);
	    pjsua_media_channel_deinit(call->index);
	    call->inv = NULL;
	    call->async_call.dlg = NULL;
	    goto on_return;
	}
    }

    /* Only do this after sending 100/Trying (really! see the long comment
     * above)
     */
    dlg->mod_data[pjsua_var.mod.id] = call;
    inv->mod_data[pjsua_var.mod.id] = call;

    ++pjsua_var.call_cnt;

    /* Check if this request should replace existing call */
    if (replaced_dlg) {
	/* Process call replace. If the media channel init has been completed,
	 * just process now, otherwise, just queue the replaced dialog so
	 * it will be processed once the media channel async init is finished
	 * successfully.
	 */
	if (call->med_ch_cb == NULL) {
	    process_incoming_call_replace(call, replaced_dlg);
	} else {
	    call->async_call.call_var.inc_call.replaced_dlg = replaced_dlg;
	}
    } else {
	/* Notify application if on_incoming_call() is overriden, 
	 * otherwise hangup the call with 480
	 */
	if (pjsua_var.ua_cfg.cb.on_incoming_call) {
	    pjsua_var.ua_cfg.cb.on_incoming_call(acc_id, call_id, rdata);
	} else {
	    pjsua_call_hangup(call_id, PJSIP_SC_TEMPORARILY_UNAVAILABLE, 
			      NULL, NULL);
	}
    }


    /* This INVITE request has been handled. */
on_return:
    pj_log_pop_indent();
    PJSUA_UNLOCK();
    return PJ_TRUE;
}



/*
 * Check if the specified call has active INVITE session and the INVITE
 * session has not been disconnected.
 */
PJ_DEF(pj_bool_t) pjsua_call_is_active(pjsua_call_id call_id)
{
    PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
		     PJ_EINVAL);
    return pjsua_var.calls[call_id].inv != NULL &&
	   pjsua_var.calls[call_id].inv->state != PJSIP_INV_STATE_DISCONNECTED;
}


/* Acquire lock to the specified call_id */
pj_status_t acquire_call(const char *title,
				pjsua_call_id call_id,
				pjsua_call **p_call,
				pjsip_dialog **p_dlg)
{
    unsigned retry;
    pjsua_call *call = NULL;
    pj_bool_t has_pjsua_lock = PJ_FALSE;
    pj_status_t status = PJ_SUCCESS;
    pj_time_val time_start, timeout;
    pjsip_dialog *dlg = NULL;

    pj_gettimeofday(&time_start);
    timeout.sec = 0;
    timeout.msec = PJSUA_ACQUIRE_CALL_TIMEOUT;
    pj_time_val_normalize(&timeout);

    for (retry=0; ; ++retry) {

        if (retry % 10 == 9) {
            pj_time_val dtime;

            pj_gettimeofday(&dtime);
            PJ_TIME_VAL_SUB(dtime, time_start);
            if (!PJ_TIME_VAL_LT(dtime, timeout))
                break;
        }
	
	has_pjsua_lock = PJ_FALSE;

	status = PJSUA_TRY_LOCK();
	if (status != PJ_SUCCESS) {
	    pj_thread_sleep(retry/10);
	    continue;
	}

	has_pjsua_lock = PJ_TRUE;
	call = &pjsua_var.calls[call_id];
        if (call->inv)
            dlg = call->inv->dlg;
        else
            dlg = call->async_call.dlg;

	if (dlg == NULL) {
	    PJSUA_UNLOCK();
	    PJ_LOG(3,(THIS_FILE, "Invalid call_id %d in %s", call_id, title));
	    return PJSIP_ESESSIONTERMINATED;
	}

	status = pjsip_dlg_try_inc_lock(dlg);
	if (status != PJ_SUCCESS) {
	    PJSUA_UNLOCK();
	    pj_thread_sleep(retry/10);
	    continue;
	}

	PJSUA_UNLOCK();

	break;
    }

    if (status != PJ_SUCCESS) {
	if (has_pjsua_lock == PJ_FALSE)
	    PJ_LOG(1,(THIS_FILE, "Timed-out trying to acquire PJSUA mutex "
				 "(possibly system has deadlocked) in %s",
				 title));
	else
	    PJ_LOG(1,(THIS_FILE, "Timed-out trying to acquire dialog mutex "
				 "(possibly system has deadlocked) in %s",
				 title));
	return PJ_ETIMEDOUT;
    }
    
    *p_call = call;
    *p_dlg = dlg;

    return PJ_SUCCESS;
}


/*
 * Obtain detail information about the specified call.
 */
PJ_DEF(pj_status_t) pjsua_call_get_info( pjsua_call_id call_id,
					 pjsua_call_info *info)
{
    pjsua_call *call;
    pjsip_dialog *dlg;
    unsigned mi;

    PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
		     PJ_EINVAL);

    pj_bzero(info, sizeof(*info));

    /* Use PJSUA_LOCK() instead of acquire_call():
     *  https://trac.pjsip.org/repos/ticket/1371
     */
    PJSUA_LOCK();

    call = &pjsua_var.calls[call_id];
    dlg = (call->inv ? call->inv->dlg : call->async_call.dlg);
    if (!dlg) {
	PJSUA_UNLOCK();
	return PJSIP_ESESSIONTERMINATED;
    }

    /* id and role */
    info->id = call_id;
    info->role = dlg->role;
    info->acc_id = call->acc_id;

    /* local info */
    info->local_info.ptr = info->buf_.local_info;
    pj_strncpy(&info->local_info, &dlg->local.info_str,
	       sizeof(info->buf_.local_info));

    /* local contact */
    info->local_contact.ptr = info->buf_.local_contact;
    info->local_contact.slen = pjsip_uri_print(PJSIP_URI_IN_CONTACT_HDR,
					       dlg->local.contact->uri,
					       info->local_contact.ptr,
					       sizeof(info->buf_.local_contact));

    /* remote info */
    info->remote_info.ptr = info->buf_.remote_info;
    pj_strncpy(&info->remote_info, &dlg->remote.info_str,
	       sizeof(info->buf_.remote_info));

    /* remote contact */
    if (dlg->remote.contact) {
	int len;
	info->remote_contact.ptr = info->buf_.remote_contact;
	len = pjsip_uri_print(PJSIP_URI_IN_CONTACT_HDR,
			      dlg->remote.contact->uri,
			      info->remote_contact.ptr,
			      sizeof(info->buf_.remote_contact));
	if (len < 0) len = 0;
	info->remote_contact.slen = len;
    } else {
	info->remote_contact.slen = 0;
    }

    /* call id */
    info->call_id.ptr = info->buf_.call_id;
    pj_strncpy(&info->call_id, &dlg->call_id->id,
	       sizeof(info->buf_.call_id));

    /* call setting */
    pj_memcpy(&info->setting, &call->opt, sizeof(call->opt));

    /* state, state_text */
    if (call->inv) {
        info->state = call->inv->state;
    } else if (call->async_call.dlg && call->last_code==0) {
        info->state = PJSIP_INV_STATE_NULL;
    } else {
        info->state = PJSIP_INV_STATE_DISCONNECTED;
    }
    info->state_text = pj_str((char*)pjsip_inv_state_name(info->state));

    /* If call is disconnected, set the last_status from the cause code */
    if (call->inv && call->inv->state >= PJSIP_INV_STATE_DISCONNECTED) {
	/* last_status, last_status_text */
	info->last_status = call->inv->cause;

	info->last_status_text.ptr = info->buf_.last_status_text;
	pj_strncpy(&info->last_status_text, &call->inv->cause_text,
		   sizeof(info->buf_.last_status_text));
    } else {
	/* last_status, last_status_text */
	info->last_status = call->last_code;

	info->last_status_text.ptr = info->buf_.last_status_text;
	pj_strncpy(&info->last_status_text, &call->last_text,
		   sizeof(info->buf_.last_status_text));
    }
    
    /* Audio & video count offered by remote */
    info->rem_offerer   = call->rem_offerer;
    if (call->rem_offerer) {
	info->rem_aud_cnt = call->rem_aud_cnt;
	info->rem_vid_cnt = call->rem_vid_cnt;
    }

    /* Build array of active media info */
    info->media_cnt = 0;
    for (mi=0; mi < call->med_cnt &&
	       info->media_cnt < PJ_ARRAY_SIZE(info->media); ++mi)
    {
	pjsua_call_media *call_med = &call->media[mi];

	info->media[info->media_cnt].index = mi;
	info->media[info->media_cnt].status = call_med->state;
	info->media[info->media_cnt].dir = call_med->dir;
	info->media[info->media_cnt].type = call_med->type;

	if (call_med->type == PJMEDIA_TYPE_AUDIO) {
	    info->media[info->media_cnt].stream.aud.conf_slot =
						call_med->strm.a.conf_slot;
	} else if (call_med->type == PJMEDIA_TYPE_VIDEO) {
	    pjmedia_vid_dev_index cap_dev = PJMEDIA_VID_INVALID_DEV;

	    info->media[info->media_cnt].stream.vid.win_in = 
						call_med->strm.v.rdr_win_id;

	    if (call_med->strm.v.cap_win_id != PJSUA_INVALID_ID) {
		cap_dev = call_med->strm.v.cap_dev;
	    }
	    info->media[info->media_cnt].stream.vid.cap_dev = cap_dev;
	} else {
	    continue;
	}
	++info->media_cnt;
    }

    if (call->audio_idx != -1) {
	info->media_status = call->media[call->audio_idx].state;
	info->media_dir = call->media[call->audio_idx].dir;
	info->conf_slot = call->media[call->audio_idx].strm.a.conf_slot;
    }

    /* Build array of provisional media info */
    info->prov_media_cnt = 0;
    for (mi=0; mi < call->med_prov_cnt &&
	       info->prov_media_cnt < PJ_ARRAY_SIZE(info->prov_media); ++mi)
    {
	pjsua_call_media *call_med = &call->media_prov[mi];

	info->prov_media[info->prov_media_cnt].index = mi;
	info->prov_media[info->prov_media_cnt].status = call_med->state;
	info->prov_media[info->prov_media_cnt].dir = call_med->dir;
	info->prov_media[info->prov_media_cnt].type = call_med->type;
	if (call_med->type == PJMEDIA_TYPE_AUDIO) {
	    info->prov_media[info->prov_media_cnt].stream.aud.conf_slot =
						call_med->strm.a.conf_slot;
	} else if (call_med->type == PJMEDIA_TYPE_VIDEO) {
	    pjmedia_vid_dev_index cap_dev = PJMEDIA_VID_INVALID_DEV;

	    info->prov_media[info->prov_media_cnt].stream.vid.win_in = 
						call_med->strm.v.rdr_win_id;

	    if (call_med->strm.v.cap_win_id != PJSUA_INVALID_ID) {
		cap_dev = call_med->strm.v.cap_dev;
	    }
	    info->prov_media[info->prov_media_cnt].stream.vid.cap_dev=cap_dev;
	} else {
	    continue;
	}
	++info->prov_media_cnt;
    }

    /* calculate duration */
    if (info->state >= PJSIP_INV_STATE_DISCONNECTED) {

	info->total_duration = call->dis_time;
	PJ_TIME_VAL_SUB(info->total_duration, call->start_time);

	if (call->conn_time.sec) {
	    info->connect_duration = call->dis_time;
	    PJ_TIME_VAL_SUB(info->connect_duration, call->conn_time);
	}

    } else if (info->state == PJSIP_INV_STATE_CONFIRMED) {

	pj_gettimeofday(&info->total_duration);
	PJ_TIME_VAL_SUB(info->total_duration, call->start_time);

	pj_gettimeofday(&info->connect_duration);
	PJ_TIME_VAL_SUB(info->connect_duration, call->conn_time);

    } else {
	pj_gettimeofday(&info->total_duration);
	PJ_TIME_VAL_SUB(info->total_duration, call->start_time);
    }

    PJSUA_UNLOCK();

    return PJ_SUCCESS;
}

/*
 * Check if call remote peer support the specified capability.
 */
PJ_DEF(pjsip_dialog_cap_status) pjsua_call_remote_has_cap(
						    pjsua_call_id call_id,
						    int htype,
						    const pj_str_t *hname,
						    const pj_str_t *token)
{
    pjsua_call *call;
    pjsip_dialog *dlg;
    pj_status_t status;
    pjsip_dialog_cap_status cap_status;

    status = acquire_call("pjsua_call_peer_has_cap()", call_id, &call, &dlg);
    if (status != PJ_SUCCESS)
	return PJSIP_DIALOG_CAP_UNKNOWN;

    cap_status = pjsip_dlg_remote_has_cap(dlg, htype, hname, token);

    pjsip_dlg_dec_lock(dlg);

    return cap_status;
}


/*
 * Attach application specific data to the call.
 */
PJ_DEF(pj_status_t) pjsua_call_set_user_data( pjsua_call_id call_id,
					      void *user_data)
{
    PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
		     PJ_EINVAL);
    pjsua_var.calls[call_id].user_data = user_data;

    return PJ_SUCCESS;
}


/*
 * Get user data attached to the call.
 */
PJ_DEF(void*) pjsua_call_get_user_data(pjsua_call_id call_id)
{
    PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
		     NULL);
    return pjsua_var.calls[call_id].user_data;
}


/*
 * Get remote's NAT type.
 */
PJ_DEF(pj_status_t) pjsua_call_get_rem_nat_type(pjsua_call_id call_id,
						pj_stun_nat_type *p_type)
{
    PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
		     PJ_EINVAL);
    PJ_ASSERT_RETURN(p_type != NULL, PJ_EINVAL);

    *p_type = pjsua_var.calls[call_id].rem_nat_type;
    return PJ_SUCCESS;
}


/*
 * Get media transport info for the specified media index.
 */
PJ_DEF(pj_status_t) 
pjsua_call_get_med_transport_info(pjsua_call_id call_id,
                                  unsigned med_idx,
                                  pjmedia_transport_info *t)
{
    pjsua_call *call;
    pjsua_call_media *call_med;
    pj_status_t status;

    PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
		     PJ_EINVAL);
    PJ_ASSERT_RETURN(t, PJ_EINVAL);

    PJSUA_LOCK();

    call = &pjsua_var.calls[call_id];
    
    if (med_idx >= call->med_cnt) {
	PJSUA_UNLOCK();
	return PJ_EINVAL;
    }

    call_med = &call->media[med_idx];

    pjmedia_transport_info_init(t);
    status = pjmedia_transport_get_info(call_med->tp, t);
    
    PJSUA_UNLOCK();
    return status;
}


/* Media channel init callback for pjsua_call_answer(). */
static pj_status_t
on_answer_call_med_tp_complete(pjsua_call_id call_id,
                               const pjsua_med_tp_state_info *info)
{
    pjsua_call *call = &pjsua_var.calls[call_id];
    pjmedia_sdp_session *sdp;
    int sip_err_code = (info? info->sip_err_code: 0);
    pj_status_t status = (info? info->status: PJ_SUCCESS);

    PJSUA_LOCK();

    if (status != PJ_SUCCESS) {
	pjsua_perror(THIS_FILE, "Error initializing media channel", status);
        goto on_return;
    }

    /* pjsua_media_channel_deinit() has been called. */
    if (call->async_call.med_ch_deinit) {
        pjsua_media_channel_deinit(call->index);
        call->med_ch_cb = NULL;
        PJSUA_UNLOCK();
        return PJ_SUCCESS;
    }

    status = pjsua_media_channel_create_sdp(call_id,
                                            call->async_call.dlg->pool, 
					    NULL, &sdp, &sip_err_code);
    if (status != PJ_SUCCESS) {
	pjsua_perror(THIS_FILE, "Error creating SDP answer", status);
        goto on_return;
    }

    status = pjsip_inv_set_local_sdp(call->inv, sdp);
    if (status != PJ_SUCCESS) {
	pjsua_perror(THIS_FILE, "Error setting local SDP", status);
        sip_err_code = PJSIP_SC_NOT_ACCEPTABLE_HERE;
        goto on_return;
    }

on_return:
    if (status != PJ_SUCCESS) {
        /* If the callback is called from pjsua_call_on_incoming(), the
         * invite's state is PJSIP_INV_STATE_NULL, so the invite session
         * will be terminated later, otherwise we end the session here.
         */
        if (call->inv->state > PJSIP_INV_STATE_NULL) {
            pjsip_tx_data *tdata;
            pj_status_t status_;

	    status_ = pjsip_inv_end_session(call->inv, sip_err_code, NULL,
                                            &tdata);
	    if (status_ == PJ_SUCCESS && tdata)
	        status_ = pjsip_inv_send_msg(call->inv, tdata);
        }

        pjsua_media_channel_deinit(call->index);
    }

    /* Set the callback to NULL to indicate that the async operation
     * has completed.
     */
    call->med_ch_cb = NULL;

    /* Finish any pending process */
    if (status == PJ_SUCCESS) {
	/* Process pending call answers */
	process_pending_call_answer(call);
    }

    PJSUA_UNLOCK();
    return status;
}


/*
 * Send response to incoming INVITE request.
 */
PJ_DEF(pj_status_t) pjsua_call_answer( pjsua_call_id call_id, 
				       unsigned code,
				       const pj_str_t *reason,
				       const pjsua_msg_data *msg_data)
{
    return pjsua_call_answer2(call_id, NULL, code, reason, msg_data);
}


/*
 * Send response to incoming INVITE request.
 */
PJ_DEF(pj_status_t) pjsua_call_answer2(pjsua_call_id call_id,
				       const pjsua_call_setting *opt,
				       unsigned code,
				       const pj_str_t *reason,
				       const pjsua_msg_data *msg_data)
{
    pjsua_call *call;
    pjsip_dialog *dlg = NULL;
    pjsip_tx_data *tdata;
    pj_status_t status;

    PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
		     PJ_EINVAL);

    PJ_LOG(4,(THIS_FILE, "Answering call %d: code=%d", call_id, code));
    pj_log_push_indent();

    status = acquire_call("pjsua_call_answer()", call_id, &call, &dlg);
    if (status != PJ_SUCCESS)
	goto on_return;

    /* Apply call setting, only if status code is 1xx or 2xx. */
    if (opt && code < 300) {
	/* Check if it has not been set previously or it is different to
	 * the previous one.
	 */
	if (!call->opt_inited) {
	    call->opt_inited = PJ_TRUE;
	    apply_call_setting(call, opt, NULL);
	} else if (pj_memcmp(opt, &call->opt, sizeof(*opt)) != 0) {
	    /* Warn application about call setting inconsistency */
	    PJ_LOG(2,(THIS_FILE, "The call setting changes is ignored."));
	}
    }

    PJSUA_LOCK();

    /* Ticket #1526: When the incoming call contains no SDP offer, the media
     * channel may have not been initialized at this stage. The media channel
     * will be initialized here (along with SDP local offer generation) when
     * the following conditions are met:
     * - no pending media channel init
     * - local SDP has not been generated
     * - call setting has just been set, or SDP offer needs to be sent, i.e:
     *   answer code 183 or 2xx is issued
     */
    if (!call->med_ch_cb && 
	(call->opt_inited || (code==183 || code/100==2)) &&
	(!call->inv->neg ||
	 pjmedia_sdp_neg_get_state(call->inv->neg) == 
		PJMEDIA_SDP_NEG_STATE_NULL))
    {
	/* Mark call setting as initialized as it is just about to be used
	 * for initializing the media channel.
	 */
	call->opt_inited = PJ_TRUE;

	status = pjsua_media_channel_init(call->index, PJSIP_ROLE_UAC,
					  call->secure_level,
					  dlg->pool,
					  NULL, NULL, PJ_TRUE,
					  &on_answer_call_med_tp_complete);
	if (status == PJ_SUCCESS) {
	    status = on_answer_call_med_tp_complete(call->index, NULL);
	    if (status != PJ_SUCCESS) {
		PJSUA_UNLOCK();
		goto on_return;
	    }
	} else if (status != PJ_EPENDING) {
	    PJSUA_UNLOCK();
	    pjsua_perror(THIS_FILE, "Error initializing media channel", status);
	    goto on_return;
	}
    }

    /* If media transport creation is not yet completed, we will answer
     * the call in the media transport creation callback instead.
     */
    if (call->med_ch_cb) {
        struct call_answer *answer;
        
        PJ_LOG(4,(THIS_FILE, "Pending answering call %d upon completion "
                             "of media transport", call_id));

        answer = PJ_POOL_ZALLOC_T(call->inv->pool_prov, struct call_answer);
        answer->code = code;
	if (opt) {
	    answer->opt = PJ_POOL_ZALLOC_T(call->inv->pool_prov,
					   pjsua_call_setting);
	    *answer->opt = *opt;
	}
        if (reason) {
            pj_strdup(call->inv->pool_prov, answer->reason, reason);
        }
        if (msg_data) {
            answer->msg_data = pjsua_msg_data_clone(call->inv->pool_prov,
                                                    msg_data);
        }
        pj_list_push_back(&call->async_call.call_var.inc_call.answers,
                          answer);

        PJSUA_UNLOCK();
        if (dlg) pjsip_dlg_dec_lock(dlg);
        pj_log_pop_indent();
        return status;
    }

    PJSUA_UNLOCK();

    if (call->res_time.sec == 0)
	pj_gettimeofday(&call->res_time);

    if (reason && reason->slen == 0)
	reason = NULL;

    /* Create response message */
    status = pjsip_inv_answer(call->inv, code, reason, NULL, &tdata);
    if (status != PJ_SUCCESS) {
	pjsua_perror(THIS_FILE, "Error creating response", 
		     status);
	goto on_return;
    }

    /* Call might have been disconnected if application is answering with
     * 200/OK and the media failed to start.
     */
    if (call->inv == NULL)
	goto on_return;

    /* Add additional headers etc */
    pjsua_process_msg_data( tdata, msg_data);

    /* Send the message */
    status = pjsip_inv_send_msg(call->inv, tdata);
    if (status != PJ_SUCCESS)
	pjsua_perror(THIS_FILE, "Error sending response", 
		     status);

on_return:
    if (dlg) pjsip_dlg_dec_lock(dlg);
    pj_log_pop_indent();
    return status;
}


/*
 * Hangup call by using method that is appropriate according to the
 * call state.
 */
PJ_DEF(pj_status_t) pjsua_call_hangup(pjsua_call_id call_id,
				      unsigned code,
				      const pj_str_t *reason,
				      const pjsua_msg_data *msg_data)
{
    pjsua_call *call;
    pjsip_dialog *dlg = NULL;
    pj_status_t status;
    pjsip_tx_data *tdata;


    if (call_id<0 || call_id>=(int)pjsua_var.ua_cfg.max_calls) {
	PJ_LOG(1,(THIS_FILE, "pjsua_call_hangup(): invalid call id %d",
			     call_id));
    }
    
    PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
		     PJ_EINVAL);

    PJ_LOG(4,(THIS_FILE, "Call %d hanging up: code=%d..", call_id, code));
    pj_log_push_indent();

    status = acquire_call("pjsua_call_hangup()", call_id, &call, &dlg);
    if (status != PJ_SUCCESS)
	goto on_return;

    /* If media transport creation is not yet completed, we will hangup
     * the call in the media transport creation callback instead.
     */
    if (call->med_ch_cb && !call->inv) {
        PJ_LOG(4,(THIS_FILE, "Pending call %d hangup upon completion "
                             "of media transport", call_id));
        call->async_call.call_var.out_call.hangup = PJ_TRUE;
        if (code == 0)
            call->last_code = PJSIP_SC_REQUEST_TERMINATED;
        else
            call->last_code = (pjsip_status_code)code;
        if (reason) {
            pj_strncpy(&call->last_text, reason,
		       sizeof(call->last_text_buf_));
        }
        
        goto on_return;
    }

    if (code==0) {
	if (call->inv->state == PJSIP_INV_STATE_CONFIRMED)
	    code = PJSIP_SC_OK;
	else if (call->inv->role == PJSIP_ROLE_UAS)
	    code = PJSIP_SC_DECLINE;
	else
	    code = PJSIP_SC_REQUEST_TERMINATED;
    }

    status = pjsip_inv_end_session(call->inv, code, reason, &tdata);
    if (status != PJ_SUCCESS) {
	pjsua_perror(THIS_FILE, 
		     "Failed to create end session message", 
		     status);
	goto on_return;
    }

    /* pjsip_inv_end_session may return PJ_SUCCESS with NULL 
     * as p_tdata when INVITE transaction has not been answered
     * with any provisional responses.
     */
    if (tdata == NULL)
	goto on_return;

    /* Add additional headers etc */
    pjsua_process_msg_data( tdata, msg_data);

    /* Send the message */
    status = pjsip_inv_send_msg(call->inv, tdata);
    if (status != PJ_SUCCESS) {
	pjsua_perror(THIS_FILE, 
		     "Failed to send end session message", 
		     status);
	goto on_return;
    }

    /* Stop reinvite timer, if it is active */
    if (call->reinv_timer.id) {
	pjsua_cancel_timer(&call->reinv_timer);
	call->reinv_timer.id = PJ_FALSE;
    }

on_return:
    if (dlg) pjsip_dlg_dec_lock(dlg);
    pj_log_pop_indent();
    return status;
}


/*
 * Accept or reject redirection.
 */
PJ_DEF(pj_status_t) pjsua_call_process_redirect( pjsua_call_id call_id,
						 pjsip_redirect_op cmd)
{
    pjsua_call *call;
    pjsip_dialog *dlg;
    pj_status_t status;

    PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
		     PJ_EINVAL);

    status = acquire_call("pjsua_call_process_redirect()", call_id, 
			  &call, &dlg);
    if (status != PJ_SUCCESS)
	return status;

    status = pjsip_inv_process_redirect(call->inv, cmd, NULL);

    pjsip_dlg_dec_lock(dlg);

    return status;
}


/*
 * Put the specified call on hold.
 */
PJ_DEF(pj_status_t) pjsua_call_set_hold(pjsua_call_id call_id,
					const pjsua_msg_data *msg_data)
{
    return pjsua_call_set_hold2(call_id, 0, msg_data);
}

PJ_DEF(pj_status_t) pjsua_call_set_hold2(pjsua_call_id call_id,
                                         unsigned options,
					 const pjsua_msg_data *msg_data)
{
    pjmedia_sdp_session *sdp;
    pjsua_call *call;
    pjsip_dialog *dlg = NULL;
    pjsip_tx_data *tdata;
    pj_str_t *new_contact = NULL;
    pj_status_t status;

    PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
		     PJ_EINVAL);

    PJ_LOG(4,(THIS_FILE, "Putting call %d on hold", call_id));
    pj_log_push_indent();

    status = acquire_call("pjsua_call_set_hold()", call_id, &call, &dlg);
    if (status != PJ_SUCCESS)
	goto on_return;

    if (call->inv->state != PJSIP_INV_STATE_CONFIRMED) {
	PJ_LOG(3,(THIS_FILE, "Can not hold call that is not confirmed"));
	status = PJSIP_ESESSIONSTATE;
	goto on_return;
    }

    status = create_sdp_of_call_hold(call, &sdp);
    if (status != PJ_SUCCESS)
	goto on_return;

    if ((options & PJSUA_CALL_UPDATE_CONTACT) &&
	pjsua_acc_is_valid(call->acc_id))
    {
	new_contact = &pjsua_var.acc[call->acc_id].contact;
    }

    /* Create re-INVITE with new offer */
    status = pjsip_inv_reinvite( call->inv, new_contact, sdp, &tdata);
    if (status != PJ_SUCCESS) {
	pjsua_perror(THIS_FILE, "Unable to create re-INVITE", status);
	goto on_return;
    }

    /* Add additional headers etc */
    pjsua_process_msg_data( tdata, msg_data);

    /* Record the tx_data to keep track the operation */
    call->hold_msg = (void*) tdata;

    /* Send the request */
    status = pjsip_inv_send_msg( call->inv, tdata);
    if (status != PJ_SUCCESS) {
	pjsua_perror(THIS_FILE, "Unable to send re-INVITE", status);
	call->hold_msg = NULL;
	goto on_return;
    }

    /* Set flag that local put the call on hold */
    call->local_hold = PJ_TRUE;

on_return:
    if (dlg) pjsip_dlg_dec_lock(dlg);
    pj_log_pop_indent();
    return status;
}


/*
 * Send re-INVITE (to release hold).
 */
PJ_DEF(pj_status_t) pjsua_call_reinvite( pjsua_call_id call_id,
                                         unsigned options,
					 const pjsua_msg_data *msg_data)
{
    pjsua_call *call;
    pjsip_dialog *dlg = NULL;
    pj_status_t status;

    status = acquire_call("pjsua_call_reinvite()", call_id, &call, &dlg);
    if (status != PJ_SUCCESS)
	goto on_return;

    if (options != call->opt.flag)
	call->opt.flag = options;

    status = pjsua_call_reinvite2(call_id, NULL, msg_data);

on_return:
    if (dlg) pjsip_dlg_dec_lock(dlg);
    return status;
}


/*
 * Send re-INVITE (to release hold).
 */
PJ_DEF(pj_status_t) pjsua_call_reinvite2(pjsua_call_id call_id,
                                         const pjsua_call_setting *opt,
					 const pjsua_msg_data *msg_data)
{
    pjmedia_sdp_session *sdp;
    pj_str_t *new_contact = NULL;
    pjsip_tx_data *tdata;
    pjsua_call *call;
    pjsip_dialog *dlg = NULL;
    pj_status_t status;


    PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
		     PJ_EINVAL);

    PJ_LOG(4,(THIS_FILE, "Sending re-INVITE on call %d", call_id));
    pj_log_push_indent();

    status = acquire_call("pjsua_call_reinvite2()", call_id, &call, &dlg);
    if (status != PJ_SUCCESS)
	goto on_return;

    if (call->inv->state != PJSIP_INV_STATE_CONFIRMED) {
	PJ_LOG(3,(THIS_FILE, "Can not re-INVITE call that is not confirmed"));
	status = PJSIP_ESESSIONSTATE;
	goto on_return;
    }

    status = apply_call_setting(call, opt, NULL);
    if (status != PJ_SUCCESS) {
	pjsua_perror(THIS_FILE, "Failed to apply call setting", status);
	goto on_return;
    }

    /* Create SDP */
    if (call->local_hold && (call->opt.flag & PJSUA_CALL_UNHOLD)==0) {
	status = create_sdp_of_call_hold(call, &sdp);
    } else {
	status = pjsua_media_channel_create_sdp(call->index, 
						call->inv->pool_prov,
						NULL, &sdp, NULL);
	call->local_hold = PJ_FALSE;
    }
    if (status != PJ_SUCCESS) {
	pjsua_perror(THIS_FILE, "Unable to get SDP from media endpoint", 
		     status);
	goto on_return;
    }

    if ((call->opt.flag & PJSUA_CALL_UPDATE_CONTACT) &&
	    pjsua_acc_is_valid(call->acc_id))
    {
	new_contact = &pjsua_var.acc[call->acc_id].contact;
    }

    /* Create re-INVITE with new offer */
    status = pjsip_inv_reinvite( call->inv, new_contact, sdp, &tdata);
    if (status != PJ_SUCCESS) {
	pjsua_perror(THIS_FILE, "Unable to create re-INVITE", status);
	goto on_return;
    }

    /* Add additional headers etc */
    pjsua_process_msg_data( tdata, msg_data);

    /* Send the request */
    status = pjsip_inv_send_msg( call->inv, tdata);
    if (status != PJ_SUCCESS) {
	pjsua_perror(THIS_FILE, "Unable to send re-INVITE", status);
	goto on_return;
    }

on_return:
    if (dlg) pjsip_dlg_dec_lock(dlg);
    pj_log_pop_indent();
    return status;
}


/*
 * Send UPDATE request.
 */
PJ_DEF(pj_status_t) pjsua_call_update( pjsua_call_id call_id,
				       unsigned options,
				       const pjsua_msg_data *msg_data)
{
    pjsua_call *call;
    pjsip_dialog *dlg = NULL;
    pj_status_t status;

    status = acquire_call("pjsua_call_update()", call_id, &call, &dlg);
    if (status != PJ_SUCCESS)
	goto on_return;

    if (options != call->opt.flag)
	call->opt.flag = options;

    status = pjsua_call_update2(call_id, NULL, msg_data);

on_return:
    if (dlg) pjsip_dlg_dec_lock(dlg);
    return status;
}


/*
 * Send UPDATE request.
 */
PJ_DEF(pj_status_t) pjsua_call_update2(pjsua_call_id call_id,
				       const pjsua_call_setting *opt,
				       const pjsua_msg_data *msg_data)
{
    pjmedia_sdp_session *sdp;
    pj_str_t *new_contact = NULL;
    pjsip_tx_data *tdata;
    pjsua_call *call;
    pjsip_dialog *dlg = NULL;
    pj_status_t status;

    PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
		     PJ_EINVAL);

    PJ_LOG(4,(THIS_FILE, "Sending UPDATE on call %d", call_id));
    pj_log_push_indent();

    status = acquire_call("pjsua_call_update2()", call_id, &call, &dlg);
    if (status != PJ_SUCCESS)
	goto on_return;

    status = apply_call_setting(call, opt, NULL);
    if (status != PJ_SUCCESS) {
	pjsua_perror(THIS_FILE, "Failed to apply call setting", status);
	goto on_return;
    }

    /* Create SDP */
    if (call->local_hold && (call->opt.flag & PJSUA_CALL_UNHOLD)==0) {
	status = create_sdp_of_call_hold(call, &sdp);
    } else {
	status = pjsua_media_channel_create_sdp(call->index,
						call->inv->pool_prov,
						NULL, &sdp, NULL);
	call->local_hold = PJ_FALSE;
    }

    if (status != PJ_SUCCESS) {
	pjsua_perror(THIS_FILE, "Unable to get SDP from media endpoint",
		     status);
	goto on_return;
    }

    if ((call->opt.flag & PJSUA_CALL_UPDATE_CONTACT) &&
	    pjsua_acc_is_valid(call->acc_id))
    {
	new_contact = &pjsua_var.acc[call->acc_id].contact;
    }

    /* Create UPDATE with new offer */
    status = pjsip_inv_update(call->inv, new_contact, sdp, &tdata);
    if (status != PJ_SUCCESS) {
	pjsua_perror(THIS_FILE, "Unable to create UPDATE request", status);
	goto on_return;
    }

    /* Add additional headers etc */
    pjsua_process_msg_data( tdata, msg_data);

    /* Send the request */
    status = pjsip_inv_send_msg( call->inv, tdata);
    if (status != PJ_SUCCESS) {
	pjsua_perror(THIS_FILE, "Unable to send UPDATE request", status);
	goto on_return;
    }

on_return:
    if (dlg) pjsip_dlg_dec_lock(dlg);
    pj_log_pop_indent();
    return status;
}


/*
 * Initiate call transfer to the specified address.
 */
PJ_DEF(pj_status_t) pjsua_call_xfer( pjsua_call_id call_id, 
				     const pj_str_t *dest,
				     const pjsua_msg_data *msg_data)
{
    pjsip_evsub *sub;
    pjsip_tx_data *tdata;
    pjsua_call *call;
    pjsip_dialog *dlg = NULL;
    pjsip_generic_string_hdr *gs_hdr;
    const pj_str_t str_ref_by = { "Referred-By", 11 };
    struct pjsip_evsub_user xfer_cb;
    pj_status_t status;


    PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls &&
                     dest, PJ_EINVAL);
    
    PJ_LOG(4,(THIS_FILE, "Transfering call %d to %.*s", call_id,
			 (int)dest->slen, dest->ptr));
    pj_log_push_indent();

    status = acquire_call("pjsua_call_xfer()", call_id, &call, &dlg);
    if (status != PJ_SUCCESS)
	goto on_return;
   
    /* Create xfer client subscription. */
    pj_bzero(&xfer_cb, sizeof(xfer_cb));
    xfer_cb.on_evsub_state = &xfer_client_on_evsub_state;

    status = pjsip_xfer_create_uac(call->inv->dlg, &xfer_cb, &sub);
    if (status != PJ_SUCCESS) {
	pjsua_perror(THIS_FILE, "Unable to create xfer", status);
	goto on_return;
    }

    /* Associate this call with the client subscription */
    pjsip_evsub_set_mod_data(sub, pjsua_var.mod.id, call);

    /*
     * Create REFER request.
     */
    status = pjsip_xfer_initiate(sub, dest, &tdata);
    if (status != PJ_SUCCESS) {
	pjsua_perror(THIS_FILE, "Unable to create REFER request", status);
	goto on_return;
    }

    /* Add Referred-By header */
    gs_hdr = pjsip_generic_string_hdr_create(tdata->pool, &str_ref_by,
					     &dlg->local.info_str);
    pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)gs_hdr);


    /* Add additional headers etc */
    pjsua_process_msg_data( tdata, msg_data);

    /* Send. */
    status = pjsip_xfer_send_request(sub, tdata);
    if (status != PJ_SUCCESS) {
	pjsua_perror(THIS_FILE, "Unable to send REFER request", status);
	goto on_return;
    }

    /* For simplicity (that's what this program is intended to be!), 
     * leave the original invite session as it is. More advanced application
     * may want to hold the INVITE, or terminate the invite, or whatever.
     */
on_return:
    if (dlg) pjsip_dlg_dec_lock(dlg);
    pj_log_pop_indent();
    return status;

}


/*
 * Initiate attended call transfer to the specified address.
 */
PJ_DEF(pj_status_t) pjsua_call_xfer_replaces( pjsua_call_id call_id, 
					      pjsua_call_id dest_call_id,
					      unsigned options,
					      const pjsua_msg_data *msg_data)
{
    pjsua_call *dest_call;
    pjsip_dialog *dest_dlg;
    char str_dest_buf[PJSIP_MAX_URL_SIZE*2];
    pj_str_t str_dest;
    int len;
    pjsip_uri *uri;
    pj_status_t status;
    

    PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
		     PJ_EINVAL);
    PJ_ASSERT_RETURN(dest_call_id>=0 && 
		      dest_call_id<(int)pjsua_var.ua_cfg.max_calls,
		     PJ_EINVAL);
    
    PJ_LOG(4,(THIS_FILE, "Transfering call %d replacing with call %d",
			 call_id, dest_call_id));
    pj_log_push_indent();

    status = acquire_call("pjsua_call_xfer_replaces()", dest_call_id, 
			  &dest_call, &dest_dlg);
    if (status != PJ_SUCCESS) {
	pj_log_pop_indent();
	return status;
    }
        
    /* 
     * Create REFER destination URI with Replaces field.
     */

    /* Make sure we have sufficient buffer's length */
    PJ_ASSERT_ON_FAIL(dest_dlg->remote.info_str.slen +
		      dest_dlg->call_id->id.slen +
		      dest_dlg->remote.info->tag.slen +
		      dest_dlg->local.info->tag.slen + 32 
		      < (long)sizeof(str_dest_buf),
		      { status=PJSIP_EURITOOLONG; goto on_error; });

    /* Print URI */
    str_dest_buf[0] = '<';
    str_dest.slen = 1;

    uri = (pjsip_uri*) pjsip_uri_get_uri(dest_dlg->remote.info->uri);
    len = pjsip_uri_print(PJSIP_URI_IN_REQ_URI, uri, 
		          str_dest_buf+1, sizeof(str_dest_buf)-1);
    if (len < 0) {
	status = PJSIP_EURITOOLONG;
	goto on_error;
    }

    str_dest.slen += len;


    /* Build the URI */
    len = pj_ansi_snprintf(str_dest_buf + str_dest.slen, 
			   sizeof(str_dest_buf) - str_dest.slen,
			   "?%s"
			   "Replaces=%.*s"
			   "%%3Bto-tag%%3D%.*s"
			   "%%3Bfrom-tag%%3D%.*s>",
			   ((options&PJSUA_XFER_NO_REQUIRE_REPLACES) ?
			    "" : "Require=replaces&"),
			   (int)dest_dlg->call_id->id.slen,
			   dest_dlg->call_id->id.ptr,
			   (int)dest_dlg->remote.info->tag.slen,
			   dest_dlg->remote.info->tag.ptr,
			   (int)dest_dlg->local.info->tag.slen,
			   dest_dlg->local.info->tag.ptr);

    PJ_ASSERT_ON_FAIL(len > 0 && len <= (int)sizeof(str_dest_buf)-str_dest.slen,
		      { status=PJSIP_EURITOOLONG; goto on_error; });
    
    str_dest.ptr = str_dest_buf;
    str_dest.slen += len;

    pjsip_dlg_dec_lock(dest_dlg);
    
    status = pjsua_call_xfer(call_id, &str_dest, msg_data);

    pj_log_pop_indent();
    return status;

on_error:
    if (dest_dlg) pjsip_dlg_dec_lock(dest_dlg);
    pj_log_pop_indent();
    return status;
}


/**
 * Send instant messaging inside INVITE session.
 */
PJ_DEF(pj_status_t) pjsua_call_send_im( pjsua_call_id call_id, 
					const pj_str_t *mime_type,
					const pj_str_t *content,
					const pjsua_msg_data *msg_data,
					void *user_data)
{
    pjsua_call *call;
    pjsip_dialog *dlg = NULL;
    const pj_str_t mime_text_plain = pj_str("text/plain");
    pjsip_media_type ctype;
    pjsua_im_data *im_data;
    pjsip_tx_data *tdata;
    pj_status_t status;

    PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
		     PJ_EINVAL);

    PJ_LOG(4,(THIS_FILE, "Call %d sending %d bytes MESSAGE..",
        	          call_id, (int)content->slen));
    pj_log_push_indent();

    status = acquire_call("pjsua_call_send_im()", call_id, &call, &dlg);
    if (status != PJ_SUCCESS)
	goto on_return;
    
    /* Set default media type if none is specified */
    if (mime_type == NULL) {
	mime_type = &mime_text_plain;
    }

    /* Create request message. */
    status = pjsip_dlg_create_request( call->inv->dlg, &pjsip_message_method,
				       -1, &tdata);
    if (status != PJ_SUCCESS) {
	pjsua_perror(THIS_FILE, "Unable to create MESSAGE request", status);
	goto on_return;
    }

    /* Add accept header. */
    pjsip_msg_add_hdr( tdata->msg, 
		       (pjsip_hdr*)pjsua_im_create_accept(tdata->pool));

    /* Parse MIME type */
    pjsua_parse_media_type(tdata->pool, mime_type, &ctype);

    /* Create "text/plain" message body. */
    tdata->msg->body = pjsip_msg_body_create( tdata->pool, &ctype.type,
					      &ctype.subtype, content);
    if (tdata->msg->body == NULL) {
	pjsua_perror(THIS_FILE, "Unable to create msg body", PJ_ENOMEM);
	pjsip_tx_data_dec_ref(tdata);
	goto on_return;
    }

    /* Add additional headers etc */
    pjsua_process_msg_data( tdata, msg_data);

    /* Create IM data and attach to the request. */
    im_data = PJ_POOL_ZALLOC_T(tdata->pool, pjsua_im_data);
    im_data->acc_id = call->acc_id;
    im_data->call_id = call_id;
    im_data->to = call->inv->dlg->remote.info_str;
    pj_strdup_with_null(tdata->pool, &im_data->body, content);
    im_data->user_data = user_data;


    /* Send the request. */
    status = pjsip_dlg_send_request( call->inv->dlg, tdata, 
				     pjsua_var.mod.id, im_data);
    if (status != PJ_SUCCESS) {
	pjsua_perror(THIS_FILE, "Unable to send MESSAGE request", status);
	goto on_return;
    }

on_return:
    if (dlg) pjsip_dlg_dec_lock(dlg);
    pj_log_pop_indent();
    return status;
}


/*
 * Send IM typing indication inside INVITE session.
 */
PJ_DEF(pj_status_t) pjsua_call_send_typing_ind( pjsua_call_id call_id, 
						pj_bool_t is_typing,
						const pjsua_msg_data*msg_data)
{
    pjsua_call *call;
    pjsip_dialog *dlg = NULL;
    pjsip_tx_data *tdata;
    pj_status_t status;

    PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
		     PJ_EINVAL);

    PJ_LOG(4,(THIS_FILE, "Call %d sending typing indication..",
            	          call_id));
    pj_log_push_indent();

    status = acquire_call("pjsua_call_send_typing_ind", call_id, &call, &dlg);
    if (status != PJ_SUCCESS)
	goto on_return;

    /* Create request message. */
    status = pjsip_dlg_create_request( call->inv->dlg, &pjsip_message_method,
				       -1, &tdata);
    if (status != PJ_SUCCESS) {
	pjsua_perror(THIS_FILE, "Unable to create MESSAGE request", status);
	goto on_return;
    }

    /* Create "application/im-iscomposing+xml" msg body. */
    tdata->msg->body = pjsip_iscomposing_create_body(tdata->pool, is_typing,
						     NULL, NULL, -1);

    /* Add additional headers etc */
    pjsua_process_msg_data( tdata, msg_data);

    /* Send the request. */
    status = pjsip_dlg_send_request( call->inv->dlg, tdata, -1, NULL);
    if (status != PJ_SUCCESS) {
	pjsua_perror(THIS_FILE, "Unable to send MESSAGE request", status);
	goto on_return;
    }

on_return:
    if (dlg) pjsip_dlg_dec_lock(dlg);
    pj_log_pop_indent();
    return status;
}


/*
 * Send arbitrary request.
 */
PJ_DEF(pj_status_t) pjsua_call_send_request(pjsua_call_id call_id,
					    const pj_str_t *method_str,
					    const pjsua_msg_data *msg_data)
{
    pjsua_call *call;
    pjsip_dialog *dlg = NULL;
    pjsip_method method;
    pjsip_tx_data *tdata;
    pj_status_t status;

    PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
		     PJ_EINVAL);

    PJ_LOG(4,(THIS_FILE, "Call %d sending %.*s request..",
            	          call_id, (int)method_str->slen, method_str->ptr));
    pj_log_push_indent();

    status = acquire_call("pjsua_call_send_request", call_id, &call, &dlg);
    if (status != PJ_SUCCESS)
	goto on_return;

    /* Init method */
    pjsip_method_init_np(&method, (pj_str_t*)method_str);

    /* Create request message. */
    status = pjsip_dlg_create_request( call->inv->dlg, &method, -1, &tdata);
    if (status != PJ_SUCCESS) {
	pjsua_perror(THIS_FILE, "Unable to create request", status);
	goto on_return;
    }

    /* Add additional headers etc */
    pjsua_process_msg_data( tdata, msg_data);

    /* Send the request. */
    status = pjsip_dlg_send_request( call->inv->dlg, tdata, -1, NULL);
    if (status != PJ_SUCCESS) {
	pjsua_perror(THIS_FILE, "Unable to send request", status);
	goto on_return;
    }

on_return:
    if (dlg) pjsip_dlg_dec_lock(dlg);
    pj_log_pop_indent();
    return status;
}


/*
 * Terminate all calls.
 */
PJ_DEF(void) pjsua_call_hangup_all(void)
{
    unsigned i;

    PJ_LOG(4,(THIS_FILE, "Hangup all calls.."));
    pj_log_push_indent();

    // This may deadlock, see https://trac.pjsip.org/repos/ticket/1305
    //PJSUA_LOCK();

    for (i=0; i<pjsua_var.ua_cfg.max_calls; ++i) {
	if (pjsua_var.calls[i].inv)
	    pjsua_call_hangup(i, 0, NULL, NULL);
    }

    //PJSUA_UNLOCK();
    pj_log_pop_indent();
}


/* Timer callback to send re-INVITE/UPDATE to lock codec or ICE update */
static void reinv_timer_cb(pj_timer_heap_t *th, pj_timer_entry *entry)
{
    pjsua_call_id call_id = (pjsua_call_id)(pj_size_t)entry->user_data;
    pjsip_dialog *dlg;
    pjsua_call *call;
    pj_status_t status;

    PJ_UNUSED_ARG(th);

    pjsua_var.calls[call_id].reinv_timer.id = PJ_FALSE;

    pj_log_push_indent();

    status = acquire_call("reinv_timer_cb()", call_id, &call, &dlg);
    if (status != PJ_SUCCESS) {
	pj_log_pop_indent();
	return;
    }

    process_pending_reinvite(call);

    pjsip_dlg_dec_lock(dlg);

    pj_log_pop_indent();
}


/* Check if the specified format can be skipped in counting codecs */
static pj_bool_t is_non_av_fmt(const pjmedia_sdp_media *m,
			       const pj_str_t *fmt)
{
    const pj_str_t STR_TEL = {"telephone-event", 15};
    unsigned pt;

    pt = pj_strtoul(fmt);

    /* Check for comfort noise */
    if (pt == PJMEDIA_RTP_PT_CN)
	return PJ_TRUE;

    /* Dynamic PT, check the format name */
    if (pt >= 96) {
	pjmedia_sdp_attr *a;
	pjmedia_sdp_rtpmap rtpmap;

	/* Get the format name */
	a = pjmedia_sdp_attr_find2(m->attr_count, m->attr, "rtpmap", fmt);
	if (a && pjmedia_sdp_attr_get_rtpmap(a, &rtpmap)==PJ_SUCCESS) {
	    /* Check for telephone-event */
	    if (pj_stricmp(&rtpmap.enc_name, &STR_TEL)==0)
		return PJ_TRUE;
	} else {
	    /* Invalid SDP, should not reach here */
	    pj_assert(!"SDP should have been validated!");
	    return PJ_TRUE;
	}
    }

    return PJ_FALSE;
}


/* Schedule check for the need of re-INVITE/UPDATE after media update, cases:
 * - lock codec if remote answerer has given us more than one codecs
 * - update ICE default transport address if it has changed after ICE
 *   connectivity check.
 */
void pjsua_call_schedule_reinvite_check(pjsua_call *call, unsigned delay_ms)
{
    pj_time_val delay;

    /* Stop reinvite timer, if it is active */
    if (call->reinv_timer.id)
	pjsua_cancel_timer(&call->reinv_timer);

    delay.sec = 0;
    delay.msec = delay_ms;
    pj_time_val_normalize(&delay);
    call->reinv_timer.id = PJ_TRUE;
    pjsua_schedule_timer(&call->reinv_timer, &delay);
}


/* Check if lock codec is needed */
static pj_bool_t check_lock_codec(pjsua_call *call)
{
    const pjmedia_sdp_session *local_sdp, *remote_sdp;
    pj_bool_t has_mult_fmt = PJ_FALSE;
    unsigned i;
    pj_status_t status;

    /* Check if lock codec is disabled */
    if (!pjsua_var.acc[call->acc_id].cfg.lock_codec)
	return PJ_FALSE;

    /* Check lock codec retry count */
    if (call->lock_codec.retry_cnt >= LOCK_CODEC_MAX_RETRY)
        return PJ_FALSE;

    /* Check if we are the answerer, we shouldn't need to lock codec */
    if (!call->inv->neg || !pjmedia_sdp_neg_was_answer_remote(call->inv->neg))
        return PJ_FALSE;

    /* Check if remote answerer has given us more than one codecs. */
    status = pjmedia_sdp_neg_get_active_local(call->inv->neg, &local_sdp);
    if (status != PJ_SUCCESS)
	return PJ_FALSE;
    status = pjmedia_sdp_neg_get_active_remote(call->inv->neg, &remote_sdp);
    if (status != PJ_SUCCESS)
	return PJ_FALSE;

    for (i = 0; i < call->med_cnt && !has_mult_fmt; ++i) {
	pjsua_call_media *call_med = &call->media[i];
	const pjmedia_sdp_media *rem_m, *loc_m;
	unsigned codec_cnt = 0;
	unsigned j;

	/* Skip this if the media is inactive or error */
	if (call_med->state == PJSUA_CALL_MEDIA_NONE ||
	    call_med->state == PJSUA_CALL_MEDIA_ERROR ||
	    call_med->dir == PJMEDIA_DIR_NONE)
	{
	    continue;
	}

	/* Remote may answer with less media lines. */
	if (i >= remote_sdp->media_count)
	    continue;

	rem_m = remote_sdp->media[i];
	loc_m = local_sdp->media[i];

	/* Verify that media must be active. */
	pj_assert(loc_m->desc.port && rem_m->desc.port);

	/* Count the formats in the answer. */
	for (j=0; j<rem_m->desc.fmt_count && codec_cnt <= 1; ++j) {
	    if (!is_non_av_fmt(rem_m, &rem_m->desc.fmt[j]) && ++codec_cnt > 1)
		has_mult_fmt = PJ_TRUE;
	}
    }

    /* Reset retry count when remote answer has one codec */
    if (!has_mult_fmt)
	call->lock_codec.retry_cnt = 0;

    return has_mult_fmt;
}

/* Check if ICE setup is complete and if it needs to send reinvite */
static pj_bool_t check_ice_complete(pjsua_call *call, pj_bool_t *need_reinv)
{
    pj_bool_t ice_need_reinv = PJ_FALSE;
    pj_bool_t ice_complete = PJ_TRUE;
    unsigned i;

    /* Check if ICE setup is complete and if it needs reinvite */
    for (i = 0; i < call->med_cnt; ++i) {
	pjsua_call_media *call_med = &call->media[i];
	pjmedia_transport_info tpinfo;
	pjmedia_ice_transport_info *ice_info;
	
	if (call_med->tp_st == PJSUA_MED_TP_NULL ||
	    call_med->tp_st == PJSUA_MED_TP_DISABLED ||
	    call_med->state == PJSUA_CALL_MEDIA_ERROR)
	{
	    continue;
	}
	
	pjmedia_transport_info_init(&tpinfo);
	pjmedia_transport_get_info(call_med->tp, &tpinfo);
	ice_info = (pjmedia_ice_transport_info*)
		   pjmedia_transport_info_get_spc_info(
					&tpinfo, PJMEDIA_TRANSPORT_TYPE_ICE);

	/* Check if ICE is active */
	if (!ice_info || !ice_info->active)
	    continue;

	/* Check if ICE setup not completed yet */
	if (ice_info->sess_state < PJ_ICE_STRANS_STATE_RUNNING)	{
	    ice_complete = PJ_FALSE;
	    break;
	}
	
	/* Check if ICE needs to send reinvite */
	if (!ice_need_reinv &&
	    ice_info->sess_state == PJ_ICE_STRANS_STATE_RUNNING &&
	    ice_info->role == PJ_ICE_SESS_ROLE_CONTROLLING)
	{
	    pjsua_ice_config *cfg=&pjsua_var.acc[call->acc_id].cfg.ice_cfg;
	    if ((cfg->ice_always_update && !call->reinv_ice_sent) ||
		pj_sockaddr_cmp(&tpinfo.sock_info.rtp_addr_name,
				&call_med->rtp_addr))
	    {
		ice_need_reinv = PJ_TRUE;
	    }
	}
    }
    
    if (ice_complete && need_reinv)
	*need_reinv = ice_need_reinv;
    
    return ice_complete;
}

/* Check and send reinvite for lock codec and ICE update */
static pj_status_t process_pending_reinvite(pjsua_call *call)
{
    const pj_str_t ST_UPDATE = {"UPDATE", 6};
    pj_pool_t *pool = call->inv->pool_prov;
    pjsip_inv_session *inv = call->inv;
    pj_bool_t ice_need_reinv;
    pj_bool_t ice_completed;
    pj_bool_t need_lock_codec;
    pj_bool_t rem_can_update;
    pjmedia_sdp_session *new_offer;
    pjsip_tx_data *tdata;
    unsigned i;
    pj_status_t status;

    /* Verify if another SDP negotiation is in progress, e.g: session timer
     * or another re-INVITE.
     */
    if (inv==NULL || inv->neg==NULL ||
	pjmedia_sdp_neg_get_state(inv->neg)!=PJMEDIA_SDP_NEG_STATE_DONE)
    {
	return PJMEDIA_SDPNEG_EINSTATE;
    }

    /* Don't do this if call is disconnecting! */
    if (inv->state > PJSIP_INV_STATE_CONFIRMED || inv->cause >= 200)
    {
	return PJ_EINVALIDOP;
    }

    /* Delay this when the SDP negotiation done in call state EARLY and
     * remote does not support UPDATE method.
     */
    if (inv->state == PJSIP_INV_STATE_EARLY && 
	pjsip_dlg_remote_has_cap(inv->dlg, PJSIP_H_ALLOW, NULL, &ST_UPDATE)!=
	PJSIP_DIALOG_CAP_SUPPORTED)
    {
        call->reinv_pending = PJ_TRUE;
        return PJ_EPENDING;
    }

    /* Check if ICE setup is complete and if it needs reinvite */
    ice_completed = check_ice_complete(call, &ice_need_reinv);
    if (!ice_completed)
	return PJ_EPENDING;

    /* Check if we need to lock codec */
    need_lock_codec = check_lock_codec(call);

    /* Check if reinvite is really needed */
    if (!need_lock_codec && !ice_need_reinv)
	return PJ_SUCCESS;

    
    /* Okay! So we need to send re-INVITE/UPDATE */

    /* Check if remote support UPDATE */
    rem_can_update = pjsip_dlg_remote_has_cap(inv->dlg, PJSIP_H_ALLOW, NULL,
					      &ST_UPDATE) ==
						PJSIP_DIALOG_CAP_SUPPORTED;

    /* Logging stuff */
    {
	const char *ST_ICE_UPDATE = "ICE transport address after "
				    "ICE negotiation";
	const char *ST_LOCK_CODEC = "media session to use only one codec";
	PJ_LOG(4,(THIS_FILE, "Call %d sending %s for updating %s%s%s",
		  call->index,
		  (rem_can_update? "UPDATE" : "re-INVITE"),
		  (ice_need_reinv? ST_ICE_UPDATE : ST_LOCK_CODEC),
		  (ice_need_reinv && need_lock_codec? " and " : ""),
		  (ice_need_reinv && need_lock_codec? ST_LOCK_CODEC : "")
		  ));
    }
    
    /* Generate SDP re-offer */
    status = pjsua_media_channel_create_sdp(call->index, pool, NULL,
					    &new_offer, NULL);
    if (status != PJ_SUCCESS) {
	pjsua_perror(THIS_FILE, "Unable to create local SDP", status);
	return status;
    }

    /* Update the new offer so it contains only a codec. Note that
     * SDP nego has removed unmatched codecs from the offer and the codec
     * order in the offer has been matched to the answer, so we'll override
     * the codecs in the just generated SDP with the ones from the active
     * local SDP and leave just one codec for the next SDP re-offer.
     */
    if (need_lock_codec) {
	const pjmedia_sdp_session *ref_sdp;
	
	/* Get local active SDP as reference */
	status = pjmedia_sdp_neg_get_active_local(call->inv->neg, &ref_sdp);
	if (status != PJ_SUCCESS)
	    return status;
	
	/* Verify media count. Note that remote may add/remove media line
	 * in the answer. When answer has less media, it must have been
	 * handled by pjsua_media_channel_update() as disabled media.
	 * When answer has more media, it must have been ignored (treated
	 * as non-exist) anywhere. Local media count should not be updated
	 * at this point, as modifying media count operation (i.e: reinvite,
	 * update, vid_set_strm) is currently blocking, protected with
	 * dialog mutex, and eventually reset SDP nego state to LOCAL OFFER.
	 */
	if (call->med_cnt != ref_sdp->media_count ||
	    ref_sdp->media_count != new_offer->media_count)
	{
	    /* Anyway, just in case, let's just return error */
	    return PJMEDIA_SDPNEG_EINSTATE;
	}

	for (i = 0; i < call->med_cnt; ++i) {
	    unsigned j, codec_cnt = 0;
	    const pjmedia_sdp_media *ref_m = ref_sdp->media[i];
	    pjmedia_sdp_media *m = new_offer->media[i];
	    pjsua_call_media *call_med = &call->media[i];
    
	    /* Verify if media is deactivated */
	    if (call_med->state == PJSUA_CALL_MEDIA_NONE ||
		call_med->state == PJSUA_CALL_MEDIA_ERROR ||
		call_med->dir == PJMEDIA_DIR_NONE)
	    {
		continue;
	    }
    
	    /* Reset formats */
	    m->desc.fmt_count = 0;
	    pjmedia_sdp_attr_remove_all(&m->attr_count, m->attr, "rtpmap");
	    pjmedia_sdp_attr_remove_all(&m->attr_count, m->attr, "fmtp");
	    
	    /* Copy only the first format + any non-AV formats from
	     * the active local SDP.
	     */
	    for (j = 0; j < ref_m->desc.fmt_count; ++j) {
		const pj_str_t *fmt = &ref_m->desc.fmt[j];

		if (is_non_av_fmt(ref_m, fmt) || (++codec_cnt == 1)) {
		    pjmedia_sdp_attr *a;
		    
		    m->desc.fmt[m->desc.fmt_count++] = *fmt;
		    a = pjmedia_sdp_attr_find2(ref_m->attr_count, ref_m->attr,
					       "rtpmap", fmt);
		    if (a) pjmedia_sdp_attr_add(&m->attr_count, m->attr, a);
		    a = pjmedia_sdp_attr_find2(ref_m->attr_count, ref_m->attr,
					       "fmtp", fmt);
		    if (a) pjmedia_sdp_attr_add(&m->attr_count, m->attr, a);
		}
	    }
	}
    }

    /* Put back original direction and "c=0.0.0.0" line */
    {
	const pjmedia_sdp_session *cur_sdp;
	
	/* Get local active SDP */
	status = pjmedia_sdp_neg_get_active_local(call->inv->neg, &cur_sdp);
	if (status != PJ_SUCCESS)
	    return status;

	/* Make sure media count has not been changed */
	if (call->med_cnt != cur_sdp->media_count)
	    return PJMEDIA_SDPNEG_EINSTATE;

	for (i = 0; i < call->med_cnt; ++i) {
	    const pjmedia_sdp_media *m = cur_sdp->media[i];
	    pjmedia_sdp_media *new_m = new_offer->media[i];
	    pjsua_call_media *call_med = &call->media[i];
	    pjmedia_sdp_attr *a = NULL;

	    /* Update direction to the current dir */
	    pjmedia_sdp_media_remove_all_attr(new_m, "sendrecv");
	    pjmedia_sdp_media_remove_all_attr(new_m, "sendonly");
	    pjmedia_sdp_media_remove_all_attr(new_m, "recvonly");
	    pjmedia_sdp_media_remove_all_attr(new_m, "inactive");

	    if (call_med->dir == PJMEDIA_DIR_ENCODING_DECODING) {
		a = pjmedia_sdp_attr_create(pool, "sendrecv", NULL);
	    } else if (call_med->dir == PJMEDIA_DIR_ENCODING) {
		a = pjmedia_sdp_attr_create(pool, "sendonly", NULL);
	    } else if (call_med->dir == PJMEDIA_DIR_DECODING) {
		a = pjmedia_sdp_attr_create(pool, "recvonly", NULL);
	    } else {
		const pjmedia_sdp_conn *conn;
		a = pjmedia_sdp_attr_create(pool, "inactive", NULL);

		/* Also check if the original c= line address is zero */
		conn = m->conn;
		if (!conn)
		    conn = cur_sdp->conn;
		if (pj_strcmp2(&conn->addr, "0.0.0.0")==0 ||
		    pj_strcmp2(&conn->addr, "0")==0)
		{
		    if (!new_m->conn) {
			new_m->conn = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_conn);
		    }

		    if (pj_strcmp2(&new_m->conn->addr, "0.0.0.0")) {
			new_m->conn->net_type = pj_str("IN");
			new_m->conn->addr_type = pj_str("IP4");
			new_m->conn->addr = pj_str("0.0.0.0");
		    }
		}
	    }

	    pj_assert(a);
	    pjmedia_sdp_media_add_attr(new_m, a);
	}
    }

    
    if (rem_can_update) {
	status = pjsip_inv_update(inv, NULL, new_offer, &tdata);
    } else {
	status = pjsip_inv_reinvite(inv, NULL, new_offer, &tdata);
    }

    if (status==PJ_EINVALIDOP &&
	++call->lock_codec.retry_cnt < LOCK_CODEC_MAX_RETRY)
    {
	/* Ups, let's reschedule again */
	pjsua_call_schedule_reinvite_check(call, LOCK_CODEC_RETRY_INTERVAL);
	return PJ_SUCCESS;
    } else if (status != PJ_SUCCESS) {
	pjsua_perror(THIS_FILE, "Error creating UPDATE/re-INVITE",
		     status);
	return status;
    }

    /* Send the UPDATE/re-INVITE request */
    status = pjsip_inv_send_msg(inv, tdata);
    if (status != PJ_SUCCESS) {
	pjsua_perror(THIS_FILE, "Error sending UPDATE/re-INVITE",
		     status);
	return status;
    }

    /* Update flags */
    if (ice_need_reinv)
	call->reinv_ice_sent = PJ_TRUE;
    if (need_lock_codec)
	++call->lock_codec.retry_cnt;
    
    return PJ_SUCCESS;
}


/*
 * This callback receives notification from invite session when the
 * session state has changed.
 */
static void pjsua_call_on_state_changed(pjsip_inv_session *inv, 
					pjsip_event *e)
{
    pjsua_call *call;

    pj_log_push_indent();

    call = (pjsua_call*) inv->dlg->mod_data[pjsua_var.mod.id];

    if (!call) {
	pj_log_pop_indent();
	return;
    }


    /* Get call times */
    switch (inv->state) {
	case PJSIP_INV_STATE_EARLY:
	case PJSIP_INV_STATE_CONNECTING:
	    if (call->res_time.sec == 0)
		pj_gettimeofday(&call->res_time);
	    call->last_code = (pjsip_status_code) 
	    		      e->body.tsx_state.tsx->status_code;
	    pj_strncpy(&call->last_text, 
		       &e->body.tsx_state.tsx->status_text,
		       sizeof(call->last_text_buf_));
	    break;
	case PJSIP_INV_STATE_CONFIRMED:
	    pj_gettimeofday(&call->conn_time);

            /* See if auto reinvite was pended as media update was done in the
             * EARLY state and remote does not support UPDATE.
             */
            if (call->reinv_pending) {
		call->reinv_pending = PJ_FALSE;
		pjsua_call_schedule_reinvite_check(call, 0);
	    }
	    break;
	case PJSIP_INV_STATE_DISCONNECTED:
	    pj_gettimeofday(&call->dis_time);
	    if (call->res_time.sec == 0)
		pj_gettimeofday(&call->res_time);
	    if (e->type == PJSIP_EVENT_TSX_STATE && 
		e->body.tsx_state.tsx->status_code > call->last_code) 
	    {
		call->last_code = (pjsip_status_code) 
				  e->body.tsx_state.tsx->status_code;
		pj_strncpy(&call->last_text, 
			   &e->body.tsx_state.tsx->status_text,
			   sizeof(call->last_text_buf_));
	    } else {
		call->last_code = PJSIP_SC_REQUEST_TERMINATED;
		pj_strncpy(&call->last_text,
			   pjsip_get_status_text(call->last_code),
			   sizeof(call->last_text_buf_));
	    }

	    /* Stop reinvite timer, if it is active */
	    if (call->reinv_timer.id) {
		pjsua_cancel_timer(&call->reinv_timer);
		call->reinv_timer.id = PJ_FALSE;
	    }
	    break;
	default:
	    call->last_code = (pjsip_status_code) 
	    		      e->body.tsx_state.tsx->status_code;
	    pj_strncpy(&call->last_text, 
		       &e->body.tsx_state.tsx->status_text,
		       sizeof(call->last_text_buf_));
	    break;
    }

    /* If this is an outgoing INVITE that was created because of
     * REFER/transfer, send NOTIFY to transferer.
     */
    if (call->xfer_sub && e->type==PJSIP_EVENT_TSX_STATE)  {
	int st_code = -1;
	pjsip_evsub_state ev_state = PJSIP_EVSUB_STATE_ACTIVE;
	

	switch (call->inv->state) {
	case PJSIP_INV_STATE_NULL:
	case PJSIP_INV_STATE_CALLING:
	    /* Do nothing */
	    break;

	case PJSIP_INV_STATE_EARLY:
	case PJSIP_INV_STATE_CONNECTING:
	    st_code = e->body.tsx_state.tsx->status_code;
	    if (call->inv->state == PJSIP_INV_STATE_CONNECTING)
		ev_state = PJSIP_EVSUB_STATE_TERMINATED;
	    else
		ev_state = PJSIP_EVSUB_STATE_ACTIVE;
	    break;

	case PJSIP_INV_STATE_CONFIRMED:
#if 0
/* We don't need this, as we've terminated the subscription in
 * CONNECTING state.
 */
	    /* When state is confirmed, send the final 200/OK and terminate
	     * subscription.
	     */
	    st_code = e->body.tsx_state.tsx->status_code;
	    ev_state = PJSIP_EVSUB_STATE_TERMINATED;
#endif
	    break;

	case PJSIP_INV_STATE_DISCONNECTED:
	    st_code = e->body.tsx_state.tsx->status_code;
	    ev_state = PJSIP_EVSUB_STATE_TERMINATED;
	    break;

	case PJSIP_INV_STATE_INCOMING:
	    /* Nothing to do. Just to keep gcc from complaining about
	     * unused enums.
	     */
	    break;
	}

	if (st_code != -1) {
	    pjsip_tx_data *tdata;
	    pj_status_t status;

	    status = pjsip_xfer_notify( call->xfer_sub,
					ev_state, st_code,
					NULL, &tdata);
	    if (status != PJ_SUCCESS) {
		pjsua_perror(THIS_FILE, "Unable to create NOTIFY", status);
	    } else {
		status = pjsip_xfer_send_request(call->xfer_sub, tdata);
		if (status != PJ_SUCCESS) {
		    pjsua_perror(THIS_FILE, "Unable to send NOTIFY", status);
		}
	    }
	}
    }

    /* Ticket #1627: Invoke on_call_tsx_state() when call is disconnected. */
    if (inv->state == PJSIP_INV_STATE_DISCONNECTED &&
	e->type == PJSIP_EVENT_TSX_STATE &&
	call->inv &&
	pjsua_var.ua_cfg.cb.on_call_tsx_state)
    {
	(*pjsua_var.ua_cfg.cb.on_call_tsx_state)(call->index,
						 e->body.tsx_state.tsx, e);
    }

    if (pjsua_var.ua_cfg.cb.on_call_state)
	(*pjsua_var.ua_cfg.cb.on_call_state)(call->index, e);

    /* call->inv may be NULL now */

    /* Destroy media session when invite session is disconnected. */
    if (inv->state == PJSIP_INV_STATE_DISCONNECTED) {

	PJSUA_LOCK();
	
	pjsua_media_channel_deinit(call->index);

	/* Free call */
	call->inv = NULL;

	pj_assert(pjsua_var.call_cnt > 0);
	--pjsua_var.call_cnt;

	/* Reset call */
	reset_call(call->index);

	pjsua_check_snd_dev_idle();

	PJSUA_UNLOCK();
    }
    pj_log_pop_indent();
}

/*
 * This callback is called by invite session framework when UAC session
 * has forked.
 */
static void pjsua_call_on_forked( pjsip_inv_session *inv, 
				  pjsip_event *e)
{
    PJ_UNUSED_ARG(inv);
    PJ_UNUSED_ARG(e);

    PJ_TODO(HANDLE_FORKED_DIALOG);
}


/*
 * Callback from UA layer when forked dialog response is received.
 */
pjsip_dialog* on_dlg_forked(pjsip_dialog *dlg, pjsip_rx_data *res)
{
    if (dlg->uac_has_2xx && 
	res->msg_info.cseq->method.id == PJSIP_INVITE_METHOD &&
	pjsip_rdata_get_tsx(res) == NULL &&
	res->msg_info.msg->line.status.code/100 == 2) 
    {
	pjsip_dialog *forked_dlg;
	pjsip_tx_data *bye;
	pj_status_t status;

	/* Create forked dialog */
	status = pjsip_dlg_fork(dlg, res, &forked_dlg);
	if (status != PJ_SUCCESS)
	    return NULL;

	pjsip_dlg_inc_lock(forked_dlg);

	/* Disconnect the call */
	status = pjsip_dlg_create_request(forked_dlg, &pjsip_bye_method,
					  -1, &bye);
	if (status == PJ_SUCCESS) {
	    status = pjsip_dlg_send_request(forked_dlg, bye, -1, NULL);
	}

	pjsip_dlg_dec_lock(forked_dlg);

	if (status != PJ_SUCCESS) {
	    return NULL;
	}

	return forked_dlg;

    } else {
	return dlg;
    }
}

/*
 * Disconnect call upon error.
 */
static void call_disconnect( pjsip_inv_session *inv, 
			     int code )
{
    pjsua_call *call;
    pjsip_tx_data *tdata;
    pj_status_t status;

    call = (pjsua_call*) inv->dlg->mod_data[pjsua_var.mod.id];

    status = pjsip_inv_end_session(inv, code, NULL, &tdata);
    if (status != PJ_SUCCESS)
	return;

    /* Add SDP in 488 status */
#if DISABLED_FOR_TICKET_1185
    if (call && call->tp && tdata->msg->type==PJSIP_RESPONSE_MSG &&
	code==PJSIP_SC_NOT_ACCEPTABLE_HERE) 
    {
	pjmedia_sdp_session *local_sdp;
	pjmedia_transport_info ti;

	pjmedia_transport_info_init(&ti);
	pjmedia_transport_get_info(call->med_tp, &ti);
	status = pjmedia_endpt_create_sdp(pjsua_var.med_endpt, tdata->pool, 
					  1, &ti.sock_info, &local_sdp);
	if (status == PJ_SUCCESS) {
	    pjsip_create_sdp_body(tdata->pool, local_sdp,
				  &tdata->msg->body);
	}
    }
#endif

    pjsip_inv_send_msg(inv, tdata);
}

/*
 * Callback to be called when SDP offer/answer negotiation has just completed
 * in the session. This function will start/update media if negotiation
 * has succeeded.
 */
static void pjsua_call_on_media_update(pjsip_inv_session *inv,
				       pj_status_t status)
{
    pjsua_call *call;
    const pjmedia_sdp_session *local_sdp;
    const pjmedia_sdp_session *remote_sdp;
    //const pj_str_t st_update = {"UPDATE", 6};

    pj_log_push_indent();

    call = (pjsua_call*) inv->dlg->mod_data[pjsua_var.mod.id];

    if (status != PJ_SUCCESS) {

	pjsua_perror(THIS_FILE, "SDP negotiation has failed", status);

	/* Clean up provisional media */
	pjsua_media_prov_clean_up(call->index);

	/* Do not deinitialize media since this may be a re-INVITE or
	 * UPDATE (which in this case the media should not get affected
	 * by the failed re-INVITE/UPDATE). The media will be shutdown
	 * when call is disconnected anyway.
	 */
	/* Stop/destroy media, if any */
	/*pjsua_media_channel_deinit(call->index);*/

	/* Disconnect call if we're not in the middle of initializing an
	 * UAS dialog and if this is not a re-INVITE 
	 */
	if (inv->state != PJSIP_INV_STATE_NULL &&
	    inv->state != PJSIP_INV_STATE_CONFIRMED) 
	{
	    call_disconnect(inv, PJSIP_SC_UNSUPPORTED_MEDIA_TYPE);
	}

	goto on_return;
    }


    /* Get local and remote SDP */
    status = pjmedia_sdp_neg_get_active_local(call->inv->neg, &local_sdp);
    if (status != PJ_SUCCESS) {
	pjsua_perror(THIS_FILE, 
		     "Unable to retrieve currently active local SDP", 
		     status);
	//call_disconnect(inv, PJSIP_SC_UNSUPPORTED_MEDIA_TYPE);
	goto on_return;
    }

    status = pjmedia_sdp_neg_get_active_remote(call->inv->neg, &remote_sdp);
    if (status != PJ_SUCCESS) {
	pjsua_perror(THIS_FILE, 
		     "Unable to retrieve currently active remote SDP", 
		     status);
	//call_disconnect(inv, PJSIP_SC_UNSUPPORTED_MEDIA_TYPE);
	goto on_return;
    }

    /* Update remote's NAT type */
    if (pjsua_var.ua_cfg.nat_type_in_sdp) {
	update_remote_nat_type(call, remote_sdp);
    }

    /* Update media channel with the new SDP */
    status = pjsua_media_channel_update(call->index, local_sdp, remote_sdp);
    if (status != PJ_SUCCESS) {
	pjsua_perror(THIS_FILE, "Unable to create media session", 
		     status);
	call_disconnect(inv, PJSIP_SC_NOT_ACCEPTABLE_HERE);
	/* No need to deinitialize; media will be shutdown when call
	 * state is disconnected anyway.
	 */
	/*pjsua_media_channel_deinit(call->index);*/
	goto on_return;
    }

    /* Ticket #476: make sure only one codec is specified in the answer. */
    pjsua_call_schedule_reinvite_check(call, 0);

    /* Call application callback, if any */
    if (pjsua_var.ua_cfg.cb.on_call_media_state)
	pjsua_var.ua_cfg.cb.on_call_media_state(call->index);

on_return:
    pj_log_pop_indent();
}


/* Modify SDP for call hold. */
static pj_status_t modify_sdp_of_call_hold(pjsua_call *call,
					   pj_pool_t *pool,
					   pjmedia_sdp_session *sdp,
					   pj_bool_t as_answerer)
{
    unsigned mi;

    /* Call-hold is done by set the media direction to 'sendonly' 
     * (PJMEDIA_DIR_ENCODING), except when current media direction is 
     * 'inactive' (PJMEDIA_DIR_NONE).
     * (See RFC 3264 Section 8.4 and RFC 4317 Section 3.1)
     */
    /* http://trac.pjsip.org/repos/ticket/880 
       if (call->dir != PJMEDIA_DIR_ENCODING) {
     */
    /* https://trac.pjsip.org/repos/ticket/1142:
     *  configuration to use c=0.0.0.0 for call hold.
     */

    for (mi=0; mi<sdp->media_count; ++mi) {
	pjmedia_sdp_media *m = sdp->media[mi];

	if (call->call_hold_type == PJSUA_CALL_HOLD_TYPE_RFC2543) {
	    pjmedia_sdp_conn *conn;
	    pjmedia_sdp_attr *attr;

	    /* Get SDP media connection line */
	    conn = m->conn;
	    if (!conn)
		conn = sdp->conn;

	    /* Modify address */
	    conn->addr = pj_str("0.0.0.0");

	    /* Remove existing directions attributes */
	    pjmedia_sdp_media_remove_all_attr(m, "sendrecv");
	    pjmedia_sdp_media_remove_all_attr(m, "sendonly");
	    pjmedia_sdp_media_remove_all_attr(m, "recvonly");
	    pjmedia_sdp_media_remove_all_attr(m, "inactive");

	    /* Add inactive attribute */
	    attr = pjmedia_sdp_attr_create(pool, "inactive", NULL);
	    pjmedia_sdp_media_add_attr(m, attr);


	} else {
	    pjmedia_sdp_attr *attr;

	    /* Remove existing directions attributes */
	    pjmedia_sdp_media_remove_all_attr(m, "sendrecv");
	    pjmedia_sdp_media_remove_all_attr(m, "sendonly");
	    pjmedia_sdp_media_remove_all_attr(m, "recvonly");
	    pjmedia_sdp_media_remove_all_attr(m, "inactive");

	    /* When as answerer, just simply set dir to "sendonly", note that
	     * if the offer uses "sendonly" or "inactive", the SDP negotiator
	     * will change our answer dir to "inactive".
	     */
	    if (as_answerer || (call->media[mi].dir & PJMEDIA_DIR_ENCODING)) {
		/* Add sendonly attribute */
		attr = pjmedia_sdp_attr_create(pool, "sendonly", NULL);
		pjmedia_sdp_media_add_attr(m, attr);
	    } else {
		/* Add inactive attribute */
		attr = pjmedia_sdp_attr_create(pool, "inactive", NULL);
		pjmedia_sdp_media_add_attr(m, attr);
	    }
	}
    }

    return PJ_SUCCESS;
}

/* Create SDP for call hold. */
static pj_status_t create_sdp_of_call_hold(pjsua_call *call,
					   pjmedia_sdp_session **p_sdp)
{
    pj_status_t status;
    pj_pool_t *pool;
    pjmedia_sdp_session *sdp;

    /* Use call's provisional pool */
    pool = call->inv->pool_prov;

    /* Create new offer */
    status = pjsua_media_channel_create_sdp(call->index, pool, NULL, &sdp,
					    NULL);
    if (status != PJ_SUCCESS) {
	pjsua_perror(THIS_FILE, "Unable to create local SDP", status);
	return status;
    }

    status = modify_sdp_of_call_hold(call, pool, sdp, PJ_FALSE);
    if (status != PJ_SUCCESS)
	return status;

    *p_sdp = sdp;

    return PJ_SUCCESS;
}

/*
 * Called when session received new offer.
 */
static void pjsua_call_on_rx_offer(pjsip_inv_session *inv,
				   const pjmedia_sdp_session *offer)
{
    pjsua_call *call;
    pjmedia_sdp_session *answer;
    unsigned i;
    pj_status_t status;

    call = (pjsua_call*) inv->dlg->mod_data[pjsua_var.mod.id];

    /* Supply candidate answer */
    PJ_LOG(4,(THIS_FILE, "Call %d: received updated media offer",
	      call->index));
    pj_log_push_indent();

    if (pjsua_var.ua_cfg.cb.on_call_rx_offer) {
	pjsip_status_code code = PJSIP_SC_OK;
	pjsua_call_setting opt = call->opt;
	
	(*pjsua_var.ua_cfg.cb.on_call_rx_offer)(call->index, offer, NULL,
						&code, &opt);

	if (code != PJSIP_SC_OK) {
	    PJ_LOG(4,(THIS_FILE, "Rejecting updated media offer on call %d",
		      call->index));
	    goto on_return;
	}

	call->opt = opt;
    }
    
    /* Re-init media for the new remote offer before creating SDP */
    status = apply_call_setting(call, &call->opt, offer);
    if (status != PJ_SUCCESS)
	goto on_return;

    status = pjsua_media_channel_create_sdp(call->index, 
					    call->inv->pool_prov, 
					    offer, &answer, NULL);
    if (status != PJ_SUCCESS) {
	pjsua_perror(THIS_FILE, "Unable to create local SDP", status);
	goto on_return;
    }

    /* Validate media count in the generated answer */
    pj_assert(answer->media_count == offer->media_count);

    /* Check if offer's conn address is zero */
    for (i = 0; i < answer->media_count; ++i) {
	pjmedia_sdp_conn *conn;

	conn = offer->media[i]->conn;
	if (!conn)
	    conn = offer->conn;

	if (pj_strcmp2(&conn->addr, "0.0.0.0")==0 ||
	    pj_strcmp2(&conn->addr, "0")==0)
	{
	    pjmedia_sdp_conn *a_conn = answer->media[i]->conn;

	    /* Modify answer address */
	    if (a_conn) {
		a_conn->addr = pj_str("0.0.0.0");
	    } else if (answer->conn == NULL ||
		       pj_strcmp2(&answer->conn->addr, "0.0.0.0") != 0)
	    {
		a_conn = PJ_POOL_ZALLOC_T(call->inv->pool_prov,
					  pjmedia_sdp_conn);
		a_conn->net_type = pj_str("IN");
		a_conn->addr_type = pj_str("IP4");
		a_conn->addr = pj_str("0.0.0.0");
		answer->media[i]->conn = a_conn;
	    }
	}
    }

    /* Check if call is on-hold */
    if (call->local_hold) {
	modify_sdp_of_call_hold(call, call->inv->pool_prov, answer, PJ_TRUE);
    }

    status = pjsip_inv_set_sdp_answer(call->inv, answer);
    if (status != PJ_SUCCESS) {
	pjsua_perror(THIS_FILE, "Unable to set answer", status);
	goto on_return;
    }

on_return:
    pj_log_pop_indent();
}


/*
 * Called to generate new offer.
 */
static void pjsua_call_on_create_offer(pjsip_inv_session *inv,
				       pjmedia_sdp_session **offer)
{
    pjsua_call *call;
    pj_status_t status;

    pj_log_push_indent();

    call = (pjsua_call*) inv->dlg->mod_data[pjsua_var.mod.id];

    /* See if we've put call on hold. */
    if (call->local_hold) {
	PJ_LOG(4,(THIS_FILE, 
		  "Call %d: call is on-hold locally, creating call-hold SDP ",
		  call->index));
	status = create_sdp_of_call_hold( call, offer );
    } else {
	PJ_LOG(4,(THIS_FILE, "Call %d: asked to send a new offer",
		  call->index));

	status = pjsua_media_channel_create_sdp(call->index, 
						call->inv->pool_prov, 
					        NULL, offer, NULL);
    }

    if (status != PJ_SUCCESS) {
	pjsua_perror(THIS_FILE, "Unable to create local SDP", status);
	goto on_return;
    }

on_return:
    pj_log_pop_indent();
}


/*
 * Callback called by event framework when the xfer subscription state
 * has changed.
 */
static void xfer_client_on_evsub_state( pjsip_evsub *sub, pjsip_event *event)
{
    
    PJ_UNUSED_ARG(event);

    pj_log_push_indent();

    /*
     * When subscription is accepted (got 200/OK to REFER), check if 
     * subscription suppressed.
     */
    if (pjsip_evsub_get_state(sub) == PJSIP_EVSUB_STATE_ACCEPTED) {

	pjsip_rx_data *rdata;
	pjsip_generic_string_hdr *refer_sub;
	const pj_str_t REFER_SUB = { "Refer-Sub", 9 };
	pjsua_call *call;

	call = (pjsua_call*) pjsip_evsub_get_mod_data(sub, pjsua_var.mod.id);

	/* Must be receipt of response message */
	pj_assert(event->type == PJSIP_EVENT_TSX_STATE && 
		  event->body.tsx_state.type == PJSIP_EVENT_RX_MSG);
	rdata = event->body.tsx_state.src.rdata;

	/* Find Refer-Sub header */
	refer_sub = (pjsip_generic_string_hdr*)
		    pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, 
					       &REFER_SUB, NULL);

	/* Check if subscription is suppressed */
	if (refer_sub && pj_stricmp2(&refer_sub->hvalue, "false")==0) {
	    /* Since no subscription is desired, assume that call has been
	     * transfered successfully.
	     */
	    if (call && pjsua_var.ua_cfg.cb.on_call_transfer_status) {
		const pj_str_t ACCEPTED = { "Accepted", 8 };
		pj_bool_t cont = PJ_FALSE;
		(*pjsua_var.ua_cfg.cb.on_call_transfer_status)(call->index, 
							       200,
							       &ACCEPTED,
							       PJ_TRUE,
							       &cont);
	    }

	    /* Yes, subscription is suppressed.
	     * Terminate our subscription now.
	     */
	    PJ_LOG(4,(THIS_FILE, "Xfer subscription suppressed, terminating "
				 "event subcription..."));
	    pjsip_evsub_terminate(sub, PJ_TRUE);

	} else {
	    /* Notify application about call transfer progress. 
	     * Initially notify with 100/Accepted status.
	     */
	    if (call && pjsua_var.ua_cfg.cb.on_call_transfer_status) {
		const pj_str_t ACCEPTED = { "Accepted", 8 };
		pj_bool_t cont = PJ_FALSE;
		(*pjsua_var.ua_cfg.cb.on_call_transfer_status)(call->index, 
							       100,
							       &ACCEPTED,
							       PJ_FALSE,
							       &cont);
	    }
	}
    }
    /*
     * On incoming NOTIFY, notify application about call transfer progress.
     */
    else if (pjsip_evsub_get_state(sub) == PJSIP_EVSUB_STATE_ACTIVE ||
	     pjsip_evsub_get_state(sub) == PJSIP_EVSUB_STATE_TERMINATED) 
    {
	pjsua_call *call;
	pjsip_msg *msg;
	pjsip_msg_body *body;
	pjsip_status_line status_line;
	pj_bool_t is_last;
	pj_bool_t cont;
	pj_status_t status;

	call = (pjsua_call*) pjsip_evsub_get_mod_data(sub, pjsua_var.mod.id);

	/* When subscription is terminated, clear the xfer_sub member of 
	 * the inv_data.
	 */
	if (pjsip_evsub_get_state(sub) == PJSIP_EVSUB_STATE_TERMINATED) {
	    pjsip_evsub_set_mod_data(sub, pjsua_var.mod.id, NULL);
	    PJ_LOG(4,(THIS_FILE, "Xfer client subscription terminated"));

	}

	if (!call || !event || !pjsua_var.ua_cfg.cb.on_call_transfer_status) {
	    /* Application is not interested with call progress status */
	    goto on_return;
	}

	/* This better be a NOTIFY request */
	if (event->type == PJSIP_EVENT_TSX_STATE &&
	    event->body.tsx_state.type == PJSIP_EVENT_RX_MSG)
	{
	    pjsip_rx_data *rdata;

	    rdata = event->body.tsx_state.src.rdata;

	    /* Check if there's body */
	    msg = rdata->msg_info.msg;
	    body = msg->body;
	    if (!body) {
		PJ_LOG(2,(THIS_FILE, 
			  "Warning: received NOTIFY without message body"));
		goto on_return;
	    }

	    /* Check for appropriate content */
	    if (pj_stricmp2(&body->content_type.type, "message") != 0 ||
		pj_stricmp2(&body->content_type.subtype, "sipfrag") != 0)
	    {
		PJ_LOG(2,(THIS_FILE, 
			  "Warning: received NOTIFY with non message/sipfrag "
			  "content"));
		goto on_return;
	    }

	    /* Try to parse the content */
	    status = pjsip_parse_status_line((char*)body->data, body->len, 
					     &status_line);
	    if (status != PJ_SUCCESS) {
		PJ_LOG(2,(THIS_FILE, 
			  "Warning: received NOTIFY with invalid "
			  "message/sipfrag content"));
		goto on_return;
	    }

	} else {
	    status_line.code = 500;
	    status_line.reason = *pjsip_get_status_text(500);
	}

	/* Notify application */
	is_last = (pjsip_evsub_get_state(sub)==PJSIP_EVSUB_STATE_TERMINATED);
	cont = !is_last;
	(*pjsua_var.ua_cfg.cb.on_call_transfer_status)(call->index, 
						       status_line.code,
						       &status_line.reason,
						       is_last, &cont);

	if (!cont) {
	    pjsip_evsub_set_mod_data(sub, pjsua_var.mod.id, NULL);
	}

	/* If the call transfer has completed but the subscription is
	 * not terminated, terminate it now.
	 */
	if (status_line.code/100 == 2 && !is_last) {
	    pjsip_tx_data *tdata;

	    status = pjsip_evsub_initiate(sub, &pjsip_subscribe_method, 
					  0, &tdata);
	    if (status == PJ_SUCCESS)
		status = pjsip_evsub_send_request(sub, tdata);
	}
    }

on_return:
    pj_log_pop_indent();
}


/*
 * Callback called by event framework when the xfer subscription state
 * has changed.
 */
static void xfer_server_on_evsub_state( pjsip_evsub *sub, pjsip_event *event)
{
    PJ_UNUSED_ARG(event);

    pj_log_push_indent();

    /*
     * When subscription is terminated, clear the xfer_sub member of 
     * the inv_data.
     */
    if (pjsip_evsub_get_state(sub) == PJSIP_EVSUB_STATE_TERMINATED) {
	pjsua_call *call;

	call = (pjsua_call*) pjsip_evsub_get_mod_data(sub, pjsua_var.mod.id);
	if (!call)
	    goto on_return;

	pjsip_evsub_set_mod_data(sub, pjsua_var.mod.id, NULL);
	call->xfer_sub = NULL;

	PJ_LOG(4,(THIS_FILE, "Xfer server subscription terminated"));
    }

on_return:
    pj_log_pop_indent();
}


/*
 * Follow transfer (REFER) request.
 */
static void on_call_transfered( pjsip_inv_session *inv,
			        pjsip_rx_data *rdata )
{
    pj_status_t status;
    pjsip_tx_data *tdata;
    pjsua_call *existing_call;
    int new_call;
    const pj_str_t str_refer_to = { "Refer-To", 8};
    const pj_str_t str_refer_sub = { "Refer-Sub", 9 };
    const pj_str_t str_ref_by = { "Referred-By", 11 };
    pjsip_generic_string_hdr *refer_to;
    pjsip_generic_string_hdr *refer_sub;
    pjsip_hdr *ref_by_hdr;
    pj_bool_t no_refer_sub = PJ_FALSE;
    char *uri;
    pjsua_msg_data msg_data;
    pj_str_t tmp;
    pjsip_status_code code;
    pjsip_evsub *sub;
    pjsua_call_setting call_opt;

    pj_log_push_indent();

    existing_call = (pjsua_call*) inv->dlg->mod_data[pjsua_var.mod.id];

    /* Find the Refer-To header */
    refer_to = (pjsip_generic_string_hdr*)
	pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &str_refer_to, NULL);

    if (refer_to == NULL) {
	/* Invalid Request.
	 * No Refer-To header!
	 */
	PJ_LOG(4,(THIS_FILE, "Received REFER without Refer-To header!"));
	pjsip_dlg_respond( inv->dlg, rdata, 400, NULL, NULL, NULL);
	goto on_return;
    }

    /* Find optional Refer-Sub header */
    refer_sub = (pjsip_generic_string_hdr*)
	pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &str_refer_sub, NULL);

    if (refer_sub) {
	if (!pj_strnicmp2(&refer_sub->hvalue, "true", 4)==0)
	    no_refer_sub = PJ_TRUE;
    }

    /* Find optional Referred-By header (to be copied onto outgoing INVITE
     * request.
     */
    ref_by_hdr = (pjsip_hdr*)
		 pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &str_ref_by, 
					    NULL);

    /* Notify callback */
    code = PJSIP_SC_ACCEPTED;
    if (pjsua_var.ua_cfg.cb.on_call_transfer_request) {
	(*pjsua_var.ua_cfg.cb.on_call_transfer_request)(existing_call->index,
							&refer_to->hvalue, 
							&code);
    }

    call_opt = existing_call->opt;
    if (pjsua_var.ua_cfg.cb.on_call_transfer_request2) {
	(*pjsua_var.ua_cfg.cb.on_call_transfer_request2)(existing_call->index,
							 &refer_to->hvalue, 
							 &code,
							 &call_opt);
    }

    if (code < 200)
	code = PJSIP_SC_ACCEPTED;
    if (code >= 300) {
	/* Application rejects call transfer request */
	pjsip_dlg_respond( inv->dlg, rdata, code, NULL, NULL, NULL);
	goto on_return;
    }

    PJ_LOG(3,(THIS_FILE, "Call to %.*s is being transfered to %.*s",
	      (int)inv->dlg->remote.info_str.slen,
	      inv->dlg->remote.info_str.ptr,
	      (int)refer_to->hvalue.slen, 
	      refer_to->hvalue.ptr));

    if (no_refer_sub) {
	/*
	 * Always answer with 2xx.
	 */
	pjsip_tx_data *tdata;
	const pj_str_t str_false = { "false", 5};
	pjsip_hdr *hdr;

	status = pjsip_dlg_create_response(inv->dlg, rdata, code, NULL, 
					   &tdata);
	if (status != PJ_SUCCESS) {
	    pjsua_perror(THIS_FILE, "Unable to create 2xx response to REFER",
			 status);
	    goto on_return;
	}

	/* Add Refer-Sub header */
	hdr = (pjsip_hdr*) 
	       pjsip_generic_string_hdr_create(tdata->pool, &str_refer_sub,
					      &str_false);
	pjsip_msg_add_hdr(tdata->msg, hdr);


	/* Send answer */
	status = pjsip_dlg_send_response(inv->dlg, pjsip_rdata_get_tsx(rdata),
					 tdata);
	if (status != PJ_SUCCESS) {
	    pjsua_perror(THIS_FILE, "Unable to create 2xx response to REFER",
			 status);
	    goto on_return;
	}

	/* Don't have subscription */
	sub = NULL;

    } else {
	struct pjsip_evsub_user xfer_cb;
	pjsip_hdr hdr_list;

	/* Init callback */
	pj_bzero(&xfer_cb, sizeof(xfer_cb));
	xfer_cb.on_evsub_state = &xfer_server_on_evsub_state;

	/* Init additional header list to be sent with REFER response */
	pj_list_init(&hdr_list);

	/* Create transferee event subscription */
	status = pjsip_xfer_create_uas( inv->dlg, &xfer_cb, rdata, &sub);
	if (status != PJ_SUCCESS) {
	    pjsua_perror(THIS_FILE, "Unable to create xfer uas", status);
	    pjsip_dlg_respond( inv->dlg, rdata, 500, NULL, NULL, NULL);
	    goto on_return;
	}

	/* If there's Refer-Sub header and the value is "true", send back
	 * Refer-Sub in the response with value "true" too.
	 */
	if (refer_sub) {
	    const pj_str_t str_true = { "true", 4 };
	    pjsip_hdr *hdr;

	    hdr = (pjsip_hdr*) 
		   pjsip_generic_string_hdr_create(inv->dlg->pool, 
						   &str_refer_sub,
						   &str_true);
	    pj_list_push_back(&hdr_list, hdr);

	}

	/* Accept the REFER request, send 2xx. */
	pjsip_xfer_accept(sub, rdata, code, &hdr_list);

	/* Create initial NOTIFY request */
	status = pjsip_xfer_notify( sub, PJSIP_EVSUB_STATE_ACTIVE,
				    100, NULL, &tdata);
	if (status != PJ_SUCCESS) {
	    pjsua_perror(THIS_FILE, "Unable to create NOTIFY to REFER", 
			 status);
	    goto on_return;
	}

	/* Send initial NOTIFY request */
	status = pjsip_xfer_send_request( sub, tdata);
	if (status != PJ_SUCCESS) {
	    pjsua_perror(THIS_FILE, "Unable to send NOTIFY to REFER", status);
	    goto on_return;
	}
    }

    /* We're cheating here.
     * We need to get a null terminated string from a pj_str_t.
     * So grab the pointer from the hvalue and NULL terminate it, knowing
     * that the NULL position will be occupied by a newline. 
     */
    uri = refer_to->hvalue.ptr;
    uri[refer_to->hvalue.slen] = '\0';

    /* Init msg_data */
    pjsua_msg_data_init(&msg_data);

    /* If Referred-By header is present in the REFER request, copy this
     * to the outgoing INVITE request.
     */
    if (ref_by_hdr != NULL) {
	pjsip_hdr *dup = (pjsip_hdr*)
			 pjsip_hdr_clone(rdata->tp_info.pool, ref_by_hdr);
	pj_list_push_back(&msg_data.hdr_list, dup);
    }

    /* Now make the outgoing call. */
    tmp = pj_str(uri);
    status = pjsua_call_make_call(existing_call->acc_id, &tmp, &call_opt,
				  existing_call->user_data, &msg_data, 
				  &new_call);
    if (status != PJ_SUCCESS) {

	/* Notify xferer about the error (if we have subscription) */
	if (sub) {
	    status = pjsip_xfer_notify(sub, PJSIP_EVSUB_STATE_TERMINATED,
				       500, NULL, &tdata);
	    if (status != PJ_SUCCESS) {
		pjsua_perror(THIS_FILE, "Unable to create NOTIFY to REFER", 
			      status);
		goto on_return;
	    }
	    status = pjsip_xfer_send_request(sub, tdata);
	    if (status != PJ_SUCCESS) {
		pjsua_perror(THIS_FILE, "Unable to send NOTIFY to REFER", 
			      status);
		goto on_return;
	    }
	}
	goto on_return;
    }

    if (sub) {
	/* Put the server subscription in inv_data.
	 * Subsequent state changed in pjsua_inv_on_state_changed() will be
	 * reported back to the server subscription.
	 */
	pjsua_var.calls[new_call].xfer_sub = sub;

	/* Put the invite_data in the subscription. */
	pjsip_evsub_set_mod_data(sub, pjsua_var.mod.id, 
				 &pjsua_var.calls[new_call]);
    }

on_return:
    pj_log_pop_indent();
}



/*
 * This callback is called when transaction state has changed in INVITE
 * session. We use this to trap:
 *  - incoming REFER request.
 *  - incoming MESSAGE request.
 */
static void pjsua_call_on_tsx_state_changed(pjsip_inv_session *inv,
					    pjsip_transaction *tsx,
					    pjsip_event *e)
{
    pjsua_call *call;

    pj_log_push_indent();

    call = (pjsua_call*) inv->dlg->mod_data[pjsua_var.mod.id];

    if (call == NULL)
	goto on_return;

    if (call->inv == NULL) {
	/* Call has been disconnected. */
	goto on_return;
    }

    /* https://trac.pjsip.org/repos/ticket/1452:
     *    If a request is retried due to 401/407 challenge, don't process the
     *    transaction first but wait until we've retried it.
     */
    if (tsx->role == PJSIP_ROLE_UAC &&
	(tsx->status_code==401 || tsx->status_code==407) &&
	tsx->last_tx && tsx->last_tx->auth_retry)
    {
	goto on_return;
    }

    /* Notify application callback first */
    if (pjsua_var.ua_cfg.cb.on_call_tsx_state) {
	(*pjsua_var.ua_cfg.cb.on_call_tsx_state)(call->index, tsx, e);
    }

    if (tsx->role==PJSIP_ROLE_UAS &&
	tsx->state==PJSIP_TSX_STATE_TRYING &&
	pjsip_method_cmp(&tsx->method, pjsip_get_refer_method())==0)
    {
	/*
	 * Incoming REFER request.
	 */
	on_call_transfered(call->inv, e->body.tsx_state.src.rdata);

    }
    else if (tsx->role==PJSIP_ROLE_UAS &&
	     tsx->state==PJSIP_TSX_STATE_TRYING &&
	     pjsip_method_cmp(&tsx->method, &pjsip_message_method)==0)
    {
	/*
	 * Incoming MESSAGE request!
	 */
	pjsip_rx_data *rdata;
	pjsip_msg *msg;
	pjsip_accept_hdr *accept_hdr;
	pj_status_t status;

	rdata = e->body.tsx_state.src.rdata;
	msg = rdata->msg_info.msg;

	/* Request MUST have message body, with Content-Type equal to
	 * "text/plain".
	 */
	if (pjsua_im_accept_pager(rdata, &accept_hdr) == PJ_FALSE) {

	    pjsip_hdr hdr_list;

	    pj_list_init(&hdr_list);
	    pj_list_push_back(&hdr_list, accept_hdr);

	    pjsip_dlg_respond( inv->dlg, rdata, PJSIP_SC_NOT_ACCEPTABLE_HERE, 
			       NULL, &hdr_list, NULL );
	    goto on_return;
	}

	/* Respond with 200 first, so that remote doesn't retransmit in case
	 * the UI takes too long to process the message. 
	 */
	status = pjsip_dlg_respond( inv->dlg, rdata, 200, NULL, NULL, NULL);

	/* Process MESSAGE request */
	pjsua_im_process_pager(call->index, &inv->dlg->remote.info_str,
			       &inv->dlg->local.info_str, rdata);

    }
    else if (tsx->role == PJSIP_ROLE_UAC &&
	     pjsip_method_cmp(&tsx->method, &pjsip_message_method)==0)
    {
	/* Handle outgoing pager status */
	if (tsx->status_code >= 200) {
	    pjsua_im_data *im_data;

	    im_data = (pjsua_im_data*) tsx->mod_data[pjsua_var.mod.id];
	    /* im_data can be NULL if this is typing indication */

	    if (im_data && pjsua_var.ua_cfg.cb.on_pager_status) {
		pjsua_var.ua_cfg.cb.on_pager_status(im_data->call_id,
						    &im_data->to,
						    &im_data->body,
						    im_data->user_data,
						    (pjsip_status_code)
						    	tsx->status_code,
						    &tsx->status_text);
	    }
	}
    } else if (tsx->role == PJSIP_ROLE_UAC &&
	       tsx->last_tx == (pjsip_tx_data*)call->hold_msg &&
	       tsx->state >= PJSIP_TSX_STATE_COMPLETED)
    {
	/* Monitor the status of call hold request */
	call->hold_msg = NULL;
	if (tsx->status_code/100 != 2) {
	    /* Outgoing call hold failed */
	    call->local_hold = PJ_FALSE;
	    PJ_LOG(3,(THIS_FILE, "Error putting call %d on hold (reason=%d)",
		      call->index, tsx->status_code));
	}
    } else if (tsx->role == PJSIP_ROLE_UAC &&
               (call->opt.flag & PJSUA_CALL_UNHOLD) &&
               tsx->state >= PJSIP_TSX_STATE_COMPLETED)
    {
        /* Monitor the status of call unhold request */
        if (tsx->status_code/100 != 2 &&
            (tsx->status_code!=401 && tsx->status_code!=407))
        {
            /* Call unhold failed */
            call->opt.flag &= ~PJSUA_CALL_UNHOLD;
            call->local_hold = PJ_TRUE;
	    PJ_LOG(3,(THIS_FILE, "Error releasing hold on call %d (reason=%d)",
		      call->index, tsx->status_code));
        }
    } else if (tsx->role==PJSIP_ROLE_UAS &&
	tsx->state==PJSIP_TSX_STATE_TRYING &&
	pjsip_method_cmp(&tsx->method, &pjsip_info_method)==0)
    {
	/*
	 * Incoming INFO request for media control.
	 */
	const pj_str_t STR_APPLICATION	     = { "application", 11};
	const pj_str_t STR_MEDIA_CONTROL_XML = { "media_control+xml", 17 };
	pjsip_rx_data *rdata = e->body.tsx_state.src.rdata;
	pjsip_msg_body *body = rdata->msg_info.msg->body;

	if (body && body->len &&
	    pj_stricmp(&body->content_type.type, &STR_APPLICATION)==0 &&
	    pj_stricmp(&body->content_type.subtype, &STR_MEDIA_CONTROL_XML)==0)
	{
	    pjsip_tx_data *tdata;
	    pj_str_t control_st;
	    pj_status_t status;

	    /* Apply and answer the INFO request */
	    pj_strset(&control_st, (char*)body->data, body->len);
	    status = pjsua_media_apply_xml_control(call->index, &control_st);
	    if (status == PJ_SUCCESS) {
		status = pjsip_endpt_create_response(tsx->endpt, rdata,
						     200, NULL, &tdata);
		if (status == PJ_SUCCESS)
		    status = pjsip_tsx_send_msg(tsx, tdata);
	    } else {
		status = pjsip_endpt_create_response(tsx->endpt, rdata,
						     400, NULL, &tdata);
		if (status == PJ_SUCCESS)
		    status = pjsip_tsx_send_msg(tsx, tdata);
	    }
	}
    }

on_return:
    pj_log_pop_indent();
}


/* Redirection handler */
static pjsip_redirect_op pjsua_call_on_redirected(pjsip_inv_session *inv,
						  const pjsip_uri *target,
						  const pjsip_event *e)
{
    pjsua_call *call = (pjsua_call*) inv->dlg->mod_data[pjsua_var.mod.id];
    pjsip_redirect_op op;

    pj_log_push_indent();

    if (pjsua_var.ua_cfg.cb.on_call_redirected) {
	op = (*pjsua_var.ua_cfg.cb.on_call_redirected)(call->index, 
							 target, e);
    } else {
	PJ_LOG(4,(THIS_FILE, "Unhandled redirection for call %d "
		  "(callback not implemented by application). Disconnecting "
		  "call.",
		  call->index));
	op = PJSIP_REDIRECT_STOP;
    }

    pj_log_pop_indent();

    return op;
}

