Asterisk Examples

TableOfContents(3)

Notes

Asterisk has very bad code to handle enum lookups, it's suggested that people use a [http://www.voip-info.org/tiki-index.php?page=Asterisk+and+multiple+ENUM+entries replacement AGI script instead] which does correctly handle lookups.

Over View

To utilise our lookup services, just add the following to your configs

In enum.conf add the following lines, to the top of the file just under [general]:

search => e164.org
search => e164.arpa

To receive calls from other people using enum, you need a guest account in your iax.conf

[guest]
type=user
context=mainmenu-iax

Then in extensions.conf you need a catch all to redirect calls to your main voice menu, or you can discriminate as all connections send the full number dialed

[mainmenu-iax]
exten => _.,1,Goto(mainmenu,s,1)

You will also need a dial plan to be able to have asterisk lookup normal pots numbers from enum, we have a few example dial plan configs.

Example Australian Dial Plan

Below is an example for Sydney, Australia, which provides an example of lowest cost routing (LCR), the example below outlines how you can set asterisk up to check for a voip server accessable over the internet listed in DNS, then goes to either PSTN or voip depending on call cost.

[internal]
exten => _000,1,Goto(emergency,000,1)
exten => _8XXXXXXX,1,Macro(enum-call,localcall,612${EXTEN})
exten => _9XXXXXXX,1,Macro(enum-call,localcall,612${EXTEN})
exten => _ZXXXXXXX,1,Macro(enum-call,STD,612${EXTEN})
exten => _028XXXXXXX,1,Macro(enum-call,localcall,61${EXTEN:1})
exten => _029XXXXXXX,1,Macro(enum-call,localcall,61${EXTEN:1})
exten => _04XXXXXXXX,1,Macro(enum-call,mobile,61${EXTEN:1})
exten => _0ZXXXXXXXX,1,Macro(enum-call,STD,61${EXTEN:1})
exten => _13XXXX,1,Goto(localcall,61${EXTEN}, 1)
exten => _1300XXXXXX,1,Goto(localcall,61${EXTEN}, 1)
exten => _1800XXXXXX,1,Goto(freecall,61${EXTEN}, 1)
exten => _00116128XXXXXXX,1,Macro(enum-call,localcall,${EXTEN:4})
exten => _00116129XXXXXXX,1,Macro(enum-call,localcall,${EXTEN:4})
exten => _0011614XXXXXXXX,1,Macro(enum-call,mobile,${EXTEN:4})
exten => _001161ZXXXXXXXX,1,Macro(enum-call,STD,${EXTEN:4})
exten => _0011X.,1,Macro(enum-call,international,${EXTEN:4})
exten => _88299.,1,Macro(enum-call,international,${EXTEN})

[macro-enum-call]
exten => s,1,SetCallerID(61290000000)
exten => s,n,Set(counter=0)
exten => s,n,Set(DS=0)
exten => s,n,Set(count=${ENUMLOOKUP(+${ARG1},ALL,c,e164.org)})
exten => s,n(start),GotoIf($["${counter}" >= "${count}"]?end)
exten => s,n,Set(counter=$[${counter}+1])
exten => s,n,Set(ENUM=${ENUMLOOKUP(+${ARG1},ALL,${counter},e164.org)})
exten => s,n,GotoIf($["${LEN(${ENUM})}" = "0" ]?start)
exten => s,n,GotoIf($["${ENUM:0:3}"="sip"]?sip)
exten => s,n,GotoIf($["${ENUM:0:3}"="iax"]?iax:start)
exten => s,n(sip),Set(DS=$[${DS}+1])
exten => s,n,Set(DIALSTR${DS}=SIP/${ENUM:4})
exten => s,n,Goto(start)
exten => s,n(iax),Set(DS=$[${DS}+1])
exten => s,n,Set(DIALSTR${DS}=IAX2/${ENUM:5})
exten => s,n,Goto(start)
exten => s,n(end),Set(counter=0)
exten => s,n(start2),GotoIf($["${counter}" >= "${DS}"]?end2)
exten => s,n,Set(counter=$[${counter}+1])
exten => s,n,Set(DIALSTRING=${DIALSTR${counter}})
exten => s,n,Dial(${DIALSTRING}|120)
exten => s,n,GotoIf($[$["${DIALSTATUS}"="CHANUNAVAIL"]|
                                $["${DIALSTATUS}"="CONGESTION"]]?start2:hangup)
