<p>George Joseph <strong>submitted</strong> this change.</p><p><a href="https://gerrit.asterisk.org/c/asterisk/+/17637">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  George Joseph: Looks good to me, approved; Approved for Submit

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">pbx: Add variable substitution API for extensions<br><br>Currently, variable substitution involving dialplan<br>extensions is quite clunky since it entails obtaining<br>the current dialplan location, backing it up, storing<br>the desired variables for substitution on the channel,<br>performing substitution, then restoring the original<br>location.<br><br>In addition to being clunky, things could also go wrong<br>if an async goto were to occur and change the dialplan<br>location during a substitution.<br><br>Fundamentally, there's no reason it needs to be done this<br>way, so new API is added to allow for directly passing in<br>the dialplan location for the purposes of variable<br>substitution so we don't need to mess with the channel<br>information anymore. Existing API is not changed.<br><br>ASTERISK-29745 #close<br><br>Change-Id: I23273bf27fa0efb64a606eebf9aa8e2f41a065e4<br>---<br>M include/asterisk/pbx.h<br>M main/pbx.c<br>M main/pbx_variables.c<br>3 files changed, 57 insertions(+), 1 deletion(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/asterisk/pbx.h b/include/asterisk/pbx.h</span><br><span>index 55a5b9f..f5f0691 100644</span><br><span>--- a/include/asterisk/pbx.h</span><br><span>+++ b/include/asterisk/pbx.h</span><br><span>@@ -1272,6 +1272,22 @@</span><br><span> const char *ast_get_extension_app(struct ast_exten *e);</span><br><span> const char *ast_get_extension_label(struct ast_exten *e);</span><br><span> void *ast_get_extension_app_data(struct ast_exten *e);</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%);">+ * \brief Fill a string buffer with the data at a dialplan extension</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param buf String buffer</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param bufsize Size of buf</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param c Channel</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param context Dialplan context</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param exten Dialplan extension</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param priority Dialplan priority</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \retval -1 Failed to obtain extension data</span><br><span style="color: hsl(120, 100%, 40%);">+ * \retval 0 Successfully obtained extension data</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int ast_get_extension_data(char *buf, int bufsize, struct ast_channel *c,</span><br><span style="color: hsl(120, 100%, 40%);">+     const char *context, const char *exten, int priority);</span><br><span> /*! @} */</span><br><span> </span><br><span> /*! @name Registrar info functions ... */</span><br><span>@@ -1395,6 +1411,11 @@</span><br><span> void pbx_substitute_variables_helper(struct ast_channel *c, const char *cp1, char *cp2, int count);</span><br><span> void pbx_substitute_variables_varshead(struct varshead *headp, const char *cp1, char *cp2, int count);</span><br><span> void pbx_substitute_variables_helper_full(struct ast_channel *c, struct varshead *headp, const char *cp1, char *cp2, int cp2_size, size_t *used);</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%);">+ * \brief Substitutes variables, similar to pbx_substitute_variables_helper_full, but allows passing the context, extension, and priority in.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+void pbx_substitute_variables_helper_full_location(struct ast_channel *c, struct varshead *headp, const char *cp1, char *cp2, int cp2_size, size_t *used, char *context, char *exten, int pri);</span><br><span> /*! @} */</span><br><span> </span><br><span> /*! @name Substitution routines, using dynamic string buffers</span><br><span>diff --git a/main/pbx.c b/main/pbx.c</span><br><span>index 2ed1dd1..07cf8e7 100644</span><br><span>--- a/main/pbx.c</span><br><span>+++ b/main/pbx.c</span><br><span>@@ -8602,6 +8602,27 @@</span><br><span>      return e ? e->data : NULL;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+int ast_get_extension_data(char *buf, int bufsize, struct ast_channel *c,</span><br><span style="color: hsl(120, 100%, 40%);">+     const char *context, const char *exten, int priority)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      struct ast_exten *e;</span><br><span style="color: hsl(120, 100%, 40%);">+  struct pbx_find_info q = { .stacklen = 0 }; /* the rest is set in pbx_find_context */</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_rdlock_contexts();</span><br><span style="color: hsl(120, 100%, 40%);">+        e = pbx_find_extension(c, NULL, &q, context, exten, priority, NULL, "", E_MATCH);</span><br><span style="color: hsl(120, 100%, 40%);">+       if (e) {</span><br><span style="color: hsl(120, 100%, 40%);">+              if (buf) {</span><br><span style="color: hsl(120, 100%, 40%);">+                    const char *tmp = ast_get_extension_app_data(e);</span><br><span style="color: hsl(120, 100%, 40%);">+                      if (tmp) {</span><br><span style="color: hsl(120, 100%, 40%);">+                            ast_copy_string(buf, tmp, bufsize);</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_unlock_contexts();</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%);">+     ast_unlock_contexts();</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> /*</span><br><span>  * Walking functions ...</span><br><span>  */</span><br><span>diff --git a/main/pbx_variables.c b/main/pbx_variables.c</span><br><span>index 91b5bbb..b6c0dd8 100644</span><br><span>--- a/main/pbx_variables.c</span><br><span>+++ b/main/pbx_variables.c</span><br><span>@@ -625,6 +625,11 @@</span><br><span> </span><br><span> void pbx_substitute_variables_helper_full(struct ast_channel *c, struct varshead *headp, const char *cp1, char *cp2, int count, size_t *used)</span><br><span> {</span><br><span style="color: hsl(120, 100%, 40%);">+        pbx_substitute_variables_helper_full_location(c, headp, cp1, cp2, count, used, NULL, NULL, 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%);">+void pbx_substitute_variables_helper_full_location(struct ast_channel *c, struct varshead *headp, const char *cp1, char *cp2, int count, size_t *used, char *context, char *exten, int pri)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span>  /* Substitutes variables into cp2, based on string cp1, cp2 NO LONGER NEEDS TO BE ZEROED OUT!!!!  */</span><br><span>         const char *whereweare;</span><br><span>      const char *orig_cp2 = cp2;</span><br><span>@@ -759,7 +764,16 @@</span><br><span>                           ast_debug(2, "Function %s result is '%s'\n", vars, cp4 ? cp4 : "(null)");</span><br><span>                        } else {</span><br><span>                             /* Retrieve variable value */</span><br><span style="color: hsl(0, 100%, 40%);">-                           pbx_retrieve_variable(c, vars, &cp4, workspace, VAR_BUF_SIZE, headp);</span><br><span style="color: hsl(120, 100%, 40%);">+                             /* For dialplan location, if we were told what to substitute explicitly, use that instead */</span><br><span style="color: hsl(120, 100%, 40%);">+                          if (exten && !strcmp(vars, "EXTEN")) {</span><br><span style="color: hsl(120, 100%, 40%);">+                                      ast_copy_string(workspace, exten, VAR_BUF_SIZE);</span><br><span style="color: hsl(120, 100%, 40%);">+                              } else if (context && !strcmp(vars, "CONTEXT")) {</span><br><span style="color: hsl(120, 100%, 40%);">+                                   ast_copy_string(workspace, context, VAR_BUF_SIZE);</span><br><span style="color: hsl(120, 100%, 40%);">+                            } else if (pri && !strcmp(vars, "PRIORITY")) {</span><br><span style="color: hsl(120, 100%, 40%);">+                                      snprintf(workspace, VAR_BUF_SIZE, "%d", pri);</span><br><span style="color: hsl(120, 100%, 40%);">+                               } else {</span><br><span style="color: hsl(120, 100%, 40%);">+                                      pbx_retrieve_variable(c, vars, &cp4, workspace, VAR_BUF_SIZE, headp);</span><br><span style="color: hsl(120, 100%, 40%);">+                             }</span><br><span>                    }</span><br><span>                    if (cp4) {</span><br><span>                           cp4 = substring(cp4, offset, offset2, workspace, VAR_BUF_SIZE);</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/+/17637">change 17637</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/+/17637"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: 19 </div>
<div style="display:none"> Gerrit-Change-Id: I23273bf27fa0efb64a606eebf9aa8e2f41a065e4 </div>
<div style="display:none"> Gerrit-Change-Number: 17637 </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-MessageType: merged </div>