/* $Id$ */
/* 
 * Copyright (C) 2008-2009 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/presence.h>
#include <pjsip-simple/errno.h>
#include <pjsip-simple/evsub_msg.h>
#include <pjsip/sip_module.h>
#include <pjsip/sip_multipart.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		    "presence.c"
#define PRES_DEFAULT_EXPIRES	    PJSIP_PRES_DEFAULT_EXPIRES

#if PJSIP_PRES_BAD_CONTENT_RESPONSE < 200 || \
    PJSIP_PRES_BAD_CONTENT_RESPONSE > 699 || \
    PJSIP_PRES_BAD_CONTENT_RESPONSE/100 == 3
# error Invalid PJSIP_PRES_BAD_CONTENT_RESPONSE value
#endif

/*
 * Presence module (mod-presence)
 */
static struct pjsip_module mod_presence = 
{
    NULL, NULL,			    /* prev, next.			*/
    { "mod-presence", 12 },	    /* 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()			*/
};


/*
 * Presence message body type.
 */
typedef enum content_type_e
{
    CONTENT_TYPE_NONE,
    CONTENT_TYPE_PIDF,
    CONTENT_TYPE_XPIDF,
} content_type_e;

/*
 * This structure describe a presentity, for both subscriber and notifier.
 */
struct pjsip_pres
{
    pjsip_evsub		*sub;		/**< Event subscribtion record.	    */
    pjsip_dialog	*dlg;		/**< The dialog.		    */
    content_type_e	 content_type;	/**< Content-Type.		    */
    pj_pool_t		*status_pool;	/**< Pool for pres_status	    */
    pjsip_pres_status	 status;	/**< Presence status.		    */
    pj_pool_t		*tmp_pool;	/**< Pool for tmp_status	    */
    pjsip_pres_status	 tmp_status;	/**< Temp, before NOTIFY is answred.*/
    pjsip_evsub_user	 user_cb;	/**< The user callback.		    */
};


typedef struct pjsip_pres pjsip_pres;


/*
 * Forward decl for evsub callback.
 */
static void pres_on_evsub_state( pjsip_evsub *sub, pjsip_event *event);
static void pres_on_evsub_tsx_state( pjsip_evsub *sub, pjsip_transaction *tsx,
				     pjsip_event *event);
static void pres_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 pres_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 pres_on_evsub_client_refresh(pjsip_evsub *sub);
static void pres_on_evsub_server_timeout(pjsip_evsub *sub);


/*
 * Event subscription callback for presence.
 */
static pjsip_evsub_user pres_user = 
{
    &pres_on_evsub_state,
    &pres_on_evsub_tsx_state,
    &pres_on_evsub_rx_refresh,
    &pres_on_evsub_rx_notify,
    &pres_on_evsub_client_refresh,
    &pres_on_evsub_server_timeout,
};


/*
 * Some static constants.
 */
const pj_str_t STR_EVENT	    = { "Event", 5 };
const pj_str_t STR_PRESENCE	    = { "presence", 8 };
const pj_str_t STR_APPLICATION	    = { "application", 11 };
const pj_str_t STR_PIDF_XML	    = { "pidf+xml", 8};
const pj_str_t STR_XPIDF_XML	    = { "xpidf+xml", 9};
const pj_str_t STR_APP_PIDF_XML	    = { "application/pidf+xml", 20 };
const pj_str_t STR_APP_XPIDF_XML    = { "application/xpidf+xml", 21 };


/*
 * Init presence module.
 */
PJ_DEF(pj_status_t) pjsip_pres_init_module( pjsip_endpoint *endpt,
					    pjsip_module *mod_evsub)
{
    pj_status_t status;
    pj_str_t accept[2];

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

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

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

    accept[0] = STR_APP_PIDF_XML;
    accept[1] = STR_APP_XPIDF_XML;

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

    return PJ_SUCCESS;
}


/*
 * Get presence module instance.
 */
PJ_DEF(pjsip_module*) pjsip_pres_instance(void)
{
    return &mod_presence;
}


/*
 * Create client subscription.
 */
