/* $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 <pjsua-lib/pjsua.h>
#include <pjsua-lib/pjsua_internal.h>


#define THIS_FILE   "pjsua_im.h"


/* Declare MESSAGE method */
/* We put PJSIP_MESSAGE_METHOD as the enum here, so that when
 * somebody add that method into pjsip_method_e in sip_msg.h we
 * will get an error here.
 */
enum
{
    PJSIP_MESSAGE_METHOD = PJSIP_OTHER_METHOD
};

const pjsip_method pjsip_message_method =
{
    (pjsip_method_e) PJSIP_MESSAGE_METHOD,
    { "MESSAGE", 7 }
};


/* Proto */
static pj_bool_t im_on_rx_request(pjsip_rx_data *rdata);


/* The module instance. */
static pjsip_module mod_pjsua_im = 
{
    NULL, NULL,				/* prev, next.		*/
    { "mod-pjsua-im", 12 },		/* Name.		*/
    -1,					/* Id			*/
    PJSIP_MOD_PRIORITY_APPLICATION,	/* Priority	        */
    NULL,				/* load()		*/
    NULL,				/* start()		*/
    NULL,				/* stop()		*/
    NULL,				/* unload()		*/
    &im_on_rx_request,			/* on_rx_request()	*/
    NULL,				/* on_rx_response()	*/
    NULL,				/* on_tx_request.	*/
    NULL,				/* on_tx_response()	*/
    NULL,				/* on_tsx_state()	*/

};


/* MIME constants. */
static const pj_str_t STR_MIME_APP	   = { "application", 11 };
static const pj_str_t STR_MIME_ISCOMPOSING = { "im-iscomposing+xml", 18 };
static const pj_str_t STR_MIME_TEXT	   = { "text", 4 };
static const pj_str_t STR_MIME_PLAIN	   = { "plain", 5 };


/* Check if content type is acceptable */
#if 0
static pj_bool_t acceptable_message(const pjsip_media_type *mime)
{
    return (pj_stricmp(&mime->type, &STR_MIME_TEXT)==0 &&
	    pj_stricmp(&mime->subtype, &STR_MIME_PLAIN)==0)
	    ||
	   (pj_stricmp(&mime->type, &STR_MIME_APP)==0 &&
	    pj_stricmp(&mime->subtype, &STR_MIME_ISCOMPOSING)==0);
}
#endif

/**
 * Create Accept header for MESSAGE.
 */
pjsip_accept_hdr* pjsua_im_create_accept(pj_pool_t *pool)
{
    /* Create Accept header. */
    pjsip_accept_hdr *accept;

    accept = pjsip_accept_hdr_create(pool);
    accept->values[0] = pj_str("text/plain");
    accept->values[1] = pj_str("application/im-iscomposing+xml");
    accept->count = 2;

    return accept;
}

/**
 * Private: check if we can accept the message.
 */
pj_bool_t pjsua_im_accept_pager(pjsip_rx_data *rdata,
				pjsip_accept_hdr **p_accept_hdr)
{
    /* Some UA sends text/html, so this check will break */
#if 0
    pjsip_ctype_hdr *ctype;
    pjsip_msg *msg;

    msg = rdata->msg_info.msg;

    /* Request MUST have message body, with Content-Type equal to
     * "text/plain".
     */
    ctype = (pjsip_ctype_hdr*)
	    pjsip_msg_find_hdr(msg, PJSIP_H_CONTENT_TYPE, NULL);
    if (msg->body == NULL || ctype == NULL || 
	!acceptable_message(&ctype->media)) 
    {
	/* Create Accept header. */
	if (p_accept_hdr)
	    *p_accept_hdr = pjsua_im_create_accept(rdata->tp_info.pool);

	return PJ_FALSE;
    }
#elif 0
    pjsip_msg *msg;

    msg = rdata->msg_info.msg;
    if (msg->body == NULL) {
	/* Create Accept header. */
	if (p_accept_hdr)
	    *p_accept_hdr = pjsua_im_create_accept(rdata->tp_info.pool);

	return PJ_FALSE;
    }
#else
    /* Ticket #693: allow incoming MESSAGE without message body */
    PJ_UNUSED_ARG(rdata);
    PJ_UNUSED_ARG(p_accept_hdr);
#endif

    return PJ_TRUE;
}