exten => s,n(end2),NoOp
exten => s,n,Goto(${ARG1},${ARG2},1)
exten => s,n(hangup),Hangup

[emergency] ; If 000 is dialed dump the current pstn line and dial it
exten => 000,1,ChanIsAvail(Zap/1)
exten => 000,2,Dial(${AVAILCHAN}/000)
exten => 000,3,Hangup()
exten => 000,102,SoftHangup(Zap/1-1)
exten => 000,103,Wait(1)
exten => 000,104,Goto(1)

[freecall] ; after doing an enum check, might as well just send this out as a local call
exten => _X.,1,StripMSD(2)
exten => _X.,2,Goto(localcall,${EXTEN},2)

[localcall] ; local calls by PSTN is a fixed charge, voip is per minute
exten => _X.,1,StripMSD(3)
exten => _X.,2,Dial(ZAP/1/${EXTEN},60,t)
exten => _X.,3,Dial(IAX2/user:pass@localprovider.com.au/${EXTEN},60,t)
exten => _X.,4,Dial(IAX2/user:pass@secondprovider.com.au/${EXTEN},60,t)
exten => _X.,5,Hangup
exten => _X.,103,Hangup
exten => _X.,104,Hangup
exten => _X.,105,Hangup

[STD] ; long distance by VOIP is deffinately cheaper then PSTN in Australia
exten => _X.,1,StripMSD(2)
exten => _X.,2,Prefix(0)
exten => _X.,3,Dial(IAX2/user:pass@localprovider.com.au/${EXTEN},60,t)
exten => _X.,4,Dial(IAX2/user:pass@secondprovider.com.au/${EXTEN},60,t)
exten => _X.,5,Dial(ZAP/1/${EXTEN},60,t)
exten => _X.,6,Hangup
exten => _X.,104,Hangup
exten => _X.,105,Hangup
exten => _X.,106,Hangup

[mobile] ; Maybe be cheaper to route mobile calls differently to STD in some cases
exten => _X.,1,Goto(STD,${EXTEN},1)

[international] ; Using overseas providers for calls is usually cheaper but more lag
exten => _X.,1,Dial(IAX2/user:pass@provider1.com/${EXTEN},60,t)
exten => _X.,2,Dial(IAX2/user:pass@provider2.com/${EXTEN},60,t)
exten => _X.,3,Dial(ZAP/1/0011${EXTEN},60,t)
exten => _X.,4,Hangup
exten => _X.,102,Hangup
exten => _X.,103,Hangup
exten => _X.,104,Hangup

Example North American Dial Plan

Below is an example for Vancouver, Canada, which provides an example of lowest cost routing (LCR), the example below outlines how you can set asterisk up to check for a voip server accessable over the internet listed in DNS, then goes to either PSTN or voip depending on call cost.

[internal]
exten => _604NXXXXXX,1,Macro(enum-call,localcall,1${EXTEN})
exten => _1604NXXXXXX,1,Macro(enum-call,localcall,${EXTEN})
exten => _0111604NXXXXXX,1,Macro(enum-call,localcall,${EXTEN:3})
exten => _0111NXXNXXXXXX,1,Macro(enum-call,NA,${EXTEN:3})
exten => _NXXNXXXXXX,1,Prefix(1)
exten => _1NXXNXXXXXX,1,Macro(enum-call,NA,${EXTEN})
exten => _1NXXNXXXXXX,2,Macro(enum-call,NA,${EXTEN})
exten => _011X.,1,Macro(enum-call,international,${EXTEN:3})
exten => _88299.,1,Macro(enum-call,international,${EXTEN})

