summaryrefslogtreecommitdiff
path: root/main
diff options
context:
space:
mode:
authorJoshua Colp <jcolp@digium.com>2017-11-20 14:30:05 -0600
committerGerrit Code Review <gerrit2@gerrit.digium.api>2017-11-20 14:30:05 -0600
commitda89afc2e20bfaced44482e8fbd1ad0b4603636f (patch)
tree69fd498a6817a51b97072e2bbbce701e27d45a95 /main
parentbef287ccf2f168737250e62daccc2e0ff6d30e59 (diff)
parent0a7bbb068b58482882a81b873825917ac968921d (diff)
Merge "bridge_basic: Ignore answer from transfer target when they've timed out." into 13
Diffstat (limited to 'main')
-rw-r--r--main/bridge_basic.c24
1 files changed, 23 insertions, 1 deletions
diff --git a/main/bridge_basic.c b/main/bridge_basic.c
index b24df0506..ef6d47cfe 100644
--- a/main/bridge_basic.c
+++ b/main/bridge_basic.c
@@ -1549,6 +1549,23 @@ static void stimulate_attended_transfer(struct attended_transfer_properties *pro
ao2_unlock(props);
}
+static void remove_attended_transfer_stimulus(struct attended_transfer_properties *props,
+ enum attended_transfer_stimulus stimulus)
+{
+ struct stimulus_list *list;
+
+ ao2_lock(props);
+ AST_LIST_TRAVERSE_SAFE_BEGIN(&props->stimulus_queue, list, next) {
+ if (list->stimulus == stimulus) {
+ AST_LIST_REMOVE_CURRENT(next);
+ ast_free(list);
+ break;
+ }
+ }
+ AST_LIST_TRAVERSE_SAFE_END;
+ ao2_unlock(props);
+}
+
/*!
* \brief Get a desired transfer party for a bridge the transferer is not in.
*
@@ -2341,6 +2358,10 @@ static enum attended_transfer_state blond_nonfinal_exit(struct attended_transfer
return TRANSFER_RESUME;
case STIMULUS_TIMEOUT:
ast_softhangup(props->recall_target, AST_SOFTHANGUP_EXPLICIT);
+ /* It is possible before we hung them up that they queued up a recall target answer
+ * so we remove it if present as it should not exist.
+ */
+ remove_attended_transfer_stimulus(props, STIMULUS_RECALL_TARGET_ANSWER);
case STIMULUS_RECALL_TARGET_HANGUP:
props->recall_target = ast_channel_unref(props->recall_target);
return TRANSFER_RECALLING;
@@ -2806,7 +2827,8 @@ static struct ast_frame *transfer_target_framehook_cb(struct ast_channel *chan,
if (event == AST_FRAMEHOOK_EVENT_READ &&
frame && frame->frametype == AST_FRAME_CONTROL &&
- frame->subclass.integer == AST_CONTROL_ANSWER) {
+ frame->subclass.integer == AST_CONTROL_ANSWER &&
+ !ast_check_hangup(chan)) {
ast_debug(1, "Detected an answer for recall attempt on attended transfer %p\n", props);
if (props->superstate == SUPERSTATE_TRANSFER) {