Asterisk Manager Originate Response

Hello,
I am using AMI to generate outbound calls and handling the result using the OriginateResponse. One thing I see which is missing is a reliable “reason” as to why the call failed (if it did). I have generated a NOANSWER and BUSY and they both seem to return a reason of 1. It looks like an ANSWER always returns a 4 though.

Perhaps I am doing something wrong, anyone have any suggestions for determing the reason an outbound call failed?

Thanks,
G

I do not get reliable info from the voip carriers for failed calls either. Sometimes I get busy, sometimes cancel. I have asked them about this and they say that they depend on what they receive as a response and then send it back. I don’t think you are doing anything wrong.

Looking at the manager originate code, it doesn’t appear that the reason is properly set for anything other than an aswer.

I believe this is an ‘issue’ with asterisk and NOT the carriers. I have come up with work-arounds for this problem.

What have you done to work around this?

i am using a combination of AGI scripts and OriginateResponse handlers. The AGI script is my first line of defense for handling the result of an originate, 9 times out of 10 the AGI gets executed and I can capture the DIALSTATUS value. Depending on how a call fails sometimes the AGI doesn’t get called and I need to rely on the OriginateResponse to declare the outdial failed. At this point I simply default the status to ROUTE-FAIL because I have no idea why it actually failed.

One thing to note is that this logic is inside a much bigger application. I am using FastAGI and the asterisk-java package, so I have a central state engine which I use to keep track of things…

g2010:

I’m using Asterisk Java to send originates via AMI to Asterisk. If the channel I originate to is busy, Asterisk Java always returns “No Answer”.

How did you setup your agi script to determine the dial status? Do you have a more complete example that you can share with us? I’m sure there are many of us that are having the same problem.

Thank you for your help! I really appreciate it!

I am doing a couple of things to assist in capturing the true result of a outbound call.

1 - I am originating the call to a Local channel instead of directly to the SIP. This gives me some better control over the handling of post dial results. The OriginateAction to a local would look something like this:

OriginateAction dial = new OriginateAction();
dial.setChannel("Local/DIAL@my_context");
dial.setContext("my_context");
dial.setExten("ANSWERED");
dial.setPriority(1);
dial.setAsync(true);
dial.setCallerId("5555551212");
dial.setVariable("dial_string","SIP/+15555551213@myprovider.com");

2 - The above example Originates a Local channel to the DIAL extension of “my_context”. Now that we are that far along, we need to have some dialplan to support that. It would look something like this:

[my_context]
exten => DIAL,1,Verbose(1,About to perform outdial)
exten => DIAL,n,Dial(${dial_string},30)
exten => DIAL,n,Agi(agi://127.0.0.1/MyAGI.agi?dial_result=${DIALSTATUS})
exten => DIAL,n,Hangup()

exten => ANSWERED,1,Answer()
exten => ANSWERED,n,Agi(agi://127.0.0.1/MyAGI.agi?dial_result=ANSWER)
exten => ANSWERED,n,Hangup()

The above example will automatically jump to the ANSWERED section upon answer, otherwise it will just fall to the next line with the ${DIALSTATUS} variable properly populated with the reason for the failure.

Hope this helps.

Thank you for your quick reply! I really appreciate it!

I implemented what you suggested and I’m running into a problem. When the Dial command fails due to busy, Asterisk never executes the Agi command to report the dial status.

I have 2, 4 port, T1 cards in my machine and I’m having the first card loop back into the 2nd. I’m originating to an extension that plays Congestion. As you can see below, it executes the first Verbose statement fine but not the second. It is also worth noting that I’m running Asterisk Business Edition (Asterisk C 2.1.2)

Here is my extensions.conf:

[local-originate]

exten=>DIAL,1,Verbose(1,About to perform outdial)
exten=>DIAL,n,Dial(${dcc_dial_string},${dcc_timeout})
exten=>DIAL,n,Verbose(1,Dial Complete. Status: ${DIALSTATUS})
exten=>DIAL,n,Agi(agi://127.0.0.1/dccOutbound.agi?dccid=${dccid}&dial_status=${DIALSTATUS})
exten=>DIAL,n,Hangup()

== Parsing ‘/etc/asterisk/manager.conf’: Found
== Manager ‘manager’ logged on from 172.40.4.111
– Executing [DIAL@local-originate:1] Verbose(“Local/DIAL@local-originate-7715,2”, “1|About to perform outdial”) in new stack
About to perform outdial
– Executing [DIAL@local-originate:2] Dial(“Local/DIAL@local-originate-7715,2”, “Zap/g1/700|3”) in new stack
– Requested transfer capability: 0x00 - SPEECH
– Called g1/700
– Executing [700@test-cases:1] Congestion(“Zap/97-1”, “”) in new stack
– Accepting call from ‘’ to ‘700’ on channel 0/1, span 5
– Zap/1-1 is proceeding passing it to Local/DIAL@local-originate-7715,2
– Zap/1-1 is making progress passing it to Local/DIAL@local-originate-7715,2
– Hungup ‘Zap/1-1’
== Spawn extension (local-originate, DIAL, 2) exited non-zero on ‘Local/DIAL@local-originate-7715,2’
– Channel 0/1, span 5 got hangup request, cause 16
== Manager ‘manager’ logged off from 172.40.4.111
== Spawn extension (test-cases, 700, 1) exited non-zero on ‘Zap/97-1’
– Hungup ‘Zap/97-1’

[quote=“g2010”]I am doing a couple of things to assist in capturing the true result of a outbound call.

1 - I am originating the call to a Local channel instead of directly to the SIP. This gives me some better control over the handling of post dial results. The OriginateAction to a local would look something like this:

OriginateAction dial = new OriginateAction();
dial.setChannel("Local/DIAL@my_context");
dial.setContext("my_context");
dial.setExten("ANSWERED");
dial.setPriority(1);
dial.setAsync(true);
dial.setCallerId("5555551212");
dial.setVariable("dial_string","SIP/+15555551213@myprovider.com");

2 - The above example Originates a Local channel to the DIAL extension of “my_context”. Now that we are that far along, we need to have some dialplan to support that. It would look something like this:

[my_context]
exten => DIAL,1,Verbose(1,About to perform outdial)
exten => DIAL,n,Dial(${dial_string},30)
exten => DIAL,n,Agi(agi://127.0.0.1/MyAGI.agi?dial_result=${DIALSTATUS})
exten => DIAL,n,Hangup()

exten => ANSWERED,1,Answer()
exten => ANSWERED,n,Agi(agi://127.0.0.1/MyAGI.agi?dial_result=ANSWER)
exten => ANSWERED,n,Hangup()

The above example will automatically jump to the ANSWERED section upon answer, otherwise it will just fall to the next line with the ${DIALSTATUS} variable properly populated with the reason for the failure.

Hope this helps.[/quote]

Hi,

I’d like to ask you something about the sample code you posted. For what I understand the line MyAGI.agi?dial_result=${DIALSTATUS} means that you’re passing the variable dial_result to the agi which could be written in java? Could you tell me how the java class receives the variable?

Thanks!