浏览代码

siputils: completed the function to return RURI parameter value

- closes FS#238, based on a patch by Luis Martin
Daniel-Constantin Mierla 12 年之前
父节点
当前提交
45b2ea3018
共有 5 个文件被更改,包括 245 次插入103 次删除
  1. 122 103
      modules/siputils/README
  2. 50 0
      modules/siputils/checks.c
  3. 5 0
      modules/siputils/checks.h
  4. 29 0
      modules/siputils/doc/siputils_admin.xml
  5. 39 0
      modules/siputils/siputils.c

+ 122 - 103
modules/siputils/README

@@ -75,23 +75,24 @@ Gabriel Vasile
               4.5. uri_param(param)
               4.6. uri_param(param,value)
               4.7. add_uri_param(param)
-              4.8. tel2sip(uri, hostpart, result)
-              4.9. is_e164(pseudo-variable)
-              4.10. is_uri_user_e164(pseudo-variable)
-              4.11. encode_contact(encoding_prefix,hostpart)
-              4.12. decode_contact()
-              4.13. decode_contact_header()
-              4.14. cmp_uri(str1, str2)
-              4.15. cmp_aor(str1, str2)
-              4.16. is_rpid_user_e164()
-              4.17. append_rpid_hf()
-              4.18. append_rpid_hf(prefix, suffix)
-              4.19. is_rpid_user_e164()
-              4.20. set_uri_user(uri, user)
-              4.21. set_uri_host(uri, host)
-              4.22. is_request()
-              4.23. is_reply()
-              4.24. is_gruu([uri])
+              4.8. get_uri_param(name, var)
+              4.9. tel2sip(uri, hostpart, result)
+              4.10. is_e164(pseudo-variable)
+              4.11. is_uri_user_e164(pseudo-variable)
+              4.12. encode_contact(encoding_prefix,hostpart)
+              4.13. decode_contact()
+              4.14. decode_contact_header()
+              4.15. cmp_uri(str1, str2)
+              4.16. cmp_aor(str1, str2)
+              4.17. is_rpid_user_e164()
+              4.18. append_rpid_hf()
+              4.19. append_rpid_hf(prefix, suffix)
+              4.20. is_rpid_user_e164()
+              4.21. set_uri_user(uri, user)
+              4.22. set_uri_host(uri, host)
+              4.23. is_request()
+              4.24. is_reply()
+              4.25. is_gruu([uri])
 
    List of Examples
 
@@ -111,23 +112,24 @@ Gabriel Vasile
    1.14. uri_param usage
    1.15. uri_param usage
    1.16. add_uri_param usage
-   1.17. tel2sip usage
-   1.18. is_e164 usage
-   1.19. is_uri_user_e164 usage
-   1.20. encode_contact usage
-   1.21. decode_contact usage
-   1.22. decode_contact_header usage
-   1.23. cmp_uri usage
-   1.24. cmp_aor usage
-   1.25. is_rpid_user_e164 usage
-   1.26. append_rpid_hf usage
-   1.27. append_rpid_hf(prefix, suffix) usage
-   1.28. is_rpid_user_e164 usage
-   1.29. set_uri_user usage
-   1.30. set_uri_host usage
-   1.31. is_request usage
-   1.32. is_reply usage
-   1.33. is_gruu() usage
+   1.17. add_uri_param usage
+   1.18. tel2sip usage
+   1.19. is_e164 usage
+   1.20. is_uri_user_e164 usage
+   1.21. encode_contact usage
+   1.22. decode_contact usage
+   1.23. decode_contact_header usage
+   1.24. cmp_uri usage
+   1.25. cmp_aor usage
+   1.26. is_rpid_user_e164 usage
+   1.27. append_rpid_hf usage
+   1.28. append_rpid_hf(prefix, suffix) usage
+   1.29. is_rpid_user_e164 usage
+   1.30. set_uri_user usage
+   1.31. set_uri_host usage
+   1.32. is_request usage
+   1.33. is_reply usage
+   1.34. is_gruu() usage
 
 Chapter 1. Admin Guide
 
@@ -160,23 +162,24 @@ Chapter 1. Admin Guide
         4.5. uri_param(param)
         4.6. uri_param(param,value)
         4.7. add_uri_param(param)
