/* $Id$ */
/* 
 * Copyright (C) 2003-2007 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_regc.h>
#include <pjsip/sip_endpoint.h>
#include <pjsip/sip_parser.h>
#include <pjsip/sip_module.h>
#include <pjsip/sip_transaction.h>
#include <pjsip/sip_event.h>
#include <pjsip/sip_util.h>
#include <pjsip/sip_auth_msg.h>
#include <pjsip/sip_errno.h>
#include <pj/assert.h>
#include <pj/guid.h>
#include <pj/os.h>
#include <pj/pool.h>
#include <pj/log.h>
#include <pj/rand.h>
#include <pj/string.h>


#define REFRESH_TIMER		1
#define DELAY_BEFORE_REFRESH	5
#define THIS_FILE		"sip_reg.c"

/* Outgoing transaction timeout when server sends 100 but never replies
 * with final response. Value is in MILISECONDS!
 */
#define REGC_TSX_TIMEOUT	33000


/**
 * SIP client registration structure.
 */
struct pjsip_regc
{
    pj_pool_t			*pool;
    pjsip_endpoint		*endpt;
    pj_bool_t			 _delete_flag;
    pj_bool_t			 has_tsx;
    pj_int32_t			 busy;

    void			*token;
    pjsip_regc_cb		*cb;

    pj_str_t			 str_srv_url;
    pjsip_uri			*srv_url;
    pjsip_cid_hdr		*cid_hdr;
    pjsip_cseq_hdr		*cseq_hdr;
    pj_str_t			 from_uri;
    pjsip_from_hdr		*from_hdr;
    pjsip_to_hdr		*to_hdr;
    pjsip_hdr			 contact_hdr_list;
    pjsip_expires_hdr		*expires_hdr;
    pjsip_contact_hdr		*unreg_contact_hdr;
    pjsip_expires_hdr		*unreg_expires_hdr;
    pj_uint32_t			 expires;
    pjsip_route_hdr		 route_set;
    pjsip_hdr			 hdr_list;

    /* Authorization sessions. */
    pjsip_auth_clt_sess		 auth_sess;

    /* Auto refresh registration. */
    pj_bool_t			 auto_reg;
    pj_time_val			 last_reg;
    pj_time_val			 next_reg;
    pj_timer_entry		 timer;

    /* Transport selector */
    pjsip_tpselector		 tp_sel;

    /* Last transport used. We acquire the transport to keep
     * it open.
     */
    pjsip_transport		*last_transport;
};



PJ_DEF(pj_status_t) pjsip_regc_create( pjsip_endpoint *endpt, void *token,
				       pjsip_regc_cb *cb,
				       pjsip_regc **p_regc)
{
    pj_pool_t *pool;
    pjsip_regc *regc;
    pj_status_t status;

    /* Verify arguments. */
    PJ_ASSERT_RETURN(endpt && cb && p_regc, PJ_EINVAL);

    pool = pjsip_endpt_create_pool(endpt, "regc%p", 1024, 1024);
    PJ_ASSERT_RETURN(pool != NULL, PJ_ENOMEM);

    regc = PJ_POOL_ZALLOC_T(pool, pjsip_regc);

    regc->pool = pool;
    regc->endpt = endpt;
    regc->token = token;
    regc->cb = cb;
    regc->expires = PJSIP_REGC_EXPIRATION_NOT_SPECIFIED;

    status = pjsip_auth_clt_init(&regc->auth_sess, endpt, regc->pool, 0);
    if (status != PJ_SUCCESS)
	return status;

    pj_list_init(&regc->route_set);
    pj_list_init(&regc->hdr_list);
    pj_list_init(&regc->contact_hdr_list);

    /* Done */
    *p_regc = regc;
    return PJ_SUCCESS;
}


PJ_DEF(pj_status_t) pjsip_regc_destroy(pjsip_regc *regc)
{
    PJ_ASSERT_RETURN(regc, PJ_EINVAL);

    if (regc->has_tsx || regc->busy) {
	regc->_delete_flag = 1;
	regc->cb = NULL;
    } else {
	pjsip_tpselector_dec_ref(&regc->tp_sel);
	if (regc->last_transport) {
	    pjsip_transport_dec_ref(regc->last_transport);
	    regc->last_transport = NULL;
	}
	pjsip_endpt_release_pool(regc->endpt, regc->pool);
    }

    return PJ_SUCCESS;
}


