<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>