Browse Source

siputils: added new function is_supported(option)

- Checks if given option is listed in any of the Supported: headers of
  the request.
Juha Heinanen 12 years ago
parent
commit
d992d3b223

+ 43 - 26
modules/siputils/README

@@ -40,7 +40,7 @@ Edited by
 
 
 Gabriel Vasile
 Gabriel Vasile
 
 
-   Copyright © 2008, 2005, 2003 1&1 Internet AG, FhG Fokus, Voice Sistem
+   Copyright (c) 2008, 2005, 2003 1&1 Internet AG, FhG Fokus, Voice Sistem
    SRL
    SRL
      __________________________________________________________________
      __________________________________________________________________
 
 
@@ -93,6 +93,7 @@ Gabriel Vasile
               4.23. is_request()
               4.23. is_request()
               4.24. is_reply()
               4.24. is_reply()
               4.25. is_gruu([uri])
               4.25. is_gruu([uri])
+              4.26. is_supported(option)
 
 
    List of Examples
    List of Examples
 
 
@@ -130,6 +131,7 @@ Gabriel Vasile
    1.32. is_request usage
    1.32. is_request usage
    1.33. is_reply usage
    1.33. is_reply usage
    1.34. is_gruu() usage
    1.34. is_gruu() usage
+   1.35. is_supported() usage
 
 
 Chapter 1. Admin Guide
 Chapter 1. Admin Guide
 
 
@@ -180,6 +182,7 @@ Chapter 1. Admin Guide
         4.23. is_request()
         4.23. is_request()
         4.24. is_reply()
         4.24. is_reply()
         4.25. is_gruu([uri])
         4.25. is_gruu([uri])
+        4.26. is_supported(option)
 
 
 1. Overview
 1. Overview
 
 
@@ -380,8 +383,9 @@ modparam("auth", "rpid_avp", "$avp(myrpid)")
    4.23. is_request()
    4.23. is_request()
    4.24. is_reply()
    4.24. is_reply()
    4.25. is_gruu([uri])
    4.25. is_gruu([uri])
+   4.26. is_supported(option)
 
 
-4.1. ring_insert_callid()
+4.1.  ring_insert_callid()
 
 
    Inserting the call-id in the internal list, which is checked when
    Inserting the call-id in the internal list, which is checked when
    further replies arrive. Any 183 reply that is received during the
    further replies arrive. Any 183 reply that is received during the
@@ -398,7 +402,7 @@ modparam("auth", "rpid_avp", "$avp(myrpid)")
 ring_insert_callid();
 ring_insert_callid();
 ...
 ...
 
 
-4.2. options_reply()
+4.2.  options_reply()
 
 
    This function checks if the request method is OPTIONS and if the
    This function checks if the request method is OPTIONS and if the
    request URI does not contain an username. If both is true the request
    request URI does not contain an username. If both is true the request
@@ -426,7 +430,7 @@ if (uri==myself) {
 }
 }
 ...
 ...
 
 
-4.3. is_user(username)
+4.3.  is_user(username)
 
 
    Check if the username in credentials matches the given username.
    Check if the username in credentials matches the given username.
 
 
@@ -442,7 +446,7 @@ if (is_user("john")) {
 };
 };
 ...
 ...
 
 
-4.4. has_totag()
+4.4.  has_totag()
 
 
    Check if To header field uri contains tag parameter.
    Check if To header field uri contains tag parameter.
 
 
@@ -455,7 +459,7 @@ if (has_totag()) {
 };
 };
 ...
 ...
 
 
-4.5. uri_param(param)
+4.5.  uri_param(param)
 
 
    Find if Request URI has a given parameter with no value
    Find if Request URI has a given parameter with no value
 
 
@@ -471,7 +475,7 @@ if (uri_param("param1")) {
 };
 };
 ...
 ...
 
 
-4.6. uri_param(param,value)
+4.6.  uri_param(param,value)
 
 
    Find if Request URI has a given parameter with matching value
    Find if Request URI has a given parameter with matching value
 
 
@@ -488,7 +492,7 @@ if (uri_param("param1","value1")) {
 };
 };
 ...
 ...
 
 