PJ_DEF(pj_status_t) pjsip_regc_get_info( pjsip_regc *regc,
					 pjsip_regc_info *info )
{
    PJ_ASSERT_RETURN(regc && info, PJ_EINVAL);

    info->server_uri = regc->str_srv_url;
    info->client_uri = regc->from_uri;
    info->is_busy = (regc->busy || regc->has_tsx);
    info->auto_reg = regc->auto_reg;
    info->interval = regc->expires;
    
    if (regc->has_tsx)
	info->next_reg = 0;
    else if (regc->auto_reg == 0)
	info->next_reg = 0;
    else if (regc->expires < 0)
	info->next_reg = regc->expires;
    else {
	pj_time_val now, next_reg;

	next_reg = regc->next_reg;
	pj_gettimeofday(&now);
	PJ_TIME_VAL_SUB(next_reg, now);
	info->next_reg = next_reg.sec;
    }

    return PJ_SUCCESS;
}


PJ_DEF(pj_pool_t*) pjsip_regc_get_pool(pjsip_regc *regc)
{
    return regc->pool;
}

static void set_expires( pjsip_regc *regc, pj_uint32_t expires)
{
    if (expires != regc->expires) {
	regc->expires_hdr = pjsip_expires_hdr_create(regc->pool, expires);
    } else {
	regc->expires_hdr = NULL;
    }
}


static pj_status_t set_contact( pjsip_regc *regc,
			        int contact_cnt,
				const pj_str_t contact[] )
{
    const pj_str_t CONTACT = { "Contact", 7 };
    int i;
    
    /* Clear existing contacts */
    pj_list_init(&regc->contact_hdr_list);

    for (i=0; i<contact_cnt; ++i) {
	pjsip_hdr *hdr;
	pj_str_t tmp;

	pj_strdup_with_null(regc->pool, &tmp, &contact[i]);
	hdr = (pjsip_hdr*)
              pjsip_parse_hdr(regc->pool, &CONTACT, tmp.ptr, tmp.slen, NULL);
	if (hdr == NULL) {
	    PJ_LOG(4,(THIS_FILE, "Invalid Contact URI: \"%.*s\"", 
		     (int)tmp.slen, tmp.ptr));
	    return PJSIP_EINVALIDURI;
	}

	pj_list_push_back(&regc->contact_hdr_list, hdr);
    }

    return PJ_SUCCESS;
}


