/* $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-simple/evsub.h>
#include <pjsip-simple/evsub_msg.h>
#include <pjsip-simple/errno.h>
#include <pjsip/sip_errno.h>
#include <pjsip/sip_module.h>
#include <pjsip/sip_endpoint.h>
#include <pjsip/sip_dialog.h>
#include <pjsip/sip_auth.h>
#include <pjsip/sip_transaction.h>
#include <pjsip/sip_event.h>
#include <pj/assert.h>
#include <pj/guid.h>
#include <pj/log.h>
#include <pj/os.h>
#include <pj/pool.h>
#include <pj/string.h>


#define THIS_FILE	"evsub.c"

/*
 * Global constant
 */

/* Let's define this enum, so that it'll trigger compilation error
 * when somebody define the same enum in sip_msg.h
 */
enum
{
    PJSIP_SUBSCRIBE_METHOD = PJSIP_OTHER_METHOD,
    PJSIP_NOTIFY_METHOD = PJSIP_OTHER_METHOD
};

const pjsip_method pjsip_subscribe_method = 
{
    PJSIP_SUBSCRIBE_METHOD,
    { "SUBSCRIBE", 9 }
};

const pjsip_method pjsip_notify_method = 
{
    PJSIP_NOTIFY_METHOD,
    { "NOTIFY", 6 }
};

/*
 * Static prototypes.
 */
static void	   mod_evsub_on_tsx_state(pjsip_transaction*, pjsip_event*);
static pj_status_t mod_evsub_unload(void);


/*
 * State names.
 */
static pj_str_t evsub_state_names[] = 
{
    { "NULL",	    4},
    { "SENT",	    4},
    { "ACCEPTED",   8},
    { "PENDING",    7},
    { "ACTIVE",	    6},
    { "TERMINATED", 10},
    { "UNKNOWN",    7}
};

/*
 * Timer constants.
 */

/* Number of seconds to send SUBSCRIBE before the actual expiration */
#define TIME_UAC_REFRESH	5

/* Time to wait for the final NOTIFY after sending unsubscription */
#define TIME_UAC_TERMINATE	5

/* If client responds NOTIFY with non-2xx final response (such as 401),
 * wait for this seconds for further NOTIFY, otherwise client will
 * unsubscribe
 */
#define TIME_UAC_WAIT_NOTIFY	5


/*
 * Timer id
 */
enum timer_id
{
    /* No timer. */
    TIMER_TYPE_NONE,

    /* Time to refresh client subscription. 
     * The action is to call on_client_refresh() callback.
     */
    TIMER_TYPE_UAC_REFRESH,

    /* UAS timeout after to subscription refresh. 
     * The action is to call on_server_timeout() callback.
     */
    TIMER_TYPE_UAS_TIMEOUT,

    /* UAC waiting for final NOTIFY after unsubscribing 
     * The action is to terminate.
     */
    TIMER_TYPE_UAC_TERMINATE,

    /* UAC waiting for further NOTIFY after sending non-2xx response to 
     * NOTIFY. The action is to unsubscribe.
     */
    TIMER_TYPE_UAC_WAIT_NOTIFY,

    /* Max nb of timer types. */
    TIMER_TYPE_MAX
};

static const char *timer_names[] = 
{
    "None",
    "UAC_REFRESH",
    "UAS_TIMEOUT"
    "UAC_TERMINATE",
    "UAC_WAIT_NOTIFY",
    "INVALID_TIMER"
};

/*
 * Definition of event package.
 */
struct evpkg
{
    PJ_DECL_LIST_MEMBER(struct evpkg);

    pj_str_t		 pkg_name;
    pjsip_module	*pkg_mod;
    unsigned		 pkg_expires;
    pjsip_accept_hdr	*pkg_accept;
};


/*
 * Event subscription module (mod-evsub).
 */
static struct mod_evsub
{
    pjsip_module	     mod;
    pj_pool_t		    *pool;
    pjsip_endpoint	    *endpt;
    struct evpkg	     pkg_list;
    pjsip_allow_events_hdr  *allow_events_hdr;

} mod_evsub = 
{
    {
	NULL, NULL,			    /* prev, next.		*/
	{ "mod-evsub", 9 },		    /* Name.			*/
	-1,				    /* Id			*/
	PJSIP_MOD_PRIORITY_DIALOG_USAGE,    /* Priority			*/
	NULL,				    /* load()			*/
	NULL,				    /* start()			*/
	NULL,				    /* stop()			*/
	&mod_evsub_unload,		    /* unload()			*/
	NULL,				    /* on_rx_request()		*/
	NULL,				    /* on_rx_response()		*/
	NULL,				    /* on_tx_request.		*/
	NULL,				    /* on_tx_response()		*/
	&mod_evsub_on_tsx_state,	    /* on_tsx_state()		*/
    }
};


/*
 * Event subscription session.
 */
struct pjsip_evsub
{
    char		  obj_name[PJ_MAX_OBJ_NAME]; /**< Name.		    */
    pj_pool_t		 *pool;		/**< Pool.			    */
    pjsip_endpoint	 *endpt;	/**< Endpoint instance.		    */
    pjsip_dialog	 *dlg;		/**< Underlying dialog.		    */
    struct evpkg	 *pkg;		/**< The event package.		    */
    unsigned		  option;	/**< Options.			    */
    pjsip_evsub_user	  user;		/**< Callback.			    */
    pj_bool_t		  call_cb;	/**< Notify callback?		    */
    pjsip_role_e	  role;		/**< UAC=subscriber, UAS=notifier   */
    pjsip_evsub_state	  state;	/**< Subscription state.	    */
    pj_str_t		  state_str;	/**< String describing the state.   */
    pjsip_evsub_state	  dst_state;	/**< Pending state to be set.	    */
    pj_str_t		  dst_state_str;/**< Pending state to be set.	    */
    pjsip_method	  method;	/**< Method that established subscr.*/
    pjsip_event_hdr	 *event;	/**< Event description.		    */
    pjsip_expires_hdr	 *expires;	/**< Expires header		    */
    pjsip_accept_hdr	 *accept;	/**< Local Accept header.	    */

    pj_time_val		  refresh_time;	/**< Time to refresh.		    */
    pj_timer_entry	  timer;	/**< Internal timer.		    */
    int			  pending_tsx;	/**< Number of pending transactions.*/
    pjsip_transaction	 *pending_sub;	/**< Pending UAC SUBSCRIBE tsx.	    */

    void		 *mod_data[PJSIP_MAX_MODULE];	/**< Module data.   */
};


/*
 * This is the structure that will be "attached" to dialog.
 * The purpose is to allow multiple subscriptions inside a dialog.
 */
struct dlgsub
{
    PJ_DECL_LIST_MEMBER(struct dlgsub);
    pjsip_evsub *sub;
};


/* Static vars. */
static const pj_str_t STR_EVENT	     = { "Event", 5 };
static const pj_str_t STR_SUB_STATE  = { "Subscription-State", 18 };
static const pj_str_t STR_TERMINATED = { "terminated", 10 };
static const pj_str_t STR_ACTIVE     = { "active", 6 };
static const pj_str_t STR_PENDING    = { "pending", 7 };
static const pj_str_t STR_TIMEOUT    = { "timeout", 7};


/*
 * On unload module.
 */
static pj_status_t mod_evsub_unload(void)
{
    pjsip_endpt_release_pool(mod_evsub.endpt, mod_evsub.pool);
    mod_evsub.pool = NULL;

    return PJ_SUCCESS;
}

/* Proto for pjsipsimple_strerror().
 * Defined in errno.c
 */
PJ_DECL(pj_str_t) pjsipsimple_strerror( pj_status_t statcode, 
				        char *buf, pj_size_t bufsize );

/*
 * Init and register module.
 */
