Selaa lähdekoodia

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 vuotta sitten
vanhempi
commit
d992d3b223

+ 43 - 26
modules/siputils/README

@@ -40,7 +40,7 @@ Edited by
 
 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
      __________________________________________________________________
 
@@ -93,6 +93,7 @@ Gabriel Vasile
               4.23. is_request()
               4.24. is_reply()
               4.25. is_gruu([uri])
+              4.26. is_supported(option)
 
    List of Examples
 
@@ -130,6 +131,7 @@ Gabriel Vasile
    1.32. is_request usage
    1.33. is_reply usage
    1.34. is_gruu() usage
+   1.35. is_supported() usage
 
 Chapter 1. Admin Guide
 
@@ -180,6 +182,7 @@ Chapter 1. Admin Guide
         4.23. is_request()
         4.24. is_reply()
         4.25. is_gruu([uri])
+        4.26. is_supported(option)
 
 1. Overview
 
@@ -380,8 +383,9 @@ modparam("auth", "rpid_avp", "$avp(myrpid)")
    4.23. is_request()
    4.24. is_reply()
    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
    further replies arrive. Any 183 reply that is received during the
@@ -398,7 +402,7 @@ modparam("auth", "rpid_avp", "$avp(myrpid)")
 ring_insert_callid();
 ...
 
-4.2. options_reply()
+4.2.  options_reply()
 
    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
@@ -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.
 
@@ -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.
 
@@ -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
 
@@ -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
 
@@ -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);
 
@@ -502,7 +506,7 @@ if (uri_param("param1","value1")) {
 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.
 
@@ -517,7 +521,7 @@ add_uri_param("nat=yes");
 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
    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
 ...
 
-4.10. is_e164(pseudo-variable)
+4.10.  is_e164(pseudo-variable)
 
    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.
 
@@ -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
    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");
 ...
 
-4.13. decode_contact()
+4.13.  decode_contact()
 
    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
@@ -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(); }
 ...
 
-4.14. decode_contact_header()
+4.14.  decode_contact_header()
 
    This function will decode URIs inside Contact header. If the URI in the
    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.
 
@@ -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
    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
    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
    '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
 ...
 
-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
    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");
 ...
 
-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
    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
    value of pseudo variable 'user'.
@@ -769,7 +773,7 @@ $var(user) = "new_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
    value of pseudo variable 'host'.
@@ -783,7 +787,7 @@ $var(host) = "new_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.
 
@@ -796,7 +800,7 @@ if (is_request()) {
 }
 ...
 
-4.24. is_reply()
+4.24.  is_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
    present): 1 - pub-gruu; 2 - temp-gruu.
@@ -824,3 +828,16 @@ if (is_reply()) {
 ...
 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()) { ... }
 ...
+</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>
 		</example>
 	</section>

+ 17 - 0
modules/siputils/sipops.c

@@ -33,6 +33,7 @@
 
 #include "../../mod_fix.h"
 #include "../../parser/parse_uri.h"
+#include "../../parser/parse_supported.h"
 #include "../../lib/kcore/cmpapi.h"
 
 #include "sipops.h"
@@ -114,3 +115,19 @@ int w_is_gruu(sip_msg_t *msg, char *uri1, char *p2)
 	}
 	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_aor(struct sip_msg *msg, char *uri1, char *uri2);
 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

+ 70 - 0
modules/siputils/siputils.c

@@ -65,6 +65,7 @@
 #include "../../ut.h"
 #include "../../mod_fix.h"
 #include "../../error.h"
+#include "../../parser/parse_option_tags.h"
 
 #include "ring.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_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;
@@ -169,6 +171,8 @@ static cmd_export_t cmds[]={
 		0, ANY_ROUTE},
 	{"is_gruu",  (cmd_function)w_is_gruu,                    1, fixup_spve_null,
 		0, ANY_ROUTE},
+	{"is_supported",  (cmd_function)w_is_supported,                    1, fixup_option,
+		0, ANY_ROUTE},
 	{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);
 	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;
+}