/* $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 <pjsip/sip_dialog.h>
#include <pjsip/sip_ua_layer.h>
#include <pjsip/sip_errno.h>
#include <pjsip/sip_endpoint.h>
#include <pjsip/sip_parser.h>
#include <pjsip/sip_module.h>
#include <pjsip/sip_util.h>
#include <pjsip/sip_transaction.h>
#include <pj/assert.h>
#include <pj/os.h>
#include <pj/string.h>
#include <pj/pool.h>
#include <pj/guid.h>
#include <pj/rand.h>
#include <pj/array.h>
#include <pj/except.h>
#include <pj/hash.h>
#include <pj/log.h>

#define THIS_FILE	"sip_dialog.c"

long pjsip_dlg_lock_tls_id;

/* Config */
pj_bool_t pjsip_include_allow_hdr_in_dlg = PJSIP_INCLUDE_ALLOW_HDR_IN_DLG;

/* Contact header string */
static const pj_str_t HCONTACT = { "Contact", 7 };


PJ_DEF(pj_bool_t) pjsip_method_creates_dialog(const pjsip_method *m)
{
    const pjsip_method subscribe = { PJSIP_OTHER_METHOD, {"SUBSCRIBE", 9}};
    const pjsip_method refer = { PJSIP_OTHER_METHOD, {"REFER", 5}};
    const pjsip_method notify = { PJSIP_OTHER_METHOD, {"NOTIFY", 6}};
    const pjsip_method update = { PJSIP_OTHER_METHOD, {"UPDATE", 6}};

    return m->id == PJSIP_INVITE_METHOD ||
	   (pjsip_method_cmp(m, &subscribe)==0) ||
	   (pjsip_method_cmp(m, &refer)==0) ||
	   (pjsip_method_cmp(m, &notify)==0) ||
	   (pjsip_method_cmp(m, &update)==0);
}

static pj_status_t create_dialog( pjsip_user_agent *ua,
				  pjsip_dialog **p_dlg)
{
    pjsip_endpoint *endpt;
    pj_pool_t *pool;
    pjsip_dialog *dlg;
    pj_status_t status;

    endpt = pjsip_ua_get_endpt(ua);
    if (!endpt)
	return PJ_EINVALIDOP;

    pool = pjsip_endpt_create_pool(endpt, "dlg%p", 
				   PJSIP_POOL_LEN_DIALOG, 
				   PJSIP_POOL_INC_DIALOG);
    if (!pool)
	return PJ_ENOMEM;

    dlg = PJ_POOL_ZALLOC_T(pool, pjsip_dialog);
    PJ_ASSERT_RETURN(dlg != NULL, PJ_ENOMEM);

    dlg->pool = pool;
    pj_ansi_snprintf(dlg->obj_name, sizeof(dlg->obj_name), "dlg%p", dlg);
    dlg->ua = ua;
    dlg->endpt = endpt;
    dlg->state = PJSIP_DIALOG_STATE_NULL;
    dlg->add_allow = pjsip_include_allow_hdr_in_dlg;

    pj_list_init(&dlg->inv_hdr);
    pj_list_init(&dlg->rem_cap_hdr);

    status = pj_mutex_create_recursive(pool, dlg->obj_name, &dlg->mutex_);
    if (status != PJ_SUCCESS)
	goto on_error;

    pjsip_target_set_init(&dlg->target_set);

    *p_dlg = dlg;
    return PJ_SUCCESS;

on_error:
    if (dlg->mutex_)
	pj_mutex_destroy(dlg->mutex_);
    pjsip_endpt_release_pool(endpt, pool);
    return status;
}

static void destroy_dialog( pjsip_dialog *dlg )
{
    if (dlg->mutex_) {
	pj_mutex_destroy(dlg->mutex_);
	dlg->mutex_ = NULL;
    }
    if (dlg->tp_sel.type != PJSIP_TPSELECTOR_NONE) {
	pjsip_tpselector_dec_ref(&dlg->tp_sel);
	pj_bzero(&dlg->tp_sel, sizeof(pjsip_tpselector));
    }
    pjsip_endpt_release_pool(dlg->endpt, dlg->pool);
}


/*
 * Create an UAC dialog.
 */
PJ_DEF(pj_status_t) pjsip_dlg_create_uac( pjsip_user_agent *ua,
					  const pj_str_t *local_uri,
					  const pj_str_t *local_contact,
					  const pj_str_t *remote_uri,
					  const pj_str_t *target,
					  pjsip_dialog **p_dlg)
{
    pj_status_t status;
    pj_str_t tmp;
    pjsip_dialog *dlg;

    /* Check arguments. */
    PJ_ASSERT_RETURN(ua && local_uri && remote_uri && p_dlg, PJ_EINVAL);

    /* Create dialog instance. */
    status = create_dialog(ua, &dlg);
    if (status != PJ_SUCCESS)
	return status;

    /* Parse target. */
    pj_strdup_with_null(dlg->pool, &tmp, target ? target : remote_uri);
    dlg->target = pjsip_parse_uri(dlg->pool, tmp.ptr, tmp.slen, 0);
    if (!dlg->target) {
	status = PJSIP_EINVALIDURI;
	goto on_error;
    }

    /* Put any header param in the target URI into INVITE header list. */
    if (PJSIP_URI_SCHEME_IS_SIP(dlg->target) ||
	PJSIP_URI_SCHEME_IS_SIPS(dlg->target))
    {
	pjsip_param *param;
	pjsip_sip_uri *uri = (pjsip_sip_uri*)pjsip_uri_get_uri(dlg->target);

	param = uri->header_param.next;
	while (param != &uri->header_param) {
	    pjsip_hdr *hdr;
	    int c;

	    c = param->value.ptr[param->value.slen];
	    param->value.ptr[param->value.slen] = '\0';

	    hdr = (pjsip_hdr*)
	    	  pjsip_parse_hdr(dlg->pool, &param->name, param->value.ptr,
				  param->value.slen, NULL);

	    param->value.ptr[param->value.slen] = (char)c;

	    if (hdr == NULL) {
		status = PJSIP_EINVALIDURI;
		goto on_error;
	    }
	    pj_list_push_back(&dlg->inv_hdr, hdr);

	    param = param->next;
	}

	/* Now must remove any header params from URL, since that would
	 * create another header in pjsip_endpt_create_request().
	 */
	pj_list_init(&uri->header_param);
    }

    /* Add target to the target set */
    pjsip_target_set_add_uri(&dlg->target_set, dlg->pool, dlg->target, 0);

    /* Init local info. */
    dlg->local.info = pjsip_from_hdr_create(dlg->pool);
    pj_strdup_with_null(dlg->pool, &dlg->local.info_str, local_uri);
    dlg->local.info->uri = pjsip_parse_uri(dlg->pool, 
					   dlg->local.info_str.ptr, 
					   dlg->local.info_str.slen, 0);
    if (!dlg->local.info->uri) {
	status = PJSIP_EINVALIDURI;
	goto on_error;
    }

    /* Generate local tag. */
    pj_create_unique_string(dlg->pool, &dlg->local.info->tag);

    /* Calculate hash value of local tag. */
    dlg->local.tag_hval = pj_hash_calc_tolower(0, NULL,
                                               &dlg->local.info->tag);

    /* Randomize local CSeq. */
    dlg->local.first_cseq = pj_rand() & 0x7FFF;
    dlg->local.cseq = dlg->local.first_cseq;

    /* Init local contact. */
    pj_strdup_with_null(dlg->pool, &tmp, 
			local_contact ? local_contact : local_uri);
    dlg->local.contact = (pjsip_contact_hdr*)
			 pjsip_parse_hdr(dlg->pool, &HCONTACT, tmp.ptr, 
					 tmp.slen, NULL);
    if (!dlg->local.contact) {
	status = PJSIP_EINVALIDURI;
	goto on_error;
    }

    /* Init remote info. */
    dlg->remote.info = pjsip_to_hdr_create(dlg->pool);
    pj_strdup_with_null(dlg->pool, &dlg->remote.info_str, remote_uri);
    dlg->remote.info->uri = pjsip_parse_uri(dlg->pool, 
					    dlg->remote.info_str.ptr, 
					    dlg->remote.info_str.slen, 0);
    if (!dlg->remote.info->uri) {
	status = PJSIP_EINVALIDURI;
	goto on_error;
    }

    /* Remove header param from remote.info_str, if any */
    if (PJSIP_URI_SCHEME_IS_SIP(dlg->remote.info->uri) ||
	PJSIP_URI_SCHEME_IS_SIPS(dlg->remote.info->uri))
    {
	pjsip_sip_uri *sip_uri = (pjsip_sip_uri *) 
				 pjsip_uri_get_uri(dlg->remote.info->uri);
	if (!pj_list_empty(&sip_uri->header_param)) {
	    pj_str_t tmp;

	    /* Remove all header param */
	    pj_list_init(&sip_uri->header_param);

	    /* Print URI */
	    tmp.ptr = (char*) pj_pool_alloc(dlg->pool, 
	    				    dlg->remote.info_str.slen);
	    tmp.slen = pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR,
				       sip_uri, tmp.ptr, 
				       dlg->remote.info_str.slen);

	    if (tmp.slen < 1) {
		status = PJSIP_EURITOOLONG;
		goto on_error;
	    }

	    /* Assign remote.info_str */
	    dlg->remote.info_str = tmp;
	}
    }


    /* Initialize remote's CSeq to -1. */
    dlg->remote.cseq = dlg->remote.first_cseq = -1;

    /* Initial role is UAC. */
    dlg->role = PJSIP_ROLE_UAC;

    /* Secure? */
    dlg->secure = PJSIP_URI_SCHEME_IS_SIPS(dlg->target);

    /* Generate Call-ID header. */
    dlg->call_id = pjsip_cid_hdr_create(dlg->pool);
    pj_create_unique_string(dlg->pool, &dlg->call_id->id);

    /* Initial route set is empty. */
    pj_list_init(&dlg->route_set);

    /* Init client authentication session. */
    status = pjsip_auth_clt_init(&dlg->auth_sess, dlg->endpt, 
				 dlg->pool, 0);
    if (status != PJ_SUCCESS)
	goto on_error;

    /* Register this dialog to user agent. */
    status = pjsip_ua_register_dlg( ua, dlg );
    if (status != PJ_SUCCESS)
	goto on_error;


    /* Done! */
    *p_dlg = dlg;


    PJ_LOG(5,(dlg->obj_name, "UAC dialog created"));

    return PJ_SUCCESS;

