/* $Id$ */
/* 
 * Copyright (C) 2003-2006 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_mod_ua/sip_dialog.h>
#include <pjsip_mod_ua/sip_ua.h>
#include <pjsip_mod_ua/sip_ua_private.h>
#include <pjsip/sip_transport.h>
#include <pjsip/sip_transaction.h>
#include <pjsip/sip_types.h>
#include <pjsip/sip_endpoint.h>
#include <pjsip/sip_uri.h>
#include <pjsip/sip_util.h>
#include <pjsip/sip_module.h>
#include <pjsip/sip_event.h>
#include <pjsip/sip_parser.h>
#include <pj/string.h>
#include <pj/log.h>
#include <pj/os.h>
#include <pj/guid.h>
#include <pj/except.h>
#include <pj/pool.h>

/* TLS to keep dialog lock record (initialized by UA) */
int pjsip_dlg_lock_tls_id;

struct dialog_lock_data
{
    struct dialog_lock_data *prev;
    pjsip_dlg	    *dlg;
    int			     is_alive;
};

/*
 * Static function prototypes.
 */
static void dlg_create_request_throw( pjsip_tx_data **p_tdata,
				      pjsip_dlg *dlg,
				      const pjsip_method *method,
				      int cseq );
static int  dlg_on_all_state_pre(  pjsip_dlg *dlg, 
				   pjsip_transaction *tsx,
				   pjsip_event *event);
static int  dlg_on_all_state_post( pjsip_dlg *dlg, 
				   pjsip_transaction *tsx,
				   pjsip_event *event);
static int  dlg_on_state_null( pjsip_dlg *dlg, 
			       pjsip_transaction *tsx,
			       pjsip_event *event);
static int  dlg_on_state_incoming( pjsip_dlg *dlg, 
				   pjsip_transaction *tsx,
				   pjsip_event *event);
static int  dlg_on_state_calling( pjsip_dlg *dlg, 
				  pjsip_transaction *tsx,
				  pjsip_event *event);
static int  dlg_on_state_proceeding( pjsip_dlg *dlg, 
				     pjsip_transaction *tsx,
				     pjsip_event *event);
static int  dlg_on_state_proceeding_caller( pjsip_dlg *dlg, 
					    pjsip_transaction *tsx,
					    pjsip_event *event);
static int  dlg_on_state_proceeding_callee( pjsip_dlg *dlg, 
					    pjsip_transaction *tsx,
					    pjsip_event *event);
static int  dlg_on_state_connecting( pjsip_dlg *dlg, 
				     pjsip_transaction *tsx,
				     pjsip_event *event);
static int  dlg_on_state_established( pjsip_dlg *dlg, 
				      pjsip_transaction *tsx,
				      pjsip_event *event);
static int  dlg_on_state_disconnected( pjsip_dlg *dlg, 
				       pjsip_transaction *tsx,
				       pjsip_event *event);
static int  dlg_on_state_terminated( pjsip_dlg *dlg, 
				     pjsip_transaction *tsx,
				     pjsip_event *event);

/*
 * Dialog state handlers.
 */
static int  (*dlg_state_handlers[])(struct pjsip_dlg *, pjsip_transaction *,
				    pjsip_event *) = 
{
    &dlg_on_state_null,
    &dlg_on_state_incoming,
    &dlg_on_state_calling,
    &dlg_on_state_proceeding,
    &dlg_on_state_connecting,
    &dlg_on_state_established,
    &dlg_on_state_disconnected,
    &dlg_on_state_terminated,
};

/*
 * Dialog state names.
 */
static const char* dlg_state_names[] = 
{
    "STATE_NULL",
    "STATE_INCOMING",
    "STATE_CALLING",
    "STATE_PROCEEDING",
    "STATE_CONNECTING",
    "STATE_ESTABLISHED",
    "STATE_DISCONNECTED",
    "STATE_TERMINATED",
};


/*
 * Get the dialog string state, normally for logging purpose.
 */
const char *pjsip_dlg_state_str(pjsip_dlg_state_e state)
{
    return dlg_state_names[state];
}

/* Lock dialog mutex. */
static void lock_dialog(pjsip_dlg *dlg, struct dialog_lock_data *lck)
{
    struct dialog_lock_data *prev;

    pj_mutex_lock(dlg->mutex);
    prev = pj_thread_local_get(pjsip_dlg_lock_tls_id);
    lck->prev = prev;
    lck->dlg = dlg;
    lck->is_alive = 1;
    pj_thread_local_set(pjsip_dlg_lock_tls_id, lck);
}

/* Carefully unlock dialog mutex, protect against situation when the dialog
 * has already been destroyed.
 */
static pj_status_t unlock_dialog(pjsip_dlg *dlg, struct dialog_lock_data *lck)
{
    pj_assert(pj_thread_local_get(pjsip_dlg_lock_tls_id) == lck);
    pj_assert(dlg == lck->dlg);

    pj_thread_local_set(pjsip_dlg_lock_tls_id, lck->prev);
    if (lck->is_alive)
	pj_mutex_unlock(dlg->mutex);

    return lck->is_alive ? 0 : -1;
}

/*
 * This is called by dialog's FSM to change dialog's state.
 */
static void dlg_set_state( pjsip_dlg *dlg, pjsip_dlg_state_e state,
			   pjsip_event *event)
{
    PJ_UNUSED_ARG(event);

    PJ_LOG(4, (dlg->obj_name, "State %s-->%s (ev=%s, src=%s, data=%p)", 
	       pjsip_dlg_state_str(dlg->state), pjsip_dlg_state_str(state),
	       event ? pjsip_event_str(event->type) : "", 
	       event ? pjsip_event_str(event->src_type) : "",
	       event ? event->src.data : NULL));

    dlg->state = state;
    dlg->handle_tsx_event = dlg_state_handlers[state];
}

/*
 * Invoke dialog's callback.
 * This function is called by dialog's FSM, and interpret the event and call
 * the corresponding callback registered by application.
 */
static void dlg_call_dlg_callback( pjsip_dlg *dlg, pjsip_dlg_event_e dlg_event,
				   pjsip_event *event )
{
    pjsip_dlg_callback *cb = dlg->ua->dlg_cb;
    if (!cb) {
	PJ_LOG(4,(dlg->obj_name, "Can not call callback (none registered)."));
	return;
    }

    /* Low level event: call the all-events callback. */
    if (cb->on_all_events) {
	(*cb->on_all_events)(dlg, dlg_event, event);
    }

    /* Low level event: call the tx/rx callback if this is a tx/rx event. */
    if (event->type == PJSIP_EVENT_BEFORE_TX && cb->on_before_tx)
    {
	(*cb->on_before_tx)(dlg, event->obj.tsx, event->src.tdata, event->data.long_data);
    }
    else if (event->type == PJSIP_EVENT_TX_MSG && 
	event->src_type == PJSIP_EVENT_TX_MSG && cb->on_tx_msg) 
    {
	(*cb->on_tx_msg)(dlg, event->obj.tsx, event->src.tdata);
    } 
    else if (event->type == PJSIP_EVENT_RX_MSG &&
	     event->src_type == PJSIP_EVENT_RX_MSG && cb->on_rx_msg) {
	(*cb->on_rx_msg)(dlg, event->obj.tsx, event->src.rdata);
    }

    /* Now trigger high level events. 
     * High level event should only occurs when dialog's state has changed,
     * except for on_provisional, which may be called multiple times whenever
     * response message is sent
     */
    if (dlg->state == PJSIP_DIALOG_STATE_PROCEEDING &&
	(event->type== PJSIP_EVENT_TSX_STATE_CHANGED) && 
	event->obj.tsx == dlg->invite_tsx) 
    {
	/* Sent/received provisional responses. */
	if (cb->on_provisional)
	    (*cb->on_provisional)(dlg, event->obj.tsx, event);
    }

    if (dlg_event == PJSIP_DIALOG_EVENT_MID_CALL_REQUEST) {
	if (cb->on_mid_call_events)
	    (*cb->on_mid_call_events)(dlg, event);
	return;
    }

    if (dlg_event != PJSIP_DIALOG_EVENT_STATE_CHANGED)
	return;

    if (dlg->state == PJSIP_DIALOG_STATE_INCOMING) {

	/* New incoming dialog. */
	pj_assert (event->src_type == PJSIP_EVENT_RX_MSG);
	(*cb->on_incoming)(dlg, event->obj.tsx, event->src.rdata);

    } else if (dlg->state == PJSIP_DIALOG_STATE_CALLING) {

	/* Dialog has just sent the first INVITE. */
	if (cb->on_calling) {
	    (*cb->on_calling)(dlg, event->obj.tsx, event->src.tdata);
	}

    } else if (dlg->state == PJSIP_DIALOG_STATE_DISCONNECTED) {

	if (cb->on_disconnected)
	    (*cb->on_disconnected)(dlg, event);

    } else if (dlg->state == PJSIP_DIALOG_STATE_TERMINATED) {

	if (cb->on_terminated)
	    (*cb->on_terminated)(dlg);

	pjsip_ua_destroy_dialog(dlg);

    } else if (dlg->state == PJSIP_DIALOG_STATE_CONNECTING) {

	if (cb->on_connecting)
	    (*cb->on_connecting)(dlg, event);

    } else if (dlg->state == PJSIP_DIALOG_STATE_ESTABLISHED) {

	if (cb->on_established)
	    (*cb->on_established)(dlg, event);
    }
}

