diff options
author | Matthew Jordan <mjordan@digium.com> | 2014-04-12 02:27:43 +0000 |
---|---|---|
committer | Matthew Jordan <mjordan@digium.com> | 2014-04-12 02:27:43 +0000 |
commit | eed03fc01ac8c6ef424eff65c718f7802a4cb1ef (patch) | |
tree | 9d7f8bd4fa085773b28aa8f6ad4c251fe11dbab7 /channels/sip/reqresp_parser.c | |
parent | 39ba6a16f5c0fd1fe40a41d7102b057ef3490a9e (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.c | 101 |
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, ¶ms, &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; } |