فهرست منبع

modules/sdpops: added sdp_transport(pv) function

Juha Heinanen 11 سال پیش
والد
کامیت
5ce86dca57
3فایلهای تغییر یافته به همراه164 افزوده شده و 42 حذف شده
  1. 59 42
      modules/sdpops/README
  2. 22 0
      modules/sdpops/doc/sdpops_admin.xml
  3. 83 0
      modules/sdpops/sdpops_mod.c

+ 59 - 42
modules/sdpops/README

@@ -35,13 +35,14 @@ Daniel-Constantin Mierla
               4.7. sdp_remove_media(type)
               4.7. sdp_remove_media(type)
               4.8. sdp_with_transport(type)
               4.8. sdp_with_transport(type)
               4.9. sdp_with_transport_like(string)
               4.9. sdp_with_transport_like(string)
-              4.10. sdp_remove_transport(type)
-              4.11. sdp_with_codecs_by_id(list)
-              4.12. sdp_with_codecs_by_name(list)
-              4.13. sdp_print(level)
-              4.14. sdp_get(avpvar)
-              4.15. sdp_content()
-              4.16. sdp_get_line_startswith(avpvar, string)
+              4.10. sdp_transport(pv)
+              4.11. sdp_remove_transport(type)
+              4.12. sdp_with_codecs_by_id(list)
+              4.13. sdp_with_codecs_by_name(list)
+              4.14. sdp_print(level)
+              4.15. sdp_get(avpvar)
+              4.16. sdp_content()
+              4.17. sdp_get_line_startswith(avpvar, string)
 
 
    List of Examples
    List of Examples
 
 
@@ -54,13 +55,14 @@ Daniel-Constantin Mierla
    1.7. sdp_remove_media usage
    1.7. sdp_remove_media usage
    1.8. sdp_with_transport usage
    1.8. sdp_with_transport usage
    1.9. sdp_with_transport_like usage
    1.9. sdp_with_transport_like usage
-   1.10. sdp_remove_transport usage
-   1.11. sdp_with_codecs_by_id usage
-   1.12. sdp_with_codecs_by_name usage
-   1.13. sdp_print usage
-   1.14. sdp_get usage
-   1.15. sdp_content usage
-   1.16. sdp_get_line_startswith usage
+   1.10. sdp_transport usage
+   1.11. sdp_remove_transport usage
+   1.12. sdp_with_codecs_by_id usage
+   1.13. sdp_with_codecs_by_name usage
+   1.14. sdp_print usage
+   1.15. sdp_get usage
+   1.16. sdp_content usage
+   1.17. sdp_get_line_startswith usage
 
 
 Chapter 1. Admin Guide
 Chapter 1. Admin Guide
 
 
@@ -84,13 +86,14 @@ Chapter 1. Admin Guide
         4.7. sdp_remove_media(type)
         4.7. sdp_remove_media(type)
         4.8. sdp_with_transport(type)
         4.8. sdp_with_transport(type)
         4.9. sdp_with_transport_like(string)
         4.9. sdp_with_transport_like(string)
-        4.10. sdp_remove_transport(type)
-        4.11. sdp_with_codecs_by_id(list)
-        4.12. sdp_with_codecs_by_name(list)
-        4.13. sdp_print(level)
-        4.14. sdp_get(avpvar)
-        4.15. sdp_content()
-        4.16. sdp_get_line_startswith(avpvar, string)
+        4.10. sdp_transport(pv)
+        4.11. sdp_remove_transport(type)
+        4.12. sdp_with_codecs_by_id(list)
+        4.13. sdp_with_codecs_by_name(list)
+        4.14. sdp_print(level)
+        4.15. sdp_get(avpvar)
+        4.16. sdp_content()
+        4.17. sdp_get_line_startswith(avpvar, string)
 
 
 1. Overview
 1. Overview
 
 
@@ -133,13 +136,14 @@ Chapter 1. Admin Guide
    4.7. sdp_remove_media(type)
    4.7. sdp_remove_media(type)
    4.8. sdp_with_transport(type)
    4.8. sdp_with_transport(type)
    4.9. sdp_with_transport_like(string)
    4.9. sdp_with_transport_like(string)