/*
 * This callback receives event from the transaction layer (via User Agent),
 * or from dialog timer (for 200/INVITE or ACK retransmission).
 */
void pjsip_dlg_on_tsx_event( pjsip_dlg *dlg, 
			     pjsip_transaction *tsx, 
			     pjsip_event *event)
{
    int status = 0;
    struct dialog_lock_data lck;

    PJ_LOG(4, (dlg->obj_name, "state=%s (evt=%s, src=%s)", 
			 pjsip_dlg_state_str(dlg->state),
			 pjsip_event_str(event->type),
			 pjsip_event_str(event->src_type)));


    lock_dialog(dlg, &lck);

    status = dlg_on_all_state_pre( dlg, tsx, event);

    if (status==0) {
	status = (*dlg->handle_tsx_event)(dlg, tsx, event);
    }
    if (status==0) {
	status = dlg_on_all_state_post( dlg, tsx, event);
    }
    
    unlock_dialog(dlg, &lck);
}

/*
 * This function contains common processing in all states, and it is called
 * before the FSM is invoked.
 */
static int  dlg_on_all_state_pre( pjsip_dlg *dlg, 
				  pjsip_transaction *tsx,
				  pjsip_event *event)
{
    PJ_UNUSED_ARG(event)

    if (event->type != PJSIP_EVENT_TSX_STATE_CHANGED)
	return 0;

    if (tsx && (tsx->state==PJSIP_TSX_STATE_CALLING || 
	tsx->state==PJSIP_TSX_STATE_TRYING)) 
    {
	++dlg->pending_tsx_count;

    } else if (tsx && tsx->state==PJSIP_TSX_STATE_DESTROYED) 
    {
	--dlg->pending_tsx_count;
	if (tsx == dlg->invite_tsx)
	    dlg->invite_tsx = NULL;
    }

    if (tsx->method.id == PJSIP_INVITE_METHOD) {
	tsx->handle_ack = 1;
    }
    return 0;
}


/*
 * This function contains common processing in all states, and it is called
 * after the FSM is invoked.
 */
static int  dlg_on_all_state_post( pjsip_dlg *dlg, 
				   pjsip_transaction *tsx,
				   pjsip_event *event)
{
    PJ_UNUSED_ARG(event)

    if (tsx && tsx->state==PJSIP_TSX_STATE_DESTROYED) {
	if (dlg->pending_tsx_count == 0 &&
	    dlg->state != PJSIP_DIALOG_STATE_CONNECTING &&
	    dlg->state != PJSIP_DIALOG_STATE_ESTABLISHED &&
	    dlg->state != PJSIP_DIALOG_STATE_TERMINATED) 
	{
	    dlg_set_state(dlg, PJSIP_DIALOG_STATE_TERMINATED, event);
	    dlg_call_dlg_callback(dlg, PJSIP_DIALOG_EVENT_STATE_CHANGED, event);
	    return -1;
	}
    }

    return 0;
}


/*
 * Internal function to initialize dialog, contains common initialization
 * for both UAS and UAC dialog.
 */
static pj_status_t dlg_init( pjsip_dlg *dlg )
{
    /* Init mutex. */
    dlg->mutex = pj_mutex_create(dlg->pool, "mdlg%p", 0);
    if (!dlg->mutex) {
	PJ_PERROR((dlg->obj_name, "pj_mutex_create()"));
	return -1;
    }

    /* Init route-set (Initially empty) */
    pj_list_init(&dlg->route_set);

    /* Init auth credential list. */
    pj_list_init(&dlg->auth_sess);

    return PJ_SUCCESS;
}

/*
 * This one is called just before dialog is destroyed.
 * It is called while mutex is held.
 */
PJ_DEF(void) pjsip_on_dialog_destroyed( pjsip_dlg *dlg )
{
    struct dialog_lock_data *lck;

    //PJ_TODO(CHECK_THIS);
    pj_assert(dlg->pending_tsx_count == 0);

    /* Mark dialog as dead. */
    lck = pj_thread_local_get(pjsip_dlg_lock_tls_id);
    while (lck) {
	if (lck->dlg == dlg)
	    lck->is_alive = 0;
	lck = lck->prev;
    }
}

/*
 * Initialize dialog from the received request.
 * This is an internal function which is called by the User Agent (sip_ua.c), 
 * and it will initialize most of dialog's properties with values from the
 * received message.
 */
pj_status_t pjsip_dlg_init_from_rdata( pjsip_dlg *dlg, pjsip_rx_data *rdata )
{
    pjsip_msg *msg = rdata->msg;
    pjsip_to_hdr *to;
    pjsip_contact_hdr *contact;
    pjsip_name_addr *name_addr;
    pjsip_url *url;
    unsigned flag;
    pjsip_event event;

    pj_assert(dlg && rdata);

    PJ_LOG(5, (dlg->obj_name, "init_from_rdata(%p)", rdata));

    /* Must be an INVITE request. */
    pj_assert(msg->type == PJSIP_REQUEST_MSG && 
	      msg->line.req.method.id == PJSIP_INVITE_METHOD);

    /* Init general dialog data. */
    if (dlg_init(dlg) != PJ_SUCCESS) {
	return -1;
    }

    /* Get the To header. */
    to = rdata->to;

    /* Copy URI in the To header as our local URI. */
    dlg->local.info = pjsip_hdr_clone( dlg->pool, to);

    /* Set tag in the local info. */
    dlg->local.info->tag = dlg->local.tag;

    /* Create local Contact to be advertised in the response.
     * At the moment, just copy URI from the local URI as our contact.
     */
    dlg->local.contact = pjsip_contact_hdr_create( dlg->pool );
    dlg->local.contact->star = 0;
    name_addr = (pjsip_name_addr *)dlg->local.info->uri;
    dlg->local.contact->uri = (pjsip_uri*) name_addr;
    url = (pjsip_url*) name_addr->uri;
    //url->port = rdata->via->sent_by.port;
    //url->port = pj_sockaddr_get_port( pjsip_transport_get_local_addr(rdata->transport) );

    /* Save remote URI. */
    dlg->remote.info = pjsip_hdr_clone( dlg->pool, rdata->from );
    pjsip_fromto_set_to( dlg->remote.info );
    pj_strdup( dlg->pool, &dlg->remote.tag, &rdata->from->tag );

    /* Save remote Contact. */
    contact = pjsip_msg_find_hdr( msg, PJSIP_H_CONTACT, NULL);
    if (contact) {
    	dlg->remote.contact = pjsip_hdr_clone( dlg->pool, contact );
    } else {
	PJ_LOG(3,(dlg->obj_name, "No Contact header in INVITE from %s", 
		  pj_sockaddr_get_str_addr(&rdata->addr)));
   	dlg->remote.contact = pjsip_contact_hdr_create( dlg->pool );
	dlg->remote.contact->uri = dlg->remote.info->uri;
    }

    /* Save Call-ID. */
    dlg->call_id = pjsip_cid_hdr_create(dlg->pool);
    pj_strdup( dlg->pool, &dlg->call_id->id, &rdata->call_id );

    /* Initialize local CSeq and save remote CSeq.*/
    dlg->local.cseq = rdata->timestamp.sec & 0xFFFF;
    dlg->remote.cseq = rdata->cseq->cseq;

    /* Secure? */
    flag = pjsip_transport_get_flag(rdata->transport);
    dlg->secure = (flag & PJSIP_TRANSPORT_SECURE) != 0;

    /* Initial state is NULL. */
    event.type = event.src_type = PJSIP_EVENT_RX_MSG;
    event.src.rdata = rdata;
    dlg_set_state(dlg, PJSIP_DIALOG_STATE_NULL, &event);

    PJ_LOG(5, (dlg->obj_name, "init_from_rdata(%p) complete",  rdata));
    return PJ_SUCCESS;
}

