Closed #1146: support for multipart message bodies in incoming NOTIFY requests

git-svn-id: https://svn.pjsip.org/repos/pjproject/trunk@3337 74dad513-b988-da41-8d7b-12977e46ad98
This commit is contained in:
Benny Prijono 2010-10-12 11:35:55 +00:00
parent 3e310ec787
commit f279c0937d
4 changed files with 217 additions and 6 deletions

View File

@ -328,11 +328,31 @@ PJ_DECL(pj_status_t) pjsip_pres_create_xpidf(pj_pool_t *pool,
* @param status The presence status to be initialized.
*
* @return PJ_SUCCESS on success.
*
* @see pjsip_pres_parse_pidf2()
*/
PJ_DECL(pj_status_t) pjsip_pres_parse_pidf(pjsip_rx_data *rdata,
pj_pool_t *pool,
pjsip_pres_status *status);
/**
* This is a utility function to parse PIDF body into PJSIP presence status.
*
* @param body Text body, with one extra space at the end to place
* NULL character temporarily during parsing.
* @param body_len Length of the body, not including the NULL termination
* character.
* @param pool Pool to allocate memory to copy the strings into
* the presence status structure.
* @param status The presence status to be initialized.
*
* @return PJ_SUCCESS on success.
*
* @see pjsip_pres_parse_pidf()
*/
PJ_DECL(pj_status_t) pjsip_pres_parse_pidf2(char *body, unsigned body_len,
pj_pool_t *pool,
pjsip_pres_status *status);
/**
@ -344,12 +364,34 @@ PJ_DECL(pj_status_t) pjsip_pres_parse_pidf(pjsip_rx_data *rdata,
* @param status The presence status to be initialized.
*
* @return PJ_SUCCESS on success.
*
* @see pjsip_pres_parse_xpidf2()
*/
PJ_DECL(pj_status_t) pjsip_pres_parse_xpidf(pjsip_rx_data *rdata,
pj_pool_t *pool,
pjsip_pres_status *status);
/**
* This is a utility function to parse X-PIDF body into PJSIP presence status.
*
* @param body Text body, with one extra space at the end to place
* NULL character temporarily during parsing.
* @param body_len Length of the body, not including the NULL termination
* character.
* @param pool Pool to allocate memory to copy the strings into
* the presence status structure.
* @param status The presence status to be initialized.
*
* @return PJ_SUCCESS on success.
*
* @see pjsip_pres_parse_xpidf()
*/
PJ_DECL(pj_status_t) pjsip_pres_parse_xpidf2(char *body, unsigned body_len,
pj_pool_t *pool,
pjsip_pres_status *status);
/**
* @}

View File

@ -21,6 +21,7 @@
#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>
@ -682,6 +683,7 @@ static pj_status_t pres_process_rx_notify( pjsip_pres *pres,
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;
@ -707,7 +709,36 @@ static pj_status_t pres_process_rx_notify( pjsip_pres *pres,
}
/* 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)
{

View File

@ -198,13 +198,20 @@ PJ_DEF(pj_status_t) pjsip_pres_create_xpidf( pj_pool_t *pool,
PJ_DEF(pj_status_t) pjsip_pres_parse_pidf( pjsip_rx_data *rdata,
pj_pool_t *pool,
pjsip_pres_status *pres_status)
{
return pjsip_pres_parse_pidf2((char*)rdata->msg_info.msg->body->data,
rdata->msg_info.msg->body->len,
pool, pres_status);
}
PJ_DEF(pj_status_t) pjsip_pres_parse_pidf2(char *body, unsigned body_len,
pj_pool_t *pool,
pjsip_pres_status *pres_status)
{
pjpidf_pres *pidf;
pjpidf_tuple *pidf_tuple;
pidf = pjpidf_parse(rdata->tp_info.pool,
(char*)rdata->msg_info.msg->body->data,
rdata->msg_info.msg->body->len);
pidf = pjpidf_parse(pool, body, body_len);
if (pidf == NULL)
return PJSIP_SIMPLE_EBADPIDF;
@ -250,12 +257,19 @@ PJ_DEF(pj_status_t) pjsip_pres_parse_pidf( pjsip_rx_data *rdata,
PJ_DEF(pj_status_t) pjsip_pres_parse_xpidf(pjsip_rx_data *rdata,
pj_pool_t *pool,
pjsip_pres_status *pres_status)
{
return pjsip_pres_parse_xpidf2((char*)rdata->msg_info.msg->body->data,
rdata->msg_info.msg->body->len,
pool, pres_status);
}
PJ_DEF(pj_status_t) pjsip_pres_parse_xpidf2(char *body, unsigned body_len,
pj_pool_t *pool,
pjsip_pres_status *pres_status)
{
pjxpidf_pres *xpidf;
xpidf = pjxpidf_parse(rdata->tp_info.pool,
(char*)rdata->msg_info.msg->body->data,
rdata->msg_info.msg->body->len);
xpidf = pjxpidf_parse(pool, body, body_len);
if (xpidf == NULL)
return PJSIP_SIMPLE_EBADXPIDF;

View File

@ -0,0 +1,124 @@
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE scenario SYSTEM "sipp.dtd">
<!-- 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 -->
<!-- -->
<!-- Late NOTIFY scenario: -->
<!-- - UAC sends SUBSCRIBE, we reply with 200 -->
<!-- - we send NOTIFY, expect 200 -->
<!-- - UAC sends SUBSCRIBE, we ignore -->
<!-- - we send NOTIFY -->
<!-- See http://trac.pjsip.org/repos/ticket/911 -->
<!-- -->
<scenario name="SUBSCRIBE tests">
<!-- Establish subscription -->
<recv request="SUBSCRIBE" crlf="true">
<action>
<ereg regexp=".*" search_in="hdr" header="From" assign_to="3"/>
<ereg regexp="sip:(.*)>" search_in="hdr" header="Contact" assign_to="4,5"/>
<assign assign_to="4" variable="5" />
</action>
</recv>
<send>
<![CDATA[
SIP/2.0 200 OK
[last_Via:]
[last_From:]
[last_To:];tag=[call_number]
[last_Call-ID:]
[last_CSeq:]
Contact: <sip:sipp@[local_ip]:[local_port]>
Content-Length: 0
Expires: 60
]]>
</send>
<send retrans="500">
<![CDATA[
NOTIFY sip:[$5] SIP/2.0
Via: SIP/2.0/[transport] [local_ip]:[local_port];rport;branch=z9hG4bKPj01
From: sipp <sip:sipp@[local_ip]>;tag=[call_number]
To[$3]
Call-ID: [call_id]
Cseq: 1 NOTIFY
Contact: sip:sipp@[local_ip]:[local_port]
Max-Forwards: 70
Event: presence
Subscription-State: active;expires=50
Content-Type: multipart/mixed;boundary=abcd
--abcd
Content-Type: text/plain
Hi there, please don't read this part.
--abcd
Content-Type: application/pidf+xml
<?xml version="1.0" encoding="UTF-8"?>
<presence xmlns="urn:ietf:params:xml:ns:pidf" xmlns:op="urn:oma:xml:prs:pidf:oma-pres" entity="sip:test@pjsip.org">
<tuple id="17415d5738f332a64a2f1d8cfb4ab0a5">
<status>
<basic>open</basic>
</status>
</tuple>
</presence>
--abcd--
]]>
</send>
<recv response="200">
</recv>
<!-- Subscription has been established at this point -->
<!-- *******
Wait for subscription refresh, reply with 481
-->
<recv request="SUBSCRIBE" crlf="true">
</recv>
<send>
<![CDATA[
SIP/2.0 481 You should resubscribe mow
[last_Via:]
[last_From:]
[last_To:];tag=[call_number]
[last_Call-ID:]
[last_CSeq:]
Contact: <sip:sipp@[local_ip]:[local_port]>
Content-Length: 0
]]>
</send>
<!-- definition of the response time repartition table (unit is ms) -->
<ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150, 200"/>
<!-- definition of the call length repartition table (unit is ms) -->
<CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000"/>
</scenario>