/* $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-ua/sip_100rel.h>
#include <pjsip/sip_endpoint.h>
#include <pjsip/sip_event.h>
#include <pjsip/sip_module.h>
#include <pjsip/sip_transaction.h>
#include <pj/assert.h>
#include <pj/ctype.h>
#include <pj/log.h>
#include <pj/os.h>
#include <pj/pool.h>
#include <pj/rand.h>
#include <pj/string.h>

#define THIS_FILE	"sip_100rel.c"

/* PRACK method */
PJ_DEF_DATA(const pjsip_method) pjsip_prack_method =
{
    PJSIP_OTHER_METHOD,
    { "PRACK", 5 }
};

typedef struct dlg_data dlg_data;

/*
 * Static prototypes.
 */
static pj_status_t mod_100rel_load(pjsip_endpoint *endpt);

static void on_retransmit(pj_timer_heap_t *timer_heap,
			  struct pj_timer_entry *entry);


const pj_str_t tag_100rel = { "100rel", 6 };
const pj_str_t RSEQ = { "RSeq", 4 };
const pj_str_t RACK = { "RAck", 4 };


/* 100rel module */
static struct mod_100rel
{
    pjsip_module	 mod;
    pjsip_endpoint	*endpt;
} mod_100rel = 
{
    {
	NULL, NULL,			    /* prev, next.		*/
	{ "mod-100rel", 10 },		    /* Name.			*/
	-1,				    /* Id			*/
	PJSIP_MOD_PRIORITY_DIALOG_USAGE,    /* Priority			*/
	&mod_100rel_load,		    /* load()			*/
	NULL,				    /* start()			*/
	NULL,				    /* stop()			*/
	NULL,				    /* unload()			*/
	NULL,				    /* on_rx_request()		*/
	NULL,				    /* on_rx_response()		*/
	NULL,				    /* on_tx_request.		*/
	NULL,				    /* on_tx_response()		*/
	NULL,				    /* on_tsx_state()		*/
    }

};

/* List of pending transmission (may include the final response as well) */
typedef struct tx_data_list_t
{
	PJ_DECL_LIST_MEMBER(struct tx_data_list_t);
	pj_uint32_t	 rseq;
	pjsip_tx_data	*tdata;
} tx_data_list_t;


/* Below, UAS and UAC roles are of the INVITE transaction */

/* UAS state. */
typedef struct uas_state_t
{
	pj_int32_t	 cseq;
	pj_uint32_t	 rseq;	/* Initialized to -1 */
	tx_data_list_t	 tx_data_list;
	unsigned	 retransmit_count;
	pj_timer_entry	 retransmit_timer;
} uas_state_t;


/* UAC state */
typedef struct uac_state_t
{
    pj_str_t		tag;	/* To tag	     	*/
    pj_int32_t		cseq;
    pj_uint32_t		rseq;	/* Initialized to -1 	*/
    struct uac_state_t *next;	/* next call leg	*/
} uac_state_t;


/* State attached to each dialog. */
struct dlg_data
{
	pjsip_inv_session	*inv;
	uas_state_t		*uas_state;
	uac_state_t		*uac_state_list;
};


/*****************************************************************************
 **
 ** Module
 **
 *****************************************************************************
 */
static pj_status_t mod_100rel_load(pjsip_endpoint *endpt)
{
    mod_100rel.endpt = endpt;
    pjsip_endpt_add_capability(endpt, &mod_100rel.mod, 
			       PJSIP_H_ALLOW, NULL,
			       1, &pjsip_prack_method.name);
    pjsip_endpt_add_capability(endpt, &mod_100rel.mod, 
			       PJSIP_H_SUPPORTED, NULL,
			       1, &tag_100rel);

    return PJ_SUCCESS;
}

static pjsip_require_hdr *find_req_hdr(pjsip_msg *msg)
{
    pjsip_require_hdr *hreq;

    hreq = (pjsip_require_hdr*)
	    pjsip_msg_find_hdr(msg, PJSIP_H_REQUIRE, NULL);

    while (hreq) {
	unsigned i;
	for (i=0; i<hreq->count; ++i) {
	    if (!pj_stricmp(&hreq->values[i], &tag_100rel)) {
		return hreq;
	    }
	}

	if ((void*)hreq->next == (void*)&msg->hdr)
	    return NULL;

	hreq = (pjsip_require_hdr*)
		pjsip_msg_find_hdr(msg, PJSIP_H_REQUIRE, hreq->next);

    }

    return NULL;
}


