[asterisk-commits] mjordan: trunk r412292 - in /trunk: ./ channels/ channels/sip/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Fri Apr 11 21:27:51 CDT 2014


Author: mjordan
Date: Fri Apr 11 21:27:43 2014
New Revision: 412292

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=412292
Log:
chan_sip: Support RFC-3966 TEL URIs in inbound INVITE requests

This patch adds support for handling TEL URIs in inbound INVITE requests.
This includes the Request URI and the From URI. The number specified in
the Request URI will be the destination of the inbound channel in the dialplan.
The phone-context specified in the Request URI will be stored in the
TELPHONECONTEXT channel variable.

Review: https://reviewboard.asterisk.org/r/3349

ASTERISK-17179 #close
Reported by: Geert Van Pamel
Tested by: Geert Van Pamel
patches:
  asterisk-12.0.0-chan_sip-RFC3966_patch.txt uploaded by Geert Van Pamel (License 6140)
  asterisk-12.0.0-reqresp_parser-RFC3966_patch.txt uploaded by Geert Van Pamel (License 6140)


Modified:
    trunk/CHANGES
    trunk/channels/chan_sip.c
    trunk/channels/sip/reqresp_parser.c

Modified: trunk/CHANGES
URL: http://svnview.digium.com/svn/asterisk/trunk/CHANGES?view=diff&rev=412292&r1=412291&r2=412292
==============================================================================
--- trunk/CHANGES (original)
+++ trunk/CHANGES Fri Apr 11 21:27:43 2014
@@ -85,6 +85,17 @@
 -------------------------
  * A new function, MIXMONITOR, has been added to allow access to individual
    instances of MixMonitor on a channel.
+
+
+Channel Drivers
+-------------------------
+
+chan_sip
+-------------------------
+ * TEL URI support for inbound INVITE requests has been added. chan_sip will
+   now handle TEL schemes in the Request and From URIs. The phone-context in
+   the Request URI will be stored in the TELPHONECONTEXT channel variable on
+   the inbound channel.
 
 Debugging
 -------------------------

Modified: trunk/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/chan_sip.c?view=diff&rev=412292&r1=412291&r2=412292
==============================================================================
--- trunk/channels/chan_sip.c (original)
+++ trunk/channels/chan_sip.c Fri Apr 11 21:27:43 2014
@@ -17691,7 +17691,7 @@
 
 	uri = ast_strdupa(get_in_brackets(tmp));
 
