[Asterisk-Users] Dial Plan Sequencing

John Todd jtodd at loligo.com
Fri Nov 14 00:13:31 MST 2003


>I have an interesting dilemma with sequencing in the dialplan.  Up 
>to now, I have assumed that the extensions in the dial plan were 
>tested in the order that they appear in extensions.conf.  In other 
>words, I have the following fragment which was designed to dial toll 
>free on the PSTN and all other long distance on VoIP:
>
>[longdistance]
>include => local                                                       
>                                        ;Handle local, etc first. (or 
>so I thought!)
>exten => _91NXXNXXXXXX,1,Dial(${VPLSTRUNK}/${EXTEN:1})        ;Dial 
>long distance through VoiP
>exten => _91NXXNXXXXXX,2,Congestion                                  
>              ;OOPS! No lines available?
>:
>:
>
>[local]
>:
>exten => _91800NXXXXXX,1,Dial(${PSTNTRUNK}/${EXTEN}) ;     Long 
>distance toll free accessed through PSTN trunk interface
>exten => _91800NXXXXXX,2,Congestion
>exten => _91888NXXXXXX,1,Dial(${PSTNTRUNK}/${EXTEN})
>exten => _91888NXXXXXX,2,Congestion
>exten => _91877NXXXXXX,1,Dial(${PSTNTRUNK}/${EXTEN})
>exten => _91877NXXXXXX,2,Congestion
>exten => _91866NXXXXXX,1,Dial(${PSTNTRUNK}/${EXTEN})
>exten => _91866NXXXXXX,2,Congestion
>
>; The rest of the local definitions, etc
>:
>
>I expected that the "_918" definitions would be tested first, 
>followed by the "_91N" definitions.  Unfortunately, it appears as if 
>the definitions made using the "include=" operator are always tested 
>last.  This means that the toll free numbers dialed by people in the 
>longdistance context are always routed over VoIP rather than PSTN 
>because they match the "_91N" pattern.  While I can fix this with a 
>complicated set of conditionals or dial string patterns, I wonder if 
>anyone has found a more elegant solution, remembering that I want to 
>give some extensions access to only the local context, but still 
>provide toll free service for everyone (i.e, I don't want to move 
>the "_918" definitions into the longdistance context).
>
>Stephen R. Besch

Stephen -
   I think others have covered the examples fairly well, but let me 
re-state what they've shown you.  Your example includes "normal" 
matching statements as well as an "include"d set of statements in the 
same context; Asterisk will try to match the "normal" lines first, 
then the included lines.

Ordering of matches in extensions.conf is irrelevant within contexts, 
except where "include" is concerned.  All lines within a particular 
context are re-sorted upon loading into memory in numerical order. 
The only way you can force one set of matches ahead of another within 
a specific context is to split up the match statements and use 
'include' to force their ordering.  The 'include' statement will 
force matches to happen in the order in which the include lines are 
specified in extensions.conf, but you must "include" all possible 
matches if you want to truly force the ordering exactly the way you 
want.  You can be safe only if matches against unique things like "h" 
or "fax" are made in the primary context.

Let's say we're passing a call into context [foo] that we want (in 
order of preference) the SIP extensions to be matched first, then if 
those aren't matched, we want to see if the number starts with a "9" 
and if so, send it out our Zap analog channel, and finally, if that 
doesn't match, we want to play a recording and hangup.

So, we put something like this together:

[foo]
exten => 1234,1,Dial(SIP/1234)
exten => 9992,1,Dial(SIP/9992)
exten => _9.,1,Dial(Zap/1/${EXTEN})
exten => _.,1,Playback(sorry-no-match)
exten => _.,2,Hangup
exten => h,1,Hangup    ; we always include an "h" extension

But this doesn't work!  As soon as we pass a number into the context, 
it matches successfully against _., and we get our sorry-no-match 
recording and the line hangs up.  Here's how we force the ordering by 
using "include" to regulate order of matching:

[foo]
include => foo1
include => foo2
include => foo3
exten => h,1,Hangup

[foo1]
exten => 1234,1,Dial(SIP/1234)
exten => 9992,1,Dial(SIP/9992)

[foo2]
exten => _9.,1,Dial(Zap/1/${EXTEN})

[foo3]
exten => _.,1,Playback(sorry-no-match)
exten => _.,2,Hangup


I typically use numeric suffixes at the end of the basename of the 
context for similar matches.  Thus, if the main context is "foo", 
then "foo1, foo2, etc."  would be the followup matches.  You'll find 
that you may even have sub-sub contexts, and adding a dot and a 
number might make sense ("foo1.2, foo1.3" might be included in "foo1" 
if you get complex.)

Note that my example doesn't work with some types of dialing, such as 
match-as-you-go (commonly used for FXS/FXO interfaces) since those 
will try to run through the entire list of all included lines during 
each keypress.  SIP phones, as an example, will work fine with my 
example since they send their entire dialstring all at once for 
matching, instead of allowing Asterisk to see each digit as it is 
typed into the keypad.

Of course, there are always multiple way to do a particular task in 
Asterisk, and this method may not suit you.  Persons with other 
methods are welcome to submit them in response to my posting.

JT



More information about the asterisk-users mailing list