PJ_DEF(pj_status_t) pjsip_pres_create_uac( pjsip_dialog *dlg,
					   const pjsip_evsub_user *user_cb,
					   unsigned options,
					   pjsip_evsub **p_evsub )
{
    pj_status_t status;
    pjsip_pres *pres;
    char obj_name[PJ_MAX_OBJ_NAME];
    pjsip_evsub *sub;

    PJ_ASSERT_RETURN(dlg && p_evsub, PJ_EINVAL);

    pjsip_dlg_inc_lock(dlg);

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

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

    pj_ansi_snprintf(obj_name, PJ_MAX_OBJ_NAME, "pres%p", dlg->pool);
    pres->status_pool = pj_pool_create(dlg->pool->factory, obj_name, 
				       512, 512, NULL);
    pj_ansi_snprintf(obj_name, PJ_MAX_OBJ_NAME, "tmpres%p", dlg->pool);
    pres->tmp_pool = pj_pool_create(dlg->pool->factory, obj_name, 
				    512, 512, NULL);

    /* Attach to evsub */
    pjsip_evsub_set_mod_data(sub, mod_presence.id, pres);

    *p_evsub = sub;

on_return:
    pjsip_dlg_dec_lock(dlg);
    return status;
}


/*
 * Create server subscription.
 */
PJ_DEF(pj_status_t) pjsip_pres_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;
    content_type_e content_type = CONTENT_TYPE_NONE;
    pjsip_evsub *sub;
    pjsip_pres *pres;
    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 "presence" */
    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_PRESENCE) != 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_PIDF_XML)==0) {
		content_type = CONTENT_TYPE_PIDF;
		break;
	    } else
	    if (pj_stricmp(&accept->values[i], &STR_APP_XPIDF_XML)==0) {
		content_type = CONTENT_TYPE_XPIDF;
		break;
	    }
	}

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

    } else {
	/* No Accept header.
	 * Treat as "application/pidf+xml"
	 */
	content_type = CONTENT_TYPE_PIDF;
    }

    /* Lock dialog */
    pjsip_dlg_inc_lock(dlg);


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

    /* Create server presence subscription */
    pres = PJ_POOL_ZALLOC_T(dlg->pool, pjsip_pres);
    pres->dlg = dlg;
    pres->sub = sub;
    pres->content_type = content_type;
    if (user_cb)
	pj_memcpy(&pres->user_cb, user_cb, sizeof(pjsip_evsub_user));

    pj_ansi_snprintf(obj_name, PJ_MAX_OBJ_NAME, "pres%p", dlg->pool);
    pres->status_pool = pj_pool_create(dlg->pool->factory, obj_name, 
				       512, 512, NULL);
    pj_ansi_snprintf(obj_name, PJ_MAX_OBJ_NAME, "tmpres%p", dlg->pool);
    pres->tmp_pool = pj_pool_create(dlg->pool->factory, obj_name, 
				    512, 512, NULL);

    /* Attach to evsub */
    pjsip_evsub_set_mod_data(sub, mod_presence.id, pres);

    /* Done: */
    *p_evsub = sub;

on_return:
    pjsip_dlg_dec_lock(dlg);
    return status;
}


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

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


/*
 * Add custom headers.
 */
PJ_DEF(pj_status_t) pjsip_pres_add_header( pjsip_evsub *sub,
					   const pjsip_hdr *hdr_list )
{
    return pjsip_evsub_add_header( sub, hdr_list );
}


/*
 * Accept incoming subscription.
 */
PJ_DEF(pj_status_t) pjsip_pres_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 );
}


/*
 * Get presence status.
 */
PJ_DEF(pj_status_t) pjsip_pres_get_status( pjsip_evsub *sub,
					   pjsip_pres_status *status )
{
    pjsip_pres *pres;

    PJ_ASSERT_RETURN(sub && status, PJ_EINVAL);

    pres = (pjsip_pres*) pjsip_evsub_get_mod_data(sub, mod_presence.id);
    PJ_ASSERT_RETURN(pres!=NULL, PJSIP_SIMPLE_ENOPRESENCE);

    if (pres->tmp_status._is_valid) {
	PJ_ASSERT_RETURN(pres->tmp_pool!=NULL, PJSIP_SIMPLE_ENOPRESENCE);
	pj_memcpy(status, &pres->tmp_status, sizeof(pjsip_pres_status));
    } else {
	PJ_ASSERT_RETURN(pres->status_pool!=NULL, PJSIP_SIMPLE_ENOPRESENCE);
	pj_memcpy(status, &pres->status, sizeof(pjsip_pres_status));
    }

    return PJ_SUCCESS;
}