/**
 * Private: process pager message.
 *	    This may trigger pjsua_ui_on_pager() or pjsua_ui_on_typing().
 */
void pjsua_im_process_pager(int call_id, const pj_str_t *from,
			    const pj_str_t *to, pjsip_rx_data *rdata)
{
    pjsip_contact_hdr *contact_hdr;
    pj_str_t contact;
    pjsip_msg_body *body = rdata->msg_info.msg->body;

#if 0
    /* Ticket #693: allow incoming MESSAGE without message body */
    /* Body MUST have been checked before */
    pj_assert(body != NULL);
#endif


    /* Build remote contact */
    contact_hdr = (pjsip_contact_hdr*)
		  pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT,
				     NULL);
    if (contact_hdr) {
	contact.ptr = (char*) pj_pool_alloc(rdata->tp_info.pool, 
				    	    PJSIP_MAX_URL_SIZE);
	contact.slen = pjsip_uri_print(PJSIP_URI_IN_CONTACT_HDR,
				       contact_hdr->uri, contact.ptr,
				       PJSIP_MAX_URL_SIZE);
    } else {
	contact.slen = 0;
    }

    if (body && pj_stricmp(&body->content_type.type, &STR_MIME_APP)==0 &&
	pj_stricmp(&body->content_type.subtype, &STR_MIME_ISCOMPOSING)==0)
    {
	/* Expecting typing indication */
	pj_status_t status;
	pj_bool_t is_typing;

	status = pjsip_iscomposing_parse(rdata->tp_info.pool, (char*)body->data,
					 body->len, &is_typing, NULL, NULL,
					 NULL );
	if (status != PJ_SUCCESS) {
	    pjsua_perror(THIS_FILE, "Invalid MESSAGE body", status);
	    return;
	}

	if (pjsua_var.ua_cfg.cb.on_typing) {
	    (*pjsua_var.ua_cfg.cb.on_typing)(call_id, from, to, &contact,
					     is_typing);
	}

	if (pjsua_var.ua_cfg.cb.on_typing2) {
	    pjsua_acc_id acc_id;

	    if (call_id == PJSUA_INVALID_ID) {
		acc_id = pjsua_acc_find_for_incoming(rdata);
	    } else {
		pjsua_call *call = &pjsua_var.calls[call_id];
		acc_id = call->acc_id;
	    }


	    (*pjsua_var.ua_cfg.cb.on_typing2)(call_id, from, to, &contact,
					      is_typing, rdata, acc_id);
	}

    } else {
	pj_str_t mime_type;
	char buf[256];
	pjsip_media_type *m;
	pj_str_t text_body;
	
	/* Save text body */
	if (body) {
	    text_body.ptr = (char*)rdata->msg_info.msg->body->data;
	    text_body.slen = rdata->msg_info.msg->body->len;

	    /* Get mime type */
	    m = &rdata->msg_info.msg->body->content_type;
	    mime_type.ptr = buf;
	    mime_type.slen = pj_ansi_snprintf(buf, sizeof(buf),
					      "%.*s/%.*s",
					      (int)m->type.slen,
					      m->type.ptr,
					      (int)m->subtype.slen,
					      m->subtype.ptr);
	    if (mime_type.slen < 1)
		mime_type.slen = 0;


	} else {
	    text_body.ptr = mime_type.ptr = "";
	    text_body.slen = mime_type.slen = 0;
	}

	if (pjsua_var.ua_cfg.cb.on_pager) {
	    (*pjsua_var.ua_cfg.cb.on_pager)(call_id, from, to, &contact, 
					    &mime_type, &text_body);
	}

	if (pjsua_var.ua_cfg.cb.on_pager2) {
	    pjsua_acc_id acc_id;

	    if (call_id == PJSUA_INVALID_ID) {
		acc_id = pjsua_acc_find_for_incoming(rdata);
	    } else {
		pjsua_call *call = &pjsua_var.calls[call_id];
		acc_id = call->acc_id;
	    }

	    (*pjsua_var.ua_cfg.cb.on_pager2)(call_id, from, to, &contact, 
					     &mime_type, &text_body, rdata,
					     acc_id);
	}
    }
}


