MavEtJu's Distorted View of the World

Asterisk Dialplan - Best practice

Posted on 2005-03-28 23:14:38, modified on 2006-01-09 16:29:23
Tags: Voice over IP, Asterisk

ASTERISK EXTENSIONS.CONF - BEST PRACTICE

This document describes a best practice approach to a structured and controllable design of the Asterisk extensions configuration file.

THE DESIGN

The design is as follows: There are input sources, there are dial groups and there are macros.

Input sources are places where calls are being made from. For example incoming SIP connections (authenticated or unauthenticated), calls from the PSTN and calls from the internal phone numbers.

Dial groups are destinations to be called. For example other SIP phones, calls to the PSTN, calls to internal phone numbers and calls to Asterisk applications like voicemail and conferences.

And as third, macros to reduce the amount of repetitive code.

INPUT SOURCES - part 1

The context of input sources are defined in sip.conf, iax2.conf and zapata.conf.

Sip.conf has three different contexts: The default context, to which everybody who isn't authenticated is assigned:

    [general]
    context=incoming-from-internet

People who are authenticated so they are trusted.

    [my-friend]
    context=incoming-from-friends

Iax2.conf has the same idea, but instead of putting it in the general section it's put in the guest section:

    [guest]
    context=incoming-from-internet

    [my-friend]
    context=incoming-from-friends

Zapata.conf has the definitions of ISDN channels to logical groups in it. For every group of ISDN channels you could have a different group and a different context:

    group = 1
    context = CUST1-PABX
    signalling = pri_net
    channel => 1-15,17-31

    group = 2
    context = CUST2-PABX
    signalling = pri_net
    channel => 32-46,48-62

    group = 3
    context = ME-TELCO
    signalling = pri_net
    channel => 63-77,79-93

DIAL GROUPS

Dial groups are the collections of different extension to dial. To start with, all PSTN numbers which are routed by your telco to your Asterisk server. Also all internal numbers for voicemail and conferences. And as last, a default entry for everything which is not local.

Our PSTN numbers for customers are +61 2 9210 0500 to +61 2 9210 0599 for customer 1 and +61 2 9210 0600 to +61 2 9210 0799 for customer 2. First we map the trunk to the customer onto the Zap interface, then we map the number ranges for the customers onto the customer trunks. In the dial plan we use the last mapping, so that any changes in hardware links only have to be modified in the general section. In the extensions definitions we use three versions of the number: The local number without the are code, the full national number with the area code and the international number with the country code.

    [general]
    TRUNK_CUST1= Zap/g1
    TRUNK_CUST2= Zap/g2

    TRUNK_612921005xx=${TRUNK_CUST1}
    TRUNK_612921006xx=${TRUNK_CUST2}
    TRUNK_612921007xx=${TRUNK_CUST2}

    [outgoing-customer1]
    exten => _612921005XX,1,Macro(call-int,${TRUNK_612921005xx},0${EXTEN:2})
    exten => _02921005XX,1,Macro(call-int,${TRUNK_612921005xx},${EXTEN})
    exten => _921005XX,1,Macro(call-int,${TRUNK_612921005xx},02${EXTEN})

    [outgoing-customer2]
    exten => _612921006XX,1,Macro(call-int,${TRUNK_612921006xx},0${EXTEN:2})
    exten => _02921006XX,1,Macro(call-int,${TRUNK_612921006xx},${EXTEN})
    exten => _921006XX,1,Macro(call-int,${TRUNK_612921006xx},02${EXTEN})
    exten => _612921007XX,1,Macro(call-int,${TRUNK_612921007xx},0${EXTEN:2})
    exten => _02921007XX,1,Macro(call-int,${TRUNK_612921007xx},${EXTEN})
    exten => _921007XX,1,Macro(call-int,${TRUNK_612921007xx},02${EXTEN})

The PSTN number ranges for VoIP users are +61 2 9210 081x for authenticated SIP users and +61 2 9210 080x towards a remote SIP server.

    [general]
    OTHERSIPSERVER= sip.foo.bar

    [outgoing-voip]
    exten => _6129210080X,1,Macro(call-sip-remote,${EXTEN:9}@${OTHERSIPSERVER}))
    exten => _029210080X,1,Macro(call-sip-remote,${EXTEN:8}@${OTHERSIPSERVER}))
    exten => _9210080X,1,Macro(call-sip-remote,${EXTEN:6}@${OTHERSIPSERVER}))

    exten => 61292100810,1,Macro(call-sip-local,foo,0${EXTEN:2})
    exten => 0292100810,1,Macro(call-sip-local,foo,${EXTEN})
    exten => 92100810,1,Macro(call-sip-local,foo,02${EXTEN})
    exten => 61292100811,1,Macro(call-sip-local,bar,0${EXTEN:2})
    exten => 0292100811,1,Macro(call-sip-local,bar,${EXTEN})
    exten => 92100811,1,Macro(call-sip-local,bar,02${EXTEN})

We don't want to specify all outgoing PSTN numbers, so we just use a catch-all for them:

    [general]
    TRUNK_TELCO= Zap/g3

    [outgoing-theworld]
    exten => _.,1,Macro(call-ext,${TRUNK_TELCO},${EXTEN})

And a number of tools for internal and external users on +61 2 9210 082x:

    [outgoing-tools]
    exten => 61292100820,1,MeetMe(1234|M)
    exten => 0292100820,1,MeetMe(1234|M)
    exten => 92100820,1,MeetMe(1234|M)

    exten => 61292100821,1,VoicemailMain
    exten => 61292100821,n,Hangup
    exten => 0292100821,1,VoicemailMain
    exten => 0292100821,n,Hangup
    exten => 92100821,1,VoicemailMain
    exten => 92100821,n,Hangup

    exten => *600,1,Playback(demo-echotest)
    exten => *600,n,Echo
    exten => *600,n,Playback(demo-echodone)
    exten => *600,n,Hangup

