<SOLVED> Fall through from an OutBoundRoute to another NOT WORKING

Hi all,

I have just successfully created a trunk in Asterisk with Chan_Mobile, I mean than I am using a bluetooth dongle on my asterisk pc, connected to an old mobile phone and calls work perfectly in and out !

But unfortunatly everything is not so nice…

When the phone looses signal, or if for whichever reason the call does not go through and the trunk replies its unavailability to Asterisk, then the call just drops, and for those outbounds routes that go firt on this trunk, no way to make any call…

So I was wondering… did I miss something ?

mobile.conf is like that :
[adapter]
id=dlink
address=00:0A:84:00:07:37

[Samsung-GT-S5670]
address=6C:83:36:49:8F:B7
port=1
context=from-Samsung-GT-S5670
adapter=dlink
group= 1

My trunk is a custom trunk with only a dial rule like this :
Mobile/Samsung-GT-S5670/$OUTNUM$

and my extensions.conf does include this :

[from-Samsung-GT-S5670]
exten => s,1,Noop(Entering macro-from-Samsung-GT-S5670 with DID = ${DID} and setting to: 3112460066)
exten => s,n,Set(__FROM_DID=3112460066)
exten => s,n,Goto(from-trunk,3112460066,1)
exten => s,h,Hangup

I was thinking, (I am a newbie) , maybe something is missing in the extensions.conf to tell ASterisk not to “Hangup” if the “Goto” the trunk fails, but fallback to the next trunk in the list…

Or maybe the whole extensions.conf section I added is useless for what I need ?

I followed a tutorial to reach this, but please help me solve this last part to allow calls going through that trunk follow the logical order of my outbound rules in case of failure.

Thanks in advance

PS : I edited the title to make it more generic because I found out that I have this problem also with my google voice trunk, but it is much more rare to detect the issue with this trunk as it is almost always working, but if I invert my outbound routes, cut off my internet, and put google voice as first outbound route, the outbound call (that try to go though google) will never fallback to the Chan_mobile trunk), so this is a generic problem of a Trunk fallback. I will add the traces in the next reply.

13:37:49] [[email protected]:30] Dial(“SIP/111-00000001”, “Mobile/Samsung-GT-S5670/3145673046,300,wW”) in new stack
13:37:49] WARNING[27030] chan_mobile.c: Request to call on device Samsung-GT-S5670 which is not connected / already in use.
13:37:49] WARNING[27030] app_dial.c: Unable to create channel of type ‘Mobile’ (cause 44 - Requested channel not available)
13:37:49] VERBOSE[27030] app_dial.c: == Everyone is busy/congested at this time (1:0/0/1)
13:37:49] [[email protected]:31] NoOp(“SIP/111-00000001”, “Dial failed for some reason with DIALSTATUS = CHANUNAVAIL and HANGUPCAUSE = 44”) in new stack
13:37:49] [[email protected]:32] Goto(“SIP/111-00000001”, “s-CHANUNAVAIL,1”) in new stack
13:37:49] VERBOSE[27030] pbx.c: – Goto (macro-dialout-trunk,s-CHANUNAVAIL,1)
13:37:49] [[email protected]:1] Set(“SIP/111-00000001”, “RC=44”) in new stack
13:37:49] [[email protected]:2] Goto(“SIP/111-00000001”, “44,1”) in new stack
13:37:49] VERBOSE[27030] pbx.c: – Goto (macro-dialout-trunk,44,1)
13:37:49] [[email protected]:1] Goto(“SIP/111-00000001”, “continue,1”) in new stack
13:37:49] VERBOSE[27030] pbx.c: – Goto (macro-dialout-trunk,continue,1)
13:37:49] [[email protected]:1] GotoIf(“SIP/111-00000001”, “1?noreport”) in new stack
13:37:49] VERBOSE[27030] pbx.c: – Goto (macro-dialout-trunk,continue,3)
13:37:49] [[email protected]:3] NoOp(“SIP/111-00000001”, “TRUNK Dial failed due to CHANUNAVAIL HANGUPCAUSE: 44 - failing through to other trunks”) in new stack
13:37:49] [[email protected]:4] Set(“SIP/111-00000001”, “CALLERID(number)=111”) in new stack
13:37:49] [[email protected]:7] Macro(“SIP/111-00000001”, “outisbusy,”) in new stack
13:37:49] [[email protected]:1] Progress(“SIP/111-00000001”, “”) in new stack
13:37:49] [[email protected]:2] GotoIf(“SIP/111-00000001”, “0?emergency,1”) in new stack
13:37:49] [[email protected]:3] GotoIf(“SIP/111-00000001”, “0?intracompany,1”) in new stack
13:37:49] [[email protected]:4] Playback(“SIP/111-00000001”, “all-circuits-busy-now&pls-try-call-later, noanswer”) in new stack
13:37:49] VERBOSE[27030] file.c: – <SIP/111-00000001> Playing ‘all-circuits-busy-now.g729’ (language ‘en’)
13:37:49] VERBOSE[27031] app_mixmonitor.c: == Begin MixMonitor Recording SIP/111-00000001
13:37:51] VERBOSE[27030] file.c: – <SIP/111-00000001> Playing ‘pls-try-call-later.ulaw’ (language ‘en’)
13:37:53] [[email protected]:5] Congestion(“SIP/111-00000001”, “20”) in new stack
13:37:53] WARNING[27030] channel.c: Prodding channel ‘SIP/111-00000001’ failed