-4.7. add_uri_param(param)
+4.7.  add_uri_param(param)
 
 
    Add to RURI a parameter (name=value);
    Add to RURI a parameter (name=value);
 
 
@@ -502,7 +506,7 @@ if (uri_param("param1","value1")) {
 add_uri_param("nat=yes");
 add_uri_param("nat=yes");
 ...
 ...
 
 
-4.8. get_uri_param(name, var)
+4.8.  get_uri_param(name, var)
 
 
    Get the value of RURI parameter.
    Get the value of RURI parameter.
 
 
@@ -517,7 +521,7 @@ add_uri_param("nat=yes");
 get_uri_param("nat", "$var(nat)");
 get_uri_param("nat", "$var(nat)");
 ...
 ...
 
 
-4.9. tel2sip(uri, hostpart, result)
+4.9.  tel2sip(uri, hostpart, result)
 
 
    Converts URI in first param (pseudo variable or string) to SIP URI, if
    Converts URI in first param (pseudo variable or string) to SIP URI, if
    it is a tel URI. If conversion was done, writes resulting SIP URI to
    it is a tel URI. If conversion was done, writes resulting SIP URI to
@@ -549,7 +553,7 @@ tel2sip("$ru", $fd", "$ru");
 # $ru:  sip:+12345678;ext=200;[email protected];user=phone
 # $ru:  sip:+12345678;ext=200;[email protected];user=phone
 ...
 ...
 
 
-4.10. is_e164(pseudo-variable)
+4.10.  is_e164(pseudo-variable)
 
 
    Checks if string value of pseudo variable argument is an E164 number.
    Checks if string value of pseudo variable argument is an E164 number.
 
 
@@ -567,7 +571,7 @@ if (is_e164("$avp(i:705)") {
 };
 };
 ...
 ...
 
 
-4.11. is_uri_user_e164(pseudo-variable)
+4.11.  is_uri_user_e164(pseudo-variable)
 
 
    Checks if userpart of URI stored in pseudo variable is E164 number.
    Checks if userpart of URI stored in pseudo variable is E164 number.
 
 
@@ -584,7 +588,7 @@ if (is_uri_user_e164("$avp(i:705)") {
 };
 };
 ...
 ...
 
 
-4.12. encode_contact(encoding_prefix,hostpart)
+4.12.  encode_contact(encoding_prefix,hostpart)
 
 
    This function will encode uri-s inside Contact header in the following
    This function will encode uri-s inside Contact header in the following
    manner sip:username:password@ip:port;transport=protocol goes
    manner sip:username:password@ip:port;transport=protocol goes
@@ -611,7 +615,7 @@ if (is_uri_user_e164("$avp(i:705)") {
 if (src_ip == 10.0.0.0/8) encode_contact("natted_client","1.2.3.4");
 if (src_ip == 10.0.0.0/8) encode_contact("natted_client","1.2.3.4");
 ...
 ...
 
 
-4.13. decode_contact()
+4.13.  decode_contact()
 
 
    This function will decode the request URI. If the RURI is in the format
    This function will decode the request URI. If the RURI is in the format
    sip:encoding_prefix*username*ip*port*protocol@hostpart it will be
    sip:encoding_prefix*username*ip*port*protocol@hostpart it will be
@@ -629,7 +633,7 @@ if (src_ip == 10.0.0.0/8) encode_contact("natted_client","1.2.3.4");
 if (uri =~ "^sip:natted_client") { decode_contact(); }
 if (uri =~ "^sip:natted_client") { decode_contact(); }
 ...
 ...
 
 
-4.14. decode_contact_header()
+4.14.  decode_contact_header()
 
 
    This function will decode URIs inside Contact header. If the URI in the
    This function will decode URIs inside Contact header. If the URI in the
    format sip:encoding_prefix*username*ip*port*protocol@hostpart it will
    format sip:encoding_prefix*username*ip*port*protocol@hostpart it will
@@ -651,7 +655,7 @@ reply_route[2] {
 }
 }
 ...
 ...
 
 
-4.15. cmp_uri(str1, str2)
+4.15.  cmp_uri(str1, str2)
 
 
    The function returns true if the two parameters matches as SIP URI.
    The function returns true if the two parameters matches as SIP URI.
 
 
@@ -665,7 +669,7 @@ if(cmp_uri("$ru", "sip:[email protected]"))
 }
 }
 ...
 ...
 
 
-4.16. cmp_aor(str1, str2)
+4.16.  cmp_aor(str1, str2)
 
 
    The function returns true if the two parameters matches as AoR. The
    The function returns true if the two parameters matches as AoR. The
    parameters have to be SIP URIs.
    parameters have to be SIP URIs.
@@ -680,7 +684,7 @@ if(cmp_aor("[email protected]", "sip:kamailio@$fd"))
 }
 }
 ...
 ...
 
 
