Module: sip-router Branch: master Commit: b5aafda14737467590c6324cb1ba2cb88a2531a9 URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=b5aafda1...
Author: Peter Dunkley peter.dunkley@crocodile-rcs.com Committer: Peter Dunkley peter.dunkley@crocodile-rcs.com Date: Wed Feb 29 15:18:04 2012 +0000
modules/sdpops, parser/sdp: Added new exported function to give access to the raw SDP within the config file
- Feature added by Andrew Miller @ Crocodile RCS
---
modules/sdpops/sdpops_mod.c | 61 ++++++++++++++++++++++++++++++++++++++++++ parser/sdp/sdp.c | 14 ++++++--- parser/sdp/sdp.h | 1 + parser/sdp/sdp_helpr_funcs.c | 45 +++++++++++------------------- 4 files changed, 88 insertions(+), 33 deletions(-)
diff --git a/modules/sdpops/sdpops_mod.c b/modules/sdpops/sdpops_mod.c index c2d9e9f..402ca30 100644 --- a/modules/sdpops/sdpops_mod.c +++ b/modules/sdpops/sdpops_mod.c @@ -48,6 +48,7 @@ static int w_sdp_with_codecs_by_id(sip_msg_t* msg, char* codec, char *bar); static int w_sdp_with_codecs_by_name(sip_msg_t* msg, char* codec, char *bar); static int w_sdp_remove_media(sip_msg_t* msg, char* media, char *bar); static int w_sdp_print(sip_msg_t* msg, char* level, char *bar); +static int w_get_sdp(sip_msg_t* msg, char *bar);
static int mod_init(void);
@@ -74,6 +75,8 @@ static cmd_export_t cmds[] = { 1, fixup_spve_null, 0, ANY_ROUTE}, {"sdp_print", (cmd_function)w_sdp_print, 1, fixup_igp_null, 0, ANY_ROUTE}, + {"sdp_get", (cmd_function)w_get_sdp, + 1, 0, 0, ANY_ROUTE}, {"bind_sdpops", (cmd_function)bind_sdpops, 1, 0, 0, 0}, {0, 0, 0, 0, 0, 0} @@ -928,6 +931,64 @@ static int w_sdp_print(sip_msg_t* msg, char* level, char *bar) return 1; }
+ +/** + * + */ +static int w_get_sdp(sip_msg_t* msg, char *avp) +{ + sdp_info_t *sdp = NULL; + int_str avp_val; + int_str avp_name; + static unsigned short avp_type = 0; + str s; + pv_spec_t avp_spec; + int sdp_missing=1; + + s.s = avp; s.len = strlen(s.s); + if (pv_parse_spec(&s, &avp_spec)==0 + || avp_spec.type!=PVT_AVP) { + LM_ERR("malformed or non AVP %s AVP definition\n", avp); + return -1; + } + + if(pv_get_avp_name(0, &avp_spec.pvp, &avp_name, &avp_type)!=0) + { + LM_ERR("[%s]- invalid AVP definition\n", avp); + return -1; + } + + sdp_missing = parse_sdp(msg); + if(sdp_missing < 0) { + LM_ERR("Unable to parse sdp\n"); + return -1; + } + sdp = (sdp_info_t*)msg->body; + + if (sdp_missing) { + avp_val.s.s = NULL; + avp_val.s.len = 0; + LM_DBG("No SDP\n"); + } else { + avp_val.s.s = pkg_malloc(sdp->raw_sdp.len); + avp_val.s.len = sdp->raw_sdp.len; + if (avp_val.s.s == NULL) + { + LM_ERR("Failed to alloc memory for SDP"); + return -1; + } + memcpy(avp_val.s.s, sdp->raw_sdp.s, avp_val.s.len); + LM_DBG("Found SDP %.*s\n", sdp->raw_sdp.len, sdp->raw_sdp.s); + } + if (add_avp(AVP_VAL_STR | avp_type, avp_name, avp_val) != 0) + { + LM_ERR("Failed to add SDP avp"); + return -1; + } + + return 1; +} + /** * */ diff --git a/parser/sdp/sdp.c b/parser/sdp/sdp.c index 30de265..db9003a 100644 --- a/parser/sdp/sdp.c +++ b/parser/sdp/sdp.c @@ -591,7 +591,7 @@ static int parse_mixed_content(str *mixed_body, str delimiter, sdp_info_t* _sdp) char *d1p, *d2p; char *ret, *end; unsigned int mime; - str sdp_body, cnt_disp; + str cnt_disp; int session_num; struct hdr_field hf;
@@ -659,10 +659,11 @@ static int parse_mixed_content(str *mixed_body, str delimiter, sdp_info_t* _sdp) } /* end of while */ /* and now we need to parse the content */ if (start_parsing) { - sdp_body.s = rest; - sdp_body.len = d2p-rest; - /* LM_DBG("we need to check session %d: <%.*s>\n", session_num, sdp_body.len, sdp_body.s); */ - res = parse_sdp_session(&sdp_body, session_num, &cnt_disp, _sdp); + while (('\n' == *rest) || ('\r' == *rest) || ('\t' == *rest)|| (' ' == *rest)) rest++; /* Skip any whitespace */ + _sdp->raw_sdp.s = rest; + _sdp->raw_sdp.len = d2p-rest; + /* LM_DBG("we need to check session %d: <%.*s>\n", session_num, _sdp.raw_sdp.len, _sdp.raw_sdp.s); */ + res = parse_sdp_session(&_sdp->raw_sdp, session_num, &cnt_disp, _sdp); if (res != 0) { LM_DBG("free_sdp\n"); free_sdp((sdp_info_t**)(void*)&(_sdp)); @@ -721,6 +722,9 @@ int parse_sdp(struct sip_msg* _m) LM_DBG("free_sdp\n"); free_sdp((sdp_info_t**)(void*)&_m->body); } + /* The whole body is SDP */ + ((sdp_info_t*)_m->body)->raw_sdp.s = body.s; + ((sdp_info_t*)_m->body)->raw_sdp.len = body.len; return res; break; default: diff --git a/parser/sdp/sdp.h b/parser/sdp/sdp.h index a1fa8ce..3afc50e 100644 --- a/parser/sdp/sdp.h +++ b/parser/sdp/sdp.h @@ -104,6 +104,7 @@ typedef struct sdp_info { str text; /**< link to start of sdp and its length */ int sessions_num; /**< number of SDP sessions */ int streams_num; /**< total number of streams for all SDP sessions */ + str raw_sdp; /* Pointer to the Raw SDP (Might be embedded in multipart body) */ struct sdp_session_cell *sessions; } sdp_info_t;
diff --git a/parser/sdp/sdp_helpr_funcs.c b/parser/sdp/sdp_helpr_funcs.c index 13d1ca9..32e9eb4 100644 --- a/parser/sdp/sdp_helpr_funcs.c +++ b/parser/sdp/sdp_helpr_funcs.c @@ -652,35 +652,24 @@ char* get_sdp_hdr_field(char* buf, char* end, struct hdr_field* hdr) goto error; }
- /* if header-field well-known, parse it, find its end otherwise ; - * after leaving the hdr->type switch, tmp should be set to the - * next header field - */ - switch(hdr->type){ - case HDR_CONTENTTYPE_T: - case HDR_CONTENTDISPOSITION_T: - /* just skip over it */ - hdr->body.s=tmp; - /* find end of header */ - /* find lf */ - do{ - match=memchr(tmp, '\n', end-tmp); - if (match){ - match++; - }else { - LM_ERR("bad body for <%s>(%d)\n", hdr->name.s, hdr->type); - tmp=end; - goto error; - } - tmp=match; - }while( match<end &&( (*match==' ')||(*match=='\t') ) ); - tmp=match; - hdr->body.len=match-hdr->body.s; - break; - default: - LM_CRIT("unknown header type %d\n", hdr->type); + /* just skip over it */ + hdr->body.s=tmp; + /* find end of header */ + /* find lf */ + do{ + match=memchr(tmp, '\n', end-tmp); + if (match){ + match++; + }else { + LM_ERR("bad body for <%s>(%d)\n", hdr->name.s, hdr->type); + tmp=end; goto error; - } + } + tmp=match; + }while( match<end &&( (*match==' ')||(*match=='\t') ) ); + tmp=match; + hdr->body.len=match-hdr->body.s; + /* jku: if \r covered by current length, shrink it */ trim_r( hdr->body ); hdr->len=tmp-hdr->name.s;