on_error:
    destroy_dialog(dlg);
    return status;
}


/*
 * Create UAS dialog.
 */
PJ_DEF(pj_status_t) pjsip_dlg_create_uas(   pjsip_user_agent *ua,
					    pjsip_rx_data *rdata,
					    const pj_str_t *contact,
					    pjsip_dialog **p_dlg)
{
    pj_status_t status;
    pjsip_hdr *pos = NULL;
    pjsip_contact_hdr *contact_hdr;
    pjsip_rr_hdr *rr;
    pjsip_transaction *tsx = NULL;
    pj_str_t tmp;
    enum { TMP_LEN=128};
    pj_ssize_t len;
    pjsip_dialog *dlg;

    /* Check arguments. */
    PJ_ASSERT_RETURN(ua && rdata && p_dlg, PJ_EINVAL);

    /* rdata must have request message. */
    PJ_ASSERT_RETURN(rdata->msg_info.msg->type == PJSIP_REQUEST_MSG,
		     PJSIP_ENOTREQUESTMSG);

    /* Request must not have To tag. 
     * This should have been checked in the user agent (or application?).
     */
    PJ_ASSERT_RETURN(rdata->msg_info.to->tag.slen == 0, PJ_EINVALIDOP);
		     
    /* The request must be a dialog establishing request. */
    PJ_ASSERT_RETURN(
	pjsip_method_creates_dialog(&rdata->msg_info.msg->line.req.method),
	PJ_EINVALIDOP);

    /* Create dialog instance. */
    status = create_dialog(ua, &dlg);
    if (status != PJ_SUCCESS)
	return status;

    /* Temprary string for getting the string representation of
     * both local and remote URI.
     */
    tmp.ptr = (char*) pj_pool_alloc(rdata->tp_info.pool, TMP_LEN);

    /* Init local info from the To header. */
    dlg->local.info = (pjsip_fromto_hdr*)
    		      pjsip_hdr_clone(dlg->pool, rdata->msg_info.to);
    pjsip_fromto_hdr_set_from(dlg->local.info);

    /* Generate local tag. */
    pj_create_unique_string(dlg->pool, &dlg->local.info->tag);


    /* Print the local info. */
    len = pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR,
			  dlg->local.info->uri, tmp.ptr, TMP_LEN);
    if (len < 1) {
	pj_ansi_strcpy(tmp.ptr, "<-error: uri too long->");
	tmp.slen = pj_ansi_strlen(tmp.ptr);
    } else
	tmp.slen = len;

    /* Save the local info. */
    pj_strdup(dlg->pool, &dlg->local.info_str, &tmp);

    /* Calculate hash value of local tag. */
    dlg->local.tag_hval = pj_hash_calc_tolower(0, NULL, &dlg->local.info->tag);


    /* Randomize local cseq */
    dlg->local.first_cseq = pj_rand() & 0x7FFF;
    dlg->local.cseq = dlg->local.first_cseq;

    /* Init local contact. */
    /* TODO:
     *  Section 12.1.1, paragraph about using SIPS URI in Contact.
     *  If the request that initiated the dialog contained a SIPS URI 
     *  in the Request-URI or in the top Record-Route header field value, 
     *  if there was any, or the Contact header field if there was no 
     *  Record-Route header field, the Contact header field in the response
     *  MUST be a SIPS URI.
     */
    if (contact) {
	pj_str_t tmp;

	pj_strdup_with_null(dlg->pool, &tmp, contact);
	dlg->local.contact = (pjsip_contact_hdr*)
			     pjsip_parse_hdr(dlg->pool, &HCONTACT, tmp.ptr, 
					     tmp.slen, NULL);
	if (!dlg->local.contact) {
	    status = PJSIP_EINVALIDURI;
	    goto on_error;
	}

    } else {
	dlg->local.contact = pjsip_contact_hdr_create(dlg->pool);
	dlg->local.contact->uri = dlg->local.info->uri;
    }

    /* Init remote info from the From header. */
    dlg->remote.info = (pjsip_fromto_hdr*) 
    		       pjsip_hdr_clone(dlg->pool, rdata->msg_info.from);
    pjsip_fromto_hdr_set_to(dlg->remote.info);

    /* Print the remote info. */
    len = pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR,
			  dlg->remote.info->uri, tmp.ptr, TMP_LEN);
    if (len < 1) {
	pj_ansi_strcpy(tmp.ptr, "<-error: uri too long->");
	tmp.slen = pj_ansi_strlen(tmp.ptr);
    } else
	tmp.slen = len;

    /* Save the remote info. */
    pj_strdup(dlg->pool, &dlg->remote.info_str, &tmp);


    /* Init remote's contact from Contact header. 
     * Iterate the Contact URI until we find sip: or sips: scheme.
     */
    do {
	contact_hdr = (pjsip_contact_hdr*)
		      pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT,
				         pos);
	if (contact_hdr) {
	    if (!contact_hdr->uri ||
		(!PJSIP_URI_SCHEME_IS_SIP(contact_hdr->uri) &&
		 !PJSIP_URI_SCHEME_IS_SIPS(contact_hdr->uri)))
	    {
		pos = (pjsip_hdr*)contact_hdr->next;
		if (pos == &rdata->msg_info.msg->hdr)
		    contact_hdr = NULL;
	    } else {
		break;
	    }
	}
    } while (contact_hdr);

    if (!contact_hdr) {
	status = PJSIP_ERRNO_FROM_SIP_STATUS(PJSIP_SC_BAD_REQUEST);
	goto on_error;
    }

    dlg->remote.contact = (pjsip_contact_hdr*) 
    			  pjsip_hdr_clone(dlg->pool, (pjsip_hdr*)contact_hdr);

    /* Init remote's CSeq from CSeq header */
    dlg->remote.cseq = dlg->remote.first_cseq = rdata->msg_info.cseq->cseq;

    /* Set initial target to remote's Contact. */
    dlg->target = dlg->remote.contact->uri;

    /* Initial role is UAS */
    dlg->role = PJSIP_ROLE_UAS;

    /* Secure? 
     *  RFC 3261 Section 12.1.1:
     *  If the request arrived over TLS, and the Request-URI contained a 
     *  SIPS URI, the 'secure' flag is set to TRUE.
     */
    dlg->secure = PJSIP_TRANSPORT_IS_SECURE(rdata->tp_info.transport) &&
		  PJSIP_URI_SCHEME_IS_SIPS(rdata->msg_info.msg->line.req.uri);

    /* Call-ID */
    dlg->call_id = (pjsip_cid_hdr*) 
    		   pjsip_hdr_clone(dlg->pool, rdata->msg_info.cid);

    /* Route set. 
     *  RFC 3261 Section 12.1.1:
     *  The route set MUST be set to the list of URIs in the Record-Route 
     *  header field from the request, taken in order and preserving all URI 
     *  parameters. If no Record-Route header field is present in the request,
     * the route set MUST be set to the empty set.
     */
    pj_list_init(&dlg->route_set);
    rr = rdata->msg_info.record_route;
    while (rr != NULL) {
	pjsip_route_hdr *route;

	/* Clone the Record-Route, change the type to Route header. */
	route = (pjsip_route_hdr*) pjsip_hdr_clone(dlg->pool, rr);
	pjsip_routing_hdr_set_route(route);

	/* Add to route set. */
	pj_list_push_back(&dlg->route_set, route);

	/* Find next Record-Route header. */
	rr = rr->next;
	if (rr == (void*)&rdata->msg_info.msg->hdr)
	    break;
	rr = (pjsip_route_hdr*) pjsip_msg_find_hdr(rdata->msg_info.msg, 
						   PJSIP_H_RECORD_ROUTE, rr);
    }
    dlg->route_set_frozen = PJ_TRUE;

    /* Init client authentication session. */
    status = pjsip_auth_clt_init(&dlg->auth_sess, dlg->endpt,
				 dlg->pool, 0);
    if (status != PJ_SUCCESS)
	goto on_error;

    /* Create UAS transaction for this request. */
    status = pjsip_tsx_create_uas(dlg->ua, rdata, &tsx);
    if (status != PJ_SUCCESS)
	goto on_error;

    /* Associate this dialog to the transaction. */
    tsx->mod_data[dlg->ua->id] = dlg;

    /* Increment tsx counter */
    ++dlg->tsx_count;

    /* Calculate hash value of remote tag. */
    dlg->remote.tag_hval = pj_hash_calc_tolower(0, NULL, &dlg->remote.info->tag);

    /* Update remote capabilities info */
    pjsip_dlg_update_remote_cap(dlg, rdata->msg_info.msg, PJ_TRUE);

    /* Register this dialog to user agent. */
    status = pjsip_ua_register_dlg( ua, dlg );
    if (status != PJ_SUCCESS)
	goto on_error;

    /* Put this dialog in rdata's mod_data */
    rdata->endpt_info.mod_data[ua->id] = dlg;

    PJ_TODO(DIALOG_APP_TIMER);

    /* Feed the first request to the transaction. */
    pjsip_tsx_recv_msg(tsx, rdata);

    /* Done. */
    *p_dlg = dlg;
    PJ_LOG(5,(dlg->obj_name, "UAS dialog created"));
    return PJ_SUCCESS;

on_error:
    if (tsx) {
	pjsip_tsx_terminate(tsx, 500);
	pj_assert(dlg->tsx_count>0);
	--dlg->tsx_count;
    }

    destroy_dialog(dlg);
    return status;
}