[macro-enum-call]
exten => s,1,SetCallerID(16045551212)
exten => s,n,Set(counter=0)
exten => s,n,Set(DS=0)
exten => s,n,Set(count=${ENUMLOOKUP(+${ARG1},ALL,c,e164.org)})
exten => s,n(start),GotoIf($["${counter}" >= "${count}"]?end)
exten => s,n,Set(counter=$[${counter}+1])
exten => s,n,Set(ENUM=${ENUMLOOKUP(+${ARG1},ALL,${counter},e164.org)})
exten => s,n,GotoIf($["${LEN(${ENUM})}" = "0" ]?start)
exten => s,n,GotoIf($["${ENUM:0:3}"="sip"]?sip)
exten => s,n,GotoIf($["${ENUM:0:3}"="iax"]?iax:start)
exten => s,n(sip),Set(DS=$[${DS}+1])
exten => s,n,Set(DIALSTR${DS}=SIP/${ENUM:4})
exten => s,n,Goto(start)
exten => s,n(iax),Set(DS=$[${DS}+1])
exten => s,n,Set(DIALSTR${DS}=IAX2/${ENUM:5})
exten => s,n,Goto(start)
exten => s,n(end),Set(counter=0)
exten => s,n(start2),GotoIf($["${counter}" >= "${DS}"]?end2)
exten => s,n,Set(counter=$[${counter}+1])
exten => s,n,Set(DIALSTRING=${DIALSTR${counter}})
exten => s,n,Dial(${DIALSTRING}|120)
exten => s,n,GotoIf($[$["${DIALSTATUS}"="CHANUNAVAIL"]|
                                $["${DIALSTATUS}"="CONGESTION"]]?start2:hangup)
exten => s,n(end2),NoOp
exten => s,n,Goto(${ARG1},${ARG2},1)
exten => s,n(hangup),Hangup

[localcall] ; in this example pstn is cheaper to use then voip so we try pstn then voip.
exten => _X.,1,Dial(ZAP/1/${EXTEN},60,t)
exten => _X.,2,Dial(IAX2/user:pass@localprovider.ca/${EXTEN},60,t)
exten => _X.,3,Dial(IAX2/user:pass@secondprovider.ca/${EXTEN},60,t)
exten => _X.,4,Hangup
exten => _X.,102,Hangup
exten => _X.,103,Hangup
exten => _X.,104,Hangup

[longdistance] ; for long distance calls, voip is cheaper then pstn
exten => _X.,1,Dial(IAX2/user:pass@localprovider.ca/${EXTEN},60,t)
exten => _X.,2,Dial(IAX2/user:pass@secondprovider.ca/${EXTEN},60,t)
exten => _X.,3,Dial(ZAP/1/${EXTEN},60,t)
exten => _X.,4,Hangup
exten => _X.,102,Hangup
exten => _X.,103,Hangup
exten => _X.,104,Hangup

[international] ; Using overseas providers for calls is usually cheaper but more lag
exten => _X.,1,Dial(IAX2/user:pass@provider1.com/${EXTEN},60,t)
exten => _X.,2,Dial(IAX2/user:pass@provider2.com/${EXTEN},60,t)
exten => _X.,3,Dial(ZAP/1/011${EXTEN},60,t)
exten => _X.,4,Hangup
exten => _X.,102,Hangup
exten => _X.,103,Hangup
exten => _X.,104,Hangup

Example New Zealand Dial Plan

Below is an example for Wellington, New Zealand, which provides an example of lowest cost routing (LCR), the example below outlines how you can set asterisk up to check for a voip server accessable over the internet listed in DNS, then goes to either PSTN or voip depending on call cost.

[internal]
exten => _XXXXXXX,1,Macro(enum-call,localcall,644${EXTEN})
exten => _04XXXXXXX,1,Macro(enum-call,localcall,64${EXTEN:1})
exten => _02XXXXXXX,1,Macro(enum-call,mobile,64${EXTEN:1})
exten => _0ZXXXXXXXX,1,Macro(enum-call,longdistance,64${EXTEN:1})
exten => _00644XXXXXXX,1,Macro(enum-call,localcall,${EXTEN:2})
exten => _00642XXXXXXX,1,Macro(enum-call,mobile,${EXTEN:2})
exten => _0064XXXXXXXX,1,Macro(enum-call,longdistance,${EXTEN:2})
exten => _00X.,1,Macro(enum-call,international,${EXTEN:2})
exten => _88299.,1,Macro(enum-call,international,${EXTEN})