MACROS

Now we're in the section which actually does do the dialing. The following four macros are all we need: call-int, call-ext and call-sip-local and call-sip-remote.

The call-int macro calls on an internal trunk. Further call handling is done by these phone systems:

    [macro-call-int]
    exten => s,1,NoOp(Trunk:${ARG1})
    exten => s,n,NoOp(Number:${ARG2})
    exten => s,n,ChanIsAvail(${ARG1})
    exten => s,n,Cut(C=AVAILCHAN,,1)
    exten => s,n,Dial(${C}/${ARG2})
    exten => s,n,Hangup()

The call-ext macro calls on a trunk to the outside world. We need to check for dial responses like BUSY, CHANUNAVAIL and others.

    [macro-call-ext]
    exten => s,1,NoOp(Trunk:${ARG1})
    exten => s,n,NoOp(Number:${ARG2})
    exten => s,n,ChanIsAvail(${ARG1})
    exten => s,n,Cut(C=AVAILCHAN,,1)
    exten => s,n,Dial(${C}/${ARG1}) 
    exten => s,n,Goto(s-${DIALSTATUS},1)
    exten => s,n,Hangup()

    exten => s-BUSY,1,Busy()
    exten => s-BUSY,n,Hangup()
     
    exten => s-CHANUNAVAIL,1,PlayTones(congestion)
    exten => s-CHANUNAVAIL,n,Wait(5)
    exten => s-CHANUNAVAIL,n,StopPlayTones()
    exten => s-CHANUNAVAIL,n,Hangup
     
    exten => s-CONGESTION,1,PlayTones(congestion)
    exten => s-CONGESTION,n,Wait(5)
    exten => s-CONGESTION,n,StopPlayTones()
    exten => s-CONGESTION,n,Hangup
     
    exten => s-NOANSWER,1,Hangup

    exten => s-ANSWER,1,Hangup
    exten => s-CANCEL,1,Hangup

Call-sip-remote is just like call-int, but then for an SIP session:

    [macro-call-sip-remote]
    exten => s,1,Playback(pls-wait-connect-call)
    exten => s,n,Dial(SIP/${ARG1},45,r)
    exten => s,n,Hangup

And call-sip-local is like call-ext, but with better handling of failed dial attempts since we need to use voicemail there:

    [macro-call-sip-local]
    exten => s,1,NoOp(To user: ${ARG1})
    exten => s,n,NoOp(Voicemail: ${ARG2})
    exten => s,n,Dial(SIP/${ARG1},45,r)
    exten => s,n,NoOp(${DIALSTATUS})
    exten => s,n,Goto(s-${DIALSTATUS},1)
    exten => s,n,Hangup
     
    exten => s-BUSY,1,Playback(user)
    exten => s-BUSY,n,Playback(is-curntly-busy)
    exten => s-BUSY,n,Goto(s-VM,1)
     
    exten => s-NOANSWER,1,Playback(user)
    exten => s-NOANSWER,n,Playback(is-curntly-unavail)
    exten => s-NOANSWER,n,Goto(s-VM,1)
     
    exten => s-ANSWER,1,Playback(thank-you-for-calling)
    exten => s-ANSWER,n,Hangup
     
    exten => s-CHANUNAVAIL,1,Playback(is-curntly-unavail)
    exten => s-CHANUNAVAIL,n,Goto(s-VM,1)
     
    exten => s-CONGESTION,1,PlayTones(congestion)
    exten => s-CONGESTION,n,Wait(5)
    exten => s-CONGESTION,n,StopPlayTones()
    exten => s-CONGESTION,n,Goto(s-VM,1)

    exten => s-CANCEL,1,Hangup
     
    exten => s-VM,1,VoiceMail(${ARG2})
    exten => s-VM,n,Hangup

Pfioew! That's all the low level work.

INPUT SOURCES - part 2

Now it's time to glue the input source and the dial groups together. Every input source has its own definitions on which dial groups it is allowed to call.

The first group is the unauthenticated people on the internet which get routed to my Asterisk server. They are allowed to call my public PSTN numbers, but not to retrieve voicemail and do conferencing.

    [incoming-from-internet]
    include => outgoing-voip
    include => outgoing-customer1
    include => outgoing-customer2

The second group is the authenticated people on the internet which actually register at my Asterisk server. They are allowed as above, but also to retrieve voicemail and do conferencing.

    [incoming-from-friends]
    include => outgoing-tools
    include => outgoing-voip
    include => outgoing-customer1
    include => outgoing-customer2

All incoming called from the PSTN are allowed to call my public PSTN numbers and to retrieve voicemail and do conferencing.

    [ME-TELCO]
    include => outgoing-tools
    include => outgoing-voip
    include => outgoing-customer1
    include => outgoing-customer2

And the customers are allowed to call everything: public PSTN numbers, retrieve voicemail and do conferencing and make PSTN calls.

    [CUST1-PABX]
    include => outgoing-tools
    include => outgoing-voip
    include => outgoing-customer1
    include => outgoing-customer2
    include => outgoing-theworld

    [CUST2-PABX]
    include => outgoing-tools
    include => outgoing-voip
    include => outgoing-customer1
    include => outgoing-customer2
    include => outgoing-theworld

CONCLUSION

By properly defining what the input sources are, what the destination groups are and what the allowed destinations for an input source are, it is possible to have a structured, scalable and safe dial plan.

| Share on Facebook | Share on Twitter
Comments: No comments yet
Leave a comment
Back to the main page