/*
 * Set the contact details.
 */
PJ_DEF(pj_status_t) pjsip_dlg_set_contact( pjsip_dlg *dlg,
					   const pj_str_t *contact )
{
    pjsip_uri *local_uri;
    pj_str_t tmp;

    pj_strdup_with_null(dlg->pool, &tmp, contact);
    local_uri = pjsip_parse_uri( dlg->pool, tmp.ptr, tmp.slen, 
				 PJSIP_PARSE_URI_AS_NAMEADDR);
    if (local_uri == NULL) {
	PJ_LOG(2, (dlg->obj_name, "set_contact: invalid URI"));
	return -1;
    }

    dlg->local.contact->star = 0;
    dlg->local.contact->uri = local_uri;
    return 0;
}

/*
 * Set route set.
 */
PJ_DEF(pj_status_t) pjsip_dlg_set_route_set( pjsip_dlg *dlg,
					     const pjsip_route_hdr *route_set )
{
    pjsip_route_hdr *hdr;

    pj_list_init(&dlg->route_set);
    hdr = route_set->next;
    while (hdr != route_set) {
	pjsip_route_hdr *cloned = pjsip_hdr_clone(dlg->pool, hdr);
	pj_list_insert_before( &dlg->route_set, cloned);
	hdr = hdr->next;
    }
    return 0;
}

/*
 * Set route set without cloning the header.
 */
PJ_DEF(pj_status_t) pjsip_dlg_set_route_set_np( pjsip_dlg *dlg,
						pjsip_route_hdr *route_set)
{
    pjsip_route_hdr *hdr;

    pj_list_init(&dlg->route_set);
    hdr = route_set->next;
    while (hdr != route_set) {
	pj_list_insert_before( &dlg->route_set, hdr);
	hdr = hdr->next;
    }
    return 0;
}

/*
 * Application calls this function when it wants to initiate an outgoing
 * dialog (incoming dialogs are created automatically by UA when it receives
 * INVITE, by calling pjsip_dlg_init_from_rdata()).
 * This function should initialize most of the dialog's properties.
 */
PJ_DEF(pj_status_t) pjsip_dlg_init( pjsip_dlg *dlg,
				    const pj_str_t *c_local_info,
				    const pj_str_t *c_remote_info,
				    const pj_str_t *c_target)
{
    pj_time_val tv;
    pjsip_event event;
    pj_str_t buf;

    if (!dlg || !c_local_info || !c_remote_info) {
	pj_assert(dlg && c_local_info && c_remote_info);
	return -1;
    }

    PJ_LOG(5, (dlg->obj_name, "initializing"));

    /* Init general dialog */
    if (dlg_init(dlg) != PJ_SUCCESS) {
	return -1;
    }

    /* Duplicate local info. */
    pj_strdup_with_null( dlg->pool, &buf, c_local_info);

    /* Build local URI. */
    dlg->local.target = pjsip_parse_uri(dlg->pool, buf.ptr, buf.slen, 
				        PJSIP_PARSE_URI_AS_NAMEADDR);
    if (dlg->local.target == NULL) {
	PJ_LOG(2, (dlg->obj_name, 
		   "pjsip_dlg_init: invalid local URI %s", buf.ptr));
	return -1;
    }

    /* Set local URI. */
    dlg->local.info = pjsip_from_hdr_create(dlg->pool);
    dlg->local.info->uri = dlg->local.target;
    dlg->local.info->tag = dlg->local.tag;

    /* Create local Contact to be advertised in the response. */
    dlg->local.contact = pjsip_contact_hdr_create( dlg->pool );
    dlg->local.contact->star = 0;
    dlg->local.contact->uri = dlg->local.target;

    /* Set remote URI. */
    dlg->remote.info = pjsip_to_hdr_create(dlg->pool);

    /* Duplicate to buffer. */
    pj_strdup_with_null( dlg->pool, &buf, c_remote_info);

    /* Build remote info. */
    dlg->remote.info->uri = pjsip_parse_uri( dlg->pool, buf.ptr, buf.slen,
					     PJSIP_PARSE_URI_AS_NAMEADDR);
    if (dlg->remote.info->uri == NULL) {
	PJ_LOG(2, (dlg->obj_name, 
		   "pjsip_dlg_init: invalid remote URI %s", buf.ptr));
	return -1;
    }

    /* Set remote Contact initially equal to the remote URI. */
    dlg->remote.contact = pjsip_contact_hdr_create(dlg->pool);
    dlg->remote.contact->star = 0;
    dlg->remote.contact->uri = dlg->remote.info->uri;

    /* Set initial remote target. */
    if (c_target != NULL) {
	pj_strdup_with_null( dlg->pool, &buf, c_target);
	dlg->remote.target = pjsip_parse_uri( dlg->pool, buf.ptr, buf.slen, 0);
	if (dlg->remote.target == NULL) {
	    PJ_LOG(2, (dlg->obj_name, 
		       "pjsip_dlg_init: invalid remote target %s", buf.ptr));
	    return -1;
	}
    } else {
	dlg->remote.target = dlg->remote.info->uri;
    }

    /* Create globally unique Call-ID */
    dlg->call_id = pjsip_cid_hdr_create(dlg->pool);
    pj_create_unique_string( dlg->pool, &dlg->call_id->id );

    /* Local and remote CSeq */
    pj_gettimeofday(&tv);
    dlg->local.cseq = tv.sec & 0xFFFF;
    dlg->remote.cseq = 0;

    /* Initial state is NULL. */
    event.type = event.src_type = PJSIP_EVENT_TX_MSG;
    event.src.data = NULL;
    dlg_set_state(dlg, PJSIP_DIALOG_STATE_NULL, &event);

    /* Done. */
    PJ_LOG(4, (dlg->obj_name, "%s dialog initialized, From: %.*s, To: %.*s",
	       pjsip_role_name(dlg->role), 
	       c_local_info->slen, c_local_info->ptr,
	       c_remote_info->slen, c_remote_info->ptr));

    return PJ_SUCCESS;
}

/*
 * Set credentials.
 */
PJ_DEF(pj_status_t) pjsip_dlg_set_credentials(  pjsip_dlg *dlg,
					        int count,
						const pjsip_cred_info *cred)
{
    if (count > 0) {
	dlg->cred_info = pj_pool_alloc(dlg->pool, count * sizeof(pjsip_cred_info));
	pj_memcpy(dlg->cred_info, cred, count * sizeof(pjsip_cred_info));
    }
    dlg->cred_count = count;
    return 0;
}

