/* $Id: mwi.c 4172 2012-06-19 14:35:18Z nanang $ */
/* 
 * 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-simple/mwi.h>
#include <pjsip-simple/errno.h>
#include <pjsip-simple/evsub_msg.h>
#include <pjsip/sip_module.h>
#include <pjsip/sip_endpoint.h>
#include <pjsip/sip_dialog.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		    "mwi.c"

 /*
 * MWI module (mod-mdi)
 */
static struct pjsip_module mod_mwi = 
{
    NULL, NULL,			    /* prev, next.			*/
    { "mod-mwi", 7 },		    /* Name.				*/
    -1,				    /* Id				*/
    PJSIP_MOD_PRIORITY_DIALOG_USAGE,/* Priority				*/
    NULL,			    /* 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()			*/
};


/*
 * This structure describe an mwi agent (both client and server)
 */
typedef struct pjsip_mwi
{
    pjsip_evsub		*sub;		/**< Event subscribtion record.	    */
    pjsip_dialog	*dlg;		/**< The dialog.		    */
    pjsip_evsub_user	 user_cb;	/**< The user callback.		    */

    /* These are for server subscriptions */
    pj_pool_t		*body_pool;	/**< Pool to save message body	    */
    pjsip_media_type	 mime_type;	/**< MIME type of last msg body	    */
    pj_str_t		 body;		/**< Last sent message body	    */
} pjsip_mwi;


/*
 * Forward decl for evsub callbacks.
 */
static void mwi_on_evsub_state( pjsip_evsub *sub, pjsip_event *event);
static void mwi_on_evsub_tsx_state( pjsip_evsub *sub, pjsip_transaction *tsx,
				    pjsip_event *event);
static void mwi_on_evsub_rx_refresh( pjsip_evsub *sub, 
				     pjsip_rx_data *rdata,
				     int *p_st_code,
				     pj_str_t **p_st_text,
				     pjsip_hdr *res_hdr,
				     pjsip_msg_body **p_body);
static void mwi_on_evsub_rx_notify( pjsip_evsub *sub, 
				    pjsip_rx_data *rdata,
				    int *p_st_code,
				    pj_str_t **p_st_text,
				    pjsip_hdr *res_hdr,
				    pjsip_msg_body **p_body);
static void mwi_on_evsub_client_refresh(pjsip_evsub *sub);
static void mwi_on_evsub_server_timeout(pjsip_evsub *sub);


/*
 * Event subscription callback for mwi.
 */
static pjsip_evsub_user mwi_user = 
{
    &mwi_on_evsub_state,
    &mwi_on_evsub_tsx_state,
    &mwi_on_evsub_rx_refresh,
    &mwi_on_evsub_rx_notify,
    &mwi_on_evsub_client_refresh,
    &mwi_on_evsub_server_timeout,
};


/*
 * Some static constants.
 */
static const pj_str_t STR_EVENT		 = { "Event", 5 };
static const pj_str_t STR_MWI		 = { "message-summary", 15 };
static const pj_str_t STR_APP_SIMPLE_SMS = { "application/simple-message-summary", 34};

/*
 * Init mwi module.
 */
PJ_DEF(pj_status_t) pjsip_mwi_init_module( pjsip_endpoint *endpt,
					   pjsip_module *mod_evsub)
{
    pj_status_t status;
    pj_str_t accept[1];

    /* Check arguments. */
    PJ_ASSERT_RETURN(endpt && mod_evsub, PJ_EINVAL);

    /* Must have not been registered */
    PJ_ASSERT_RETURN(mod_mwi.id == -1, PJ_EINVALIDOP);

    /* Register to endpoint */
    status = pjsip_endpt_register_module(endpt, &mod_mwi);
    if (status != PJ_SUCCESS)
	return status;

    accept[0] = STR_APP_SIMPLE_SMS;

    /* Register event package to event module. */
    status = pjsip_evsub_register_pkg( &mod_mwi, &STR_MWI, 
				       PJSIP_MWI_DEFAULT_EXPIRES, 
				       PJ_ARRAY_SIZE(accept), accept);
    if (status != PJ_SUCCESS) {
	pjsip_endpt_unregister_module(endpt, &mod_mwi);
	return status;
    }

    return PJ_SUCCESS;
}


/*
 * Get mwi module instance.
 */
PJ_DEF(pjsip_module*) pjsip_mwi_instance(void)
{
    return &mod_mwi;
}


/*
 * Create client subscription.
 */