PJ_DEF(pj_status_t) pjsip_regc_init( pjsip_regc *regc,
				     const pj_str_t *srv_url,
				     const pj_str_t *from_url,
				     const pj_str_t *to_url,
				     int contact_cnt,
				     const pj_str_t contact[],
				     pj_uint32_t expires)
{
    pj_str_t tmp;
    pj_status_t status;

    PJ_ASSERT_RETURN(regc && srv_url && from_url && to_url && 
		     contact_cnt && contact && expires, PJ_EINVAL);

    /* Copy server URL. */
    pj_strdup_with_null(regc->pool, &regc->str_srv_url, srv_url);

    /* Set server URL. */
    tmp = regc->str_srv_url;
    regc->srv_url = pjsip_parse_uri( regc->pool, tmp.ptr, tmp.slen, 0);
    if (regc->srv_url == NULL) {
	return PJSIP_EINVALIDURI;
    }

    /* Set "From" header. */
    pj_strdup_with_null(regc->pool, &regc->from_uri, from_url);
    tmp = regc->from_uri;
    regc->from_hdr = pjsip_from_hdr_create(regc->pool);
    regc->from_hdr->uri = pjsip_parse_uri(regc->pool, tmp.ptr, tmp.slen, 
					  PJSIP_PARSE_URI_AS_NAMEADDR);
    if (!regc->from_hdr->uri) {
	PJ_LOG(4,(THIS_FILE, "regc: invalid source URI %.*s", 
		  from_url->slen, from_url->ptr));
	return PJSIP_EINVALIDURI;
    }

    /* Set "To" header. */
    pj_strdup_with_null(regc->pool, &tmp, to_url);
    regc->to_hdr = pjsip_to_hdr_create(regc->pool);
    regc->to_hdr->uri = pjsip_parse_uri(regc->pool, tmp.ptr, tmp.slen, 
					PJSIP_PARSE_URI_AS_NAMEADDR);
    if (!regc->to_hdr->uri) {
	PJ_LOG(4,(THIS_FILE, "regc: invalid target URI %.*s", to_url->slen, to_url->ptr));
	return PJSIP_EINVALIDURI;
    }


    /* Set "Contact" header. */
    status = set_contact( regc, contact_cnt, contact);
    if (status != PJ_SUCCESS)
	return status;

    /* Set "Expires" header, if required. */
    set_expires( regc, expires);

    /* Set "Call-ID" header. */
    regc->cid_hdr = pjsip_cid_hdr_create(regc->pool);
    pj_create_unique_string(regc->pool, &regc->cid_hdr->id);

    /* Set "CSeq" header. */
    regc->cseq_hdr = pjsip_cseq_hdr_create(regc->pool);
    regc->cseq_hdr->cseq = pj_rand() % 0xFFFF;
    pjsip_method_set( &regc->cseq_hdr->method, PJSIP_REGISTER_METHOD);

    /* Create "Contact" header used in unregistration. */
    regc->unreg_contact_hdr = pjsip_contact_hdr_create(regc->pool);
    regc->unreg_contact_hdr->star = 1;

    /* Create "Expires" header used in unregistration. */
    regc->unreg_expires_hdr = pjsip_expires_hdr_create( regc->pool, 0);

    /* Done. */
    return PJ_SUCCESS;
}

PJ_DEF(pj_status_t) pjsip_regc_set_credentials( pjsip_regc *regc,
						int count,
						const pjsip_cred_info cred[] )
{
    PJ_ASSERT_RETURN(regc && count && cred, PJ_EINVAL);
    return pjsip_auth_clt_set_credentials(&regc->auth_sess, count, cred);
}

PJ_DEF(pj_status_t) pjsip_regc_set_prefs( pjsip_regc *regc,
					  const pjsip_auth_clt_pref *pref)
{
    PJ_ASSERT_RETURN(regc && pref, PJ_EINVAL);
    return pjsip_auth_clt_set_prefs(&regc->auth_sess, pref);
}

PJ_DEF(pj_status_t) pjsip_regc_set_route_set( pjsip_regc *regc,
					      const pjsip_route_hdr *route_set)
{
    const pjsip_route_hdr *chdr;

    PJ_ASSERT_RETURN(regc && route_set, PJ_EINVAL);

    pj_list_init(&regc->route_set);

    chdr = route_set->next;
    while (chdr != route_set) {
	pj_list_push_back(&regc->route_set, pjsip_hdr_clone(regc->pool, chdr));
	chdr = chdr->next;
    }

    return PJ_SUCCESS;
}


/*
 * Bind client registration to a specific transport/listener. 
 */
PJ_DEF(pj_status_t) pjsip_regc_set_transport( pjsip_regc *regc,
					      const pjsip_tpselector *sel)
{
    PJ_ASSERT_RETURN(regc && sel, PJ_EINVAL);

    pjsip_tpselector_dec_ref(&regc->tp_sel);
    pj_memcpy(&regc->tp_sel, sel, sizeof(*sel));
    pjsip_tpselector_add_ref(&regc->tp_sel);

    return PJ_SUCCESS;
}


PJ_DEF(pj_status_t) pjsip_regc_add_headers( pjsip_regc *regc,
					    const pjsip_hdr *hdr_list)
{
    const pjsip_hdr *hdr;

    PJ_ASSERT_RETURN(regc && hdr_list, PJ_EINVAL);

    //This is "add" operation, so don't remove headers.
    //pj_list_init(&regc->hdr_list);

    hdr = hdr_list->next;
    while (hdr != hdr_list) {
	pj_list_push_back(&regc->hdr_list, pjsip_hdr_clone(regc->pool, hdr));
	hdr = hdr->next;
    }

    return PJ_SUCCESS;
}