/*
 * 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 void dlg_create_request_throw( pjsip_tx_data **p_tdata,
				      pjsip_dlg *dlg,
				      const pjsip_method *method,
				      int cseq )
{
    pjsip_tx_data *tdata;
    pjsip_contact_hdr *contact;
    pjsip_route_hdr *route, *end_list;

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

    tdata = pjsip_endpt_create_request_from_hdr( dlg->ua->endpt,
						 method,
						 dlg->remote.target,
						 dlg->local.info,
						 dlg->remote.info,
						 contact,
						 dlg->call_id,
						 cseq,
						 NULL);
    if (!tdata) {
	PJ_THROW(1);
	return;
    }

    /* 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_hdr_shallow_clone( tdata->pool, route );
	pjsip_routing_hdr_set_route(r);
	pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)r);
    }

    /* Copy authorization headers. */
    pjsip_auth_init_req( dlg->pool, tdata, &dlg->auth_sess,
			 dlg->cred_count, dlg->cred_info);

    *p_tdata = tdata;
}


/*
 * This function is called by application to create new outgoing request
 * message for this dialog. After the request is created, application can
 * modify the message (such adding headers), and eventually send the request.
 */
PJ_DEF(pjsip_tx_data*) pjsip_dlg_create_request( pjsip_dlg *dlg,
						 const pjsip_method *method,
						 int cseq)
{
    PJ_USE_EXCEPTION;
    struct dialog_lock_data lck;
    pjsip_tx_data *tdata = NULL;

    pj_assert(dlg != NULL && method != NULL);
    if (!dlg || !method) {
	return NULL;
    }

    PJ_LOG(5, (dlg->obj_name, "Creating request"));

    /* Lock dialog. */
    lock_dialog(dlg, &lck);

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

    PJ_LOG(5, (dlg->obj_name, "creating request %.*s cseq=%d", 
			      method->name.slen, method->name.ptr, cseq));

    /* Create the request. */
    PJ_TRY {
	dlg_create_request_throw(&tdata, dlg, method, cseq);
	PJ_LOG(5, (dlg->obj_name, "request data %s created", tdata->obj_name));
    }
    PJ_DEFAULT {
	/* Failed! Delete transmit data. */
	if (tdata) {
	    pjsip_tx_data_dec_ref( tdata );
	    tdata = NULL;
	}
    }
    PJ_END;

    /* Unlock dialog. */
    unlock_dialog(dlg, &lck);

    return tdata;
}

/*
 * Sends request.
 * Select the transport for the request message
 */
static pj_status_t dlg_send_request( pjsip_dlg *dlg, pjsip_tx_data *tdata )
{
    pjsip_transaction *tsx;
    pj_status_t status = PJ_SUCCESS;
    struct dialog_lock_data lck;

    pj_assert(dlg != NULL && tdata != NULL);
    if (!dlg || !tdata) {
	return -1;
    }

    PJ_LOG(5, (dlg->obj_name, "sending request %s", tdata->obj_name));

    /* Lock dialog. */
    lock_dialog(dlg, &lck);

    /* Create a new transaction. */
    tsx = pjsip_endpt_create_tsx( dlg->ua->endpt );
    if (!tsx) {
	unlock_dialog(dlg, &lck);
	return -1;
    }

    PJ_LOG(4, (dlg->obj_name, "Created new UAC transaction: %s", tsx->obj_name));

    /* Initialize transaction */
    tsx->module_data[dlg->ua->mod_id] = dlg;
    status = pjsip_tsx_init_uac( tsx, tdata );
    if (status != PJ_SUCCESS) {
	unlock_dialog(dlg, &lck);
	pjsip_endpt_destroy_tsx( dlg->ua->endpt, tsx );
	return -1;
    }
    pjsip_endpt_register_tsx( dlg->ua->endpt, tsx );

    /* Start the transaction. */
    pjsip_tsx_on_tx_msg(tsx, tdata);

    /* Unlock dialog. */
    unlock_dialog(dlg, &lck);

    return status;
}

/*
 * This function can be called by application to send ANY outgoing message
 * to remote party. 
 */
PJ_DEF(pj_status_t) pjsip_dlg_send_msg( pjsip_dlg *dlg, pjsip_tx_data *tdata )
{
    pj_status_t status;
    int tsx_status;
    struct dialog_lock_data lck;

    pj_assert(dlg != NULL && tdata != NULL);
    if (!dlg || !tdata) {
	return -1;
    }

    lock_dialog(dlg, &lck);

    if (tdata->msg->type == PJSIP_REQUEST_MSG) {
	int request_cseq;
	pjsip_msg *msg = tdata->msg;
	pjsip_cseq_hdr *cseq_hdr;

	switch (msg->line.req.method.id) {
	case PJSIP_CANCEL_METHOD:

	    /* Check the INVITE transaction state. */
	    tsx_status = dlg->invite_tsx->status_code;
	    if (tsx_status >= 200) {
		/* Already terminated. Can't cancel. */
		status = -1;
		goto on_return;
	    }

	    /* If we've got provisional response, then send CANCEL and wait for
	     * the response to INVITE to arrive. Otherwise just send CANCEL and
	     * terminate the INVITE.
	     */
	    if (tsx_status < 100) {
		pjsip_tsx_terminate( dlg->invite_tsx, 
				     PJSIP_SC_REQUEST_TERMINATED);
		status = 0;
		goto on_return;
	    }

	    status = 0;
	    request_cseq = dlg->invite_tsx->cseq;
	    break;

	case PJSIP_ACK_METHOD:
	    /* Sending ACK outside of transaction is not supported at present! */
	    pj_assert(0);
	    status = 0;
	    request_cseq = dlg->local.cseq;
	    break;

	case PJSIP_INVITE_METHOD:
	    /* For an initial INVITE, reset dialog state to NULL so we get
	     * 'normal' UAC notifications such as on_provisional(), etc.
	     * Initial INVITE is the request that is sent when the dialog has
	     * not been established yet. It's not necessarily the first INVITE
	     * sent, as when the Authorization fails, subsequent INVITE are also
	     * considered as an initial INVITE.
	     */
	    if (dlg->state != PJSIP_DIALOG_STATE_ESTABLISHED) {
		/* Set state to NULL. */
		dlg_set_state(dlg, PJSIP_DIALOG_STATE_NULL, NULL);

	    } else {
		/* This is a re-INVITE */
	    }
	    status = 0;
	    request_cseq = dlg->local.cseq + 1;
	    break;

	default:
	    status = 0;
	    request_cseq = dlg->local.cseq + 1;
	    break;
	}

	if (status != 0)
	    goto on_return;

	/* Update dialog's local CSeq, if necessary. */
	if (request_cseq != dlg->local.cseq)
	    dlg->local.cseq = request_cseq;

	/* Update CSeq header in the request. */
	cseq_hdr = (pjsip_cseq_hdr*) pjsip_msg_find_hdr( tdata->msg,
							 PJSIP_H_CSEQ, NULL);
	pj_assert(cseq_hdr != NULL);

	/* Update the CSeq */
	cseq_hdr->cseq = request_cseq;

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

	/* Now send the request. */
	status = dlg_send_request(dlg, tdata);

    } else {
	/*
	 * This is only valid for sending response to INVITE!
	 */
	pjsip_cseq_hdr *cseq_hdr;

	if (dlg->invite_tsx == NULL || dlg->invite_tsx->status_code >= 200) {
	    status = -1;
	    goto on_return;
	}

	cseq_hdr = (pjsip_cseq_hdr*) pjsip_msg_find_hdr( tdata->msg,
							 PJSIP_H_CSEQ, NULL);
	pj_assert(cseq_hdr);

	if (cseq_hdr->method.id != PJSIP_INVITE_METHOD) {
	    status = -1;
	    goto on_return;
	}

	pj_assert(cseq_hdr->cseq == dlg->invite_tsx->cseq);
	
	pjsip_tsx_on_tx_msg(dlg->invite_tsx, tdata);
	status = 0;
    }

on_return:
    /* Unlock dialog. */
    unlock_dialog(dlg, &lck);
   
    /* Whatever happen delete the message. */
    pjsip_tx_data_dec_ref( tdata );

    return status;
}