/*
 * Bind dialog to a specific transport/listener.
 */
PJ_DEF(pj_status_t) pjsip_dlg_set_transport( pjsip_dialog *dlg,
					     const pjsip_tpselector *sel)
{
    /* Validate */
    PJ_ASSERT_RETURN(dlg && sel, PJ_EINVAL);

    /* Start locking the dialog. */
    pjsip_dlg_inc_lock(dlg);

    /* Decrement reference counter of previous transport selector */
    pjsip_tpselector_dec_ref(&dlg->tp_sel);

    /* Copy transport selector structure .*/
    pj_memcpy(&dlg->tp_sel, sel, sizeof(*sel));

    /* Increment reference counter */
    pjsip_tpselector_add_ref(&dlg->tp_sel);

    /* Unlock dialog. */
    pjsip_dlg_dec_lock(dlg);

    return PJ_SUCCESS;
}

/*
 * Set "sent-by" field of Via header.
 */
PJ_DEF(pj_status_t) pjsip_dlg_set_via_sent_by( pjsip_dialog *dlg,
				               pjsip_host_port *via_addr,
                                               pjsip_transport *via_tp)
{
    PJ_ASSERT_RETURN(dlg, PJ_EINVAL);

    if (!via_addr)
        pj_bzero(&dlg->via_addr, sizeof(dlg->via_addr));
    else {
        if (pj_strcmp(&dlg->via_addr.host, &via_addr->host))
            pj_strdup(dlg->pool, &dlg->via_addr.host, &via_addr->host);
        dlg->via_addr.port = via_addr->port;
    }
    dlg->via_tp = via_tp;

    return PJ_SUCCESS;
}


/*
 * Create forked dialog from a response.
 */
PJ_DEF(pj_status_t) pjsip_dlg_fork( const pjsip_dialog *first_dlg,
				    const pjsip_rx_data *rdata,
				    pjsip_dialog **new_dlg )
{
    pjsip_dialog *dlg;
    const pjsip_msg *msg = rdata->msg_info.msg;
    const pjsip_hdr *end_hdr, *hdr;
    const pjsip_contact_hdr *contact;
    pj_status_t status;

    /* Check arguments. */
    PJ_ASSERT_RETURN(first_dlg && rdata && new_dlg, PJ_EINVAL);
    
    /* rdata must be response message. */
    PJ_ASSERT_RETURN(msg->type == PJSIP_RESPONSE_MSG,
		     PJSIP_ENOTRESPONSEMSG);

    /* Status code MUST be 1xx (but not 100), or 2xx */
    status = msg->line.status.code;
    PJ_ASSERT_RETURN( (status/100==1 && status!=100) ||
		      (status/100==2), PJ_EBUG);

    /* To tag must present in the response. */
    PJ_ASSERT_RETURN(rdata->msg_info.to->tag.slen != 0, PJSIP_EMISSINGTAG);

    /* Find Contact header in the response */
    contact = (const pjsip_contact_hdr*)
	      pjsip_msg_find_hdr(msg, PJSIP_H_CONTACT, NULL);
    if (contact == NULL || contact->uri == NULL)
	return PJSIP_EMISSINGHDR;

    /* Create the dialog. */
    status = create_dialog((pjsip_user_agent*)first_dlg->ua, &dlg);
    if (status != PJ_SUCCESS)
	return status;

    /* Set remote target from the response. */
    dlg->target = (pjsip_uri*) pjsip_uri_clone(dlg->pool, contact->uri);

    /* Clone local info. */
    dlg->local.info = (pjsip_fromto_hdr*) 
    		      pjsip_hdr_clone(dlg->pool, first_dlg->local.info);

    /* Clone local tag. */
    pj_strdup(dlg->pool, &dlg->local.info->tag, &first_dlg->local.info->tag);
    dlg->local.tag_hval = first_dlg->local.tag_hval;

    /* Clone local CSeq. */
    dlg->local.first_cseq = first_dlg->local.first_cseq;
    dlg->local.cseq = first_dlg->local.cseq;

    /* Clone local Contact. */
    dlg->local.contact = (pjsip_contact_hdr*) 
    			 pjsip_hdr_clone(dlg->pool, first_dlg->local.contact);

    /* Clone remote info. */
    dlg->remote.info = (pjsip_fromto_hdr*) 
    		       pjsip_hdr_clone(dlg->pool, first_dlg->remote.info);

    /* Set remote tag from the response. */
    pj_strdup(dlg->pool, &dlg->remote.info->tag, &rdata->msg_info.to->tag);

    /* Initialize remote's CSeq to -1. */
    dlg->remote.cseq = dlg->remote.first_cseq = -1;

    /* Initial role is UAC. */
    dlg->role = PJSIP_ROLE_UAC;

    /* Dialog state depends on the response. */
    status = msg->line.status.code/100;
    if (status == 1 || status == 2)
	dlg->state = PJSIP_DIALOG_STATE_ESTABLISHED;
    else {
	pj_assert(!"Invalid status code");
	dlg->state = PJSIP_DIALOG_STATE_NULL;
    }

    /* Secure? */
    dlg->secure = PJSIP_URI_SCHEME_IS_SIPS(dlg->target);

    /* Clone Call-ID header. */
    dlg->call_id = (pjsip_cid_hdr*) 
    		   pjsip_hdr_clone(dlg->pool, first_dlg->call_id);

    /* Get route-set from the response. */
    pj_list_init(&dlg->route_set);
    end_hdr = &msg->hdr;
    for (hdr=msg->hdr.prev; hdr!=end_hdr; hdr=hdr->prev) {
	if (hdr->type == PJSIP_H_RECORD_ROUTE) {
	    pjsip_route_hdr *r;
	    r = (pjsip_route_hdr*) pjsip_hdr_clone(dlg->pool, hdr);
	    pjsip_routing_hdr_set_route(r);
	    pj_list_push_back(&dlg->route_set, r);
	}
    }

    //dlg->route_set_frozen = PJ_TRUE;

    /* Clone client authentication session. */
    status = pjsip_auth_clt_clone(dlg->pool, &dlg->auth_sess, 
				  &first_dlg->auth_sess);
    if (status != PJ_SUCCESS)
	goto on_error;

    /* Register this dialog to user agent. */
    status = pjsip_ua_register_dlg(dlg->ua, dlg );
    if (status != PJ_SUCCESS)
	goto on_error;


    /* Done! */
    *new_dlg = dlg;

    PJ_LOG(5,(dlg->obj_name, "Forked dialog created"));
    return PJ_SUCCESS;

on_error:
    destroy_dialog(dlg);
    return status;
}


/*
 * Destroy dialog.
 */
static pj_status_t unregister_and_destroy_dialog( pjsip_dialog *dlg )
{
    pj_status_t status;

    /* Lock must have been held. */

    /* Check dialog state. */
    /* Number of sessions must be zero. */
    PJ_ASSERT_RETURN(dlg->sess_count==0, PJ_EINVALIDOP);

    /* MUST not have pending transactions. */
    PJ_ASSERT_RETURN(dlg->tsx_count==0, PJ_EINVALIDOP);

    /* Unregister from user agent. */
    status = pjsip_ua_unregister_dlg(dlg->ua, dlg);
    if (status != PJ_SUCCESS) {
	pj_assert(!"Unexpected failed unregistration!");
	return status;
    }

    /* Log */
    PJ_LOG(5,(dlg->obj_name, "Dialog destroyed"));

    /* Destroy this dialog. */
    destroy_dialog(dlg);

    return PJ_SUCCESS;
}


/*
 * Forcefully terminate dialog.
 */
PJ_DEF(pj_status_t) pjsip_dlg_terminate( pjsip_dialog *dlg )
{
    /* Number of sessions must be zero. */
    PJ_ASSERT_RETURN(dlg->sess_count==0, PJ_EINVALIDOP);

    /* MUST not have pending transactions. */
    PJ_ASSERT_RETURN(dlg->tsx_count==0, PJ_EINVALIDOP);

    return unregister_and_destroy_dialog(dlg);
}


/*
 * Set route_set
 */
PJ_DEF(pj_status_t) pjsip_dlg_set_route_set( pjsip_dialog *dlg,
					     const pjsip_route_hdr *route_set )
{
    pjsip_route_hdr *r;

    PJ_ASSERT_RETURN(dlg, PJ_EINVAL);

    pjsip_dlg_inc_lock(dlg);

    /* Clear route set. */
    pj_list_init(&dlg->route_set);

    if (!route_set) {
	pjsip_dlg_dec_lock(dlg);
	return PJ_SUCCESS;
    }

    r = route_set->next;
    while (r != route_set) {
	pjsip_route_hdr *new_r;

	new_r = (pjsip_route_hdr*) pjsip_hdr_clone(dlg->pool, r);
	pj_list_push_back(&dlg->route_set, new_r);

	r = r->next;
    }

    pjsip_dlg_dec_lock(dlg);
    return PJ_SUCCESS;
}


/*
 * Increment session counter.
 */
PJ_DEF(pj_status_t) pjsip_dlg_inc_session( pjsip_dialog *dlg,
					   pjsip_module *mod )
{
    PJ_ASSERT_RETURN(dlg && mod, PJ_EINVAL);

    pj_log_push_indent();

    pjsip_dlg_inc_lock(dlg);
    ++dlg->sess_count;
    pjsip_dlg_dec_lock(dlg);

    PJ_LOG(5,(dlg->obj_name, "Session count inc to %d by %.*s",
	      dlg->sess_count, (int)mod->name.slen, mod->name.ptr));

    pj_log_pop_indent();
    return PJ_SUCCESS;
}

/*
 * Lock dialog and increment session counter temporarily
 * to prevent it from being deleted. In addition, it must lock
 * the user agent's dialog table first, to prevent deadlock.
 */