/*
 * Handler to receive incoming MESSAGE
 */
static pj_bool_t im_on_rx_request(pjsip_rx_data *rdata)
{
    pj_str_t from, to;
    pjsip_accept_hdr *accept_hdr;
    pjsip_msg *msg;
    pj_status_t status;

    msg = rdata->msg_info.msg;

    /* Only want to handle MESSAGE requests. */
    if (pjsip_method_cmp(&msg->line.req.method, &pjsip_message_method) != 0) {
	return PJ_FALSE;
    }


    /* Should not have any transaction attached to rdata. */
    PJ_ASSERT_RETURN(pjsip_rdata_get_tsx(rdata)==NULL, PJ_FALSE);

    /* Should not have any dialog attached to rdata. */
    PJ_ASSERT_RETURN(pjsip_rdata_get_dlg(rdata)==NULL, PJ_FALSE);

    /* Check if we can accept the message. */
    if (!pjsua_im_accept_pager(rdata, &accept_hdr)) {
	pjsip_hdr hdr_list;

	pj_list_init(&hdr_list);
	pj_list_push_back(&hdr_list, accept_hdr);

	pjsip_endpt_respond_stateless(pjsua_var.endpt, rdata, 
				      PJSIP_SC_NOT_ACCEPTABLE_HERE, NULL, 
				      &hdr_list, NULL);
	return PJ_TRUE;
    }
    
    /* Respond with 200 first, so that remote doesn't retransmit in case
     * the UI takes too long to process the message. 
     */
    status = pjsip_endpt_respond( pjsua_var.endpt, NULL, rdata, 200, NULL,
				  NULL, NULL, NULL);

    /* For the source URI, we use Contact header if present, since
     * Contact header contains the port number information. If this is
     * not available, then use From header.
     */
    from.ptr = (char*)pj_pool_alloc(rdata->tp_info.pool, PJSIP_MAX_URL_SIZE);
    from.slen = pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR, 
				rdata->msg_info.from->uri,
				from.ptr, PJSIP_MAX_URL_SIZE);

    if (from.slen < 1)
	from = pj_str("<--URI is too long-->");

    /* Build the To text. */
    to.ptr = (char*) pj_pool_alloc(rdata->tp_info.pool, PJSIP_MAX_URL_SIZE);
    to.slen = pjsip_uri_print( PJSIP_URI_IN_FROMTO_HDR, 
			       rdata->msg_info.to->uri,
			       to.ptr, PJSIP_MAX_URL_SIZE);
    if (to.slen < 1)
	to = pj_str("<--URI is too long-->");

    /* Process pager. */
    pjsua_im_process_pager(-1, &from, &to, rdata);

    /* Done. */
    return PJ_TRUE;
}