-4.17. is_rpid_user_e164()
+4.17.  is_rpid_user_e164()
 
 
    The function checks if the SIP URI received from the database or radius
    The function checks if the SIP URI received from the database or radius
    server and will potentially be used in Remote-Party-ID header field
    server and will potentially be used in Remote-Party-ID header field
@@ -697,7 +701,7 @@ if (is_rpid_user_e164()) {
 };
 };
 ...
 ...
 
 
-4.18. append_rpid_hf()
+4.18.  append_rpid_hf()
 
 
    Appends to the message a Remote-Party-ID header that contains header
    Appends to the message a Remote-Party-ID header that contains header
    'Remote-Party-ID: ' followed by the saved value of the SIP URI received
    'Remote-Party-ID: ' followed by the saved value of the SIP URI received
@@ -713,7 +717,7 @@ if (is_rpid_user_e164()) {
 append_rpid_hf();  # Append Remote-Party-ID header field
 append_rpid_hf();  # Append Remote-Party-ID header field
 ...
 ...
 
 
-4.19. append_rpid_hf(prefix, suffix)
+4.19.  append_rpid_hf(prefix, suffix)
 
 
    This function is the same as Section 4.18, " append_rpid_hf()". The
    This function is the same as Section 4.18, " append_rpid_hf()". The
    only difference is that it accepts two parameters--prefix and suffix to
    only difference is that it accepts two parameters--prefix and suffix to
@@ -738,7 +742,7 @@ append_rpid_hf();  # Append Remote-Party-ID header field
 append_rpid_hf("", ";party=calling;id-type=subscriber;screen=yes");
 append_rpid_hf("", ";party=calling;id-type=subscriber;screen=yes");
 ...
 ...
 
 
-4.20. is_rpid_user_e164()
+4.20.  is_rpid_user_e164()
 
 
    The function checks if the SIP URI received from the database or radius
    The function checks if the SIP URI received from the database or radius
    server and will potentially be used in Remote-Party-ID header field
    server and will potentially be used in Remote-Party-ID header field
@@ -755,7 +759,7 @@ if (is_rpid_user_e164()) {
 };
 };
 ...
 ...
 
 
-4.21. set_uri_user(uri, user)
+4.21.  set_uri_user(uri, user)
 
 
    Sets userpart of SIP URI stored in writable pseudo variable 'uri' to
    Sets userpart of SIP URI stored in writable pseudo variable 'uri' to
    value of pseudo variable 'user'.
    value of pseudo variable 'user'.
@@ -769,7 +773,7 @@ $var(user) = "new_user";
 set_uri_user("$var(uri)", "$var(user)");
 set_uri_user("$var(uri)", "$var(user)");
 ...
 ...
 
 
-4.22. set_uri_host(uri, host)
+4.22.  set_uri_host(uri, host)
 
 
    Sets hostpart of SIP URI stored in writable pseudo variable 'uri' to
    Sets hostpart of SIP URI stored in writable pseudo variable 'uri' to
    value of pseudo variable 'host'.
    value of pseudo variable 'host'.
@@ -783,7 +787,7 @@ $var(host) = "new_host";
 set_uri_host("$var(uri)", "$var(host)");
 set_uri_host("$var(uri)", "$var(host)");
 ...
 ...
 
 