PJ_DEF(pj_status_t) pjsip_evsub_init_module(pjsip_endpoint *endpt)
{
    pj_status_t status;
    pj_str_t method_tags[] = {
	{ "SUBSCRIBE", 9},
	{ "NOTIFY", 6}
    };

    pj_register_strerror(PJSIP_SIMPLE_ERRNO_START, PJ_ERRNO_SPACE_SIZE,
			 &pjsipsimple_strerror);

    PJ_ASSERT_RETURN(endpt != NULL, PJ_EINVAL);
    PJ_ASSERT_RETURN(mod_evsub.mod.id == -1, PJ_EINVALIDOP);

    /* Keep endpoint for future reference: */
    mod_evsub.endpt = endpt;

    /* Init event package list: */
    pj_list_init(&mod_evsub.pkg_list);

    /* Create pool: */
    mod_evsub.pool = pjsip_endpt_create_pool(endpt, "evsub", 4000, 4000);
    if (!mod_evsub.pool)
	return PJ_ENOMEM;

    /* Register module: */
    status = pjsip_endpt_register_module(endpt, &mod_evsub.mod);
    if (status  != PJ_SUCCESS)
	goto on_error;
 
    /* Create Allow-Events header: */
    mod_evsub.allow_events_hdr = pjsip_allow_events_hdr_create(mod_evsub.pool);

    /* Register SIP-event specific headers parser: */
    pjsip_evsub_init_parser();

    /* Register new methods SUBSCRIBE and NOTIFY in Allow-ed header */
    pjsip_endpt_add_capability(endpt, &mod_evsub.mod, PJSIP_H_ALLOW, NULL,
			       2, method_tags);

    /* Done. */
    return PJ_SUCCESS;

on_error:
    if (mod_evsub.pool) {
	pjsip_endpt_release_pool(endpt, mod_evsub.pool);
	mod_evsub.pool = NULL;
    }
    mod_evsub.endpt = NULL;
    return status;
}


/*
 * Get the instance of the module.
 */
PJ_DEF(pjsip_module*) pjsip_evsub_instance(void)
{
    PJ_ASSERT_RETURN(mod_evsub.mod.id != -1, NULL);

    return &mod_evsub.mod;
}


/*
 * Get the event subscription instance in the transaction.
 */
PJ_DEF(pjsip_evsub*) pjsip_tsx_get_evsub(pjsip_transaction *tsx)
{
    return tsx->mod_data[mod_evsub.mod.id];
}


/*
 * Set event subscription's module data.
 */
PJ_DEF(void) pjsip_evsub_set_mod_data( pjsip_evsub *sub, unsigned mod_id,
				       void *data )
{
    PJ_ASSERT_ON_FAIL(mod_id < PJSIP_MAX_MODULE, return);
    sub->mod_data[mod_id] = data;
}


/*
 * Get event subscription's module data.
 */
PJ_DEF(void*) pjsip_evsub_get_mod_data( pjsip_evsub *sub, unsigned mod_id )
{
    PJ_ASSERT_RETURN(mod_id < PJSIP_MAX_MODULE, NULL);
    return sub->mod_data[mod_id];
}


/*
 * Find registered event package with matching name.
 */
static struct evpkg* find_pkg(const pj_str_t *event_name)
{
    struct evpkg *pkg;

    pkg = mod_evsub.pkg_list.next;
    while (pkg != &mod_evsub.pkg_list) {

	if (pj_stricmp(&pkg->pkg_name, event_name) == 0) {
	    return pkg;
	}

	pkg = pkg->next;
    }

    return NULL;
}

/*
 * Register an event package
 */
PJ_DEF(pj_status_t) pjsip_evsub_register_pkg( pjsip_module *pkg_mod,
					      const pj_str_t *event_name,
					      unsigned expires,
					      unsigned accept_cnt,
					      const pj_str_t accept[])
{
    struct evpkg *pkg;
    unsigned i;

    PJ_ASSERT_RETURN(pkg_mod && event_name, PJ_EINVAL);
    PJ_ASSERT_RETURN(accept_cnt < PJ_ARRAY_SIZE(pkg->pkg_accept->values), 
		     PJ_ETOOMANY);

    /* Make sure no module with the specified name already registered: */

    PJ_ASSERT_RETURN(find_pkg(event_name) == NULL, PJSIP_SIMPLE_EPKGEXISTS);


    /* Create new event package: */

    pkg = pj_pool_alloc(mod_evsub.pool, sizeof(struct evpkg));
    pkg->pkg_mod = pkg_mod;
    pkg->pkg_expires = expires;
    pj_strdup(mod_evsub.pool, &pkg->pkg_name, event_name);

    pkg->pkg_accept = pjsip_accept_hdr_create(mod_evsub.pool);
    pkg->pkg_accept->count = accept_cnt;
    for (i=0; i<accept_cnt; ++i) {
	pj_strdup(mod_evsub.pool, &pkg->pkg_accept->values[i], &accept[i]);
    }

    /* Add to package list: */

    pj_list_push_back(&mod_evsub.pkg_list, pkg);

    /* Add to Allow-Events header: */

    if (mod_evsub.allow_events_hdr->count !=
	PJ_ARRAY_SIZE(mod_evsub.allow_events_hdr->values))
    {
	mod_evsub.allow_events_hdr->values[mod_evsub.allow_events_hdr->count] =
	    pkg->pkg_name;
	++mod_evsub.allow_events_hdr->count;
    }
    

    /* Done */

    PJ_LOG(5,(THIS_FILE, "Event pkg \"%.*s\" registered by %.*s",
	      (int)event_name->slen, event_name->ptr,
	      (int)pkg_mod->name.slen, pkg_mod->name.ptr));

    return PJ_SUCCESS;
}



/*
 * Update expiration time.
 */
static void update_expires( pjsip_evsub *sub, pj_uint32_t interval )
{
    pj_gettimeofday(&sub->refresh_time);
    sub->refresh_time.sec += interval;
}


/* 
 * Schedule timer.
 */
static void set_timer( pjsip_evsub *sub, int timer_id,
		       pj_int32_t seconds)
{
    if (sub->timer.id != TIMER_TYPE_NONE) {
	PJ_LOG(5,(sub->obj_name, "%s %s timer", 
		  (timer_id==sub->timer.id ? "Updating" : "Cancelling"),
		  timer_names[sub->timer.id]));
	pjsip_endpt_cancel_timer(sub->endpt, &sub->timer);
	sub->timer.id = TIMER_TYPE_NONE;
    }

    if (timer_id != TIMER_TYPE_NONE) {
	pj_time_val timeout;

	PJ_ASSERT_ON_FAIL(seconds > 0, return);
	PJ_ASSERT_ON_FAIL(timer_id>TIMER_TYPE_NONE && timer_id<TIMER_TYPE_MAX,
			  return);

	timeout.sec = seconds;
	timeout.msec = 0;
	sub->timer.id = timer_id;

	pjsip_endpt_schedule_timer(sub->endpt, &sub->timer, &timeout);

	PJ_LOG(5,(sub->obj_name, "Timer %s scheduled in %d seconds", 
		  timer_names[sub->timer.id], timeout.sec));
    }
}


/*
 * Destroy session.
 */
static void evsub_destroy( pjsip_evsub *sub )
{
    struct dlgsub *dlgsub_head, *dlgsub;

    PJ_LOG(4,(sub->obj_name, "Subscription destroyed"));

    /* Kill timer */
    set_timer(sub, TIMER_TYPE_NONE, 0);

    /* Remote this session from dialog's list of subscription */
    dlgsub_head = sub->dlg->mod_data[mod_evsub.mod.id];
    dlgsub = dlgsub_head->next;
    while (dlgsub != dlgsub_head) {
	
	if (dlgsub->sub == sub) {
	    pj_list_erase(dlgsub);
	    break;
	}

	dlgsub = dlgsub->next;
    }

    /* Decrement dialog's session */
    pjsip_dlg_dec_session(sub->dlg, &mod_evsub.mod);
}

