Automatic Dial Resource Fail-over in Asterisk

Asterisk is generally pretty reliable, but termination providers aren’t always so good; in a market where anybody can re-sell an upstream provider, or setup a few Asterisk boxes and start routing calls for people, it’s generally a good idea to have a “backup” provider (or three) to route your calls through.

You can easily setup an Asterisk system, to fail-over to secondary systems, if your primary provider fails for some reason- and this can all be done right in the dial plan, using a simple MACRO.

Add this MACRO to your dial plan:

exten => s,1,Set(CALL_ATTEMPT=1)
exten => s,3,Dial(${TERM_PROVIDER}/${ARG1},60)
exten => s,4,GotoIf($["${CALL_ATTEMPT}" >= "${MAX_PROVIDERS}"]?s-CANCEL,1)
exten => s,5,Set(CALL_ATTEMPT=$[${CALL_ATTEMPT} + 1])
exten => s,6,Goto(s-${DIALSTATUS},1)

exten => s-BUSY,1,Noop()
exten => s-NOANSWER,1,Noop()
exten => s-CANCEL,1,Hangup()
exten => s-HANGUP,1,Hangup()

exten => s-CHANUNAVAIL,2,Goto(s,3)

exten => s-CONGESTION,2,Goto(s,3)

Now you’ll need to route your calls into this MACRO; this can vary by dial plan, as you may have a special configuration for different area codes, or country codes, or based on some least-cost-routing business decisions, but a simple example would be something like this:

exten => _1NXXNXXXXXX,1,Answer()
exten => _1NXXNXXXXXX,2,Macro(direct-dial,${EXTEN})
exten => _1NXXNXXXXXX,3,Hangup()

This routes any NANPA numbers through the direct-dial MACRO above, passing in the phone number as the first argument to the MACRO.

Now, before this will work, you’ll need to configure some variables; this can be done in many places- in my working configuration, I have these variables dynamically generated via an AGI script, based on the phone number being dialed. This way I can control dial-groups, by phone number, based on a cost/preference/etc.

In this example, we’ll simply set these values in the globals section of the extensions.conf file:

TERM_PROVIDER1 = SIP/first_provider
TERM_PROVIDER2 = IAX/second_provider
TERM_PROVIDER3 = SIP/last_provider

So I’ve configured three fictitious termination providers; you can specify as many as you like, as long as the TERM_PROVIDER increments one for each, and you set the MAX_PROVIDERS value to the total number of providers listed.

This is obviously more useful if this list is automatically generated somehow, or changed based on the phone number being dialed, otherwise the retries could simply be hard-coded into the dial plan.

Now when you dial your number, it will start with the first (default) provider; if the dial() function returns a congestion or channel un-available error, the MACRO will cycle to the next provider, until it as gone through all of the providers listed.

7 thoughts on “Automatic Dial Resource Fail-over in Asterisk

  1. Ray

    Just happened to reach this post about fail over function..just want to say ..really appreciated it..I will try it out

  2. Rokibul Hasan

    Great job. It works perfectly. Thanks a lot to share such an important things. Can you please try out one more things. In my system some callid comes like 99999999!012345678 (DNIS!callerid) format. Is there any dial plan to resize the number to 012345678 only.
    Advanced thanks……

  3. mike Post author

    Hey Rokibul,

    Asterisk supports doing substrings on variables, by simple doing:


    Where X is the start position, and y is the number of characters to copy.

    So in your case above,


    would return “012345678”


  4. deville

    I use askozia 1.02 old version without the failover providers function.
    How do I add your code to askozia in order for this failover to work.

  5. Mridul

    I’ve 1200 different provider SIP trunk. how can I set dial plan for them? I think 1200 dial plan for 1200 trunk isn’t wise decision. can you suggest me an idea or any alternative ?

    Thanks in Advance

  6. mike Post author

    Hey Mridul,

    Without knowing more about what your goal is, it’s tough to say- but I would probably put the list of SIP trunk providers in a database, and access them via AGI- depending on your logic.


  7. zeeshan

    this works really fine, but i am in problem when i try to implement it in my scenario, suppose some one have 100’s or 1000’s of extensions, and he want to do outbound white list on every extension (where every extension have only 10 different white list numbers in it), how he would achieve this?

    i tried a work around with your given code , but miserably failed, i did a call re routing setup on each and every extension to look for (guided by your code) , if there exists a number in corresponding extension’s white list guided by ( which independently works really fine, but that didnt work for me when i put both together. because of calling macros in macros (this is what i think) …i will be greatfull to you if you can throw some light on it

Leave a Reply

Your email address will not be published. Required fields are marked *