Fun times with Asterisk dialplan logic
-
Here is the kind of advanced stuff I play with in FreePBX.
[macro-dialout-trunk-predial-hook] exten => s,1,NoOp() ; Skip if this is an emergency call exten => s,n,GotoIf($["${EMERGENCYROUTE}"=="YES"]?emergencyrouteused) ; Check if the call has already been validated to go out, and skip the rest of the processing exten => s,n,GotoIf($["${OUTBOUND_ROUTE_NAME}"=="Call_Validated_to_go_Out"]?skipvalidation) ; Depending on the outbound route send the call to be validated ; NANPA style number dialed with a code exten => s,n,GotoIf($["${OUTBOUND_ROUTE_NAME}"=="NANPA_Dialed_with_Code"]?validatenanpa,s,1) ;More logic coming. For now, dump channel and terminate call. exten => s,n,DumpChan exten => s,n,Hangup() ; The call was an emegerncy dial, do no processing, but note the log. exten => s,n(emergencyrouteused),NoOp() exten => s,n,Log(NOTICE, 911 was dialed by extension ${FROMEXTEN}) ; The call was validated, nothing else to do. exten => s,n(skipvalidation),NoOp()
[validatenanpa] exten => s,1,NoOp() ; NANPA format means digit zero is 7 or 8 and digit one is a 1 ; digits two through ten should be a 10 digit number ; the last five digits are the AUTCODE exten => s,n,Set(USERDIALED=${OUTNUM:2:10}) exten => s,n,Set(AUTCODE=${OUTNUM:-5}) ; Go check for a valid code exten => s,n,Set(RETURNTOCONTEXT=validatenanpa) exten => s,n,GoTo(checkvalidautcode,s,1) ; Return location if AUTCODE is valid exten => s,n(autcodevalid),NoOp() ; Check if the AUTCODE has a CID associated with it. exten => s,n,Set(AUTCODECIDNUM=${GET_AUTCODECID(${AUTCODE})}) ; If there is no CID jump to autcidno, otherwise autcidyes exten => s,n,GotoIf($["${AUTCODECIDNUM}" == ""]?autcidno:autcidyes) exten => s,n,Hangup() exten => s,n(autcidyes),NoOp() exten => s,n,Log(NOTICE, The AUTCODE of ${AUTCODE} has an associated CID of ${AUTCODECIDNUM}. Forcing it to apply. exten => s,n,Set(TRUNKCIDOVERRIDE=${AUTCODECIDNUM}) exten => s,n(autcidno),NoOp() ; Go back to outbound route logic with the "secret" prefix of 8675309 (Jenny) that will match the pattern to get to an outboud trunk exten => s,n,Goto(outbound-allroutes,8675309${USERDIALED},1) exten => s,n,Hangup()
; This context checks that the AUTCODE value (last five digits) exists in the `autcodes` table ; See func_odbc.conf for the SQL statement. ; This context requires that the variable RETURNTOCONTEXT be set in by the context that calls it ; This context also requres that the calling context have a line labeled autcodevalid to return to [checkvalidautcode] exten => s,1,NoOp() ; Start a rety counter. exten => s,n,Set(RETRYCODE=0) ; If code is invalid, user is prompted to try again and the call is sent back to here exten => s,n(tryagain),NoOp() ; Check the database for the autcode. SQL query returns the `id` of the row if found exten => s,n,Set(AUTCODEID=${GET_VALIDATEAUTCODE(${AUTCODE})}) ; if no rows are returned jump to badaut, if something is returned jump to goodaut exten => s,n,GotoIf($[${ODBCROWS} = 0]?badaut,1:goodaut,1) exten => s,n,Hangup() exten => badaut,1,NoOp() exten => badaut,n(notfound),Log(NOTICE, The AUTCODE of ${AUTCODE} was not found, user needs to try again) ; Increment the fail counter exten => badaut,n,Set(RETRYCODE=$[${RETRYCODE} + 1]) ; If the user has failed 3 times (or more somehow) jump to toomanytries exten => badaut,n,GotoIf($[${RETRYCODE} >= 3]?toomanytries,1) ; Tell them the code was bad and to try again exten => badaut,n,Playback(you-entered) exten => badaut,n,Playback(access-code) exten => badaut,n,SayDigits(${AUTCODE}) exten => badaut,n,Playback(vm-pls-try-again) exten => badaut,n,Set(TIMEOUT(response)=10) exten => badaut,n,Read(AUTCODE,access-code,5,,2,5) ; If the entered code was 5 digits jump back up to try again, otherwise jump up to not found exten => badaut,n,GotoIf($[${LEN(${AUTCODE})}==5]?s,tryagain:notfound) exten => badaut,n,Hangup() exten => goodaut,1,NoOp() exten => goodaut,n,Log(NOTICE, The AUTCODE of ${AUTCODE} was found, let call proceed) ; The code was found, so go back to the context that we came from at the spot marked autcodevalid exten => goodaut,n,GoTo(${RETURNTOCONTEXT},s,autcodevalid) exten => goodaut,n,Hangup() exten => toomanytries,1,NoOp() exten => toomanytries,n,Log(NOTICE, The user failed to enter a valid AUTCODE too many times) ; The user the dialed the code wrong too many times, hangup the call exten => toomanytries,n,Playback(sorry) exten => toomanytries,n,Playback(goodbye) exten => toomanytries,n,Hangup()
-
I appreciate your liberal use of comments in your files even if it all means nothing to me
Would you mind giving a quick overview on exactly what is happening here for those of us who haven't played with Asterisk's conf files? -
Start with a normal outbound route named
NANPA_Dialed_with_Code
.
Give it a dialpattern of [78]1NXXNXXXXXXXXXXXWhen a user dials 81800555121298765 it will match that pattern for this outbound route. The outbound route will send the call to a trunk.
Prior to the call getting to the trunk, the the built in context named
[macro-dialout-trunk-predial-hook]
is executed.The first thing it does is check if the call was routed via a route marked emergency, if so, jump to that label.
If not, it checks the name of the route used as shown. Since it matches one of the if logics, it jumps to the context
validatenanpa
at position s,1.This context pulls apart the number as noted in the comments and then attempts to validate the autcode (short for authorization code).
If you cannot follow the logic from there, me explaining more wont really help..
-
@JaredBusch said in Fun times with Asterisk dialplan logic:
NANPA
Perfect, that was very helpful and makes it perfectly clear.
-
@manxam said in Fun times with Asterisk dialplan logic:
@JaredBusch said in Fun times with Asterisk dialplan logic:
NANPA
Perfect, that was very helpful and makes it perfectly clear.
This NANPA: https://en.wikipedia.org/wiki/North_American_Numbering_Plan
Not this one, it is totally different: https://en.wikipedia.org/wiki/Nanpa (Thank you Japan)
-
So I was at my computer and thought I would share a few screenshots.
Here is the outbound route list.
This is what the Dial Pattenr looks like for one of them.
Both of those NANPA routes send to the
Catch_All
trunk.Trunks available
This trunk would simply hangup the call if a call actually gets to it.
But calls never get to that trunk as noted in the previous posts.
-
@JaredBusch : Funny that you posted that as I actually had to go LOOK UP NANPA when you had mentioned it above and, at first, wondered what it had to do with the Japanese dating scene..