Originate Using Asterisk Local Channels
Mysteries around MASQ and ZOMBIE
Whenever you want to place a call between two extensions in the dialplan you have to use Local channels.
The OriginateAction that you use when placing calls through the Manager API requires a channel name for the first leg. Usually your application has no knowledge of the dialplan details, i.e. it does not know which channel is triggered by an extension (maybe it's a SIP hardphone, an IAX device or a link to another Asterisk server). What you want to do is "place a call between number a and number b" and leave the rest to Asterisk.
Local channels act as a proxy to the real channels mapped to an extension. So to place a call from 1310 to 1299 your Originate looks like:
Channel: Local/1310@from-local Context: from-local Exten: 1310 Priority: 1
instead of
Channel: SIP/1310 Context: from-local Exten: 1399 Priority: 1
There is an article about Local Channels at voip-info.org that covers the basics.
So that's all very nice and looks straight forward. It becomes more interesting if you have a look at what happens under the hood:
A Local channel actually consists of two channels in Asterisk: Local/XXX,1 and Local/XXX,2. The Local/XXX,2 channel traverses the dialplan starting at the context and extension you provided. In our example this is the extension 1310 in from-local. If you watch the CLI or the events triggered you will see:
Set(_ALERT_INFO=<Bellcore-dr1>) Macro(localexten|1310|SIP/1310) Dial(SIP/1310|30|t)
This corresponds to the defintion of 1310 in my dialplan:
[from-local]
exten => 1310,1,Set(_ALERT_INFO=<Bellcore-dr1>)
exten => 1310,n,Macro(localexten,${EXTEN},SIP/${EXTEN})
[macro-localexten]
exten => s,1,Dial(${ARG2},30,t)
exten => s,n,Goto(s-${DIALSTATUS},1)
exten => s-NOANSWER,1,Voicemail(u${ARG1})
exten => s-NOANSWER,n,Hangup
exten => s-BUSY,1,Busy
exten => _s-.,1,Goto(s-NOANSWER,1)
The Dial command triggers an additional channel (SIP/1310). This is the actual channel that is proxied by the Local channel.
The other side of the Local channel, Local/XXX,1, is used for the desination. In our example this is the extension 1299 in from-local. You see similar events for this channel. The actual channel that is triggered for 1299 is an IAX channel to another Asterisk server: IAX2/iax_reucon_net-3.
Now we reach the point where we have four channels set up: The two sides of the Local channel and the two "real" channels SIP/1310 and IAX2/iax_reucon_net. Two channels are now longer needed and will vanish. Before this happens all data of the proxied channel is copied (masqueraded) to Local/XXX,1 so that Local/XXX,1 is renamed to SIP/1310. The "old" SIP/1310 channel is renamed to SIP/1310-0820f718<MASQ> and finally to Local/1310@from-local-1e71,1<ZOMBIE> before it is hung up. Local/XXX,2 is hung up without any renaming.
So in the end you have exactly what you would have expected: Two channels, SIP/1310 and IAX2/iax_reucon_net up and connected.
I have prepared a nice diagram that shows all these steps in detail and helps you understand what happens:
How to deal with the Hangup problem of Local Channel?
My thought has been falling to confusion now because i have tried to many many methods and searched many many websites on google,but still failed.So can you give me some hints:
What we want to achieve is as the effect as jajah:http://www.jajah.com/
That's to say we attempt to setup on a Asterisk server as the follows:
A Web-CallBack Panel for Asterisk Server :
1. Provide a web form for end user fill with phone#1, Phone#2(the authentication is ignored in the demo phase)
2.We can call to phone#1
3.With time delay (optional) call to phone#2
4.Now phone#1 talks with phone#2
The design idea of such callback system,which i reference the idea from your article and so i am very appreciate with you.Beside i referenced the project from:http://trac.asterisk-support.com/dtl/browser,and it's web interface::http://voipcontrol.net/callback/
At present,we have achieved the req: phone#1 can talks with phone#2 successfully.
Step 1:
After two phone nums are input in the web form,the php action page will deal with the submitted data and access the Asterisk by AGI script:
$dialcmd = "Action: Originate\r\nChannel: Local/s@skype-web-callback-dial/n\r\nTimeout: 30000\r\n".
"Context: skype-web-callback-answer\r\nExtension: s\r\nPriority: 1\r\n".
"Variable: __CALLING={$calling}\r\nVariable: __CALLED={$called}\r\n\r\n";
Step 2:
After the step 1,asterisk entered into the dialplan of Local/s@skype-web-callback-dial,2?trigger the caller ,phone#1 and generate the actual Sip Channel? :
[skype-web-callback-dial]
exten => s,1,Set(CALLERID(all)=${CALLED})
exten => s,2,Dial(SIP/${CALLING}@219.238.239.71||gjA(Welcome)L(30000))
exten => s,3,Hangup()
Step 3:
After the caller(phone#1)answered the calling from asterisk in skype-web-callback-dial contex,the Local/s@skype-web-callback-dial,1 would dialed the callee(phone#2) as the Originate in Step 1 showed:Context: skype-web-callback-answer,and the caller(phone#1) would be ringing until the callee answered:
[skype-web-callback-answer]
exten => s,1,Set(CALLERID(all)=${CALLING})
exten => s,2,Dial(SIP/${CALLED}@219.238.239.71||gL(30000))
exten => s,3,Hangup()
Step 4:
And then the Local/s@skype-web-callback-dial,1 trigger the callee and generate the actual Sip Channel,dialing the callee(phone#2 ):
Now what i faced is:
If callee(phone#2 ) answered the incoming call from Local/s@skype-web-callback-dial,1, it's ok,there was no problem of such req.
But:
1.When the callee(phone#2 ) reject to answered the incoming call,that's to say cancelling it,the problem arised:The caller(phone#1)still went on ringing until the tmeout(L(30000)).We all hope in such circomstance,the caller(phone#1) would hangup right now.I have tried several ways but failured.
2.By contraries,when the caller(phone#1) hangup first before the callee(phone#2 ),the bad thing arised: the callee(phone#2 ) went on ringing,but the caller had hangup!!Even if the callee(phone#2 ) answerd,i will be
nothing!!!
3.How to deal with such circomstance as the callee (phone#2 ):NO ANSWER,BUSY and so on.
All of the above i think are related to the chan_local,which is very differnt from the other channel,so can you gives me some hints about the above problem.
Best regards
Golin