[macro-enum-call]
exten => s,1,SetCallerID(6441234567)
exten => s,n,Set(counter=0)
exten => s,n,Set(DS=0)
exten => s,n,Set(count=${ENUMLOOKUP(+${ARG1},ALL,c,e164.org)})
exten => s,n(start),GotoIf($["${counter}" >= "${count}"]?end)
exten => s,n,Set(counter=$[${counter}+1])
exten => s,n,Set(ENUM=${ENUMLOOKUP(+${ARG1},ALL,${counter},e164.org)})
exten => s,n,GotoIf($["${LEN(${ENUM})}" = "0" ]?start)
exten => s,n,GotoIf($["${ENUM:0:3}"="sip"]?sip)
exten => s,n,GotoIf($["${ENUM:0:3}"="iax"]?iax:start)
exten => s,n(sip),Set(DS=$[${DS}+1])
exten => s,n,Set(DIALSTR${DS}=SIP/${ENUM:4})
exten => s,n,Goto(start)
exten => s,n(iax),Set(DS=$[${DS}+1])
exten => s,n,Set(DIALSTR${DS}=IAX2/${ENUM:5})
exten => s,n,Goto(start)
exten => s,n(end),Set(counter=0)
exten => s,n(start2),GotoIf($["${counter}" >= "${DS}"]?end2)
exten => s,n,Set(counter=$[${counter}+1])
exten => s,n,Set(DIALSTRING=${DIALSTR${counter}})
exten => s,n,Dial(${DIALSTRING}|120)
exten => s,n,GotoIf($[$["${DIALSTATUS}"="CHANUNAVAIL"]|
                                $["${DIALSTATUS}"="CONGESTION"]]?start2:hangup)
exten => s,n(end2),NoOp
exten => s,n,Goto(${ARG1},${ARG2},1)
exten => s,n(hangup),Hangup

[localcall] ; local calls by PSTN is a fixed charge, voip is per minute
exten => _X.,1,StripMSD(3)
exten => _X.,2,Dial(ZAP/1/${EXTEN},60,t)
exten => _X.,3,Dial(IAX2/user:pass@localprovider.co.nz/${EXTEN},60,t)
exten => _X.,4,Dial(IAX2/user:pass@secondprovider.co.nz/${EXTEN},60,t)
exten => _X.,5,Hangup
exten => _X.,103,Hangup
exten => _X.,104,Hangup
exten => _X.,105,Hangup

[longdistance] ; long distance by VOIP is deffinately cheaper then PSTN in Australia
exten => _X.,1,StripMSD(2)
exten => _X.,2,Prefix(0)
exten => _X.,3,Dial(IAX2/user:pass@localprovider.co.nz/${EXTEN},60,t)
exten => _X.,4,Dial(IAX2/user:pass@secondprovider.co.nz/${EXTEN},60,t)
exten => _X.,5,Dial(ZAP/1/${EXTEN},60,t)
exten => _X.,6,Hangup
exten => _X.,104,Hangup
exten => _X.,105,Hangup
exten => _X.,106,Hangup

[mobile] ; Maybe be cheaper to route mobile calls differently to longdistance in some cases
exten => _X.,1,Goto(longdistance,${EXTEN},1)

[international] ; Using overseas providers for calls is usually cheaper but more lag
exten => _X.,1,Dial(IAX2/user:pass@provider1.com/${EXTEN},60,t)
exten => _X.,2,Dial(IAX2/user:pass@provider2.com/${EXTEN},60,t)
exten => _X.,3,Dial(ZAP/1/00${EXTEN},60,t)
exten => _X.,4,Hangup
exten => _X.,102,Hangup
exten => _X.,103,Hangup
exten => _X.,104,Hangup