/*
 * Set subscription session state.
 */
static void set_state( pjsip_evsub *sub, pjsip_evsub_state state,
		       const pj_str_t *state_str, pjsip_event *event)
{
    pjsip_evsub_state prev_state = sub->state;
    pj_str_t old_state_str = sub->state_str;

    sub->state = state;

    if (state_str && state_str->slen)
	pj_strdup_with_null(sub->pool, &sub->state_str, state_str);
    else
	sub->state_str = evsub_state_names[state];

    PJ_LOG(4,(sub->obj_name, 
	      "Subscription state changed %.*s --> %.*s",
	      (int)old_state_str.slen,
	      old_state_str.ptr,
	      (int)sub->state_str.slen,
	      sub->state_str.ptr));

    if (sub->user.on_evsub_state && sub->call_cb)
	(*sub->user.on_evsub_state)(sub, event);

    if (state == PJSIP_EVSUB_STATE_TERMINATED &&
	prev_state != PJSIP_EVSUB_STATE_TERMINATED) 
    {
	if (sub->pending_tsx == 0) {
	    evsub_destroy(sub);
	}
    }
}


/*
 * Timer callback.
 */
static void on_timer( pj_timer_heap_t *timer_heap,
		      struct pj_timer_entry *entry)
{
    pjsip_evsub *sub;
    int timer_id;

    PJ_UNUSED_ARG(timer_heap);

    sub = entry->user_data;

    pjsip_dlg_inc_lock(sub->dlg);

    timer_id = entry->id;
    entry->id = TIMER_TYPE_NONE;

    switch (timer_id) {

    case TIMER_TYPE_UAC_REFRESH:
	/* Time for UAC to refresh subscription */
	if (sub->user.on_client_refresh && sub->call_cb) {
	    (*sub->user.on_client_refresh)(sub);
	} else {
	    pjsip_tx_data *tdata;
	    pj_status_t status;

	    PJ_LOG(5,(sub->obj_name, "Refreshing subscription."));
	    status = pjsip_evsub_initiate(sub, &sub->method, 
					  sub->expires->ivalue,
					  &tdata);
	    if (status == PJ_SUCCESS)
		pjsip_evsub_send_request(sub, tdata);
	}
	break;

    case TIMER_TYPE_UAS_TIMEOUT:
	/* Refresh from UAC has not been received */
	if (sub->user.on_server_timeout && sub->call_cb) {
	    (*sub->user.on_server_timeout)(sub);
	} else {
	    pjsip_tx_data *tdata;
	    pj_status_t status;

	    PJ_LOG(5,(sub->obj_name, "Timeout waiting for refresh. "
				     "Sending NOTIFY to terminate."));
	    status = pjsip_evsub_notify( sub, PJSIP_EVSUB_STATE_TERMINATED, 
					 NULL, &STR_TIMEOUT, &tdata);
	    if (status == PJ_SUCCESS)
		pjsip_evsub_send_request(sub, tdata);
	}
	break;

    case TIMER_TYPE_UAC_TERMINATE:
	{
	    PJ_LOG(5,(sub->obj_name, "Timeout waiting for final NOTIFY. "
				     "Terminating.."));
	    set_state(sub, PJSIP_EVSUB_STATE_TERMINATED, NULL, NULL);
	}
	break;

    case TIMER_TYPE_UAC_WAIT_NOTIFY:
	{
	    pjsip_tx_data *tdata;
	    pj_status_t status;

	    PJ_LOG(5,(sub->obj_name, 
		     "Timeout waiting for subsequent NOTIFY (we did "
		     "send non-2xx response for previous NOTIFY). "
		     "Unsubscribing.."));
	    status = pjsip_evsub_initiate( sub, &sub->method, 0, &tdata);
	    if (status == PJ_SUCCESS)
		pjsip_evsub_send_request(sub, tdata);
	}
	break;

    default:
	pj_assert(!"Invalid timer id");
    }

    pjsip_dlg_dec_lock(sub->dlg);
}


/*
 * Create subscription session, used for both client and notifier.
 */
static pj_status_t evsub_create( pjsip_dialog *dlg,
				 pjsip_role_e role,
				 const pjsip_evsub_user *user_cb,
				 const pj_str_t *event,
				 unsigned option,
				 pjsip_evsub **p_evsub )
{
    pjsip_evsub *sub;
    struct evpkg *pkg;
    struct dlgsub *dlgsub_head, *dlgsub;
    pj_status_t status;

    /* Make sure there's package register for the event name: */

    pkg = find_pkg(event);
    if (pkg == NULL)
	return PJSIP_SIMPLE_ENOPKG;


    /* Init attributes: */

    sub = pj_pool_zalloc(dlg->pool, sizeof(struct pjsip_evsub));
    sub->pool = dlg->pool;
    sub->endpt = dlg->endpt;
    sub->dlg = dlg;
    sub->pkg = pkg;
    sub->role = role;
    sub->call_cb = PJ_TRUE;
    sub->option = option;
    sub->state = PJSIP_EVSUB_STATE_NULL;
    sub->state_str = evsub_state_names[sub->state];
    sub->expires = pjsip_expires_hdr_create(sub->pool, pkg->pkg_expires);
    sub->accept = pjsip_hdr_clone(sub->pool, pkg->pkg_accept);

    sub->timer.user_data = sub;
    sub->timer.cb = &on_timer;

    /* Set name. */
    pj_ansi_snprintf(sub->obj_name, PJ_ARRAY_SIZE(sub->obj_name),
		     "evsub%p", sub);


    /* Copy callback, if any: */
    if (user_cb)
	pj_memcpy(&sub->user, user_cb, sizeof(pjsip_evsub_user));


    /* Create Event header: */
    sub->event = pjsip_event_hdr_create(sub->pool);
    pj_strdup(sub->pool, &sub->event->event_type, event);


    /* Create subcription list: */

    dlgsub_head = pj_pool_alloc(sub->pool, sizeof(struct dlgsub));
    dlgsub = pj_pool_alloc(sub->pool, sizeof(struct dlgsub));
    dlgsub->sub = sub;

    pj_list_init(dlgsub_head);
    pj_list_push_back(dlgsub_head, dlgsub);


    /* Register as dialog usage: */

    status = pjsip_dlg_add_usage(dlg, &mod_evsub.mod, dlgsub_head);
    if (status != PJ_SUCCESS)
	return status;


    PJ_LOG(5,(sub->obj_name, "%s subscription created, using dialog %s",
	      (role==PJSIP_ROLE_UAC ? "UAC" : "UAS"),
	      dlg->obj_name));

    *p_evsub = sub;

    return PJ_SUCCESS;
}



/*
 * Create client subscription session.
 */
PJ_DEF(pj_status_t) pjsip_evsub_create_uac( pjsip_dialog *dlg,
					    const pjsip_evsub_user *user_cb,
					    const pj_str_t *event,
					    unsigned option,
					    pjsip_evsub **p_evsub)
{
    pjsip_evsub *sub;
    pj_status_t status;

    PJ_ASSERT_RETURN(dlg && event && p_evsub, PJ_EINVAL);

    pjsip_dlg_inc_lock(dlg);
    status = evsub_create(dlg, PJSIP_UAC_ROLE, user_cb, event, option, &sub);
    if (status != PJ_SUCCESS)
	goto on_return;

    /* Add unique Id to Event header, only when PJSIP_EVSUB_NO_EVENT_ID
     * is not specified.
     */
    if ((option & PJSIP_EVSUB_NO_EVENT_ID) == 0) {
	pj_create_unique_string(sub->pool, &sub->event->id_param);
    }

    /* Increment dlg session. */
    pjsip_dlg_inc_session(sub->dlg, &mod_evsub.mod);

    /* Done */
    *p_evsub = sub;

on_return:
    pjsip_dlg_dec_lock(dlg);
    return status;
}