/*
 * Set presence status.
 */
PJ_DEF(pj_status_t) pjsip_pres_set_status( pjsip_evsub *sub,
					   const pjsip_pres_status *status )
{
    unsigned i;
    pj_pool_t *tmp;
    pjsip_pres *pres;

    PJ_ASSERT_RETURN(sub && status, PJ_EINVAL);

    pres = (pjsip_pres*) pjsip_evsub_get_mod_data(sub, mod_presence.id);
    PJ_ASSERT_RETURN(pres!=NULL, PJSIP_SIMPLE_ENOPRESENCE);

    for (i=0; i<status->info_cnt; ++i) {
	pres->status.info[i].basic_open = status->info[i].basic_open;
	if (pres->status.info[i].id.slen) {
	    /* Id already set */
	} else if (status->info[i].id.slen == 0) {
	    pj_create_unique_string(pres->dlg->pool, 
	    			    &pres->status.info[i].id);
	} else {
	    pj_strdup(pres->dlg->pool, 
		      &pres->status.info[i].id,
		      &status->info[i].id);
	}
	pj_strdup(pres->tmp_pool, 
		  &pres->status.info[i].contact,
		  &status->info[i].contact);

	/* Duplicate <person> */
	pres->status.info[i].rpid.activity = 
	    status->info[i].rpid.activity;
	pj_strdup(pres->tmp_pool, 
		  &pres->status.info[i].rpid.id,
		  &status->info[i].rpid.id);
	pj_strdup(pres->tmp_pool,
		  &pres->status.info[i].rpid.note,
		  &status->info[i].rpid.note);

    }

    pres->status.info_cnt = status->info_cnt;

    /* Swap pools */
    tmp = pres->tmp_pool;
    pres->tmp_pool = pres->status_pool;
    pres->status_pool = tmp;
    pj_pool_reset(pres->tmp_pool);

    return PJ_SUCCESS;
}


/*
 * Create message body.
 */
static pj_status_t pres_create_msg_body( pjsip_pres *pres, 
					 pjsip_tx_data *tdata)
{
    pj_str_t entity;

    /* Get publisher URI */
    entity.ptr = (char*) pj_pool_alloc(tdata->pool, PJSIP_MAX_URL_SIZE);
    entity.slen = pjsip_uri_print(PJSIP_URI_IN_REQ_URI,
				  pres->dlg->local.info->uri,
				  entity.ptr, PJSIP_MAX_URL_SIZE);
    if (entity.slen < 1)
	return PJ_ENOMEM;

    if (pres->content_type == CONTENT_TYPE_PIDF) {

	return pjsip_pres_create_pidf(tdata->pool, &pres->status,
				      &entity, &tdata->msg->body);

    } else if (pres->content_type == CONTENT_TYPE_XPIDF) {

	return pjsip_pres_create_xpidf(tdata->pool, &pres->status,
				       &entity, &tdata->msg->body);

    } else {
	return PJSIP_SIMPLE_EBADCONTENT;
    }
}


/*
 * Create NOTIFY
 */
PJ_DEF(pj_status_t) pjsip_pres_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_pres *pres;
    pjsip_tx_data *tdata;
    pj_status_t status;
    
    /* Check arguments. */
    PJ_ASSERT_RETURN(sub, PJ_EINVAL);

    /* Get the presence object. */
    pres = (pjsip_pres*) pjsip_evsub_get_mod_data(sub, mod_presence.id);
    PJ_ASSERT_RETURN(pres != NULL, PJSIP_SIMPLE_ENOPRESENCE);

    /* Must have at least one presence info, unless state is 
     * PJSIP_EVSUB_STATE_TERMINATED. This could happen if subscription
     * has not been active (e.g. we're waiting for user authorization)
     * and remote cancels the subscription.
     */
    PJ_ASSERT_RETURN(state==PJSIP_EVSUB_STATE_TERMINATED ||
		     pres->status.info_cnt > 0, PJSIP_SIMPLE_ENOPRESENCEINFO);


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

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


    /* Create message body to reflect the presence status. 
     * Only do this if we have presence status info to send (see above).
     */
    if (pres->status.info_cnt > 0) {
	status = pres_create_msg_body( pres, tdata );
	if (status != PJ_SUCCESS)
	    goto on_return;
    }

    /* Done. */
    *p_tdata = tdata;


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


