summaryrefslogtreecommitdiff
path: root/pjsip
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2008-05-13 09:38:50 +0000
committerBenny Prijono <bennylp@teluu.com>2008-05-13 09:38:50 +0000
commit7056ed05759237312c35a6a42706959f94a63b76 (patch)
treebec209d46706e5add0486a4ca1c7841dfedf40f9 /pjsip
parent0ee6805a9757610af92f19a88d142276586a41ef (diff)
Ticket #533: Support for parsing Retry-After SIP header
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@1954 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjsip')
-rw-r--r--pjsip/include/pjsip/sip_msg.h10
-rw-r--r--pjsip/src/pjsip/sip_msg.c87
-rw-r--r--pjsip/src/pjsip/sip_parser.c21
3 files changed, 115 insertions, 3 deletions
diff --git a/pjsip/include/pjsip/sip_msg.h b/pjsip/include/pjsip/sip_msg.h
index 8a202c4b..97bf1a73 100644
--- a/pjsip/include/pjsip/sip_msg.h
+++ b/pjsip/include/pjsip/sip_msg.h
@@ -1649,7 +1649,15 @@ PJ_DECL(pjsip_require_hdr*) pjsip_require_hdr_init( pj_pool_t *pool,
/**
* Retry-After header.
*/
-typedef pjsip_generic_int_hdr pjsip_retry_after_hdr;
+typedef struct pjsip_retry_after_hdr
+{
+ /** Standard header field. */
+ PJSIP_DECL_HDR_MEMBER(struct pjsip_retry_after_hdr);
+ pj_int32_t ivalue; /**< Retry-After value */
+ pjsip_param param; /**< Optional parameters */
+ pj_str_t comment; /**< Optional comments. */
+} pjsip_retry_after_hdr;
+
/**
* Create new Retry-After header instance.
diff --git a/pjsip/src/pjsip/sip_msg.c b/pjsip/src/pjsip/sip_msg.c
index f635a3da..20cece07 100644
--- a/pjsip/src/pjsip/sip_msg.c
+++ b/pjsip/src/pjsip/sip_msg.c
@@ -1644,6 +1644,22 @@ PJ_DEF(pjsip_require_hdr*) pjsip_require_hdr_create(pj_pool_t *pool)
/*
* Retry-After header.
*/
+static int pjsip_retry_after_hdr_print(pjsip_retry_after_hdr *r,
+ char *buf, pj_size_t size );
+static pjsip_retry_after_hdr* pjsip_retry_after_hdr_clone(pj_pool_t *pool,
+ const pjsip_retry_after_hdr *r);
+static pjsip_retry_after_hdr*
+pjsip_retry_after_hdr_shallow_clone(pj_pool_t *pool,
+ const pjsip_retry_after_hdr *r );
+
+static pjsip_hdr_vptr retry_after_hdr_vptr =
+{
+ (pjsip_hdr_clone_fptr) &pjsip_retry_after_hdr_clone,
+ (pjsip_hdr_clone_fptr) &pjsip_retry_after_hdr_shallow_clone,
+ (pjsip_hdr_print_fptr) &pjsip_retry_after_hdr_print,
+};
+
+
PJ_DEF(pjsip_retry_after_hdr*) pjsip_retry_after_hdr_init( pj_pool_t *pool,
void *mem,
int value )
@@ -1652,8 +1668,9 @@ PJ_DEF(pjsip_retry_after_hdr*) pjsip_retry_after_hdr_init( pj_pool_t *pool,
PJ_UNUSED_ARG(pool);
- init_hdr(hdr, PJSIP_H_RETRY_AFTER, &generic_int_hdr_vptr);
+ init_hdr(hdr, PJSIP_H_RETRY_AFTER, &retry_after_hdr_vptr);
hdr->ivalue = value;
+ pj_list_init(&hdr->param);
return hdr;
}
@@ -1665,6 +1682,74 @@ PJ_DEF(pjsip_retry_after_hdr*) pjsip_retry_after_hdr_create(pj_pool_t *pool,
}
+static int pjsip_retry_after_hdr_print(pjsip_retry_after_hdr *hdr,
+ char *buf, pj_size_t size)
+{
+ char *p = buf;
+ char *endbuf = buf + size;
+ const pj_str_t *hname = &hdr->name;
+ const pjsip_parser_const_t *pc = pjsip_parser_const();
+ int printed;
+
+ if ((pj_ssize_t)size < hdr->name.slen + 2+11)
+ return -1;
+
+ pj_memcpy(p, hdr->name.ptr, hdr->name.slen);
+ p += hname->slen;
+ *p++ = ':';
+ *p++ = ' ';
+
+ p += pj_utoa(hdr->ivalue, p);
+
+ if (hdr->comment.slen) {
+ pj_bool_t enclosed;
+
+ if (endbuf-p < hdr->comment.slen + 3)
+ return -1;
+
+ enclosed = (*hdr->comment.ptr == '(');
+ if (!enclosed)
+ *p++ = '(';
+ pj_memcpy(p, hdr->comment.ptr, hdr->comment.slen);
+ p += hdr->comment.slen;
+ if (!enclosed)
+ *p++ = ')';
+
+ if (!pj_list_empty(&hdr->param))
+ *p++ = ' ';
+ }
+
+ printed = pjsip_param_print_on(&hdr->param, p, endbuf-p,
+ &pc->pjsip_TOKEN_SPEC,
+ &pc->pjsip_TOKEN_SPEC,
+ ';');
+ if (printed < 0)
+ return printed;
+
+ p += printed;
+
+ return p - buf;
+}
+
+static pjsip_retry_after_hdr* pjsip_retry_after_hdr_clone(pj_pool_t *pool,
+ const pjsip_retry_after_hdr *rhs)
+{
+ pjsip_retry_after_hdr *hdr = pjsip_retry_after_hdr_create(pool, rhs->ivalue);
+ pj_strdup(pool, &hdr->comment, &rhs->comment);
+ pjsip_param_clone(pool, &hdr->param, &rhs->param);
+ return hdr;
+}
+
+static pjsip_retry_after_hdr*
+pjsip_retry_after_hdr_shallow_clone(pj_pool_t *pool,
+ const pjsip_retry_after_hdr *rhs)
+{
+ pjsip_retry_after_hdr *hdr = PJ_POOL_ALLOC_T(pool, pjsip_retry_after_hdr);
+ pj_memcpy(hdr, rhs, sizeof(*hdr));
+ pjsip_param_shallow_clone(pool, &hdr->param, &rhs->param);
+ return hdr;
+}
+
///////////////////////////////////////////////////////////////////////////////
/*
* Supported header.
diff --git a/pjsip/src/pjsip/sip_parser.c b/pjsip/src/pjsip/sip_parser.c
index 88edf707..839e3bed 100644
--- a/pjsip/src/pjsip/sip_parser.c
+++ b/pjsip/src/pjsip/sip_parser.c
@@ -1825,8 +1825,27 @@ static pjsip_hdr* parse_hdr_require( pjsip_parse_ctx *ctx )
static pjsip_hdr* parse_hdr_retry_after(pjsip_parse_ctx *ctx)
{
pjsip_retry_after_hdr *hdr;
+ pj_scanner *scanner = ctx->scanner;
+ pj_str_t tmp;
+
hdr = pjsip_retry_after_hdr_create(ctx->pool, 0);
- parse_generic_int_hdr(hdr, ctx->scanner);
+
+ pj_scan_get(scanner, &pconst.pjsip_DIGIT_SPEC, &tmp);
+ hdr->ivalue = pj_strtoul(&tmp);
+
+ while (!pj_scan_is_eof(scanner) && *scanner->curptr!='\r' &&
+ *scanner->curptr=='\n')
+ {
+ if (*scanner->curptr=='(') {
+ pj_scan_get_quote(scanner, '(', ')', &hdr->comment);
+ } else if (*scanner->curptr==';') {
+ pjsip_param *prm = PJ_POOL_ALLOC_T(ctx->pool, pjsip_param);
+ int_parse_param(scanner, ctx->pool, &prm->name, &prm->value, 0);
+ pj_list_push_back(&hdr->param, prm);
+ }
+ }
+
+ parse_hdr_end(scanner);
return (pjsip_hdr*)hdr;
}