/* Outgoing IM callback. */
static void im_callback(void *token, pjsip_event *e)
{
    pjsua_im_data *im_data = (pjsua_im_data*) token;

    if (e->type == PJSIP_EVENT_TSX_STATE) {

	pjsip_transaction *tsx = e->body.tsx_state.tsx;

	/* Ignore provisional response, if any */
	if (tsx->status_code < 200)
	    return;


	/* Handle authentication challenges */
	if (e->body.tsx_state.type == PJSIP_EVENT_RX_MSG &&
	    (tsx->status_code == 401 || tsx->status_code == 407)) 
	{
	    pjsip_rx_data *rdata = e->body.tsx_state.src.rdata;
	    pjsip_tx_data *tdata;
	    pjsip_auth_clt_sess auth;
	    pj_status_t status;

	    PJ_LOG(4,(THIS_FILE, "Resending IM with authentication"));

	    /* Create temporary authentication session */
	    pjsip_auth_clt_init(&auth,pjsua_var.endpt,rdata->tp_info.pool, 0);
    
	    pjsip_auth_clt_set_credentials(&auth, 
		pjsua_var.acc[im_data->acc_id].cred_cnt,
		pjsua_var.acc[im_data->acc_id].cred);

	    pjsip_auth_clt_set_prefs(&auth, 
				     &pjsua_var.acc[im_data->acc_id].cfg.auth_pref);

	    status = pjsip_auth_clt_reinit_req(&auth, rdata, tsx->last_tx,
					       &tdata);
	    if (status == PJ_SUCCESS) {
		pjsua_im_data *im_data2;

		/* Must duplicate im_data */
		im_data2 = pjsua_im_data_dup(tdata->pool, im_data);

		/* Re-send request */
		status = pjsip_endpt_send_request( pjsua_var.endpt, tdata, -1,
						   im_data2, &im_callback);
		if (status == PJ_SUCCESS) {
		    /* Done */
		    return;
		}
	    }
	}

	if (tsx->status_code/100 == 2) {
	    PJ_LOG(4,(THIS_FILE, 
		      "Message \'%s\' delivered successfully",
		      im_data->body.ptr));
	} else {
	    PJ_LOG(3,(THIS_FILE, 
		      "Failed to deliver message \'%s\': %d/%.*s",
		      im_data->body.ptr,
		      tsx->status_code,
		      (int)tsx->status_text.slen,
		      tsx->status_text.ptr));
	}

	if (pjsua_var.ua_cfg.cb.on_pager_status) {
	    pjsua_var.ua_cfg.cb.on_pager_status(im_data->call_id, 
					        &im_data->to,
						&im_data->body,
						im_data->user_data,
						(pjsip_status_code) 
						    tsx->status_code,
						&tsx->status_text);
	}

	if (pjsua_var.ua_cfg.cb.on_pager_status2) {
	    pjsip_rx_data *rdata;

	    if (e->body.tsx_state.type == PJSIP_EVENT_RX_MSG)
		rdata = e->body.tsx_state.src.rdata;
	    else
		rdata = NULL;

	    pjsua_var.ua_cfg.cb.on_pager_status2(im_data->call_id, 
					         &im_data->to,
					 	 &im_data->body,
						 im_data->user_data,
						 (pjsip_status_code) 
						    tsx->status_code,
						 &tsx->status_text,
						 tsx->last_tx,
						 rdata, im_data->acc_id);
	}
    }
}


/* Outgoing typing indication callback. 
 * (used to reauthenticate request)
 */
static void typing_callback(void *token, pjsip_event *e)
{
    pjsua_im_data *im_data = (pjsua_im_data*) token;

    if (e->type == PJSIP_EVENT_TSX_STATE) {

	pjsip_transaction *tsx = e->body.tsx_state.tsx;

	/* Ignore provisional response, if any */
	if (tsx->status_code < 200)
	    return;

	/* Handle authentication challenges */
	if (e->body.tsx_state.type == PJSIP_EVENT_RX_MSG &&
	    (tsx->status_code == 401 || tsx->status_code == 407)) 
	{
	    pjsip_rx_data *rdata = e->body.tsx_state.src.rdata;
	    pjsip_tx_data *tdata;
	    pjsip_auth_clt_sess auth;
	    pj_status_t status;

	    PJ_LOG(4,(THIS_FILE, "Resending IM with authentication"));

	    /* Create temporary authentication session */
	    pjsip_auth_clt_init(&auth,pjsua_var.endpt,rdata->tp_info.pool, 0);
    
	    pjsip_auth_clt_set_credentials(&auth, 
		pjsua_var.acc[im_data->acc_id].cred_cnt,
		pjsua_var.acc[im_data->acc_id].cred);

	    pjsip_auth_clt_set_prefs(&auth, 
				     &pjsua_var.acc[im_data->acc_id].cfg.auth_pref);

	    status = pjsip_auth_clt_reinit_req(&auth, rdata, tsx->last_tx,
					       &tdata);
	    if (status == PJ_SUCCESS) {
		pjsua_im_data *im_data2;

		/* Must duplicate im_data */
		im_data2 = pjsua_im_data_dup(tdata->pool, im_data);

		/* Re-send request */
		status = pjsip_endpt_send_request( pjsua_var.endpt, tdata, -1,
						   im_data2, &typing_callback);
		if (status == PJ_SUCCESS) {
		    /* Done */
		    return;
		}
	    }
	}

    }
}