/*
 * Get PRACK method constant. 
 */
PJ_DEF(const pjsip_method*) pjsip_get_prack_method(void)
{
    return &pjsip_prack_method;
}


/*
 * init module
 */
PJ_DEF(pj_status_t) pjsip_100rel_init_module(pjsip_endpoint *endpt)
{
    if (mod_100rel.mod.id != -1)
	return PJ_SUCCESS;

    return pjsip_endpt_register_module(endpt, &mod_100rel.mod);
}


/*
 * API: attach 100rel support in invite session. Called by
 *      sip_inv.c
 */
PJ_DEF(pj_status_t) pjsip_100rel_attach(pjsip_inv_session *inv)
{
    dlg_data *dd;

    /* Check that 100rel module has been initialized */
    PJ_ASSERT_RETURN(mod_100rel.mod.id >= 0, PJ_EINVALIDOP);

    /* Create and attach as dialog usage */
    dd = PJ_POOL_ZALLOC_T(inv->dlg->pool, dlg_data);
    dd->inv = inv;
    pjsip_dlg_add_usage(inv->dlg, &mod_100rel.mod, (void*)dd);

    PJ_LOG(5,(dd->inv->dlg->obj_name, "100rel module attached"));

    return PJ_SUCCESS;
}


/*
 * Check if incoming response has reliable provisional response feature.
 */
PJ_DEF(pj_bool_t) pjsip_100rel_is_reliable(pjsip_rx_data *rdata)
{
    pjsip_msg *msg = rdata->msg_info.msg;

    PJ_ASSERT_RETURN(msg->type == PJSIP_RESPONSE_MSG, PJ_FALSE);

    return msg->line.status.code > 100 && msg->line.status.code < 200 &&
	   rdata->msg_info.require != NULL &&
	   find_req_hdr(msg) != NULL;
}


/*
 * Create PRACK request for the incoming reliable provisional response.
 */
