فهرست منبع

sdpops: added sdpops_remove_codecs_by_name(list)

- it takes as parameter a csv list with codec names
- works for now with codecs that have ID assigned by IANA, the rest will
  follow
Daniel-Constantin Mierla 14 سال پیش
والد
کامیت
e8ae4acb4e
5فایلهای تغییر یافته به همراه240 افزوده شده و 42 حذف شده
  1. 34 13
      modules/sdpops/README
  2. 26 0
      modules/sdpops/doc/sdpops_admin.xml
  3. 123 1
      modules/sdpops/sdpops_data.c
  4. 4 1
      modules/sdpops/sdpops_data.h
  5. 53 27
      modules/sdpops/sdpops_mod.c

+ 34 - 13
modules/sdpops/README

@@ -10,7 +10,7 @@ Daniel-Constantin Mierla
 
    <[email protected]>
 
-   Copyright © 2011 asipto.com
+   Copyright © 2011 asipto.com
      __________________________________________________________________
 
    Table of Contents
@@ -27,14 +27,16 @@ Daniel-Constantin Mierla
         4. Exported Functions
 
               4.1. sdp_remove_codecs_by_id(list)
-              4.2. sdp_with_media(type)
-              4.3. sdp_print(level)
+              4.2. sdp_remove_codecs_by_name(list)
+              4.3. sdp_with_media(type)
+              4.4. sdp_print(level)
 
    List of Examples
 
    1.1. sdp_remove_codecs_by_id usage
-   1.2. sdp_with_media usage
-   1.3. sdp_print usage
+   1.2. sdp_remove_codecs_by_name usage
+   1.3. sdp_with_media usage
+   1.4. sdp_print usage
 
 Chapter 1. Admin Guide
 
@@ -50,8 +52,9 @@ Chapter 1. Admin Guide
    4. Exported Functions
 
         4.1. sdp_remove_codecs_by_id(list)
-        4.2. sdp_with_media(type)
-        4.3. sdp_print(level)
+        4.2. sdp_remove_codecs_by_name(list)
+        4.3. sdp_with_media(type)
+        4.4. sdp_print(level)
 
 1. Overview
 
@@ -86,8 +89,9 @@ Chapter 1. Admin Guide
 4. Exported Functions
 
    4.1. sdp_remove_codecs_by_id(list)
-   4.2. sdp_with_media(type)
-   4.3. sdp_print(level)
+   4.2. sdp_remove_codecs_by_name(list)
+   4.3. sdp_with_media(type)
+   4.4. sdp_print(level)
 
 4.1.  sdp_remove_codecs_by_id(list)
 
@@ -106,7 +110,24 @@ sdp_remove_codecs_by_id("0");
 sdp_remove_codecs_by_id("0,8,3");
 ...
 
-4.2.  sdp_with_media(type)
+4.2.  sdp_remove_codecs_by_name(list)
+
+   Remove the codecs provided in the parameter 'list' from all media
+   streams found in SDP payload. The parameter 'list' must be one or a
+   comma separated list of codec names. The parameter can be a static
+   string or a variable holding the list of codec names.
+
+   This function can be used from ANY_ROUTE.
+
+   Example 1.2. sdp_remove_codecs_by_name usage
+...
+# remove PCMU
+sdp_remove_codecs_by_name("PCMU");
+# remove PCMU, PCMA and GSM
+sdp_remove_codecs_by_name("PCMU,PCMA,GSM");
+...
+
+4.3.  sdp_with_media(type)
 
    Return true of the SDP has 'media=type ...' line. Useful to check the
    content of the RTP sessions, such as 'audio' or 'video'. The parameter
@@ -114,7 +135,7 @@ sdp_remove_codecs_by_id("0,8,3");
 
    This function can be used from ANY_ROUTE.
 
-   Example 1.2. sdp_with_media usage
+   Example 1.3. sdp_with_media usage
 ...
 # check for video stream
 if(sdp_with_media("video"))
@@ -123,14 +144,14 @@ if(sdp_with_media("video"))
 }
 ...
 
-4.3.  sdp_print(level)
+4.4.  sdp_print(level)
 
    Print the SDP internal structure to log 'level'. The parameter can be
    static integer or variable holding the integer value of the log level.
 
    This function can be used from ANY_ROUTE.
 
-   Example 1.3. sdp_print usage
+   Example 1.4. sdp_print usage
 ...
 # print the SDP
 sdp_print("1");

+ 26 - 0
modules/sdpops/doc/sdpops_admin.xml

@@ -90,6 +90,32 @@ sdp_remove_codecs_by_id("0");
 # remove PCMU, PCMA and GSM
 sdp_remove_codecs_by_id("0,8,3");
 ...
