<p>Friendly Automation <strong>submitted</strong> this change.</p><p><a href="https://gerrit.asterisk.org/c/asterisk/+/19523">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;">app_stack: Print proper exit location for PBXless channels.<br><br>When gosub is executed on channels without a PBX, the context,<br>extension, and priority are initialized to the channel driver's<br>default location for that endpoint. As a result, the last Return<br>will restore this location and the Gosub logs will print out bogus<br>information about our exit point.<br><br>To fix this, on channels that don't have a PBX, the execution<br>location is left intact on the last return if there are no<br>further stack frames left. This allows the correct location<br>to be printed out to the user, rather than the bogus default<br>context.<br><br>ASTERISK-30076 #close<br><br>Change-Id: I1d42a99c9aa9e3708d32718863175158a894e414<br>---<br>M apps/app_stack.c<br>1 file changed, 63 insertions(+), 8 deletions(-)<br><br></pre>
<pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/apps/app_stack.c b/apps/app_stack.c</span><br><span>index a84a45c..70aff6f 100644</span><br><span>--- a/apps/app_stack.c</span><br><span>+++ b/apps/app_stack.c</span><br><span>@@ -377,6 +377,26 @@</span><br><span>  return res;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static int frames_left(struct ast_channel *chan)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     struct ast_datastore *stack_store;</span><br><span style="color: hsl(120, 100%, 40%);">+    struct gosub_stack_list *oldlist;</span><br><span style="color: hsl(120, 100%, 40%);">+     int exists;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_channel_lock(chan);</span><br><span style="color: hsl(120, 100%, 40%);">+       stack_store = ast_channel_datastore_find(chan, &stack_info, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+        if (!stack_store) {</span><br><span style="color: hsl(120, 100%, 40%);">+           ast_channel_unlock(chan);</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%);">+     oldlist = stack_store->data;</span><br><span style="color: hsl(120, 100%, 40%);">+       AST_LIST_LOCK(oldlist);</span><br><span style="color: hsl(120, 100%, 40%);">+       exists = oldlist->first ? 1 : 0;</span><br><span style="color: hsl(120, 100%, 40%);">+   AST_LIST_UNLOCK(oldlist);</span><br><span style="color: hsl(120, 100%, 40%);">+     ast_channel_unlock(chan);</span><br><span style="color: hsl(120, 100%, 40%);">+     return exists;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> static int return_exec(struct ast_channel *chan, const char *data)</span><br><span> {</span><br><span>       struct ast_datastore *stack_store;</span><br><span>@@ -384,6 +404,7 @@</span><br><span>     struct gosub_stack_list *oldlist;</span><br><span>    const char *retval = data;</span><br><span>   int res = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+  int lastframe;</span><br><span> </span><br><span>   ast_channel_lock(chan);</span><br><span>      if (!(stack_store = ast_channel_datastore_find(chan, &stack_info, NULL))) {</span><br><span>@@ -395,6 +416,7 @@</span><br><span>        oldlist = stack_store->data;</span><br><span>      AST_LIST_LOCK(oldlist);</span><br><span>      oldframe = AST_LIST_REMOVE_HEAD(oldlist, entries);</span><br><span style="color: hsl(120, 100%, 40%);">+    lastframe = oldlist->first ? 0 : 1;</span><br><span>       AST_LIST_UNLOCK(oldlist);</span><br><span> </span><br><span>        if (!oldframe) {</span><br><span>@@ -412,12 +434,19 @@</span><br><span>      * what was there before.  Channels that do not have a PBX may</span><br><span>        * not have the context or exten set.</span><br><span>         */</span><br><span style="color: hsl(0, 100%, 40%);">-     ast_channel_context_set(chan, oldframe->context);</span><br><span style="color: hsl(0, 100%, 40%);">-    ast_channel_exten_set(chan, oldframe->extension);</span><br><span style="color: hsl(0, 100%, 40%);">-    if (ast_test_flag(ast_channel_flags(chan), AST_FLAG_IN_AUTOLOOP)) {</span><br><span style="color: hsl(0, 100%, 40%);">-             --oldframe->priority;</span><br><span style="color: hsl(120, 100%, 40%);">+      if (ast_channel_pbx(chan) || !lastframe) {</span><br><span style="color: hsl(120, 100%, 40%);">+            /* If there's no PBX, the "old location" is simply</span><br><span style="color: hsl(120, 100%, 40%);">+               * the configured context for the device, such as</span><br><span style="color: hsl(120, 100%, 40%);">+              * for pre-dial handlers, and restoring this location</span><br><span style="color: hsl(120, 100%, 40%);">+          * is nonsensical. So if no PBX and there are no further</span><br><span style="color: hsl(120, 100%, 40%);">+               * frames, leave the location as it is. */</span><br><span style="color: hsl(120, 100%, 40%);">+            ast_channel_context_set(chan, oldframe->context);</span><br><span style="color: hsl(120, 100%, 40%);">+          ast_channel_exten_set(chan, oldframe->extension);</span><br><span style="color: hsl(120, 100%, 40%);">+          if (ast_test_flag(ast_channel_flags(chan), AST_FLAG_IN_AUTOLOOP)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                   --oldframe->priority;</span><br><span style="color: hsl(120, 100%, 40%);">+              }</span><br><span style="color: hsl(120, 100%, 40%);">+             ast_channel_priority_set(chan, oldframe->priority);</span><br><span>       }</span><br><span style="color: hsl(0, 100%, 40%);">-       ast_channel_priority_set(chan, oldframe->priority);</span><br><span>       ast_set2_flag(ast_channel_flags(chan), oldframe->in_subroutine, AST_FLAG_SUBROUTINE_EXEC);</span><br><span> </span><br><span>    gosub_release_frame(chan, oldframe);</span><br><span>@@ -1068,10 +1097,13 @@</span><br><span>                               ast_channel_priority(chan), ast_channel_name(chan));</span><br><span>                 }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-           /* Did the routine return? */</span><br><span style="color: hsl(0, 100%, 40%);">-           if (ast_channel_priority(chan) == saved_priority</span><br><span style="color: hsl(120, 100%, 40%);">+              /* Did the routine return?</span><br><span style="color: hsl(120, 100%, 40%);">+             * For things like predial where there's no PBX on the channel yet,</span><br><span style="color: hsl(120, 100%, 40%);">+                * the last return leaves the location alone so we can print it out correctly here.</span><br><span style="color: hsl(120, 100%, 40%);">+            * So to ensure we finished properly, make sure there are no frames left in that case. */</span><br><span style="color: hsl(120, 100%, 40%);">+             if ((!ast_channel_pbx(chan) && !frames_left(chan)) || (ast_channel_priority(chan) == saved_priority</span><br><span>                  && !strcmp(ast_channel_context(chan), saved_context)</span><br><span style="color: hsl(0, 100%, 40%);">-                    && !strcmp(ast_channel_exten(chan), saved_exten)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                   && !strcmp(ast_channel_exten(chan), saved_exten))) {</span><br><span>                         ast_verb(3, "%s Internal %s(%s) complete GOSUB_RETVAL=%s\n",</span><br><span>                               ast_channel_name(chan), app_gosub, sub_args,</span><br><span>                                 S_OR(pbx_builtin_getvar_helper(chan, "GOSUB_RETVAL"), ""));</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/c/asterisk/+/19523">change 19523</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/+/19523"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: 20 </div>
<div style="display:none"> Gerrit-Change-Id: I1d42a99c9aa9e3708d32718863175158a894e414 </div>
<div style="display:none"> Gerrit-Change-Number: 19523 </div>
<div style="display:none"> Gerrit-PatchSet: 2 </div>
<div style="display:none"> Gerrit-Owner: N A <asterisk@phreaknet.org> </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>