PJ_DEF(void) pjsip_dlg_inc_lock(pjsip_dialog *dlg)
{
    PJ_LOG(6,(dlg->obj_name, "Entering pjsip_dlg_inc_lock(), sess_count=%d", 
	      dlg->sess_count));

    pj_mutex_lock(dlg->mutex_);
    dlg->sess_count++;

    PJ_LOG(6,(dlg->obj_name, "Leaving pjsip_dlg_inc_lock(), sess_count=%d", 
	      dlg->sess_count));
}

/* Try to acquire dialog's mutex, but bail out if mutex can not be
 * acquired immediately.
 */
PJ_DEF(pj_status_t) pjsip_dlg_try_inc_lock(pjsip_dialog *dlg)
{
    pj_status_t status;

    PJ_LOG(6,(dlg->obj_name,"Entering pjsip_dlg_try_inc_lock(), sess_count=%d", 
	      dlg->sess_count));

    status = pj_mutex_trylock(dlg->mutex_);
    if (status != PJ_SUCCESS) {
	PJ_LOG(6,(dlg->obj_name, "pjsip_dlg_try_inc_lock() failed"));
	return status;
    }

    dlg->sess_count++;

    PJ_LOG(6,(dlg->obj_name, "Leaving pjsip_dlg_try_inc_lock(), sess_count=%d", 
	      dlg->sess_count));

    return PJ_SUCCESS;
}


/*
 * Unlock dialog and decrement session counter.
 * It may delete the dialog!
 */
PJ_DEF(void) pjsip_dlg_dec_lock(pjsip_dialog *dlg)
{
    PJ_ASSERT_ON_FAIL(dlg!=NULL, return);

    PJ_LOG(6,(dlg->obj_name, "Entering pjsip_dlg_dec_lock(), sess_count=%d", 
	      dlg->sess_count));

    pj_assert(dlg->sess_count > 0);
    --dlg->sess_count;

    if (dlg->sess_count==0 && dlg->tsx_count==0) {
	pj_mutex_unlock(dlg->mutex_);
	pj_mutex_lock(dlg->mutex_);
	unregister_and_destroy_dialog(dlg);
    } else {
	pj_mutex_unlock(dlg->mutex_);
    }

    PJ_LOG(6,(THIS_FILE, "Leaving pjsip_dlg_dec_lock() (dlg=%p)", dlg));
}



/*
 * Decrement session counter.
 */
PJ_DEF(pj_status_t) pjsip_dlg_dec_session( pjsip_dialog *dlg,
					   pjsip_module *mod)
{
    PJ_ASSERT_RETURN(dlg, PJ_EINVAL);

    pj_log_push_indent();

    PJ_LOG(5,(dlg->obj_name, "Session count dec to %d by %.*s",
	      dlg->sess_count-1, (int)mod->name.slen, mod->name.ptr));

    pjsip_dlg_inc_lock(dlg);
    --dlg->sess_count;
    pjsip_dlg_dec_lock(dlg);

    pj_log_pop_indent();
    return PJ_SUCCESS;
}

/*
 * Check if the module is registered as a usage
 */
PJ_DEF(pj_bool_t) pjsip_dlg_has_usage( pjsip_dialog *dlg,
					  pjsip_module *mod)
{
    unsigned index;
    pj_bool_t found = PJ_FALSE;

    pjsip_dlg_inc_lock(dlg);
    for (index=0; index<dlg->usage_cnt; ++index) {
    	if (dlg->usage[index] == mod) {
    	    found = PJ_TRUE;
    	    break;
    	}
    }
    pjsip_dlg_dec_lock(dlg);

    return found;
}

/*
 * Add usage.
 */
PJ_DEF(pj_status_t) pjsip_dlg_add_usage( pjsip_dialog *dlg,
					 pjsip_module *mod,
					 void *mod_data )
{
    unsigned index;

    PJ_ASSERT_RETURN(dlg && mod, PJ_EINVAL);
    PJ_ASSERT_RETURN(mod->id >= 0 && mod->id < PJSIP_MAX_MODULE,
		     PJ_EINVAL);
    PJ_ASSERT_RETURN(dlg->usage_cnt < PJSIP_MAX_MODULE, PJ_EBUG);

    PJ_LOG(5,(dlg->obj_name, 
	      "Module %.*s added as dialog usage, data=%p",
	      (int)mod->name.slen, mod->name.ptr, mod_data));

    pjsip_dlg_inc_lock(dlg);

    /* Usages are sorted on priority, lowest number first.
     * Find position to put the new module, also makes sure that
     * this module has not been registered before.
     */
    for (index=0; index<dlg->usage_cnt; ++index) {
	if (dlg->usage[index] == mod) {
	    /* Module may be registered more than once in the same dialog.
	     * For example, when call transfer fails, application may retry
	     * call transfer on the same dialog.
	     * So return PJ_SUCCESS here.
	     */
	    PJ_LOG(4,(dlg->obj_name, 
		      "Module %.*s already registered as dialog usage, "
		      "updating the data %p",
		      (int)mod->name.slen, mod->name.ptr, mod_data));
	    dlg->mod_data[mod->id] = mod_data;

	    pjsip_dlg_dec_lock(dlg);
	    return PJ_SUCCESS;

	    //pj_assert(!"This module is already registered");
	    //pjsip_dlg_dec_lock(dlg);
	    //return PJSIP_ETYPEEXISTS;
	}

	if (dlg->usage[index]->priority > mod->priority)
	    break;
    }

    /* index holds position to put the module.
     * Insert module at this index.
     */
    pj_array_insert(dlg->usage, sizeof(dlg->usage[0]), dlg->usage_cnt,
		    index, &mod);
    
    /* Set module data. */
    dlg->mod_data[mod->id] = mod_data;

    /* Increment count. */
    ++dlg->usage_cnt;

    pjsip_dlg_dec_lock(dlg);

    return PJ_SUCCESS;
}


/*
 * Attach module specific data to the dialog. Application can also set 
 * the value directly by accessing dlg->mod_data[module_id].
 */
PJ_DEF(pj_status_t) pjsip_dlg_set_mod_data( pjsip_dialog *dlg,
					    int mod_id,
					    void *data )
{
    PJ_ASSERT_RETURN(dlg, PJ_EINVAL);
    PJ_ASSERT_RETURN(mod_id >= 0 && mod_id < PJSIP_MAX_MODULE,
		     PJ_EINVAL);
    dlg->mod_data[mod_id] = data;
    return PJ_SUCCESS;
}

/**
 * Get module specific data previously attached to the dialog. Application
 * can also get value directly by accessing dlg->mod_data[module_id].
 */
PJ_DEF(void*) pjsip_dlg_get_mod_data( pjsip_dialog *dlg,
				      int mod_id)
{
    PJ_ASSERT_RETURN(dlg, NULL);
    PJ_ASSERT_RETURN(mod_id >= 0 && mod_id < PJSIP_MAX_MODULE,
		     NULL);
    return dlg->mod_data[mod_id];
}


/*
 * Create a new request within dialog (i.e. after the dialog session has been
 * established). The construction of such requests follows the rule in 
 * RFC3261 section 12.2.1.
 */
static pj_status_t dlg_create_request_throw( pjsip_dialog *dlg,
					     const pjsip_method *method,
					     int cseq,
					     pjsip_tx_data **p_tdata )
{
    pjsip_tx_data *tdata;
    pjsip_contact_hdr *contact;
    pjsip_route_hdr *route, *end_list;
    pj_status_t status;

    /* Contact Header field.
     * Contact can only be present in requests that establish dialog (in the 
     * core SIP spec, only INVITE).
     */
    if (pjsip_method_creates_dialog(method))
	contact = dlg->local.contact;
    else
	contact = NULL;

    /*
     * Create the request by cloning from the headers in the
     * dialog.
     */
    status = pjsip_endpt_create_request_from_hdr(dlg->endpt,
						 method,
						 dlg->target,
						 dlg->local.info,
						 dlg->remote.info,
						 contact,
						 dlg->call_id,
						 cseq,
						 NULL,
						 &tdata);
    if (status != PJ_SUCCESS)
	return status;

    /* Just copy dialog route-set to Route header. 
     * The transaction will do the processing as specified in Section 12.2.1
     * of RFC 3261 in function tsx_process_route() in sip_transaction.c.
     */
    route = dlg->route_set.next;
    end_list = &dlg->route_set;
    for (; route != end_list; route = route->next ) {
	pjsip_route_hdr *r;
	r = (pjsip_route_hdr*) pjsip_hdr_shallow_clone( tdata->pool, route );
	pjsip_routing_hdr_set_route(r);
	pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)r);
    }

    /* Copy authorization headers, if request is not ACK or CANCEL. */
    if (method->id != PJSIP_ACK_METHOD && method->id != PJSIP_CANCEL_METHOD) {
	status = pjsip_auth_clt_init_req( &dlg->auth_sess, tdata );
	if (status != PJ_SUCCESS)
	    return status;
    }

    /* Done. */
    *p_tdata = tdata;

    return PJ_SUCCESS;
}



/*
 * Create outgoing request.
 */
PJ_DEF(pj_status_t) pjsip_dlg_create_request( pjsip_dialog *dlg,
					      const pjsip_method *method,
					      int cseq,
					      pjsip_tx_data **p_tdata)
{
    pj_status_t status;
    pjsip_tx_data *tdata = NULL;
    PJ_USE_EXCEPTION;

    PJ_ASSERT_RETURN(dlg && method && p_tdata, PJ_EINVAL);

    /* Lock dialog. */
    pjsip_dlg_inc_lock(dlg);

    /* Use outgoing CSeq and increment it by one. */
    if (cseq < 0)
	cseq = dlg->local.cseq + 1;

    /* Keep compiler happy */
    status = PJ_EBUG;

    /* Create the request. */
    PJ_TRY {
	status = dlg_create_request_throw(dlg, method, cseq, &tdata);
    }
    PJ_CATCH_ANY {
	status = PJ_ENOMEM;
    }
    PJ_END;

    /* Failed! Delete transmit data. */
    if (status != PJ_SUCCESS && tdata) {
	pjsip_tx_data_dec_ref( tdata );
	tdata = NULL;
    }

    /* Unlock dialog. */
    pjsip_dlg_dec_lock(dlg);

    *p_tdata = tdata;

    return status;
}