/*
 * Create server subscription session from incoming request.
 */
PJ_DEF(pj_status_t) pjsip_evsub_create_uas( pjsip_dialog *dlg,
					    const pjsip_evsub_user *user_cb,
					    pjsip_rx_data *rdata,
					    unsigned option,
					    pjsip_evsub **p_evsub)
{
    pjsip_evsub *sub;
    pjsip_transaction *tsx;
    pjsip_accept_hdr *accept_hdr;
    pjsip_event_hdr *event_hdr;
    pjsip_expires_hdr *expires_hdr;
    pj_status_t status;

    /* Check arguments: */
    PJ_ASSERT_RETURN(dlg && rdata && p_evsub, PJ_EINVAL);

    /* MUST be request message: */
    PJ_ASSERT_RETURN(rdata->msg_info.msg->type == PJSIP_REQUEST_MSG,
		     PJSIP_ENOTREQUESTMSG);

    /* Transaction MUST have been created (in the dialog) */
    tsx = pjsip_rdata_get_tsx(rdata);
    PJ_ASSERT_RETURN(tsx != NULL, PJSIP_ENOTSX);

    /* No subscription must have been attached to transaction */
    PJ_ASSERT_RETURN(tsx->mod_data[mod_evsub.mod.id] == NULL, 
		     PJSIP_ETYPEEXISTS);

    /* Package MUST implement on_rx_refresh */
    PJ_ASSERT_RETURN(user_cb->on_rx_refresh, PJ_EINVALIDOP);

    /* Request MUST have "Event" header. We need the Event header to get 
     * the package name (don't want to add more arguments in the function).
     */
    event_hdr = (pjsip_event_hdr*) 
	pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &STR_EVENT, NULL);
    if (event_hdr == NULL) {
	return PJSIP_ERRNO_FROM_SIP_STATUS(PJSIP_SC_BAD_REQUEST);
    }

    /* Start locking the mutex: */

    pjsip_dlg_inc_lock(dlg);

    /* Create the session: */

    status = evsub_create(dlg, PJSIP_UAS_ROLE, user_cb, 
			  &event_hdr->event_type, option, &sub);
    if (status != PJ_SUCCESS)
	goto on_return;

    /* Just duplicate Event header from the request */
    sub->event = pjsip_hdr_clone(sub->pool, event_hdr);

    /* Set the method: */
    pjsip_method_copy(sub->pool, &sub->method, 
		      &rdata->msg_info.msg->line.req.method);

    /* Update expiration time according to client request: */

    expires_hdr = (pjsip_expires_hdr*)
	pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_EXPIRES, NULL);
    if (expires_hdr) {
	sub->expires->ivalue = expires_hdr->ivalue;
    }

    /* Update time. */
    update_expires(sub, sub->expires->ivalue);

    /* Update Accept header: */

    accept_hdr = (pjsip_accept_hdr*)
	pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_ACCEPT, NULL);
    if (accept_hdr)
	sub->accept = pjsip_hdr_clone(sub->pool, accept_hdr);

    /* We can start the session: */

    pjsip_dlg_inc_session(dlg, &mod_evsub.mod);
    sub->pending_tsx++;
    tsx->mod_data[mod_evsub.mod.id] = sub;


    /* Done. */
    *p_evsub = sub;


on_return:
    pjsip_dlg_dec_lock(dlg);
    return status;
}


/*
 * Forcefully destroy subscription.
 */
PJ_DEF(pj_status_t) pjsip_evsub_terminate( pjsip_evsub *sub,
					   pj_bool_t notify )
{
    PJ_ASSERT_RETURN(sub, PJ_EINVAL);

    pjsip_dlg_inc_lock(sub->dlg);

    if (sub->pending_tsx) {
	pj_assert(!"Unable to terminate when there's pending tsx");
	pjsip_dlg_dec_lock(sub->dlg);
	return PJ_EINVALIDOP;
    }

    sub->call_cb = notify;
    set_state(sub, PJSIP_EVSUB_STATE_TERMINATED, NULL, NULL);

    pjsip_dlg_dec_lock(sub->dlg);
    return PJ_SUCCESS;
}

/*
 * Get subscription state.
 */
PJ_DEF(pjsip_evsub_state) pjsip_evsub_get_state(pjsip_evsub *sub)
{
    return sub->state;
}

/*
 * Get state name.
 */
PJ_DEF(const char*) pjsip_evsub_get_state_name(pjsip_evsub *sub)
{
    return sub->state_str.ptr;
}


/*
 * Initiate client subscription
 */
PJ_DEF(pj_status_t) pjsip_evsub_initiate( pjsip_evsub *sub,
					  const pjsip_method *method,
					  pj_int32_t expires,
					  pjsip_tx_data **p_tdata)
{
    pjsip_tx_data *tdata;
    pj_status_t status;

    PJ_ASSERT_RETURN(sub!=NULL && p_tdata!=NULL, PJ_EINVAL);

    /* Use SUBSCRIBE if method is not specified */
    if (method == NULL)
	method = &pjsip_subscribe_method;

    pjsip_dlg_inc_lock(sub->dlg);

    /* Update method: */
    if (sub->state == PJSIP_EVSUB_STATE_NULL)
	pjsip_method_copy(sub->pool, &sub->method, method);

    status = pjsip_dlg_create_request( sub->dlg, method, -1, &tdata);
    if (status != PJ_SUCCESS)
	goto on_return;


    /* Add Event header: */
    pjsip_msg_add_hdr( tdata->msg,
		       pjsip_hdr_shallow_clone(tdata->pool, sub->event));

    /* Update and add expires header: */
    if (expires >= 0)
	sub->expires->ivalue = expires;
    pjsip_msg_add_hdr( tdata->msg,
		       pjsip_hdr_shallow_clone(tdata->pool, sub->expires));

    /* Add Accept header: */
    pjsip_msg_add_hdr( tdata->msg,
		       pjsip_hdr_shallow_clone(tdata->pool, sub->accept));
    

    /* Add Allow-Events header: */
    pjsip_msg_add_hdr( tdata->msg,
		       pjsip_hdr_shallow_clone(tdata->pool, 
					       mod_evsub.allow_events_hdr));

   
    *p_tdata = tdata;


on_return:

    pjsip_dlg_dec_lock(sub->dlg);
    return status;
}


/*
 * Accept incoming subscription request.
 */
PJ_DEF(pj_status_t) pjsip_evsub_accept( pjsip_evsub *sub,
					pjsip_rx_data *rdata,
				        int st_code,
					const pjsip_hdr *hdr_list )
{
    pjsip_tx_data *tdata;
    pjsip_transaction *tsx;
    pj_status_t status;

    /* Check arguments */
    PJ_ASSERT_RETURN(sub && rdata, PJ_EINVAL);

    /* Can only be for server subscription: */
    PJ_ASSERT_RETURN(sub->role == PJSIP_ROLE_UAS, PJ_EINVALIDOP);

    /* Only expect 2xx status code (for now) */
    PJ_ASSERT_RETURN(st_code/100 == 2, PJ_EINVALIDOP);

    /* Subscription MUST have been attached to the transaction.
     * Initial subscription request will be attached on evsub_create_uas(),
     * while subsequent requests will be attached in tsx_state()
     */
    tsx = pjsip_rdata_get_tsx(rdata);
    PJ_ASSERT_RETURN(tsx->mod_data[mod_evsub.mod.id] != NULL,
		     PJ_EINVALIDOP);

    /* Lock dialog */
    pjsip_dlg_inc_lock(sub->dlg);

    /* Create response: */
    status = pjsip_dlg_create_response( sub->dlg, rdata, st_code, NULL, 
					&tdata);
    if (status != PJ_SUCCESS)
	goto on_return;


    /* Add expires header: */
    pjsip_msg_add_hdr( tdata->msg,
		       pjsip_hdr_shallow_clone(tdata->pool, sub->expires));

    /* Add additional header, if any. */
    if (hdr_list) {
	const pjsip_hdr *hdr = hdr_list->next;
	while (hdr != hdr_list) {
	    pjsip_msg_add_hdr( tdata->msg,
			       pjsip_hdr_clone(tdata->pool, hdr));
	    hdr = hdr->next;
	}
    }

    /* Send the response: */
    status = pjsip_dlg_send_response( sub->dlg, tsx, tdata );
    if (status != PJ_SUCCESS)
	goto on_return;


on_return:

    pjsip_dlg_dec_lock(sub->dlg);
    return status;
}


