Skip to content

Commit 12d18b0

Browse files
InterLinked1Friendly Automation
authored and
Friendly Automation
committed
app_stack: Print proper exit location for PBXless channels.
When gosub is executed on channels without a PBX, the context, extension, and priority are initialized to the channel driver's default location for that endpoint. As a result, the last Return will restore this location and the Gosub logs will print out bogus information about our exit point. To fix this, on channels that don't have a PBX, the execution location is left intact on the last return if there are no further stack frames left. This allows the correct location to be printed out to the user, rather than the bogus default context. ASTERISK-30076 #close Change-Id: I1d42a99c9aa9e3708d32718863175158a894e414
1 parent b6670e2 commit 12d18b0

File tree

1 file changed

+40
-8
lines changed

1 file changed

+40
-8
lines changed

apps/app_stack.c

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -377,13 +377,34 @@ static int pop_exec(struct ast_channel *chan, const char *data)
377377
return res;
378378
}
379379

380+
static int frames_left(struct ast_channel *chan)
381+
{
382+
struct ast_datastore *stack_store;
383+
struct gosub_stack_list *oldlist;
384+
int exists;
385+
386+
ast_channel_lock(chan);
387+
stack_store = ast_channel_datastore_find(chan, &stack_info, NULL);
388+
if (!stack_store) {
389+
ast_channel_unlock(chan);
390+
return -1;
391+
}
392+
oldlist = stack_store->data;
393+
AST_LIST_LOCK(oldlist);
394+
exists = oldlist->first ? 1 : 0;
395+
AST_LIST_UNLOCK(oldlist);
396+
ast_channel_unlock(chan);
397+
return exists;
398+
}
399+
380400
static int return_exec(struct ast_channel *chan, const char *data)
381401
{
382402
struct ast_datastore *stack_store;
383403
struct gosub_stack_frame *oldframe;
384404
struct gosub_stack_list *oldlist;
385405
const char *retval = data;
386406
int res = 0;
407+
int lastframe;
387408

388409
ast_channel_lock(chan);
389410
if (!(stack_store = ast_channel_datastore_find(chan, &stack_info, NULL))) {
@@ -395,6 +416,7 @@ static int return_exec(struct ast_channel *chan, const char *data)
395416
oldlist = stack_store->data;
396417
AST_LIST_LOCK(oldlist);
397418
oldframe = AST_LIST_REMOVE_HEAD(oldlist, entries);
419+
lastframe = oldlist->first ? 0 : 1;
398420
AST_LIST_UNLOCK(oldlist);
399421

400422
if (!oldframe) {
@@ -412,12 +434,19 @@ static int return_exec(struct ast_channel *chan, const char *data)
412434
* what was there before. Channels that do not have a PBX may
413435
* not have the context or exten set.
414436
*/
415-
ast_channel_context_set(chan, oldframe->context);
416-
ast_channel_exten_set(chan, oldframe->extension);
417-
if (ast_test_flag(ast_channel_flags(chan), AST_FLAG_IN_AUTOLOOP)) {
418-
--oldframe->priority;
437+
if (ast_channel_pbx(chan) || !lastframe) {
438+
/* If there's no PBX, the "old location" is simply
439+
* the configured context for the device, such as
440+
* for pre-dial handlers, and restoring this location
441+
* is nonsensical. So if no PBX and there are no further
442+
* frames, leave the location as it is. */
443+
ast_channel_context_set(chan, oldframe->context);
444+
ast_channel_exten_set(chan, oldframe->extension);
445+
if (ast_test_flag(ast_channel_flags(chan), AST_FLAG_IN_AUTOLOOP)) {
446+
--oldframe->priority;
447+
}
448+
ast_channel_priority_set(chan, oldframe->priority);
419449
}
420-
ast_channel_priority_set(chan, oldframe->priority);
421450
ast_set2_flag(ast_channel_flags(chan), oldframe->in_subroutine, AST_FLAG_SUBROUTINE_EXEC);
422451

423452
gosub_release_frame(chan, oldframe);
@@ -1068,10 +1097,13 @@ static int gosub_run(struct ast_channel *chan, const char *sub_args, int ignore_
10681097
ast_channel_priority(chan), ast_channel_name(chan));
10691098
}
10701099

1071-
/* Did the routine return? */
1072-
if (ast_channel_priority(chan) == saved_priority
1100+
/* Did the routine return?
1101+
* For things like predial where there's no PBX on the channel yet,
1102+
* the last return leaves the location alone so we can print it out correctly here.
1103+
* So to ensure we finished properly, make sure there are no frames left in that case. */
1104+
if ((!ast_channel_pbx(chan) && !frames_left(chan)) || (ast_channel_priority(chan) == saved_priority
10731105
&& !strcmp(ast_channel_context(chan), saved_context)
1074-
&& !strcmp(ast_channel_exten(chan), saved_exten)) {
1106+
&& !strcmp(ast_channel_exten(chan), saved_exten))) {
10751107
ast_verb(3, "%s Internal %s(%s) complete GOSUB_RETVAL=%s\n",
10761108
ast_channel_name(chan), app_gosub, sub_args,
10771109
S_OR(pbx_builtin_getvar_helper(chan, "GOSUB_RETVAL"), ""));

0 commit comments

Comments
 (0)