Well, if my question is stupid please say so…
but I would really apreciate all help, even to tell me that there is not enough info.

I’ve been following with curiosity.

Only thing that looks strange to me is this:
exten => s,h,Hangup
Isn’t that alternative syntax for creating a label ‘h’ in extension ‘s’?

Shouldn’t that be like this?
exten => h,Hangup()
Although you only reach ‘h’ by Hangup(), so the call should be superfluous.

Otherwise it would always hangup, not only on extension ‘h’.

exten => s,1,Set(DIAL_TRUNK=${ARG1})
exten => s,n,GosubIf($[$["${ARG3}" != “”] & $["${DB(AMPUSER/${AMPUSER}/pinless)}" != “NOPASSWD”]]?sub-pincheck,s,1())
exten => s,n,GotoIf($[“x${OUTDISABLE_${DIAL_TRUNK}}” = “xon”]?disabletrunk,1)
exten => s,n,Set(DIAL_NUMBER=${ARG2})
exten => s,n,Set(DIAL_TRUNK_OPTIONS=${DIAL_OPTIONS})
exten => s,n,Set(OUTBOUND_GROUP=OUT_${DIAL_TRUNK})
exten => s,n,GotoIf($["${OUTMAXCHANS_${DIAL_TRUNK}}foo" = “foo”]?nomax)
exten => s,n,GotoIf($[ ${GROUP_COUNT(OUT_${DIAL_TRUNK})} >= ${OUTMAXCHANS_${DIAL_TRUNK}} ]?chanfull)
exten => s,n(nomax),GotoIf($["${INTRACOMPANYROUTE}" = “YES”]?skipoutcid)
exten => s,n,Set(DIAL_TRUNK_OPTIONS=${TRUNK_OPTIONS})
exten => s,n,Macro(outbound-callerid,${DIAL_TRUNK})
exten => s,n(skipoutcid),GosubIf($["${PREFIX_TRUNK_${DIAL_TRUNK}}" != “”]?sub-flp-${DIAL_TRUNK},s,1())
exten => s,n,Set(OUTNUM=${OUTPREFIX_${DIAL_TRUNK}}${DIAL_NUMBER})
exten => s,n,Set(custom=${CUT(OUT_${DIAL_TRUNK},:,1)})
exten => s,n,ExecIf($["${MOHCLASS}"!=“default” & “${MOHCLASS}”!="" & “${FORCE_CONFIRM}”="" ]?Set(DIAL_TRUNK_OPTIONS=M(setmusic^${MOHCLASS})${D$
exten => s,n,ExecIf($["${FORCE_CONFIRM}"!="" ]?Set(DIAL_TRUNK_OPTIONS=${DIAL_TRUNK_OPTIONS}M(confirm)))
exten => s,n(gocall),Macro(dialout-trunk-predial-hook,)
exten => s,n,GotoIf($["${PREDIAL_HOOK_RET}" = “BYPASS”]?bypass,1)
exten => s,n,ExecIf($["${DB(AMPUSER/${AMPUSER}/cidname)}" != “”]?Set(CONNECTEDLINE(num,i)=${DIAL_NUMBER}))
exten => s,n,ExecIf($["${DB(AMPUSER/${AMPUSER}/cidname)}" != “”]?Set(CONNECTEDLINE(name,i)=CID:${CALLERID(number)}))
exten => s,n,GotoIf($["${custom}" = “AMP”]?customtrunk)
exten => s,n,Dial(${OUT_${DIAL_TRUNK}}/${OUTNUM},300,${DIAL_TRUNK_OPTIONS})
exten => s,n,Noop(Dial failed for some reason with DIALSTATUS = ${DIALSTATUS} and HANGUPCAUSE = ${HANGUPCAUSE})
exten => s,n,Goto(s-${DIALSTATUS},1)
exten => s,n(customtrunk),Set(pre_num=${CUT(OUT_${DIAL_TRUNK},$,1)})
exten => s,n,Set(the_num=${CUT(OUT_${DIAL_TRUNK},$,2)})
exten => s,n,Set(post_num=${CUT(OUT_${DIAL_TRUNK},$,3)})
exten => s,n,GotoIf($["${the_num}" = “OUTNUM”]?outnum:skipoutnum)
exten => s,n(outnum),Set(the_num=${OUTNUM})
exten => s,n(skipoutnum),Dial(${pre_num:4}${the_num}${post_num},300,${DIAL_TRUNK_OPTIONS})
exten => s,n,Noop(Dial failed for some reason with DIALSTATUS = ${DIALSTATUS} and HANGUPCAUSE = ${HANGUPCAUSE})
exten => s,n,Goto(s-${DIALSTATUS},1)
exten => s,n(chanfull),Noop(max channels used up)

exten => s-BUSY,1,Noop(Dial failed due to trunk reporting BUSY - giving up)
exten => s-BUSY,n,Playtones(busy)
exten => s-BUSY,n,Busy(20)
exten => s-ANSWER,1,Noop(Call successfully answered - Hanging up now)
exten => s-ANSWER,n,Macro(hangupcall,)

exten => s-NOANSWER,1,Noop(Dial failed due to trunk reporting NOANSWER - giving up)
exten => s-NOANSWER,n,Progress
exten => s-NOANSWER,n,Playback(number-not-answering,noanswer)
exten => s-NOANSWER,n,Congestion(20)

exten => s-INVALIDNMBR,1,Noop(Dial failed due to trunk reporting Address Incomplete - giving up)
exten => s-INVALIDNMBR,n,Progress
exten => s-INVALIDNMBR,n,Playback(ss-noservice,noanswer)
exten => s-INVALIDNMBR,n,Busy(20)

exten => s-CHANGED,1,Noop(Dial failed due to trunk reporting Number Changed - giving up)
exten => s-CHANGED,n,Playtones(busy)
exten => s-CHANGED,n,Busy(20)

exten => _s-.,1,Set(RC=${IF($[${ISNULL(${HANGUPCAUSE})}]?0:${HANGUPCAUSE})})
exten => _s-.,n,Goto(${RC},1)

exten => 17,1,Goto(s-BUSY,1)

exten => 18,1,Goto(s-NOANSWER,1)

exten => 22,1,Goto(s-CHANGED,1)

exten => 23,1,Goto(s-CHANGED,1)

exten => 28,1,Goto(s-INVALIDNMBR,1)

exten => _X,1,Goto(continue,1)

exten => X.,1,Goto(continue,1)
exten => continue,1,GotoIf($["${OUTFAIL
${ARG1}}" = “”]?noreport)
exten => continue,n,AGI(${OUTFAIL_${ARG1}})
exten => continue,n(noreport),Noop(TRUNK Dial failed due to ${DIALSTATUS} HANGUPCAUSE: ${HANGUPCAUSE} - failing through to other trunks)
exten => continue,n,Set(CALLERID(number)=${AMPUSER})

exten => disabletrunk,1,Noop(TRUNK: ${OUT_${DIAL_TRUNK}} DISABLED - falling through to next trunk)

exten => bypass,1,Noop(TRUNK: ${OUT_${DIAL_TRUNK}} BYPASSING because dialout-trunk-predial-hook)

exten => h,1,Macro(hangupcall,)

I am trying to generate a trunk fall back.
So I limited some trunks to only one channel.
But I detected that the “Maximum Channels” doesn’t work as I epxected.
I configured “Maximum Channels” = 1 into various trunks but if I make a call for which the primary outbound routes uses a trunk with this setting to 1, the next call supposed to go first through that trunk get the message “all circuits are busy” instead of falling back to the Google voice or any other trunk I also configured and that are available, without limitation of channels.
So the trunk fall back issue I have is more general.
I am lost…

but I tried both, and this doesn’t change a thing. Still no fall through…

this issue is really starting to impact us…
any idea, or track i could follow ?

What is the purpose of the Hangup() ?

It seems counterintuitive to me, since that would mean that the call is, well, being hung up on.
Maybe you could try looking at some FreePBX generated code for trunk failover and compare that to yours in order to determine if you’re missing something?

I cannot tell you why the hangup() is here because I followed a tutorial with limited knowlegde of Asterisk, but anyway the failover is not only failing with this chan_mobile trunk, but as I said, even on a normal SIP trunk, if I set the max channel to 1, then the second outbound call will not use the next available trunk.
Thanks for giving me investigation ideas, I will try without this hangup() line, and will also try to look another Freepbx generated code to see the difference with mine.
I am using Asterisk 1.8.20.1 and freepbx 2.10, updated.

PS: I remover the hangup() line in the extensions-custom.conf and still, no trunk failover

I think very few people have done this, hence why you don’t get many replies here with this.

By trunk failover, do you mean “try next available trunk” in the Trunk config or the trunk priority in the outbound route section?
What happens if you select the trunks in the order you want to try them in a single outbound route?

reading in detail the process that leads to the faillure, i can see that in the “continue” section of the macro there is this line :
exten => continue,n,AGI(${OUTFAIL_${ARG1}})
This line is skipped because of test done juste before, would this line be where there is an attempt to go through another trunk ?
In which case the error would be in the test done just before…

yes thats what i mean, there is no attempt of the next available trunk.

What do you mean : “What happens if you select the trunks in the order you want to try them in a single outbound route?” : Because for what I saw in FreePBX an outbound route can only hold one trunk. Am I wrong ? Edit : Yes I am wrong, good Idea I will try this !

I have outbound routes based on the type of number called (land line. mobile, toll free…) and I have a catch all route, in case all the other outbound routes are busy. This last route is never used… because either the number called first hit a route that uses a busy trunk, in which case the call is not done and I get the message “all circuits are busy” or its first route uses an available trunk, in which case the call works.

That way it works, within a given route is goes from trunk to trunk, but then I have an issue which is that the manipulation of the number are not the same trunk per trunk, because some trunk need the country code added and other not… thats why I created various routes.

Ok, so I created much less outbound routes, one per destination type I would like to reach, in each route all the trunks in the good order.
THEN I added in each trunk specific dialed number manipulation paterns so that depending the route that is sending the DIALED number this number is corrected to right format of each trunk.
And it worked as expected.
But what a PAIN, I have to manupulate the DIALED numbers twice !
Why no simply try a next outbound route when all the trunks of a first one is busy ??
Ok, namezero111111 I owe you one !

I’m glad this worked for you!
As for the manipulating the dialed numbers:
Normally, dial patterns in outbound routes are only there to determine which numbers should match that route, not format it for the trunk.
Trunk dial patterns are there to format the number so that the trunk will accept it. It’s a very fine line, but once understood can help you really design routes and trunks well!
This article here attempts to explain the difference:
http://www.freepbx.org/support/documentation/howtos/howto-route-dial-patterns-and-trunk-dial-rules

It’s subtle, but if designed correctly, you should be able to add a second trunk to an outbound route and it’ll work with no further tampering with dial patterns anywhere.

Very well.
See me port below for an explanation of dial patterns in outbound routes vs. trunks.
So if you had an outbound route for landline, it should attempt to match only landline numbers, not format them in any way for a specific trunk.
Then, each trunk should format the number in the way as required by the peer.