[asterisk-dev] Attended transfers and MOH

Kevin Harwell kharwell at digium.com
Fri Feb 14 09:53:11 CST 2014

On Fri, 2014-02-14 at 08:26 -0600, Mark Michelson wrote:
> > 
> > Kevin Harwell
> > Thursday, February 13, 2014 5:43 PM
> > Greetings,
> > 
> > There is a bug currently in Asterisk that essentially boils down to
> > MOH
> > not being [re]started for an attended transfered call when the
> > transferor was listening to it.
> > 
> > For example, here is a specific scenario (issue ASTERISK-19499):
> > Alice
> > calls Bob, Bob starts a SIP attended transfer into a confbridge that
> > is
> > set to play music when empty. Alice hears music since she is now on
> > hold and Bob hears music from the confbridge. Bob then completes the
> > transfer and then Alice enters the confbridge, but hears no music.
> > 
> > This situation occurs because during the transfer and channel
> > masquerade
> > the application has no way to know the channel was swapped out.
> > There
> > are a couple of ways to approach a fix for this:
> > 
> > 1) Use a channel fixup in the applications that are affected. A
> > small
> > change to the "do masquerade" function has to be made to get this to
> > work too.
> > 
> > 2) In the relevant channel drivers when an attended transfer occurs
> > check to see if MOH is currently playing on the transferor. If so,
> > once
> > the transfer occurs start MOH on the transferee. This idea was put
> > forth by Olle Johansson (currently implemented in his
> > rana-moh-queue-transfer-1.8 team branch). Albeit a few changes will
> > have to be made in order to use it in the main branches, but the
> > idea
> > will essentially remain.
> > 
> > I like option 2 as it seems to be a bit less intrusive (no changes
> > to
> > masquerades and such). Also in 12+ the logic can be put into the
> > bridge
> > transfer code reducing the changes further.
> > 
> > Thoughts? Ideas? Something I have missed or need to be aware of?
> > 
> > I'll start to move forward with #2 soon and put it up for review.
> > Comments and feedback always welcome.
> > 
> > Thanks!
> > 
> > 
> > 
> > ____________________________________________________________________
> I was thinking about this, and one of the things that the masquerade
> code currently does is to determine if the original channel in a
> masquerade has a "visible indication" on it. A visible indication is
> something that is indicated by a control frame and which the user of
> the channel can actually tell is being indicated. For instance, if an
> AST_CONTROL_RINGING frame is indicated to a channel, the user can hear
> ringing. It is a visible indication. If the ringing channel  is going
> to be part of a masquerade, the masquerade detects that the party has
> a visible indication of AST_CONTROL_RINGING on it. After performing
> all of the rest of the masquerade operation, any visible indication is
> then re-indicated to the masqueraded channel. So in the
> AST_CONTROL_RINGING case, the control frame is re-indicated to the
> channel after the masquerade so that the channel will still hear
> ringing.
> Since masquerades already have code in them to attempt to detect
> user-perceivable state on the channel, I think you should essentially
> do option 2, but do it in the masquerade code instead of in channel
> drivers. Here's a summary of my idea for how to do this:
> 1) Around the same area where the visible indication on the original
> is checked, set a variable if AST_FLAG_MOH is set on original.
> 2) Around the same area where the visible indication is re-indicated
> on the original, if the variable you created for AST_FLAG_MOH is set,
> then call ast_moh_start() on original to get music playing on the
> channel again.
> The advantage to doing it in the masquerade code is that it will work
> for situations other than attended transfers (e.g. AMI redirects) and
> you won't have to put the same code in multiple places. Since
> masquerade code already has a blueprint for how to do this sort of
> thing, there shouldn't be much risk in expanding on it.

I had a similar thought about putting the code in ast_do_masquerade, but
by the time execution gets to that function MOH has been stopped on the
channels, so a check if MOH is playing will always be false (at least as
far as chan_sip functionality goes).

I could look into having the masquerade handle stopping/starting the MOH
as suggested and also remove any places that stop it before that, but
unknown side effects are adding up fast.  At least from my perspective.
Any thoughts on possible problems with that?

More information about the asterisk-dev mailing list