summaryrefslogtreecommitdiff
path: root/channels/sip/reqresp_parser.c
diff options
context:
space:
mode:
authorMatthew Jordan <mjordan@digium.com>2014-04-12 02:27:43 +0000
committerMatthew Jordan <mjordan@digium.com>2014-04-12 02:27:43 +0000
commiteed03fc01ac8c6ef424eff65c718f7802a4cb1ef (patch)
tree9d7f8bd4fa085773b28aa8f6ad4c251fe11dbab7 /channels/sip/reqresp_parser.c
parent39ba6a16f5c0fd1fe40a41d7102b057ef3490a9e (diff)
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) git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@412292 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'channels/sip/reqresp_parser.c')
-rw-r--r--channels/sip/reqresp_parser.c101
1 files changed, 99 insertions, 2 deletions
diff --git a/channels/sip/reqresp_parser.c b/channels/sip/reqresp_parser.c
index 7d4445784..5c2f2eb1f 100644
--- a/channels/sip/reqresp_parser.c
+++ b/channels/sip/reqresp_parser.c
@@ -45,6 +45,7 @@ int parse_uri_full(char *uri, const char *scheme, char **user, char **pass,
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 @@ int parse_uri_full(char *uri, const char *scheme, char **user, char **pass,
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 @@ int parse_uri_full(char *uri, const char *scheme, char **user, char **pass,
/* 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 @@ AST_TEST_DEFINE(sip_parse_uri_full_test)
.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_TEST_DEFINE(sip_parse_uri_full_test)
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 @@ AST_TEST_DEFINE(sip_parse_uri_full_test)
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 @@ AST_TEST_DEFINE(sip_parse_uri_test)
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:
@@ -588,6 +674,17 @@ AST_TEST_DEFINE(sip_parse_uri_test)
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;
+ }
+
return res;
}