aboutsummaryrefslogtreecommitdiffstats
path: root/channels/chan_local.c
diff options
context:
space:
mode:
authormmichelson <mmichelson@f38db490-d61c-443f-a65b-d21fe96a405b>2008-01-21 23:56:40 +0000
committermmichelson <mmichelson@f38db490-d61c-443f-a65b-d21fe96a405b>2008-01-21 23:56:40 +0000
commit54710096e0f620fd800d3579374a3b85326f8357 (patch)
tree493823f0ab87df455ab94f3ab474cc2a5147f01c /channels/chan_local.c
parent9534f137ec06cdb5b1ecbb0c79bc1ee6ee7d2ba2 (diff)
Merged revisions 99426 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r99426 | mmichelson | 2008-01-21 17:55:26 -0600 (Mon, 21 Jan 2008) | 12 lines Fixing an issue wherein monitoring local channels was not possible. During a channel masquerade, the monitors on the two channels involved are swapped. In 99% of the cases this results in the desired effect. However, if monitoring a local channel, this caused the monitor which was on the local channel to get moved onto a channel which is immediately hung up after the masquerade has completed. By swapping the monitors prior to the masquerade, we avoid the problem by tricking the masquerade into placing the monitor back onto the channel where we want it. During the investigation of the issue, the channel's monitor was the only thing that was swapped in such a manner which did not make sense to have done. All other variable swapping made sense. ........ git-svn-id: http://svn.digium.com/svn/asterisk/trunk@99427 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'channels/chan_local.c')
-rw-r--r--channels/chan_local.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/channels/chan_local.c b/channels/chan_local.c
index e42368e32..46051c383 100644
--- a/channels/chan_local.c
+++ b/channels/chan_local.c
@@ -228,6 +228,7 @@ static int local_answer(struct ast_channel *ast)
static void check_bridge(struct local_pvt *p, int isoutbound)
{
+ struct ast_channel_monitor *tmp;
if (ast_test_flag(p, LOCAL_ALREADY_MASQED) || ast_test_flag(p, LOCAL_NO_OPTIMIZATION) || !p->chan || !p->owner || (p->chan->_bridge != ast_bridged_channel(p->chan)))
return;
@@ -245,6 +246,16 @@ 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 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
+ * ends up where it is expected.
+ */
+ tmp = p->owner->monitor;
+ p->owner->monitor = p->chan->_bridge->monitor;
+ p->chan->_bridge->monitor = tmp;
+ }
ast_channel_masquerade(p->owner, p->chan->_bridge);
ast_set_flag(p, LOCAL_ALREADY_MASQED);
}