+</programlisting>
+	    </example>
+	</section>
+	<section>
+	    <title>
+		<function moreinfo="none">sdp_remove_codecs_by_name(list)</function>
+	    </title>
+	    <para>
+			Remove the codecs provided in the parameter 'list' from all
+			media streams found in SDP payload. The parameter 'list' must
+			be one or a comma separated list of codec names. The
+			parameter can be a static string or a variable holding the
+			list of codec names.
+	    </para>
+		<para>
+			This function can be used from ANY_ROUTE.
+	    </para>
+		<example>
+		<title><function>sdp_remove_codecs_by_name</function> usage</title>
+		<programlisting format="linespecific">
+...
+# remove PCMU
+sdp_remove_codecs_by_name("PCMU");
+# remove PCMU, PCMA and GSM
+sdp_remove_codecs_by_name("PCMU,PCMA,GSM");
+...
 </programlisting>
 	    </example>
 	</section>

+ 123 - 1
modules/sdpops/sdpops_data.c

@@ -27,6 +27,7 @@
 #include <stdio.h>
 
 #include "../../dprint.h"
+#include "../../trim.h"
 #include "sdpops_data.h"
 
 #if 0
@@ -92,7 +93,128 @@ Registration Procedures: Standards Action Process or expert approval
 
 #endif
 
-int sdpops_get_id_by_name(str *name, str *id)
+typedef struct _codecsmap {
+	str name;
+	str ids;
+} codecsmap_t;
+
+codecsmap_t sdpops_codecsmap_table[] = {
+	{ {"PCMU",  4},  {"0",         1} },
+	{ {"GSM",   3},  {"3",         1} },
+	{ {"G723",  4},  {"4",         1} },
+	{ {"DVI4",  4},  {"5,6,16,17", 9} },
+	{ {"LPC",   3},  {"7",         1} },
+	{ {"PCMA",  4},  {"8",         1} },
+	{ {"G722",  4},  {"9",         1} },
+	{ {"L16",   3},  {"10,11",     5} },
+	{ {"QCELP", 5},  {"12",        2} },
+	{ {"CN",    2},  {"13",        5} },
+	{ {"MPA",   3},  {"14",        2} },
+	{ {"G728",  4},  {"15",        2} },
+	{ {"G729",  4},  {"18",        2} },
+	{ {0, 0}, {0, 0} }
+};
+
+/**
+ * set the string with the IDs mapped to codec name
+ * - return 0 if found, -1 if not found
+ */
+int sdpops_get_ids_by_name(str *name, str *ids)
+{
+	int i;
+	for(i=0; sdpops_codecsmap_table[i].name.s!=0; i++)
+	{
+		if(name->len==sdpops_codecsmap_table[i].name.len
+				&& strncasecmp(sdpops_codecsmap_table[i].name.s, name->s,
+					name->len)==0)
+		{
+			*ids = sdpops_codecsmap_table[i].ids;
+			return 0;
+		}
+	}
+	ids->s = NULL;
+	ids->len = 0;
+	return -1;
+}
+
+/**
+ * build the csv list of ids from csv list of names
+ */
+int sdpops_build_ids_list(str *names, str *ids)
+{
+#define SDPOPS_MAX_LIST_SIZE	64
+	static char _local_idslist[SDPOPS_MAX_LIST_SIZE];
+	str tmp;
+	str codec;
+	str cids;
+	char *p;
+
+	tmp = *names;
+	ids->len = 0;
+	ids->s   = 0;
+	p = _local_idslist;
+	while(str_find_token(&tmp, &codec, ',')==0
+		&& codec.len>0)
+	{
+		tmp.len -= (int)(&codec.s[codec.len]-codec.s);
+		tmp.s = codec.s + codec.len;
+
+		if( sdpops_get_ids_by_name(&codec, &cids)==0) {
+			LM_DBG("codecs list [%.*s] - at name [%.*s] with ids [%.*s]\n",
+				names->len, names->s,
+				codec.len, codec.s,
+				cids.len,  cids.s);
+			if(ids->len + cids.len>=SDPOPS_MAX_LIST_SIZE)
+			{
+				LM_ERR("the list with codecs ids is too big\n");
+				ids->len = 0;
+				ids->s = 0;
+				return -1;
+			}
+			strncpy(p, cids.s, cids.len);
+			p += cids.len;
+			*p = ',';
+			p++;
+			ids->len += cids.len + 1;
+		}
+	}
+	if(ids->len>0)
+	{
+		p--;
+		ids->len--;
+		*p = '\0';
+		ids->s = _local_idslist;
+		LM_DBG("codecs list [%.*s] - ids list [%.*s]\n",
+				names->len, names->s,
+				ids->len, ids->s);
+		return 0;
+	}
+	return -1;
+}
+
+
+/**
+ *
+ */
+int str_find_token(str *text, str *result, char delim)
 {
+	int i;
+	if(text==NULL || result==NULL)
+		return -1;
+	if(text->s[0] == delim)
+	{
+		 text->s += 1;
+		 text->len -= 1;
+	}
+	trim_leading(text);
+	result->s = text->s;
+	result->len = 0;
+	for (i=0; i<text->len; i++)
+	{
+		if(result->s[i]==delim || result->s[i]=='\0'
+				|| result->s[i]=='\r' || result->s[i]=='\n')
+			return 0;
+		result->len++;
+	}
 	return 0;
 }

