[sr-dev] git:master: parser/sdp: added partial parsing of a=candidate attributes

Juha Heinanen jh at tutpro.com
Mon Dec 31 14:57:56 CET 2012


Module: sip-router
Branch: master
Commit: b7a1ea4c8a88eea873bf6b4bfac5e1f477a19073
URL:    http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=b7a1ea4c8a88eea873bf6b4bfac5e1f477a19073

Author: Juha Heinanen <jh at tutpro.com>
Committer: Juha Heinanen <jh at tutpro.com>
Date:   Mon Dec 31 15:51:53 2012 +0200

parser/sdp: added partial parsing of a=candidate attributes

---

 parser/sdp/sdp.c             |   20 +++++++++++-
 parser/sdp/sdp.h             |   14 ++++++++
 parser/sdp/sdp_helpr_funcs.c |   74 ++++++++++++++++++++++++++++++++++++++++++
 parser/sdp/sdp_helpr_funcs.h |    2 +
 4 files changed, 109 insertions(+), 1 deletions(-)

diff --git a/parser/sdp/sdp.c b/parser/sdp/sdp.c
index df017be..ab04d60 100644
--- a/parser/sdp/sdp.c
+++ b/parser/sdp/sdp.c
@@ -161,6 +161,7 @@ static inline sdp_payload_attr_t *add_sdp_payload(sdp_stream_cell_t* _stream, in
 	return payload_attr;
 }
 
+
 /**
  * Initialize fast access pointers.
  */
@@ -550,6 +551,8 @@ static int parse_sdp_session(str *sdp_body, int session_num, str *cnt_disp, sdp_
 				a1p = fmtp_string.s + fmtp_string.len;
 				payload_attr = (sdp_payload_attr_t*)get_sdp_payload4payload(stream, &rtp_payload);
 				set_sdp_payload_fmtp(payload_attr, &fmtp_string);
+			} else if (parse_payload_attr && extract_candidate(&tmpstr1, stream) == 0) {
+			        a1p += 2;
 			} else if (extract_accept_types(&tmpstr1, &stream->accept_types) == 0) {
 				a1p = stream->accept_types.s + stream->accept_types.len;
 			} else if (extract_accept_wrapped_types(&tmpstr1, &stream->accept_wrapped_types) == 0) {
@@ -777,6 +780,7 @@ void free_sdp(sdp_info_t** _sdp)
 	sdp_session_cell_t *session, *l_session;
 	sdp_stream_cell_t *stream, *l_stream;
 	sdp_payload_attr_t *payload, *l_payload;
+        sdp_ice_attr_t *tmp;
 
 	LM_DBG("_sdp = %p\n", _sdp);
 	if (sdp == NULL) return;
@@ -799,6 +803,11 @@ void free_sdp(sdp_info_t** _sdp)
 			if (l_stream->p_payload_attr) {
 				pkg_free(l_stream->p_payload_attr);
 			}
+			while (l_stream->ice_attr) {
+			    tmp = l_stream->ice_attr->next;
+			    pkg_free(l_stream->ice_attr);
+			    l_stream->ice_attr->next = tmp;
+			}
 			pkg_free(l_stream);
 		}
 		pkg_free(l_session);
@@ -811,8 +820,9 @@ void free_sdp(sdp_info_t** _sdp)
 void print_sdp_stream(sdp_stream_cell_t *stream, int log_level)
 {
 	sdp_payload_attr_t *payload;
+        sdp_ice_attr_t *ice_attr;
 
-	LOG(log_level , "....stream[%d]:%p=>%p {%p} '%.*s' '%.*s:%.*s:%.*s' '%.*s' [%d] '%.*s' '%.*s:%.*s' (%d)=>%p '%.*s' '%.*s' '%.*s' '%.*s' '%.*s' '%.*s'\n",
+	LOG(log_level , "....stream[%d]:%p=>%p {%p} '%.*s' '%.*s:%.*s:%.*s' '%.*s' [%d] '%.*s' '%.*s:%.*s' (%d)=>%p (%d)=>%p '%.*s' '%.*s' '%.*s' '%.*s' '%.*s' '%.*s'\n",
 		stream->stream_num, stream, stream->next,
 		stream->p_payload_attr,
 		stream->media.len, stream->media.s,
@@ -822,6 +832,7 @@ void print_sdp_stream(sdp_stream_cell_t *stream, int log_level)
 		stream->payloads.len, stream->payloads.s,
 		stream->bw_type.len, stream->bw_type.s, stream->bw_width.len, stream->bw_width.s,
 		stream->payloads_num, stream->payload_attr,
+		stream->ice_attrs_num, stream->ice_attr,
 		stream->sendrecv_mode.len, stream->sendrecv_mode.s,
 		stream->ptime.len, stream->ptime.s,
 		stream->path.len, stream->path.s,
@@ -840,6 +851,13 @@ void print_sdp_stream(sdp_stream_cell_t *stream, int log_level)
 			payload->fmtp_string.len, payload->fmtp_string.s);
 		payload=payload->next;
 	}
+	ice_attr = stream->ice_attr;
+	while (ice_attr) {
+	    LOG(log_level, "......'%.*s' %u\n",
+		ice_attr->foundation.len, ice_attr->foundation.s,
+		ice_attr->component_id);
+	    ice_attr = ice_attr->next;
+	}
 }
 
 void print_sdp_session(sdp_session_cell_t *session, int log_level)