/*
 * Sends outgoing invitation.
 */
PJ_DEF(pjsip_tx_data*) pjsip_dlg_invite( pjsip_dlg *dlg )
{
    pjsip_method method;
    struct dialog_lock_data lck;
    const pjsip_allow_hdr *allow_hdr;
    pjsip_tx_data *tdata;

    pj_assert(dlg != NULL);
    if (!dlg) {
	return NULL;
    }

    PJ_LOG(4, (dlg->obj_name, "request to send invitation"));

    /* Lock dialog. */
    lock_dialog(dlg, &lck);

    /* Create request. */
    pjsip_method_set( &method, PJSIP_INVITE_METHOD);
    tdata = pjsip_dlg_create_request( dlg, &method, -1 );
    if (tdata == NULL) {
	unlock_dialog(dlg, &lck);
	return NULL;
    }

    /* Invite SHOULD contain "Allow" header. */
    allow_hdr = pjsip_endpt_get_allow_hdr( dlg->ua->endpt );
    if (allow_hdr) {
	pjsip_msg_add_hdr( tdata->msg, 
			   pjsip_hdr_shallow_clone( tdata->pool, allow_hdr));
    }

    /* Unlock dialog. */
    unlock_dialog(dlg, &lck);

    return tdata;
}

/*
 * Cancel pending outgoing dialog invitation. 
 */
PJ_DEF(pjsip_tx_data*) pjsip_dlg_cancel( pjsip_dlg *dlg )
{
    pjsip_tx_data *tdata = NULL;
    struct dialog_lock_data lck;

    pj_assert(dlg != NULL);
    if (!dlg) {
	return NULL;
    }

    PJ_LOG(4, (dlg->obj_name, "request to cancel invitation"));

    lock_dialog(dlg, &lck);

    /* Check the INVITE transaction. */
    if (dlg->invite_tsx == NULL || dlg->role != PJSIP_ROLE_UAC) {
	PJ_LOG(2, (dlg->obj_name, "pjsip_dlg_cancel failed: "
				  "no INVITE transaction found"));
	goto on_return;
    }

    /* Construct the CANCEL request. */
    tdata = pjsip_endpt_create_cancel( dlg->ua->endpt,
				       dlg->invite_tsx->last_tx );
    if (tdata == NULL) {
	PJ_LOG(2, (dlg->obj_name, "pjsip_dlg_cancel failed: "
				  "unable to construct request"));
	goto on_return;
    }

    /* Add reference counter to tdata. */
    pjsip_tx_data_add_ref(tdata);

on_return:
    unlock_dialog(dlg, &lck);
    return tdata;
}


/*
 * Answer incoming dialog invitation, with either provisional responses
 * or a final response.
 */
PJ_DEF(pjsip_tx_data*) pjsip_dlg_answer( pjsip_dlg *dlg, int code )
{
    pjsip_tx_data *tdata = NULL;
    pjsip_msg *msg;
    struct dialog_lock_data lck;

    pj_assert(dlg != NULL);
    if (!dlg) {
	return NULL;
    }

    PJ_LOG(4, (dlg->obj_name, "pjsip_dlg_answer: code=%d", code));

    /* Lock dialog. */
    lock_dialog(dlg, &lck);

    /* Must have pending INVITE. */
    if (dlg->invite_tsx == NULL) {
	PJ_LOG(2, (dlg->obj_name, "pjsip_dlg_answer: no INVITE transaction found"));
	goto on_return;
    }
    /* Must be UAS. */
    if (dlg->role != PJSIP_ROLE_UAS) {
	PJ_LOG(2, (dlg->obj_name, "pjsip_dlg_answer: not UAS"));
	goto on_return;
    }
    /* Must have not answered with final response before. */
    if (dlg->invite_tsx->status_code >= 200) {
	PJ_LOG(2, (dlg->obj_name, "pjsip_dlg_answer: transaction already terminated "
				  "with status %d", dlg->invite_tsx->status_code));
	goto on_return;
    }

    /* Get transmit data and the message. 
     * We will rewrite the message with a new status code.
     */
    only if tdata is not pending!!!
    tdata = dlg->invite_tsx->last_tx;
    msg = tdata->msg;

    /* Set status code and reason phrase. */
    if (code < 100 || code >= 700) code = 500;
    msg->line.status.code = code;
    msg->line.status.reason = *pjsip_get_status_text(code);

    /* For 2xx response, Contact and Record-Route must be added. */
    if (PJSIP_IS_STATUS_IN_CLASS(code,200)) {
	const pjsip_allow_hdr *allow_hdr;

	if (pjsip_msg_find_hdr(msg, PJSIP_H_CONTACT, NULL) == NULL) {
	    pjsip_contact_hdr *contact;
	    contact = pjsip_hdr_shallow_clone( tdata->pool, dlg->local.contact);
	    pjsip_msg_add_hdr( msg, (pjsip_hdr*)contact );
	}

	/* 2xx response MUST contain "Allow" header. */
	allow_hdr = pjsip_endpt_get_allow_hdr( dlg->ua->endpt );
	if (allow_hdr) {
	    pjsip_msg_add_hdr( msg, pjsip_hdr_shallow_clone( tdata->pool, allow_hdr));
	}
    }

    /* for all but 100 responses, To-tag must be set. */
    if (code != 100) {
	pjsip_to_hdr *to;
	to = pjsip_msg_find_hdr( msg, PJSIP_H_TO, NULL);
	to->tag = dlg->local.tag;
    }

    /* Reset packet buffer. */
    pjsip_tx_data_invalidate_msg(tdata);

    /* Add reference counter */
    pjsip_tx_data_add_ref(tdata);

on_return:

    /* Unlock dialog. */
    unlock_dialog(dlg, &lck);

    return tdata;
}


/*
 * Send BYE request to terminate the dialog's session.
 */
PJ_DEF(pjsip_tx_data*) pjsip_dlg_bye( pjsip_dlg *dlg )
{
    pjsip_method method;
    struct dialog_lock_data lck;
    pjsip_tx_data *tdata;

    if (!dlg) {
	pj_assert(dlg != NULL);
	return NULL;
    }

    PJ_LOG(4, (dlg->obj_name, "request to terminate session"));

    lock_dialog(dlg, &lck);

    pjsip_method_set( &method, PJSIP_BYE_METHOD);
    tdata = pjsip_dlg_create_request( dlg, &method, -1 );

    unlock_dialog(dlg, &lck);

    return tdata;
}

/*
 * High level function to disconnect dialog's session. Depending on dialog's 
 * state, this function will either send CANCEL, final response, or BYE to
 * trigger the disconnection. A status code must be supplied, which will be
 * sent if dialog will be transmitting a final response to INVITE.
 */
PJ_DEF(pjsip_tx_data*) pjsip_dlg_disconnect( pjsip_dlg *dlg, 
					     int status_code )
{
    pjsip_tx_data *tdata = NULL;

    pj_assert(dlg != NULL);
    if (!dlg) {
	return NULL;
    }

    switch (dlg->state) {
    case PJSIP_DIALOG_STATE_INCOMING:
	tdata = pjsip_dlg_answer(dlg, status_code);
	break;

    case PJSIP_DIALOG_STATE_CALLING:
	tdata = pjsip_dlg_cancel(dlg);
	break;

    case PJSIP_DIALOG_STATE_PROCEEDING:
	if (dlg->role == PJSIP_ROLE_UAC) {
	    tdata = pjsip_dlg_cancel(dlg);
	} else {
	    tdata = pjsip_dlg_answer(dlg, status_code);
	}
	break;

    case PJSIP_DIALOG_STATE_ESTABLISHED:
	tdata = pjsip_dlg_bye(dlg);
	break;

    default:
	PJ_LOG(4,(dlg->obj_name, "Invalid state %s in pjsip_dlg_disconnect()", 
		  dlg_state_names[dlg->state]));
	break;
    }

    return tdata;
}