PJ_DEF(pj_status_t) pjsip_100rel_create_prack( pjsip_inv_session *inv,
					       pjsip_rx_data *rdata,
					       pjsip_tx_data **p_tdata)
{
    dlg_data *dd;
    uac_state_t *uac_state = NULL;
    const pj_str_t *to_tag = &rdata->msg_info.to->tag;
    pjsip_transaction *tsx;
    pjsip_msg *msg;
    pjsip_generic_string_hdr *rseq_hdr;
    pjsip_generic_string_hdr *rack_hdr;
    unsigned rseq;
    pj_str_t rack;
    char rack_buf[80];
    pjsip_tx_data *tdata;
    pj_status_t status;

    *p_tdata = NULL;

    dd = (dlg_data*) inv->dlg->mod_data[mod_100rel.mod.id];
    PJ_ASSERT_RETURN(dd != NULL, PJSIP_ENOTINITIALIZED);

    tsx = pjsip_rdata_get_tsx(rdata);
    msg = rdata->msg_info.msg;

    /* Check our assumptions */
    pj_assert( tsx->role == PJSIP_ROLE_UAC &&
	       tsx->method.id == PJSIP_INVITE_METHOD &&
	       msg->line.status.code > 100 &&
	       msg->line.status.code < 200);


    /* Get the RSeq header */
    rseq_hdr = (pjsip_generic_string_hdr*)
	       pjsip_msg_find_hdr_by_name(msg, &RSEQ, NULL);
    if (rseq_hdr == NULL) {
	PJ_LOG(4,(dd->inv->dlg->obj_name, 
		 "Ignoring 100rel response with no RSeq header"));
	return PJSIP_EMISSINGHDR;
    }
    rseq = (pj_uint32_t) pj_strtoul(&rseq_hdr->hvalue);

    /* Find UAC state for the specified call leg */
    uac_state = dd->uac_state_list;
    while (uac_state) {
	if (pj_stricmp(&uac_state->tag, to_tag)==0)
	    break;
	uac_state = uac_state->next;
    }

    /* Create new UAC state if we don't have one */
    if (uac_state == NULL) {
	uac_state = PJ_POOL_ZALLOC_T(dd->inv->dlg->pool, uac_state_t);
	uac_state->cseq = rdata->msg_info.cseq->cseq;
	uac_state->rseq = rseq - 1;
	pj_strdup(dd->inv->dlg->pool, &uac_state->tag, to_tag);
	uac_state->next = dd->uac_state_list;
	dd->uac_state_list = uac_state;
    }

    /* If this is from new INVITE transaction, reset UAC state. */
    if (rdata->msg_info.cseq->cseq != uac_state->cseq) {
	uac_state->cseq = rdata->msg_info.cseq->cseq;
	uac_state->rseq = rseq - 1;
    }

    /* Ignore provisional response retransmission */
    if (rseq <= uac_state->rseq) {
	/* This should have been handled before */
	return PJ_EIGNORED;

    /* Ignore provisional response with out-of-order RSeq */
    } else if (rseq != uac_state->rseq + 1) {
	PJ_LOG(4,(dd->inv->dlg->obj_name, 
		 "Ignoring 100rel response because RSeq jump "
		 "(expecting %u, got %u)",
		 uac_state->rseq+1, rseq));
	return PJ_EIGNORED;
    }

    /* Update our RSeq */
    uac_state->rseq = rseq;

    /* Create PRACK */
    status = pjsip_dlg_create_request(dd->inv->dlg, &pjsip_prack_method,
				      -1, &tdata);
    if (status != PJ_SUCCESS)
	return status;

    /* If this response is a forked response from a different call-leg,
     * update the req URI (https://trac.pjsip.org/repos/ticket/1364)
     */
    if (pj_stricmp(&uac_state->tag, &dd->inv->dlg->remote.info->tag)) {
	const pjsip_contact_hdr *mhdr;

	mhdr = (const pjsip_contact_hdr*)
	       pjsip_msg_find_hdr(rdata->msg_info.msg,
	                          PJSIP_H_CONTACT, NULL);
	if (!mhdr || !mhdr->uri) {
	    PJ_LOG(4,(dd->inv->dlg->obj_name,
		     "Ignoring 100rel response with no or "
		     "invalid Contact header"));
	    pjsip_tx_data_dec_ref(tdata);
	    return PJ_EIGNORED;
	}
	tdata->msg->line.req.uri = (pjsip_uri*)
				   pjsip_uri_clone(tdata->pool, mhdr->uri);
    }

    /* Create RAck header */
    rack.ptr = rack_buf;
    rack.slen = pj_ansi_snprintf(rack.ptr, sizeof(rack_buf),
				 "%u %u %.*s",
				 rseq, rdata->msg_info.cseq->cseq,
				 (int)tsx->method.name.slen,
				 tsx->method.name.ptr);
    if (rack.slen < 1 || rack.slen >= (int)sizeof(rack_buf)) {
	return PJ_ETOOSMALL;
    }
    rack_hdr = pjsip_generic_string_hdr_create(tdata->pool, &RACK, &rack);
    pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*) rack_hdr);

    /* Done */
    *p_tdata = tdata;

    return PJ_SUCCESS;
}


/*
 * Send PRACK request.
 */
PJ_DEF(pj_status_t) pjsip_100rel_send_prack( pjsip_inv_session *inv,
					     pjsip_tx_data *tdata)
{
    dlg_data *dd;

    dd = (dlg_data*) inv->dlg->mod_data[mod_100rel.mod.id];
    PJ_ASSERT_ON_FAIL(dd != NULL, 
    {pjsip_tx_data_dec_ref(tdata); return PJSIP_ENOTINITIALIZED; });

    return pjsip_dlg_send_request(inv->dlg, tdata, 
				  mod_100rel.mod.id, (void*) dd);

}


/*
 * Notify 100rel module that the invite session has been disconnected.
 */
PJ_DEF(pj_status_t) pjsip_100rel_end_session(pjsip_inv_session *inv)
{
    dlg_data *dd;

    dd = (dlg_data*) inv->dlg->mod_data[mod_100rel.mod.id];
    if (!dd)
	return PJ_SUCCESS;

    /* Make sure we don't have pending transmission */
    if (dd->uas_state) {
	pj_assert(!dd->uas_state->retransmit_timer.id);
	pj_assert(pj_list_empty(&dd->uas_state->tx_data_list));
    }

    return PJ_SUCCESS;
}


