Is it possible...alternate trunks PSTN

Hello,

I have a trixbox up and running with 2 pstn trunks and freepbx of course. I was wondering if I can edit some config file to be able to balance the outbound calls alternating each of the trunks. As currently I have notice that all the calls are been made by trunk 1 and 2 is only used as last resource if trunk 1 is being used at that moment. I want to make one call by trunk 1 the next call by trunk 2.

So in conclusion is it possible…any advices.

Thanks a lot

Yes.
You can use an agi or in the dialplan like this:

Add in extensions_custom.conf

[distribute-pstn-trunks]
;pstn trunk are number 2 and 3
exten => _0XXXXXXXXX,1,Set(COUNT=${DB(test/count)})
;increment
exten => _0XXXXXXXXX,n,SetVar(COUNT=$[${COUNT} + 1])
exten => _0XXXXXXXXX,n,SetVar(COUNT=${IF($[ ${COUNT} = 4]?2:${COUNT})})
exten => _0XXXXXXXXX,n,Set(DB(test/count)=${COUNT})
exten => _0XXXXXXXXX,n,NoOp(Number dialed is ${EXTEN} by trunk pstn ${COUNT})
exten => _0XXXXXXXXX,n,Macro(dialout-trunk,${COUNT},${EXTEN},,)
exten => _0XXXXXXXXX,n,Macro(outisbusy,)

Adapt it to your config.

Then create a custom trunk : Local/$OUTNUM$@distribute-pstn-trunks

Use the custom trunk in your outbound routes…
Done. :slight_smile:
Fastm3.

Sorry to ask you to help me again , but I´m kind of impaired in this things and didn´t get you how to customize it. So I was wondering if you can help me to adapt the config correctly.
My pstn lines are attached to channels 1 and 2 of my zaptel pci card, I have another sip trunk but it is used only for the international calling so it should be left outside the distribute script.

Maybe with that you can help me kind of more directly.

Thanks again for such a quick reply and help.

Well I have tried to do it myself but couldn´t…here is what I added to the extensions_custom.conf at the end:

[distribute-pstn-trunks]
;pstn trunk are number 1 and 2
exten => _0XXXXXXXXX,1,Set(COUNT=${DB(test/count)})
;increment
exten => _0XXXXXXXXX,n,SetVar(COUNT=$[${COUNT} + 1])
exten => _0XXXXXXXXX,n,SetVar(COUNT=${IF($[ ${COUNT} = 3]?1:${COUNT})})
exten => _0XXXXXXXXX,n,Set(DB(test/count)=${COUNT})
exten => _0XXXXXXXXX,n,NoOp(Number dialed is ${EXTEN} by trunk pstn ${COUNT})
exten => _0XXXXXXXXX,n,Macro(dialout-trunk,${COUNT},${EXTEN},)
exten => _0XXXXXXXXX,n,Macro(outisbusy,)

And I created a custom trunk only setting at the Custom Dial String: Local/$OUTNUM$@distribute-pstn-trunks

Then created an outbound route with a dial pattern of 8|. using the new Trunk Local/$OUTNUM$@

Tested a call but got a reply that al circuits are busy now…so something is wrong at the script I think… I just edited the numbers as I though will be correct for me…

The dialout-trunk macro needs the number associated to the trunk. You will find it in extensions_additionnal.conf. This is not linked to the channel used in your zaptel card.
If you find something like that: OUT_3 = ZAP/g0
It means that ZAP/g0 is number 3. 3 will be the parameter needed for the dialout-trunk macro.
It could be 5 or 10 or any number depending on your config.

2 trunks may be needed in the outbound route because the chosen trunk can be busy. You can fix that in the distribute-pstn-trunks context or in the outbound route. You could indeed get all-circuit busy even if one of them ( not chosen ) is free.
Hope these comments helps.
Fastm3.

Well thanks for the guide I had been doing some more test and research and found out that the script should be like the following I believe according to my trunks numbers and that I want to be used in a match all outgoing calls format:

[quote][distribute-pstn-trunks]
;pstn trunk are number 1 and 2
exten => _.,1,Set(COUNT=${DB(test/count)})
;increment
exten => _.,n,SetVar(COUNT=$[${COUNT} + 1])
exten => _.,n,SetVar(COUNT=${IF($[ ${COUNT} = 3]?1:${COUNT})})
exten => _.,n,Set(DB(test/count)=${COUNT})
exten => _.,n,NoOp(Number dialed is ${EXTEN} by trunk pstn ${COUNT})
exten => _.,n,Macro(dialout-trunk,${COUNT},${EXTEN},)
exten => _.,n,Macro(outisbusy,)[/quote]