PJ_DEF(pj_status_t) pjsip_mwi_create_uac( pjsip_dialog *dlg,
					  const pjsip_evsub_user *user_cb,
					  unsigned options,
					  pjsip_evsub **p_evsub )
{
    pj_status_t status;
    pjsip_mwi *mwi;
    pjsip_evsub *sub;

    PJ_ASSERT_RETURN(dlg && p_evsub, PJ_EINVAL);

    PJ_UNUSED_ARG(options);

    pjsip_dlg_inc_lock(dlg);

    /* Create event subscription */
    status = pjsip_evsub_create_uac( dlg,  &mwi_user, &STR_MWI, 
				     options, &sub);
    if (status != PJ_SUCCESS)
	goto on_return;

    /* Create mwi */
    mwi = PJ_POOL_ZALLOC_T(dlg->pool, pjsip_mwi);
    mwi->dlg = dlg;
    mwi->sub = sub;
    if (user_cb)
	pj_memcpy(&mwi->user_cb, user_cb, sizeof(pjsip_evsub_user));

    /* Attach to evsub */
    pjsip_evsub_set_mod_data(sub, mod_mwi.id, mwi);

    *p_evsub = sub;

on_return:
    pjsip_dlg_dec_lock(dlg);
    return status;
}


/*
 * Create server subscription.
 */
PJ_DEF(pj_status_t) pjsip_mwi_create_uas( pjsip_dialog *dlg,
					  const pjsip_evsub_user *user_cb,
					  pjsip_rx_data *rdata,
					  pjsip_evsub **p_evsub )
{
    pjsip_accept_hdr *accept;
    pjsip_event_hdr *event;
    pjsip_evsub *sub;
    pjsip_mwi *mwi;
    char obj_name[PJ_MAX_OBJ_NAME];
    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);

    /* Check that request is SUBSCRIBE */
    PJ_ASSERT_RETURN(pjsip_method_cmp(&rdata->msg_info.msg->line.req.method,
				      &pjsip_subscribe_method)==0,
		     PJSIP_SIMPLE_ENOTSUBSCRIBE);

    /* Check that Event header contains "mwi" */
    event = (pjsip_event_hdr*)
    	    pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &STR_EVENT, NULL);
    if (!event) {
	return PJSIP_ERRNO_FROM_SIP_STATUS(PJSIP_SC_BAD_REQUEST);
    }
    if (pj_stricmp(&event->event_type, &STR_MWI) != 0) {
	return PJSIP_ERRNO_FROM_SIP_STATUS(PJSIP_SC_BAD_EVENT);
    }

    /* Check that request contains compatible Accept header. */
    accept = (pjsip_accept_hdr*)
    	     pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_ACCEPT, NULL);
    if (accept) {
	unsigned i;
	for (i=0; i<accept->count; ++i) {
	    if (pj_stricmp(&accept->values[i], &STR_APP_SIMPLE_SMS)==0) {
		break;
	    }
	}

	if (i==accept->count) {
	    /* Nothing is acceptable */
	    return PJSIP_ERRNO_FROM_SIP_STATUS(PJSIP_SC_NOT_ACCEPTABLE);
	}

    } else {
	/* No Accept header. 
	 * Assume client supports "application/simple-message-summary" 
	*/
    }

    /* Lock dialog */
    pjsip_dlg_inc_lock(dlg);


    /* Create server subscription */
    status = pjsip_evsub_create_uas( dlg, &mwi_user, rdata, 0, &sub);
    if (status != PJ_SUCCESS)
	goto on_return;

    /* Create server mwi subscription */
    mwi = PJ_POOL_ZALLOC_T(dlg->pool, pjsip_mwi);
    mwi->dlg = dlg;
    mwi->sub = sub;
    if (user_cb)
	pj_memcpy(&mwi->user_cb, user_cb, sizeof(pjsip_evsub_user));

    pj_ansi_snprintf(obj_name, PJ_MAX_OBJ_NAME, "mwibd%p", dlg->pool);
    mwi->body_pool = pj_pool_create(dlg->pool->factory, obj_name, 
				    512, 512, NULL);

    /* Attach to evsub */
    pjsip_evsub_set_mod_data(sub, mod_mwi.id, mwi);

    /* Done: */
    *p_evsub = sub;

on_return:
    pjsip_dlg_dec_lock(dlg);
    return status;
}


/*
 * Forcefully terminate mwi.
 */
PJ_DEF(pj_status_t) pjsip_mwi_terminate( pjsip_evsub *sub,
					 pj_bool_t notify )
{
    return pjsip_evsub_terminate(sub, notify);
}

/*
 * Create SUBSCRIBE
 */
PJ_DEF(pj_status_t) pjsip_mwi_initiate( pjsip_evsub *sub,
					pj_int32_t expires,
					pjsip_tx_data **p_tdata)
{
    return pjsip_evsub_initiate(sub, &pjsip_subscribe_method, expires, 
				p_tdata);
}


/*
 * Accept incoming subscription.
 */