-4.23. is_request()
+4.23.  is_request()
 
 
    Return true if the SIP message is a request.
    Return true if the SIP message is a request.
 
 
@@ -796,7 +800,7 @@ if (is_request()) {
 }
 }
 ...
 ...
 
 
-4.24. is_reply()
+4.24.  is_reply()
 
 
    Return true if the SIP message is a reply.
    Return true if the SIP message is a reply.
 
 
@@ -809,7 +813,7 @@ if (is_reply()) {
 }
 }
 ...
 ...
 
 
-4.25. is_gruu([uri])
+4.25.  is_gruu([uri])
 
 
    The function returns true if the uri is GRUU ('gr' parameter is
    The function returns true if the uri is GRUU ('gr' parameter is
    present): 1 - pub-gruu; 2 - temp-gruu.
    present): 1 - pub-gruu; 2 - temp-gruu.
@@ -824,3 +828,16 @@ if (is_reply()) {
 ...
 ...
 if(is_gruu()) { ... }
 if(is_gruu()) { ... }
 ...
 ...
+
+4.26.  is_supported(option)
+
+   Function returns true if given option is listed in Supported header(s)
+   (if any) of the request. Currently the following options are known:
+   path, 100rel, timer, eventlist, gruu, and outbound.
+
+   This function can be used from ANY_ROUTE.
+
+   Example 1.35. is_supported() usage
+...
+if (is_supported("outbound")) { ... }
+...

+ 23 - 0
modules/siputils/doc/siputils_admin.xml

@@ -986,6 +986,29 @@ if (is_reply()) {
 ...
 ...
 if(is_gruu()) { ... }
 if(is_gruu()) { ... }
 ...
 ...
+</programlisting>
+		</example>
+	</section>
+	<section id="is-supported">
+		<title>
+			<function moreinfo="none">is_supported(option)</function>
+		</title>
+		<para>
+			Function returns true if given option is listed
+			in Supported header(s) (if any) of the request.
+			Currently the following options are known: path,
+			100rel, timer, eventlist, gruu, and outbound.
+			
+		</para>
+		<para>
+		This function can be used from ANY_ROUTE.
+		</para>
+		<example>
+		<title>is_supported() usage</title>
+		<programlisting format="linespecific">
+...
+if (is_supported("outbound")) { ... }
+...
 </programlisting>
 </programlisting>
 		</example>
 		</example>
 	</section>
 	</section>

+ 17 - 0
modules/siputils/sipops.c

@@ -33,6 +33,7 @@
 
 
 #include "../../mod_fix.h"
 #include "../../mod_fix.h"
 #include "../../parser/parse_uri.h"
 #include "../../parser/parse_uri.h"
+#include "../../parser/parse_supported.h"
 #include "../../lib/kcore/cmpapi.h"
 #include "../../lib/kcore/cmpapi.h"
 
 
 #include "sipops.h"
 #include "sipops.h"
@@ -114,3 +115,19 @@ int w_is_gruu(sip_msg_t *msg, char *uri1, char *p2)
 	}
 	}
 	return -1;
 	return -1;
 }
 }
+
+int w_is_supported(sip_msg_t *msg, char *_option, char *p2)
+{
+    unsigned long option;
+
+    option = (unsigned long)_option;
+
+    if (parse_supported(msg) < 0)
+	return -1;
+
+    if ((((struct option_tag_body*)msg->supported->parsed)->option_tags_all &
+	 option) == 0)
+	return -1;
+    else
+	return 1;
+}

+ 1 - 0
modules/siputils/sipops.h

@@ -39,5 +39,6 @@
 int w_cmp_uri(struct sip_msg *msg, char *uri1, char *uri2);
 int w_cmp_uri(struct sip_msg *msg, char *uri1, char *uri2);
 int w_cmp_aor(struct sip_msg *msg, char *uri1, char *uri2);
 int w_cmp_aor(struct sip_msg *msg, char *uri1, char *uri2);
 int w_is_gruu(sip_msg_t *msg, char *uri1, char *p2);
 int w_is_gruu(sip_msg_t *msg, char *uri1, char *p2);