I set the dot as I found that this should match all outside calls…and set trunks 1 and max 3 till reset to 1 so in use 1 & 2 only… Also I setup a custom trunks as said before with only “Local/$OUTNUM$@distribute-free-trunks” and setup an outbound route that use this trunk with a dial pattern of “8|.” However it stills when dialed out as 82417908 a reply that all circuits are busy even all are free. I believe the script is now correct as in extensions_additional.conf I have the following (showed below) from where I got the trunk numbers 1 and 2 However, please help me checking and correcting any mistake I have done…Thanks in advance.

Should work. Check that all parameters are correct. Have a look to the output in cli. You should find out why the Macro(dialout-trunk,1 or 2 ,${EXTEN},) fails.
Fastm3.

Thanks for reviewing it…here is the output of the CLI but stills not knowing what is going on as I not a pro at all in this…Hope you could give me a hand on this one…:

[php]
Connected to Asterisk 1.4.20-1 RPM by [email protected] currently running on trixbox1 (pid = 2704)
Verbosity is at least 3
– Starting simple switch on ‘Zap/3-1’
– Executing [82811656@from-internal:1] Macro(“Zap/3-1”, “user-callerid|SKIPTTL|”) in new stack
– Executing [s@macro-user-callerid:1] NoOp(“Zap/3-1”, “user-callerid: device 202”) in new stack
– Executing [s@macro-user-callerid:2] Set(“Zap/3-1”, “AMPUSER=202”) in new stack
– Executing [s@macro-user-callerid:3] GotoIf(“Zap/3-1”, “0?report”) in new stack
– Executing [s@macro-user-callerid:4] ExecIf(“Zap/3-1”, “1|Set|REALCALLERIDNUM=202”) in new stack
– Executing [s@macro-user-callerid:5] NoOp(“Zap/3-1”, “REALCALLERIDNUM is 202”) in new stack
– Executing [s@macro-user-callerid:6] Set(“Zap/3-1”, “AMPUSER=202”) in new stack
– Executing [s@macro-user-callerid:7] Set(“Zap/3-1”, “AMPUSERCIDNAME=CentralDect”) in new stack
– Executing [s@macro-user-callerid:8] GotoIf(“Zap/3-1”, “0?report”) in new stack
– Executing [s@macro-user-callerid:9] Set(“Zap/3-1”, “AMPUSERCID=202”) in new stack
– Executing [s@macro-user-callerid:10] Set(“Zap/3-1”, “CALLERID(all)=“CentralDect” <202>”) in new stack
– Executing [s@macro-user-callerid:11] Set(“Zap/3-1”, “REALCALLERIDNUM=202”) in new stack
– Executing [s@macro-user-callerid:12] ExecIf(“Zap/3-1”, “0|Set|CHANNEL(language)=”) in new stack
– Executing [s@macro-user-callerid:13] NoOp(“Zap/3-1”, “TTL: ARG1: SKIPTTL”) in new stack
– Executing [s@macro-user-callerid:14] GotoIf(“Zap/3-1”, “1?continue”) in new stack
– Goto (macro-user-callerid,s,23)
– Executing [s@macro-user-callerid:23] NoOp(“Zap/3-1”, “Using CallerID “CentralDect” <202>”) in new stack
– Executing [82811656@from-internal:2] Set(“Zap/3-1”, “_NODEST=”) in new stack
– Executing [82811656@from-internal:3] Macro(“Zap/3-1”, “record-enable|202|OUT|”) in new stack
– Executing [s@macro-record-enable:1] GotoIf(“Zap/3-1”, “0?2:4”) in new stack
– Goto (macro-record-enable,s,4)
– Executing [s@macro-record-enable:4] AGI(“Zap/3-1”, “recordingcheck|20080619-164646|1213912000.23”) in new stack
– Launched AGI Script /var/lib/asterisk/agi-bin/recordingcheck
recordingcheck|20080619-164646|1213912000.23: Outbound recording enabled.
recordingcheck|20080619-164646|1213912000.23: CALLFILENAME=OUT202-20080619-164646-1213912000.23
– AGI Script recordingcheck completed, returning 0
– Executing [s@macro-record-enable:999] MixMonitor(“Zap/3-1”, “OUT202-20080619-164646-1213912000.23.wav”) in new stack
– Executing [82811656@from-internal:4] Macro(“Zap/3-1”, “dialout-trunk|4|2811656||”) in new stack
– Executing [s@macro-dialout-trunk:1] Set(“Zap/3-1”, “DIAL_TRUNK=4”) in new stack
– Executing [s@macro-dialout-trunk:2] ExecIf(“Zap/3-1”, “0|Authenticate|”) in new stack
– Executing [s@macro-dialout-trunk:3] GotoIf(“Zap/3-1”, “0?disabletrunk|1”) in new stack
– Executing [s@macro-dialout-trunk:4] Set(“Zap/3-1”, “DIAL_NUMBER=2811656”) in new stack
– Executing [s@macro-dialout-trunk:5] Set(“Zap/3-1”, “DIAL_TRUNK_OPTIONS=trT”) in new stack
– Executing [s@macro-dialout-trunk:6] Set(“Zap/3-1”, “GROUP()=OUT_4”) in new stack
– Executing [s@macro-dialout-trunk:7] GotoIf(“Zap/3-1”, “1?nomax”) in new stack
– Goto (macro-dialout-trunk,s,9)
– Executing [s@macro-dialout-trunk:9] GotoIf(“Zap/3-1”, “0?skipoutcid”) in new stack
– Executing [s@macro-dialout-trunk:10] Set(“Zap/3-1”, “DIAL_TRUNK_OPTIONS=tT”) in new stack
– Executing [s@macro-dialout-trunk:11] Macro(“Zap/3-1”, “outbound-callerid|4”) in new stack
– Executing [s@macro-outbound-callerid:1] GotoIf(“Zap/3-1”, “1?start”) in new stack
– Goto (macro-outbound-callerid,s,3)
– Executing [s@macro-outbound-callerid:3] NoOp(“Zap/3-1”, “REALCALLERIDNUM is 202”) in new stack
– Executing [s@macro-outbound-callerid:4] GotoIf(“Zap/3-1”, “1?normcid”) in new stack
– Goto (macro-outbound-callerid,s,9)
– Executing [s@macro-outbound-callerid:9] Set(“Zap/3-1”, “USEROUTCID=”) in new stack
– Executing [s@macro-outbound-callerid:10] Set(“Zap/3-1”, “EMERGENCYCID=”) in new stack
– Executing [s@macro-outbound-callerid:11] Set(“Zap/3-1”, “TRUNKOUTCID=”) in new stack
– Executing [s@macro-outbound-callerid:12] GotoIf(“Zap/3-1”, “1?trunkcid”) in new stack
– Goto (macro-outbound-callerid,s,16)
– Executing [s@macro-outbound-callerid:16] GotoIf(“Zap/3-1”, “1?usercid”) in new stack
– Goto (macro-outbound-callerid,s,18)
– Executing [s@macro-outbound-callerid:18] GotoIf(“Zap/3-1”, “1?report”) in new stack
– Goto (macro-outbound-callerid,s,22)
– Executing [s@macro-outbound-callerid:22] NoOp(“Zap/3-1”, “CallerID set to “CentralDect” <202>”) in new stack
– Executing [s@macro-dialout-trunk:12] AGI(“Zap/3-1”, “fixlocalprefix”) in new stack
– Launched AGI Script /var/lib/asterisk/agi-bin/fixlocalprefix
== Begin MixMonitor Recording Zap/3-1
– AGI Script fixlocalprefix completed, returning 0
– Executing [s@macro-dialout-trunk:13] Set(“Zap/3-1”, “OUTNUM=2811656”) in new stack
– Executing [s@macro-dialout-trunk:14] Set(“Zap/3-1”, “custom=AMP”) in new stack
– Executing [s@macro-dialout-trunk:15] GotoIf(“Zap/3-1”, “1?gocall”) in new stack
– Goto (macro-dialout-trunk,s,17)
– Executing [s@macro-dialout-trunk:17] Macro(“Zap/3-1”, “dialout-trunk-predial-hook|”) in new stack
– Executing [s@macro-dialout-trunk:18] GotoIf(“Zap/3-1”, “0?bypass|1”) in new stack
– Executing [s@macro-dialout-trunk:19] GotoIf(“Zap/3-1”, “1?customtrunk”) in new stack
– Goto (macro-dialout-trunk,s,22)
– Executing [s@macro-dialout-trunk:22] Set(“Zap/3-1”, “pre_num=AMP:Local/”) in new stack
– Executing [s@macro-dialout-trunk:23] Set(“Zap/3-1”, “the_num=OUTNUM”) in new stack
– Executing [s@macro-dialout-trunk:24] Set(“Zap/3-1”, “post_num=@distribute-pstn-trunks”) in new stack
– Executing [s@macro-dialout-trunk:25] GotoIf(“Zap/3-1”, “1?outnum:skipoutnum”) in new stack
– Goto (macro-dialout-trunk,s,26)
– Executing [s@macro-dialout-trunk:26] Set(“Zap/3-1”, “the_num=2811656”) in new stack
– Executing [s@macro-dialout-trunk:27] Dial(“Zap/3-1”, “Local/2811656@distribute-pstn-trunks|300|tT”) in new stack
– Called 2811656@distribute-pstn-trunks
– Executing [2811656@distribute-pstn-trunks:1] Set(“Local/2811656@distribute-pstn-trunks-8ebb,2”, “COUNT=”) in new stack
== Spawn extension (distribute-pstn-trunks, 2811656, 2) exited non-zero on ‘Local/2811656@distribute-pstn-trunks-8ebb,2’
– Executing [h@distribute-pstn-trunks:1] Set(“Local/2811656@distribute-pstn-trunks-8ebb,2”, “COUNT=”) in new stack
== Spawn extension (distribute-pstn-trunks, h, 2) exited non-zero on ‘Local/2811656@distribute-pstn-trunks-8ebb,2’
== Everyone is busy/congested at this time (1:0/0/1)
– Executing [s@macro-dialout-trunk:28] Goto(“Zap/3-1”, “s-CHANUNAVAIL|1”) in new stack
– Goto (macro-dialout-trunk,s-CHANUNAVAIL,1)
– Executing [s-CHANUNAVAIL@macro-dialout-trunk:1] GotoIf(“Zap/3-1”, “1?noreport”) in new stack
– Goto (macro-dialout-trunk,s-CHANUNAVAIL,3)
– Executing [s-CHANUNAVAIL@macro-dialout-trunk:3] NoOp(“Zap/3-1”, “TRUNK Dial failed due to CHANUNAVAIL - failing through to other trunks”) in new stack
– Executing [82811656@from-internal:5] Macro(“Zap/3-1”, “outisbusy|”) in new stack
– Executing [s@macro-outisbusy:1] Playback(“Zap/3-1”, “all-circuits-busy-now|noanswer”) in new stack
– <Zap/3-1> Playing ‘all-circuits-busy-now’ (language ‘en’)
– Executing [s@macro-outisbusy:2] Playback(“Zap/3-1”, “pls-try-call-later|noanswer”) in new stack
– <Zap/3-1> Playing ‘pls-try-call-later’ (language ‘en’)
– Executing [s@macro-outisbusy:3] Macro(“Zap/3-1”, “hangupcall”) in new stack
– Executing [s@macro-hangupcall:1] ResetCDR(“Zap/3-1”, “w”) in new stack
– Executing [s@macro-hangupcall:2] NoCDR(“Zap/3-1”, “”) in new stack
– Executing [s@macro-hangupcall:3] GotoIf(“Zap/3-1”, “1?skiprg”) in new stack
– Goto (macro-hangupcall,s,6)
– Executing [s@macro-hangupcall:6] GotoIf(“Zap/3-1”, “1?skipblkvm”) in new stack
– Goto (macro-hangupcall,s,9)
– Executing [s@macro-hangupcall:9] GotoIf(“Zap/3-1”, “1?theend”) in new stack
– Goto (macro-hangupcall,s,11)
– Executing [s@macro-hangupcall:11] Hangup(“Zap/3-1”, “”) in new stack
== Spawn extension (macro-hangupcall, s, 11) exited non-zero on ‘Zap/3-1’ in macro ‘hangupcall’
== Spawn extension (macro-hangupcall, s, 11) exited non-zero on ‘Zap/3-1’ in macro ‘outisbusy’
== Spawn extension (macro-hangupcall, s, 11) exited non-zero on ‘Zap/3-1’
– Hungup ‘Zap/3-1’
== End MixMonitor Recording Zap/3-1
trixbox1*CLI>
[/php]