PJ_DEF(pj_status_t) pjsip_mwi_accept( pjsip_evsub *sub,
				      pjsip_rx_data *rdata,
				      int st_code,
				      const pjsip_hdr *hdr_list )
{
    return pjsip_evsub_accept( sub, rdata, st_code, hdr_list );
}

/*
 * Create message body and attach it to the (NOTIFY) request.
 */
static pj_status_t mwi_create_msg_body( pjsip_mwi *mwi, 
					pjsip_tx_data *tdata)
{
    pjsip_msg_body *body;
    pj_str_t dup_text;

    PJ_ASSERT_RETURN(mwi->mime_type.type.slen && mwi->body.slen, PJ_EINVALIDOP);
    
    /* Clone the message body and mime type */
    pj_strdup(tdata->pool, &dup_text, &mwi->body);

    /* Create the message body */
    body = PJ_POOL_ZALLOC_T(tdata->pool, pjsip_msg_body);
    pjsip_media_type_cp(tdata->pool, &body->content_type, &mwi->mime_type);
    body->data = dup_text.ptr;
    body->len = (unsigned)dup_text.slen;
    body->print_body = &pjsip_print_text_body;
    body->clone_data = &pjsip_clone_text_data;

    /* Attach to tdata */
    tdata->msg->body = body;

    return PJ_SUCCESS;
}


/*
 * Create NOTIFY
 */
