summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2010-08-01 09:24:58 +0000
committerBenny Prijono <bennylp@teluu.com>2010-08-01 09:24:58 +0000
commit42cd3a38756cc1baef47cd808273435518c56401 (patch)
tree2092f37d8bcc0bb0cb170a08a79a4d382fb92fc2
parent311528e2bc573606fb611175fbd7b981780664e2 (diff)
Re #1070 (support for multipart bodies): modified the param field of pjsip_media_type from a simple string to pjsip_param, to support a more complex use of this field
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@3241 74dad513-b988-da41-8d7b-12977e46ad98
-rw-r--r--pjsip/include/pjsip/sip_msg.h49
-rw-r--r--pjsip/src/pjsip-ua/sip_xfer.c11
-rw-r--r--pjsip/src/pjsip/sip_msg.c113
-rw-r--r--pjsip/src/test/msg_test.c30
4 files changed, 172 insertions, 31 deletions
diff --git a/pjsip/include/pjsip/sip_msg.h b/pjsip/include/pjsip/sip_msg.h
index 489fb025..4c112dc9 100644
--- a/pjsip/include/pjsip/sip_msg.h
+++ b/pjsip/include/pjsip/sip_msg.h
@@ -515,11 +515,45 @@ typedef struct pjsip_media_type
{
pj_str_t type; /**< Media type. */
pj_str_t subtype; /**< Media subtype. */
- pj_str_t param; /**< Media type parameters (concatenated). */
+ pjsip_param param; /**< Media type parameters */
} pjsip_media_type;
/**
+ * Initialize the media type with the specified type and subtype string.
+ *
+ * @param mt The media type.
+ * @param type Optionally specify the media type.
+ * @param subtype Optionally specify the media subtype.
+ */
+PJ_DECL(void) pjsip_media_type_init(pjsip_media_type *mt,
+ pj_str_t *type,
+ pj_str_t *subtype);
+
+/**
+ * Initialize the media type with the specified type and subtype string.
+ *
+ * @param mt The media type.
+ * @param type Optionally specify the media type.
+ * @param subtype Optionally specify the media subtype.
+ */
+PJ_DECL(void) pjsip_media_type_init2(pjsip_media_type *mt,
+ char *type,
+ char *subtype);
+
+/**
+ * Compare two media types.
+ *
+ * @param mt1 The first media type.
+ * @param mt2 The second media type.
+ *
+ * @return Zero if both media types are equal, -1 if mt1 < mt2,
+ * 1 if mt1 > mt2.
+ */
+PJ_DECL(int) pjsip_media_type_cmp(const pjsip_media_type *mt1,
+ const pjsip_media_type *mt2);
+
+/**
* Copy SIP media type to another.
*
* @param pool Pool to duplicate strings.
@@ -531,6 +565,19 @@ PJ_DECL(void) pjsip_media_type_cp(pj_pool_t *pool,
const pjsip_media_type *src);
/**
+ * Print media type to the specified buffer.
+ *
+ * @param buf Destination buffer.
+ * @param len Length of the buffer.
+ * @param mt The media type to be printed.
+ *
+ * @return The number of characters printed to the buffer, or -1
+ * if there's not enough space in the buffer.
+ */
+PJ_DECL(int) pjsip_media_type_print(char *buf, unsigned len,
+ const pjsip_media_type *mt);
+
+/**
* @}
*/
diff --git a/pjsip/src/pjsip-ua/sip_xfer.c b/pjsip/src/pjsip-ua/sip_xfer.c
index eb932655..47608d74 100644
--- a/pjsip/src/pjsip-ua/sip_xfer.c
+++ b/pjsip/src/pjsip-ua/sip_xfer.c
@@ -374,6 +374,7 @@ PJ_DEF(pj_status_t) pjsip_xfer_notify( pjsip_evsub *sub,
{
pjsip_tx_data *tdata;
pjsip_xfer *xfer;
+ pjsip_param *param;
const pj_str_t reason = { "noresource", 10 };
char *body;
int bodylen;
@@ -422,14 +423,18 @@ PJ_DEF(pj_status_t) pjsip_xfer_notify( pjsip_evsub *sub,
/* Create SIP message body. */
msg_body = PJ_POOL_ZALLOC_T(tdata->pool, pjsip_msg_body);
- msg_body->content_type.type = STR_MESSAGE;
- msg_body->content_type.subtype = STR_SIPFRAG;
- msg_body->content_type.param = STR_SIPFRAG_VERSION;
+ pjsip_media_type_init(&msg_body->content_type, (pj_str_t*)&STR_MESSAGE,
+ (pj_str_t*)&STR_SIPFRAG);
msg_body->data = body;
msg_body->len = bodylen;
msg_body->print_body = &pjsip_print_text_body;
msg_body->clone_data = &pjsip_clone_text_data;
+ param = PJ_POOL_ALLOC_T(tdata->pool, pjsip_param);
+ param->name = pj_str("version");
+ param->value = pj_str("2.0");
+ pj_list_push_back(&msg_body->content_type.param, param);
+
/* Attach sipfrag body. */
tdata->msg->body = msg_body;
diff --git a/pjsip/src/pjsip/sip_msg.c b/pjsip/src/pjsip/sip_msg.c
index fe86362e..4c6b376c 100644
--- a/pjsip/src/pjsip/sip_msg.c
+++ b/pjsip/src/pjsip/sip_msg.c
@@ -22,6 +22,7 @@
#include <pjsip/print_util.h>
#include <pjsip/sip_errno.h>
#include <pj/ctype.h>
+#include <pj/guid.h>
#include <pj/string.h>
#include <pj/pool.h>
#include <pj/assert.h>
@@ -145,7 +146,8 @@ const pjsip_hdr_name_info_t pjsip_hdr_names[] =
pj_bool_t pjsip_use_compact_form = PJSIP_ENCODE_SHORT_HNAME;
static pj_str_t status_phrase[710];
-static int print_media_type(char *buf, const pjsip_media_type *media);
+static int print_media_type(char *buf, unsigned len,
+ const pjsip_media_type *media);
static int init_status_phrase()
{
@@ -489,14 +491,12 @@ PJ_DEF(pj_ssize_t) pjsip_msg_print( const pjsip_msg *msg,
}
/* Add Content-Type header. */
- if ( (end-p) < 24 + media->type.slen + media->subtype.slen +
- media->param.slen)
- {
+ if ( (end-p) < 24 + media->type.slen + media->subtype.slen) {
return -1;
}
pj_memcpy(p, ctype_hdr.ptr, ctype_hdr.slen);
p += ctype_hdr.slen;
- p += print_media_type(p, media);
+ p += print_media_type(p, end-p, media);
*p++ = '\r';
*p++ = '\n';
@@ -602,6 +602,65 @@ PJ_DEF(const pj_str_t*) pjsip_get_status_text(int code)
/*
* Media type
*/
+/*
+ * Init media type.
+ */
+PJ_DEF(void) pjsip_media_type_init( pjsip_media_type *mt,
+ pj_str_t *type,
+ pj_str_t *subtype)
+{
+ pj_bzero(mt, sizeof(*mt));
+ pj_list_init(&mt->param);
+ if (type)
+ mt->type = *type;
+ if (subtype)
+ mt->subtype = *subtype;
+}
+
+PJ_DEF(void) pjsip_media_type_init2( pjsip_media_type *mt,
+ char *type,
+ char *subtype)
+{
+ pj_str_t s_type, s_subtype;
+
+ if (type) {
+ s_type = pj_str(type);
+ } else {
+ s_type.ptr = NULL;
+ s_type.slen = 0;
+ }
+
+ if (subtype) {
+ s_subtype = pj_str(subtype);
+ } else {
+ s_subtype.ptr = NULL;
+ s_subtype.slen = 0;
+ }
+
+ pjsip_media_type_init(mt, &s_type, &s_subtype);
+}
+
+/*
+ * Compare two media types.
+ */
+PJ_DEF(int) pjsip_media_type_cmp( const pjsip_media_type *mt1,
+ const pjsip_media_type *mt2)
+{
+ int rc;
+
+ PJ_ASSERT_RETURN(mt1 && mt2, 1);
+
+ rc = pj_stricmp(&mt1->type, &mt2->type);
+ if (rc) return rc;
+
+ rc = pj_stricmp(&mt1->subtype, &mt2->subtype);
+ if (rc) return rc;
+
+ rc = pjsip_param_cmp(&mt1->param, &mt2->param, 0);
+
+ return rc;
+}
+
PJ_DEF(void) pjsip_media_type_cp( pj_pool_t *pool,
pjsip_media_type *dst,
const pjsip_media_type *src)
@@ -609,7 +668,7 @@ PJ_DEF(void) pjsip_media_type_cp( pj_pool_t *pool,
PJ_ASSERT_ON_FAIL(pool && dst && src, return);
pj_strdup(pool, &dst->type, &src->type);
pj_strdup(pool, &dst->subtype, &src->subtype);
- pj_strdup(pool, &dst->param, &src->param);
+ pjsip_param_clone(pool, &dst->param, &src->param);
}
///////////////////////////////////////////////////////////////////////////////
@@ -1263,6 +1322,7 @@ PJ_DEF(pjsip_ctype_hdr*) pjsip_ctype_hdr_init( pj_pool_t *pool,
pj_bzero(mem, sizeof(pjsip_ctype_hdr));
init_hdr(hdr, PJSIP_H_CONTENT_TYPE, &ctype_hdr_vptr);
+ pj_list_init(&hdr->media.param);
return hdr;
}
@@ -1273,9 +1333,12 @@ PJ_DEF(pjsip_ctype_hdr*) pjsip_ctype_hdr_create( pj_pool_t *pool )
return pjsip_ctype_hdr_init(pool, mem);
}
-static int print_media_type(char *buf, const pjsip_media_type *media)
+static int print_media_type(char *buf, unsigned len,
+ const pjsip_media_type *media)
{
char *p = buf;
+ pj_ssize_t printed;
+ const pjsip_parser_const_t *pc;
pj_memcpy(p, media->type.ptr, media->type.slen);
p += media->type.slen;
@@ -1283,14 +1346,25 @@ static int print_media_type(char *buf, const pjsip_media_type *media)
pj_memcpy(p, media->subtype.ptr, media->subtype.slen);
p += media->subtype.slen;
- if (media->param.slen) {
- pj_memcpy(p, media->param.ptr, media->param.slen);
- p += media->param.slen;
- }
+ pc = pjsip_parser_const();
+ printed = pjsip_param_print_on(&media->param, p, buf+len-p,
+ &pc->pjsip_TOKEN_SPEC,
+ &pc->pjsip_TOKEN_SPEC, ';');
+ if (printed < 0)
+ return -1;
+
+ p += printed;
return p-buf;
}
+
+PJ_DEF(int) pjsip_media_type_print(char *buf, unsigned len,
+ const pjsip_media_type *media)
+{
+ return print_media_type(buf, len, media);
+}
+
static int pjsip_ctype_hdr_print( pjsip_ctype_hdr *hdr,
char *buf, pj_size_t size)
{
@@ -1299,8 +1373,7 @@ static int pjsip_ctype_hdr_print( pjsip_ctype_hdr *hdr,
const pj_str_t *hname = pjsip_use_compact_form? &hdr->sname : &hdr->name;
if ((pj_ssize_t)size < hname->slen +
- hdr->media.type.slen + hdr->media.subtype.slen +
- hdr->media.param.slen + 8)
+ hdr->media.type.slen + hdr->media.subtype.slen + 8)
{
return -1;
}
@@ -1310,7 +1383,7 @@ static int pjsip_ctype_hdr_print( pjsip_ctype_hdr *hdr,
*p++ = ':';
*p++ = ' ';
- len = print_media_type(p, &hdr->media);
+ len = print_media_type(p, buf+size-p, &hdr->media);
p += len;
*p = '\0';
@@ -1323,7 +1396,7 @@ static pjsip_ctype_hdr* pjsip_ctype_hdr_clone( pj_pool_t *pool,
pjsip_ctype_hdr *hdr = pjsip_ctype_hdr_create(pool);
pj_strdup(pool, &hdr->media.type, &rhs->media.type);
pj_strdup(pool, &hdr->media.subtype, &rhs->media.subtype);
- pj_strdup(pool, &hdr->media.param, &rhs->media.param);
+ pjsip_param_clone(pool, &hdr->media.param, &rhs->media.param);
return hdr;
}
@@ -2078,12 +2151,8 @@ PJ_DEF(pj_status_t) pjsip_msg_body_copy( pj_pool_t *pool,
PJ_ASSERT_RETURN( src_body->clone_data!=NULL, PJ_EINVAL );
/* Duplicate content-type */
- pj_strdup(pool, &dst_body->content_type.type,
- &src_body->content_type.type);
- pj_strdup(pool, &dst_body->content_type.subtype,
- &src_body->content_type.subtype);
- pj_strdup(pool, &dst_body->content_type.param,
- &src_body->content_type.param);
+ pjsip_media_type_cp(pool, &dst_body->content_type,
+ &src_body->content_type);
/* Duplicate data. */
dst_body->data = (*src_body->clone_data)(pool, src_body->data,
@@ -2129,7 +2198,7 @@ PJ_DEF(pjsip_msg_body*) pjsip_msg_body_create( pj_pool_t *pool,
pj_strdup(pool, &body->content_type.type, type);
pj_strdup(pool, &body->content_type.subtype, subtype);
- body->content_type.param.slen = 0;
+ pj_list_init(&body->content_type.param);
body->data = pj_pool_alloc(pool, text->slen);
pj_memcpy(body->data, text->ptr, text->slen);
diff --git a/pjsip/src/test/msg_test.c b/pjsip/src/test/msg_test.c
index 3bb58f69..a7ce838b 100644
--- a/pjsip/src/test/msg_test.c
+++ b/pjsip/src/test/msg_test.c
@@ -481,6 +481,7 @@ static pjsip_msg *create_msg0(pj_pool_t *pool)
pjsip_routing_hdr *routing;
pjsip_via_hdr *via;
pjsip_generic_string_hdr *generic;
+ pjsip_param *prm;
pj_str_t str;
msg = pjsip_msg_create(pool, PJSIP_REQUEST_MSG);
@@ -569,7 +570,10 @@ static pjsip_msg *create_msg0(pj_pool_t *pool)
pjsip_msg_add_hdr(msg, (pjsip_hdr*)ctype);
pj_strdup2(pool, &ctype->media.type, "text");
pj_strdup2(pool, &ctype->media.subtype, "html");
- pj_strdup2(pool, &ctype->media.param, ";charset=ISO-8859-4");
+ prm = PJ_POOL_ALLOC_T(pool, pjsip_param);
+ prm->name = pj_str("charset");
+ prm->value = pj_str("ISO-8859-4");
+ pj_list_push_back(&ctype->media.param, prm);
/* "Route: <sip:bigbox3.site3.atlanta.com;lr>,\r\n" */
routing = pjsip_route_hdr_create(pool);
@@ -1590,6 +1594,7 @@ static int hdr_test_content_length(pjsip_hdr *h)
static int hdr_test_content_type(pjsip_hdr *h)
{
pjsip_ctype_hdr *hdr = (pjsip_ctype_hdr*)h;
+ const pjsip_param *prm;
if (h->type != PJSIP_H_CONTENT_TYPE)
return -1910;
@@ -1603,10 +1608,25 @@ static int hdr_test_content_type(pjsip_hdr *h)
/* Currently, if the media parameter contains escaped characters,
* pjsip will print the parameter unescaped.
*/
- PJ_TODO(FIX_PARAMETER_IN_MEDIA_TYPE);
-
- if (pj_strcmp2(&hdr->media.param, ";" GENERIC_PARAM_PARSED))
- return -1940;
+ prm = hdr->media.param.next;
+ if (prm == &hdr->media.param) return -1940;
+ if (pj_strcmp2(&prm->name, "p0")) return -1941;
+ if (pj_strcmp2(&prm->value, "a")) return -1942;
+
+ prm = prm->next;
+ if (prm == &hdr->media.param) return -1950;
+ if (pj_strcmp2(&prm->name, "p1")) { PJ_LOG(3,("", "%.*s", (int)prm->name.slen, prm->name.ptr)); return -1951; }
+ if (pj_strcmp2(&prm->value, "\"ab:;cd\"")) { PJ_LOG(3,("", "%.*s", (int)prm->value.slen, prm->value.ptr)); return -1952; }
+
+ prm = prm->next;
+ if (prm == &hdr->media.param) return -1960;
+ if (pj_strcmp2(&prm->name, "p2")) return -1961;
+ if (pj_strcmp2(&prm->value, "ab:cd")) return -1962;
+
+ prm = prm->next;
+ if (prm == &hdr->media.param) return -1970;
+ if (pj_strcmp2(&prm->name, "p3")) return -1971;
+ if (pj_strcmp2(&prm->value, "")) return -1972;
return 0;
}