Example United Kingdom Dial Plan

Below is an example for Glasgow, Scotland, which provides an example of lowest cost routing (LCR), the example below outlines how you can set asterisk up to check for a voip server accessable over the internet listed in DNS, then goes to either PSTN or voip depending on call cost.

[internal]
exten => _XXXXXXX,1,Macro(enum-call,localcall,44141${EXTEN})
exten => _0141XXXXXXX,1,Macro(enum-call,localcall,44${EXTEN:1})
exten => _0044141XXXXXXX,1,Macro(enum-call,localcall,${EXTEN:2})
exten => _07XXXXXXXXX,1,Macro(enum-call,mobile,44${EXTEN:1})
exten => _00447XXXXXXXXX,1,Macro(enum-call,mobile,${EXTEN:2})
exten => _0ZXXXXXXXXX,1,Macro(enum-call,longdistance,44${EXTEN:1})
exten => _0044ZXXXXXXXXX,1,Macro(enum-call,longdistance,${EXTEN:2})
exten => _00X.,1,Macro(enum-call,international,${EXTEN:2})
exten => _88299.,1,Macro(enum-call,international,${EXTEN})

[macro-enum-call]
exten => s,1,SetCallerID(441411234567)
exten => s,n,Set(counter=0)
exten => s,n,Set(DS=0)
exten => s,n,Set(count=${ENUMLOOKUP(+${ARG1},ALL,c,e164.org)})
exten => s,n(start),GotoIf($["${counter}" >= "${count}"]?end)
exten => s,n,Set(counter=$[${counter}+1])
exten => s,n,Set(ENUM=${ENUMLOOKUP(+${ARG1},ALL,${counter},e164.org)})
exten => s,n,GotoIf($["${LEN(${ENUM})}" = "0" ]?start)
exten => s,n,GotoIf($["${ENUM:0:3}"="sip"]?sip)
exten => s,n,GotoIf($["${ENUM:0:3}"="iax"]?iax:start)
exten => s,n(sip),Set(DS=$[${DS}+1])
exten => s,n,Set(DIALSTR${DS}=SIP/${ENUM:4})
exten => s,n,Goto(start)
exten => s,n(iax),Set(DS=$[${DS}+1])
exten => s,n,Set(DIALSTR${DS}=IAX2/${ENUM:5})
exten => s,n,Goto(start)
exten => s,n(end),Set(counter=0)
exten => s,n(start2),GotoIf($["${counter}" >= "${DS}"]?end2)
exten => s,n,Set(counter=$[${counter}+1])
exten => s,n,Set(DIALSTRING=${DIALSTR${counter}})
exten => s,n,Dial(${DIALSTRING}|120)
exten => s,n,GotoIf($[$["${DIALSTATUS}"="CHANUNAVAIL"]|
                                $["${DIALSTATUS}"="CONGESTION"]]?start2:hangup)
exten => s,n(end2),NoOp
exten => s,n,Goto(${ARG1},${ARG2},1)
exten => s,n(hangup),Hangup

[localcall] ; local calls by PSTN is a fixed charge, voip is per minute
exten => _X.,1,StripMSD(5)
exten => _X.,2,Dial(ZAP/1/${EXTEN},60,t)
exten => _X.,3,Dial(IAX2/user:pass@localprovider.co.uk/${EXTEN},60,t)
exten => _X.,4,Dial(IAX2/user:pass@secondprovider.co.uk/${EXTEN},60,t)
exten => _X.,5,Hangup
exten => _X.,103,Hangup
exten => _X.,104,Hangup
exten => _X.,105,Hangup

[longdistance] ; long distance by VOIP is deffinately cheaper then PSTN in Australia
exten => _X.,1,StripMSD(2)
exten => _X.,2,Prefix(0)
exten => _X.,3,Dial(IAX2/user:pass@localprovider.co.uk/${EXTEN},60,t)
exten => _X.,4,Dial(IAX2/user:pass@secondprovider.co.uk/${EXTEN},60,t)
exten => _X.,5,Dial(ZAP/1/${EXTEN},60,t)
exten => _X.,6,Hangup
exten => _X.,104,Hangup
exten => _X.,105,Hangup
exten => _X.,106,Hangup