static void parse_rack(const pj_str_t *rack,
		       pj_uint32_t *p_rseq, pj_int32_t *p_seq,
		       pj_str_t *p_method)
{
    const char *p = rack->ptr, *end = p + rack->slen;
    pj_str_t token;

    token.ptr = (char*)p;
    while (p < end && pj_isdigit(*p))
	++p;
    token.slen = p - token.ptr;
    *p_rseq = pj_strtoul(&token);

    ++p;
    token.ptr = (char*)p;
    while (p < end && pj_isdigit(*p))
	++p;
    token.slen = p - token.ptr;
    *p_seq = pj_strtoul(&token);

    ++p;
    if (p < end) {
	p_method->ptr = (char*)p;
	p_method->slen = end - p;
    } else {
	p_method->ptr = NULL;
	p_method->slen = 0;
    }
}

/* Clear all responses in the transmission list */
static void clear_all_responses(dlg_data *dd)
{
    tx_data_list_t *tl;

    tl = dd->uas_state->tx_data_list.next;
    while (tl != &dd->uas_state->tx_data_list) {
	pjsip_tx_data_dec_ref(tl->tdata);
	tl = tl->next;
    }
    pj_list_init(&dd->uas_state->tx_data_list);
}


/*
 * Handle incoming PRACK request.
 */
PJ_DEF(pj_status_t) pjsip_100rel_on_rx_prack( pjsip_inv_session *inv,
					      pjsip_rx_data *rdata)
{
    dlg_data *dd;
    pjsip_transaction *tsx;
    pjsip_msg *msg;
    pjsip_generic_string_hdr *rack_hdr;
    pjsip_tx_data *tdata;
    pj_uint32_t rseq;
    pj_int32_t cseq;
    pj_str_t method;
    pj_status_t status;

    tsx = pjsip_rdata_get_tsx(rdata);
    pj_assert(tsx != NULL);

    msg = rdata->msg_info.msg;

    dd = (dlg_data*) inv->dlg->mod_data[mod_100rel.mod.id];
    if (dd == NULL) {
	/* UAC sends us PRACK while we didn't send reliable provisional 
	 * response. Respond with 400 (?) 
	 */
	const pj_str_t reason = pj_str("Unexpected PRACK");

	status = pjsip_dlg_create_response(inv->dlg, rdata, 400, 
					   &reason, &tdata);
	if (status == PJ_SUCCESS) {
	    status = pjsip_dlg_send_response(inv->dlg, tsx, tdata);
	}
	return PJSIP_ENOTINITIALIZED;
    }

    /* Always reply with 200/OK for PRACK */
    status = pjsip_dlg_create_response(inv->dlg, rdata, 200, NULL, &tdata);
    if (status == PJ_SUCCESS) {
	status = pjsip_dlg_send_response(inv->dlg, tsx, tdata);
    }

    /* Ignore if we don't have pending transmission */
    if (dd->uas_state == NULL || pj_list_empty(&dd->uas_state->tx_data_list)) {
	PJ_LOG(4,(dd->inv->dlg->obj_name, 
		  "PRACK ignored - no pending response"));
	return PJ_EIGNORED;
    }

    /* Find RAck header */
    rack_hdr = (pjsip_generic_string_hdr*)
	       pjsip_msg_find_hdr_by_name(msg, &RACK, NULL);
    if (!rack_hdr) {
	/* RAck header not found */
	PJ_LOG(4,(dd->inv->dlg->obj_name, "No RAck header"));
	return PJSIP_EMISSINGHDR;
    }

    /* Parse RAck header */
    parse_rack(&rack_hdr->hvalue, &rseq, &cseq, &method);


    /* Match RAck against outgoing transmission */
    if (rseq == dd->uas_state->tx_data_list.next->rseq &&
	cseq == dd->uas_state->cseq)
    {
	/* 
	 * Yes this PRACK matches outgoing transmission.
	 */
	tx_data_list_t *tl = dd->uas_state->tx_data_list.next;

	if (dd->uas_state->retransmit_timer.id) {
	    pjsip_endpt_cancel_timer(dd->inv->dlg->endpt,
				     &dd->uas_state->retransmit_timer);
	    dd->uas_state->retransmit_timer.id = PJ_FALSE;
	}

	/* Remove from the list */
	if (tl != &dd->uas_state->tx_data_list) {
	    pj_list_erase(tl);

	    /* Destroy the response */
	    pjsip_tx_data_dec_ref(tl->tdata);
	}

	/* Schedule next packet */
	dd->uas_state->retransmit_count = 0;
	if (!pj_list_empty(&dd->uas_state->tx_data_list)) {
	    on_retransmit(NULL, &dd->uas_state->retransmit_timer);
	}

    } else {
	/* No it doesn't match */
	PJ_LOG(4,(dd->inv->dlg->obj_name, 
		 "Rx PRACK with no matching reliable response"));
	return PJ_EIGNORED;
    }

    return PJ_SUCCESS;
}