/*
 * Send request statefully, and update dialog'c CSeq.
 */
PJ_DEF(pj_status_t) pjsip_dlg_send_request( pjsip_dialog *dlg,
					    pjsip_tx_data *tdata,
					    int mod_data_id,
					    void *mod_data)
{
    pjsip_transaction *tsx;
    pjsip_msg *msg = tdata->msg;
    pj_status_t status;

    /* Check arguments. */
    PJ_ASSERT_RETURN(dlg && tdata && tdata->msg, PJ_EINVAL);
    PJ_ASSERT_RETURN(tdata->msg->type == PJSIP_REQUEST_MSG,
		     PJSIP_ENOTREQUESTMSG);

    pj_log_push_indent();
    PJ_LOG(5,(dlg->obj_name, "Sending %s",
	      pjsip_tx_data_get_info(tdata)));

    /* Lock and increment session */
    pjsip_dlg_inc_lock(dlg);

    /* If via_addr is set, use this address for the Via header. */
    if (dlg->via_addr.host.slen > 0) {
        tdata->via_addr = dlg->via_addr;
        tdata->via_tp = dlg->via_tp;
    }

    /* Update dialog's CSeq and message's CSeq if request is not
     * ACK nor CANCEL.
     */
    if (msg->line.req.method.id != PJSIP_CANCEL_METHOD &&
	msg->line.req.method.id != PJSIP_ACK_METHOD) 
    {
	pjsip_cseq_hdr *ch;
	
	ch = PJSIP_MSG_CSEQ_HDR(msg);
	PJ_ASSERT_RETURN(ch!=NULL, PJ_EBUG);

	ch->cseq = dlg->local.cseq++;

	/* Force the whole message to be re-printed. */
	pjsip_tx_data_invalidate_msg( tdata );
    }

    /* Create a new transaction if method is not ACK.
     * The transaction user is the user agent module.
     */
    if (msg->line.req.method.id != PJSIP_ACK_METHOD) {
	int tsx_count;

	status = pjsip_tsx_create_uac(dlg->ua, tdata, &tsx);
	if (status != PJ_SUCCESS)
	    goto on_error;

	/* Set transport selector */
	status = pjsip_tsx_set_transport(tsx, &dlg->tp_sel);
	pj_assert(status == PJ_SUCCESS);

	/* Attach this dialog to the transaction, so that user agent
	 * will dispatch events to this dialog.
	 */
	tsx->mod_data[dlg->ua->id] = dlg;

	/* Copy optional caller's mod_data, if present */
	if (mod_data_id >= 0 && mod_data_id < PJSIP_MAX_MODULE)
	    tsx->mod_data[mod_data_id] = mod_data;

	/* Increment transaction counter. */
	tsx_count = ++dlg->tsx_count;

	/* Send the message. */
	status = pjsip_tsx_send_msg(tsx, tdata);
	if (status != PJ_SUCCESS) {
	    if (dlg->tsx_count == tsx_count)
		pjsip_tsx_terminate(tsx, tsx->status_code);
	    goto on_error;
	}

    } else {
	/* Set transport selector */
	pjsip_tx_data_set_transport(tdata, &dlg->tp_sel);

	/* Send request */
	status = pjsip_endpt_send_request_stateless(dlg->endpt, tdata, 
						    NULL, NULL);
	if (status != PJ_SUCCESS)
	    goto on_error;

    }

    /* Unlock dialog, may destroy dialog. */
    pjsip_dlg_dec_lock(dlg);
    pj_log_pop_indent();
    return PJ_SUCCESS;

on_error:
    /* Unlock dialog, may destroy dialog. */
    pjsip_dlg_dec_lock(dlg);
   
    /* Whatever happen delete the message. */
    pjsip_tx_data_dec_ref( tdata );
    pj_log_pop_indent();
    return status;
}

/* Add standard headers for certain types of response */
static void dlg_beautify_response(pjsip_dialog *dlg,
				  pj_bool_t add_headers,
				  int st_code,
				  pjsip_tx_data *tdata)
{
    pjsip_cseq_hdr *cseq;
    int st_class;
    const pjsip_hdr *c_hdr;
    pjsip_hdr *hdr;

    cseq = PJSIP_MSG_CSEQ_HDR(tdata->msg);
    pj_assert(cseq != NULL);

    st_class = st_code / 100;

    /* Contact, Allow, Supported header. */
    if (add_headers && pjsip_method_creates_dialog(&cseq->method)) {
	/* Add Contact header for 1xx, 2xx, 3xx and 485 response. */
	if (st_class==2 || st_class==3 || (st_class==1 && st_code != 100) ||
	    st_code==485) 
	{
	    /* Add contact header only if one is not present. */
	    if (pjsip_msg_find_hdr(tdata->msg, PJSIP_H_CONTACT, NULL) == 0 &&
		pjsip_msg_find_hdr_by_name(tdata->msg, &HCONTACT, NULL) == 0) 
	    {
		hdr = (pjsip_hdr*) pjsip_hdr_clone(tdata->pool, 
						   dlg->local.contact);
		pjsip_msg_add_hdr(tdata->msg, hdr);
	    }
	}

	/* Add Allow header in 18x, 2xx and 405 response. */
	if ((((st_code/10==18 || st_class==2) && dlg->add_allow)
	     || st_code==405) &&
	    pjsip_msg_find_hdr(tdata->msg, PJSIP_H_ALLOW, NULL)==NULL) 
	{
	    c_hdr = pjsip_endpt_get_capability(dlg->endpt,
					       PJSIP_H_ALLOW, NULL);
	    if (c_hdr) {
		hdr = (pjsip_hdr*) pjsip_hdr_clone(tdata->pool, c_hdr);
		pjsip_msg_add_hdr(tdata->msg, hdr);
	    }
	}

	/* Add Supported header in 2xx response. */
	if (st_class==2 && 
	    pjsip_msg_find_hdr(tdata->msg, PJSIP_H_SUPPORTED, NULL)==NULL) 
	{
	    c_hdr = pjsip_endpt_get_capability(dlg->endpt,
					       PJSIP_H_SUPPORTED, NULL);
	    if (c_hdr) {
		hdr = (pjsip_hdr*) pjsip_hdr_clone(tdata->pool, c_hdr);
		pjsip_msg_add_hdr(tdata->msg, hdr);
	    }
	}

    }

    /* Add To tag in all responses except 100 */
    if (st_code != 100) {
	pjsip_to_hdr *to;

	to = PJSIP_MSG_TO_HDR(tdata->msg);
	pj_assert(to != NULL);

	to->tag = dlg->local.info->tag;

	if (dlg->state == PJSIP_DIALOG_STATE_NULL)
	    dlg->state = PJSIP_DIALOG_STATE_ESTABLISHED;
    }
}


/*
 * Create response.
 */
PJ_DEF(pj_status_t) pjsip_dlg_create_response(	pjsip_dialog *dlg,
						pjsip_rx_data *rdata,
						int st_code,
						const pj_str_t *st_text,
						pjsip_tx_data **p_tdata)
{
    pj_status_t status;
    pjsip_tx_data *tdata;

    /* Create generic response.
     * This will initialize response's Via, To, From, Call-ID, CSeq
     * and Record-Route headers from the request.
     */
    status = pjsip_endpt_create_response(dlg->endpt,
					 rdata, st_code, st_text, &tdata);
    if (status != PJ_SUCCESS)
	return status;

    /* Lock the dialog. */
    pjsip_dlg_inc_lock(dlg);

    dlg_beautify_response(dlg, PJ_FALSE, st_code, tdata);

    /* Unlock the dialog. */
    pjsip_dlg_dec_lock(dlg);

    /* Done. */
    *p_tdata = tdata;
    return PJ_SUCCESS;
}

/*
 * Modify response.
 */
PJ_DEF(pj_status_t) pjsip_dlg_modify_response(	pjsip_dialog *dlg,
						pjsip_tx_data *tdata,
						int st_code,
						const pj_str_t *st_text)
{
    pjsip_hdr *hdr;

    PJ_ASSERT_RETURN(dlg && tdata && tdata->msg, PJ_EINVAL);
    PJ_ASSERT_RETURN(tdata->msg->type == PJSIP_RESPONSE_MSG,
		     PJSIP_ENOTRESPONSEMSG);
    PJ_ASSERT_RETURN(st_code >= 100 && st_code <= 699, PJ_EINVAL);

    /* Lock and increment session */
    pjsip_dlg_inc_lock(dlg);

    /* Replace status code and reason */
    tdata->msg->line.status.code = st_code;
    if (st_text) {
	pj_strdup(tdata->pool, &tdata->msg->line.status.reason, st_text);
    } else {
	tdata->msg->line.status.reason = *pjsip_get_status_text(st_code);
    }

    /* Remove existing Contact header (without this, when dialog sent 
     * 180 and then 302, the Contact in 302 will not get updated).
     */
    hdr = (pjsip_hdr*) pjsip_msg_find_hdr(tdata->msg, PJSIP_H_CONTACT, NULL);
    if (hdr)
	pj_list_erase(hdr);

    /* Add tag etc. if necessary */
    dlg_beautify_response(dlg, st_code/100 <= 2, st_code, tdata);


    /* Must add reference counter, since tsx_send_msg() will decrement it */
    pjsip_tx_data_add_ref(tdata);

    /* Force to re-print message. */
    pjsip_tx_data_invalidate_msg(tdata);

    /* Unlock dialog and dec session, may destroy dialog. */
    pjsip_dlg_dec_lock(dlg);

    return PJ_SUCCESS;
}