/*
 * Handling of the receipt of 2xx/INVITE response.
 */
static void dlg_on_recv_2xx_invite( pjsip_dlg *dlg,
				    pjsip_event *event )
{
    pjsip_msg *msg;
    pjsip_contact_hdr *contact;
    pjsip_hdr *hdr, *end_hdr;
    pjsip_method method;
    pjsip_tx_data *ack_tdata;
    
    /* Get the message */
    msg = event->src.rdata->msg;
    
    /* Update remote's tag information. */
    pj_strdup(dlg->pool, &dlg->remote.info->tag, &event->src.rdata->to_tag);

    /* Copy Contact information in the 2xx/INVITE response to dialog's.
     * remote contact
     */
    contact = pjsip_msg_find_hdr( msg, PJSIP_H_CONTACT, NULL);
    if (contact) {
	dlg->remote.contact = pjsip_hdr_clone( dlg->pool, contact );
    } else {
	/* duplicate contact from "From" header (?) */
	PJ_LOG(4,(dlg->obj_name, "Received 200/OK to INVITE with no Contact!"));
	dlg->remote.contact = pjsip_contact_hdr_create(dlg->pool);
	dlg->remote.contact->uri = dlg->remote.info->uri;
    }
    
    /* Copy Record-Route header (in reverse order) as dialog's route-set,
     * overwriting previous route-set, if any, even if the received route-set
     * is empty.
     */
    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_hdr_clone(dlg->pool, hdr);
	    pjsip_routing_hdr_set_route(r);
	    pj_list_insert_before(&dlg->route_set, r);
	}
    }
    
    /* On receipt of 200/INVITE response, send ACK. 
     * This ack must be saved and retransmitted whenever we receive
     * 200/INVITE retransmission, until 64*T1 seconds elapsed.
     */
    pjsip_method_set( &method, PJSIP_ACK_METHOD);
    ack_tdata = pjsip_dlg_create_request( dlg, &method, dlg->invite_tsx->cseq);
    if (ack_tdata == NULL) {
	//PJ_TODO(HANDLE_CREATE_ACK_FAILURE)
	PJ_LOG(2, (dlg->obj_name, "Error sending ACK msg: can't create request"));
	return;
    }	
    
    /* Send with the transaction. */
    pjsip_tsx_on_tx_ack( dlg->invite_tsx, ack_tdata);
	
    /* Decrement reference counter because pjsip_dlg_create_request 
     * automatically increments the request.
     */
    pjsip_tx_data_dec_ref( ack_tdata );
}

/*
 * State NULL, before any events have been received.
 */
static int  dlg_on_state_null( pjsip_dlg *dlg, 
			       pjsip_transaction *tsx,
			       pjsip_event *event)
{
    if (event->type == PJSIP_EVENT_TSX_STATE_CHANGED &&
	event->src_type == PJSIP_EVENT_RX_MSG) 
    {
	pjsip_hdr *hdr, *hdr_list;

	pj_assert(tsx->method.id == PJSIP_INVITE_METHOD);

	/* Save the INVITE transaction. */
	dlg->invite_tsx = tsx;

	/* Change state to INCOMING */
	dlg_set_state(dlg, PJSIP_DIALOG_STATE_INCOMING, event);

	/* Create response buffer. */
	tsx->last_tx = pjsip_endpt_create_response( dlg->ua->endpt, event->src.rdata, 100);
	pjsip_tx_data_add_ref(tsx->last_tx);

	/* Copy the Record-Route headers into dialog's route_set, maintaining
	 * the order.
	 */
	pj_list_init(&dlg->route_set);
	hdr_list = &event->src.rdata->msg->hdr;
	hdr = hdr_list->next;
	while (hdr != hdr_list) {
	    if (hdr->type == PJSIP_H_RECORD_ROUTE) {
		pjsip_route_hdr *route;
		route = pjsip_hdr_clone(dlg->pool, hdr);
		pjsip_routing_hdr_set_route(route);
		pj_list_insert_before(&dlg->route_set, route);
	    }
	    hdr = hdr->next;
	}

	/* Notify application. */
	dlg_call_dlg_callback(dlg, PJSIP_DIALOG_EVENT_STATE_CHANGED, event);

    } else if (event->type == PJSIP_EVENT_TSX_STATE_CHANGED &&
	       event->src_type == PJSIP_EVENT_TX_MSG) 
    {
	pj_assert(tsx->method.id == PJSIP_INVITE_METHOD);

	/* Save the INVITE transaction. */
	dlg->invite_tsx = tsx;

	/* Change state to CALLING. */
	dlg_set_state(dlg, PJSIP_DIALOG_STATE_CALLING, event);

	/* Notify application. */
	dlg_call_dlg_callback(dlg, PJSIP_DIALOG_EVENT_STATE_CHANGED, event);

    } else {
	dlg_call_dlg_callback(dlg, PJSIP_DIALOG_EVENT_OTHER, event);
    }

    return 0;
}

/*
 * State INCOMING is after the (callee) dialog has been initialized with
 * the incoming request, but before any responses is sent by the dialog.
 */
static int  dlg_on_state_incoming( pjsip_dlg *dlg, 
				   pjsip_transaction *tsx,
				   pjsip_event *event)
{
    return dlg_on_state_proceeding_callee( dlg, tsx, event );
}

/*
 * State CALLING is after the (caller) dialog has sent outgoing invitation
 * but before any responses are received.
 */
static int  dlg_on_state_calling( pjsip_dlg *dlg, 
				  pjsip_transaction *tsx,
				  pjsip_event *event)
{
    if (tsx == dlg->invite_tsx) {
	return dlg_on_state_proceeding_caller( dlg, tsx, event );
    }
    return 0;
}

/*
 * State PROCEEDING is after provisional response is received.
 * Since the processing is similar to state CALLING, this function is also
 * called for CALLING state.
 */