/*
 * This is retransmit timer callback, called initially to send the response,
 * and subsequently when the retransmission time elapses.
 */
static void on_retransmit(pj_timer_heap_t *timer_heap,
			  struct pj_timer_entry *entry)
{
    dlg_data *dd;
    tx_data_list_t *tl;
    pjsip_tx_data *tdata;
    pj_bool_t final;
    pj_time_val delay;

    PJ_UNUSED_ARG(timer_heap);

    dd = (dlg_data*) entry->user_data;

    entry->id = PJ_FALSE;

    ++dd->uas_state->retransmit_count;
    if (dd->uas_state->retransmit_count >= 7) {
	/* If a reliable provisional response is retransmitted for
	   64*T1 seconds  without reception of a corresponding PRACK,
	   the UAS SHOULD reject the original request with a 5xx 
	   response.
	*/
	pj_str_t reason = pj_str("Reliable response timed out");
	pj_status_t status;

	/* Clear all pending responses */
	clear_all_responses(dd);

	/* Send 500 response */
	status = pjsip_inv_end_session(dd->inv, 500, &reason, &tdata);
	if (status == PJ_SUCCESS) {
	    pjsip_dlg_send_response(dd->inv->dlg, 
				    dd->inv->invite_tsx,
				    tdata);
	}
	return;
    }

    pj_assert(!pj_list_empty(&dd->uas_state->tx_data_list));
    tl = dd->uas_state->tx_data_list.next;
    tdata = tl->tdata;

    pjsip_tx_data_add_ref(tdata);
    final = tdata->msg->line.status.code >= 200;

    if (dd->uas_state->retransmit_count == 1) {
	pjsip_tsx_send_msg(dd->inv->invite_tsx, tdata);
    } else {
	pjsip_tsx_retransmit_no_state(dd->inv->invite_tsx, tdata);
    }

    if (final) {
	/* This is final response, which will be retransmitted by
	 * UA layer. There's no more task to do, so clear the
	 * transmission list and bail out.
	 */
	clear_all_responses(dd);
	return;
    }

    /* Schedule next retransmission */
    if (dd->uas_state->retransmit_count < 6) {
	delay.sec = 0;
	delay.msec = (1 << dd->uas_state->retransmit_count) * 
		     pjsip_cfg()->tsx.t1;
	pj_time_val_normalize(&delay);
    } else {
	delay.sec = 1;
	delay.msec = 500;
    }


    pjsip_endpt_schedule_timer(dd->inv->dlg->endpt, 
			       &dd->uas_state->retransmit_timer,
			       &delay);

    entry->id = PJ_TRUE;
}


/* Clone response. */
static pjsip_tx_data *clone_tdata(dlg_data *dd,
				  const pjsip_tx_data *src)
{
    pjsip_tx_data *dst;
    const pjsip_hdr *hsrc;
    pjsip_msg *msg;
    pj_status_t status;

    status = pjsip_endpt_create_tdata(dd->inv->dlg->endpt, &dst);
    if (status != PJ_SUCCESS)
	return NULL;

    msg = pjsip_msg_create(dst->pool, PJSIP_RESPONSE_MSG);
    dst->msg = msg;
    pjsip_tx_data_add_ref(dst);

    /* Duplicate status line */
    msg->line.status.code = src->msg->line.status.code;
    pj_strdup(dst->pool, &msg->line.status.reason, 
	      &src->msg->line.status.reason);

    /* Duplicate all headers */
    hsrc = src->msg->hdr.next;
    while (hsrc != &src->msg->hdr) {
	pjsip_hdr *h = (pjsip_hdr*) pjsip_hdr_clone(dst->pool, hsrc);
	pjsip_msg_add_hdr(msg, h);
	hsrc = hsrc->next;
    }

    /* Duplicate message body */
    if (src->msg->body)
	msg->body = pjsip_msg_body_clone(dst->pool, src->msg->body);

    PJ_LOG(5,(dd->inv->dlg->obj_name,
	     "Reliable response %s created",
	     pjsip_tx_data_get_info(dst)));

    return dst;
}