If you want to do this only with your zaptel trunks, you can use the channel group feature in zapata.conf to do it.

In your zapata.conf file, define a channel group like this:

group=0 channel=1-2

That will define zap channel group 0 to contain channels 1 and 2. Then in the “Zap Identifier” under the “Outgoing Settings” on the “Edit ZAP Trunk” page, you can specify how the system will select an available trunk from the group by specifying one of these letters followed by the group number (0):

  • g: select the lowest-numbered non-busy Zap channel (aka. ascending sequential hunt group)
  • G: select the highest-numbered non-busy Zap channel (aka. descending sequential hunt group)
  • r: use a round-robin search, starting at the next highest channel than last time (aka. ascending rotary hunt group)
  • R: use a round-robin search, starting at the next lowest channel than last time (aka. descending rotary hunt group)

To get the behavior you want, you’d specify “r0” or “R0” for the Zap Identifier.

It sounds like you already have a channel group defined since you said the system tries channel 1 first then tries channel 2. If that’s the case, you are probably already using “g0” as the Zap Identifier for your trunk. If so, all you need to do is to change that to “r0”.

For more information, see “Dialing a Group” in Asterisk ZAP channels.

Lee

Thanks a lot…you ROCK…
It worked and was a lot easier…lol…
Again…:Thanks a lot…you don´t know how much time I spend on this little thing.