-        4.8. tel2sip(uri, hostpart, result)
-        4.9. is_e164(pseudo-variable)
-        4.10. is_uri_user_e164(pseudo-variable)
-        4.11. encode_contact(encoding_prefix,hostpart)
-        4.12. decode_contact()
-        4.13. decode_contact_header()
-        4.14. cmp_uri(str1, str2)
-        4.15. cmp_aor(str1, str2)
-        4.16. is_rpid_user_e164()
-        4.17. append_rpid_hf()
-        4.18. append_rpid_hf(prefix, suffix)
-        4.19. is_rpid_user_e164()
-        4.20. set_uri_user(uri, user)
-        4.21. set_uri_host(uri, host)
-        4.22. is_request()
-        4.23. is_reply()
-        4.24. is_gruu([uri])
+        4.8. get_uri_param(name, var)
+        4.9. tel2sip(uri, hostpart, result)
+        4.10. is_e164(pseudo-variable)
+        4.11. is_uri_user_e164(pseudo-variable)
+        4.12. encode_contact(encoding_prefix,hostpart)
+        4.13. decode_contact()
+        4.14. decode_contact_header()
+        4.15. cmp_uri(str1, str2)
+        4.16. cmp_aor(str1, str2)
+        4.17. is_rpid_user_e164()
+        4.18. append_rpid_hf()
+        4.19. append_rpid_hf(prefix, suffix)
+        4.20. is_rpid_user_e164()
+        4.21. set_uri_user(uri, user)
+        4.22. set_uri_host(uri, host)
+        4.23. is_request()
+        4.24. is_reply()
+        4.25. is_gruu([uri])
 
 1. Overview
 
@@ -359,23 +362,24 @@ modparam("auth", "rpid_avp", "$avp(myrpid)")
    4.5. uri_param(param)
    4.6. uri_param(param,value)
    4.7. add_uri_param(param)
-   4.8. tel2sip(uri, hostpart, result)
-   4.9. is_e164(pseudo-variable)
-   4.10. is_uri_user_e164(pseudo-variable)
-   4.11. encode_contact(encoding_prefix,hostpart)
-   4.12. decode_contact()
-   4.13. decode_contact_header()
-   4.14. cmp_uri(str1, str2)
-   4.15. cmp_aor(str1, str2)
-   4.16. is_rpid_user_e164()
-   4.17. append_rpid_hf()
-   4.18. append_rpid_hf(prefix, suffix)
-   4.19. is_rpid_user_e164()
-   4.20. set_uri_user(uri, user)
-   4.21. set_uri_host(uri, host)
-   4.22. is_request()
-   4.23. is_reply()
-   4.24. is_gruu([uri])
+   4.8. get_uri_param(name, var)
+   4.9. tel2sip(uri, hostpart, result)
+   4.10. is_e164(pseudo-variable)
+   4.11. is_uri_user_e164(pseudo-variable)
+   4.12. encode_contact(encoding_prefix,hostpart)
+   4.13. decode_contact()
+   4.14. decode_contact_header()
+   4.15. cmp_uri(str1, str2)
+   4.16. cmp_aor(str1, str2)
+   4.17. is_rpid_user_e164()
+   4.18. append_rpid_hf()
+   4.19. append_rpid_hf(prefix, suffix)
+   4.20. is_rpid_user_e164()
+   4.21. set_uri_user(uri, user)
+   4.22. set_uri_host(uri, host)
+   4.23. is_request()
+   4.24. is_reply()
+   4.25. is_gruu([uri])
 
 4.1. ring_insert_callid()
 
