<p>Joshua Colp <strong>merged</strong> this change.</p><p><a href="https://gerrit.asterisk.org/6118">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  Richard Mudgett: Looks good to me, but someone else must approve
  Jenkins2: Approved for Submit
  Joshua Colp: Looks good to me, approved

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">chan_sip: Access incoming REFER headers in dialplan<br><br>This adds a way to access information passed along with SIP headers in<br>a REFER message that initiates a transfer. Headers matching a dialplan<br>variable GET_TRANSFERRER_DATA in the transferrer channel are added to<br>a HASH object TRANSFER_DATA to be accessed with functions HASHKEY and HASH.<br><br>The variable GET_TRANSFERRER_DATA is interpreted to be a prefix for<br>headers that should be put into the hash. If not set, no headers are<br>included. If set to a string (perhaps 'X-' in a typical case), all headers<br>starting this string are added. Empty string matches all headers.<br><br>If there are multiple of the same header, only the latest occurrence in<br>the REFER message is available in the hash.<br><br>Obviously, the variable GET_TRANSFERRER_DATA must be inherited by the<br>referrer channel, and should be set with the '_' or '__' prefix.<br><br>I avoided a specific reference to SIP or REFER, as in my mind the mechanism<br>can be generalized to other channel techs.<br><br>ASTERISK-27162<br><br>Change-Id: I73d7a1e95981693bc59aa0d5093c074b555f708e<br>---<br>M CHANGES<br>M channels/chan_sip.c<br>2 files changed, 49 insertions(+), 1 deletion(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">diff --git a/CHANGES b/CHANGES<br>index 4f5225a..67d33c9 100644<br>--- a/CHANGES<br>+++ b/CHANGES<br>@@ -16,6 +16,10 @@<br> ------------------<br>  * New function SIP_HEADERS() enumerates all headers in the incoming INVITE.<br> <br>+ * The variable GET_TRANSFERRER_DATA set in the peer channel causes matching<br>+   headers be retrieved from the REFER message and made accessible to the<br>+   dialplan in the hash TRANSFER_DATA.<br>+<br> ------------------------------------------------------------------------------<br> --- Functionality changes from Asterisk 14 to Asterisk 15 --------------------<br> ------------------------------------------------------------------------------<br>diff --git a/channels/chan_sip.c b/channels/chan_sip.c<br>index 941a1e9..dcfadf4 100644<br>--- a/channels/chan_sip.c<br>+++ b/channels/chan_sip.c<br>@@ -377,7 +377,20 @@<br>                     <para>Since there are several headers (such as Via) which can occur multiple<br>                    times, SIP_HEADER takes an optional second argument to specify which header with<br>                      that name to retrieve. Headers start at offset <literal>1</literal>.</para><br>-                        <para>Please observe that contents of the SDP (an attachment to the<br>+                    <para>This function does not access headers from the REFER message if the call<br>+                 was transferred. To obtain the REFER headers, set the dialplan variable<br>+                      <variable>GET_TRANSFERRER_DATA</variable> to the prefix of the headers of the<br>+                    REFER message that you need to access; for example, <literal>X-</literal> to<br>+                     get all headers starting with <literal>X-</literal>. The variable must be set<br>+                    before a call to the application that starts the channel that may eventually<br>+                 transfer back into the dialplan, and must be inherited by that channel, so prefix<br>+                    it with the <literal>_</literal> or <literal>__</literal> when setting (or<br>+                   set it in the pre-dial handler executed on the new channel). To get all headers<br>+                      of the REFER message, set the value to <literal>*</literal>. Headers<br>+                     are returned in the form of a dialplan hash TRANSFER_DATA, and can be accessed<br>+                       with the functions <variable>HASHKEYS(TRANSFER_DATA)</variable> and, e. g.,<br>+                      <variable>HASH(TRANSFER_DATA,X-That-Special-Header)</variable>.</para><br>+                     <para>Please also note that contents of the SDP (an attachment to the<br>                   SIP request) can't be accessed with this function.</para><br>           </description><br>          <see-also><br>@@ -18662,6 +18675,29 @@<br>    return 0;<br> }<br> <br>+static void extract_transferrer_headers(const char *prefix, struct ast_channel *peer, const struct sip_request *req)<br>+{<br>+  struct ast_str *pbxvar = ast_str_alloca(120);<br>+        int i;<br>+<br>+    /* The '*' alone matches all headers. */<br>+     if (strcmp(prefix, "*") == 0) {<br>+            prefix = "";<br>+       }<br>+<br>+ for (i = 0; i < req->headers; i++) {<br>+           const char *header = REQ_OFFSET_TO_STR(req, header[i]);<br>+              if (ast_begins_with(header, prefix)) {<br>+                       int hdrlen = strcspn(header, " \t:");<br>+                      const char *val = ast_skip_blanks(header + hdrlen);<br>+                  if (hdrlen > 0 && *val == ':') {<br>+                          ast_str_set(&pbxvar, -1, "~HASH~TRANSFER_DATA~%.*s~", hdrlen, header);<br>+                         pbx_builtin_setvar_helper(peer, ast_str_buffer(pbxvar), ast_skip_blanks(val + 1));<br>+                   }<br>+            }<br>+    }<br>+}<br>+<br> /*! \brief Call transfer support (the REFER method)<br>  *     Extracts Refer headers into pvt dialog structure<br>  *<br>@@ -18724,10 +18760,18 @@<br> <br>           peer = ast_channel_bridge_peer(owner_ref);<br>            if (peer) {<br>+                  const char *get_xfrdata;<br>+<br>                   pbx_builtin_setvar_helper(peer, "SIPREFERRINGCONTEXT",<br>                              S_OR(transferer->context, NULL));<br>                  pbx_builtin_setvar_helper(peer, "__SIPREFERREDBYHDR",<br>                               S_OR(p_referred_by, NULL));<br>+<br>+                       ast_channel_lock(peer);<br>+                      get_xfrdata = pbx_builtin_getvar_helper(peer, "GET_TRANSFERRER_DATA");<br>+                     if (!ast_strlen_zero(get_xfrdata)) {<br>+                         extract_transferrer_headers(get_xfrdata, peer, req);<br>+                 }<br>                     ast_channel_unlock(peer);<br>             }<br> <br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/6118">change 6118</a>. To unsubscribe, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/6118"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: merged </div>
<div style="display:none"> Gerrit-Change-Id: I73d7a1e95981693bc59aa0d5093c074b555f708e </div>
<div style="display:none"> Gerrit-Change-Number: 6118 </div>
<div style="display:none"> Gerrit-PatchSet: 7 </div>
<div style="display:none"> Gerrit-Owner: Kirill Katsnelson <kkm@smartaction.com> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins2 </div>
<div style="display:none"> Gerrit-Reviewer: Joshua Colp <jcolp@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Kirill Katsnelson <kkm@smartaction.com> </div>
<div style="display:none"> Gerrit-Reviewer: Richard Mudgett <rmudgett@digium.com> </div>