/*
 * Create Subscription-State header based on current server subscription
 * state.
 */
static pjsip_sub_state_hdr* sub_state_create( pj_pool_t *pool,
					      pjsip_evsub *sub,
					      pjsip_evsub_state state,
					      const pj_str_t *state_str,
					      const pj_str_t *reason )
{
    pjsip_sub_state_hdr *sub_state;
    pj_time_val now, delay;

    /* Get the remaining time before refresh is required */
    pj_gettimeofday(&now);
    delay = sub->refresh_time;
    PJ_TIME_VAL_SUB(delay, now);

    /* Create the Subscription-State header */
    sub_state = pjsip_sub_state_hdr_create(pool);

    /* Fill up the header */
    switch (state) {
    case PJSIP_EVSUB_STATE_NULL:
    case PJSIP_EVSUB_STATE_SENT:
    case PJSIP_EVSUB_STATE_ACCEPTED:
	pj_assert(!"Invalid state!");
	/* Treat as pending */

    case PJSIP_EVSUB_STATE_PENDING:
	sub_state->sub_state = STR_PENDING;
	sub_state->expires_param = delay.sec;
	break;

    case PJSIP_EVSUB_STATE_ACTIVE:
	sub_state->sub_state = STR_ACTIVE;
	sub_state->expires_param = delay.sec;
	break;

    case PJSIP_EVSUB_STATE_TERMINATED:
	sub_state->sub_state = STR_TERMINATED;
	if (reason != NULL)
	    pj_strdup(pool, &sub_state->reason_param, reason);
	break;

    case PJSIP_EVSUB_STATE_UNKNOWN:
	pj_assert(state_str != NULL);
	pj_strdup(pool, &sub_state->sub_state, state_str);
	break;
    }
    
    return sub_state;
}

/*
 * Create and send NOTIFY request.
 */
PJ_DEF(pj_status_t) pjsip_evsub_notify( pjsip_evsub *sub,
					pjsip_evsub_state state,
					const pj_str_t *state_str,
					const pj_str_t *reason,
					pjsip_tx_data **p_tdata)
{
    pjsip_tx_data *tdata;
    pjsip_sub_state_hdr *sub_state;
    pj_status_t status;

    /* Check arguments. */
    PJ_ASSERT_RETURN(sub!=NULL && p_tdata!=NULL, PJ_EINVAL);

    /* Lock dialog. */
    pjsip_dlg_inc_lock(sub->dlg);

    /* Create NOTIFY request */
    status = pjsip_dlg_create_request( sub->dlg, &pjsip_notify_method, -1, 
				       &tdata);
    if (status != PJ_SUCCESS)
	goto on_return;

    /* Add Event header */
    pjsip_msg_add_hdr(tdata->msg,
		      pjsip_hdr_shallow_clone(tdata->pool, sub->event));

    /* Add Subscription-State header */
    sub_state = sub_state_create(tdata->pool, sub, state, state_str,
				 reason);
    pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)sub_state);

    /* Add Allow-Events header */
    pjsip_msg_add_hdr(tdata->msg,
		      pjsip_hdr_shallow_clone(tdata->pool, mod_evsub.allow_events_hdr));

    /* Add Authentication headers. */
    pjsip_auth_clt_init_req( &sub->dlg->auth_sess, tdata );

    

    /* Save destination state. */
    sub->dst_state = state;
    if (state_str)
	pj_strdup(sub->pool, &sub->dst_state_str, state_str);
    else
	sub->dst_state_str.slen = 0;


    *p_tdata = tdata;

on_return:
    /* Unlock dialog */
    pjsip_dlg_dec_lock(sub->dlg);
    return status;
}


/*
 * Create NOTIFY to reflect current status.
 */
PJ_DEF(pj_status_t) pjsip_evsub_current_notify( pjsip_evsub *sub,
						pjsip_tx_data **p_tdata )
{
    return pjsip_evsub_notify( sub, sub->state, &sub->state_str, 
			       NULL, p_tdata );
}


/*
 * Send request.
 */
PJ_DEF(pj_status_t) pjsip_evsub_send_request( pjsip_evsub *sub,
					      pjsip_tx_data *tdata)
{
    pj_status_t status;

    /* Must be request message. */
    PJ_ASSERT_RETURN(tdata->msg->type == PJSIP_REQUEST_MSG,
		     PJSIP_ENOTREQUESTMSG);

    /* Lock */
    pjsip_dlg_inc_lock(sub->dlg);

    /* Send the request. */
    status = pjsip_dlg_send_request(sub->dlg, tdata, -1, NULL);
    if (status != PJ_SUCCESS)
	goto on_return;


    /* Special case for NOTIFY:
     * The new state was set in pjsip_evsub_notify(), but we apply the
     * new state now, when the request was actually sent.
     */
    if (pjsip_method_cmp(&tdata->msg->line.req.method, 
			 &pjsip_notify_method)==0) 
    {
	PJ_ASSERT_ON_FAIL(  sub->dst_state!=PJSIP_EVSUB_STATE_NULL,
			    {goto on_return;});

	set_state(sub, sub->dst_state, 
		  (sub->dst_state_str.slen ? &sub->dst_state_str : NULL), 
		  NULL);

	sub->dst_state = PJSIP_EVSUB_STATE_NULL;
	sub->dst_state_str.slen = 0;

    }


on_return:
    pjsip_dlg_dec_lock(sub->dlg);
    return status;
}



/*
 * Attach subscription session to newly created transaction, if appropriate.
 */