-   4.10. sdp_remove_transport(type)
-   4.11. sdp_with_codecs_by_id(list)
-   4.12. sdp_with_codecs_by_name(list)
-   4.13. sdp_print(level)
-   4.14. sdp_get(avpvar)
-   4.15. sdp_content()
-   4.16. sdp_get_line_startswith(avpvar, string)
+   4.10. sdp_transport(pv)
+   4.11. sdp_remove_transport(type)
+   4.12. sdp_with_codecs_by_id(list)
+   4.13. sdp_with_codecs_by_name(list)
+   4.14. sdp_print(level)
+   4.15. sdp_get(avpvar)
+   4.16. sdp_content()
+   4.17. sdp_get_line_startswith(avpvar, string)
 
 
 4.1.  sdp_remove_codecs_by_id(list)
 4.1.  sdp_remove_codecs_by_id(list)
 
 
@@ -299,20 +303,33 @@ if(sdp_with_transport_like("SAVPF"))
 }
 }
 ...
 ...
 
 
-4.10.  sdp_remove_transport(type)
+4.10.  sdp_transport(pv)
+
+   Assigns common media transport (if any) of 'm' lines to pv argument.
+   Returns 1 if common media transport was found, -2 if there was no
+   common media transport, and -1 in case of error.
+
+   This function can be used from ANY_ROUTE.
+
+   Example 1.10. sdp_transport usage
+...
+sdp_transport("$avp(caller_rtp_transport)");
+...
+
+4.11.  sdp_remove_transport(type)
 
 
    Remove the streams that match on 'm=media port type ...' line. The
    Remove the streams that match on 'm=media port type ...' line. The
    parameter can be static string or variable holding the transport type.
    parameter can be static string or variable holding the transport type.
 
 
    This function can be used from ANY_ROUTE.
    This function can be used from ANY_ROUTE.
 
 
-   Example 1.10. sdp_remove_transport usage
+   Example 1.11. sdp_remove_transport usage
 ...
 ...
 # remove stream with transport RTP/AVP
 # remove stream with transport RTP/AVP
 sdp_remove_transport("RTP/AVP");
 sdp_remove_transport("RTP/AVP");
 ...
 ...
 
 
-4.11.  sdp_with_codecs_by_id(list)
+4.12.  sdp_with_codecs_by_id(list)
 
 
    Returns true if any of the codecs provided in the parameter 'list' from
    Returns true if any of the codecs provided in the parameter 'list' from
    all media streams is found in SDP payload. The parameter 'list' must be
    all media streams is found in SDP payload. The parameter 'list' must be
@@ -321,7 +338,7 @@ sdp_remove_transport("RTP/AVP");
 
 
    This function can be used from ANY_ROUTE.
    This function can be used from ANY_ROUTE.
 
 
-   Example 1.11. sdp_with_codecs_by_id usage
+   Example 1.12. sdp_with_codecs_by_id usage
 ...
 ...
 # test for PCMU
 # test for PCMU
 if(sdp_with_codecs_by_id("0")) { ... }
 if(sdp_with_codecs_by_id("0")) { ... }
@@ -329,7 +346,7 @@ if(sdp_with_codecs_by_id("0")) { ... }
 if(sdp_with_codecs_by_id("0,8,3")) { ... }
 if(sdp_with_codecs_by_id("0,8,3")) { ... }
 ...
 ...
 
 
-4.12.  sdp_with_codecs_by_name(list)
+4.13.  sdp_with_codecs_by_name(list)
 
 
    Returns true if any of the codecs provided in the parameter 'list' from
    Returns true if any of the codecs provided in the parameter 'list' from
    all media streams is found in SDP payload. The parameter 'list' must be
    all media streams is found in SDP payload. The parameter 'list' must be
@@ -338,7 +355,7 @@ if(sdp_with_codecs_by_id("0,8,3")) { ... }
 
 
    This function can be used from ANY_ROUTE.
    This function can be used from ANY_ROUTE.
 
 
-   Example 1.12. sdp_with_codecs_by_name usage
+   Example 1.13. sdp_with_codecs_by_name usage
 ...
 ...
 # test for PCMU
 # test for PCMU
 if(sdp_with_codecs_by_name("PCMU")) { ... }
 if(sdp_with_codecs_by_name("PCMU")) { ... }
@@ -346,45 +363,45 @@ if(sdp_with_codecs_by_name("PCMU")) { ... }
 if(sdp_with_codecs_by_name("PCMU,PCMA,GSM")) { ... }
 if(sdp_with_codecs_by_name("PCMU,PCMA,GSM")) { ... }
 ...
 ...
 
 
