summaryrefslogtreecommitdiff
path: root/main/channel.c
diff options
context:
space:
mode:
authorJoshua Colp <jcolp@digium.com>2017-04-30 21:40:16 +0000
committerJoshua Colp <jcolp@digium.com>2017-05-04 16:40:04 -0500
commitc90d81ef5195c71db81ed69782d84ab357787516 (patch)
tree7c71b96d4f31bd93c9d738876d057627e1f92fb0 /main/channel.c
parent7b0e3b92fd49e5fbe406ef74336e164eb3f31b6e (diff)
bridge: Fix returning to dialplan when executing Bridge() from AMI.
When using the Bridge AMI action on the same channel multiple times it was possible for the channel to return to the wrong location in the dialplan if the other party hung up. This happened because the priority of the channel was not preserved across each action invocation and it would fail to move on to the next priority in other cases. This change makes it so that the priority of a channel is preserved when taking control of it from another thread and it is incremented as appropriate such that the priority reflects where the channel should next be executed in the dialplan, not where it may or may not currently be. The Bridge AMI action was also changed to ensure that it too starts the channels at the next location in the dialplan. ASTERISK-24529 Change-Id: I52406669cf64208aef7252a65b63ade31fbf7a5a
Diffstat (limited to 'main/channel.c')
-rw-r--r--main/channel.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/main/channel.c b/main/channel.c
index dbf235499..099e6f65a 100644
--- a/main/channel.c
+++ b/main/channel.c
@@ -10566,6 +10566,7 @@ struct ast_channel *ast_channel_yank(struct ast_channel *yankee)
char *context;
char *name;
int amaflags;
+ int priority;
struct ast_format *readformat;
struct ast_format *writeformat;
} my_vars = { 0, };
@@ -10576,6 +10577,16 @@ struct ast_channel *ast_channel_yank(struct ast_channel *yankee)
my_vars.context = ast_strdupa(ast_channel_context(yankee));
my_vars.name = ast_strdupa(ast_channel_name(yankee));
my_vars.amaflags = ast_channel_amaflags(yankee);
+ my_vars.priority = ast_channel_priority(yankee);
+ /* The priority as returned by ast_channel_yank is where the channel
+ * should go if the dialplan is executed on it. If the channel is
+ * already executing dialplan then the priority currently set is
+ * where it is currently. We increment it so it becomes where it should
+ * execute.
+ */
+ if (ast_test_flag(ast_channel_flags(yankee), AST_FLAG_IN_AUTOLOOP)) {
+ my_vars.priority++;
+ }
my_vars.writeformat = ao2_bump(ast_channel_writeformat(yankee));
my_vars.readformat = ao2_bump(ast_channel_readformat(yankee));
ast_channel_unlock(yankee);
@@ -10595,6 +10606,7 @@ struct ast_channel *ast_channel_yank(struct ast_channel *yankee)
ast_channel_set_writeformat(yanked_chan, my_vars.writeformat);
ao2_cleanup(my_vars.readformat);
ao2_cleanup(my_vars.writeformat);
+ ast_channel_priority_set(yanked_chan, my_vars.priority);
ast_channel_unlock(yanked_chan);