diff options
-rw-r--r-- | apps/app_dial.c | 5 | ||||
-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-- | res/res_features.c | 4 |
5 files changed, 26 insertions, 1 deletions
diff --git a/apps/app_dial.c b/apps/app_dial.c index 5192217f1..1782e13f1 100644 --- a/apps/app_dial.c +++ b/apps/app_dial.c @@ -857,6 +857,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_flags *peerflags, int *continue_exec) { int res = -1; @@ -1795,6 +1799,7 @@ static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags config.start_sound = start_sound; 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 3de1a4608..fca6facc2 100644 --- a/apps/app_followme.c +++ b/apps/app_followme.c @@ -935,6 +935,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; @@ -1057,6 +1062,7 @@ static int app_exec(struct ast_channel *chan, void *data) 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 d879cb006..cbe4c6f20 100644 --- a/channels/chan_local.c +++ b/channels/chan_local.c @@ -254,7 +254,7 @@ static void check_bridge(struct local_pvt *p, int isoutbound) if (!p->chan->_bridge->_softhangup) { if (!ast_mutex_trylock(&p->owner->lock)) { if (!p->owner->_softhangup) { - 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 @@ -264,6 +264,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 be08873ae..ea4dac2bc 100644 --- a/include/asterisk/channel.h +++ b/include/asterisk/channel.h @@ -542,6 +542,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/res/res_features.c b/res/res_features.c index 816e1630f..a5c3dc9b5 100644 --- a/res/res_features.c +++ b/res/res_features.c @@ -982,6 +982,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, newchan->language, "")) ast_log(LOG_WARNING, "Failed to play transfer sound!\n"); ast_bridge_call_thread_launch(tobj); |