/*
 * Send instant messaging outside dialog, using the specified account for
 * route set and authentication.
 */
PJ_DEF(pj_status_t) pjsua_im_send( pjsua_acc_id acc_id, 
				   const pj_str_t *to,
				   const pj_str_t *mime_type,
				   const pj_str_t *content,
				   const pjsua_msg_data *msg_data,
				   void *user_data)
{
    pjsip_tx_data *tdata;
    const pj_str_t mime_text_plain = pj_str("text/plain");
    const pj_str_t STR_CONTACT = { "Contact", 7 };
    pjsip_media_type media_type;
    pjsua_im_data *im_data;
    pj_str_t contact;
    pj_status_t status;

    /* To and message body must be specified. */
    PJ_ASSERT_RETURN(to && content, PJ_EINVAL);

    /* Create request. */
    status = pjsip_endpt_create_request(pjsua_var.endpt, 
					&pjsip_message_method, to, 
					&pjsua_var.acc[acc_id].cfg.id,
					to, NULL, NULL, -1, NULL, &tdata);
    if (status != PJ_SUCCESS) {
	pjsua_perror(THIS_FILE, "Unable to create request", status);
	return status;
    }

    /* If account is locked to specific transport, then set transport to
     * the request.
     */
    if (pjsua_var.acc[acc_id].cfg.transport_id != PJSUA_INVALID_ID) {
	pjsip_tpselector tp_sel;

	pjsua_init_tpselector(pjsua_var.acc[acc_id].cfg.transport_id, &tp_sel);
	pjsip_tx_data_set_transport(tdata, &tp_sel);
    }

    /* Add accept header. */
    pjsip_msg_add_hdr( tdata->msg, 
		       (pjsip_hdr*)pjsua_im_create_accept(tdata->pool));

    /* Add contact. */
    status = pjsua_acc_create_uac_contact(tdata->pool, &contact, acc_id, to);
    if (status != PJ_SUCCESS) {
	pjsua_perror(THIS_FILE, "Unable to generate Contact header", status);
	pjsip_tx_data_dec_ref(tdata);
	return status;
    }

    pjsip_msg_add_hdr( tdata->msg, (pjsip_hdr*)
	pjsip_generic_string_hdr_create(tdata->pool, 
					&STR_CONTACT, &contact));

    /* Create IM data to keep message details and give it back to
     * application on the callback
     */
    im_data = PJ_POOL_ZALLOC_T(tdata->pool, pjsua_im_data);
    im_data->acc_id = acc_id;
    im_data->call_id = PJSUA_INVALID_ID;
    pj_strdup_with_null(tdata->pool, &im_data->to, to);
    pj_strdup_with_null(tdata->pool, &im_data->body, content);
    im_data->user_data = user_data;


    /* Set default media type if none is specified */
    if (mime_type == NULL) {
	mime_type = &mime_text_plain;
    }

    /* Parse MIME type */
    pjsua_parse_media_type(tdata->pool, mime_type, &media_type);

    /* Add message body */
    tdata->msg->body = pjsip_msg_body_create( tdata->pool, &media_type.type,
					      &media_type.subtype, 
					      &im_data->body);
    if (tdata->msg->body == NULL) {
	pjsua_perror(THIS_FILE, "Unable to create msg body", PJ_ENOMEM);
	pjsip_tx_data_dec_ref(tdata);
	return PJ_ENOMEM;
    }

    /* Add additional headers etc. */
    pjsua_process_msg_data(tdata, msg_data);

    /* Add route set */
    pjsua_set_msg_route_set(tdata, &pjsua_var.acc[acc_id].route_set);

    /* Send request (statefully) */
    status = pjsip_endpt_send_request( pjsua_var.endpt, tdata, -1, 
				       im_data, &im_callback);
    if (status != PJ_SUCCESS) {
	pjsua_perror(THIS_FILE, "Unable to send request", status);
	return status;
    }

    return PJ_SUCCESS;
}


/*
 * Send typing indication outside dialog.
 */
