; -- Start Asterisk extensions.conf Config >=1.2 --
;
; 2005-12-18 jtodd@loligo.com  v1.1
;
; This is a reasonably complete, but minimalist, configuration
;  for an Asterisk server connected to a PBX, which provides
;  inbound SIP URI-to-extension mapping (which by default is
;  also ISN inbound mapping) and then also performs outbound
;  ISN dialing (PBX-to-SIP) conversion.  There is also basic
;  username-to-number mapping in a static file format (see
;  the comments below for the "usernames-to-numbers" context)
;
; This will be a quick instruction on how to make an Asterisk
;  server function as a very basic inbound session border
;  controller (SBC) which then will sit in front of an existing
;  PBX with a PRI attaching Asterisk to the PBX.
;
; Anyone elsewhere on the Internet dialing the ISN of
;  "1415551234*255" will be routed to extension "51234" on the
;  PRI, which then hopefully will ring the phone on the desk
;  of that person.  Similarly, dialing "51234*255" will go to
;  the same place.
;
; The second part of this dialplan is to take calls from
;  the PBX, and perform various ENUM lookups on them, or ISN
;  lookups if appropriate.  If there is a valid result from
;  either source, then the call will be directed to that 
;  SIP destination.  If there is no valid response, then the
;  PBX will be given a "Congestion" signal, which hopefully 
;  will cause the PBX to (in the case of an E.164 number)
;  fail over to a PSTN connection.  In the case of an ISN
;  dialing failure, a message will be played, as the call
;  cannot continue out any other path.
;
;  Further assumptions (all modifiable) will be:
;
;   - the PBX uses 5 digit extensions
;
;   - the PBX passes 5 digit extensions in as caller ID
;     for calls from the PRI
;
;   - the PBX routes all calls from all phones starting with
;     "012" in the dialed string to the PRI on this Asterisk
;     server.
;
;   - the PBX has PSTN connectivity that handles calls for
;     the E.164 ranges of 1-415-555-1xxx and 1-451-999-8xxx
;
;   - there are no "black" or "white" lists that are desired
;
;   - this demonstration server is called sip.bigu.edu, and
;     has matching forward/inverse records to that extent
;
;   - SRV records are in place for this domain, such that
;     requests to "51234@bigu.edu" get mapped to this server.
;     This means that the following line is in the zone file
;     in the "bigu.edu" level:
;
;      _sip._udp.bigu.edu. SRV 10 10 5060 sip.bigu.edu.
;
;   - the ISN for this demonstration is "255"
;
;   - the DNS for this ISN is (long line, careful of wraps):
;
;      *.255.freenum.org IN NAPTR 100 10 "u" "E2U+sip"
;      "!^\\+*([^\\*]*)!sip:\\1@sip.bigu.edu!" .
;
;      (yes, it's to "sip.bigu.edu" since it's pointless to force
;       an SRV lookup if this is a "behind-the-scenes" method.)
;       If you don't know what ISNs are, see:
;         http://www.internet2.edu/sip.edu/isn/
;       Don't worry if you don't understand or need this now; nothing
;        will break if you're not using ISN inbound.
;
;   - The PRI is configured to communicate with the PBX, and the PBX
;      is expecting the following patterns:
;         XXXXX       = local user, on-campus
;         1XXXXXXXXXX = Domestic US call
;         011X.       = International call (011 followed by 1 or more digits)
;         x11         = Handoff to appropriate CLASS feature (911, 411, etc.)
;      There are no "local" numbers with only seven digits in this
;       dialplan.  The luxury of seven digit PSTN dialing is over. 
;       Get used to it.  Furthermore, requiring a leading "1" for North
;       American calls eliminates a HUGE number of matching problems,
;       so that is also enforced for SIP users.  This is where PBX
;       dialplans and VoIP gateway dialplans get complex and disgusting,
;       so contact me if you can't make things work as expected and
;       I'll try to help.
;
;   - The PRI is on Zap/g1 ("group" 1).  Here are some demonstration
;      files, but you will probably need to read the docs to get
;      the correct configs if you require more advanced settings:
;
;      /etc/zaptel.conf:
;       loadzone = us
;       defaultzone = us
;       span=1,1,0,esf,b8zs
;       bchan=1-23
;       dchan=24
;
;      /etc/asterisk/zapata.conf:
;        group=1
;        context=from-pri
;        signalling=pri_net
;        switchtype=national
;        pridialplan=unknown
;        usecallerid=yes
;        channel => 1-23   
;    
;   - The sip.conf file has the following lines in it in the [general]
;      stanza:
;
;      ; Send calls from "the Internet" to the [from-internet] context
;      context=from-internet
;      ; Allow only "free" codecs.  You may change this to
;      ;  just ulaw and alaw if this is a CPU-constrained box.
;      disallow=all
;      allow=ulaw
;      allow=alaw
;      allow=gsm
;      allow=ilbc
;      allow=speex
;      ; Hang up any calls that don't have media flowing
;      rtptimeout=60
;
;  and at the end of sip.conf, add this Tello peer, but change the 
;    parameters to match your account.  To get a Tello account for your
;    PBX, go to http://www.tello.com/
;
;    [tello]
;    type=peer
;    username=9            ;your Tello ID number
;    secret=e98xza         ;your password
;    host=66.28.153.31     ;the Tello ZCR SIP proxy
;    insecure=very         ;accept inbound calls
;    context=from-internet ;context for Tello inbound
;    qualify=4000          ;max. latency for "heartbeat"
;
;
; If you want to use LDAP, this example does not cover that
;  example, as it is "advanced magic."  If you wish to give it
;  a try, see http://www.mezzo.net/asterisk/app_ldap.html for
;  an LDAPget lookup method that can be added to Asterisk.
;  Currently, Astlinux does not support the OpenLDAP libraries
;  and so this module is not included.  You could use a System
;  call to perform a wget or other web-based call to a remote
;  platform that does have LDAP on it...
;
;
;
;
[globals]
;
; These are some global values that each site will probably want
;  to change based on their local data.  They are used in the 
;  config in generic places.
;
; What SIP domain are you using?  Typically this is your "primary"
;  domain name, and you'll have SRV records pointed to this host,
;  but we're using this as the "From:" header data.
;
MYSIPDOMAIN=bigu.edu
;
;
; The IP address of this server.  Used for determining if certain
;  calls are destined for our own users, or somewhere else.
;
MYIPADDRESS=111.222.333.444
;
;
; Your "human-friendly" organization name (keep it very short)
;
ORGANIZATIONNAME=Big University
;
; Your local area code, if 7-digit calls need to have an NPA prefixed
;  onto them.
;
AREACODE=212
;
;
; ENUM zones we want to test.  If the string is empty, it won't be
;  tested.  Otherwise, any numbers coming from your PRI in e.164 format
;  will be tested in order against these ENUM (or ENUM-like) top-level
;  domains.  Careful with post-dial-delay here, folks... too many
;  trees gets busy.  Tello can do these in parallel...
;
ENUM-TREE1=e164.arpa
ENUM-TREE2=e164.org
ENUM-TREE3=
ENUM-TREE4=
;
;
; Tello, Inc. offers SIP lookups for inter-organization connections without
;  using ENUM and providing even cooler features.  See comments in
;  README.FIRST for details on reaching Tello.
;
;
;
[macro-setcid-uri]
;
; This Macro is used in several places to set caller ID. In calls from
;  the PRI outbound to SIP destinations, use the extension number
;  as the subscriber ID.
;
; In calls from sip-devices (like desktop softphones) we use the 
;  caller ID that was set in sip.conf for that device.
;
; Let's see if there is anything in the Caller ID Name that leads
;  us to think it's already a SIP URI.  Look for anything to the
;  right of an "@" sign... if nothing there, then it's probably not
;  a SIP URI.
;
exten => s,1,Set(rightampersand=${CUT(CALLERID(name),@,-)})
exten => s,n,GotoIf(${ISNULL(${rightampersand})}?setpri:endmacro)
;
; So, if we get to priority "setpri" then there was no URI-formatted
;  string in the Caller ID Name, so let's use the numeric extension
;  that we've been given.  There _better_ be a numeric extension...
; 
; First, configure an outbound caller ID which at least looks
;  like a SIP URI for the outbound call.
;
; We're going to assume that the ANI (callerid) extension of the PRI
;  call is valid, so re-set it with the SIPDOMAIN (i.e.: "bigu.edu") for
;  a complete SIP URI.  If the name field is null, then set the
;  caller ID name to $ORGANIZATIONNAME (i.e.: "Big University), 
;  otherwise leave alone.  This will result in a caller ID like:
;
;    From: "Jane Smith"<sip:12345@bigu.edu>
; or
;    From: "Big University"<sip:12345@bigu.edu>
;
; If you want to get more clever with matching caller ID digit sequences
;  to usernames via some external database, this is the place to do it.
;
exten => s,n(setpri),Set(${CALLERID(num)=${CALLERID(num)}@${MYSIPDOMAIN})
exten => s,n,GotoIf($["${CALLERID(name)"=""]?setid:endmacro)
exten => s,n(setid),Set(${CALLERID(name)=${ORGANIZATIONNAME})
exten => s,n(endmacro),NoOp
;
;
;
;
;
[from-internet]
;
; Catch all inbound numbers that seem to be for us, and send
;  them to context [from-internet2] with only the last five
;  digits of the dialed number.
;
; Note that for ISN dialing, the number of digits presented is
;  a function of the regular expression that is in the DNS for
;  your ISN zone.  Typically, the whole number will be passed
;  through to the receiving server instead of the regexp trying
;  to be clever.  Asterisk will do all the conversion work here, 
;  no matter what format the number is passed in as.
;
; ***EDIT THESE LINES TO MATCH YOUR LOCAL CONFIGURATIONS ***
;
exten => _14155551XXX,1,Goto(from-internet2,${EXTEN:6},1)
exten => _4155551XXX,1,Goto(from-internet2,${EXTEN:5},1)
exten => _51XXX,1,Goto(from-internet2,${EXTEN},1)
;
exten => _14159998XXX,1,Goto(from-internet2,${EXTEN:6},1)
exten => _4159998XXX,1,Goto(from-internet2,${EXTEN:5},1)
exten => _98XXX,1,Goto(from-internet2,${EXTEN},1)
;
;
; Include email-address style name context from an external
;  file called "usernames-to-numbers".  This is for true inbound SIP
;  username-to-extension mapping, so that "njersey@bigu.edu" will
;  end up ringing Dr. Jersey's desktop phone.
;
; The file "usernames-to-numbers" on the remote server should contain a context
;  and dialing  rules for each user which redirects the call flow to the
;  [from-internet2] context with their PBX extension number, like this:
;
; [usernames-to-numbers]
; exten => njersey,1,Goto(from-internet2,39914,1)
; exten => jsmallberries,1,Goto(from-internet2,39919,1)
;
; For external editing of this file from a different server, 
;  you could add a line that loads the file from a remote web 
;  server every time the extensions.conf file is re-loaded:
;
;#exec /mnt/kd/asterisk/fetch-user-context
;
; If you use this method, make sure to remove the ";" from the "exec" line,
;  but leave the "#" sign.
;
; There is a file called /mnt/kd/asterisk/fetch-user-context in
;  the standard distribution compact-flash versions of this astlinux
;  installation which will provide the ability to fetch specific files
;  from remote locations.  However, if you are doing this "from scratch" you
;  might need this file, so it is included here for cut-and-paste (make sure
;  to "chmod a+x /mnt/kd/asterisk/fetch-user-context"
;
; #!/bin/sh
; #
; # Start up wget, try to fetch the file in the background
; #
; /usr/bin/wget -O /mnt/kd/asterisk/username-dialplan.conf http://my.webserver.tld/username-dialplan.conf &
; #
; # Wait 15 seconds regardless of result...
; #
; sleep 15
; #
; # Now hand back the contents of the user-context file
; # via stdout...
; #
; /bin/cat /mnt/kd/asterisk/username-dialplan.conf
; #
; # end 
;
; This just uses "wget" to fetch a file from a remote server and
;  redirect the output into a "holding" file called username-dialplan.conf
;  file via stdout.  Regardless of the success or failure of the wget,
;  we wait for 15 seconds for the fetch to be attempted, and then
;  the contents of that file (hopefully a valid Asterisk context!) is
;  included in the main extensions.conf file.  If the fetch fails, the
;  system will read the most recently downloaded copy of the file so
;  that there is some minor "failsafe" capability.  See the [test-special]
;  context in the PRI sections of this file for how to allow remote
;  users to update this file by dialing a number.
; 
; Now that the "#exec" routine has created the context, include the
;  [usernames-to-numbers] context in this context for dialplan matching.
;
include => usernames-to-numbers
;
; Include some quick test destinations that can be used for
;  debugging by other people.  These are not standardized names
;  yet, but it seems that they're a good idea for a network of
;  experimental or test-heavy destionations.
;
include => tests
;
; If no matches are in any of the above rules, then the call
;  should be send to the "i"nvalid rule.  This will send a
;  SIP error back to the caller.
;
exten => i,1,Congestion
;
; If someone hangs up before this context quits, we need an
;  "h"angup extension.
;
exten => h,1,Hangup
;
; Advanced Dialplan-Fu: if you have another internal SIP
;  proxy, you could "include" a context in [from-internet]
;  which points usernames at alternate SIP URIs and actually
;  creates a SIP INVITE to them, like this:
; 
;  [more-usernames]
;  exten => reno,1,Dial(SIP/reno@pbx.cs.bigu.edu)
;  exten => ptommy,1,Dial(SIP/perfect@asterisk.ee.bigu.edu)
;
;
;
[from-internet2]
;
; Here is where we pass off the call onto the PRI.  The
;  call is capped at 3 hours (to prevent "zombies") and then
;  it is simply handed to the PRI, since we already normalized
;  the extensions to the "expected" numeric digits which
;  the PBX is looking for.
;
exten => _X.,1,Set(TIMEOUT(absolute)=10800)
;
; Now dial!  There are no parameters, since this system is
;  not acting as a voicemail system or doing any clever stuff
;  to the calls; this is purely a passthrough.  This might
;  sit and ring for 3 hours; nothing smart done here, it is
;  assumed that the PBX is handling errors and timers after this
;  handoff.
; We're using "g"roup 1, which means "any PRI trunks that aren't
;  being used for other things right now."
;
exten => _X.,n,Dial(Zap/g1/${EXTEN})
;
; If we get to priority 3, something is wrong.  Send congestion,
; hangup.
;
exten => _X.,n,Congestion
;
; Handle "T"imeouts, and "h"angups.
;
exten => T,1,Hangup
exten => h,1,Hangup
;
; This is the end of the "core" of the inbound-from-Internet
; dialplan.  Pretty simple, eh?
;
;
;
[tests]
;
;  Destinations used for testing purposes. 
;
; "echo": Set timer on this call to 500 seconds, play announcement,
;  echo
;
exten => 999,1,Goto(echo,1)
exten => echo,1,Set(TIMEOUT(absolute)=500)
exten => echo,2,Playback(demo-echotest)
exten => echo,3,Echo
;
; "date": Play date/time, hangup
;
exten => 998,1,Goto(date,1)
exten => date,1,Answer
exten => date,2,Wait(2)
exten => date,3,SayUnixTime
exten => date,4,Hangup
;
;
;
; ======================================
;
; This is for OUTBOUND lookups/calls, meaning from the PRI 
;  out to the Internet.
;
; This routine performs three possible functions:
;
;  1) Look up and route ISN numbers
;      If the number is ISN-formatted and fails, the system will
;      play back a failure message and hang up.
;
;  2) Look up and route ENUM destionations (E.164)
;      If the number does not have an ENUM entry in any of the
;      various ENUM trees consulted, the system will go to the
;      SIP proxies (method 3) to test for a match
;
;  3) Test-dial via other SIP proxies
;      If the SIP dialing method has no elements in it's list,
;      or there are no valid results from the remote SIP proxies
;      then the system will send a "Congestion" signal back down
;      the PRI.  At that time, the PBX should try sending the call
;      out a "normal" PSTN trunk.
;
;
; If the number has less than 7 digits, the call will immediately 
;  result in a "Congestion" tone.  7 digit numbers will have an 
;  area code and a leading "1" added to guess the intention.  Numbers
;  starting with "011" will be assumed as international. 
;  International numbers do not need to start with "011".
;
; The PBX should send calls with the digits "012" to the Asterisk
;  server, and leave everything else unmodified OR will take calls
;  with at least one digit, followed by *, followed by at least 
;  one digit.   Calls starting with "012" will be examined first.
;  This is the "leading" prefix for ISN dialing.
; The prefix for ISN numbers on this local system is "012" so
;  strip off those digits when presenting.  Your site may be
;  different.  The system will handle ISN dialing with or without
;  the leading three digit prefix.
;
; This method uses the "new" ENUMLOOKUP functions to look up ISN
;  numbers in the DNS.  The parsing for ISN numbers was
;  specifically included in the code, so no fancy re-writing of
;  the number is required by the dialplan administrator - Asterisk
;  takes care of the internal swapping and zone creation that turns
;  "1234*256" into "4.3.2.1.256" and then adds the zone.
;
; The ISN zone used is currently "freenum.org" as of 2005-11-22.  This
;  zone is subject to change; please see the http://www.freenum.org/
;  site for details, if available.
;
; This method uses the first SIP result from the list of valid
;  NAPTRs for an ISN lookup.  If you want to iterate through the
;  NAPTRs, then you will need to learn more about the ENUMLOOKUP
;  function and it's abilities - see "README.enum" in the docs
;  directory in the Asterisk source code tree.
;
; There is little error handling in this very brief example. 
;
; SPECIAL NOTE: Admittedly, these have not been tested with anyone's
;  "real" PBX.  Therefore, if your PBX sends overlap dial in certain
;  ways, it may not work correctly on the matching sequence.  If this
;  is the case, PLEASE contact John Todd (jtodd@loligo.com) and he
;  will attempt to come up with a site-specific workaround and then
;  include the notes in this example.
;
[from-pri]
;
; Force the ordering of "_012" first, then "_.*." second  and then
;  all other numbers last by using "include" to use evaluation ordering.
;
; At least one of these three included contexts should have a 
;  match, otherwise the call will get a "Congestion" signal back down
;  the PRI.
;
include => test-special
include => test-isn
include => test-isn2
include => test-e164
;
; Hang up on invalid or hangup error conditions.
exten => i,1,Congestion
exten => h,1,hangup
;
;
;
[test-special]
;
; This context is for a few "special" numbers that have meaning to this
;  local system.  Currently, the only special command that is included
;  is the ability to re-load the extensions file.  This is for use when
;  there is an external file that maps usernames-to-numbers which is
;  updated by an administrative person.  If the file on the external 
;  webserver is changed, Asterisk needs to be told to re-read the file and
;  use it in the dialplan.  Four ways exist to tell Asterisk that it needs
;  to execute an "extensions reload" command:
;  1) ssh to the machine, run "asterisk -rc" and type "extensions reload"
;  2) ssh -l root@the.soekris.box "asterisk -rx extensions reload"
;  3) Log into the Astlinux web interface with administrator rights, and
;     execute an Asterisk shell command of "extensions reload"
;  4) Create a special extension that when called will perform the 
;     command.
; This single line assumes that the "magic" extension of 12345 has been
;  routed to the PRI, and that it will only be used by the person who
;  is administering the file on that webserver.
;
; YOU WILL NEED TO CHANGE THIS NUMBER AND UNCOMMENT THESE LINES IF YOU WANT
;  TO PROVIDE THIS ABILITY.
;
;exten => 12345,1,System(/usr/sbin/asterisk -rx "extensions reload")
;exten => 12345,2,Answer
;exten => 12345,3,Wait(2)
;exten => 12345,4,Playback(good)
;exten => 12345,5,Wait(2)
;exten => 12345,6,Hangup
;
;
;
[test-isn]
;
; Match on the prefix of "012" followed by one or more digits,
;  followed by a "*", followed by one or more digits.  Also match on a
;  straight ISN (one or more digits starting with 1-9 as the first
;  digit, followed by "*", followed by one or more digits.)
;
; If a match is found, jump to the [dial-isn] context to create the SIP
;  call.  The PRI channel will then be connected to the SIP channel.
;
exten => _012.*.,1,Goto(dial-isn,${EXTEN:3},1)
;
;
[test-isn2]
;
; We'll also match on any dialstring that contains all numerics and
;  has inside it an "*" character somewhere separating at least two
;  strings of numbers, each consisting of at least one digit.
; This is for those of you who are clipping any sort of special prefix
;  out within your PBX.  Even if you are not removing the special 
;  prefix on your PBX, this will not cause any harm since only numbers
;  with "*" in them are match (which is impossible on E.164 calls, so
;  no worries.)
;
exten => _.*.,1,Cut(itad=EXTEN,*,2)
exten => _.*.,n,GotoIf($[${LEN(${itad})} < 1]?bad-announce|${EXTEN}|1)
exten => _.*.,n,Cut(subscriber=EXTEN,*,1)
exten => _.*.,n,Gotoif($[${LEN(${subscriber})} < 1]?bad-announce|${EXTEN}|1:dial-isn|${EXTEN}|1)
;
;
[test-e164]
;
; We're starting to build our "include" statements here.  Since we have 
;  a lot of wildcards, many of which could match, we have to force ordering
;  so that the "best" ones match first.
;
include => test-e164.1
include => test-e164.2
include => test-e164.3
include => test-e164.4
include => test-e164.5
include => test-e164.6
include => test-e164.7
include => test-e164.8
include => test-e164.9
include => test-e164.10
;
exten => h,1,Hangup
exten => T,1,Hangup
exten => i,1,Congestion
;
;
[test-e164.1]
;
; Now, let's match on all other numbers.  We have a bias towards North
;  American numbers, so let's do a little cleanup for those systems which
;  are too dumb or ossified to allow flexible number plans... check for
;  NANP numbers with a leading "1" or without...
;
; Add leading "1" to ten digit numerics, and loop. 
;  ***NOTE***: Your site may not require this.  Think about this carefully.
;
exten => _XXXXXXXXXX,1,Goto(test-e164,1${EXTEN}),1)
;
; We've found a match for a ten-digit number starting with "1", which
;  means a possible North American destination.  Jump out.
;
exten => _1XXXXXXXXXX,1,Goto(dial-e164,${EXTEN},1)
;
;
[test-e164.2]
;
; Remove leading "011", which is the three-digit prefix for "international"
;  calls in North America.  We just want to use the E.164 number; no leading
;  digits.  Strip "011" digits, and loop.
;
exten => _011.,1,Goto(test-e164,${EXTEN:3},1)
;
;
[test-e164.3]
; If the number is only 7 digits, add the "local" area code, loop.  Yuck.
;  ***NOTE***: This is REALLY REALLY ugly.  Hopefully your site does not
;  need this line, and you can just comment it out.  Your PBX/switch should
;  be trying to append an area code to all outbound calls, but just in case
;  it doesn't, we prefix with the area code (specified at the top of this
;  file in variable AREACODE) and a leading "1".  This is site-specific and
;  may need to be modified.
;  
;
exten => _XXXXXXX,1,Goto(test-e164,1${AREACODE}${EXTEN},1)
;
;
[test-e164.4]
; If the number is less than 7 digits, dump to congestion immediately since
;  that is almost certainly not a valid full E.164 number. (Can anyone prove
;  that this is not a sufficient test?)
;
exten => _XXXXXX,1,Congestion
[test-e164.5]
exten => _XXXXX,1,Congestion
[test-e164.6]
exten => _XXXX,1,Congestion
[test-e164.7]
exten => _XXX,1,Congestion
[test-e164.8]
exten => _XX,1,Congestion
[test-e164.9]
exten => _X,1,Congestion
;
;
[test-e164.10]
; Now, if we've gone this far down the matching tree, it means that
;  the number is probably a non-North American destination having more
;  than seven digits and not starting with "011". Jump out and let's 
;  assume it's valid.
;
exten => _X.,1,Goto(dial-e164,${EXTEN},1)
;
;
;
;
[dial-isn]
;
; An ISN-formatted dialing pattern was detected!  Time to try
;  the actual call with the results, or play an error.
;
; Let's set the Caller ID correctly on our attempt...
;
exten => _X.,1,Macro(setcid-uri)
;
; Now, set a maximum timer on the call to prevent zombies (3 hours)
;
exten => _X.,n,Set(TIMEOUT(absolute)=10800)
;
; Do the ENUMLOOKUP on the number in the "freenum.org" zone... 
;  This is where we actually look up the ISN number in the DNS and
;  get back a SIP record as a result.  This is a very simple 
;  implementation, and we only look for the first SIP record.
;
exten => _X.,n,Set(isnresult=${ENUMLOOKUP(${EXTEN},sip,i,freenum.org)})
;
; If the result is not null, dial the SIP destination.  If no
;  answer in 100 seconds, go to an error message.  This ends the
;  process in either case (success or failure.)
;
exten => _X.,n,GotoIf($["${isnresult}"=""]?failed:success)
exten => _X.,n(success),Dial(SIP/${isnresult},100)
;
; The lookup failed, so we should play back an "invalid number" message
;  to the caller twice, and then hang up.  
;
exten => _X.,n(failed),Answer
exten => _X.,n,Playback(invalid)
exten => _X.,n,Wait(3)
exten => _X.,n,Playback(invalid)
exten => _X.,n,Hangup
;
;
; Include standard failure mode extensions for "h"angup,
;  "T"imeout, and "i"nvalid results
;
exten => h,1,Hangup
exten => i,1,Hangup
exten => T,1,Hangup
;
;
;
[dial-e164]
;
; There are two sub-parts to the E.164 dialing routines.
;  First is the ENUM lookups.  You can specify which ENUM trees you
;  wish to search by giving values to the ENUM-TREEx variables
;  in the [globals] section at the top of the file.
;
; Note: if you are using Tello services, you may want to do NO
;  ENUM lookups, since Tello can integrate these lookups in their
;  SIP query, in parallel (_much_ faster.)
;
; The second part of the E.164 process will attempt to dial the 
;  number using SIP peers.  The only peer that is configured
;  is the Tello peer, but others can be placed here as well.
;  These might be SIP proxies that have a larger number of 
;  endpoints that they know about or can connect you to, or
;  even some that might connect to PSTN endpoints.
;
;
;  First, we'll test the number to see if there is an ENUM result...
;
exten => _X.,1,GotoIf($["${ENUM-TREE1}"=""]?4:2)
exten => _X.,2,Set(enum-result=${ENUMLOOKUP(${EXTEN},sip,1,${ENUM-TREE1})}
exten => _X.,3,GotoIf($["${enum-result}"=""]4:20)
;
exten => _X.,4,GotoIf($["${ENUM-TREE2}"=""]?7:5)
exten => _X.,5,Set(enum-result=${ENUMLOOKUP(${EXTEN},sip,1,${ENUM-TREE2})}
exten => _X.,6,GotoIf($["${enum-result}"=""]7:20)
;
exten => _X.,7,GotoIf($["${ENUM-TREE3}"=""]?10:8)
exten => _X.,8,Set(enum-result=${ENUMLOOKUP(${EXTEN},sip,1,${ENUM-TREE3})}
exten => _X.,9,GotoIf($["${enum-result}"=""]10:20)
;
exten => _X.,10,GotoIf($["${ENUM-TREE4}"=""]?13:11)
exten => _X.,11,Set(enum-result=${ENUMLOOKUP(${EXTEN},sip,1,${ENUM-TREE4})}
exten => _X.,12,GotoIf($["${enum-result}"=""]13:20)
;
; We get to priority 13 if there were no matches in any of the trees, or
;  all the ENUM-TREEx values were empty. Jump to the next dialing method.
;
exten  => _X.,13,Goto(dial-e164.2,${EXTEN},1)
;
; One of the ENUM trees came back with a non-null answer, so try
;  to dial it.  First, set the caller ID appropriately...
;
exten => _X.,20,Macro(setcid-uri)
;
; ...and try the dial. Either it works, or it doesn't, but here
;  is the end of our dialplan for this test if we go this route.
;
exten => _X.,21,Set(TIMEOUT(absolute)=10800)
exten => _X.,22,Dial(SIP/${enum-result})
exten => _X.,23,Congestion
;
; Include standard extensions
;
exten => h,1,Hangup
exten => T,1,Hangup
exten => i,1,Hangup
;
;
;
[dial-e164.2]
;
; So, no valid ENUM lookups, so let's try sending to Tello.  Tello
;  will try to match this in their internal database, and possibly through
;  various ENUM trees (therefore, making the previous ENUM lookups redundant
;  if you have Tello service...)
;
; Set the timers, set the callerID, try to dial, and if we fail send a 
;  congestion signal.  Easy!  This is the end of the road for PRI-to-VoIP
;  paths.  If it's all failed at this point, the call can't be completed
;  out VoIP to the knowledge of this system.
;
; If you don't have Tello service, this will fail and won't add any significant
;  delay to the process, so you can probably leave it in without worry.  To 
;  activate your Tello service, go into "sip.conf" and uncomment the Tello section
;  of the file and add your account information/password data as has been 
;  provided by Tello.
;
; Now, if this is NOT a PRI-to-VoIP call, we should have something filling the
;  "E164NUMBER" variable, since that is set in sip.conf for every SIP phone
;  that is attached to this system.  Therefore, if that variable is not null,
;  then we should try dialing whatever the original dialed number is on the PRI
;  channel.  If it IS null, then we're dealing with a PRI-to-VoIP call, and
;  we should go no further since we don't want to loop back into the PRI.
;
exten => _X.,1,Set(TIMEOUT(absolute)=10800)
exten => _X.,n,Macro(setcid-uri)
exten => _X.,n,Dial(SIP/${EXTEN}@tello)
exten => _X.,n,GotoIf($[ "${E164NUMBER}" = ""]?endcall:dialzap)
exten => _X.,n(endcall),Congestion

; If we get here, it means that we've failed all of the IP-based methods for
;  handing off this call.  At this point, just use the original number that was
;  dialed, and pass the call off to the PBX via the Zap channels after setting
;  the caller ID number to be equal to the number that is set in the sip.conf
;  file for this SIP user-agent.  This is the end of the line for SIP UA
;  calls if they have not been previously matched.
;
exten => _X.,n(dialzap),Set(${CALLID(num)=${E164NUMBER})
exten => _X.,n,Dial(Zap/g1/${ORIGNUMBER})
exten => _X.,n,Congestion
;
; Include standard extensions...
;
exten => h,1,Hangup
exten => T,1,Hangup
exten => i,1,Hangup
;
;
;
[bad-announce]
; This routine is where calls to unknown extensions are sent,
;  and this reads back the number in question.  Very useful for
;  debugging.
;
; Since there is a wildcard for _all_ destinations in here, we
;  have to "include" some standard extension in to force the order
;  of evaluation, otherwise the wildcard would get even "h" or 
;  "T" extensions ("h"angup or "T"imeout.)
;
include => bad-announce1
include => bad-announce2
;
[bad-announce1]
; 
; "special" meaning clauses go here, otherwise the uber-wildcard
;  would match them, causing an endless loop.
;
exten => h,1,Hangup
exten => T,1,Hangup
exten => t,1,Hangup
exten => fax,1,Hangup
;
;
[bad-announce2]
;
; Global match (dangerous wildcard of "_.") for all values
;
exten => _.,1,Set(TIMEOUT(absolute)=90)
exten => _.,n,Answer
exten => _.,n,Wait(2)
exten => _.,n,Playback(that-is-not-rec-phn-num)
exten => _.,n,SayPhonetic(${EXTEN})
exten => _.,n,Wait(2)
exten => _.,n,Playback(that-is-not-rec-phn-num)
exten => _.,n,SayPhonetic(${EXTEN})
exten => _.,n,Playback(goodbye)
exten => _.,n,Hangup



[from-sip-clients]
;
; The matching of SIP records is fairly difficult, so this is not by any
;  means a simple section, nor is it 100% robust.  However, it will catch
;  almost any common mappings.
;
; Here is the main context for handling calls that come from SIP UA
;  clients on the desktop.  These can be hardphones or softphones; 
;  see the configuration for each extension in sip.conf.
;
; Due to the complexity of this configuration model, we will be using
;  usernames as the "Caller ID" for calls, except for when the call
;  ends up on the PBX.  For those calls, we have set a variable in
;  sip.conf for each SIP "user" which equates to their local E.164
;  number.  If your organization doesn't have a one-to-one mapping
;  of "real" telephone numbers to users, then significant modification
;  of this section will have to be done, or you'll simply have to
;  set the E164NUMBER value in sip.conf for all users to be equal
;  to the "main" number for your campus.
;
; Further note that Asterisk is a B2BUA.  It doesn't even try to be a
;  proxy.  This also means that the identity of all calls are altered
;  and "created" by Asterisk - the UA does not have any say in the 
;  matter.  This is desirable in some cases, undesirable in others.
;  It is possible to have Asterisk pass through everything from the UA
;  but this is somewhat longer a configuration example than is necessary
;  for this platform.
;
; We first must test to see if this SIP URI is destined for ourselves, or
;  is destined for elsewhere.  This decision needs to be first, since we
;  cannot match on domain within the extension itself, so we must look at
;  other variables.   If it's for outside of our domain, hand the call off.
;  If it is for inside our domain to a user OR to an sequence of digits
;  that maps to a valid path on the PRI (extension, or E164 number, or 
;  what-have you) then handle it appropriately.
;
; We first check to see if the called "number" is a SIP URI by matching
;  on strings that contain strings.  If it is, then see if the domain
;  part is this server (or the domain served by this server.)  If so, strip
;  off the domain part and loop.  Otherwise, dial the URI.
; 
; The $MYSIPDOMAIN and $MYIPADDRESS were defined in the [globals] section.
;
; SIPDOMAIN is a built-in variable that equals everything to the right of
;  the @ sign in a dialstring.  We first strip off any trailing port numbers
;  or anything after a ":" so we can test match on this host/domain.
; 
; Note: this will not match on single-letter usernames.  Sorry.
;
; Note: this may fire off a bunch of warnings about "wildcards of _. are dangerous"
;  You can ignore those warnings.  It's dangerous, but necessary here.
;
;
; Very first thing: remember the number that was originally dialed.
;
exten => _.,1,Set(ORIGNUMBER=${EXTEN})
;
; Next, set SIP domain values...
;
exten => _.,n,Cut(SHORTSIPDOMAIN=SIPDOMAIN,:,1)
exten => _.,n,Cut(SIPUSER=EXTEN,@,1)
;
; Check to see if $SIPDOMAIN equals the caller's $SHORTSIPDOMAIN.  If yes, send 
;  to the next context with just the user as the new dialed extension. 
;  If not, continue tests.
;
exten => _.,n,GotoIf($[${MYSIPDOMAIN} = ${SHORTSIPDOMAIN}]?from-sip-clients2|${SIPUSER}|1:sipcheck2)
;
; Check to see if $MYIPADDRESS is equal to $SHORTSIPDOMAIN.  If so, send the
;  call to the next context with just the user as the new dialed extension.
;  If not, dial the number because the domain part of the URI was not some
;  variation of this server's IP address or domain.
;
exten => _.,n(sipcheck2),GotoIf($[${MYIPADDRESS} = ${SHORTSIPDOMAIN}]?from-sip-clients2|${SIPUSER}|1:extern-dial)
;  
; So, the string was not a local user, therefore it must be either garbage or
;  a valid SIP URI.  To determine if the string is garbage would take a very,
;  very intense set of parsing routines. Therefore, punt and just try to dial
;  it.  If it's invalid, it will fail, otherwise it will succeed.  You may
;  wish to put some logging in here (like with a System call that dumps some
;  values to a text file somewhere) so you can see who is dialing what and
;  what the string values are other than what shows up in the /var/log/asterisk/
;  logfiles.
;
exten => _.,n(extern-dial),Dial(SIP/${EXTEN}@${SIPDOMAIN},100,rt)
;
; The call failed.  Jump to congestion.  End of the line.
;
exten => _.,n,Congestion
;
;
;
[from-sip-clients2]
;
; Now, search through various contexts to see if the number or URI that has been
;  dialed by the SIP client/user-agent can be found in any of the contexts
;  that we have in this system.  Check usernames, test extensions, PRI extensions,
;  and finally test against E.164 numbering.  If there are no matches, the system
;  will attempt to send the call out on the PRI using the number originally dialed
;  by the SIP client, which is why "test-e164" is last in the inclusion list.
;
include => usernames
include => tests
include => test-extensions
include => test-isn
include => usernames-to-numbers
include => test-e164
;
; Include standard extensions...
;
exten => h,1,Hangup
exten => T,1,Hangup
exten => i,1,Hangup
;
;
[usernames]
;
; Any of your entries in sip.conf need to have an equivalent extension mapping
;  here if you wish them to be dialed.  These will be extremely simple mapping
;  demonstrations - no voicemail, no dual-ring, no interesting paths for failed
;  calls.  This is a very plain config.  Note that the context which may or may
;  not be imported from an external file called [usernames-to-numbers] also may
;  overlap with this context - make sure you use "include" correctly to always search
;  this context first.  The purpose for this context is for user-agents (SIP 
;  devices) which are local, while the usernames-to-numbers is to convert for
;  users who don't have SIP devices but are reachable on an extension on the
;  PBX via the PRI.  The URI that external users use looks the same in it's syntax,
;  but the destinations are different from Asterisk's perspective.
;
exten => thikita,1,Dial(SIP/thikita)
exten => thikita,2,Congestion
;
;