/* Check if any pending response in transmission list has SDP */
static pj_bool_t has_sdp(dlg_data *dd)
{
    tx_data_list_t *tl;

    tl = dd->uas_state->tx_data_list.next;
    while (tl != &dd->uas_state->tx_data_list) {
	    if (tl->tdata->msg->body)
		    return PJ_TRUE;
	    tl = tl->next;
    }

    return PJ_FALSE;
}


/* Send response reliably */
PJ_DEF(pj_status_t) pjsip_100rel_tx_response(pjsip_inv_session *inv,
					     pjsip_tx_data *tdata)
{
    pjsip_cseq_hdr *cseq_hdr;
    pjsip_generic_string_hdr *rseq_hdr;
    pjsip_require_hdr *req_hdr;
    int status_code;
    dlg_data *dd;
    pjsip_tx_data *old_tdata;
    pj_status_t status;
    
    PJ_ASSERT_RETURN(tdata->msg->type == PJSIP_RESPONSE_MSG,
		     PJSIP_ENOTRESPONSEMSG);
    
    status_code = tdata->msg->line.status.code;
    
    /* 100 response doesn't need PRACK */
    if (status_code == 100)
	return pjsip_dlg_send_response(inv->dlg, inv->invite_tsx, tdata);
    

    /* Get the 100rel data attached to this dialog */
    dd = (dlg_data*) inv->dlg->mod_data[mod_100rel.mod.id];
    PJ_ASSERT_RETURN(dd != NULL, PJ_EINVALIDOP);
    
    
    /* Clone tdata.
     * We need to clone tdata because we may need to keep it in our
     * retransmission list, while the original dialog may modify it
     * if it wants to send another response.
     */
    old_tdata = tdata;
    tdata = clone_tdata(dd, old_tdata);
    pjsip_tx_data_dec_ref(old_tdata);
    

    /* Get CSeq header, and make sure this is INVITE response */
    cseq_hdr = (pjsip_cseq_hdr*)
	        pjsip_msg_find_hdr(tdata->msg, PJSIP_H_CSEQ, NULL);
    PJ_ASSERT_RETURN(cseq_hdr != NULL, PJ_EBUG);
    PJ_ASSERT_RETURN(cseq_hdr->method.id == PJSIP_INVITE_METHOD, 
	PJ_EINVALIDOP);
    
    /* Remove existing Require header */
    req_hdr = find_req_hdr(tdata->msg);
    if (req_hdr) {
	pj_list_erase(req_hdr);
    }
    
    /* Remove existing RSeq header */
    rseq_hdr = (pjsip_generic_string_hdr*)
	pjsip_msg_find_hdr_by_name(tdata->msg, &RSEQ, NULL);
    if (rseq_hdr)
	pj_list_erase(rseq_hdr);
    
    /* Different treatment for provisional and final response */
    if (status_code/100 == 2) {
	
	/* RFC 3262 Section 3: UAS Behavior:
    
	  The UAS MAY send a final response to the initial request 
	  before having received PRACKs for all unacknowledged 
	  reliable provisional responses, unless the final response 
	  is 2xx and any of the unacknowledged reliable provisional 
	  responses contained a session description.  In that case, 
	  it MUST NOT send a final response until those provisional 
	  responses are acknowledged.
	*/
	
	if (dd->uas_state && has_sdp(dd)) {
	    /* Yes we have transmitted 1xx with SDP reliably.
	     * In this case, must queue the 2xx response.
	     */
	    tx_data_list_t *tl;
	    
	    tl = PJ_POOL_ZALLOC_T(tdata->pool, tx_data_list_t);
	    tl->tdata = tdata;
	    tl->rseq = (pj_uint32_t)-1;
	    pj_list_push_back(&dd->uas_state->tx_data_list, tl);
	    
	    /* Will send later */
	    status = PJ_SUCCESS;
	    
	    PJ_LOG(4,(dd->inv->dlg->obj_name, 
		      "2xx response will be sent after PRACK"));
	    
	} else if (dd->uas_state) {
	    /* 
	    RFC 3262 Section 3: UAS Behavior:

	    If the UAS does send a final response when reliable
	    responses are still unacknowledged, it SHOULD NOT 
	    continue to retransmit the unacknowledged reliable
	    provisional responses, but it MUST be prepared to 
	    process PRACK requests for those outstanding 
	    responses.
	    */
	    
	    PJ_LOG(4,(dd->inv->dlg->obj_name, 
		      "No SDP sent so far, sending 2xx now"));
	    
	    /* Cancel the retransmit timer */
	    if (dd->uas_state->retransmit_timer.id) {
		pjsip_endpt_cancel_timer(dd->inv->dlg->endpt,
					 &dd->uas_state->retransmit_timer);
		dd->uas_state->retransmit_timer.id = PJ_FALSE;
	    }
	    
	    /* Clear all pending responses (drop 'em) */
	    clear_all_responses(dd);
	    
	    /* And transmit the 2xx response */
	    status=pjsip_dlg_send_response(inv->dlg, 
					   inv->invite_tsx, tdata);
	    
	} else {
	    /* We didn't send any reliable provisional response */
	    
	    /* Transmit the 2xx response */
	    status=pjsip_dlg_send_response(inv->dlg, 
					   inv->invite_tsx, tdata);
	}
	
    } else if (status_code >= 300) {
	
	/* 
	RFC 3262 Section 3: UAS Behavior:

	If the UAS does send a final response when reliable
	responses are still unacknowledged, it SHOULD NOT 
	continue to retransmit the unacknowledged reliable
	provisional responses, but it MUST be prepared to 
	process PRACK requests for those outstanding 
	responses.
	*/
	
	/* Cancel the retransmit timer */
	if (dd->uas_state && dd->uas_state->retransmit_timer.id) {
	    pjsip_endpt_cancel_timer(dd->inv->dlg->endpt,
				     &dd->uas_state->retransmit_timer);
	    dd->uas_state->retransmit_timer.id = PJ_FALSE;
	    
	    /* Clear all pending responses (drop 'em) */
	    clear_all_responses(dd);
	}
	
	/* And transmit the 2xx response */
	status=pjsip_dlg_send_response(inv->dlg, 
				       inv->invite_tsx, tdata);
	
    } else {
	/*
	 * This is provisional response.
	 */
	char rseq_str[32];
	pj_str_t rseq;
	tx_data_list_t *tl;
	
	/* Create UAS state if we don't have one */
	if (dd->uas_state == NULL) {
	    dd->uas_state = PJ_POOL_ZALLOC_T(inv->dlg->pool,
					     uas_state_t);
	    dd->uas_state->cseq = cseq_hdr->cseq;
	    dd->uas_state->rseq = pj_rand() % 0x7FFF;
	    pj_list_init(&dd->uas_state->tx_data_list);
	    dd->uas_state->retransmit_timer.user_data = dd;
	    dd->uas_state->retransmit_timer.cb = &on_retransmit;
	}
	
	/* Check that CSeq match */
	PJ_ASSERT_RETURN(cseq_hdr->cseq == dd->uas_state->cseq,
			 PJ_EINVALIDOP);
	
	/* Add Require header */
	req_hdr = pjsip_require_hdr_create(tdata->pool);
	req_hdr->count = 1;
	req_hdr->values[0] = tag_100rel;
	pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)req_hdr);
	
	/* Add RSeq header */
	pj_ansi_snprintf(rseq_str, sizeof(rseq_str), "%u",
			 dd->uas_state->rseq);
	rseq = pj_str(rseq_str);
	rseq_hdr = pjsip_generic_string_hdr_create(tdata->pool, 
						   &RSEQ, &rseq);
	pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)rseq_hdr);
	
	/* Create list entry for this response */
	tl = PJ_POOL_ZALLOC_T(tdata->pool, tx_data_list_t);
	tl->tdata = tdata;
	tl->rseq = dd->uas_state->rseq++;
	
	/* Add to queue if there's pending response, otherwise
	 * transmit immediately.
	 */
	if (!pj_list_empty(&dd->uas_state->tx_data_list)) {
	    
	    int code = tdata->msg->line.status.code;
	    
	    /* Will send later */
	    pj_list_push_back(&dd->uas_state->tx_data_list, tl);
	    status = PJ_SUCCESS;
	    
	    PJ_LOG(4,(dd->inv->dlg->obj_name, 
		      "Reliable %d response enqueued (%d pending)", 
		      code, pj_list_size(&dd->uas_state->tx_data_list)));
	    
	} else {
	    pj_list_push_back(&dd->uas_state->tx_data_list, tl);
	    
	    dd->uas_state->retransmit_count = 0;
	    on_retransmit(NULL, &dd->uas_state->retransmit_timer);
	    status = PJ_SUCCESS;
	}
	
    }
    
    return status;
}