PJ_DEF(pj_status_t) pjsua_im_typing( pjsua_acc_id acc_id, 
				     const pj_str_t *to, 
				     pj_bool_t is_typing,
				     const pjsua_msg_data *msg_data)
{
    const pj_str_t STR_CONTACT = { "Contact", 7 };
    pjsua_im_data *im_data;
    pjsip_tx_data *tdata;
    pj_str_t contact;
    pj_status_t status;

    /* Create request. */
    status = pjsip_endpt_create_request( pjsua_var.endpt, &pjsip_message_method,
					 to, &pjsua_var.acc[acc_id].cfg.id,
					 to, NULL, NULL, -1, NULL, &tdata);
    if (status != PJ_SUCCESS) {
	pjsua_perror(THIS_FILE, "Unable to create request", status);
	return status;
    }


    /* If account is locked to specific transport, then set transport to
     * the request.
     */
    if (pjsua_var.acc[acc_id].cfg.transport_id != PJSUA_INVALID_ID) {
	pjsip_tpselector tp_sel;

	pjsua_init_tpselector(pjsua_var.acc[acc_id].cfg.transport_id, &tp_sel);
	pjsip_tx_data_set_transport(tdata, &tp_sel);
    }

    /* Add accept header. */
    pjsip_msg_add_hdr( tdata->msg, 
		       (pjsip_hdr*)pjsua_im_create_accept(tdata->pool));


    /* Add contact. */
    status = pjsua_acc_create_uac_contact(tdata->pool, &contact, acc_id, to);
    if (status != PJ_SUCCESS) {
	pjsua_perror(THIS_FILE, "Unable to generate Contact header", status);
	pjsip_tx_data_dec_ref(tdata);
	return status;
    }

    pjsip_msg_add_hdr( tdata->msg, (pjsip_hdr*)
	pjsip_generic_string_hdr_create(tdata->pool, 
					&STR_CONTACT, &contact));


    /* Create "application/im-iscomposing+xml" msg body. */
    tdata->msg->body = pjsip_iscomposing_create_body( tdata->pool, is_typing,
						      NULL, NULL, -1);

    /* Add additional headers etc. */
    pjsua_process_msg_data(tdata, msg_data);

    /* Add route set */
    pjsua_set_msg_route_set(tdata, &pjsua_var.acc[acc_id].route_set);

    /* Create data to reauthenticate */
    im_data = PJ_POOL_ZALLOC_T(tdata->pool, pjsua_im_data);
    im_data->acc_id = acc_id;

    /* Send request (statefully) */
    status = pjsip_endpt_send_request( pjsua_var.endpt, tdata, -1, 
				       im_data, &typing_callback);
    if (status != PJ_SUCCESS) {
	pjsua_perror(THIS_FILE, "Unable to send request", status);
	return status;
    }

    return PJ_SUCCESS;
}


/*
 * Init pjsua IM module.
 */
pj_status_t pjsua_im_init(void)
{
    const pj_str_t msg_tag = { "MESSAGE", 7 };
    const pj_str_t STR_MIME_TEXT_PLAIN = { "text/plain", 10 };
    const pj_str_t STR_MIME_APP_ISCOMPOSING = 
		    { "application/im-iscomposing+xml", 30 };
    pj_status_t status;

    /* Register module */
    status = pjsip_endpt_register_module(pjsua_var.endpt, &mod_pjsua_im);
    if (status != PJ_SUCCESS)
	return status;

    /* Register support for MESSAGE method. */
    pjsip_endpt_add_capability( pjsua_var.endpt, &mod_pjsua_im, PJSIP_H_ALLOW,
				NULL, 1, &msg_tag);

    /* Register support for "application/im-iscomposing+xml" content */
    pjsip_endpt_add_capability( pjsua_var.endpt, &mod_pjsua_im, PJSIP_H_ACCEPT,
				NULL, 1, &STR_MIME_APP_ISCOMPOSING);

    /* Register support for "text/plain" content */
    pjsip_endpt_add_capability( pjsua_var.endpt, &mod_pjsua_im, PJSIP_H_ACCEPT,
				NULL, 1, &STR_MIME_TEXT_PLAIN);

    return PJ_SUCCESS;
}