static pj_status_t create_request(pjsip_regc *regc, 
				  pjsip_tx_data **p_tdata)
{
    pj_status_t status;
    pjsip_tx_data *tdata;

    PJ_ASSERT_RETURN(regc && p_tdata, PJ_EINVAL);

    /* Create the request. */
    status = pjsip_endpt_create_request_from_hdr( regc->endpt, 
						  pjsip_get_register_method(),
						  regc->srv_url,
						  regc->from_hdr,
						  regc->to_hdr,
						  NULL,
						  regc->cid_hdr,
						  regc->cseq_hdr->cseq,
						  NULL,
						  &tdata);
    if (status != PJ_SUCCESS)
	return status;

    /* Add cached authorization headers. */
    pjsip_auth_clt_init_req( &regc->auth_sess, tdata );

    /* Add Route headers from route set, ideally after Via header */
    if (!pj_list_empty(&regc->route_set)) {
	pjsip_hdr *route_pos;
	const pjsip_route_hdr *route;

	route_pos = (pjsip_hdr*)
		    pjsip_msg_find_hdr(tdata->msg, PJSIP_H_VIA, NULL);
	if (!route_pos)
	    route_pos = &tdata->msg->hdr;

	route = regc->route_set.next;
	while (route != &regc->route_set) {
	    pjsip_hdr *new_hdr = (pjsip_hdr*)
				 pjsip_hdr_shallow_clone(tdata->pool, route);
	    pj_list_insert_after(route_pos, new_hdr);
	    route_pos = new_hdr;
	    route = route->next;
	}
    }

    /* Add additional request headers */
    if (!pj_list_empty(&regc->hdr_list)) {
	const pjsip_hdr *hdr;

	hdr = regc->hdr_list.next;
	while (hdr != &regc->hdr_list) {
	    pjsip_hdr *new_hdr = (pjsip_hdr*)
				 pjsip_hdr_shallow_clone(tdata->pool, hdr);
	    pjsip_msg_add_hdr(tdata->msg, new_hdr);
	    hdr = hdr->next;
	}
    }

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


PJ_DEF(pj_status_t) pjsip_regc_register(pjsip_regc *regc, pj_bool_t autoreg,
					pjsip_tx_data **p_tdata)
{
    pjsip_msg *msg;
    pjsip_hdr *hdr;
    pj_status_t status;
    pjsip_tx_data *tdata;

    PJ_ASSERT_RETURN(regc && p_tdata, PJ_EINVAL);

    status = create_request(regc, &tdata);
    if (status != PJ_SUCCESS)
	return status;

    msg = tdata->msg;

    /* Add Contact headers. */
    hdr = regc->contact_hdr_list.next;
    while (hdr != &regc->contact_hdr_list) {
	pjsip_msg_add_hdr(msg, (pjsip_hdr*)
			       pjsip_hdr_shallow_clone(tdata->pool, hdr));
	hdr = hdr->next;
    }

    if (regc->expires_hdr)
	pjsip_msg_add_hdr(msg, (pjsip_hdr*)
			       pjsip_hdr_shallow_clone(tdata->pool,
						       regc->expires_hdr));

    if (regc->timer.id != 0) {
	pjsip_endpt_cancel_timer(regc->endpt, &regc->timer);
	regc->timer.id = 0;
    }

    regc->auto_reg = autoreg;

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


PJ_DEF(pj_status_t) pjsip_regc_unregister(pjsip_regc *regc,
					  pjsip_tx_data **p_tdata)
{
    pjsip_tx_data *tdata;
    pjsip_msg *msg;
    pjsip_hdr *hdr;
    pj_status_t status;

    PJ_ASSERT_RETURN(regc && p_tdata, PJ_EINVAL);

    if (regc->timer.id != 0) {
	pjsip_endpt_cancel_timer(regc->endpt, &regc->timer);
	regc->timer.id = 0;
    }

    status = create_request(regc, &tdata);
    if (status != PJ_SUCCESS)
	return status;

    msg = tdata->msg;

    /* Add Contact headers. */
    hdr = regc->contact_hdr_list.next;
    while (hdr != &regc->contact_hdr_list) {
	pjsip_msg_add_hdr(msg, (pjsip_hdr*)
			       pjsip_hdr_shallow_clone(tdata->pool, hdr));
	hdr = hdr->next;
    }

    pjsip_msg_add_hdr( msg, (pjsip_hdr*)regc->unreg_expires_hdr);

    *p_tdata = tdata;
    return PJ_SUCCESS;
}

PJ_DEF(pj_status_t) pjsip_regc_unregister_all(pjsip_regc *regc,
					      pjsip_tx_data **p_tdata)
{
    pjsip_tx_data *tdata;
    pjsip_msg *msg;
    pj_status_t status;

    PJ_ASSERT_RETURN(regc && p_tdata, PJ_EINVAL);

    if (regc->timer.id != 0) {
	pjsip_endpt_cancel_timer(regc->endpt, &regc->timer);
	regc->timer.id = 0;
    }

    status = create_request(regc, &tdata);
    if (status != PJ_SUCCESS)
	return status;

    msg = tdata->msg;
    pjsip_msg_add_hdr( msg, (pjsip_hdr*)regc->unreg_contact_hdr);
    pjsip_msg_add_hdr( msg, (pjsip_hdr*)regc->unreg_expires_hdr);

    *p_tdata = tdata;
    return PJ_SUCCESS;
}


PJ_DEF(pj_status_t) pjsip_regc_update_contact(  pjsip_regc *regc,
					        int contact_cnt,
						const pj_str_t contact[] )
{
    PJ_ASSERT_RETURN(regc, PJ_EINVAL);
    return set_contact( regc, contact_cnt, contact );
}


PJ_DEF(pj_status_t) pjsip_regc_update_expires(  pjsip_regc *regc,
					        pj_uint32_t expires )
{
    PJ_ASSERT_RETURN(regc, PJ_EINVAL);
    set_expires( regc, expires );
    return PJ_SUCCESS;
}


static void call_callback(pjsip_regc *regc, pj_status_t status, int st_code, 
			  const pj_str_t *reason,
			  pjsip_rx_data *rdata, pj_int32_t expiration,
			  int contact_cnt, pjsip_contact_hdr *contact[])
{
    struct pjsip_regc_cbparam cbparam;


    if (!regc->cb)
	return;

    cbparam.regc = regc;
    cbparam.token = regc->token;
    cbparam.status = status;
    cbparam.code = st_code;
    cbparam.reason = *reason;
    cbparam.rdata = rdata;
    cbparam.contact_cnt = contact_cnt;
    cbparam.expiration = expiration;
    if (contact_cnt) {
	pj_memcpy( cbparam.contact, contact, 
		   contact_cnt*sizeof(pjsip_contact_hdr*));
    }

    (*regc->cb)(&cbparam);
}

static void regc_refresh_timer_cb( pj_timer_heap_t *timer_heap,
				   struct pj_timer_entry *entry)
{
    pjsip_regc *regc = (pjsip_regc*) entry->user_data;
    pjsip_tx_data *tdata;
    pj_status_t status;
    
    PJ_UNUSED_ARG(timer_heap);

    /* Temporarily increase busy flag to prevent regc from being deleted
     * in pjsip_regc_send()
     */
    regc->busy++;

    entry->id = 0;
    status = pjsip_regc_register(regc, 1, &tdata);
    if (status == PJ_SUCCESS) {
	status = pjsip_regc_send(regc, tdata);
    } 
    
    if (status != PJ_SUCCESS && regc->cb) {
	char errmsg[PJ_ERR_MSG_SIZE];
	pj_str_t reason = pj_strerror(status, errmsg, sizeof(errmsg));
	call_callback(regc, status, 400, &reason, NULL, -1, 0, NULL);
    }

    regc->busy--;

    /* Delete the record if user destroy regc during the callback. */
    if (regc->_delete_flag && regc->busy==0) {
	pjsip_regc_destroy(regc);
    }
}

static void tsx_callback(void *token, pjsip_event *event)
{
    pj_status_t status;
    pjsip_regc *regc = (pjsip_regc*) token;
    pjsip_transaction *tsx = event->body.tsx_state.tsx;
    
    /* Decrement pending transaction counter. */
    pj_assert(regc->has_tsx);
    regc->has_tsx = PJ_FALSE;

    /* Add reference to the transport */
    if (tsx->transport != regc->last_transport) {
	if (regc->last_transport) {
	    pjsip_transport_dec_ref(regc->last_transport);
	    regc->last_transport = NULL;
	}

	if (tsx->transport) {
	    regc->last_transport = tsx->transport;
	    pjsip_transport_add_ref(regc->last_transport);
	}
    }

    /* Handle 401/407 challenge (even when _delete_flag is set) */
    if (tsx->status_code == PJSIP_SC_PROXY_AUTHENTICATION_REQUIRED ||
	tsx->status_code == PJSIP_SC_UNAUTHORIZED)
    {
	pjsip_rx_data *rdata = event->body.tsx_state.src.rdata;
	pjsip_tx_data *tdata;

	status = pjsip_auth_clt_reinit_req( &regc->auth_sess,
					    rdata, 
					    tsx->last_tx,  
					    &tdata);

	if (status == PJ_SUCCESS) {
	    ++regc->busy;
	    status = pjsip_regc_send(regc, tdata);
	    --regc->busy;
	}
	
	if (status != PJ_SUCCESS) {

	    /* Only call callback if application is still interested
	     * in it.
	     */
	    if (regc->_delete_flag == 0) {
		/* Increment busy flag temporarily to prevent regc from
		 * being destroyed.
		 */
		++regc->busy;

		call_callback(regc, status, tsx->status_code, 
			      &rdata->msg_info.msg->line.status.reason,
			      rdata, -1, 0, NULL);

		/* Decrement busy flag */
		--regc->busy;
	    }
	}

    } else if (regc->_delete_flag) {

	/* User has called pjsip_regc_destroy(), so don't call callback. 
	 * This regc will be destroyed later in this function.
	 */

	/* Nothing to do */
	;

    } else {
	int contact_cnt = 0;
	pjsip_contact_hdr *contact[PJSIP_REGC_MAX_CONTACT];
	pjsip_rx_data *rdata;
	enum { NOEXP = 0x1FFFFFFF };
	pj_int32_t expiration = NOEXP;

	if (tsx->status_code/100 == 2) {
	    int i;
	    pjsip_contact_hdr *hdr;
	    pjsip_msg *msg;
	    pj_bool_t has_our_contact = PJ_FALSE;
	    pjsip_expires_hdr *expires;

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

	    /* Record all Contact headers in the response */
	    hdr = (pjsip_contact_hdr*)
		  pjsip_msg_find_hdr( msg, PJSIP_H_CONTACT, NULL);
	    while (hdr) {
		contact[contact_cnt++] = hdr;
		hdr = hdr->next;
		if (hdr == (void*)&msg->hdr)
		    break;
		hdr = (pjsip_contact_hdr*)
		      pjsip_msg_find_hdr(msg, PJSIP_H_CONTACT, hdr);
	    }

	    /* Set default expiration value to the value of Expires hdr */
	    expires = (pjsip_expires_hdr*)
		      pjsip_msg_find_hdr(msg, PJSIP_H_EXPIRES, NULL);

	    if (expires)
		expiration = expires->ivalue;
	    
	    /* Enumerate all Contact headers found in the response and
	     * find the Contact(s) that we register.
	     */
	    for (i=0; i<contact_cnt; ++i) {
		pjsip_contact_hdr *our_contact;

		our_contact = (pjsip_contact_hdr*)
			      regc->contact_hdr_list.next;

		while ((void*)our_contact != (void*)&regc->contact_hdr_list) {

		    const pjsip_uri *uri1, *uri2;

		    /* Compare URIs.
		     * Exclude the display name when comparing the URI since
		     * server may not return it.
		     */

		    uri1=(const pjsip_uri*)pjsip_uri_get_uri(contact[i]->uri);
		    uri2=(const pjsip_uri*)pjsip_uri_get_uri(our_contact->uri);
		    if (pjsip_uri_cmp(PJSIP_URI_IN_CONTACT_HDR, uri1, uri2)==0)
		    {
			has_our_contact = PJ_TRUE;

			if (contact[i]->expires >= 0 && 
			    contact[i]->expires < expiration) 
			{
			    /* Get the lowest expiration time. */
			    expiration = contact[i]->expires;
			}
		    }

		    our_contact = our_contact->next;
		}
	    }

	    /* When the response doesn't contain our Contact header, that
	     * means we have been unregistered.
	     */
	    if (!has_our_contact)
		expiration = 0;

	    /* Schedule next registration */
	    if (regc->auto_reg && expiration != 0 && expiration != NOEXP) {
		pj_time_val delay = { 0, 0};

		delay.sec = expiration - DELAY_BEFORE_REFRESH;
		if (regc->expires != PJSIP_REGC_EXPIRATION_NOT_SPECIFIED && 
		    delay.sec > (pj_int32_t)regc->expires) 
		{
		    delay.sec = regc->expires;
		}
		if (delay.sec < DELAY_BEFORE_REFRESH) 
		    delay.sec = DELAY_BEFORE_REFRESH;
		regc->timer.cb = &regc_refresh_timer_cb;
		regc->timer.id = REFRESH_TIMER;
		regc->timer.user_data = regc;
		pjsip_endpt_schedule_timer( regc->endpt, &regc->timer, &delay);
		pj_gettimeofday(&regc->last_reg);
		regc->next_reg = regc->last_reg;
		regc->next_reg.sec += delay.sec;
	    }

	} else {
	    rdata = (event->body.tsx_state.type==PJSIP_EVENT_RX_MSG) ? 
			event->body.tsx_state.src.rdata : NULL;
	}

	/* Increment busy flag temporarily to prevent regc from
	 * being destroyed.
	 */
	++regc->busy;

	/* Call callback. */
	if (expiration == NOEXP) expiration = -1;
	call_callback(regc, PJ_SUCCESS, tsx->status_code, 
		      (rdata ? &rdata->msg_info.msg->line.status.reason 
			: pjsip_get_status_text(tsx->status_code)),
		      rdata, expiration, 
		      contact_cnt, contact);

	/* Decrement busy flag */
	--regc->busy;
    }

    /* Delete the record if user destroy regc during the callback. */
    if (regc->_delete_flag && regc->busy==0) {
	pjsip_regc_destroy(regc);
    }
}

PJ_DEF(pj_status_t) pjsip_regc_send(pjsip_regc *regc, pjsip_tx_data *tdata)
{
    pj_status_t status;
    pjsip_cseq_hdr *cseq_hdr;
    pj_uint32_t cseq;

    /* Make sure we don't have pending transaction. */
    if (regc->has_tsx) {
	PJ_LOG(4,(THIS_FILE, "Unable to send request, regc has another "
			     "transaction pending"));
	pjsip_tx_data_dec_ref( tdata );
	return PJSIP_EBUSY;
    }

    /* Invalidate message buffer. */
    pjsip_tx_data_invalidate_msg(tdata);

    /* Increment CSeq */
    cseq = ++regc->cseq_hdr->cseq;
    cseq_hdr = (pjsip_cseq_hdr*)
	       pjsip_msg_find_hdr(tdata->msg, PJSIP_H_CSEQ, NULL);
    cseq_hdr->cseq = cseq;

    /* Increment pending transaction first, since transaction callback
     * may be called even before send_request() returns!
     */
    regc->has_tsx = PJ_TRUE;
    ++regc->busy;
    status = pjsip_endpt_send_request(regc->endpt, tdata, REGC_TSX_TIMEOUT,
				      regc, &tsx_callback);
    if (status!=PJ_SUCCESS) {
	PJ_LOG(4,(THIS_FILE, "Error sending request, status=%d", status));
    }
    --regc->busy;

    /* Delete the record if user destroy regc during the callback. */
    if (regc->_delete_flag && regc->busy==0) {
	pjsip_regc_destroy(regc);
    }

    return status;
}