[mobile] ; Maybe be cheaper to route mobile calls differently to longdistance in some cases
exten => _X.,1,Goto(longdistance,${EXTEN},1)

[international] ; Using overseas providers for calls is usually cheaper but more lag
exten => _X.,1,Dial(IAX2/user:pass@provider1.com/${EXTEN},60,t)
exten => _X.,2,Dial(IAX2/user:pass@provider2.com/${EXTEN},60,t)
exten => _X.,3,Dial(ZAP/1/00${EXTEN},60,t)
exten => _X.,4,Hangup
exten => _X.,102,Hangup
exten => _X.,103,Hangup
exten => _X.,104,Hangup

Experiencing problems??

The above macro-enum-call has some problems. This is primarily because Asterisk still has some problems with the new ENUMLOOKUP function. And the ENUMLOOKUP count does not return 0! It returns null and thus "exten => s,n(start),GotoIf($["${counter}" >= "${count}"]?end)" may not work quite right.

Below is something I find works much better.

{{{[trunkld] ; ; Long distance context accessed through trunk. ; exten => _1NXXNXXXXXX,1,Macro(enum-call,${EXTEN},trunkld,2) exten => _1NXXNXXXXXX,n,Dial(${TRUNK-LD}/${EXTEN},30);fail over exten => _1NXXNXXXXXX,n,congestion()

[trunkint] ; ; International long distance context accessed through trunk. ; exten => _011.,1,Macro(enum-call,${EXTEN:3},trunkint,2) exten => _011.,n,Dial(${TRUNK-LD}/${EXTEN},30);fail over exten => _011.,n,congestion()

[macro-enum-call] ; ARG1 = extension to lookup ; ARG2 = fallback context ; ARG3 = fallback location exten => s,1,NoOp(Doing Enum lookup) exten => s,n,Set(registrars=e164.arpa-e164.org-e164.info-enum.org-e164.televolution.net) ; place your registrars to search here exten => s,n(regloop),Set(registrar=${CUT(registrars,,1)}) exten => s,n,Set(registrars=${CUT(registrars,,2-)}) exten => s,n,Set(protocols=SIP-IAX2-IAX-H323) ; place your protocols to search here exten => s,n(protoloop),Set(protocol=${CUT(protocols,,1)}) exten => s,n,Set(protocols=${CUT(protocols,,2-)}) exten => s,n,Set(count=${ENUMLOOKUP(+${ARG1},${protocol},c,${registrar})}) exten => s,n,Set(counter=0) exten => s,n(resultloop),GotoIf($[$["x${counter}"="x"]|$["${counter}" >= "${count}"]]?resultend) exten => s,n,Set(counter=$[${counter}+1]) exten => s,n,Set(ENUM=${ENUMLOOKUP(+${ARG1},${protocol},${counter},${registrar})}) exten => s,n,GotoIf($["${LEN(${ENUM})}" = "0" ]?continue) exten => s,n,Set(DIALSTR=${protocol}/${ENUM}) exten => s,n,Dial(${DIALSTR}|120) exten => s,n,GotoIf($[$["${DIALSTATUS}"="CHANUNAVAIL"]|$["${DIALSTATUS}"="CONGESTION"]]?continue:hangup) exten => s,n(continue),Goto(resultloop) exten => s,n(resultend),GotoIf($["${protocols}"=""]?regend:protoloop) exten => s,n(regend),GotoIf($["${registrars}"=""]?fallthrough:regloop) exten => s,n(hangup),NoOp(Dial failed due to ${DIALSTATUS}) exten => s,n,Hangup exten => s,n(fallthrough),NoOp(Found No Enum Entry) exten => s,n,Goto(${ARG2},${ARG3}) }}}

e164.org Wiki: AsteriskExamples (last edited 2007-01-28 01:11:32 by EvilBunny)