/*
 * Send response statefully.
 */
PJ_DEF(pj_status_t) pjsip_dlg_send_response( pjsip_dialog *dlg,
					     pjsip_transaction *tsx,
					     pjsip_tx_data *tdata)
{
    pj_status_t status;

    /* Sanity check. */
    PJ_ASSERT_RETURN(dlg && tsx && tdata && tdata->msg, PJ_EINVAL);
    PJ_ASSERT_RETURN(tdata->msg->type == PJSIP_RESPONSE_MSG,
		     PJSIP_ENOTRESPONSEMSG);

    /* The transaction must belong to this dialog.  */
    PJ_ASSERT_RETURN(tsx->mod_data[dlg->ua->id] == dlg, PJ_EINVALIDOP);

    pj_log_push_indent();

    PJ_LOG(5,(dlg->obj_name, "Sending %s",
	      pjsip_tx_data_get_info(tdata)));

    /* Check that transaction method and cseq match the response. 
     * This operation is sloooww (search CSeq header twice), that's why
     * we only do it in debug mode.
     */
#if defined(PJ_DEBUG) && PJ_DEBUG!=0
    PJ_ASSERT_RETURN( PJSIP_MSG_CSEQ_HDR(tdata->msg)->cseq == tsx->cseq &&
		      pjsip_method_cmp(&PJSIP_MSG_CSEQ_HDR(tdata->msg)->method, 
				       &tsx->method)==0,
		      PJ_EINVALIDOP);
#endif

    /* Must acquire dialog first, to prevent deadlock */
    pjsip_dlg_inc_lock(dlg);

    /* Last chance to add mandatory headers before the response is
     * sent.
     */
    dlg_beautify_response(dlg, PJ_TRUE, tdata->msg->line.status.code, tdata);

    /* If the dialog is locked to transport, make sure that transaction
     * is locked to the same transport too.
     */
    if (dlg->tp_sel.type != tsx->tp_sel.type ||
	dlg->tp_sel.u.ptr != tsx->tp_sel.u.ptr)
    {
	status = pjsip_tsx_set_transport(tsx, &dlg->tp_sel);
	pj_assert(status == PJ_SUCCESS);
    }

    /* Ask transaction to send the response */
    status = pjsip_tsx_send_msg(tsx, tdata);

    /* This function must decrement transmit data request counter 
     * regardless of the operation status. The transaction only
     * decrements the counter if the operation is successful.
     */
    if (status != PJ_SUCCESS) {
	pjsip_tx_data_dec_ref(tdata);
    }

    pjsip_dlg_dec_lock(dlg);
    pj_log_pop_indent();

    return status;
}


/*
 * Combo function to create and send response statefully.
 */
PJ_DEF(pj_status_t) pjsip_dlg_respond(  pjsip_dialog *dlg,
					pjsip_rx_data *rdata,
					int st_code,
					const pj_str_t *st_text,
					const pjsip_hdr *hdr_list,
					const pjsip_msg_body *body )
{
    pj_status_t status;
    pjsip_tx_data *tdata;

    /* Sanity check. */
    PJ_ASSERT_RETURN(dlg && rdata && rdata->msg_info.msg, PJ_EINVAL);
    PJ_ASSERT_RETURN(rdata->msg_info.msg->type == PJSIP_REQUEST_MSG,
		     PJSIP_ENOTREQUESTMSG);

    /* The transaction must belong to this dialog.  */
    PJ_ASSERT_RETURN(pjsip_rdata_get_tsx(rdata) &&
		     pjsip_rdata_get_tsx(rdata)->mod_data[dlg->ua->id] == dlg,
		     PJ_EINVALIDOP);

    /* Create the response. */
    status = pjsip_dlg_create_response(dlg, rdata, st_code, st_text, &tdata);
    if (status != PJ_SUCCESS)
	return status;

    /* Add additional header, if any */
    if (hdr_list) {
	const pjsip_hdr *hdr;

	hdr = hdr_list->next;
	while (hdr != hdr_list) {
	    pjsip_msg_add_hdr(tdata->msg,
			      (pjsip_hdr*)pjsip_hdr_clone(tdata->pool, hdr));
	    hdr = hdr->next;
	}
    }

    /* Add the message body, if any. */
    if (body) {
	tdata->msg->body = pjsip_msg_body_clone( tdata->pool, body);
    }

    /* Send the response. */
    return pjsip_dlg_send_response(dlg, pjsip_rdata_get_tsx(rdata), tdata);
}


/* This function is called by user agent upon receiving incoming request
 * message.
 */
void pjsip_dlg_on_rx_request( pjsip_dialog *dlg, pjsip_rx_data *rdata )
{
    pj_status_t status;
    pjsip_transaction *tsx = NULL;
    pj_bool_t processed = PJ_FALSE;
    unsigned i;

    PJ_LOG(5,(dlg->obj_name, "Received %s",
	      pjsip_rx_data_get_info(rdata)));
    pj_log_push_indent();

    /* Lock dialog and increment session. */
    pjsip_dlg_inc_lock(dlg);

    /* Check CSeq */
    if (rdata->msg_info.cseq->cseq <= dlg->remote.cseq &&
	rdata->msg_info.msg->line.req.method.id != PJSIP_ACK_METHOD &&
	rdata->msg_info.msg->line.req.method.id != PJSIP_CANCEL_METHOD) 
    {
	/* Invalid CSeq.
	 * Respond statelessly with 500 (Internal Server Error)
	 */
	pj_str_t warn_text;

	/* Unlock dialog and dec session, may destroy dialog. */
	pjsip_dlg_dec_lock(dlg);

	pj_assert(pjsip_rdata_get_tsx(rdata) == NULL);
	warn_text = pj_str("Invalid CSeq");
	pjsip_endpt_respond_stateless(dlg->endpt,
				      rdata, 500, &warn_text, NULL, NULL);
	pj_log_pop_indent();
	return;
    }

    /* Update CSeq. */
    dlg->remote.cseq = rdata->msg_info.cseq->cseq;

    /* Update To tag if necessary.
     * This only happens if UAS sends a new request before answering
     * our request (e.g. UAS sends NOTIFY before answering our
     * SUBSCRIBE request).
     */
    if (dlg->remote.info->tag.slen == 0) {
	pj_strdup(dlg->pool, &dlg->remote.info->tag,
		  &rdata->msg_info.from->tag);
    }

    /* Create UAS transaction for this request. */
    if (pjsip_rdata_get_tsx(rdata) == NULL && 
	rdata->msg_info.msg->line.req.method.id != PJSIP_ACK_METHOD) 
    {
	status = pjsip_tsx_create_uas(dlg->ua, rdata, &tsx);
	if (status != PJ_SUCCESS) {
	    /* Once case for this is when re-INVITE contains same
	     * Via branch value as previous INVITE (ticket #965).
	     */
	    char errmsg[PJ_ERR_MSG_SIZE];
	    pj_str_t reason;

	    reason = pj_strerror(status, errmsg, sizeof(errmsg));
	    pjsip_endpt_respond_stateless(dlg->endpt, rdata, 500, &reason,
					  NULL, NULL);
	    goto on_return;
	}

	/* Put this dialog in the transaction data. */
	tsx->mod_data[dlg->ua->id] = dlg;

	/* Add transaction count. */
	++dlg->tsx_count;
    }

    /* Update the target URI if this is a target refresh request.
     * We have passed the basic checking for the request, I think we
     * should update the target URI regardless of whether the request
     * is accepted or not (e.g. when re-INVITE is answered with 488,
     * we would still need to update the target URI, otherwise our
     * target URI would be wrong, wouldn't it).
     */
    if (pjsip_method_creates_dialog(&rdata->msg_info.cseq->method)) {
	pjsip_contact_hdr *contact;

	contact = (pjsip_contact_hdr*)
		  pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT, 
				     NULL);
	if (contact && contact->uri &&
	    (dlg->remote.contact==NULL ||
 	     pjsip_uri_cmp(PJSIP_URI_IN_REQ_URI,
			   dlg->remote.contact->uri,
			   contact->uri)))
	{
	    dlg->remote.contact = (pjsip_contact_hdr*) 
	    			  pjsip_hdr_clone(dlg->pool, contact);
	    dlg->target = dlg->remote.contact->uri;
	}
    }

    /* Report the request to dialog usages. */
    for (i=0; i<dlg->usage_cnt; ++i) {

	if (!dlg->usage[i]->on_rx_request)
	    continue;

	processed = (*dlg->usage[i]->on_rx_request)(rdata);

	if (processed)
	    break;
    }

    /* Feed the first request to the transaction. */
    if (tsx)
	pjsip_tsx_recv_msg(tsx, rdata);

    /* If no dialog usages has claimed the processing of the transaction,
     * and if transaction has not sent final response, respond with
     * 500/Internal Server Error.
     */
    if (!processed && tsx && tsx->status_code < 200) {
	pjsip_tx_data *tdata;
	const pj_str_t reason = { "Unhandled by dialog usages", 26};

	PJ_LOG(4,(tsx->obj_name, "%s was unhandled by "
				 "dialog usages, sending 500 response",
				 pjsip_rx_data_get_info(rdata)));

	status = pjsip_dlg_create_response(dlg, rdata, 500, &reason, &tdata);
	if (status == PJ_SUCCESS) {
	    status = pjsip_dlg_send_response(dlg, tsx, tdata);
	}
    }

on_return:
    /* Unlock dialog and dec session, may destroy dialog. */
    pjsip_dlg_dec_lock(dlg);
    pj_log_pop_indent();
}

