<p>George Joseph <strong>submitted</strong> this change.</p><p><a href="https://gerrit.asterisk.org/c/asterisk/+/18380">View Change</a></p><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; Approved for Submit

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">func_evalexten: Extension evaluation function.<br><br>This adds the EVAL_EXTEN function, which may be used to retrieve<br>the variable-substituted data at any extension.<br><br>ASTERISK-29486<br><br>Change-Id: Iad81019689674c9f4ac77d235f5d7234adbb1432<br>---<br>A doc/CHANGES-staging/func_evalexten.txt<br>A funcs/func_evalexten.c<br>M include/asterisk/pbx.h<br>M main/pbx.c<br>M main/pbx_variables.c<br>5 files changed, 219 insertions(+), 27 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/doc/CHANGES-staging/func_evalexten.txt b/doc/CHANGES-staging/func_evalexten.txt</span><br><span>new file mode 100644</span><br><span>index 0000000..f912bbe</span><br><span>--- /dev/null</span><br><span>+++ b/doc/CHANGES-staging/func_evalexten.txt</span><br><span>@@ -0,0 +1,4 @@</span><br><span style="color: hsl(120, 100%, 40%);">+Subject: func_evalexten</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+This adds the EVAL_EXTEN function which may be</span><br><span style="color: hsl(120, 100%, 40%);">+used to evaluate data at dialplan extensions.</span><br><span>diff --git a/funcs/func_evalexten.c b/funcs/func_evalexten.c</span><br><span>new file mode 100644</span><br><span>index 0000000..6a7d28b</span><br><span>--- /dev/null</span><br><span>+++ b/funcs/func_evalexten.c</span><br><span>@@ -0,0 +1,147 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * Asterisk -- An open source telephony toolkit.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Copyright (C) 2021, Naveen Albert</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * See http://www.asterisk.org for more information about</span><br><span style="color: hsl(120, 100%, 40%);">+ * the Asterisk project. Please do not directly contact</span><br><span style="color: hsl(120, 100%, 40%);">+ * any of the maintainers of this project for assistance;</span><br><span style="color: hsl(120, 100%, 40%);">+ * the project provides a web site, mailing lists and IRC</span><br><span style="color: hsl(120, 100%, 40%);">+ * channels for your use.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software, distributed under the terms of</span><br><span style="color: hsl(120, 100%, 40%);">+ * the GNU General Public License Version 2. See the LICENSE file</span><br><span style="color: hsl(120, 100%, 40%);">+ * at the top of the source tree.</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%);">+/*! \file</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \brief Dialplan extension evaluation function</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \author Naveen Albert <asterisk@phreaknet.org></span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \ingroup functions</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%);">+/*** MODULEINFO</span><br><span style="color: hsl(120, 100%, 40%);">+ <support_level>extended</support_level></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%);">+#include "asterisk.h"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include "asterisk/module.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "asterisk/channel.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "asterisk/pbx.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "asterisk/utils.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "asterisk/app.h"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*** DOCUMENTATION</span><br><span style="color: hsl(120, 100%, 40%);">+       <function name="EVAL_EXTEN" language="en_US"></span><br><span style="color: hsl(120, 100%, 40%);">+               <synopsis></span><br><span style="color: hsl(120, 100%, 40%);">+                      Evaluates the contents of a dialplan extension and returns it as a string.</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="context" /></span><br><span style="color: hsl(120, 100%, 40%);">+                  <parameter name="extensions" /></span><br><span style="color: hsl(120, 100%, 40%);">+                       <parameter name="priority" required="true" /></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>The EVAL_EXTEN function looks up a dialplan entry by context,extension,priority,</span><br><span style="color: hsl(120, 100%, 40%);">+                  evaluates the contents of a Return statement to resolve any variable or function</span><br><span style="color: hsl(120, 100%, 40%);">+                      references, and returns the result as a string.</para></span><br><span style="color: hsl(120, 100%, 40%);">+                  <para>You can use this function to create simple user-defined lookup tables or</span><br><span style="color: hsl(120, 100%, 40%);">+                  user-defined functions.</para></span><br><span style="color: hsl(120, 100%, 40%);">+                  <example title="Custom dialplan functions"></span><br><span style="color: hsl(120, 100%, 40%);">+                   [call-types]</span><br><span style="color: hsl(120, 100%, 40%);">+                  exten => _1NNN,1,Return(internal)</span><br><span style="color: hsl(120, 100%, 40%);">+                  exten => _NXXNXXXXXX,1,Return(external)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                  [udf]</span><br><span style="color: hsl(120, 100%, 40%);">+                 exten => calleridlen,1,Return(${LEN(${CALLERID(num)})})</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                  [default]</span><br><span style="color: hsl(120, 100%, 40%);">+                     exten => _X!,1,Verbose(Call type ${EVAL_EXTEN(call-types,${EXTEN},1)} - ${EVAL_EXTEN(udf,calleridlen,1)})</span><br><span style="color: hsl(120, 100%, 40%);">+                  </example></span><br><span style="color: hsl(120, 100%, 40%);">+                      <para>Any variables in the evaluated data will be resolved in the context of</span><br><span style="color: hsl(120, 100%, 40%);">+                    that extension. For example, <literal>${EXTEN}</literal> would refer to the</span><br><span style="color: hsl(120, 100%, 40%);">+                       EVAL_EXTEN extension, not the extension in the context invoking the function.</span><br><span style="color: hsl(120, 100%, 40%);">+                 This behavior is similar to other applications, e.g. <literal>Gosub</literal>.</para></span><br><span style="color: hsl(120, 100%, 40%);">+                       <example title="Choosing which prompt to use"></span><br><span style="color: hsl(120, 100%, 40%);">+                        same => n,Read(input,${EVAL_EXTEN(prompts,${CALLERID(num)},1)})</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                  [prompts]</span><br><span style="color: hsl(120, 100%, 40%);">+                     exten => _X!,1,Return(default)</span><br><span style="color: hsl(120, 100%, 40%);">+                     exten => _20X,1,Return(welcome)</span><br><span style="color: hsl(120, 100%, 40%);">+                    exten => _2XX,1,Return(${DB(promptsettings/${EXTEN})})</span><br><span style="color: hsl(120, 100%, 40%);">+                     exten => _3XX,1,Return(${ODBC_MYFUNC(${EXTEN})})</span><br><span style="color: hsl(120, 100%, 40%);">+                   </example></span><br><span style="color: hsl(120, 100%, 40%);">+                      <para>Extensions on which EVAL_EXTEN is invoked are not different from other</span><br><span style="color: hsl(120, 100%, 40%);">+                    extensions. However, the application at that extension is not executed.</span><br><span style="color: hsl(120, 100%, 40%);">+                       Only the application data is parsed and evaluated.</para></span><br><span style="color: hsl(120, 100%, 40%);">+                       <para>A limitation of this function is that the application at the specified</span><br><span style="color: hsl(120, 100%, 40%);">+                    extension isn't actually executed, and thus unlike a Gosub, you can't pass</span><br><span style="color: hsl(120, 100%, 40%);">+                    arguments in the EVAL_EXTEN function.</para></span><br><span style="color: hsl(120, 100%, 40%);">+            </description></span><br><span style="color: hsl(120, 100%, 40%);">+          <see-also></span><br><span style="color: hsl(120, 100%, 40%);">+                      <ref type="function">EVAL</ref></span><br><span style="color: hsl(120, 100%, 40%);">+         </see-also></span><br><span style="color: hsl(120, 100%, 40%);">+     </function></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 eval_exten_read(struct ast_channel *chan, const char *cmd, 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%);">+       char *exten, *pri, *context, *parse;</span><br><span style="color: hsl(120, 100%, 40%);">+  int ipri;</span><br><span style="color: hsl(120, 100%, 40%);">+     char tmpbuf[len];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (ast_strlen_zero(data)) {</span><br><span style="color: hsl(120, 100%, 40%);">+          ast_log(LOG_WARNING, "The EVAL_EXTEN function requires an extension\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%);">+   parse = ast_strdupa(data);</span><br><span style="color: hsl(120, 100%, 40%);">+    /* Split context,exten,pri */</span><br><span style="color: hsl(120, 100%, 40%);">+ context = strsep(&parse, ",");</span><br><span style="color: hsl(120, 100%, 40%);">+  exten = strsep(&parse, ",");</span><br><span style="color: hsl(120, 100%, 40%);">+    pri = strsep(&parse, ",");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    if (pbx_parse_location(chan, &context, &exten, &pri, &ipri, NULL, NULL)) {</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%);">+   if (ast_strlen_zero(exten) || ast_strlen_zero(context)) { /* only lock if we really need to */</span><br><span style="color: hsl(120, 100%, 40%);">+                ast_channel_lock(chan);</span><br><span style="color: hsl(120, 100%, 40%);">+               if (ast_strlen_zero(exten)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                 exten = ast_strdupa(ast_channel_exten(chan));</span><br><span style="color: hsl(120, 100%, 40%);">+         }</span><br><span style="color: hsl(120, 100%, 40%);">+             if (ast_strlen_zero(context)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                       context = ast_strdupa(ast_channel_context(chan));</span><br><span style="color: hsl(120, 100%, 40%);">+             }</span><br><span style="color: hsl(120, 100%, 40%);">+             ast_channel_unlock(chan);</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 (ast_get_extension_data(tmpbuf, len, chan, context, exten, ipri)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                return -1; /* EVAL_EXTEN failed */</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%);">+   pbx_substitute_variables_helper_full_location(chan, (chan) ? ast_channel_varshead(chan) : NULL, tmpbuf, buf, len, NULL, context, exten, ipri);</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 struct ast_custom_function eval_exten_function = {</span><br><span style="color: hsl(120, 100%, 40%);">+     .name = "EVAL_EXTEN",</span><br><span style="color: hsl(120, 100%, 40%);">+       .read = eval_exten_read,</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 unload_module(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     return ast_custom_function_unregister(&eval_exten_function);</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 load_module(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        return ast_custom_function_register(&eval_exten_function);</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_MODULE_INFO_STANDARD_EXTENDED(ASTERISK_GPL_KEY, "Extension evaluation function");</span><br><span>diff --git a/include/asterisk/pbx.h b/include/asterisk/pbx.h</span><br><span>index f5f0691..d531b44 100644</span><br><span>--- a/include/asterisk/pbx.h</span><br><span>+++ b/include/asterisk/pbx.h</span><br><span>@@ -1501,6 +1501,25 @@</span><br><span>  */</span><br><span> int ast_async_goto_if_exists(struct ast_channel *chan, const char *context, const char *exten, int priority);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/*!</span><br><span style="color: hsl(120, 100%, 40%);">+ * \brief Parses a dialplan location into context, extension, priority</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param chan Channel to execute on</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param context Pointer to initial value for context.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param exten Pointer to initial value for exten.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param pri Pointer to initial value for pri</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param ipri Pointer to integer value of priority</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param mode Pointer to mode (or NULL if mode is not used)</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param rest Pointer to buffer to capture rest of parsing (or NULL if not used)</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * strsep should be used to initially populate context, exten, and pri prior</span><br><span style="color: hsl(120, 100%, 40%);">+ * to calling this function. All arguments are modified in place.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \retval 0 success</span><br><span style="color: hsl(120, 100%, 40%);">+ * \retval non-zero failure</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int pbx_parse_location(struct ast_channel *chan, char **context, char **exten, char **pri, int *ipri, int *mode, char *rest);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> struct ast_custom_function* ast_custom_function_find(const char *name);</span><br><span> </span><br><span> /*!</span><br><span>diff --git a/main/pbx.c b/main/pbx.c</span><br><span>index 00c653f..1e08f23 100644</span><br><span>--- a/main/pbx.c</span><br><span>+++ b/main/pbx.c</span><br><span>@@ -8826,6 +8826,47 @@</span><br><span>      return __ast_goto_if_exists(chan, context, exten, priority, 1);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+int pbx_parse_location(struct ast_channel *chan, char **contextp, char **extenp, char **prip, int *ipri, int *mode, char *rest)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  char *context, *exten, *pri;</span><br><span style="color: hsl(120, 100%, 40%);">+  /* do the strsep before here, so we don't have to alloc and free */</span><br><span style="color: hsl(120, 100%, 40%);">+       if (!*extenp) {</span><br><span style="color: hsl(120, 100%, 40%);">+               /* Only a priority in this one */</span><br><span style="color: hsl(120, 100%, 40%);">+             *prip = *contextp;</span><br><span style="color: hsl(120, 100%, 40%);">+            *extenp = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+               *contextp = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+     } else if (!*prip) {</span><br><span style="color: hsl(120, 100%, 40%);">+          /* Only an extension and priority in this one */</span><br><span style="color: hsl(120, 100%, 40%);">+              *prip = *extenp;</span><br><span style="color: hsl(120, 100%, 40%);">+              *extenp = *contextp;</span><br><span style="color: hsl(120, 100%, 40%);">+          *contextp = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+     context = *contextp;</span><br><span style="color: hsl(120, 100%, 40%);">+  exten = *extenp;</span><br><span style="color: hsl(120, 100%, 40%);">+      pri = *prip;</span><br><span style="color: hsl(120, 100%, 40%);">+  if (mode) {</span><br><span style="color: hsl(120, 100%, 40%);">+           if (*pri == '+') {</span><br><span style="color: hsl(120, 100%, 40%);">+                    *mode = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+                    pri++;</span><br><span style="color: hsl(120, 100%, 40%);">+                } else if (*pri == '-') {</span><br><span style="color: hsl(120, 100%, 40%);">+                     *mode = -1;</span><br><span style="color: hsl(120, 100%, 40%);">+                   pri++;</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 ((rest && sscanf(pri, "%30d%1s", ipri, rest) != 1) || sscanf(pri, "%30d", ipri) != 1) {</span><br><span style="color: hsl(120, 100%, 40%);">+                *ipri = ast_findlabel_extension(chan, context ? context : ast_channel_context(chan),</span><br><span style="color: hsl(120, 100%, 40%);">+                  exten ? exten : ast_channel_exten(chan), pri,</span><br><span style="color: hsl(120, 100%, 40%);">+                 S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL));</span><br><span style="color: hsl(120, 100%, 40%);">+               if (*ipri < 1) {</span><br><span style="color: hsl(120, 100%, 40%);">+                   ast_log(LOG_WARNING, "Priority '%s' must be a number > 0, or valid label\n", pri);</span><br><span style="color: hsl(120, 100%, 40%);">+                       return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+            } else if (mode) {</span><br><span style="color: hsl(120, 100%, 40%);">+                    *mode = 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%);">+     return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> static int pbx_parseable_goto(struct ast_channel *chan, const char *goto_string, int async)</span><br><span> {</span><br><span>   char *exten, *pri, *context;</span><br><span>@@ -8842,31 +8883,9 @@</span><br><span>        context = strsep(&stringp, ",");  /* guaranteed non-null */</span><br><span>    exten = strsep(&stringp, ",");</span><br><span>         pri = strsep(&stringp, ",");</span><br><span style="color: hsl(0, 100%, 40%);">-      if (!exten) {   /* Only a priority in this one */</span><br><span style="color: hsl(0, 100%, 40%);">-               pri = context;</span><br><span style="color: hsl(0, 100%, 40%);">-          exten = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-           context = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">- } else if (!pri) {      /* Only an extension and priority in this one */</span><br><span style="color: hsl(0, 100%, 40%);">-                pri = exten;</span><br><span style="color: hsl(0, 100%, 40%);">-            exten = context;</span><br><span style="color: hsl(0, 100%, 40%);">-                context = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-       if (*pri == '+') {</span><br><span style="color: hsl(0, 100%, 40%);">-              mode = 1;</span><br><span style="color: hsl(0, 100%, 40%);">-               pri++;</span><br><span style="color: hsl(0, 100%, 40%);">-  } else if (*pri == '-') {</span><br><span style="color: hsl(0, 100%, 40%);">-               mode = -1;</span><br><span style="color: hsl(0, 100%, 40%);">-              pri++;</span><br><span style="color: hsl(0, 100%, 40%);">-  }</span><br><span style="color: hsl(0, 100%, 40%);">-       if (sscanf(pri, "%30d%1s", &ipri, rest) != 1) {</span><br><span style="color: hsl(0, 100%, 40%);">-           ipri = ast_findlabel_extension(chan, context ? context : ast_channel_context(chan),</span><br><span style="color: hsl(0, 100%, 40%);">-                     exten ? exten : ast_channel_exten(chan), pri,</span><br><span style="color: hsl(0, 100%, 40%);">-                   S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL));</span><br><span style="color: hsl(0, 100%, 40%);">-         if (ipri < 1) {</span><br><span style="color: hsl(0, 100%, 40%);">-                      ast_log(LOG_WARNING, "Priority '%s' must be a number > 0, or valid label\n", pri);</span><br><span style="color: hsl(0, 100%, 40%);">-                 return -1;</span><br><span style="color: hsl(0, 100%, 40%);">-              } else</span><br><span style="color: hsl(0, 100%, 40%);">-                  mode = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (pbx_parse_location(chan, &context, &exten, &pri, &ipri, &mode, rest)) {</span><br><span style="color: hsl(120, 100%, 40%);">+               return -1;</span><br><span>   }</span><br><span>    /* At this point we have a priority and maybe an extension and a context */</span><br><span> </span><br><span>diff --git a/main/pbx_variables.c b/main/pbx_variables.c</span><br><span>index a060bf5..1f78a59 100644</span><br><span>--- a/main/pbx_variables.c</span><br><span>+++ b/main/pbx_variables.c</span><br><span>@@ -736,7 +736,7 @@</span><br><span> </span><br><span>                       /* Substitute if necessary */</span><br><span>                        if (needsub) {</span><br><span style="color: hsl(0, 100%, 40%);">-                          pbx_substitute_variables_helper_full(c, headp, var, ltmp, VAR_BUF_SIZE - 1, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+                            pbx_substitute_variables_helper_full_location(c, headp, var, ltmp, VAR_BUF_SIZE - 1, NULL, context, exten, pri);</span><br><span>                             vars = ltmp;</span><br><span>                         } else {</span><br><span>                             vars = var;</span><br><span>@@ -770,10 +770,13 @@</span><br><span>                          /* For dialplan location, if we were told what to substitute explicitly, use that instead */</span><br><span>                                 if (exten && !strcmp(vars, "EXTEN")) {</span><br><span>                                     ast_copy_string(workspace, exten, VAR_BUF_SIZE);</span><br><span style="color: hsl(120, 100%, 40%);">+                                      cp4 = workspace;</span><br><span>                             } else if (context && !strcmp(vars, "CONTEXT")) {</span><br><span>                                  ast_copy_string(workspace, context, VAR_BUF_SIZE);</span><br><span style="color: hsl(120, 100%, 40%);">+                                    cp4 = workspace;</span><br><span>                             } else if (pri && !strcmp(vars, "PRIORITY")) {</span><br><span>                                     snprintf(workspace, VAR_BUF_SIZE, "%d", pri);</span><br><span style="color: hsl(120, 100%, 40%);">+                                       cp4 = workspace;</span><br><span>                             } else {</span><br><span>                                     pbx_retrieve_variable(c, vars, &cp4, workspace, VAR_BUF_SIZE, headp);</span><br><span>                            }</span><br><span>@@ -829,7 +832,7 @@</span><br><span> </span><br><span>                  /* Substitute if necessary */</span><br><span>                        if (needsub) {</span><br><span style="color: hsl(0, 100%, 40%);">-                          pbx_substitute_variables_helper_full(c, headp, var, ltmp, VAR_BUF_SIZE - 1, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+                            pbx_substitute_variables_helper_full_location(c, headp, var, ltmp, VAR_BUF_SIZE - 1, NULL, context, exten, pri);</span><br><span>                             vars = ltmp;</span><br><span>                         } else {</span><br><span>                             vars = var;</span><br><span></span><br></pre><div style="white-space:pre-wrap"></div><p>To view, visit <a href="https://gerrit.asterisk.org/c/asterisk/+/18380">change 18380</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/+/18380"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: 18 </div>
<div style="display:none"> Gerrit-Change-Id: Iad81019689674c9f4ac77d235f5d7234adbb1432 </div>
<div style="display:none"> Gerrit-Change-Number: 18380 </div>
<div style="display:none"> Gerrit-PatchSet: 2 </div>
<div style="display:none"> Gerrit-Owner: N A <mail@interlinked.x10host.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-MessageType: merged </div>