+ 4 - 1
modules/sdpops/sdpops_data.h

@@ -26,5 +26,8 @@
 #define _SDPOPS_DATA_H_
 #include "../../str.h"
 
-int sdpops_get_id_by_name(str *name, str *id);
+int sdpops_get_ids_by_name(str *name, str *ids);
+int str_find_token(str *text, str *result, char delim);
+int sdpops_build_ids_list(str *names, str *ids);
+
 #endif

+ 53 - 27
modules/sdpops/sdpops_mod.c

@@ -30,14 +30,16 @@
 #include "../../dprint.h"
 #include "../../mod_fix.h"
 #include "../../pvar.h"
-#include "../../trim.h"
 #include "../../parser/sdp/sdp.h"
+#include "../../trim.h"
 #include "../../data_lump.h"
 
+#include "sdpops_data.h"
 
 MODULE_VERSION
 
 static int w_sdp_remove_codecs_by_id(sip_msg_t* msg, char* codecs, char *bar);
+static int w_sdp_remove_codecs_by_name(sip_msg_t* msg, char* codecs, char *bar);
 static int w_sdp_with_media(sip_msg_t* msg, char* media, char *bar);
 static int w_sdp_print(sip_msg_t* msg, char* level, char *bar);
 
@@ -46,6 +48,8 @@ static int mod_init(void);
 static cmd_export_t cmds[] = {
 	{"sdp_remove_codecs_by_id",    (cmd_function)w_sdp_remove_codecs_by_id,
 		1, fixup_spve_null,  0, ANY_ROUTE},
+	{"sdp_remove_codecs_by_name",  (cmd_function)w_sdp_remove_codecs_by_name,
+		1, fixup_spve_null,  0, ANY_ROUTE},
 	{"sdp_with_media",             (cmd_function)w_sdp_with_media,
 		1, fixup_spve_null,  0, ANY_ROUTE},
 	{"sdp_print",                  (cmd_function)w_sdp_print,
@@ -93,32 +97,6 @@ static int mod_init(void)
 }
 
 
-/**
- *
- */
-int str_find_token(str *text, str *result, char delim)
-{
-	int i;
-	if(text==NULL || result==NULL)
-		return -1;
-	if(text->s[0] == delim)
-	{
-		 text->s += 1;
-		 text->len -= 1;
-	}
-	trim_leading(text);
-	result->s = text->s;
-	result->len = 0;
-	for (i=0; i<text->len; i++)
-	{
-		if(result->s[i]==delim || result->s[i]=='\0'
-				|| result->s[i]=='\r' || result->s[i]=='\n')
-			return 0;
-		result->len++;
-	}
-	return 0;
-}
-
 /**
  *
  */
@@ -316,6 +294,54 @@ static int w_sdp_remove_codecs_by_id(sip_msg_t* msg, char* codecs, char* bar)
 	return 1;
 }
 
+/**
+ *
+ */
+int sdp_remove_codecs_by_name(sip_msg_t* msg, str* codecs)
+{
+	str idslist;
+
+	if(parse_sdp(msg) < 0) {
+		LM_ERR("Unable to parse sdp\n");
+		return -1;
+	}
+
+	LM_ERR("attempting to remove codecs from sdp: [%.*s]\n",
+			codecs->len, codecs->s);
+
+	if(sdpops_build_ids_list(codecs, &idslist)<0)
+		return -1;
+
+	if(sdp_remove_codecs_by_id(msg, &idslist)<0)
+		return -1;
+
+	return 0;
+
+}
+/**
+ *
+ */
+static int w_sdp_remove_codecs_by_name(sip_msg_t* msg, char* codecs, char* bar)
+{
+	str lcodecs = {0, 0};
+
+	if(codecs==0)
+	{
+		LM_ERR("invalid parameters\n");
+		return -1;
+	}
+
+	if(fixup_get_svalue(msg, (gparam_p)codecs, &lcodecs)!=0)
+	{
+		LM_ERR("unable to get the list of codecs\n");
+		return -1;
+	}
+
+	if(sdp_remove_codecs_by_name(msg, &lcodecs)<0)
+		return -1;
+	return 1;
+}
+
 
 /** 
  * @brief check 'media' matches the value of any 'm=value ...' lines