[asterisk-dev] Scenario where generated ringtone continues after call answered.

Steve Davies davies147 at gmail.com
Fri May 11 09:57:16 CDT 2012

Better for the -dev list? Or -users list? Apologies if I got it wrong.
I am guessing this is a timing issue, though I cannot see why.

Call comes in over SIP, and enters a dialplan a bit like:

exten => _X.,1,Playback(welcome)
same  =>     n,Dial(SIP/100)
same  =>     n,Hangup

The handset SIP/100 has a SIP divert set on it, causing the creation
of a Local/ channel that runs the following:

exten => _X.,1,Playback(redirected)
same  =>     n,Dial(SIP/200)
same  =>     n,Hangup

When the 200 handset is answered, the generated ringing audio back to
the caller does not get stopped, although it is not always audible,
probably due to a timing issue of some kind.

Until the Local/ channels are optimized away, you get:

SIP/caller <--A--> Local/200 at redirected;1 <---> Local/200 at redirected;2
<--C--> SIP/200

What seems to happen is that the use of Playback() causes the ingress
channel to go ANSWERED immediately. Thus, when the Local/ channel
starts up and SIP/200 starts to ring, Asterisk passes the
AST_CONTROL_RINGING signal down to SIP/caller, bridge 'A' is broken,
and a ringtone-generator starts on SIP/caller. You cannot send 180
Ringing on an answered SIP channel, so this is exactly right.

Then when SIP/200 answers, the Dial command responsible for creating
bridge 'C' does a stop-generator call on Local/200 at redirected;2 (a
No-Op) but the call to ast_indicate(chan, -1) is suppressed because
the dial command did not start any ringing itself - It was passed down
the chain from SIP/200 to SIP/caller as a control packet, so app_dial
does not know to send the stop indication.

The following change (against trunk) seems to help. Can someone tell
me if it is utterly stupid?

Index: apps/app_dial.c
--- apps/app_dial.c     (revision 366053)
+++ apps/app_dial.c     (working copy)
@@ -2803,7 +2803,7 @@
                        if (moh) {
                                moh = 0;
-                       } else if (sentringing) {
+                       } else if (sentringing || pa.sentringing) {
                                sentringing = 0;
                                ast_indicate(chan, -1);

This basically does a stop-indication if the destination (winner)
channel started a ringer up at any point, and it was not yet

The issue only occurs if a Local/ channel is in use because app_dial
forces a stop-generator on the channel that called Dial() when the
call is answered (app_dial.c line 2811). With a Local/ channel getting
in the way, the stop-generator has no useful effect.

Many thanks,

More information about the asterisk-dev mailing list