diff options
-rw-r--r-- | apps/app_dial.c | 7 | ||||
-rw-r--r-- | apps/app_followme.c | 6 | ||||
-rw-r--r-- | channels/chan_local.c | 8 | ||||
-rw-r--r-- | include/asterisk/channel.h | 4 | ||||
-rw-r--r-- | main/features.c | 8 |
5 files changed, 31 insertions, 2 deletions
diff --git a/apps/app_dial.c b/apps/app_dial.c index b21edff3a..bc362132a 100644 --- a/apps/app_dial.c +++ b/apps/app_dial.c @@ -1282,6 +1282,10 @@ static void end_bridge_callback(void *data) ast_channel_unlock(chan); } +static void end_bridge_callback_data_fixup(struct ast_bridge_config *bconfig, struct ast_channel *originator, struct ast_channel *terminator) { + bconfig->end_bridge_callback_data = originator; +} + static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags64 *peerflags, int *continue_exec) { int res = -1; /* default: error */ @@ -1962,7 +1966,8 @@ static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags config.end_bridge_callback = end_bridge_callback; config.end_bridge_callback_data = chan; - + config.end_bridge_callback_data_fixup = end_bridge_callback_data_fixup; + if (moh) { moh = 0; ast_moh_stop(chan); diff --git a/apps/app_followme.c b/apps/app_followme.c index 6728a0fd7..92320fd9c 100644 --- a/apps/app_followme.c +++ b/apps/app_followme.c @@ -892,6 +892,11 @@ static void end_bridge_callback(void *data) ast_channel_unlock(chan); } +static void end_bridge_callback_data_fixup(struct ast_bridge_config *bconfig, struct ast_channel *originator, struct ast_channel *terminator) +{ + bconfig->end_bridge_callback_data = originator; +} + static int app_exec(struct ast_channel *chan, void *data) { struct fm_args targs; @@ -1012,6 +1017,7 @@ static int app_exec(struct ast_channel *chan, void *data) ast_set_flag(&(config.features_caller), AST_FEATURE_AUTOMON); config.end_bridge_callback = end_bridge_callback; config.end_bridge_callback_data = chan; + config.end_bridge_callback_data_fixup = end_bridge_callback_data_fixup; ast_moh_stop(caller); /* Be sure no generators are left on it */ diff --git a/channels/chan_local.c b/channels/chan_local.c index d83be6da3..4187dd876 100644 --- a/channels/chan_local.c +++ b/channels/chan_local.c @@ -287,7 +287,7 @@ static void check_bridge(struct local_pvt *p, int isoutbound) if (!ast_check_hangup(p->chan->_bridge)) { if (!ast_channel_trylock(p->owner)) { if (!ast_check_hangup(p->owner)) { - if(p->owner->monitor && !p->chan->_bridge->monitor) { + if (p->owner->monitor && !p->chan->_bridge->monitor) { /* If a local channel is being monitored, we don't want a masquerade * to cause the monitor to go away. Since the masquerade swaps the monitors, * pre-swapping the monitors before the masquerade will ensure that the monitor @@ -297,6 +297,12 @@ static void check_bridge(struct local_pvt *p, int isoutbound) p->owner->monitor = p->chan->_bridge->monitor; p->chan->_bridge->monitor = tmp; } + if (p->chan->audiohooks) { + struct ast_audiohook_list *audiohooks_swapper; + audiohooks_swapper = p->chan->audiohooks; + p->chan->audiohooks = p->owner->audiohooks; + p->owner->audiohooks = audiohooks_swapper; + } ast_channel_masquerade(p->owner, p->chan->_bridge); ast_set_flag(p, LOCAL_ALREADY_MASQED); } diff --git a/include/asterisk/channel.h b/include/asterisk/channel.h index e34f79dcc..d999d06d3 100644 --- a/include/asterisk/channel.h +++ b/include/asterisk/channel.h @@ -586,6 +586,10 @@ struct ast_bridge_config { unsigned int flags; void (* end_bridge_callback)(void *); /*!< A callback that is called after a bridge attempt */ void *end_bridge_callback_data; /*!< Data passed to the callback */ + /*! If the end_bridge_callback_data refers to a channel which no longer is going to + * exist when the end_bridge_callback is called, then it needs to be fixed up properly + */ + void (*end_bridge_callback_data_fixup)(struct ast_bridge_config *bconfig, struct ast_channel *originator, struct ast_channel *terminator); }; struct chanmon; diff --git a/main/features.c b/main/features.c index 428daa696..b986a06f2 100644 --- a/main/features.c +++ b/main/features.c @@ -1357,6 +1357,10 @@ static int builtin_atxfer(struct ast_channel *chan, struct ast_channel *peer, st tobj->peer = xferchan; tobj->bconfig = *config; + if (tobj->bconfig.end_bridge_callback_data_fixup) { + tobj->bconfig.end_bridge_callback_data_fixup(&tobj->bconfig, tobj->peer, tobj->chan); + } + if (ast_stream_and_wait(newchan, xfersound, "")) ast_log(LOG_WARNING, "Failed to play transfer sound!\n"); ast_bridge_call_thread_launch(tobj); @@ -1454,6 +1458,10 @@ static int builtin_atxfer(struct ast_channel *chan, struct ast_channel *peer, st tobj->peer = xferchan; tobj->bconfig = *config; + if (tobj->bconfig.end_bridge_callback_data_fixup) { + tobj->bconfig.end_bridge_callback_data_fixup(&tobj->bconfig, tobj->peer, tobj->chan); + } + if (ast_stream_and_wait(newchan, xfersound, "")) ast_log(LOG_WARNING, "Failed to play transfer sound!\n"); ast_bridge_call_thread_launch(tobj); |