PJ_DEF(pj_status_t) pjsip_mwi_notify(  pjsip_evsub *sub,
				       pjsip_evsub_state state,
				       const pj_str_t *state_str,
				       const pj_str_t *reason,
				       const pjsip_media_type *mime_type,
				       const pj_str_t *body,
				       pjsip_tx_data **p_tdata)
{
    pjsip_mwi *mwi;
    pjsip_tx_data *tdata;
    pj_status_t status;
    
    /* Check arguments. */
    PJ_ASSERT_RETURN(sub && mime_type && body && p_tdata, PJ_EINVAL);

    /* Get the mwi object. */
    mwi = (pjsip_mwi*) pjsip_evsub_get_mod_data(sub, mod_mwi.id);
    PJ_ASSERT_RETURN(mwi != NULL, PJ_EINVALIDOP);

    /* Lock object. */
    pjsip_dlg_inc_lock(mwi->dlg);

    /* Create the NOTIFY request. */
    status = pjsip_evsub_notify( sub, state, state_str, reason, &tdata);
    if (status != PJ_SUCCESS)
	goto on_return;

    /* Update the cached message body */
    if (mime_type || body)
	pj_pool_reset(mwi->body_pool);
    if (mime_type)
	pjsip_media_type_cp(mwi->body_pool, &mwi->mime_type, mime_type);
    if (body)
	pj_strdup(mwi->body_pool, &mwi->body, body);

    /* Create message body */
    status = mwi_create_msg_body( mwi, tdata );
    if (status != PJ_SUCCESS)
	goto on_return;

    /* Done. */
    *p_tdata = tdata;

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


/*
 * Create NOTIFY that reflect current state.
 */
PJ_DEF(pj_status_t) pjsip_mwi_current_notify( pjsip_evsub *sub,
					      pjsip_tx_data **p_tdata )
{
    pjsip_mwi *mwi;
    pjsip_tx_data *tdata;
    pj_status_t status;
    
    /* Check arguments. */
    PJ_ASSERT_RETURN(sub && p_tdata, PJ_EINVAL);

    /* Get the mwi object. */
    mwi = (pjsip_mwi*) pjsip_evsub_get_mod_data(sub, mod_mwi.id);
    PJ_ASSERT_RETURN(mwi != NULL, PJ_EINVALIDOP);

    /* Lock object. */
    pjsip_dlg_inc_lock(mwi->dlg);

    /* Create the NOTIFY request. */
    status = pjsip_evsub_current_notify( sub, &tdata);
    if (status != PJ_SUCCESS)
	goto on_return;


    /* Create message body to reflect the mwi status. */
    status = mwi_create_msg_body( mwi, tdata );
    if (status != PJ_SUCCESS)
	goto on_return;

    /* Done. */
    *p_tdata = tdata;

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


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

/*
 * This callback is called by event subscription when subscription
 * state has changed.
 */
static void mwi_on_evsub_state( pjsip_evsub *sub, pjsip_event *event)
{
    pjsip_mwi *mwi;

    mwi = (pjsip_mwi*) pjsip_evsub_get_mod_data(sub, mod_mwi.id);
    PJ_ASSERT_ON_FAIL(mwi!=NULL, {return;});

    if (mwi->user_cb.on_evsub_state)
	(*mwi->user_cb.on_evsub_state)(sub, event);

    if (pjsip_evsub_get_state(sub) == PJSIP_EVSUB_STATE_TERMINATED) {
	if (mwi->body_pool) {
	    pj_pool_release(mwi->body_pool);
	    mwi->body_pool = NULL;
	}
    }
}

/*
 * Called when transaction state has changed.
 */
static void mwi_on_evsub_tsx_state( pjsip_evsub *sub, pjsip_transaction *tsx,
				     pjsip_event *event)
{
    pjsip_mwi *mwi;

    mwi = (pjsip_mwi*) pjsip_evsub_get_mod_data(sub, mod_mwi.id);
    PJ_ASSERT_ON_FAIL(mwi!=NULL, {return;});

    if (mwi->user_cb.on_tsx_state)
	(*mwi->user_cb.on_tsx_state)(sub, tsx, event);
}


/*
 * Called when SUBSCRIBE is received.
 */
static void mwi_on_evsub_rx_refresh( pjsip_evsub *sub, 
				     pjsip_rx_data *rdata,
				     int *p_st_code,
				     pj_str_t **p_st_text,
				     pjsip_hdr *res_hdr,
				     pjsip_msg_body **p_body)
{
    pjsip_mwi *mwi;

    mwi = (pjsip_mwi*) pjsip_evsub_get_mod_data(sub, mod_mwi.id);
    PJ_ASSERT_ON_FAIL(mwi!=NULL, {return;});

    if (mwi->user_cb.on_rx_refresh) {
	(*mwi->user_cb.on_rx_refresh)(sub, rdata, p_st_code, p_st_text,
				       res_hdr, p_body);

    } else {
	/* Implementors MUST send NOTIFY if it implements on_rx_refresh */
	pjsip_tx_data *tdata;
	pj_str_t timeout = { "timeout", 7};
	pj_status_t status;

	if (pjsip_evsub_get_state(sub)==PJSIP_EVSUB_STATE_TERMINATED) {
	    status = pjsip_mwi_notify( sub, PJSIP_EVSUB_STATE_TERMINATED,
				       NULL, &timeout, NULL, NULL, &tdata);
	} else {
	    status = pjsip_mwi_current_notify(sub, &tdata);
	}

	if (status == PJ_SUCCESS)
	    pjsip_mwi_send_request(sub, tdata);
    }
}


/*
 * Called when NOTIFY is received.
 */
static void mwi_on_evsub_rx_notify( pjsip_evsub *sub, 
				     pjsip_rx_data *rdata,
				     int *p_st_code,
				     pj_str_t **p_st_text,
				     pjsip_hdr *res_hdr,
				     pjsip_msg_body **p_body)
{
    pjsip_mwi *mwi;

    mwi = (pjsip_mwi*) pjsip_evsub_get_mod_data(sub, mod_mwi.id);
    PJ_ASSERT_ON_FAIL(mwi!=NULL, {return;});

    /* Just notify application. */
    if (mwi->user_cb.on_rx_notify) {
	(*mwi->user_cb.on_rx_notify)(sub, rdata, p_st_code, p_st_text, 
				     res_hdr, p_body);
    }
}

/*
 * Called when it's time to send SUBSCRIBE.
 */
static void mwi_on_evsub_client_refresh(pjsip_evsub *sub)
{
    pjsip_mwi *mwi;

    mwi = (pjsip_mwi*) pjsip_evsub_get_mod_data(sub, mod_mwi.id);
    PJ_ASSERT_ON_FAIL(mwi!=NULL, {return;});

    if (mwi->user_cb.on_client_refresh) {
	(*mwi->user_cb.on_client_refresh)(sub);
    } else {
	pj_status_t status;
	pjsip_tx_data *tdata;

	status = pjsip_mwi_initiate(sub, -1, &tdata);
	if (status == PJ_SUCCESS)
	    pjsip_mwi_send_request(sub, tdata);
    }
}

/*
 * Called when no refresh is received after the interval.
 */
static void mwi_on_evsub_server_timeout(pjsip_evsub *sub)
{
    pjsip_mwi *mwi;

    mwi = (pjsip_mwi*) pjsip_evsub_get_mod_data(sub, mod_mwi.id);
    PJ_ASSERT_ON_FAIL(mwi!=NULL, {return;});

    if (mwi->user_cb.on_server_timeout) {
	(*mwi->user_cb.on_server_timeout)(sub);
    } else {
	pj_status_t status;
	pjsip_tx_data *tdata;
	pj_str_t reason = { "timeout", 7 };

	status = pjsip_mwi_notify(sub, PJSIP_EVSUB_STATE_TERMINATED,
				   NULL, &reason, NULL, NULL, &tdata);
	if (status == PJ_SUCCESS)
	    pjsip_mwi_send_request(sub, tdata);
    }
}