-4.13.  sdp_print(level)
+4.14.  sdp_print(level)
 
 
    Print the SDP internal structure to log 'level'. The parameter can be
    Print the SDP internal structure to log 'level'. The parameter can be
    static integer or variable holding the integer value of the log level.
    static integer or variable holding the integer value of the log level.
 
 
    This function can be used from ANY_ROUTE.
    This function can be used from ANY_ROUTE.
 
 
-   Example 1.13. sdp_print usage
+   Example 1.14. sdp_print usage
 ...
 ...
 # print the SDP
 # print the SDP
 sdp_print("1");
 sdp_print("1");
 ...
 ...
 
 
-4.14.  sdp_get(avpvar)
+4.15.  sdp_get(avpvar)
 
 
    Store the SDP part of message body in an AVP. Return 1 if SDP is found,
    Store the SDP part of message body in an AVP. Return 1 if SDP is found,
    -1 on error and -2 if there is no SDP part in the message body.
    -1 on error and -2 if there is no SDP part in the message body.
 
 
    This function can be used from ANY_ROUTE.
    This function can be used from ANY_ROUTE.
 
 
-   Example 1.14. sdp_get usage
+   Example 1.15. sdp_get usage
 ...
 ...
 sdp_get("$avp(sdp)");
 sdp_get("$avp(sdp)");
 ...
 ...
 
 
-4.15.  sdp_content()
+4.16.  sdp_content()
 
 
    Return true if the SIP message has SDP body or a SDP part in body.
    Return true if the SIP message has SDP body or a SDP part in body.
 
 
    This function can be used from ANY_ROUTE.
    This function can be used from ANY_ROUTE.
 
 
-   Example 1.15. sdp_content usage
+   Example 1.16. sdp_content usage
 ...
 ...
 if(sdp_content()) {
 if(sdp_content()) {
     ...
     ...
 }
 }
 ...
 ...
 
 
-4.16.  sdp_get_line_startswith(avpvar, string)
+4.17.  sdp_get_line_startswith(avpvar, string)
 
 
    Store the search part of SDP body message with line beginning with
    Store the search part of SDP body message with line beginning with
    'string' in an AVP. Return 1 if 'string' is found in SDP, -1 on error
    'string' in an AVP. Return 1 if 'string' is found in SDP, -1 on error
@@ -392,7 +409,7 @@ if(sdp_content()) {
 
 
    This function can be used from ANY_ROUTE.
    This function can be used from ANY_ROUTE.
 
 
-   Example 1.16. sdp_get_line_startswith usage
+   Example 1.17. sdp_get_line_startswith usage
 ...
 ...
 if(sdp_get_line_startswith("$avp(mline)", "m=")) {
 if(sdp_get_line_startswith("$avp(mline)", "m=")) {
         xlog("m-line: $avp(mline)\n");
         xlog("m-line: $avp(mline)\n");

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

@@ -298,6 +298,28 @@ if(sdp_with_transport_like("SAVPF"))
     # the session has a SAVPF stream, e.g., RTP/SAVPF or UDP/TLS/RTP/SAVPF
     # the session has a SAVPF stream, e.g., RTP/SAVPF or UDP/TLS/RTP/SAVPF
 }
 }
 ...
 ...
+</programlisting>
+	    </example>
+	</section>
+	<section>
+	    <title>
+		<function moreinfo="none">sdp_transport(pv)</function>
+	    </title>
+	    <para>
+		Assigns common media transport (if any) of 'm' lines to pv
+		argument.  Returns 1 if common media transport was found, -2
+		if there was no common media transport, and -1 in case of
+		error.
+	    </para>
+	    <para>
+		  This function can be used from ANY_ROUTE.
+	    </para>
+	    <example>
+	      <title><function>sdp_transport</function> usage</title>
+	      <programlisting format="linespecific">
+...
+sdp_transport("$avp(caller_rtp_transport)");
+...
 </programlisting>
 </programlisting>
 	    </example>
 	    </example>
 	</section>
 	</section>

+ 83 - 0
modules/sdpops/sdpops_mod.c

@@ -50,6 +50,7 @@ static int w_sdp_keep_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_with_media(sip_msg_t* msg, char* media, char *bar);
 static int w_sdp_with_transport(sip_msg_t* msg, char* transport, char *bar);
 static int w_sdp_with_transport(sip_msg_t* msg, char* transport, char *bar);
 static int w_sdp_with_transport_like(sip_msg_t* msg, char* transport, char *bar);
 static int w_sdp_with_transport_like(sip_msg_t* msg, char* transport, char *bar);
+static int w_sdp_transport(sip_msg_t* msg, char *bar);
 static int w_sdp_with_codecs_by_id(sip_msg_t* msg, char* codec, char *bar);
 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_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_remove_media(sip_msg_t* msg, char* media, char *bar);
@@ -87,6 +88,8 @@ static cmd_export_t cmds[] = {
 		1, fixup_spve_null,  0, ANY_ROUTE},
 		1, fixup_spve_null,  0, ANY_ROUTE},
 	{"sdp_remove_transport",       (cmd_function)w_sdp_remove_transport,
 	{"sdp_remove_transport",       (cmd_function)w_sdp_remove_transport,
 		1, fixup_spve_null,  0, ANY_ROUTE},
 		1, fixup_spve_null,  0, ANY_ROUTE},