/* Update route-set from incoming message */
static void dlg_update_routeset(pjsip_dialog *dlg, const pjsip_rx_data *rdata)
{
    const pjsip_hdr *hdr, *end_hdr;
    pj_int32_t msg_cseq;
    const pjsip_msg *msg;

    msg = rdata->msg_info.msg;
    msg_cseq = rdata->msg_info.cseq->cseq;

    /* Ignore if route set has been frozen */
    if (dlg->route_set_frozen)
	return;

    /* Only update route set if this message belongs to the same
     * transaction as the initial transaction that establishes dialog.
     */
    if (dlg->role == PJSIP_ROLE_UAC) {

	/* Ignore subsequent request from remote */
	if (msg->type != PJSIP_RESPONSE_MSG)
	    return;

	/* Ignore subsequent responses with higher CSeq than initial CSeq.
	 * Unfortunately this would be broken when the first request is 
	 * challenged!
	 */
	//if (msg_cseq != dlg->local.first_cseq)
	//    return;

    } else {

	/* For callee dialog, route set should have been set by initial
	 * request and it will have been rejected by dlg->route_set_frozen
	 * check above.
	 */
	pj_assert(!"Should not happen");

    }

    /* Based on the checks above, we should only get response message here */
    pj_assert(msg->type == PJSIP_RESPONSE_MSG);

    /* Ignore if this is not 1xx or 2xx response */
    if (msg->line.status.code >= 300)
	return;

    /* Reset route set */
    pj_list_init(&dlg->route_set);

    /* Update route set */
    end_hdr = &msg->hdr;
    for (hdr=msg->hdr.prev; hdr!=end_hdr; hdr=hdr->prev) {
	if (hdr->type == PJSIP_H_RECORD_ROUTE) {
	    pjsip_route_hdr *r;
	    r = (pjsip_route_hdr*) pjsip_hdr_clone(dlg->pool, hdr);
	    pjsip_routing_hdr_set_route(r);
	    pj_list_push_back(&dlg->route_set, r);
	}
    }

    PJ_LOG(5,(dlg->obj_name, "Route-set updated"));

    /* Freeze the route set only when the route set comes in 2xx response. 
     * If it is in 1xx response, prepare to recompute the route set when 
     * the 2xx response comes in.
     *
     * There is a debate whether route set should be frozen when the dialog
     * is established with reliable provisional response, but I think
     * it is safer to not freeze the route set (thus recompute the route set
     * upon receiving 2xx response). Also RFC 3261 says so in 13.2.2.4.
     *
     * The pjsip_method_creates_dialog() check protects from wrongly 
     * freezing the route set upon receiving 200/OK response for PRACK.
     */
    if (pjsip_method_creates_dialog(&rdata->msg_info.cseq->method) &&
	PJSIP_IS_STATUS_IN_CLASS(msg->line.status.code, 200)) 
    {
	dlg->route_set_frozen = PJ_TRUE;
	PJ_LOG(5,(dlg->obj_name, "Route-set frozen"));
    }
}


/* This function is called by user agent upon receiving incoming response
 * message.
 */
void pjsip_dlg_on_rx_response( pjsip_dialog *dlg, pjsip_rx_data *rdata )
{
    unsigned i;
    int res_code;

    PJ_LOG(5,(dlg->obj_name, "Received %s",
	      pjsip_rx_data_get_info(rdata)));
    pj_log_push_indent();

    /* Lock the dialog and inc session. */
    pjsip_dlg_inc_lock(dlg);

    /* Check that rdata already has dialog in mod_data. */
    pj_assert(pjsip_rdata_get_dlg(rdata) == dlg);

    /* Keep the response's status code */
    res_code = rdata->msg_info.msg->line.status.code;

    /* When we receive response that establishes dialog, update To tag, 
     * route set and dialog target.
     *
     * The second condition of the "if" is a workaround for forking.
     * Originally, the dialog takes the first To tag seen and set it as
     * the remote tag. If the tag in 2xx response is different than this
     * tag, ACK will be sent with wrong To tag and incoming request with
     * this tag will be rejected with 481.
     *
     * The workaround for this is to take the To tag received in the
     * 2xx response and set it as remote tag.
     *
     * New update:
     * We also need to update the dialog for 1xx responses, to handle the
     * case when 100rel is used, otherwise PRACK will be sent to the 
     * wrong target.
     */
    if ((dlg->state == PJSIP_DIALOG_STATE_NULL && 
	 pjsip_method_creates_dialog(&rdata->msg_info.cseq->method) &&
	 (res_code > 100 && res_code < 300) &&
	 rdata->msg_info.to->tag.slen) 
	 ||
	(dlg->role==PJSIP_ROLE_UAC &&
	 !dlg->uac_has_2xx &&
	 res_code > 100 &&
	 res_code/100 <= 2 &&
	 pjsip_method_creates_dialog(&rdata->msg_info.cseq->method) &&
	 pj_stricmp(&dlg->remote.info->tag, &rdata->msg_info.to->tag)))
    {
	pjsip_contact_hdr *contact;

	/* Update remote capability info, when To tags in the dialog remote 
	 * info and the incoming response are different, e.g: first response
	 * with To-tag or forking, apply strict update.
	 */
	pjsip_dlg_update_remote_cap(dlg, rdata->msg_info.msg,
				    pj_stricmp(&dlg->remote.info->tag,
					      &rdata->msg_info.to->tag));

	/* Update To tag. */
	pj_strdup(dlg->pool, &dlg->remote.info->tag, &rdata->msg_info.to->tag);
	/* No need to update remote's tag_hval since its never used. */

	/* RFC 3271 Section 12.1.2:
	 * The route set MUST be set to the list of URIs in the Record-Route
	 * header field from the response, taken in reverse order and 
	 * preserving all URI parameters. If no Record-Route header field 
	 * is present in the response, the route set MUST be set to the 
	 * empty set. This route set, even if empty, overrides any pre-existing
	 * route set for future requests in this dialog.
	 */
	dlg_update_routeset(dlg, rdata);

	/* The remote target MUST be set to the URI from the Contact header 
	 * field of the response.
	 */
	contact = (pjsip_contact_hdr*)
		  pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT, 
				     NULL);
	if (contact && contact->uri &&
	    (dlg->remote.contact==NULL ||
	     pjsip_uri_cmp(PJSIP_URI_IN_REQ_URI,
			   dlg->remote.contact->uri,
			   contact->uri)))
	{
	    dlg->remote.contact = (pjsip_contact_hdr*) 
	    			  pjsip_hdr_clone(dlg->pool, contact);
	    dlg->target = dlg->remote.contact->uri;
	}

	dlg->state = PJSIP_DIALOG_STATE_ESTABLISHED;

	/* Prevent dialog from being updated just in case more 2xx
	 * gets through this dialog (it shouldn't happen).
	 */
	if (dlg->role==PJSIP_ROLE_UAC && !dlg->uac_has_2xx && 
	    res_code/100==2) 
	{
	    dlg->uac_has_2xx = PJ_TRUE;
	}
    }

    /* Update remote target (again) when receiving 2xx response messages
     * that's defined as target refresh. 
     *
     * Also upon receiving 2xx response, recheck again the route set.
     * This is for compatibility with RFC 2543, as described in Section
     * 13.2.2.4 of RFC 3261:

	If the dialog identifier in the 2xx response matches the dialog
	identifier of an existing dialog, the dialog MUST be transitioned to
	the "confirmed" state, and the route set for the dialog MUST be
	recomputed based on the 2xx response using the procedures of Section
	12.2.1.2. 

	Note that the only piece of state that is recomputed is the route
	set.  Other pieces of state such as the highest sequence numbers
	(remote and local) sent within the dialog are not recomputed.  The
	route set only is recomputed for backwards compatibility.  RFC
	2543 did not mandate mirroring of the Record-Route header field in
	a 1xx, only 2xx.
     */
    if (pjsip_method_creates_dialog(&rdata->msg_info.cseq->method) &&
	res_code/100 == 2)
    {
	pjsip_contact_hdr *contact;

	contact = (pjsip_contact_hdr*) pjsip_msg_find_hdr(rdata->msg_info.msg,
							  PJSIP_H_CONTACT, 
				     			  NULL);
	if (contact && contact->uri &&
	    (dlg->remote.contact==NULL ||
	     pjsip_uri_cmp(PJSIP_URI_IN_REQ_URI,
			   dlg->remote.contact->uri,
			   contact->uri)))
	{
	    dlg->remote.contact = (pjsip_contact_hdr*) 
	    			  pjsip_hdr_clone(dlg->pool, contact);
	    dlg->target = dlg->remote.contact->uri;
	}

	dlg_update_routeset(dlg, rdata);

	/* Update remote capability info after the first 2xx response
	 * (ticket #1539). Note that the remote capability retrieved here
	 * will be assumed to remain unchanged for the duration of the dialog.
	 */
	if (dlg->role==PJSIP_ROLE_UAC && !dlg->uac_has_2xx) {
	    pjsip_dlg_update_remote_cap(dlg, rdata->msg_info.msg, PJ_FALSE);
	    dlg->uac_has_2xx = PJ_TRUE;
	}
    }

    /* Pass to dialog usages. */
    for (i=0; i<dlg->usage_cnt; ++i) {
	pj_bool_t processed;

	if (!dlg->usage[i]->on_rx_response)
	    continue;

	processed = (*dlg->usage[i]->on_rx_response)(rdata);

	if (processed)
	    break;
    }

    /* Handle the case of forked response, when the application creates
     * the forked dialog but not the invite session. In this case, the
     * forked 200/OK response will be unhandled, and we must send ACK
     * here.
     */
    if (dlg->usage_cnt==0) {
	pj_status_t status;

	if (rdata->msg_info.cseq->method.id==PJSIP_INVITE_METHOD && 
	    rdata->msg_info.msg->line.status.code/100 == 2) 
	{
	    pjsip_tx_data *ack;

	    status = pjsip_dlg_create_request(dlg, &pjsip_ack_method,
					      rdata->msg_info.cseq->cseq,
					      &ack);
	    if (status == PJ_SUCCESS)
		status = pjsip_dlg_send_request(dlg, ack, -1, NULL);
	} else if (rdata->msg_info.msg->line.status.code==401 ||
		   rdata->msg_info.msg->line.status.code==407)
	{
	    pjsip_transaction *tsx = pjsip_rdata_get_tsx(rdata);
	    pjsip_tx_data *tdata;
	    
	    status = pjsip_auth_clt_reinit_req( &dlg->auth_sess, 
						rdata, tsx->last_tx,
						&tdata);
	    
	    if (status == PJ_SUCCESS) {
		/* Re-send request. */
		status = pjsip_dlg_send_request(dlg, tdata, -1, NULL);
	    }
	}
    }

    /* Unhandled response does not necessarily mean error because
       dialog usages may choose to process the transaction state instead.
    if (i==dlg->usage_cnt) {
	PJ_LOG(4,(dlg->obj_name, "%s was not claimed by any dialog usages",
		  pjsip_rx_data_get_info(rdata)));
    }
    */

    /* Unlock dialog and dec session, may destroy dialog. */
    pjsip_dlg_dec_lock(dlg);

    pj_log_pop_indent();
}

