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 4943727b2..1da9a0d89 100644 --- a/apps/app_dial.c +++ b/apps/app_dial.c @@ -1240,6 +1240,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 */ @@ -1894,7 +1898,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 a4d20f857..f3d2c8d71 100644 --- a/apps/app_followme.c +++ b/apps/app_followme.c @@ -896,6 +896,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; @@ -1017,6 +1022,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 0dbacfe98..77de8570d 100644 --- a/channels/chan_local.c +++ b/channels/chan_local.c @@ -259,7 +259,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 @@ -269,6 +269,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 2352ec116..324fab996 100644 --- a/include/asterisk/channel.h +++ b/include/asterisk/channel.h @@ -622,6 +622,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 4eb059711..79acbcfbd 100644 --- a/main/features.c +++ b/main/features.c @@ -1145,6 +1145,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); @@ -1242,6 +1246,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); |