+	{"sdp_transport",              (cmd_function)w_sdp_transport,
+		1, 0,  0, ANY_ROUTE},
 	{"sdp_with_codecs_by_id",      (cmd_function)w_sdp_with_codecs_by_id,
 	{"sdp_with_codecs_by_id",      (cmd_function)w_sdp_with_codecs_by_id,
 		1, fixup_spve_null,  0, ANY_ROUTE},
 		1, fixup_spve_null,  0, ANY_ROUTE},
 	{"sdp_with_codecs_by_name",    (cmd_function)w_sdp_with_codecs_by_name,
 	{"sdp_with_codecs_by_name",    (cmd_function)w_sdp_with_codecs_by_name,
@@ -955,6 +958,86 @@ static int sdp_with_transport(sip_msg_t *msg, str *transport, int like)
 	return 0;
 	return 0;
 }
 }
 
 
+/** 
+ * @brief assigns common media transport (if any) of 'm' lines to pv argument
+ * @return -1 - error; 0 - not found; 1 - found
+ */
+static int w_sdp_transport(sip_msg_t* msg, char *avp)
+{
+    int_str avp_val;
+    int_str avp_name;
+    static unsigned short avp_type = 0;
+    str s;
+    pv_spec_t *avp_spec = NULL;
+    int sdp_session_num;
+    int sdp_stream_num;
+    sdp_session_cell_t* sdp_session;
+    sdp_stream_cell_t* sdp_stream;
+    str *transport;
+
+    s.s = avp; s.len = strlen(s.s);
+    if (pv_locate_name(&s) != s.len) {
+	LM_ERR("invalid avp parameter %s\n", avp);
+	return -1;
+    }
+    if (((avp_spec = pv_cache_get(&s)) == NULL)
+	|| avp_spec->type!=PVT_AVP) {
+	LM_ERR("malformed or non AVP %s\n", avp);
+	return -1;
+    }
+    if (pv_get_avp_name(0, &avp_spec->pvp, &avp_name, &avp_type) != 0) {
+	LM_ERR("invalid AVP definition %s\n", avp);
+	return -1;
+    }
+
+    if(parse_sdp(msg) < 0) {
+	LM_ERR("unable to parse sdp\n");
+	return -1;
+    }
+
+    sdp_session_num = 0;
+    transport = (str *)NULL;
+
+    for (;;) {
+	sdp_session = get_sdp_session(msg, sdp_session_num);
+	if (!sdp_session) break;
+	sdp_stream_num = 0;
+	for (;;) {
+	    sdp_stream = get_sdp_stream(msg, sdp_session_num,
+					sdp_stream_num);
+	    if (!sdp_stream) break;
+	    LM_DBG("stream %d of %d - transport [%.*s]\n",
+		   sdp_stream_num, sdp_session_num,
+		   sdp_stream->transport.len, sdp_stream->transport.s);
+	    if (transport) {
+		if (transport->len != sdp_stream->transport.len
+		    || strncasecmp(sdp_stream->transport.s, transport->s,
+				   transport->len) != 0) {
+		    LM_DBG("no common transport\n");
+		    return -2;
+		}
+	    } else {
+		transport = &sdp_stream->transport;
+	    }
+	    sdp_stream_num++;
+	}
+	sdp_session_num++;
+    }
+    if (transport) {
+	avp_val.s.s = transport->s;
+	avp_val.s.len = transport->len;
+	LM_DBG("found common transport '%.*s'\n",
+	       transport->len, transport->s);
+	if (add_avp(AVP_VAL_STR | avp_type, avp_name, avp_val) != 0) {
+	    LM_ERR("failed to add transport avp");
+	    return -1;
+	}
+    }
+
+    return 1;
+}
+
+
 /**
 /**
  *
  *
  */
  */