/* This function is called by user agent upon receiving transaction
 * state notification.
 */
void pjsip_dlg_on_tsx_state( pjsip_dialog *dlg,
			     pjsip_transaction *tsx,
			     pjsip_event *e )
{
    unsigned i;

    PJ_LOG(5,(dlg->obj_name, "Transaction %s state changed to %s",
	      tsx->obj_name, pjsip_tsx_state_str(tsx->state)));
    pj_log_push_indent();

    /* Lock the dialog and increment session. */
    pjsip_dlg_inc_lock(dlg);

    /* Pass to dialog usages. */
    for (i=0; i<dlg->usage_cnt; ++i) {

	if (!dlg->usage[i]->on_tsx_state)
	    continue;

	(*dlg->usage[i]->on_tsx_state)(tsx, e);
    }


    /* It is possible that the transaction is terminated and this function
     * is called while we're calling on_tsx_state(). So only decrement
     * the tsx_count if we're still attached to the transaction.
     */
    if (tsx->state == PJSIP_TSX_STATE_TERMINATED &&
	tsx->mod_data[dlg->ua->id] == dlg) 
    {
	pj_assert(dlg->tsx_count>0);
	--dlg->tsx_count;
	tsx->mod_data[dlg->ua->id] = NULL;
    }

    /* Unlock dialog and dec session, may destroy dialog. */
    pjsip_dlg_dec_lock(dlg);
    pj_log_pop_indent();
}


/*
 * Check if the specified capability is supported by remote.
 */
PJ_DEF(pjsip_dialog_cap_status) pjsip_dlg_remote_has_cap(
						    pjsip_dialog *dlg,
						    int htype,
						    const pj_str_t *hname,
						    const pj_str_t *token)
{
    const pjsip_generic_array_hdr *hdr;
    pjsip_dialog_cap_status cap_status = PJSIP_DIALOG_CAP_UNSUPPORTED;
    unsigned i;

    PJ_ASSERT_RETURN(dlg && token, PJSIP_DIALOG_CAP_UNKNOWN);

    pjsip_dlg_inc_lock(dlg);

    hdr = (const pjsip_generic_array_hdr*) 
	   pjsip_dlg_get_remote_cap_hdr(dlg, htype, hname);
    if (!hdr) {
	cap_status = PJSIP_DIALOG_CAP_UNKNOWN;
    } else {
	for (i=0; i<hdr->count; ++i) {
	    if (!pj_stricmp(&hdr->values[i], token)) {
		cap_status = PJSIP_DIALOG_CAP_SUPPORTED;
		break;
	    }
	}
    }

    pjsip_dlg_dec_lock(dlg);

    return cap_status;
}


/*
 * Update remote capability of ACCEPT, ALLOW, and SUPPORTED from
 * the received message.
 */
PJ_DEF(pj_status_t) pjsip_dlg_update_remote_cap(pjsip_dialog *dlg,
					        const pjsip_msg *msg,
						pj_bool_t strict)
{
    pjsip_hdr_e htypes[] = 
	{ PJSIP_H_ACCEPT, PJSIP_H_ALLOW, PJSIP_H_SUPPORTED };
    unsigned i;

    PJ_ASSERT_RETURN(dlg && msg, PJ_EINVAL);

    pjsip_dlg_inc_lock(dlg);

    /* Retrieve all specified capability header types */
    for (i = 0; i < PJ_ARRAY_SIZE(htypes); ++i) {
	const pjsip_generic_array_hdr *hdr;
	pj_status_t status;

	/* Find this capability type in the message */
	hdr = (const pjsip_generic_array_hdr*)
	      pjsip_msg_find_hdr(msg, htypes[i], NULL);
	if (!hdr) {
	    /* Not found.
	     * If strict update is specified, remote this capability type
	     * from the capability list.
	     */
	    if (strict)
		pjsip_dlg_remove_remote_cap_hdr(dlg, htypes[i], NULL);
	} else {
	    /* Found, a capability type may be specified in multiple headers,
	     * so combine all the capability tags/values into a temporary
	     * header.
	     */
	    pjsip_generic_array_hdr tmp_hdr;

	    /* Init temporary header */
	    pjsip_generic_array_hdr_init(dlg->pool, &tmp_hdr, NULL);
	    pj_memcpy(&tmp_hdr, hdr, sizeof(pjsip_hdr));

	    while (hdr) {
		unsigned j;

		/* Append the header content to temporary header */
		for(j=0; j<hdr->count &&
			 tmp_hdr.count<PJSIP_GENERIC_ARRAY_MAX_COUNT; ++j)
		{
		    tmp_hdr.values[tmp_hdr.count++] = hdr->values[j];
		}

		/* Get the next header for this capability */
		hdr = (const pjsip_generic_array_hdr*)
		      pjsip_msg_find_hdr(msg, htypes[i], hdr->next);
	    }

	    /* Save this capability */
	    status = pjsip_dlg_set_remote_cap_hdr(dlg, &tmp_hdr);
	    if (status != PJ_SUCCESS) {
		pjsip_dlg_dec_lock(dlg);
		return status;
	    }
	}
    }

    pjsip_dlg_dec_lock(dlg);

    return PJ_SUCCESS;
}


/*
 * Get the value of the specified capability header field of remote.
 */
PJ_DEF(const pjsip_hdr*) pjsip_dlg_get_remote_cap_hdr(pjsip_dialog *dlg,
						      int htype,
						      const pj_str_t *hname)
{
    pjsip_hdr *hdr;

    /* Check arguments. */
    PJ_ASSERT_RETURN(dlg, NULL);
    PJ_ASSERT_RETURN((htype != PJSIP_H_OTHER) || (hname && hname->slen),
		     NULL);

    pjsip_dlg_inc_lock(dlg);

    hdr = dlg->rem_cap_hdr.next;
    while (hdr != &dlg->rem_cap_hdr) {
	if ((htype != PJSIP_H_OTHER && htype == hdr->type) ||
	    (htype == PJSIP_H_OTHER && pj_stricmp(&hdr->name, hname) == 0))
	{
	    pjsip_dlg_dec_lock(dlg);
	    return hdr;
	}
	hdr = hdr->next;
    }

    pjsip_dlg_dec_lock(dlg);

    return NULL;
}


/*
 * Set remote capability header from a SIP header containing array
 * of capability tags/values.
 */
PJ_DEF(pj_status_t) pjsip_dlg_set_remote_cap_hdr(
				    pjsip_dialog *dlg,
				    const pjsip_generic_array_hdr *cap_hdr)
{
    pjsip_generic_array_hdr *hdr;

    /* Check arguments. */
    PJ_ASSERT_RETURN(dlg && cap_hdr, PJ_EINVAL);

    pjsip_dlg_inc_lock(dlg);

    /* Find the header. */
    hdr = (pjsip_generic_array_hdr*)
	  pjsip_dlg_get_remote_cap_hdr(dlg, cap_hdr->type, &cap_hdr->name);

    /* Quick compare if the capability is up to date */
    if (hdr && hdr->count == cap_hdr->count) {
	unsigned i;
	pj_bool_t uptodate = PJ_TRUE;

	for (i=0; i<hdr->count; ++i) {
	    if (pj_stricmp(&hdr->values[i], &cap_hdr->values[i]))
		uptodate = PJ_FALSE;
	}

	/* Capability is up to date, just return PJ_SUCCESS */
	if (uptodate) {
	    pjsip_dlg_dec_lock(dlg);
	    return PJ_SUCCESS;
	}
    }

    /* Remove existing capability header if any */
    if (hdr)
	pj_list_erase(hdr);

    /* Add the new capability header */
    hdr = (pjsip_generic_array_hdr*) pjsip_hdr_clone(dlg->pool, cap_hdr);
    hdr->type = cap_hdr->type;
    pj_strdup(dlg->pool, &hdr->name, &cap_hdr->name);
    pj_list_push_back(&dlg->rem_cap_hdr, hdr);

    pjsip_dlg_dec_lock(dlg);

    /* Done. */
    return PJ_SUCCESS;
}

/*
 * Remove a remote capability header.
 */
PJ_DEF(pj_status_t) pjsip_dlg_remove_remote_cap_hdr(pjsip_dialog *dlg,
						    int htype,
						    const pj_str_t *hname)
{
    pjsip_generic_array_hdr *hdr;

    /* Check arguments. */
    PJ_ASSERT_RETURN(dlg, PJ_EINVAL);
    PJ_ASSERT_RETURN((htype != PJSIP_H_OTHER) || (hname && hname->slen),
		     PJ_EINVAL);

    pjsip_dlg_inc_lock(dlg);

    hdr = (pjsip_generic_array_hdr*)
	  pjsip_dlg_get_remote_cap_hdr(dlg, htype, hname);
    if (!hdr) {
	pjsip_dlg_dec_lock(dlg);
	return PJ_ENOTFOUND;
    }

    pj_list_erase(hdr);

    pjsip_dlg_dec_lock(dlg);

    return PJ_SUCCESS;
}
