From 1d6b192ce0262db43b91bf736f15cd2d7f39082a Mon Sep 17 00:00:00 2001 From: Olle Johansson Date: Wed, 19 Dec 2007 08:57:45 +0000 Subject: Adding the ability to specify the To: header in an outbound INVITE by adding an exclamation mark to the dial string. This patch also exists for 1.4 in the fixtoheader-1.4 branch and has been in production for quite some time. git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@93897 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- CHANGES | 2 ++ channels/chan_sip.c | 61 ++++++++++++++++++++++++++++++++++++++++--------- configs/sip.conf.sample | 42 +++++++++++++++++++++++++--------- 3 files changed, 83 insertions(+), 22 deletions(-) diff --git a/CHANGES b/CHANGES index 91a6c3f3b..0ccb9a0cb 100644 --- a/CHANGES +++ b/CHANGES @@ -109,6 +109,8 @@ SIP changes * New settings for timer T1 and timer B on a global level or per device. This makes it possible to force timeout faster on non-responsive SIP servers. These settings are considered advanced, so don't use them unless you have a problem. + * Added a dial string option to be able to set the To: header in an INVITE to any + SIP uri. IAX2 changes ------------ diff --git a/channels/chan_sip.c b/channels/chan_sip.c index 023922fea..96076ac20 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -1053,6 +1053,7 @@ struct sip_pvt { AST_STRING_FIELD(fromuser); /*!< User to show in the user field */ AST_STRING_FIELD(fromname); /*!< Name to show in the user field */ AST_STRING_FIELD(tohost); /*!< Host we should put in the "to" field */ + AST_STRING_FIELD(todnid); /*!< DNID of this call (overrides host) */ AST_STRING_FIELD(language); /*!< Default language for this call */ AST_STRING_FIELD(mohinterpret); /*!< MOH class to use when put on hold */ AST_STRING_FIELD(mohsuggest); /*!< MOH class to suggest when putting a peer on hold */ @@ -7839,17 +7840,30 @@ static void initreqprep(struct sip_request *req, struct sip_pvt *p, int sipmetho if (p->options && p->options->uri_options) ast_str_append(&invite, 0, ";%s", p->options->uri_options); + /* This is the request URI, which is the next hop of the call + which may or may not be the destination of the call + */ ast_string_field_set(p, uri, invite->str); + + if (!ast_strlen_zero(p->todnid)) { + /*! \todo Need to add back the VXML URL here at some point, possibly use build_string for all this junk */ + if (!strchr(p->todnid, '@')) { + /* We have no domain in the dnid */ + snprintf(to, sizeof(to), "%s%s", p->todnid, p->tohost, ast_strlen_zero(p->theirtag) ? "" : ";tag=", p->theirtag); + } else { + snprintf(to, sizeof(to), "%s%s", p->todnid, ast_strlen_zero(p->theirtag) ? "" : ";tag=", p->theirtag); + } + } else { + if (sipmethod == SIP_NOTIFY && !ast_strlen_zero(p->theirtag)) { + /* If this is a NOTIFY, use the From: tag in the subscribe (RFC 3265) */ + snprintf(to, sizeof(to), "<%s%s>;tag=%s", (strncasecmp(p->uri, "sip:", 4) ? "" : "sip:"), p->uri, p->theirtag); + } else if (p->options && p->options->vxml_url) { + /* If there is a VXML URL append it to the SIP URL */ + snprintf(to, sizeof(to), "<%s>;%s", p->uri, p->options->vxml_url); + } else + snprintf(to, sizeof(to), "<%s>", p->uri); + } - if (sipmethod == SIP_NOTIFY && !ast_strlen_zero(p->theirtag)) { - /* If this is a NOTIFY, use the From: tag in the subscribe (RFC 3265) */ - snprintf(to, sizeof(to), "<%s%s>;tag=%s", (strncasecmp(p->uri, "sip:", 4) ? "" : "sip:"), p->uri, p->theirtag); - } else if (p->options && p->options->vxml_url) { - /* If there is a VXML URL append it to the SIP URL */ - snprintf(to, sizeof(to), "<%s>;%s", p->uri, p->options->vxml_url); - } else - snprintf(to, sizeof(to), "<%s>", p->uri); - init_req(req, sipmethod, p->uri); /* now tmp_n is available so reuse it to build the CSeq */ snprintf(tmp_n, sizeof(tmp_n), "%d %s", ++p->ocseq, sip_methods[sipmethod].text); @@ -7858,6 +7872,7 @@ static void initreqprep(struct sip_request *req, struct sip_pvt *p, int sipmetho add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS); /* SLD: FIXME?: do Route: here too? I think not cos this is the first request. * OTOH, then we won't have anything in p->route anyway */ + /* Build Remote Party-ID and From */ if (ast_test_flag(&p->flags[0], SIP_SENDRPID) && (sipmethod == SIP_INVITE)) { build_rpid(p); @@ -17304,7 +17319,13 @@ static int sip_devicestate(void *data) } /*! \brief PBX interface function -build SIP pvt structure - SIP calls initiated by the PBX arrive here */ + SIP calls initiated by the PBX arrive here + + SIP Dial string syntax + SIP/exten@host!dnid + or SIP/host/exten!dnid + or SIP/host!dnid +*/ static struct ast_channel *sip_request_call(const char *type, int format, void *data, int *cause) { struct sip_pvt *p; @@ -17312,6 +17333,7 @@ static struct ast_channel *sip_request_call(const char *type, int format, void * char *ext, *host; char tmp[256]; char *dest = data; + char *dnid; int oldformat = format; /* mask request with some set of allowed formats. @@ -17344,7 +17366,18 @@ static struct ast_channel *sip_request_call(const char *type, int format, void * return NULL; } + /* Save the destination, the SIP dial string */ ast_copy_string(tmp, dest, sizeof(tmp)); + + + /* Find DNID and take it away */ + dnid = strchr(tmp, '!'); + if (dnid != NULL) { + *dnid++ = '\0'; + ast_string_field_set(p, todnid, dnid); + } + + /* Find at sign - @ */ host = strchr(tmp, '@'); if (host) { *host++ = '\0'; @@ -17356,6 +17389,11 @@ static struct ast_channel *sip_request_call(const char *type, int format, void * host = tmp; } + /* We now have + host = peer name, DNS host name or DNS domain (for SRV) + ext = extension (user part of URI) + dnid = destination of the call (applies to the To: header) + */ if (create_addr(p, host)) { *cause = AST_CAUSE_UNREGISTERED; ast_debug(3, "Cant create SIP call - target device not registred\n"); @@ -17372,7 +17410,8 @@ static struct ast_channel *sip_request_call(const char *type, int format, void * /* We have an extension to call, don't use the full contact here */ /* This to enable dialing registered peers with extension dialling, like SIP/peername/extension - SIP/peername will still use the full contact */ + SIP/peername will still use the full contact + */ if (ext) { ast_string_field_set(p, username, ext); ast_string_field_set(p, fullcontact, NULL); diff --git a/configs/sip.conf.sample b/configs/sip.conf.sample index d8e25e642..78ed4806f 100644 --- a/configs/sip.conf.sample +++ b/configs/sip.conf.sample @@ -1,17 +1,37 @@ ; ; SIP Configuration example for Asterisk ; -; Syntax for specifying a SIP device in extensions.conf is -; SIP/devicename where devicename is defined in a section below. -; -; You may also use -; SIP/username@domain to call any SIP user on the Internet -; (Don't forget to enable DNS SRV records if you want to use this) -; -; If you define a SIP proxy as a peer below, you may call -; SIP/proxyhostname/user or SIP/user@proxyhostname -; where the proxyhostname is defined in a section below +; SIP dial strings +;----------------------------------------------------------- +; In the dialplan (extensions.conf) you can use several +; syntaxes for dialing SIP devices. +; SIP/devicename +; SIP/username@domain (SIP uri) +; SIP/username@host:port +; SIP/devicename/extension +; +; +; Devicename +; devicename is defined as a peer in a section below. +; +; username@domain +; Call any SIP user on the Internet +; (Don't forget to enable DNS SRV records if you want to use this) ; +; devicename/extension +; If you define a SIP proxy as a peer below, you may call +; SIP/proxyhostname/user or SIP/user@proxyhostname +; where the proxyhostname is defined in a section below +; This syntax also works with ATA's with FXO ports +; +; All of these dial strings specify the SIP request URI. +; In addition, you can specify a specific To: header by adding an +; exclamation mark after the dial string, like +; +; SIP/sales@mysipproxy!sales@edvina.net +; +; CLI Commands +; ------------------------------------------------------------- ; Useful CLI commands to check peers/users: ; sip show peers Show all SIP peers (including friends) ; sip show users Show all SIP users (including friends) @@ -23,7 +43,7 @@ ; Active SIP peers will not be reconfigured ; -; ** Deprecated options ** +; ** Deprecated configuration options ** ; The "call-limit" configuation option is deprecated. It still works in ; this version of Asterisk, but will disappear in the next version. ; You are encouraged to use the dialplan groupcount functionality -- cgit v1.2.3