<p>Friendly Automation <strong>submitted</strong> this change.</p><p><a href="https://gerrit.asterisk.org/c/asterisk/+/18830">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span></span><br></pre><div style="white-space:pre-wrap">Approvals:
Joshua Colp: Looks good to me, but someone else must approve
George Joseph: Looks good to me, approved
Friendly Automation: Approved for Submit
</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">res_pjsip_header_funcs: Add custom parameter support.<br><br>Adds support for custom URI and header parameters<br>in the From header in PJSIP. Parameters can be<br>both set and read using this function.<br><br>ASTERISK-30150 #close<br><br>Change-Id: Ifb1bc3c512ad5f6faeaebd7817f004a2ecbd6428<br>---<br>A doc/CHANGES-staging/res_pjsip_parameters.txt<br>M res/res_pjsip_header_funcs.c<br>2 files changed, 287 insertions(+), 1 deletion(-)<br><br></pre>
<pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/doc/CHANGES-staging/res_pjsip_parameters.txt b/doc/CHANGES-staging/res_pjsip_parameters.txt</span><br><span>new file mode 100644</span><br><span>index 0000000..c95b43d</span><br><span>--- /dev/null</span><br><span>+++ b/doc/CHANGES-staging/res_pjsip_parameters.txt</span><br><span>@@ -0,0 +1,5 @@</span><br><span style="color: hsl(120, 100%, 40%);">+Subject: res_pjsip_header_funcs</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+The new PJSIP_HEADER_PARAM function now fully supports both</span><br><span style="color: hsl(120, 100%, 40%);">+URI and header parameters. Both reading and writing</span><br><span style="color: hsl(120, 100%, 40%);">+parameters are supported.</span><br><span>diff --git a/res/res_pjsip_header_funcs.c b/res/res_pjsip_header_funcs.c</span><br><span>index cca2b78..8a60e36 100644</span><br><span>--- a/res/res_pjsip_header_funcs.c</span><br><span>+++ b/res/res_pjsip_header_funcs.c</span><br><span>@@ -5,6 +5,7 @@</span><br><span> *</span><br><span> * George Joseph <george.joseph@fairview5.com></span><br><span> * José Lopes <jose.lopes@nfon.com></span><br><span style="color: hsl(120, 100%, 40%);">+ * Naveen Albert <asterisk@phreaknet.org></span><br><span> *</span><br><span> * See http://www.asterisk.org for more information about</span><br><span> * the Asterisk project. Please do not directly contact</span><br><span>@@ -250,7 +251,53 @@</span><br><span> <ref type="function">PJSIP_HEADERS</ref></span><br><span> </see-also></span><br><span> </function></span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(120, 100%, 40%);">+ <function name="PJSIP_HEADER_PARAM" language="en_US"></span><br><span style="color: hsl(120, 100%, 40%);">+ <synopsis></span><br><span style="color: hsl(120, 100%, 40%);">+ Get or set header/URI parameters on a PJSIP channel.</span><br><span style="color: hsl(120, 100%, 40%);">+ </synopsis></span><br><span style="color: hsl(120, 100%, 40%);">+ <syntax></span><br><span style="color: hsl(120, 100%, 40%);">+ <parameter name="header_name" required="true"></span><br><span style="color: hsl(120, 100%, 40%);">+ <para>Header in which parameter should be read or set.</para></span><br><span style="color: hsl(120, 100%, 40%);">+ <para>Currently, the only supported header is <literal>From</literal>.</para></span><br><span style="color: hsl(120, 100%, 40%);">+ </parameter></span><br><span style="color: hsl(120, 100%, 40%);">+ <parameter name="parameter_type" required="true"></span><br><span style="color: hsl(120, 100%, 40%);">+ <para>The type of parameter to get or set.</para></span><br><span style="color: hsl(120, 100%, 40%);">+ <para>Default is header parameter.</para></span><br><span style="color: hsl(120, 100%, 40%);">+ <enumlist></span><br><span style="color: hsl(120, 100%, 40%);">+ <enum name="header"></span><br><span style="color: hsl(120, 100%, 40%);">+ <para>Header parameter.</para></span><br><span style="color: hsl(120, 100%, 40%);">+ </enum></span><br><span style="color: hsl(120, 100%, 40%);">+ <enum name="uri"></span><br><span style="color: hsl(120, 100%, 40%);">+ <para>URI parameter.</para></span><br><span style="color: hsl(120, 100%, 40%);">+ </enum></span><br><span style="color: hsl(120, 100%, 40%);">+ </enumlist></span><br><span style="color: hsl(120, 100%, 40%);">+ </parameter></span><br><span style="color: hsl(120, 100%, 40%);">+ <parameter name="parameter_name" required="true"></span><br><span style="color: hsl(120, 100%, 40%);">+ <para>Name of parameter.</para></span><br><span style="color: hsl(120, 100%, 40%);">+ </parameter></span><br><span style="color: hsl(120, 100%, 40%);">+ </syntax></span><br><span style="color: hsl(120, 100%, 40%);">+ <description></span><br><span style="color: hsl(120, 100%, 40%);">+ <para>PJSIP_HEADER_PARAM allows you to read or set parameters in a SIP header on a</span><br><span style="color: hsl(120, 100%, 40%);">+ PJSIP channel.</para></span><br><span style="color: hsl(120, 100%, 40%);">+ <para>Both URI parameters and header parameters can be read and set using</span><br><span style="color: hsl(120, 100%, 40%);">+ this function. URI parameters appear in the URI (inside the <> in the header)</span><br><span style="color: hsl(120, 100%, 40%);">+ while header parameters appear afterwards.</para></span><br><span style="color: hsl(120, 100%, 40%);">+ <note><para>If you call PJSIP_HEADER_PARAM in a normal dialplan context you'll be</span><br><span style="color: hsl(120, 100%, 40%);">+ operating on the <emphasis>caller's (incoming)</emphasis> channel which</span><br><span style="color: hsl(120, 100%, 40%);">+ may not be what you want. To operate on the <emphasis>callee's (outgoing)</emphasis></span><br><span style="color: hsl(120, 100%, 40%);">+ channel call PJSIP_HEADER_PARAM in a pre-dial handler. </para></note></span><br><span style="color: hsl(120, 100%, 40%);">+ <example title="Set URI parameter in From header on outbound channel"></span><br><span style="color: hsl(120, 100%, 40%);">+ [handler]</span><br><span style="color: hsl(120, 100%, 40%);">+ exten => addheader,1,Set(PJSIP_HEADER_PARAM(From,uri,isup-oli)=27)</span><br><span style="color: hsl(120, 100%, 40%);">+ same => n,Return()</span><br><span style="color: hsl(120, 100%, 40%);">+ [somecontext]</span><br><span style="color: hsl(120, 100%, 40%);">+ exten => 1,1,Dial(PJSIP/${EXTEN},,b(handler^addheader^1))</span><br><span style="color: hsl(120, 100%, 40%);">+ </example></span><br><span style="color: hsl(120, 100%, 40%);">+ <example title="Read URI parameter in From header on inbound channel"></span><br><span style="color: hsl(120, 100%, 40%);">+ same => n,Set(value=${PJSIP_HEADER_PARAM(From,uri,isup-oli)})</span><br><span style="color: hsl(120, 100%, 40%);">+ </example></span><br><span style="color: hsl(120, 100%, 40%);">+ </description></span><br><span style="color: hsl(120, 100%, 40%);">+ </function></span><br><span> ***/</span><br><span> </span><br><span> /*! \brief Linked list for accumulating headers */</span><br><span>@@ -996,6 +1043,223 @@</span><br><span> .incoming_response = incoming_response,</span><br><span> };</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+enum param_type {</span><br><span style="color: hsl(120, 100%, 40%);">+ PARAMETER_HEADER,</span><br><span style="color: hsl(120, 100%, 40%);">+ PARAMETER_URI,</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct param_data {</span><br><span style="color: hsl(120, 100%, 40%);">+ struct ast_sip_channel_pvt *channel;</span><br><span style="color: hsl(120, 100%, 40%);">+ char *header_name;</span><br><span style="color: hsl(120, 100%, 40%);">+ char *param_name;</span><br><span style="color: hsl(120, 100%, 40%);">+ const char *param_value; /* Only used for write */</span><br><span style="color: hsl(120, 100%, 40%);">+ enum param_type paramtype;</span><br><span style="color: hsl(120, 100%, 40%);">+ /* For read function only */</span><br><span style="color: hsl(120, 100%, 40%);">+ char *buf;</span><br><span style="color: hsl(120, 100%, 40%);">+ size_t len;</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int read_param(void *obj)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct param_data *data = obj;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct ast_sip_session *session = data->channel->session;</span><br><span style="color: hsl(120, 100%, 40%);">+ pj_str_t param_name;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ pjsip_fromto_hdr *dlg_info;</span><br><span style="color: hsl(120, 100%, 40%);">+ pjsip_name_addr *dlg_info_name_addr;</span><br><span style="color: hsl(120, 100%, 40%);">+ pjsip_sip_uri *dlg_info_uri;</span><br><span style="color: hsl(120, 100%, 40%);">+ pjsip_param *param;</span><br><span style="color: hsl(120, 100%, 40%);">+ size_t param_len;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ dlg_info = session->inv_session->dlg->remote.info; /* Remote dialog for incoming */</span><br><span style="color: hsl(120, 100%, 40%);">+ dlg_info_name_addr = (pjsip_name_addr *) dlg_info->uri;</span><br><span style="color: hsl(120, 100%, 40%);">+ dlg_info_uri = pjsip_uri_get_uri(dlg_info_name_addr);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ pj_cstr(¶m_name, data->param_name);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (data->paramtype == PARAMETER_URI) { /* URI parameter */</span><br><span style="color: hsl(120, 100%, 40%);">+ param = pjsip_param_find(&dlg_info_uri->other_param, ¶m_name);</span><br><span style="color: hsl(120, 100%, 40%);">+ } else { /* Header parameter */</span><br><span style="color: hsl(120, 100%, 40%);">+ param = pjsip_param_find(&dlg_info->other_param, ¶m_name);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!param) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_debug(1, "No %s parameter found named %s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ data->paramtype == PARAMETER_URI ? "URI" : "header", data->param_name);</span><br><span style="color: hsl(120, 100%, 40%);">+ return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ param_len = pj_strlen(¶m->value);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (param_len >= data->len) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_log(LOG_ERROR, "Buffer is too small for parameter value (%zu > %zu)\n", param_len, data->len);</span><br><span style="color: hsl(120, 100%, 40%);">+ return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_debug(2, "Successfully read %s parameter %s (length %zu)\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ data->paramtype == PARAMETER_URI ? "URI" : "header", data->param_name, param_len);</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_copy_string(data->buf, pj_strbuf(¶m->value), data->len);</span><br><span style="color: hsl(120, 100%, 40%);">+ data->buf[pj_strlen(¶m->value)] = '\0';</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*!</span><br><span style="color: hsl(120, 100%, 40%);">+ * \internal</span><br><span style="color: hsl(120, 100%, 40%);">+ * \brief Implements PJSIP_HEADER_PARAM 'add' by adding the specified parameter.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \note Unlike add_header, we can't add parameters in the outgoing_request callback: that's too late.</span><br><span style="color: hsl(120, 100%, 40%);">+ * That's why we do it here and not in a callback.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+static int add_param(void *obj)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct param_data *data = obj;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct ast_sip_session *session = data->channel->session;</span><br><span style="color: hsl(120, 100%, 40%);">+ pj_pool_t *pool = session->inv_session->dlg->pool;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ pjsip_fromto_hdr *dlg_info;</span><br><span style="color: hsl(120, 100%, 40%);">+ pjsip_name_addr *dlg_info_name_addr;</span><br><span style="color: hsl(120, 100%, 40%);">+ pjsip_sip_uri *dlg_info_uri;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ dlg_info = session->inv_session->dlg->local.info; /* Local for outgoing */</span><br><span style="color: hsl(120, 100%, 40%);">+ dlg_info_name_addr = (pjsip_name_addr *) dlg_info->uri;</span><br><span style="color: hsl(120, 100%, 40%);">+ dlg_info_uri = pjsip_uri_get_uri(dlg_info_name_addr);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!PJSIP_URI_SCHEME_IS_SIP(dlg_info_uri) && !PJSIP_URI_SCHEME_IS_SIPS(dlg_info_uri)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_log(LOG_WARNING, "Non SIP/SIPS URI\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_debug(1, "Adding custom %s param %s = %s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ data->paramtype == PARAMETER_URI ? "URI" : "header", data->param_name, data->param_value);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* This works the same as doing this in set_from_header in res_pjsip_session.c</span><br><span style="color: hsl(120, 100%, 40%);">+ * The way that this maps to pjproject is a little confusing.</span><br><span style="color: hsl(120, 100%, 40%);">+ * Say we have <sip:foo@bar.com;p1=abc;p2=def?h1=qrs&h2=tuv>;o1=foo;o2=bar</span><br><span style="color: hsl(120, 100%, 40%);">+ * p1 and p2 are URI parameters.</span><br><span style="color: hsl(120, 100%, 40%);">+ * (h1 and h2 are URI headers)</span><br><span style="color: hsl(120, 100%, 40%);">+ * o1 and o2 are header parameters (and don't have anything to do with the URI)</span><br><span style="color: hsl(120, 100%, 40%);">+ * In pjproject, other_param is used for adding all custom parameters.</span><br><span style="color: hsl(120, 100%, 40%);">+ * We use the URI for URI stuff, including URI parameters, and the header directly for header parameters.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define param_add(pool, list, pname, pvalue) { \</span><br><span style="color: hsl(120, 100%, 40%);">+ pjsip_param *param; \</span><br><span style="color: hsl(120, 100%, 40%);">+ param = PJ_POOL_ALLOC_T(pool, pjsip_param); \</span><br><span style="color: hsl(120, 100%, 40%);">+ pj_strdup2(pool, ¶m->name, pname); \</span><br><span style="color: hsl(120, 100%, 40%);">+ pj_strdup2(pool, ¶m->value, pvalue); \</span><br><span style="color: hsl(120, 100%, 40%);">+ pj_list_insert_before(list, param); \</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (data->paramtype == PARAMETER_URI) { /* URI parameter */</span><br><span style="color: hsl(120, 100%, 40%);">+ param_add(pool, &dlg_info_uri->other_param, data->param_name, S_OR(data->param_value, ""));</span><br><span style="color: hsl(120, 100%, 40%);">+ } else { /* Header parameter */</span><br><span style="color: hsl(120, 100%, 40%);">+ param_add(pool, &dlg_info->other_param, data->param_name, S_OR(data->param_value, ""));</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int func_read_param(struct ast_channel *chan, const char *function, char *data, char *buf, size_t len)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct ast_sip_channel_pvt *channel = chan ? ast_channel_tech_pvt(chan) : NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct param_data param_data;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ AST_DECLARE_APP_ARGS(args,</span><br><span style="color: hsl(120, 100%, 40%);">+ AST_APP_ARG(header_name);</span><br><span style="color: hsl(120, 100%, 40%);">+ AST_APP_ARG(param_type);</span><br><span style="color: hsl(120, 100%, 40%);">+ AST_APP_ARG(param_name);</span><br><span style="color: hsl(120, 100%, 40%);">+ );</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ AST_STANDARD_APP_ARGS(args, data);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ param_data.channel = channel;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!channel || strncmp(ast_channel_name(chan), "PJSIP/", 6)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_log(LOG_ERROR, "This function requires a PJSIP channel.\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ast_strlen_zero(args.param_type)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_log(AST_LOG_ERROR, "This function requires a parameter type.\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ast_strlen_zero(args.param_name)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_log(AST_LOG_ERROR, "This function requires a parameter name.\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Currently, only From is supported, but this could be extended in the future. */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ast_strlen_zero(args.header_name) || strcasecmp(args.header_name, "From")) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_log(LOG_WARNING, "Only the From header is currently supported\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ param_data.param_name = args.param_name;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!strcasecmp(args.param_type, "header")) {</span><br><span style="color: hsl(120, 100%, 40%);">+ param_data.paramtype = PARAMETER_HEADER;</span><br><span style="color: hsl(120, 100%, 40%);">+ } else if (!strcasecmp(args.param_type, "uri")) {</span><br><span style="color: hsl(120, 100%, 40%);">+ param_data.paramtype = PARAMETER_URI;</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_log(LOG_WARNING, "Parameter type '%s' is invalid: must be 'header' or 'uri'\n", args.param_type);</span><br><span style="color: hsl(120, 100%, 40%);">+ return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ param_data.buf = buf;</span><br><span style="color: hsl(120, 100%, 40%);">+ param_data.len = len;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return ast_sip_push_task_wait_serializer(channel->session->serializer, read_param, ¶m_data);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int func_write_param(struct ast_channel *chan, const char *cmd, char *data, const char *value)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct ast_sip_channel_pvt *channel = chan ? ast_channel_tech_pvt(chan) : NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct param_data param_data;</span><br><span style="color: hsl(120, 100%, 40%);">+ AST_DECLARE_APP_ARGS(args,</span><br><span style="color: hsl(120, 100%, 40%);">+ AST_APP_ARG(header_name);</span><br><span style="color: hsl(120, 100%, 40%);">+ AST_APP_ARG(param_type);</span><br><span style="color: hsl(120, 100%, 40%);">+ AST_APP_ARG(param_name);</span><br><span style="color: hsl(120, 100%, 40%);">+ );</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ AST_STANDARD_APP_ARGS(args, data);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ param_data.channel = channel;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!channel || strncmp(ast_channel_name(chan), "PJSIP/", 6)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_log(LOG_ERROR, "This function requires a PJSIP channel.\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ast_strlen_zero(args.param_type)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_log(AST_LOG_ERROR, "This function requires a parameter type.\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ast_strlen_zero(args.param_name)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_log(AST_LOG_ERROR, "This function requires a parameter name.\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Currently, only From is supported, but this could be extended in the future. */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ast_strlen_zero(args.header_name) || strcasecmp(args.header_name, "From")) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_log(LOG_WARNING, "Only the From header is currently supported\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ param_data.param_name = args.param_name;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!strcasecmp(args.param_type, "header")) {</span><br><span style="color: hsl(120, 100%, 40%);">+ param_data.paramtype = PARAMETER_HEADER;</span><br><span style="color: hsl(120, 100%, 40%);">+ } else if (!strcasecmp(args.param_type, "uri")) {</span><br><span style="color: hsl(120, 100%, 40%);">+ param_data.paramtype = PARAMETER_URI;</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_log(LOG_WARNING, "Parameter type '%s' is invalid: must be 'header' or 'uri'\n", args.param_type);</span><br><span style="color: hsl(120, 100%, 40%);">+ return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ param_data.param_value = value;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return ast_sip_push_task_wait_serializer(channel->session->serializer, add_param, ¶m_data);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static struct ast_custom_function pjsip_header_param_function = {</span><br><span style="color: hsl(120, 100%, 40%);">+ .name = "PJSIP_HEADER_PARAM",</span><br><span style="color: hsl(120, 100%, 40%);">+ .read = func_read_param,</span><br><span style="color: hsl(120, 100%, 40%);">+ .write = func_write_param,</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> static int load_module(void)</span><br><span> {</span><br><span> ast_sip_session_register_supplement(&header_funcs_supplement);</span><br><span>@@ -1003,6 +1267,7 @@</span><br><span> ast_custom_function_register(&pjsip_headers_function);</span><br><span> ast_custom_function_register(&pjsip_response_header_function);</span><br><span> ast_custom_function_register(&pjsip_response_headers_function);</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_custom_function_register(&pjsip_header_param_function);</span><br><span> </span><br><span> return AST_MODULE_LOAD_SUCCESS;</span><br><span> }</span><br><span>@@ -1013,6 +1278,7 @@</span><br><span> ast_custom_function_unregister(&pjsip_headers_function);</span><br><span> ast_custom_function_unregister(&pjsip_response_header_function);</span><br><span> ast_custom_function_unregister(&pjsip_response_headers_function);</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_custom_function_unregister(&pjsip_header_param_function);</span><br><span> ast_sip_session_unregister_supplement(&header_funcs_supplement);</span><br><span> return 0;</span><br><span> }</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/c/asterisk/+/18830">change 18830</a>. To unsubscribe, or for help writing mail filters, 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/c/asterisk/+/18830"/><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-Change-Id: Ifb1bc3c512ad5f6faeaebd7817f004a2ecbd6428 </div>
<div style="display:none"> Gerrit-Change-Number: 18830 </div>
<div style="display:none"> Gerrit-PatchSet: 12 </div>
<div style="display:none"> Gerrit-Owner: N A <asterisk@phreaknet.org> </div>
<div style="display:none"> Gerrit-Reviewer: Benjamin Keith Ford <bford@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Friendly Automation </div>
<div style="display:none"> Gerrit-Reviewer: George Joseph <gjoseph@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Joshua Colp <jcolp@sangoma.com> </div>
<div style="display:none"> Gerrit-Reviewer: Sean Bright <sean@seanbright.com> </div>
<div style="display:none"> Gerrit-CC: Alexei Gradinari <alex2grad@gmail.com> </div>
<div style="display:none"> Gerrit-CC: Stanislav Abramenkov <stas.abramenkov@gmail.com> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>