diff --git a/parser/sdp/sdp.h b/parser/sdp/sdp.h
index 464c835..dc0dede 100644
--- a/parser/sdp/sdp.h
+++ b/parser/sdp/sdp.h
@@ -42,6 +42,17 @@ typedef struct sdp_payload_attr {
 	str fmtp_string;
 } sdp_payload_attr_t;
 
+typedef struct sdp_ice_attr {
+    struct sdp_ice_attr *next;
+    str foundation;
+    unsigned int component_id;
+    str transport;
+    str connection_addr;
+    str port;
+    str candidate_type;
+    int candidateType; /* ICE_HOST/ICE_SRFLX/ICE_PRFLX/ICE_RELAY/ICE_UNKNOWN */
+} sdp_ice_attr_t;
+
 typedef struct sdp_stream_cell {
 	struct sdp_stream_cell *next;
 	/* c=<network type> <address type> <connection address> */
@@ -72,6 +83,9 @@ typedef struct sdp_stream_cell {
 	str accept_wrapped_types;                 /**< RFC4975: accept-wrapped-types attribute */
 	struct sdp_payload_attr **p_payload_attr; /**< fast access pointers to payloads */
 	struct sdp_payload_attr *payload_attr;
+        int ice_attrs_num;                        /**< number of ICE attrs inside a stream */
+        /* add fast access pointers to ice attributes if you need them */
+        sdp_ice_attr_t *ice_attr;
 } sdp_stream_cell_t;
 
 typedef struct sdp_session_cell {
diff --git a/parser/sdp/sdp_helpr_funcs.c b/parser/sdp/sdp_helpr_funcs.c
index 9fed80b..0b04530 100644
--- a/parser/sdp/sdp_helpr_funcs.c
+++ b/parser/sdp/sdp_helpr_funcs.c
@@ -27,10 +27,12 @@
  */
 
 
+#include <stdlib.h>
 #include "../../ut.h"
 #include "../msg_parser.h"
 #include "../parser_f.h"
 #include "../parse_hname2.h"
+#include "sdp.h"
 
 
 static struct {
@@ -309,6 +311,78 @@ int extract_fmtp( str *body, str *fmtp_payload, str *fmtp_string )
 	return 0;
 }
 
+
+/**
+ * Allocate a new ice attribute
+ */
+static inline sdp_ice_attr_t *add_sdp_ice(sdp_stream_cell_t* _stream)
+{
+	sdp_ice_attr_t *ice_attr;
+	int len;
+
+	len = sizeof(sdp_ice_attr_t);
+	ice_attr = (sdp_ice_attr_t *)pkg_malloc(len);
+	if (ice_attr == NULL) {
+	    LM_ERR("No memory left\n");
+	    return NULL;
+	}
+	memset( ice_attr, 0, len);
+
+	/* Insert the new ice attribute */
+	ice_attr->next = _stream->ice_attr;
+	_stream->ice_attr = ice_attr;
+	_stream->ice_attrs_num++;
+
+	return ice_attr;
+}
+
+
+int extract_candidate(str *body, sdp_stream_cell_t *stream)
+{
+    char *space, *start;
+    int len, fl;
+    sdp_ice_attr_t *ice_attr;
+
+    if (strncasecmp(body->s, "a=candidate:", 12) != 0) {
+	/*LM_DBG("We are not pointing to an a=candidate: attribute =>`%.*s'\n", body->len, body->s); */
+	return -1;
+    }
+    
+    start = body->s + 12;
+    len = body->len - 12;
+
+    space = memchr(start, 32, len);
+    if ((space == NULL) || (space - start + 3 > len) || !isdigit(*(space + 1)))  {
+	LM_ERR("no component in `a=candidate'\n");
+	return -1;
+    }
+
+    fl = space - start;
+    
+    start = space + 1;
+    len = len - (space - start + 1);
+    space = memchr(start, 32, len);
+    if (space == NULL) {
+	LM_ERR("no component in `a=candidate'\n");
+	return -1;
+    }
+
+    ice_attr = add_sdp_ice(stream);
+    if (ice_attr == NULL) {
+	LM_ERR("failed to add ice attribute\n");
+	return -1;
+    }
+
+    /* currently only foundation and component-id are parsed */
+    /* if needed, parse more */
+    ice_attr->foundation.s = body->s + 12;
+    ice_attr->foundation.len = fl;
+    ice_attr->component_id = strtol(start, (char **)NULL, 10);
+
+    return 0;
+}
+
+
 /* generic method for attribute extraction
  * field must has format "a=attrname:" */
 int extract_field(str *body, str *value, str field)
diff --git a/parser/sdp/sdp_helpr_funcs.h b/parser/sdp/sdp_helpr_funcs.h
index 2456cee..cc46375 100644
--- a/parser/sdp/sdp_helpr_funcs.h
+++ b/parser/sdp/sdp_helpr_funcs.h
@@ -33,6 +33,7 @@
 
 #include "../../str.h"
 #include "../msg_parser.h"
+#include "sdp.h"
 
 /**
  * Detect the mixed part delimiter.
@@ -50,6 +51,7 @@ int extract_sendrecv_mode(str *body, str *sendrecv_mode, int *is_on_hold);
 int extract_mediaip(str *body, str *mediaip, int *pf, char *line);
 int extract_media_attr(str *body, str *mediamedia, str *mediaport, str *mediatransport, str *mediapayload, int *is_rtp);
 int extract_bwidth(str *body, str *bwtype, str *bwwitdth);
+int extract_candidate(str *body, sdp_stream_cell_t *stream);
 
 /* RFC3605 attributes */
 int extract_rtcp(str *body, str *rtcp);




More information about the sr-dev mailing list