static pjsip_evsub *on_new_transaction( pjsip_transaction *tsx,
				        pjsip_event *event)
{
    /*
     * Newly created transaction will not have subscription session
     * attached to it. Find the subscription session from the dialog,
     * by matching the Event header.
     */
    pjsip_dialog *dlg;
    pjsip_event_hdr *event_hdr;
    pjsip_msg *msg;
    struct dlgsub *dlgsub_head, *dlgsub;
    pjsip_evsub *sub;
    
    dlg = pjsip_tsx_get_dlg(tsx);
    if (!dlg) {
	pj_assert(!"Transaction should have a dialog instance!");
	return NULL;
    }


    switch (event->body.tsx_state.type) {
    case PJSIP_EVENT_RX_MSG:
	msg = event->body.tsx_state.src.rdata->msg_info.msg;
	break;
    case PJSIP_EVENT_TX_MSG:
	msg = event->body.tsx_state.src.tdata->msg;
	break;
    default:
	if (tsx->role == PJSIP_ROLE_UAC)
	    msg = tsx->last_tx->msg;
	else
	    msg = NULL;
	break;
    }
    
    if (!msg) {
	//Note:
	// this transaction can be other transaction in the dialog.
	// The assertion below probably only valid for dialog that
	// only has one event subscription usage.
	//pj_assert(!"First transaction event is not TX or RX!");
	return NULL;
    }

    event_hdr = pjsip_msg_find_hdr_by_name(msg, &STR_EVENT, NULL);
    if (!event_hdr) {
	/* Not subscription related message */
	return NULL;
    }

    /* Find the subscription in the dialog, based on the content
     * of Event header: 
     */

    dlgsub_head = dlg->mod_data[mod_evsub.mod.id];
    if (dlgsub_head == NULL) {
	dlgsub_head = pj_pool_alloc(dlg->pool, sizeof(struct dlgsub));
	pj_list_init(dlgsub_head);
	dlg->mod_data[mod_evsub.mod.id] = dlgsub_head;
    }
    dlgsub = dlgsub_head->next;

    while (dlgsub != dlgsub_head) {

	if (pj_stricmp(&dlgsub->sub->event->event_type, 
		       &event_hdr->event_type)==0)
	{
	    /* Event type matched. 
	     * Check if event ID matched too.
	     */
	    if (pj_strcmp(&dlgsub->sub->event->id_param, 
			  &event_hdr->id_param)==0)
	    {
		
		break;

	    }
	    /*
	     * Otherwise if it is an UAC subscription, AND
	     * PJSIP_EVSUB_NO_EVENT_ID flag is set, AND
	     * the session's event id is NULL, AND
	     * the incoming request is NOTIFY with event ID, then
	     * we consider it as a match, and update the
	     * session's event id.
	     */
	    else if (dlgsub->sub->role == PJSIP_ROLE_UAC &&
		     (dlgsub->sub->option & PJSIP_EVSUB_NO_EVENT_ID)!=0 &&
		     dlgsub->sub->event->id_param.slen==0 &&
		     !pjsip_method_cmp(&tsx->method, &pjsip_notify_method))
	    {
		/* Update session's event id. */
		pj_strdup(dlgsub->sub->pool, 
			  &dlgsub->sub->event->id_param,
			  &event_hdr->id_param);

		break;
	    }
	}
	


	dlgsub = dlgsub->next;
    }

    if (dlgsub == dlgsub_head) {
	/* This could be incoming request to create new subscription */
	PJ_LOG(4,(THIS_FILE, 
		  "Subscription not found for %.*s, event=%.*s;id=%.*s",
		  (int)tsx->method.name.slen,
		  tsx->method.name.ptr,
		  (int)event_hdr->event_type.slen,
		  event_hdr->event_type.ptr,
		  (int)event_hdr->id_param.slen,
		  event_hdr->id_param.ptr));

	/* If this is an incoming NOTIFY, reject with 481 */
	if (tsx->state == PJSIP_TSX_STATE_TRYING &&
	    pjsip_method_cmp(&tsx->method, &pjsip_notify_method)==0)
	{
	    pj_str_t reason = pj_str("Subscription Does Not Exist");
	    pjsip_tx_data *tdata;
	    pj_status_t status;

	    status = pjsip_dlg_create_response(dlg, 
					       event->body.tsx_state.src.rdata, 
					       481, &reason, 
					       &tdata);
	    if (status == PJ_SUCCESS) {
		status = pjsip_dlg_send_response(dlg, tsx, tdata);
	    }
	}
	return NULL;
    }

    /* Found! */
    sub = dlgsub->sub;

    /* Attach session to the transaction */
    tsx->mod_data[mod_evsub.mod.id] = sub;
    sub->pending_tsx++;

    /* Special case for outgoing/UAC SUBSCRIBE/REFER transaction. 
     * We can only have one pending UAC SUBSCRIBE/REFER, so if another 
     * transaction is started while previous one still alive, terminate
     * the older one.
     *
     * Sample scenario:
     *	- subscribe sent to destination that doesn't exist, transaction
     *	  is still retransmitting request, then unsubscribe is sent.
     */
    if (tsx->role == PJSIP_ROLE_UAC &&
	tsx->state == PJSIP_TSX_STATE_CALLING &&
	pjsip_method_cmp(&tsx->method, &sub->method) == 0) 
    {

	if (sub->pending_sub && 
	    sub->pending_sub->state < PJSIP_TSX_STATE_COMPLETED) 
	{
	    PJ_LOG(4,(sub->obj_name, 
		      "Cancelling pending %.*s request",
		      (int)sub->method.name.slen, sub->method.name.ptr));

	    /* By convention, we use 490 (Request Updated) status code.
	     * When transaction handler (below) see this status code, it
	     * will ignore the transaction.
	     */
	    pjsip_tsx_terminate(sub->pending_sub, PJSIP_SC_REQUEST_UPDATED);
	}

	sub->pending_sub = tsx;

    }

    return sub;
}


/*
 * Create response, adding custome headers and msg body.
 */
static pj_status_t create_response( pjsip_evsub *sub,
				    pjsip_rx_data *rdata,
				    int st_code,
				    const pj_str_t *st_text,
				    const pjsip_hdr *res_hdr,
				    const pjsip_msg_body *body,
				    pjsip_tx_data **p_tdata)
{
    pjsip_tx_data *tdata;
    pjsip_hdr *hdr;
    pj_status_t status;

    status = pjsip_dlg_create_response(sub->dlg, rdata,
				       st_code, st_text, &tdata);
    if (status != PJ_SUCCESS)
	return status;

    *p_tdata = tdata;

    /* Add response headers. */
    hdr = res_hdr->next;
    while (hdr != res_hdr) {
	pjsip_msg_add_hdr( tdata->msg, 
			   pjsip_hdr_clone(tdata->pool, hdr));
	hdr = hdr->next;
    }

    /* Add msg body, if any */
    if (body) {
	tdata->msg->body = pjsip_msg_body_clone(tdata->pool, body);
	if (tdata->msg->body == NULL) {

	    PJ_LOG(4,(THIS_FILE, "Error: unable to clone msg body"));

	    /* Ignore */
	    return PJ_SUCCESS;
	}
    }

    return PJ_SUCCESS;
}

/*
 * Get subscription state from the value of Subscription-State header.
 */
static void get_hdr_state( pjsip_sub_state_hdr *sub_state,
			   pjsip_evsub_state *state,
			   pj_str_t **state_str )
{
    if (pj_stricmp(&sub_state->sub_state, &STR_TERMINATED)==0) {

	*state = PJSIP_EVSUB_STATE_TERMINATED;
	*state_str = NULL;

    } else if (pj_stricmp(&sub_state->sub_state, &STR_ACTIVE)==0) {

	*state = PJSIP_EVSUB_STATE_ACTIVE;
	*state_str = NULL;

    } else if (pj_stricmp(&sub_state->sub_state, &STR_PENDING)==0) {

	*state = PJSIP_EVSUB_STATE_PENDING;
	*state_str = NULL;

    } else {

	*state = PJSIP_EVSUB_STATE_UNKNOWN;
	*state_str = &sub_state->sub_state;

    }
}

/*
 * Transaction event processing by UAC, after subscription is sent.
 */