static int  dlg_on_state_proceeding_caller( pjsip_dlg *dlg, 
					    pjsip_transaction *tsx,
					    pjsip_event *event)
{
    int dlg_is_terminated = 0;

    /* We only care about our INVITE transaction. 
     * Ignore other transaction progression (such as CANCEL).
     */
    if (tsx != dlg->invite_tsx) {
	dlg_call_dlg_callback(dlg, PJSIP_DIALOG_EVENT_OTHER, event);
	return 0;
    }

    if (event->type == PJSIP_EVENT_TSX_STATE_CHANGED) {
	switch (tsx->state) {
	case PJSIP_TSX_STATE_PROCEEDING:
	    if (dlg->state != PJSIP_DIALOG_STATE_PROCEEDING) {
		/* Change state to PROCEEDING */
		dlg_set_state(dlg, PJSIP_DIALOG_STATE_PROCEEDING, event);

		/* Notify application. */
		dlg_call_dlg_callback(dlg, PJSIP_DIALOG_EVENT_STATE_CHANGED, event);
	    } else {
		/* Also notify application. */
		dlg_call_dlg_callback(dlg, PJSIP_DIALOG_EVENT_OTHER, event);
	    }
	    break;

	case PJSIP_TSX_STATE_COMPLETED:
	    /* Change dialog state. */
	    if (PJSIP_IS_STATUS_IN_CLASS(tsx->status_code, 200)) {
		/* Update remote target, take it from the contact hdr. */
		pjsip_contact_hdr *contact;
		contact = pjsip_msg_find_hdr(event->src.rdata->msg, 
					     PJSIP_H_CONTACT, NULL);
		if (contact) {
		    dlg->remote.target = pjsip_uri_clone(dlg->pool, contact->uri);
		} else {
		    PJ_LOG(4,(dlg->obj_name, 
			      "Warning: found no Contact hdr in 200/OK"));
		}
		dlg_set_state(dlg, PJSIP_DIALOG_STATE_CONNECTING, event);
	    } else if (tsx->status_code==401 || tsx->status_code==407) {
		/* Handle Authentication challenge. */
		pjsip_tx_data *tdata;
		tdata = pjsip_auth_reinit_req( dlg->ua->endpt,
					       dlg->pool, &dlg->auth_sess,
					       dlg->cred_count, dlg->cred_info,
					       tsx->last_tx, event->src.rdata);
		if (tdata) {
		    /* Re-use original request, with a new transaction. 
		     * Need not to worry about CSeq, dialog will take care.
		     */
		    pjsip_dlg_send_msg(dlg, tdata);
		    return 0;
		} else {
		    dlg_set_state(dlg, PJSIP_DIALOG_STATE_DISCONNECTED, event);
		}
	    } else {
		dlg_set_state(dlg, PJSIP_DIALOG_STATE_DISCONNECTED, event);
	    }

	    /* Notify application. */
	    dlg_call_dlg_callback(dlg, PJSIP_DIALOG_EVENT_STATE_CHANGED, event);

	    /* Send ACK when dialog is connected. */
	    if (PJSIP_IS_STATUS_IN_CLASS(tsx->status_code, 200)) {
		pj_assert(event->src_type == PJSIP_EVENT_RX_MSG);
		dlg_on_recv_2xx_invite(dlg, event);
	    }
	    break;

	case PJSIP_TSX_STATE_TERMINATED:
	    /*
	     * Transaction is terminated because of timeout or transport error.
	     * To let the application go to normal state progression, call the
	     * callback twice. First is to emulate disconnection, and then call
	     * again (with state TERMINATED) to destroy the dialog.
	     */
	    dlg_set_state(dlg, PJSIP_DIALOG_STATE_DISCONNECTED, event);
	    dlg_call_dlg_callback(dlg, PJSIP_DIALOG_EVENT_STATE_CHANGED, event);

	    /* The INVITE transaction will be destroyed, so release reference 
	     * to it. 
	     */
	    dlg->invite_tsx = NULL;

	    /* We should terminate the dialog now.
	     * But it's possible that we have other pending transactions (for 
	     * example, outgoing CANCEL is in progress).
	     * So destroy the dialog only if there's no other transaction.
	     */
	    if (dlg->pending_tsx_count == 0) {
		dlg_set_state(dlg, PJSIP_DIALOG_STATE_TERMINATED, event);
		dlg_call_dlg_callback(dlg, PJSIP_DIALOG_EVENT_STATE_CHANGED, event);
		dlg_is_terminated = 1;
	    }
	    break;

	default:
	    pj_assert(0);
	    break;
	}
    } else {
	dlg_call_dlg_callback(dlg, PJSIP_DIALOG_EVENT_OTHER, event);
    }
    return dlg_is_terminated ? -1 : 0;
}

/*
 * State PROCEEDING for UAS is after the callee send provisional response.
 * This function is also called for INCOMING state.
 */
static int  dlg_on_state_proceeding_callee( pjsip_dlg *dlg, 
					    pjsip_transaction *tsx,
					    pjsip_event *event)
{
    int dlg_is_terminated = 0;

    pj_assert( dlg->invite_tsx != NULL );

    if (event->type == PJSIP_EVENT_TSX_STATE_CHANGED &&
	event->src_type == PJSIP_EVENT_TX_MSG && 
	tsx == dlg->invite_tsx) 
    {
	switch (tsx->state) {
	case PJSIP_TSX_STATE_PROCEEDING:
	    /* Change state to PROCEEDING */
	    dlg_set_state(dlg, PJSIP_DIALOG_STATE_PROCEEDING, event);

	    /* Notify application. */
	    dlg_call_dlg_callback(dlg, PJSIP_DIALOG_EVENT_STATE_CHANGED, event);
	    break;

	case PJSIP_TSX_STATE_COMPLETED:
	case PJSIP_TSX_STATE_TERMINATED:
	    /* Change dialog state. */
	    if (PJSIP_IS_STATUS_IN_CLASS(tsx->status_code, 200)) {
		dlg_set_state(dlg, PJSIP_DIALOG_STATE_CONNECTING, event);
	    } else {
		dlg_set_state(dlg, PJSIP_DIALOG_STATE_DISCONNECTED, event);
	    }

	    /* Notify application. */
	    dlg_call_dlg_callback(dlg, PJSIP_DIALOG_EVENT_STATE_CHANGED, event);

	    /* If transaction is terminated in non-2xx situation, 
	     * terminate dialog as well. This happens when something unexpected
	     * occurs, such as transport error.
	     */
	    if (tsx->state == PJSIP_TSX_STATE_TERMINATED && 
		!PJSIP_IS_STATUS_IN_CLASS(tsx->status_code, 200)) 
	    {
		dlg_set_state(dlg, PJSIP_DIALOG_STATE_TERMINATED, event);
		dlg_call_dlg_callback(dlg, PJSIP_DIALOG_EVENT_STATE_CHANGED, event);
		dlg_is_terminated = 1;
	    }
	    break;

	default:
	    pj_assert(0);
	    break;
	}

    } else if (event->type == PJSIP_EVENT_TSX_STATE_CHANGED &&
	       event->src_type == PJSIP_EVENT_RX_MSG && 
	       tsx->method.id == PJSIP_CANCEL_METHOD) 
    {
	pjsip_tx_data *tdata;

	/* Check if sequence number matches the pending INVITE. */
	if (dlg->invite_tsx==NULL ||
	    pj_strcmp(&tsx->branch, &dlg->invite_tsx->branch) != 0) 
	{
	    PJ_LOG(4, (dlg->obj_name, "Received CANCEL with no matching INVITE"));

	    /* No matching INVITE transaction found. */
	    tdata = pjsip_endpt_create_response(dlg->ua->endpt,
						event->src.rdata,
						PJSIP_SC_CALL_TSX_DOES_NOT_EXIST );
	    pjsip_tsx_on_tx_msg(tsx, tdata);
	    return 0;
	}

	/* Always respond the CANCEL with 200/CANCEL no matter what. */
	tdata = pjsip_endpt_create_response(dlg->ua->endpt,
					    event->src.rdata,
					    200 );
	pjsip_tsx_on_tx_msg( tsx, tdata );

	/* Respond the INVITE transaction with 487, only if transaction has
	 * not completed. 
	 */
	if (dlg->invite_tsx->last_tx) {
	    if (dlg->invite_tsx->status_code < 200) {
		tdata = dlg->invite_tsx->last_tx;
		tdata->msg->line.status.code = 487;
		tdata->msg->line.status.reason = *pjsip_get_status_text(487);
		/* Reset packet buffer. */
		pjsip_tx_data_invalidate_msg(tdata);
		pjsip_tsx_on_tx_msg( dlg->invite_tsx, tdata );
	    } else {
		PJ_LOG(4, (dlg->obj_name, "Received CANCEL with no effect, "
					  "Transaction already terminated "
					  "with status %d",
					  dlg->invite_tsx->status_code));
	    }
	} else {
	    tdata = pjsip_endpt_create_response(dlg->ua->endpt,
						event->src.rdata,
						487);
	    pjsip_tsx_on_tx_msg( dlg->invite_tsx, tdata );
	}
    } else {
	dlg_call_dlg_callback(dlg, PJSIP_DIALOG_EVENT_OTHER, event);
    }

    return dlg_is_terminated ? -1 : 0;
}

static int  dlg_on_state_proceeding( pjsip_dlg *dlg, 
				     pjsip_transaction *tsx,
				     pjsip_event *event)
{
    if (dlg->role == PJSIP_ROLE_UAC) {
	return dlg_on_state_proceeding_caller( dlg, tsx, event );
    } else {
	return dlg_on_state_proceeding_callee( dlg, tsx, event );
    }
}