+int w_is_supported(sip_msg_t *msg, char *_option, char *p2);
 
 
 #endif
 #endif

+ 70 - 0
modules/siputils/siputils.c

@@ -65,6 +65,7 @@
 #include "../../ut.h"
 #include "../../ut.h"
 #include "../../mod_fix.h"
 #include "../../mod_fix.h"
 #include "../../error.h"
 #include "../../error.h"
+#include "../../parser/parse_option_tags.h"
 
 
 #include "ring.h"
 #include "ring.h"
 #include "options.h"
 #include "options.h"
@@ -112,6 +113,7 @@ static int fixup_free_set_uri(void** param, int param_no);
 static int fixup_tel2sip(void** param, int param_no);
 static int fixup_tel2sip(void** param, int param_no);
 static int fixup_get_uri_param(void** param, int param_no);
 static int fixup_get_uri_param(void** param, int param_no);
 static int free_fixup_get_uri_param(void** param, int param_no);
 static int free_fixup_get_uri_param(void** param, int param_no);
+static int fixup_option(void** param, int param_no);
 
 
 
 
 char *contact_flds_separator = DEFAULT_SEPARATOR;
 char *contact_flds_separator = DEFAULT_SEPARATOR;
@@ -169,6 +171,8 @@ static cmd_export_t cmds[]={
 		0, ANY_ROUTE},
 		0, ANY_ROUTE},
 	{"is_gruu",  (cmd_function)w_is_gruu,                    1, fixup_spve_null,
 	{"is_gruu",  (cmd_function)w_is_gruu,                    1, fixup_spve_null,
 		0, ANY_ROUTE},
 		0, ANY_ROUTE},
+	{"is_supported",  (cmd_function)w_is_supported,                    1, fixup_option,
+		0, ANY_ROUTE},
 	{0,0,0,0,0,0}
 	{0,0,0,0,0,0}
 };
 };
 
 
@@ -375,3 +379,69 @@ static int free_fixup_get_uri_param(void** param, int param_no) {
 	LM_ERR("invalid parameter number <%d>\n", param_no);
 	LM_ERR("invalid parameter number <%d>\n", param_no);
 	return -1;
 	return -1;
 }
 }
+
+/* */
+static int fixup_option(void** param, int param_no) {
+
+    char *option;
+    unsigned int option_len, res;
+
+    option = (char *)*param;
+    option_len = strlen(option);
+
+    if (param_no != 1) {
+	LM_ERR("invalid parameter number <%d>\n", param_no);
+	return -1;
+    }
+
+    switch (option_len) {
+    case 4:
+	if (strncasecmp(option, "path", 4) == 0)
+	    res = F_OPTION_TAG_PATH;
+	else if (strncasecmp(option, "gruu", 4) == 0)
+	    res = F_OPTION_TAG_GRUU;
+	else {
+	    LM_ERR("unknown option <%s>\n", option);
+	    return -1;
+	}
+	break;
+    case 5:
+	if (strncasecmp(option, "timer", 5) == 0)
+	    res = F_OPTION_TAG_TIMER;
+	else {
+	    LM_ERR("unknown option <%s>\n", option);
+	    return -1;
+	}
+	break;
+    case 6:
+	if (strncasecmp(option, "100rel", 6) == 0)
+	    res = F_OPTION_TAG_100REL;
+	else {
+	    LM_ERR("unknown option <%s>\n", option);
+	    return -1;
+	}
+	break;
+    case 8:
+	if (strncasecmp(option, "outbound", 8) == 0)
+	    res = F_OPTION_TAG_OUTBOUND;
+	else {
+	    LM_ERR("unknown option <%s>\n", option);
+	    return -1;
+	}
+	break;
+    case 9:
+	if (strncasecmp(option, "eventlist", 9) == 0)
+	    res = F_OPTION_TAG_EVENTLIST;
+	else {
+	    LM_ERR("unknown option <%s>\n", option);
+	    return -1;
+	}
+	break;
+    default:
+	LM_ERR("unknown option <%s>\n", option);
+	return -1;
+    }
+
+    *param = (void *)(long)res;
+    return 0;
+}