static void on_tsx_state_uac( pjsip_evsub *sub, pjsip_transaction *tsx,
			      pjsip_event *event )
{

    if (pjsip_method_cmp(&tsx->method, &sub->method)==0) {

	/* Received response to outgoing request that establishes/refresh
	 * subscription. 
	 */

	/* First time initial request is sent. */
	if (sub->state == PJSIP_EVSUB_STATE_NULL &&
	    tsx->state == PJSIP_TSX_STATE_CALLING)
	{
	    set_state(sub, PJSIP_EVSUB_STATE_SENT, NULL, event);
	    return;
	}

	/* Only interested in final response */
	if (tsx->state != PJSIP_TSX_STATE_COMPLETED &&
	    tsx->state != PJSIP_TSX_STATE_TERMINATED)
	{
	    return;
	}

	/* Clear pending subscription */
	if (tsx == sub->pending_sub)
	    sub->pending_sub = NULL;

	/* Handle authentication. */
	if (tsx->status_code==401 || tsx->status_code==407) {
	    pjsip_tx_data *tdata;
	    pj_status_t status;

	    if (tsx->state == PJSIP_TSX_STATE_TERMINATED) {
		/* Previously failed transaction has terminated */
		return;
	    }

	    status = pjsip_auth_clt_reinit_req(&sub->dlg->auth_sess,
					       event->body.tsx_state.src.rdata,
					       tsx->last_tx, &tdata);
	    if (status == PJ_SUCCESS) 
		status = pjsip_dlg_send_request(sub->dlg, tdata, -1, NULL);
	    
	    if (status != PJ_SUCCESS) {
		/* Authentication failed! */
		set_state(sub, PJSIP_EVSUB_STATE_TERMINATED,
			       NULL,
			       event);
		return;
	    }

	    return;
	}

	if (tsx->status_code/100 == 2) {

	    /* Successfull SUBSCRIBE request! 
	     * This could be:
	     *	- response to initial SUBSCRIBE request
	     *	- response to subsequent refresh
	     *	- response to unsubscription
	     */

	    if (tsx->state == PJSIP_TSX_STATE_TERMINATED) {
		/* Ignore; this transaction has been processed before */
		return;
	    }

	    /* Update UAC refresh time, if response contains Expires header,
	     * only when we're not unsubscribing. 
	     */
	    if (sub->expires->ivalue != 0) {
		pjsip_msg *msg;
		pjsip_expires_hdr *expires;

		msg = event->body.tsx_state.src.rdata->msg_info.msg;
		expires = pjsip_msg_find_hdr(msg, PJSIP_H_EXPIRES, NULL);
		if (expires) {
		    sub->expires->ivalue = expires->ivalue;
		}
	    }

	    /* Update time */
	    update_expires(sub, sub->expires->ivalue);

	    /* Start UAC refresh timer, only when we're not unsubscribing */
	    if (sub->expires->ivalue != 0) {
		unsigned timeout = (sub->expires->ivalue > TIME_UAC_REFRESH) ?
		    sub->expires->ivalue - TIME_UAC_REFRESH : sub->expires->ivalue;

		PJ_LOG(5,(sub->obj_name, "Will refresh in %d seconds", 
			  timeout));
		set_timer(sub, TIMER_TYPE_UAC_REFRESH, timeout);

	    } else {
		/* Otherwise set timer to terminate client subscription when
		 * NOTIFY to end subscription is not received.
		 */
		set_timer(sub, TIMER_TYPE_UAC_TERMINATE, TIME_UAC_TERMINATE);
	    }
	    
	    /* Set state, if necessary */
	    pj_assert(sub->state != PJSIP_EVSUB_STATE_NULL);
	    if (sub->state == PJSIP_EVSUB_STATE_SENT) {
		set_state(sub, PJSIP_EVSUB_STATE_ACCEPTED, NULL, event);
	    }

	} else {

	    /* Failed SUBSCRIBE request! 
	     *
	     * The RFC 3265 says that if outgoing SUBSCRIBE fails with status
	     * other than 481, the subscription is still considered valid for
	     * the duration of the last Expires.
	     *
	     * Since we send refresh about 5 seconds (TIME_UAC_REFRESH) before 
	     * expiration, theoritically the expiration is still valid for the 
	     * next 5 seconds even when we receive non-481 failed response.
	     *
	     * Ah, what the heck!
	     *
	     * Just terminate now!
	     *
	     */

	    if (sub->state == PJSIP_EVSUB_STATE_TERMINATED) {
		/* Ignore, has been handled before */
		return;
	    }

	    /* Ignore 490 (Request Updated) status. 
	     * This happens when application sends SUBSCRIBE/REFER while 
	     * another one is still in progress.
	     */
	    if (tsx->status_code == PJSIP_SC_REQUEST_UPDATED) {
		return;
	    }

	    /* Kill any timer. */
	    set_timer(sub, TIMER_TYPE_NONE, 0);

	    /* Set state to TERMINATED */
	    set_state(sub, PJSIP_EVSUB_STATE_TERMINATED, 
		      NULL, event);

	}

    } else if (pjsip_method_cmp(&tsx->method, &pjsip_notify_method) == 0) {

	/* Incoming NOTIFY. 
	 * This can be the result of:
	 *  - Initial subscription response
	 *  - UAS updating the resource info.
	 *  - Unsubscription response.
	 */
	int st_code = 200;
	pj_str_t *st_text = NULL;
	pjsip_hdr res_hdr;
	pjsip_msg_body *body = NULL;

	pjsip_rx_data *rdata;
	pjsip_msg *msg;
	pjsip_sub_state_hdr *sub_state;

	pjsip_evsub_state new_state;
	pj_str_t *new_state_str;

	pjsip_tx_data *tdata;
	pj_status_t status;
	int next_refresh;

	/* Only want to handle initial NOTIFY receive event. */
	if (tsx->state != PJSIP_TSX_STATE_TRYING)
	    return;


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

	pj_list_init(&res_hdr);

	/* Get subscription state header. */
	sub_state = pjsip_msg_find_hdr_by_name(msg, &STR_SUB_STATE, NULL);
	if (sub_state == NULL) {

	    pjsip_warning_hdr *warn_hdr;
	    pj_str_t warn_text = { "Missing Subscription-State header", 33};

	    /* Bad request! Add warning header. */
	    st_code = PJSIP_SC_BAD_REQUEST;
	    warn_hdr = pjsip_warning_hdr_create(rdata->tp_info.pool, 399,
					        pjsip_endpt_name(sub->endpt),
						&warn_text);
	    pj_list_push_back(&res_hdr, warn_hdr);
	}

	/* Call application registered callback to handle incoming NOTIFY,
	 * if any.
	 */
	if (st_code==200 && sub->user.on_rx_notify && sub->call_cb) {
	    (*sub->user.on_rx_notify)(sub, rdata, &st_code, &st_text, 
				      &res_hdr, &body);

	    /* Application MUST specify final response! */
	    PJ_ASSERT_ON_FAIL(st_code >= 200, {st_code=200; });

	    /* Must be a valid status code */
	    PJ_ASSERT_ON_FAIL(st_code <= 699, {st_code=500; });
	}


	/* If non-2xx should be returned, then send the response.
	 * No need to update server subscription state.
	 */
	if (st_code >= 300) {
	    status = create_response(sub, rdata, st_code, st_text, &res_hdr,
				     body, &tdata);
	    if (status == PJ_SUCCESS) {
		status = pjsip_dlg_send_response(sub->dlg, tsx, tdata);
	    }

	    /* Start timer to terminate subscription, just in case server
	     * is not able to generate NOTIFY to our response.
	     */
	    if (status == PJ_SUCCESS) {
		unsigned timeout = TIME_UAC_WAIT_NOTIFY;
		set_timer(sub, TIMER_TYPE_UAC_WAIT_NOTIFY, timeout);
	    } else {
		set_state(sub, PJSIP_EVSUB_STATE_TERMINATED, NULL, NULL);
	    }

	    return;
	}

	/* Update expiration from the value of expires param in
	 * Subscription-State header, but ONLY when subscription state 
	 * is "active" or "pending", AND the header contains expires param.
	 */
	if (sub->expires->ivalue != 0 &&
	    sub_state->expires_param >= 0 &&
	    (pj_stricmp(&sub_state->sub_state, &STR_ACTIVE)==0 ||
	     pj_stricmp(&sub_state->sub_state, &STR_PENDING)==0))
	{
	    next_refresh = sub_state->expires_param;

	} else {
	    next_refresh = sub->expires->ivalue;
	}

	/* Update time */
	update_expires(sub, next_refresh);

	/* Start UAC refresh timer, only when we're not unsubscribing */
	if (sub->expires->ivalue != 0) {
	    unsigned timeout = (next_refresh > TIME_UAC_REFRESH) ?
		next_refresh - TIME_UAC_REFRESH : next_refresh;

	    PJ_LOG(5,(sub->obj_name, "Will refresh in %d seconds", timeout));
	    set_timer(sub, TIMER_TYPE_UAC_REFRESH, timeout);
	}
	
	/* Find out the state */
	get_hdr_state(sub_state, &new_state, &new_state_str);

	/* Send response. */
	status = create_response(sub, rdata, st_code, st_text, &res_hdr,
				 body, &tdata);
	if (status == PJ_SUCCESS)
	    status = pjsip_dlg_send_response(sub->dlg, tsx, tdata);

	/* Set the state */
	if (status == PJ_SUCCESS) {
	    set_state(sub, new_state, new_state_str, event);
	} else {
	    set_state(sub, PJSIP_EVSUB_STATE_TERMINATED, NULL, event);
	}


    } else {

	/*
	 * Unexpected method!
	 */
	PJ_LOG(4,(sub->obj_name, "Unexpected transaction method %.*s",
		 (int)tsx->method.name.slen, tsx->method.name.ptr));
    }
}