-	if (parse_uri_legacy_check(uri, "sip:,sips:", &uri, &unused_password, &domain, NULL)) {
+	if (parse_uri_legacy_check(uri, "sip:,sips:,tel:", &uri, &unused_password, &domain, NULL)) {
 		ast_log(LOG_WARNING, "Not a SIP header (%s)?\n", uri);
 		return SIP_GET_DEST_INVALID_URI;
 	}
@@ -17719,7 +17719,7 @@
 	ast_copy_string(tmpf, sip_get_header(req, "From"), sizeof(tmpf));
 	if (!ast_strlen_zero(tmpf)) {
 		from = get_in_brackets(tmpf);
-		if (parse_uri_legacy_check(from, "sip:,sips:", &from, NULL, &domain, NULL)) {
+		if (parse_uri_legacy_check(from, "sip:,sips:,tel:", &from, NULL, &domain, NULL)) {
 			ast_log(LOG_WARNING, "Not a SIP header (%s)?\n", from);
 			return SIP_GET_DEST_INVALID_URI;
 		}
@@ -18607,10 +18607,13 @@
 
 	if (ast_strlen_zero(p->exten)) {
 		char *t = uri2;
-		if (!strncasecmp(t, "sip:", 4))
-			t+= 4;
-		else if (!strncasecmp(t, "sips:", 5))
+		if (!strncasecmp(t, "sip:", 4)) {
+			t += 4;
+		} else if (!strncasecmp(t, "sips:", 5)) {
 			t += 5;
+		} else if (!strncasecmp(t, "tel:", 4)) {	/* TEL URI INVITE */
+			t += 4;
+		}
 		ast_string_field_set(p, exten, t);
 		t = strchr(p->exten, '@');
 		if (t)
@@ -18625,7 +18628,7 @@
 	/* save the URI part of the From header */
 	ast_string_field_set(p, from, of);
 
-	if (parse_uri_legacy_check(of, "sip:,sips:", &name, &unused_password, &domain, NULL)) {
+	if (parse_uri_legacy_check(of, "sip:,sips:,tel:", &name, &unused_password, &domain, NULL)) {
 		ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n");
 	}
 

Modified: trunk/channels/sip/reqresp_parser.c
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/sip/reqresp_parser.c?view=diff&rev=412292&r1=412291&r2=412292
==============================================================================
--- trunk/channels/sip/reqresp_parser.c (original)
+++ trunk/channels/sip/reqresp_parser.c Fri Apr 11 21:27:43 2014
@@ -45,6 +45,7 @@
 	char *endparams = NULL;
 	char *c = NULL;
 	int error = 0;
+	int teluri_scheme = 0;
 
 	/*
 	 * Initialize requested strings - some functions don't care if parse_uri fails
@@ -79,6 +80,7 @@
 		for (; !ast_strlen_zero(cur); cur = strsep(&scheme2, ",")) {
 			l = strlen(cur);
 			if (!strncasecmp(uri, cur, l)) {
+				teluri_scheme = !strncasecmp(uri, "tel:", 4);	/* TEL URI */
 				uri += l;
 				break;
 			}
@@ -93,6 +95,42 @@
 		/* if we don't want to split around hostport, keep everything as a
 		 * userinfo - cos thats how old parse_uri operated*/
 		userinfo = uri;
+	} else if (teluri_scheme) {
+		/*
+		 * tel: TEL URI INVITE RFC 3966 patch
+		 * See http://www.ietf.org/rfc/rfc3966.txt
+		 *
+		 * Once the full RFC 3966 parsing is implemented,
+		 * the ext= or isub= parameters would be extracted from userinfo.
+		 * When this kind of subaddressing would be implemented, the userinfo must be further parsed.
+		 * Those parameters would be used for ISDN or PSTN local extensions.
+		 *
+		 * Current restrictions:
+		 * We currently consider the ";isub=" or the ";ext=" as part of the userinfo (unparsed).
+		 */
+
+		if ((c = strstr(uri, ";phone-context="))) {
+			/*
+			 * Local number with context or domain.
+			 * ext= or isub= TEL URI parameters should be upfront.
+			 * All other parameters should come after the ";phone-context=" parameter.
+			 * If other parameters would occur before ";phone-context=" they will be ignored.
+			 */
+
+                        *c = '\0';
+                        userinfo = uri;
+                        uri = c + 15;
+			*hostport = uri;
+                } else if ('+' == uri[0]) {
+			/* Global number without context or domain; possibly followed by RFC 3966 and optional other parameters. */
+
+                        userinfo = uri;
+			*hostport = uri;
+		} else {
+			ast_debug(1, "No RFC 3966 global number or context found in '%s'; returning local number anyway\n", uri);
+                        userinfo = uri;		/* Return local number anyway */
+			error = -1;
+		}
 	} else {
 		char *dom = "";
 		if ((c = strchr(uri, '@'))) {
@@ -375,6 +413,51 @@
 		.params.user = ""
 	};
 
+	/* RFC 3966 TEL URI INVITE */
+	struct testdata td11 = {
+		.desc = "tel local number",
+		.uri = "tel:0987654321;phone-context=+32987654321",
+		.user = "0987654321",
+		.pass = "",
+		.hostport = "+32987654321",
+		.headers = "",
+		.residue = "",
+		.params.transport = "",
+		.params.lr = 0,
+		.params.user = ""
+	};
+
+	struct testdata td12 = {
+		.desc = "tel global number",
+		.uri = "tel:+32987654321",
+		.user = "+32987654321",
+		.pass = "",
+		.hostport = "+32987654321",
+		.headers = "",
+		.residue = "",
+		.params.transport = "",
+		.params.lr = 0,
+		.params.user = ""
+	};
+
+	/*
+	 * Once the full RFC 3966 parsing is implemented,
+	 * only the ext= or isub= parameters would be extracted from .user
+	 * Then the ;param=discard would be ignored,
+	 * and the .user would only contain "0987654321"
+	 */
+	struct testdata td13 = {
+		.desc = "tel local number",
+		.uri = "tel:0987654321;ext=1234;param=discard;phone-context=+32987654321;transport=udp;param2=discard2?header=blah&header2=blah2;param3=residue",
+		.user = "0987654321;ext=1234;param=discard",
+		.pass = "",
+		.hostport = "+32987654321",
+		.headers = "header=blah&header2=blah2",
+		.residue = "param3=residue",
+		.params.transport = "udp",
+		.params.lr = 0,
+		.params.user = ""
+	};
 
 	AST_LIST_HEAD_SET_NOLOCK(&testdatalist, &td1);
 	AST_LIST_INSERT_TAIL(&testdatalist, &td2, list);
@@ -386,7 +469,9 @@
 	AST_LIST_INSERT_TAIL(&testdatalist, &td8, list);
 	AST_LIST_INSERT_TAIL(&testdatalist, &td9, list);
 	AST_LIST_INSERT_TAIL(&testdatalist, &td10, list);
-
+	AST_LIST_INSERT_TAIL(&testdatalist, &td11, list);
+	AST_LIST_INSERT_TAIL(&testdatalist, &td12, list);
+	AST_LIST_INSERT_TAIL(&testdatalist, &td13, list);
 
 	switch (cmd) {
 	case TEST_INIT:
@@ -407,7 +492,7 @@
 		params.lr = 0;
 
 		ast_copy_string(uri,testdataptr->uri,sizeof(uri));
-		if (parse_uri_full(uri, "sip:,sips:", &user,
+		if (parse_uri_full(uri, "sip:,sips:,tel:", &user,
 				   &pass, &hostport,
 				   &params,
 				   &headers,
@@ -460,6 +545,7 @@
 	char uri9[] = "sip:host:port;transport=tcp?headers=%40%40testblah&headers2=blah%20blah";
 	char uri10[] = "host:port;transport=tcp?headers=%40%40testblah&headers2=blah%20blah";
 	char uri11[] = "host";
+	char uri12[] = "tel:911";	/* TEL URI Local number without context or global number */
 
 	switch (cmd) {
 	case TEST_INIT:
@@ -585,6 +671,17 @@
 			strcmp(hostport, "host")      ||
 			!ast_strlen_zero(transport)) {
 		ast_test_status_update(test, "Test 11: simple uri with missing scheme failed. \n");
+		res = AST_TEST_FAIL;
+	}
+
+	/* Test 12, simple URI */
+	name = pass = hostport = transport = NULL;
+	if (!parse_uri(uri12, "sip:,sips:,tel:", &name, &pass, &hostport, &transport) ||
+			strcmp(name, "911")      ||	/* We return local number anyway */
+			!ast_strlen_zero(pass)      ||
+			!ast_strlen_zero(hostport)      ||	/* No global number nor context */
+			!ast_strlen_zero(transport)) {
+		ast_test_status_update(test, "Test 12: TEL URI INVITE failed.\n");
 		res = AST_TEST_FAIL;
 	}
 




More information about the asterisk-commits mailing list