Basic Asterisk Configuration

Once Asterisk is up and running, you should check the configuration files that were built by install to see that they are generally copacetic. Here are some things that you should look for.

At the top of /etc/asterisk/indications.conf, under the "[general]" section, check that the country is correct for the switch's location.

     country = us

Edit /etc/asterisk/modules.conf and uncomment the lines that preload the ODBC modules:

     preload => res_odbc.so
     preload => res_config_odbc.so

Also, add these lines to the end of the file to stop automatic loading of the modules in question:

     ;
     ; Local customization: modules not loaded.
     ;
     noload => pbx_ael.so
     noload => codec_dahdi.so

We can get rid of the AEL (Asterisk Extension Language) config file because nobody uses this dubious feature:

     su
     mv /etc/asterisk/extensions.ael /etc/asterisk/extensions.ael.orig

or, if you don't think you'll ever need it:

     su
     rm -f /etc/asterisk/extensions.ael

Also, we can get rid of the demo file because we're going straight to a working system (yeah, right):

     rm /etc/asterisk/extensions.lua

The extensions.conf file defines the dial plan used by Asterisk and can include a complete description of all the extensions used by the system. However, we prefer to keep it generalized and put all of the special definitions of local lines and extensions into separate files in a "local" subdirectory off of the main "asterisk" directory. To do this, create the "local" directory:

     su
     mkdir /etc/asterisk/local
     chown root:root /etc/asterisk/local
     chmod u=rwx,go=rx /etc/asterisk/local

Local configuration information can be put in one or more files in the "local" subdirectory and included in extensions.conf like this:

     #include local/variables.conf
     #include local/ivr-menutree.conf
     #include local/plan-features.conf
     #include local/plan-outsidelines.conf
     #include local/dahdi-extensions.conf
     #include local/dahdi-colines.conf

Now, we can change the extensions.conf configuration file so that it is generalized and all extensions work more like the way we want them to. Make the changes to the general section, shown here:

     [general]
          .
          .
          .
     writeprotect=yes
     autofallthrough=yes
     clearglobalvars=yes

Then, get rid of all the sections (e.g. dundi and iaxtel) that you don't need, along with all of the example contexts that aren't required. Keep the stdexten context, add the recordivr macro and include all of the local configuration files. Get rid of the demo.

Add Do Not Disturb, Call Forward and Busy Call Forward checking to the stdexten and stdPrivacyexten functions so that the caller will be sent straight to voicemail, if the user sets Do Not Disturb on their extension (see the Adding Special Features To The Dialplan section, below), or forwarded to another extension (either directly or as the result of BUSY or NOANSWER).

Remove the inclusion of the parking lot context. We'll take care of that in one of our local files.

Here is our complete, tuned up file:

/etc/asterisk/extensions.conf:

     ; extensions.conf - the Asterisk dial plan
     ;
     ; Static extension configuration file, used by
     ; the pbx_config module. This is where you configure all your 
     ; inbound and outbound calls in Asterisk. 
     ; 
     ; This configuration file is reloaded 
     ; - With the "dialplan reload" command in the CLI
     ; - With the "reload" command (that reloads everything) in the CLI
     ;
     ; The "General" category is for certain variables.  
     ;
     [general]
     ;
     ; If static is set to no, or omitted, then the pbx_config will rewrite
     ; this file when extensions are modified.  Remember that all comments
     ; made in the file will be lost when that happens. 
     ;
     ; XXX Not yet implemented XXX
     ;
     static=yes
     ;
     ; if static=yes and writeprotect=no, you can save dialplan by
     ; CLI command "dialplan save" too
     ;
     ;writeprotect=no
     writeprotect=yes
     ;
     ; If autofallthrough is set, then if an extension runs out of
     ; things to do, it will terminate the call with BUSY, CONGESTION
     ; or HANGUP depending on Asterisk's best guess. This is the default.
     ;
     ; If autofallthrough is not set, then if an extension runs out of 
     ; things to do, Asterisk will wait for a new extension to be dialed 
     ; (this is the original behavior of Asterisk 1.0 and earlier).
     ;
     ;autofallthrough=no
     autofallthrough=yes
     ;
     ;
     ;
     ; If extenpatternmatchnew is set (true, yes, etc), then a new algorithm that
     ; uses a Trie to find the best matching pattern is used. In dialplans
     ; with more than about 20-40 extensions in a single context, this
     ; new algorithm can provide a noticeable speedup. 
     ; With 50 extensions, the speedup is 1.32x
     ; with 88 extensions, the speedup is 2.23x
     ; with 138 extensions, the speedup is 3.44x
     ; with 238 extensions, the speedup is 5.8x
     ; with 438 extensions, the speedup is 10.4x
     ; With 1000 extensions, the speedup is ~25x
     ; with 10,000 extensions, the speedup is 374x
     ; Basically, the new algorithm provides a flat response 
     ; time, no matter the number of extensions.
     ;
     ; By default, the old pattern matcher is used. 
     ;
     ; ****This is a new feature! *********************
     ; The new pattern matcher is for the brave, the bold, and 
     ; the desperate. If you have large dialplans (more than about 50 extensions
     ; in a context), and/or high call volume, you might consider setting 
     ; this value to "yes" !!
     ; Please, if you try this out, and are forced to return to the
     ; old pattern matcher, please report your reasons in a bug report
     ; on bugs.digium.com. We have made good progress in providing something
     ; compatible with the old matcher; help us finish the job!
     ;
     ; This value can be switched at runtime using the cli command "dialplan set
     ; extenpatternmatchnew true" or "dialplan set extenpatternmatchnew false",
     ; so you can experiment to your hearts content.
     ;
     ;extenpatternmatchnew=no
     ;
     ; If clearglobalvars is set, global variables will be cleared 
     ; and reparsed on a dialplan reload, or Asterisk reload.
     ;
     ; If clearglobalvars is not set, then global variables will persist
     ; through reloads, and even if deleted from the extensions.conf or
     ; one of its included files, will remain set to the previous value.
     ;
     ; NOTE: A complication sets in, if you put your global variables into
     ; the AEL file, instead of the extensions.conf file. With clearglobalvars
     ; set, a "reload" will often leave the globals vars cleared, because it
     ; is not unusual to have extensions.conf (which will have no globals)
     ; load after the extensions.ael file (where the global vars are stored).
     ; So, with "reload" in this particular situation, first the AEL file will
     ; clear and then set all the global vars, then, later, when the
     ; extensions.conf file is loaded, the global vars are all cleared, and then
     ; not set, because they are not stored in the extensions.conf file.
     ;
     ;clearglobalvars=no
     clearglobalvars=yes
     ;
     ; If priorityjumping is set to 'yes', then applications that support
     ; 'jumping' to a different priority based on the result of their operations
     ; will do so (this is backwards compatible behavior with pre-1.2 releases
     ; of Asterisk). Individual applications can also be requested to do this
     ; by passing a 'j' option in their arguments.
     ;
     ;priorityjumping=yes
     ;
     ; User context is where entries from users.conf are registered.  The
     ; default value is 'default'
     ;
     ;userscontext=default
     ;
     ; You can include other config files, use the #include command
     ; (without the ';'). Note that this is different from the "include" command
     ; that includes contexts within other contexts. The include command works
     ; in all asterisk configuration files.
     ;include "filename.conf"
     ;include <filename.conf>
     ;include filename.conf
     ;
     ; You can execute a program or script that produces config files, and they
     ; will be inserted where you insert the #exec command. The exec command 
     ; works on all asterisk configuration files.  However, you will need to
     ; activate them within asterisk.conf with the "execincludes" option.  They
     ; are otherwise considered a security risk.
     ;exec /opt/bin/build-extra-contexts.sh
     ;exec /opt/bin/build-extra-contexts.sh --foo="bar"
     ;exec </opt/bin/build-extra-contexts.sh --foo="bar">
     ;#exec "/opt/bin/build-extra-contexts.sh --foo=\"bar\""
     ;
     ; The "Globals" category contains global variables that can be referenced
     ; in the dialplan with the GLOBAL dialplan function:
     ; ${GLOBAL(VARIABLE)}
     ; ${${GLOBAL(VARIABLE)}} or ${text${GLOBAL(VARIABLE)}} or any hybrid
     ; Unix/Linux environmental variables can be reached with the ENV dialplan
     ; function: ${ENV(VARIABLE)}
     ;
     [globals]
     CONSOLE=Console/dsp                          ; Console interface for demo
     ;CONSOLE=DAHDI/1
     ;CONSOLE=Phone/phone0
     IAXINFO=guest                                ; IAXtel username/password
     ;IAXINFO=myuser:mypass
     TRUNK=DAHDI/G2                               ; Trunk interface
     ;
     ; Note the 'G2' in the TRUNK variable above. It specifies which group (defined
     ; in chan_dahdi.conf) to dial, i.e. group 2, and how to choose a channel to
     ; use in the specified group. The four possible options are:
     ;
     ; g: select the lowest-numbered non-busy DAHDI channel
     ;    (aka. ascending sequential hunt group).
     ; G: select the highest-numbered non-busy DAHDI channel
     ;    (aka. descending sequential hunt group).
     ; r: use a round-robin search, starting at the next highest channel than last
     ;    time (aka. ascending rotary hunt group).
     ; R: use a round-robin search, starting at the next lowest channel than last
     ;    time (aka. descending rotary hunt group).
     ;
     TRUNKMSD=1                                   ; MSD digits to strip (usually
                                                  ; 1 or 0)
     ;TRUNK=IAX2/user:pass@provider
     ;FREENUMDOMAIN=mydomain.com                  ; domain to send on outbound
                                                  ; freenum calls (uses
                                                  ; outbound-freenum context)
     ;
     ; Include the local Variables.
     ;
     #include local/variables.conf
     ;
     ; WARNING WARNING WARNING WARNING
     ; If you load any other extension configuration engine, such as pbx_ael.so,
     ; your global variables may be overridden by that file.  Please take care to
     ; use only one location to set global variables, and you will likely save
     ; yourself a ton of grief.
     ; WARNING WARNING WARNING WARNING
     ;
     ; Any category other than "General" and "Globals" represent 
     ; extension contexts, which are collections of extensions.  
     ;
     ; Extension names may be numbers, letters, or combinations
     ; thereof. If an extension name is prefixed by a '_'
     ; character, it is interpreted as a pattern rather than a
     ; literal.  In patterns, some characters have special meanings:
     ;
     ;   X - any digit from 0-9
     ;   Z - any digit from 1-9
     ;   N - any digit from 2-9
     ;   [1235-9] - any digit in the brackets (in this example, 1,2,3,5,6,7,8,9)
     ;   . - wildcard, matches anything remaining (e.g. _9011. matches 
     ;        anything starting with 9011 excluding 9011 itself)
     ;   ! - wildcard, causes the matching process to complete as soon as
     ;       it can unambiguously determine that no other matches are possible
     ;
     ; For example, the extension _NXXXXXX would match normal 7 digit dialings, 
     ; while _1NXXNXXXXXX would represent an area code plus phone number
     ; preceded by a one.
     ;
     ; Each step of an extension is ordered by priority, which must always start
     ; with 1 to be considered a valid extension.  The priority "next" or "n" means
     ; the previous priority plus one, regardless of whether the previous priority
     ; was associated with the current extension or not.  The priority "same" or
     ; "s" means the same as the previously specified priority, again regardless of
     ; whether the previous entry was for the same extension.  Priorities may be
     ; immediately followed by a plus sign and another integer to add that amount
     ; (most useful with 's' or 'n').  Priorities may then also have an alias, or
     ; label, in parentheses after their name which can be used in goto situations.
     ;
     ; Contexts contain several lines, one for each step of each extension.  One
     ; may include another context in the current one as well, optionally with a
     ; date and time.  Included contexts are included in the order they are
     ; listed. Switches may also be included within a context.  The order of
     ; matching within a context is always exact extensions, pattern match
     ; extensions, includes, and switches.  Includes are always processed
     ; depth-first.  So for example, if you would like a switch "A" to match before
     ; context "B", simply put switch "A" in an included context "C", where "C" is
     ; included in your original context before "B".
     ;
     ; [context]
     ; exten => someexten,{priority|label{+|-}offset}[(alias)],\
     ;          application(arg1,arg2,...)
     ;
     ; Timing list for includes is 
     ;
     ;   <time range>,<days of week>,<days of month>,<months>[,<timezone>]
     ;
     ; Note that ranges may be specified to wrap around the ends.  Also, minutes
     ; are fine-grained only down to the closest even minute.
     ;
     ; include => daytime,9:00-17:00,mon-fri,*,
     ; include => weekend,,sat-sun,*,
     ; include => weeknights,17:02-8:58,mon-fri,,*
     ;
     ; ignorepat can be used to instruct drivers to not cancel dialtone upon
     ; receipt of a particular pattern.  The most commonly used example is of
     ; course '9' like this:
     ;
     ;ignorepat => 9
     ;
     ; so that dialtone remains even after dialing a 9.  Please note that ignorepat
     ; only works with channels which receive dialtone from the PBX, such as DAHDI,
     ; Phone, and VPB.  Other channels, such as SIP and MGCP, which generate their
     ; own dialtone and converse with the PBX only after a number is complete, are
     ; generally unaffected by ignorepat (unless DISA or another method is used to
     ; generate a dialtone after answering the channel).
     ;
     ;
     ; Include the local IVR menu.
     ;
     #include local/ivr-menutree.conf
     ;
     ; Include the special feature codes.
     ;
     #include local/plan-features.conf
     ;
     ; Include the dial plan for outside lines.
     ;
     #include local/plan-outsidelines.conf
     ;
     ; Include the dial plan for virtual extensions.
     ;
     #include local/plan-virtualexts.conf
     ;
     ; Include the local extensions and CO lines.
     ;
     #include local/dahdi-extensions.conf
     #include local/dahdi-colines.conf
     ;
     ; You can use an alternative switch type as well, to resolve
     ; extensions that are not known here, for example with remote 
     ; IAX switching you transparently get access to the remote
     ; Asterisk PBX
     ; 
     ; switch => IAX2/user:password@bigserver/local
     ;
     ; An "lswitch" is like a switch but is literal, in that
     ; variable substitution is not performed at load time
     ; but is passed to the switch directly (presumably to
     ; be substituted in the switch routine itself)
     ;
     ; lswitch => Loopback/12${EXTEN}@othercontext
     ;
     ; An "eswitch" is like a switch but the evaluation of
     ; variable substitution is performed at runtime before
     ; being passed to the switch routine.
     ;
     ; eswitch => IAX2/context@${CURSERVER}
     ;
     ; recordivr:
     ;
     ;   Macro to record a phrase as a ".wav" file in the /tmp directory, where
     ;   it can be saved for use in an IVR menu.
     ;
     ;   This uses the pls-rcrd-name-at-tone sound from the Asterisk extra sounds
     ;   in asterisk-extra-sounds-en-wav-current.tar.gz.  Its not the right prompt
     ;   but it is "a" prompt.  You could record a different prompt, using this
     ;   macro and then use that prompt for future recordings.
     ;
     ;   The result is put in /tmp/asterisk-recording.wav.  You can copy it
     ;   wherever you wish.
     ;
     [macro-recordivr]
     exten => s,1,Playback(vm-rec-temp)
     exten => s,n,Record(/tmp/asterisk-recording.wav)
     exten => s,n,Wait(2)
     exten => s,n,Playback(/tmp/asterisk-recording)
     exten => s,n,wait(2)
     exten => s,n,Hangup
     ;
     ; Standard extension subroutine:
     ;   ${EXTEN} - Extension
     ;   ${ARG1} - Device(s) to ring
     ;   ${ARG2} - Optional context in Voicemail (if empty, then "default")
     ;
     ; Note that the current version will drop through to the next priority in the
     ; case of their pressing '#'.  This gives more flexibility in what do to next:
     ; you can prompt for a new extension, or drop the call, or send them to a
     ; general delivery mailbox, or...
     ;
     ; The use of the LOCAL() function is purely for convenience.  Any variable
     ; initially declared as LOCAL() will disappear when the innermost Gosub
     ; context in which it was declared returns.  Note also that you can declare
     ; a LOCAL() variable on top of an existing variable, and its value will
     ; revert to its previous value (before being declared as LOCAL()) upon
     ; Return.
     ;
     [stdexten]
     exten => _X.,50000(stdexten),NoOp(Start stdexten)
     exten => _X.,n,Set(LOCAL(ext)=${EXTEN})
     exten => _X.,n,Set(LOCAL(dev)=${ARG1})
     exten => _X.,n,Set(LOCAL(cntx)=${ARG2})
     exten => _X.,n,Set(LOCAL(mbx)="${ext}"$["${cntx}" ? "@${cntx}" :: ""])
     ; If we were given a mailbox to use, on failure, by level 0 in the call
     ; forward recursion, use it instead.  This way, the caller ends up in
     ; the original mailbox, if the forwarded extension is DND, Busy or No
     ; Answer.
     exten => _X.,n,GotoIf($[${EXISTS(${mbxonfailure})}]?:checkfwd)
     exten => _X.,n,Set(LOCAL(mbx)=${mbxonfailure})
     ; First, check if forwarding is set on this extension.  If it is, go
     ; straight to the forwarded number without checking anything else.
     ;
     ; Note that this involves jumping back to the from-internal context to
     ; ring the forwarded extension.  However, it is possible that the
     ; forwarded extension is forwarded back to us, which will cause Asterisk
     ; to loop forever.  That being the case, we don't do the forward if the
     ; forwarded extension is also forwarded.  Its a rudimentary check but
     ; it works.  Incidentally, we do the check here because it may be
     ; possible for the users to sneak a loop by the UI.  Since we would
     ; actually loop here, this is the logical last-minute check.
     exten => _X.,n(checkfwd),Set(LOCAL(fwd)=${DB(Feature/FWD${ext})})
     exten => _X.,n,Set(LOCAL(bfwd)=${DB(Feature/BFWD${ext})})
     exten => _X.,n,GotoIf($[${ISNULL(${fwd})}]?checkdnd:)
     exten => _X.,n,Set(LOCAL(fwdloop)=${DB(Feature/FWD${fwd})})
     exten => _X.,n,GotoIf($[${ISNULL(${fwdloop})}]?:checkdnd)
     exten => _X.,n,GotoIf($[${EXISTS(${exitonfailure})}]?exitfwd:)
     exten => _X.,n,Set(mbxonfailure=${mbx})
     exten => _X.,n,Goto(from-internal,${fwd},1)  ; Recursion (1 level)
     exten => _X.,n(exitfwd),return()
     ; Check if DND is set on this extension.  Straight to Voicemail, if it is.
     exten => _X.,n(checkdnd),Set(LOCAL(dnd)=${DB(Feature/DND${ext})})
     exten => _X.,n,GotoIf($[${ISNULL(${dnd})}]?dialext:)
     exten => _X.,n,GotoIf($[${EXISTS(${exitonfailure})}]?exitfwd:)
     exten => _X.,n,Voicemail(${mbx},u)
     ; Dial the extension.
     exten => _X.,n(dialext),Dial(${dev},20,t)    ; Ring the interface, 20 seconds
                                                  ; maximum
     exten => _X.,n,Goto(stdexten-${DIALSTATUS},1)
                                                  ; Jump based on status
                                                  ; (NOANSWER,BUSY,CHANUNAVAIL,
                                                  ;   CONGESTION,ANSWER)
     exten => stdexten-NOANSWER,1,GotoIf($[${EXISTS(${exitonfailure})}]?exitnoans:)
     exten => stdexten-NOANSWER,n,GotoIf($[${ISNULL(${bfwd})}]?vmnoans:)
     exten => stdexten-NOANSWER,n,Set(LOCAL(bfwdloop)=${DB(Feature/BFWD${bfwd})})
     exten => stdexten-NOANSWER,n,GotoIf($[${ISNULL(${bfwdloop})}]?:vmnoans)
     exten => stdexten-NOANSWER,n,Set(mbxonfailure=${mbx})
     exten => stdexten-NOANSWER,n,Goto(from-internal,${bfwd},1)
                                                  ; Recursion (1 level)
     exten => stdexten-NOANSWER,n(vmnoans),Voicemail(${mbx},u)
                                                  ; If unavailable, send to
                                                  ; voicemail w/ unavail announce
     exten => stdexten-NOANSWER,n,NoOp(Finish stdexten NOANSWER)
     exten => stdexten-NOANSWER,n(exitnoans),Return()
                                                  ; If they press #, return to start
     exten => stdexten-BUSY,1,GotoIf($[${EXISTS(${exitonfailure})}]?exitbusy:)
     exten => stdexten-BUSY,n,GotoIf($[${ISNULL(${bfwd})}]?vmbusy:)
     exten => stdexten-BUSY,n,Set(LOCAL(bfwdloop)=${DB(Feature/BFWD${bfwd})})
     exten => stdexten-BUSY,n,GotoIf($[${ISNULL(${bfwdloop})}]?:vmbusy)
     exten => stdexten-BUSY,n,Set(mbxonfailure=${mbx})
     exten => stdexten-BUSY,n,Goto(from-internal,${bfwd},1)
                                                  ; Recursion (1 level)
     exten => stdexten-BUSY,n(vmbusy),Voicemail(${mbx},b)
                                                  ; If busy, send to voicemail w/
                                                  ; busy announce
     exten => stdexten-BUSY,n,NoOp(Finish stdexten BUSY)
     exten => stdexten-BUSY,n(exitbusy),Return()  ; If they press #, return to start
     exten => _stde[x]te[n]-.,1,Goto(stdexten-NOANSWER,1)
                                                  ; Treat anything else as no answer
     exten => a,1,VoicemailMain(${mbx})           ; If they press *, send the user
                                                  ; into VoicemailMain
     exten => a,n,Return()
     ;
     ; Standard privacy extension subroutine:
     ;   ${ARG1} - Extension
     ;   ${ARG2} - Device(s) to ring
     ;   ${ARG3} - Optional DONTCALL context name to jump to (assumes the s,1
     ;             extension-priority)
     ;   ${ARG4} - Optional TORTURE context name to jump to (assumes the s,1
     ;             extension-priority)`
     ;   ${ARG5} - Context in voicemail (if empty, then "default")
     ;
     ; See above note in stdexten about priority handling on exit.
     ;
     [stdPrivacyexten]
     exten => _X.,60000(stdPrivacyexten),NoOp(Start stdPrivacyexten)
     exten => _X.,n,Set(LOCAL(ext)=${ARG1})
     exten => _X.,n,Set(LOCAL(dev)=${ARG2})
     exten => _X.,n,Set(LOCAL(dontcntx)=${ARG3})
     exten => _X.,n,Set(LOCAL(tortcntx)=${ARG4})
     exten => _X.,n,Set(LOCAL(cntx)=${ARG5})
     exten => _X.,n,Set(LOCAL(mbx)="${ext}"$["${cntx}" ? "@${cntx}" :: ""])
     ; If we were given a mailbox to use, on failure, by level 0 in the call
     ; forward recursion, use it instead.  This way, the caller ends up in
     ; the original mailbox, if the forwarded extension is DND, Busy or No
     ; Answer.
     exten => _X.,n,GotoIf($[${EXISTS(${mbxonfailure})}]?:pvcheckfwd)
     exten => _X.,n,Set(LOCAL(mbx)=${mbxonfailure})
     ; First, check if forwarding is set on this extension.  If it is, go
     ; straight to the forwarded number without checking anything else.
     ;
     ; Note that this involves jumping back to the from-internal context to
     ; ring the forwarded extension.  However, it is possible that the
     ; forwarded extension is forwarded back to us, which will cause Asterisk
     ; to loop forever.  That being the case, we don't do the forward if the
     ; forwarded extension is also forwarded.  Its a rudimentary check but
     ; it works.  Incidentally, we do the check here because it may be
     ; possible for the users to sneak a loop by the UI.  Since we would
     ; actually loop here, this is the logical last-minute check.
     exten => _X.,n(pvcheckfwd),Set(LOCAL(fwd)=${DB(Feature/FWD${ext})})
     exten => _X.,n,Set(LOCAL(bfwd)=${DB(Feature/BFWD${ext})})
     exten => _X.,n,GotoIf($[${ISNULL(${fwd})}]?pvcheckdnd:)
     exten => _X.,n,Set(LOCAL(fwdloop)=${DB(Feature/FWD${fwd})})
     exten => _X.,n,GotoIf($[${ISNULL(${fwdloop})}]?:pvcheckdnd)
     exten => _X.,n,GotoIf($[${EXISTS(${exitonfailure})}]?pvexitfwd:)
     exten => _X.,n,Set(mbxonfailure=${mbx})
     exten => _X.,n,Goto(from-internal,${fwd},1)  ; Recursion (1 level)
     exten => _X.,n(pvexitfwd),return()
     ; Check if DND is set on this extension.  Straight to Voicemail, if it is.
     exten => _X.,n(pvcheckdnd),Set(LOCAL(dnd)=${DB(Feature/DND${ext})})
     exten => _X.,n,GotoIf($[${ISNULL(${dnd})}]?pvdialext:)
     exten => _X.,n,GotoIf($[${EXISTS(${exitonfailure})}]?pvexitfwd:)
     exten => _X.,n,Voicemail(${mbx},u)
     ; Dial the extension.
     exten => _X.,n(pvdialext),Dial(${dev},20,pt) ; Ring the interface, 20 seconds
                                                  ; maximum, call screening option
                                                  ; (or use P for databased call
                                                  ; _X.creening)
     exten => _X.,n,Goto(stdexten-${DIALSTATUS},1)
                                                  ; Jump based on status
                                                  ; (NOANSWER,BUSY,CHANUNAVAIL,
                                                  ; CONGESTION,ANSWER)
     exten => stdexten-NOANSWER,1,GotoIf($[${EXISTS(${exitonfailure})}]?pvexitnoans:)
     exten => stdexten-NOANSWER,n,GotoIf($[${ISNULL(${bfwd})}]?pvvmnoans:)
     exten => stdexten-NOANSWER,n,Set(LOCAL(bfwdloop)=${DB(Feature/BFWD${bfwd})})
     exten => stdexten-NOANSWER,n,GotoIf($[${ISNULL(${bfwdloop})}]?:pvvmnoans)
     exten => stdexten-NOANSWER,n,Set(mbxonfailure=${mbx})
     exten => stdexten-NOANSWER,n,Goto(from-internal,${bfwd},1)
                                                  ; Recursion (1 level)
     exten => stdexten-NOANSWER,n(pvvmnoans),Voicemail(${mbx},u)
                                                  ; If unavailable, send to
                                                  ; voicemail w/ unavail announce
     exten => stdexten-NOANSWER,n,NoOp(Finish stdPrivacyexten NOANSWER)
     exten => stdexten-NOANSWER,n(pvexitnoans),Return()
                                                  ; If they press #, return to start
     exten => stdexten-BUSY,1,GotoIf($[${EXISTS(${exitonfailure})}]?pvexitbusy:)
     exten => stdexten-BUSY,n,GotoIf($[${ISNULL(${bfwd})}]?pvvmbusy:)
     exten => stdexten-BUSY,n,Set(LOCAL(bfwdloop)=${DB(Feature/BFWD${bfwd})})
     exten => stdexten-BUSY,n,GotoIf($[${ISNULL(${bfwdloop})}]?:pvvmbusy)
     exten => stdexten-BUSY,n,Set(mbxonfailure=${mbx})
     exten => stdexten-BUSY,n,Goto(from-internal,${bfwd},1)
                                                  ; Recursion (1 level)
     exten => stdexten-BUSY,n(pvvmbusy),Voicemail(${mbx},b)
                                                  ; If busy, send to voicemail w/
                                                  ; busy announce                                               ; busy announce
     exten => stdexten-BUSY,n,NoOp(Finish stdPrivacyexten BUSY)
     exten => stdexten-BUSY,n(pvexitbusy),Return()
                                                  ; If they press #, return to start
     exten => stdexten-DONTCALL,1,Goto(${dontcntx},s,1)
                                                  ; Callee chose to send this call
                                                  ; to a polite "Don't call again"
                                                  ; script.
     exten => stdexten-TORTURE,1,Goto(${tortcntx},s,1)
                                                  ; Callee chose to send this call
                                                  ; to a telemarketer torture
                                                  ; script.
     exten => _stde[x]te[n]-.,1,Goto(stdexten-NOANSWER,1)
                                                  ; Treat anything else as no answer
     exten => a,1,VoicemailMain(${mbx})           ; If they press *, send the user
                                                  ; into VoicemailMain
     exten => a,n,Return
     ;
     ; Paging macro:
     ;
     ;       Check to see if SIP device is in use and DO NOT PAGE if they are
     ;
     ;   ${ARG1} - Device to page
     ;
     [macro-page];
     exten => s,1,ChanIsAvail(${ARG1},s)          ; s is for ANY call
     exten => s,n,GoToIf([${AVAILORIGCHAN} = ""]?fail:autoanswer)
     exten => s,n(autoanswer),Set(ALERTINFO="RA")
                                                  ; This is for the PolyComs
     exten => s,n,SIPAddHeader(Call-Info: Answer-After=0)
                                                  ; This is for the Grandstream,
                                                  ; Snoms, and Others
     exten => s,n,NoOp()                          ; Add others here and Post on
                                                  ; the Wiki!!!!
     exten => s,n,Dial(${ARG1})
     exten => s,n(fail),Hangup
     ;
     ; The page context calls up the page macro that sets variables needed for
     ; auto-answer.  It is in is own context to make calling it from the Page()
     ; application as simple as Local/{peername}@page
     ;
     [page]
     exten => _X.,1,Macro(page,SIP/${EXTEN})
     ;If you want to subscribe to the status of a parking space, this is
     ;how you do it. Subscribe to extension 6600 in sip, and you will see
     ;the status of the first parking lot with this extensions' help
     ;exten => 6600,hint,park:701@parkedcalls
     ;exten => 6600,1,noop
     ;
     ; Some other handy things are an extension for checking voicemail via
     ; voicemailmain
     ;
     ;exten => 8500,1,VoicemailMain
     ;exten => 8500,n,Hangup
     ;
     ; Or a conference room (you'll need to edit meetme.conf to enable this room)
     ;
     ;exten => 8600,1,Meetme(1234)
     ;
     ; Or playing an announcement to the called party, as soon it answers
     ;
     ;exten = 8700,1,Dial(${MARK},30,A(/path/to/my/announcemsg))
     ;
     ;
     ; "timezone" isn't a 'reserved' name in any way, and other places where
     ; the timezone is significant (e.g. calls to "SayUnixTime()", etc) will
     ; require modification as well.  Note that voicemail.conf already has
     ; a mechanism for timezones.
     ;
     [time]
     exten => _X.,30000(time),NoOp(Time: ${EXTEN} ${timezone})
     exten => _X.,n,Playback(at-tone-time-exactly)
     ; the amount of delay is set for English; you may need to adjust this time
     ; for other languages if there's no pause before the synchronizing beep.
     exten => _X.,n,Set(FUTURETIME=$[${EPOCH} + 12])
     exten => _X.,n,SayUnixTime(${FUTURETIME},Zulu,HNS)
     exten => _X.,n,SayPhonetic(z)
     ; use the timezone associated with the extension (sip only), or system-wide
     ; default if one hasn't been set.
     exten => _X.,n,SayUnixTime(${FUTURETIME},${timezone},HNS)
     exten => _X.,n,Playback(spy-local)
     exten => _X.,n,WaitUntil(${FUTURETIME})
     exten => _X.,n,Playback(beep)
     exten => _X.,n,Return()
     ;
     ; ANI context: use in the same way as "time" above
     ;
     [ani]
     exten => _X.,40000(ani),NoOp(ANI: ${EXTEN})
     exten => _X.,n,Playback(vm-from)
     exten => _X.,n,SayDigits(${CALLERID(ani)})
     exten => _X.,n,Wait(1.25)
     exten => _X.,n,SayDigits(${CALLERID(ani)})   ; playback again in case of
                                                  ; missed digit
     exten => _X.,n,Return()
     ; For more information on applications, just type "core show applications"
     ; at your friendly Asterisk CLI prompt.
     ;
     ; "core show application <command>" will show details of how you
     ; use that particular application in this file, the dial plan. 
     ; "core show functions" will list all dialplan functions
     ; "core show function <COMMAND>" will show you more information about
     ; one function. Remember that function names are UPPER CASE.

>>>>>>
Tidy up a bit (you can cut and paste all of this to the command line) cat > /etc/asterisk/sip.conf << EOF
[general]
context=default
allowguest=yes
match_auth_username=yes
allowoverlap=no
allowtransfer=no
realm=pbx12.vitell.co.uk
udpbindaddr=0.0.0.0
tcpenable=no
tlsenable=no
srvlookup=yes
pedantic=no
tos_sip=cs3
tos_audio=ef
tos_video=af41
tos_text=af41
cos_sip=3
cos_audio=5
cos_video=4
cos_text=3
maxexpiry=3600
minexpiry=60
defaultexpiry=120
mwiexpiry=3600
qualifyfreq=60
qualifygap=100
qualifypeers=1
vmexten=voicemail
disallow=all
allow=alaw
mohinterpret=default
mohsuggest=default
parkinglot=plaza
language=en
relaxdtmf=yes
useragent=AsteriskPBX
sdpsession=AsteriskPBX
promiscredir=no
dtmfmode=rfc2833
videosupport=no
callevents=no
alwaysauthreject=yes
shrinkcallerid=no
allowsubscribe=yes
subscribecontext=default
notifyringing=yes
notifyhold=yes
notifycid=yes
callcounter=yes
t38pt_udptl=yes,fec,maxdatagram=400
faxdetect=no
nat=no
directmedia=no
directrtpsetup=no
EOF
<<<<<<