/*
 * Transaction event processing by UAS, after subscription is accepted.
 */
static void on_tsx_state_uas( pjsip_evsub *sub, pjsip_transaction *tsx,
			      pjsip_event *event)
{

    if (pjsip_method_cmp(&tsx->method, &sub->method) == 0) {
	
	/*
	 * Incoming request (e.g. SUBSCRIBE or REFER) to refresh subsciption.
	 *
	 */
	pjsip_rx_data *rdata;
	pjsip_event_hdr *event_hdr;
	pjsip_expires_hdr *expires;
	pjsip_msg *msg;
	pjsip_tx_data *tdata;
	int st_code = 200;
	pj_str_t *st_text = NULL;
	pjsip_hdr res_hdr;
	pjsip_msg_body *body = NULL;
	pjsip_evsub_state old_state;
	pj_str_t old_state_str;
	pj_status_t status;


	/* Only wants to handle the first event when the request is 
	 * received.
	 */
	if (tsx->state != PJSIP_TSX_STATE_TRYING)
	    return;

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

	/* Set expiration time based on client request (in Expires header),
	 * or package default expiration time.
	 */
	event_hdr = pjsip_msg_find_hdr_by_name(msg, &STR_EVENT, NULL);
	expires = pjsip_msg_find_hdr(msg, PJSIP_H_EXPIRES, NULL);
	if (event_hdr && expires) {
	    struct evpkg *evpkg;

	    evpkg = find_pkg(&event_hdr->event_type);
	    if (evpkg) {
		if (expires->ivalue < (pj_int32_t)evpkg->pkg_expires)
		    sub->expires->ivalue = expires->ivalue;
		else
		    sub->expires->ivalue = evpkg->pkg_expires;
	    }
	}
	
	/* Update time (before calling on_rx_refresh, since application
	 * will send NOTIFY.
	 */
	update_expires(sub, sub->expires->ivalue);


	/* Save old state.
	 * If application respond with non-2xx, revert to old state.
	 */
	old_state = sub->state;
	old_state_str = sub->state_str;

	if (sub->expires->ivalue == 0) {
	    sub->state = PJSIP_EVSUB_STATE_TERMINATED;
	    sub->state_str = evsub_state_names[sub->state];
	} else  if (sub->state == PJSIP_EVSUB_STATE_NULL) {
	    sub->state = PJSIP_EVSUB_STATE_ACCEPTED;
	    sub->state_str = evsub_state_names[sub->state];
	}

	/* Call application's on_rx_refresh, just in case it wants to send
	 * response other than 200 (OK)
	 */
	pj_list_init(&res_hdr);

	if (sub->user.on_rx_refresh && sub->call_cb) {
	    (*sub->user.on_rx_refresh)(sub, rdata, &st_code, &st_text, 
				       &res_hdr, &body);
	}

	/* Application MUST specify final response! */
	PJ_ASSERT_ON_FAIL(st_code >= 200, {st_code=200; });

	/* Must be a valid status code */
	PJ_ASSERT_ON_FAIL(st_code <= 699, {st_code=500; });


	/* Create and send response */
	status = create_response(sub, rdata, st_code, st_text, &res_hdr,
				 body, &tdata);
	if (status == PJ_SUCCESS) {
	    /* Add expires header: */
	    pjsip_msg_add_hdr( tdata->msg,
			       pjsip_hdr_shallow_clone(tdata->pool, 
						       sub->expires));

	    /* Send */
	    status = pjsip_dlg_send_response(sub->dlg, tsx, tdata);
	}

	/* Update state or revert state */
	if (st_code/100==2) {
	    
	    if (sub->expires->ivalue == 0) {
		set_state(sub, sub->state, NULL, event);
	    } else  if (sub->state == PJSIP_EVSUB_STATE_NULL) {
		set_state(sub, sub->state, NULL, event);
	    }

	    /* Set UAS timeout timer, when state is not terminated. */
	    if (sub->state != PJSIP_EVSUB_STATE_TERMINATED) {
		PJ_LOG(5,(sub->obj_name, "UAS timeout in %d seconds",
			  sub->expires->ivalue));
		set_timer(sub, TIMER_TYPE_UAS_TIMEOUT, 
			  sub->expires->ivalue);
	    }

	}  else {
	    sub->state = old_state;
	    sub->state_str = old_state_str;
	}


    } else if (pjsip_method_cmp(&tsx->method, &pjsip_notify_method)==0) {

	/* Handle authentication */ 
	if (tsx->state == PJSIP_TSX_STATE_COMPLETED &&
	    (tsx->status_code==401 || tsx->status_code==407))
	{
	    pjsip_rx_data *rdata = event->body.tsx_state.src.rdata;
	    pjsip_tx_data *tdata;
	    pj_status_t status;

	    status = pjsip_auth_clt_reinit_req( &sub->dlg->auth_sess, rdata, 
						tsx->last_tx, &tdata);
	    if (status == PJ_SUCCESS)
		status = pjsip_dlg_send_request( sub->dlg, tdata, -1, NULL );

	    if (status != PJ_SUCCESS) {
		/* Can't authenticate. Terminate session (?) */
		set_state(sub, PJSIP_EVSUB_STATE_TERMINATED, NULL, NULL);
		return;
	    }

	}
	/*
	 * Terminate event usage if we receive 481, 408, and 7 class
	 * responses.
	 */
	if (sub->state != PJSIP_EVSUB_STATE_TERMINATED &&
	    (tsx->status_code==481 || tsx->status_code==408 ||
	     tsx->status_code/100 == 7))
	{
	    set_state(sub, PJSIP_EVSUB_STATE_TERMINATED, NULL, event);
	    return;
	}

    } else {

	/*
	 * Unexpected method!
	 */
	PJ_LOG(4,(sub->obj_name, "Unexpected transaction method %.*s",
		 (int)tsx->method.name.slen, tsx->method.name.ptr));
    
    }
}


/*
 * Notification when transaction state has changed!
 */
static void mod_evsub_on_tsx_state(pjsip_transaction *tsx, pjsip_event *event)
{
    pjsip_evsub *sub = pjsip_tsx_get_evsub(tsx);

    if (sub == NULL) {
	sub = on_new_transaction(tsx, event);
	if (sub == NULL)
	    return;
    }


    /* Call on_tsx_state callback, if any. */
    if (sub->user.on_tsx_state && sub->call_cb)
	(*sub->user.on_tsx_state)(sub, tsx, event);


    /* Process the event: */

    if (sub->role == PJSIP_ROLE_UAC) {
	on_tsx_state_uac(sub, tsx, event);
    } else {
	on_tsx_state_uas(sub, tsx, event);
    }


    /* Check transaction TERMINATE event */
    if (tsx->state == PJSIP_TSX_STATE_TERMINATED) {

	--sub->pending_tsx;

	if (sub->state == PJSIP_EVSUB_STATE_TERMINATED &&
	    sub->pending_tsx == 0)
	{
	    evsub_destroy(sub);
	}

    }
}