static int  dlg_on_state_connecting( pjsip_dlg *dlg, 
				     pjsip_transaction *tsx,
				     pjsip_event *event)
{
    if (tsx == dlg->invite_tsx) {
	if (event->type == PJSIP_EVENT_TSX_STATE_CHANGED &&
	    (tsx->state == PJSIP_TSX_STATE_TERMINATED ||
	    tsx->state == PJSIP_TSX_STATE_COMPLETED ||
	    tsx->state == PJSIP_TSX_STATE_CONFIRMED)) 
	{
	    if (PJSIP_IS_STATUS_IN_CLASS(tsx->status_code, 200)) {
		dlg_set_state(dlg, PJSIP_DIALOG_STATE_ESTABLISHED, event);
	    } else {
		/* Probably because we never get the ACK, or transport error
		* when sending ACK.
		*/
		dlg_set_state(dlg, PJSIP_DIALOG_STATE_DISCONNECTED, event);
	    }
	    dlg_call_dlg_callback(dlg, PJSIP_DIALOG_EVENT_STATE_CHANGED, event);
	} else {
	    dlg_call_dlg_callback(dlg, PJSIP_DIALOG_EVENT_OTHER, event);
	}
    } else {
	/* Handle case when transaction is started when dialog is connecting
	* (e.g. BYE requests cross wire.
	*/
	if (event->type == PJSIP_EVENT_TSX_STATE_CHANGED &&
	    event->src_type == PJSIP_EVENT_RX_MSG &&
	    tsx->role == PJSIP_ROLE_UAS)
	{
	    pjsip_tx_data *response;

	    if (tsx->status_code >= 200)
		return 0;

	    if (tsx->method.id == PJSIP_BYE_METHOD) {
		/* Set state to DISCONNECTED. */
		dlg_set_state(dlg, PJSIP_DIALOG_STATE_DISCONNECTED, event);

		/* Notify application. */
		dlg_call_dlg_callback(dlg, PJSIP_DIALOG_EVENT_STATE_CHANGED, event);

		response = pjsip_endpt_create_response(	dlg->ua->endpt, 
							event->src.rdata, 200);
	    } else {
		response = pjsip_endpt_create_response( dlg->ua->endpt, event->src.rdata,
							PJSIP_SC_INTERNAL_SERVER_ERROR);
	    }

	    if (response)
		pjsip_tsx_on_tx_msg(tsx, response);

	    return 0;
	}
    }
    return 0;
}

static int  dlg_on_state_established( pjsip_dlg *dlg, 
				      pjsip_transaction *tsx,
				      pjsip_event *event)
{
    PJ_UNUSED_ARG(tsx)

    if (tsx && tsx->method.id == PJSIP_BYE_METHOD) {
	/* Set state to DISCONNECTED. */
	dlg_set_state(dlg, PJSIP_DIALOG_STATE_DISCONNECTED, event);

	/* Notify application. */
	dlg_call_dlg_callback(dlg, PJSIP_DIALOG_EVENT_STATE_CHANGED, event);

	/* Answer with 200/BYE. */
	if (event->src_type == PJSIP_EVENT_RX_MSG) {
	    pjsip_tx_data *tdata;
	    tdata = pjsip_endpt_create_response(dlg->ua->endpt,
						event->src.rdata,
						200 );
	    if (tdata)
		pjsip_tsx_on_tx_msg( tsx, tdata );
	}
    } else if (tsx && event->src_type == PJSIP_EVENT_RX_MSG) {
	pjsip_method_e method = event->src.rdata->cseq->method.id;

	PJ_TODO(PROPERLY_HANDLE_REINVITATION)

	/* Reinvitation. The message may be INVITE or an ACK. */
	if (method == PJSIP_INVITE_METHOD) {
	    if (dlg->invite_tsx && dlg->invite_tsx->status_code < 200) {
		/* Section 14.2: A UAS that receives a second INVITE before it 
		* sends the final response to a first INVITE with a lower
		* CSeq sequence number on the same dialog MUST return a 500 
		* (Server Internal Error) response to the second INVITE and 
		* MUST include a Retry-After header field with a randomly 
		* chosen value of between 0 and 10 seconds.
		*/
		pjsip_retry_after_hdr *hdr;
		pjsip_tx_data *tdata = 
		    pjsip_endpt_create_response(dlg->ua->endpt, 
						event->src.rdata, 500);

		if (!tdata)
		    return 0;

		/* Add Retry-After. */
		hdr = pjsip_retry_after_hdr_create(tdata->pool);
		hdr->ivalue = 9;
		pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)hdr);

		/* Send. */
		pjsip_tsx_on_tx_msg(tsx, tdata);

		return 0;
	    }

	    /* Keep this as our current INVITE transaction. */
	    dlg->invite_tsx = tsx;

	    /* Create response buffer. */
	    tsx->last_tx = pjsip_endpt_create_response( dlg->ua->endpt, 
							event->src.rdata, 100);
	    pjsip_tx_data_add_ref(tsx->last_tx);

	}

	/* Notify application. */
	dlg_call_dlg_callback(dlg, PJSIP_DIALOG_EVENT_MID_CALL_REQUEST, event);

    }  else {
	dlg_call_dlg_callback(dlg, PJSIP_DIALOG_EVENT_OTHER, event);
    }

    return 0;
}

static int  dlg_on_state_disconnected( pjsip_dlg *dlg, 
				       pjsip_transaction *tsx,
				       pjsip_event *event)
{
    PJ_UNUSED_ARG(tsx)

    /* Handle case when transaction is started when dialog is disconnected
     * (e.g. BYE requests cross wire.
     */
    if (event->type == PJSIP_EVENT_TSX_STATE_CHANGED &&
	event->src_type == PJSIP_EVENT_RX_MSG &&
	tsx->role == PJSIP_ROLE_UAS)
    {
	pjsip_tx_data *response = NULL;

	if (tsx->status_code >= 200)
	    return 0;

	if (tsx->method.id == PJSIP_BYE_METHOD) {
	    response = pjsip_endpt_create_response( dlg->ua->endpt, 
						    event->src.rdata, 200);
	} else {
	    response = pjsip_endpt_create_response( dlg->ua->endpt, event->src.rdata, 
						    PJSIP_SC_INTERNAL_SERVER_ERROR);
	}
	if (response)
	    pjsip_tsx_on_tx_msg(tsx, response);

	return 0;
    } 
    /* Handle case when outgoing BYE was rejected with 401/407 */
    else if (event->type == PJSIP_EVENT_TSX_STATE_CHANGED &&
	     event->src_type == PJSIP_EVENT_RX_MSG &&
	     tsx->role == PJSIP_ROLE_UAC)
    {
	if (tsx->status_code==401 || tsx->status_code==407) {
	    pjsip_tx_data *tdata;
	    tdata = pjsip_auth_reinit_req( dlg->ua->endpt, dlg->pool,
					   &dlg->auth_sess,
					   dlg->cred_count, dlg->cred_info,
					   tsx->last_tx, event->src.rdata);
	    if (tdata) {
		pjsip_dlg_send_msg(dlg, tdata);
	    }
	}
    }
	    

    if (dlg->pending_tsx_count == 0) {
	/* Set state to TERMINATED. */
	dlg_set_state(dlg, PJSIP_DIALOG_STATE_TERMINATED, event);

	/* Notify application. */
	dlg_call_dlg_callback(dlg, PJSIP_DIALOG_EVENT_STATE_CHANGED, event);

	return -1;
    } else {
	dlg_call_dlg_callback(dlg, PJSIP_DIALOG_EVENT_OTHER, event);
    }

    return 0;
}

static int  dlg_on_state_terminated( pjsip_dlg *dlg, 
				     pjsip_transaction *tsx,
				     pjsip_event *event)
{
    PJ_UNUSED_ARG(dlg)
    PJ_UNUSED_ARG(tsx)
    PJ_UNUSED_ARG(event)

    return -1;
}