/*
 * Create NOTIFY that reflect current state.
 */
PJ_DEF(pj_status_t) pjsip_pres_current_notify( pjsip_evsub *sub,
					       pjsip_tx_data **p_tdata )
{
    pjsip_pres *pres;
    pjsip_tx_data *tdata;
    pj_status_t status;
    
    /* Check arguments. */
    PJ_ASSERT_RETURN(sub, PJ_EINVAL);

    /* Get the presence object. */
    pres = (pjsip_pres*) pjsip_evsub_get_mod_data(sub, mod_presence.id);
    PJ_ASSERT_RETURN(pres != NULL, PJSIP_SIMPLE_ENOPRESENCE);

    /* We may not have a presence info yet, e.g. when we receive SUBSCRIBE
     * to refresh subscription while we're waiting for user authorization.
     */
    //PJ_ASSERT_RETURN(pres->status.info_cnt > 0, 
    //		       PJSIP_SIMPLE_ENOPRESENCEINFO);


    /* Lock object. */
    pjsip_dlg_inc_lock(pres->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 presence status. */
    if (pres->status.info_cnt > 0) {
	status = pres_create_msg_body( pres, tdata );
	if (status != PJ_SUCCESS)
	    goto on_return;
    }

    /* Done. */
    *p_tdata = tdata;


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


/*
 * Send request.
 */
PJ_DEF(pj_status_t) pjsip_pres_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 pres_on_evsub_state( pjsip_evsub *sub, pjsip_event *event)
{
    pjsip_pres *pres;

    pres = (pjsip_pres*) pjsip_evsub_get_mod_data(sub, mod_presence.id);
    PJ_ASSERT_ON_FAIL(pres!=NULL, {return;});

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

    if (pjsip_evsub_get_state(sub) == PJSIP_EVSUB_STATE_TERMINATED) {
	if (pres->status_pool) {
	    pj_pool_release(pres->status_pool);
	    pres->status_pool = NULL;
	}
	if (pres->tmp_pool) {
	    pj_pool_release(pres->tmp_pool);
	    pres->tmp_pool = NULL;
	}
    }
}

/*
 * Called when transaction state has changed.
 */
static void pres_on_evsub_tsx_state( pjsip_evsub *sub, pjsip_transaction *tsx,
				     pjsip_event *event)
{
    pjsip_pres *pres;

    pres = (pjsip_pres*) pjsip_evsub_get_mod_data(sub, mod_presence.id);
    PJ_ASSERT_ON_FAIL(pres!=NULL, {return;});

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


/*
 * Called when SUBSCRIBE is received.
 */
static void pres_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_pres *pres;

    pres = (pjsip_pres*) pjsip_evsub_get_mod_data(sub, mod_presence.id);
    PJ_ASSERT_ON_FAIL(pres!=NULL, {return;});

    if (pres->user_cb.on_rx_refresh) {
	(*pres->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_pres_notify( sub, PJSIP_EVSUB_STATE_TERMINATED,
					NULL, &timeout, &tdata);
	} else {
	    status = pjsip_pres_current_notify(sub, &tdata);
	}

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


/*
 * Process the content of incoming NOTIFY request and update temporary
 * status.
 *
 * return PJ_SUCCESS if incoming request is acceptable. If return value
 *	  is not PJ_SUCCESS, res_hdr may be added with Warning header.
 */
static pj_status_t pres_process_rx_notify( pjsip_pres *pres,
					   pjsip_rx_data *rdata, 
					   int *p_st_code,
					   pj_str_t **p_st_text,
					   pjsip_hdr *res_hdr)
{
    const pj_str_t STR_MULTIPART = { "multipart", 9 };
    pjsip_ctype_hdr *ctype_hdr;
    pj_status_t status;

    *p_st_text = NULL;

    /* Check Content-Type and msg body are present. */
    ctype_hdr = rdata->msg_info.ctype;

    if (ctype_hdr==NULL || rdata->msg_info.msg->body==NULL) {
	
	pjsip_warning_hdr *warn_hdr;
	pj_str_t warn_text;

	*p_st_code = PJSIP_SC_BAD_REQUEST;

	warn_text = pj_str("Message body is not present");
	warn_hdr = pjsip_warning_hdr_create(rdata->tp_info.pool, 399,
					    pjsip_endpt_name(pres->dlg->endpt),
					    &warn_text);
	pj_list_push_back(res_hdr, warn_hdr);

	return PJSIP_ERRNO_FROM_SIP_STATUS(PJSIP_SC_BAD_REQUEST);
    }

    /* Parse content. */
    if (pj_stricmp(&ctype_hdr->media.type, &STR_MULTIPART)==0) {
	pjsip_multipart_part *mpart;
	pjsip_media_type ctype;

	pjsip_media_type_init(&ctype, (pj_str_t*)&STR_APPLICATION,
			      (pj_str_t*)&STR_PIDF_XML);
	mpart = pjsip_multipart_find_part(rdata->msg_info.msg->body,
					  &ctype, NULL);
	if (mpart) {
	    status = pjsip_pres_parse_pidf2((char*)mpart->body->data,
					    mpart->body->len, pres->tmp_pool,
					    &pres->tmp_status);
	}

	if (mpart==NULL) {
	    pjsip_media_type_init(&ctype, (pj_str_t*)&STR_APPLICATION,
				  (pj_str_t*)&STR_XPIDF_XML);
	    mpart = pjsip_multipart_find_part(rdata->msg_info.msg->body,
					      &ctype, NULL);
	    if (mpart) {
		status = pjsip_pres_parse_xpidf2((char*)mpart->body->data,
						 mpart->body->len,
						 pres->tmp_pool,
						 &pres->tmp_status);
	    } else {
		status = PJSIP_SIMPLE_EBADCONTENT;
	    }
	}
    }
    else
    if (pj_stricmp(&ctype_hdr->media.type, &STR_APPLICATION)==0 &&
	pj_stricmp(&ctype_hdr->media.subtype, &STR_PIDF_XML)==0)
    {
	status = pjsip_pres_parse_pidf( rdata, pres->tmp_pool,
					&pres->tmp_status);
    }
    else 
    if (pj_stricmp(&ctype_hdr->media.type, &STR_APPLICATION)==0 &&
	pj_stricmp(&ctype_hdr->media.subtype, &STR_XPIDF_XML)==0)
    {
	status = pjsip_pres_parse_xpidf( rdata, pres->tmp_pool,
					 &pres->tmp_status);
    }
    else
    {
	status = PJSIP_SIMPLE_EBADCONTENT;
    }

    if (status != PJ_SUCCESS) {
	/* Unsupported or bad Content-Type */
	if (PJSIP_PRES_BAD_CONTENT_RESPONSE >= 300) {
	    pjsip_accept_hdr *accept_hdr;
	    pjsip_warning_hdr *warn_hdr;

	    *p_st_code = PJSIP_PRES_BAD_CONTENT_RESPONSE;

	    /* Add Accept header */
	    accept_hdr = pjsip_accept_hdr_create(rdata->tp_info.pool);
	    accept_hdr->values[accept_hdr->count++] = STR_APP_PIDF_XML;
	    accept_hdr->values[accept_hdr->count++] = STR_APP_XPIDF_XML;
	    pj_list_push_back(res_hdr, accept_hdr);

	    /* Add Warning header */
	    warn_hdr = pjsip_warning_hdr_create_from_status(
					rdata->tp_info.pool,
					pjsip_endpt_name(pres->dlg->endpt),
					status);
	    pj_list_push_back(res_hdr, warn_hdr);

	    return status;
	} else {
	    pj_assert(PJSIP_PRES_BAD_CONTENT_RESPONSE/100 == 2);
	    PJ_PERROR(4,(THIS_FILE, status,
			 "Ignoring presence error due to "
		         "PJSIP_PRES_BAD_CONTENT_RESPONSE setting [%d]",
		         PJSIP_PRES_BAD_CONTENT_RESPONSE));
	    *p_st_code = PJSIP_PRES_BAD_CONTENT_RESPONSE;
	    status = PJ_SUCCESS;
	}
    }

    /* If application calls pres_get_status(), redirect the call to
     * retrieve the temporary status.
     */
    pres->tmp_status._is_valid = PJ_TRUE;

    return PJ_SUCCESS;
}


/*
 * Called when NOTIFY is received.
 */
static void pres_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_pres *pres;
    pj_status_t status;

    pres = (pjsip_pres*) pjsip_evsub_get_mod_data(sub, mod_presence.id);
    PJ_ASSERT_ON_FAIL(pres!=NULL, {return;});

    if (rdata->msg_info.msg->body) {
	status = pres_process_rx_notify( pres, rdata, p_st_code, p_st_text,
					 res_hdr );
	if (status != PJ_SUCCESS)
	    return;

    } else {
#if 1
	/* This is the newest change, http://trac.pjsip.org/repos/ticket/873
	 * Some app want to be notified about the empty NOTIFY, e.g. to 
	 * decide whether it should consider the buddy as offline.
	 * In this case, leave the buddy state unchanged, but set the
	 * "tuple_node" in pjsip_pres_status to NULL.
	 */
	unsigned i;
	for (i=0; i<pres->status.info_cnt; ++i) {
	    pres->status.info[i].tuple_node = NULL;
	}

#elif 0
	/* This has just been changed. Previously, we treat incoming NOTIFY
	 * with no message body as having the presence subscription closed.
	 * Now we treat it as no change in presence status (ref: EyeBeam).
	 */
	*p_st_code = 200;
	return;
#else
	unsigned i;
	/* Subscription is terminated. Consider contact is offline */
	pres->tmp_status._is_valid = PJ_TRUE;
	for (i=0; i<pres->tmp_status.info_cnt; ++i)
	    pres->tmp_status.info[i].basic_open = PJ_FALSE;
#endif
    }

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

    
    /* If application responded NOTIFY with 2xx, copy temporary status
     * to main status, and mark the temporary status as invalid.
     */
    if ((*p_st_code)/100 == 2) {
	pj_pool_t *tmp;

	pj_memcpy(&pres->status, &pres->tmp_status, sizeof(pjsip_pres_status));

	/* Swap the pool */
	tmp = pres->tmp_pool;
	pres->tmp_pool = pres->status_pool;
	pres->status_pool = tmp;
    }

    pres->tmp_status._is_valid = PJ_FALSE;
    pj_pool_reset(pres->tmp_pool);

    /* Done */
}

/*
 * Called when it's time to send SUBSCRIBE.
 */
static void pres_on_evsub_client_refresh(pjsip_evsub *sub)
{
    pjsip_pres *pres;

    pres = (pjsip_pres*) pjsip_evsub_get_mod_data(sub, mod_presence.id);
    PJ_ASSERT_ON_FAIL(pres!=NULL, {return;});

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

	status = pjsip_pres_initiate(sub, -1, &tdata);
	if (status == PJ_SUCCESS)
	    pjsip_pres_send_request(sub, tdata);
    }
}

/*
 * Called when no refresh is received after the interval.
 */
static void pres_on_evsub_server_timeout(pjsip_evsub *sub)
{
    pjsip_pres *pres;

    pres = (pjsip_pres*) pjsip_evsub_get_mod_data(sub, mod_presence.id);
    PJ_ASSERT_ON_FAIL(pres!=NULL, {return;});

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

	status = pjsip_pres_notify(sub, PJSIP_EVSUB_STATE_TERMINATED,
				   NULL, &reason, &tdata);
	if (status == PJ_SUCCESS)
	    pjsip_pres_send_request(sub, tdata);
    }
}