@@ -498,7 +502,22 @@ if (uri_param("param1","value1")) {
 add_uri_param("nat=yes");
 ...
 
-4.8. tel2sip(uri, hostpart, result)
+4.8. get_uri_param(name, var)
+
+   Get the value of RURI parameter.
+
+   Meaning of the parameters is as follows:
+     * name - the name of R-URI parameter
+     * var - the variable where to store the value of the parameter
+
+   This function can be used from REQUEST_ROUTE.
+
+   Example 1.17. add_uri_param usage
+...
+get_uri_param("nat", "$var(nat)");
+...
+
+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
@@ -517,7 +536,7 @@ add_uri_param("nat=yes");
    This function can be used from REQUEST_ROUTE, FAILURE_ROUTE,
    BRANCH_ROUTE, or ONREPLY_ROUTE.
 
-   Example 1.17. tel2sip usage
+   Example 1.18. tel2sip usage
 ...
 # $ru: tel:+(34)-999-888-777
 # $fu: sip:[email protected]
@@ -530,14 +549,14 @@ tel2sip("$ru", $fd", "$ru");
 # $ru:  sip:+12345678;ext=200;[email protected];user=phone
 ...
 
-4.9. is_e164(pseudo-variable)
+4.10. is_e164(pseudo-variable)
 
    Checks if string value of pseudo variable argument is an E164 number.
 
    This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, and
    LOCAL_ROUTE.
 
-   Example 1.18. is_e164 usage
+   Example 1.19. is_e164 usage
 ...
 if (is_164("$fU")) {  # Check From header URI user part
    ...
@@ -548,13 +567,13 @@ if (is_e164("$avp(i:705)") {
 };
 ...
 
-4.10. 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.
 
    This function can be used from ANY_ROUTE.
 
-   Example 1.19. is_uri_user_e164 usage
+   Example 1.20. is_uri_user_e164 usage
 ...
 if (is_uri_user_e164("$fu")) {  # Check From header URI user part
    ...
@@ -565,7 +584,7 @@ if (is_uri_user_e164("$avp(i:705)") {
 };
 ...
 
-4.11. 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
@@ -587,12 +606,12 @@ if (is_uri_user_e164("$avp(i:705)") {
 
    This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE.
 
-   Example 1.20. encode_contact usage
+   Example 1.21. encode_contact usage
 ...
 if (src_ip == 10.0.0.0/8) encode_contact("natted_client","1.2.3.4");
 ...
 
-4.12. 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
@@ -605,12 +624,12 @@ if (src_ip == 10.0.0.0/8) encode_contact("natted_client","1.2.3.4");
 
    This function can be used from REQUEST_ROUTE.
 
-   Example 1.21. decode_contact usage
+   Example 1.22. decode_contact usage
 ...
 if (uri =~ "^sip:natted_client") { decode_contact(); }
 ...
 
-4.13. 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
@@ -623,7 +642,7 @@ if (uri =~ "^sip:natted_client") { decode_contact(); }
 
    This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE.
 
-   Example 1.22. decode_contact_header usage
+   Example 1.23. decode_contact_header usage
 ...
 reply_route[2] {
         ...
@@ -632,13 +651,13 @@ reply_route[2] {
 }
 ...
 
-4.14. cmp_uri(str1, str2)
+4.15. cmp_uri(str1, str2)
 
    The function returns true if the two parameters matches as SIP URI.
 
    This function can be used from ANY_ROUTE.
 
-   Example 1.23. cmp_uri usage
+   Example 1.24. cmp_uri usage
 ...
 if(cmp_uri("$ru", "sip:[email protected]"))
 {
@@ -646,14 +665,14 @@ if(cmp_uri("$ru", "sip:[email protected]"))
 }
 ...
 
-4.15. 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.
 
    This function can be used from ANY_ROUTE.
 
-   Example 1.24. cmp_aor usage
+   Example 1.25. cmp_aor usage
 ...
 if(cmp_aor("[email protected]", "sip:kamailio@$fd"))
 {
@@ -661,7 +680,7 @@ if(cmp_aor("[email protected]", "sip:kamailio@$fd"))
 }
 ...
 
-4.16. 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
@@ -671,14 +690,14 @@ if(cmp_aor("[email protected]", "sip:kamailio@$fd"))
 
    This function can be used from REQUEST_ROUTE.
 
-   Example 1.25. is_rpid_user_e164 usage
+   Example 1.26. is_rpid_user_e164 usage
 ...
 if (is_rpid_user_e164()) {
     # do something here
 };
 ...
 
-4.17. 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
@@ -689,14 +708,14 @@ if (is_rpid_user_e164()) {
    This function can be used from REQUEST_ROUTE, FAILURE_ROUTE,
    BRANCH_ROUTE.
 
-   Example 1.26. append_rpid_hf usage
+   Example 1.27. append_rpid_hf usage
 ...
 append_rpid_hf();  # Append Remote-Party-ID header field
 ...
 
-4.18. append_rpid_hf(prefix, suffix)
+4.19. append_rpid_hf(prefix, suffix)
 
-   This function is the same as Section 4.17, " 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
    be added to Remote-Party-ID header field. This function ignores
    rpid_prefix and rpid_suffix parameters, instead of that allows to set
@@ -713,13 +732,13 @@ append_rpid_hf();  # Append Remote-Party-ID header field
    This function can be used from REQUEST_ROUTE, FAILURE_ROUTE,
    BRANCH_ROUTE.
 
-   Example 1.27. append_rpid_hf(prefix, suffix) usage
+   Example 1.28. append_rpid_hf(prefix, suffix) usage
 ...
 # Append Remote-Party-ID header field
 append_rpid_hf("", ";party=calling;id-type=subscriber;screen=yes");
 ...
 
-4.19. 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
@@ -729,68 +748,68 @@ append_rpid_hf("", ";party=calling;id-type=subscriber;screen=yes");
 
    This function can be used from REQUEST_ROUTE.
 
-   Example 1.28. is_rpid_user_e164 usage
+   Example 1.29. is_rpid_user_e164 usage
 ...
 if (is_rpid_user_e164()) {
     # do something here
 };
 ...
 
-4.20. 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'.
 
    This function can be used from ANY_ROUTE.
 
-   Example 1.29. set_uri_user usage
+   Example 1.30. set_uri_user usage
 ...
 $var(uri) = "sip:user@host";
 $var(user) = "new_user";
 set_uri_user("$var(uri)", "$var(user)");
 ...
 
-4.21. 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'.
 
    This function can be used from ANY_ROUTE.
 
-   Example 1.30. set_uri_host usage
+   Example 1.31. set_uri_host usage
 ...
 $var(uri) = "sip:user@host";
 $var(host) = "new_host";
 set_uri_host("$var(uri)", "$var(host)");
 ...
 
-4.22. is_request()
+4.23. is_request()
 
    Return true if the SIP message is a request.
 
    This function can be used from ANY_ROUTE.
 
-   Example 1.31. is_request usage
+   Example 1.32. is_request usage
 ...
 if (is_request()) {
         ...
 }
 ...
 
-4.23. is_reply()
+4.24. is_reply()
 
    Return true if the SIP message is a reply.
 
    This function can be used from ANY_ROUTE.
 
-   Example 1.32. is_reply usage
+   Example 1.33. is_reply usage
 ...
 if (is_reply()) {
         ...
 }
 ...
 
-4.24. 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.
@@ -801,7 +820,7 @@ if (is_reply()) {
 
    This function can be used from ANY_ROUTE.
 
-   Example 1.33. is_gruu() usage
+   Example 1.34. is_gruu() usage
 ...
 if(is_gruu()) { ... }
 ...

+ 50 - 0
modules/siputils/checks.c

@@ -675,3 +675,53 @@ int set_uri_host(struct sip_msg* _m, char* _uri, char* _value)
 
     return 1;
 }
+
+/**
+ * Find if Request URI has a given parameter and returns the value.
+ */
+int get_uri_param(struct sip_msg* _msg, char* _param, char* _value)
+{
+	str *param, t;
+	pv_spec_t* dst;
+	pv_value_t val;
+
+	param_hooks_t hooks;
+	param_t* params;
+
+	param = (str*)_param;
+	dst = (pv_spec_t *) _value;
+  
+	if (parse_sip_msg_uri(_msg) < 0) {
+		LM_ERR("ruri parsing failed\n");
+		return -1;
+	}
+
+	t = _msg->parsed_uri.params;
+
+	if (parse_params(&t, CLASS_ANY, &hooks, &params) < 0) {
+		LM_ERR("ruri parameter parsing failed\n");
+		return -1;
+	}
+
+	while (params) {
+		if ((params->name.len == param->len)
+				&& (strncmp(params->name.s, param->s, param->len) == 0)) {
+			memset(&val, 0, sizeof(pv_value_t));
+			val.rs.s = params->body.s;
+			val.rs.len = params->body.len;
+			val.flags = PV_VAL_STR;
+			dst->setf(_msg, &dst->pvp, (int)EQ_T, &val);
+			goto found;
+		} else {
+			params = params->next;
+		}
+	}
+  
+	free_params(params);
+	return -1;
+
+found:
+	free_params(params);
+	return 1;
+}
+

+ 5 - 0
modules/siputils/checks.h

@@ -112,4 +112,9 @@ int w_is_request(struct sip_msg* msg, char *foo, char *bar);
  */
 int w_is_reply(struct sip_msg* msg, char *foo, char *bar);
 
+/*
+ * Find if Request URI has a given parameter with matching value
+ */
+int get_uri_param(struct sip_msg* _msg, char* _param, char* _value);
+
 #endif /* CHECKS_H */

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

@@ -473,6 +473,35 @@ if (uri_param("param1","value1")) {
 ...
 add_uri_param("nat=yes");
 ...
+</programlisting>
+		</example>
+	</section>
+	<section>
+		<title>
+		<function moreinfo="none">get_uri_param(name, var)</function>
+		</title>
+		<para>
+		Get the value of RURI parameter.
+		</para>
+		<para>Meaning of the parameters is as follows:</para>
+		<itemizedlist>
+		<listitem>
+			<para><emphasis>name</emphasis> - the name of R-URI parameter</para>
+		</listitem>
+		<listitem>
+			<para><emphasis>var</emphasis> - the variable where to store the
+			value of the parameter</para>
+		</listitem>
+		</itemizedlist>
+		<para>
+		This function can be used from REQUEST_ROUTE.
+		</para>
+		<example>
+		<title><function>add_uri_param</function> usage</title>
+		<programlisting format="linespecific">
+...
+get_uri_param("nat", "$var(nat)");
+...
 </programlisting>
 		</example>
 	</section>

+ 39 - 0
modules/siputils/siputils.c

@@ -110,6 +110,9 @@ static void mod_destroy(void);
 static int fixup_set_uri(void** param, int param_no);
 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);
+
 
 char *contact_flds_separator = DEFAULT_SEPARATOR;
 
@@ -128,6 +131,8 @@ static cmd_export_t cmds[]={
 		0, REQUEST_ROUTE|LOCAL_ROUTE},
 	{"add_uri_param",      (cmd_function)add_uri_param,     1, fixup_str_null,
 		0, REQUEST_ROUTE},
+	{"get_uri_param",      (cmd_function)get_uri_param,     2, fixup_get_uri_param, 
+		free_fixup_get_uri_param, REQUEST_ROUTE|LOCAL_ROUTE},
 	{"tel2sip", (cmd_function)tel2sip, 3, fixup_tel2sip, 0,
 	 REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|ONREPLY_ROUTE},
 	{"is_e164",            (cmd_function)is_e164,           1, fixup_pvar_null,
@@ -336,3 +341,37 @@ static int fixup_tel2sip(void** param, int param_no)
     LM_ERR("invalid parameter number <%d>\n", param_no);
     return -1;
 }
+
+/* */
+static int fixup_get_uri_param(void** param, int param_no) {
+	if (param_no == 1) {
+		return fixup_str_null(param, 1);
+	}
+	if (param_no == 2) {
+		if (fixup_pvar_null(param, 1) != 0) {
+			LM_ERR("failed to fixup result pvar\n");
+			return -1;
+		}
+		if (((pv_spec_t *)(*param))->setf == NULL) {
+			LM_ERR("result pvar is not writeble\n");
+			return -1;
+		}
+		return 0;
+	}
+
+	LM_ERR("invalid parameter number <%d>\n", param_no);
+	return -1;
+}
+
+/* */
+static int free_fixup_get_uri_param(void** param, int param_no) {
+	if (param_no == 1) {
+		LM_WARN("free function has not been defined for spve\n");
+		return 0;
+	}
+	if (param_no == 2) {
+		return fixup_free_pvar_null(param, 1);
+	}
+	LM_ERR("invalid parameter number <%d>\n", param_no);
+	return -1;
+}