[Asterisk-doc] extensions.conf section
Steven Critchfield
asterisk-doc@lists.digium.com
Sun, 04 Jan 2004 03:59:25 -0600
--=-GmN7wBJWNCijcLvIiY8h
Content-Type: text/plain
Content-Transfer-Encoding: 7bit
Just to get something going here, and I was bored. I have written a fair
amount of this section now. It became evident that mixing of pieces of
the outline together was convenient to the writing of the section. So
this is submitted for review instead of the outline.
Let it be known that I am open to all constructive critique. Even to the
point of ripping this section apart, or not using it at all.
Anyways, I've been up too long and am ready to release this in it's
current form even though it needs several more paragraphs.
--
Steven Critchfield <critch@basesys.com>
--=-GmN7wBJWNCijcLvIiY8h
Content-Disposition: attachment; filename=extensions.xml
Content-Type: text/html; name=extensions.xml; charset=ANSI_X3.4-1968
Content-Transfer-Encoding: 7bit
<chapter>
<title>Components of Asterisk Configuration</title>
<sect1>
<title>The Asterisk Directory Structure</title>
<para>
Asterisk has a few directory trees that you will need to be aware of.
</para>
<sect2>
<title>/etc/asterisk</title>
<para>
This directory is for all your configuration files.
</para>
</sect2>
<sect2>
<title>/usr/src/asterisk</title>
<para>
This is where standard convention places the asterisk source code.
All examples will point you to this directory when pointing to the
source code.
</para>
</sect2>
<sect2>
<title>/usr/lib/asterisk/modules</title>
<para>
You will find the modules that asterisk loads in this directory.
</para>
</sect2>
<sect2>
<title>/var/lib/asterisk</title>
<para>
Outside of /etc/asterisk, this is the most important directory. In
this directory you will find a directory for your AGI applications,
directories for images and sounds to be served to clients, a
directory to place your music on hold files, and a directory for
your security keys for authentication. The asterisk DB1 file also
resides here.
</para>
</sect2>
<sect2>
<title>/var/spool/asterisk</title>
<para>
Transient files are found here. The directory outgoing is used for
queuing calls to be made. Voicemail is pretty self explanation.
<!-- qcall? Someone who knows this should fill in a sentence about
it. -->
</para>
</sect2>
<sect2>
<title>/var/log/asterisk</title>
<para>
Here is where you find the directory for the Call Detail
Records(CDR), and a few files containing the messages generated by
asterisk while running.
</para>
</sect2>
</sect1>
<sect1>
<title>Configuration</title>
<para>
This aim of this section is to give you a solid base on how the various
config files work and the conventions used in expressing the
configuration.
</para>
<para>
The config files have been modeled after the INI files commonly found
on Windows systems. Sections of the files are blocked off by a title
placed with in square braces. Due to the pound sign being a valid
key press within a dial plan, the comment character in asterisk config
files is the semicolon. Objects or interfaces accept the
configurations defined above it. Settings are usually defined by a
keyword and a equal sign followed by the new definition. Objects can
also be defined with the equal sign, but sometimes the equal sign is
replaced by an arrow made up by an equal sign followed by a greater
than symbol.
</para>
<programlisting>
[title]
attribute=value
attribute2=value2
object=>interface
<lineannotation>; object was defined with attribute and attribute2</lineannotation>
attribute2=""
object2=>interface2
<lineannotation>; object2 defined with attribute but not attribute2</lineannotation>
</programlisting>
<sect2>
<title>extensions.conf</title>
<para>
You will spend many hours in this file. It is the basis for how
every call made is dealt with. The concepts covered in this section
will be used the entire time you use asterisk.
</para>
<sect3>
<title>Contexts</title>
<para>
The first bit of information to learn about is contexts. Contexts
have a couple of functions within asterisk dial plan. Contexts
define scope. All calls that enter asterisk will begin in a
defined context. What is defined in this context will determine
what is possible for the call to do. Contexts can also help build
an IVR menu where you reuse extension numbers as options on you
menu.
</para>
<para>
Contexts are capable of including other contexts into themselves.
The include functionality is even possible on a time of day,
day of week, or day of month basis. The normal use for this
conditional include is for an automatic transition from business
hours to after hours prompts to direct a caller.
</para>
<para>
Contexts are denoted by their name inside of square brackets.
Contexts may contain extension definitions, and includes of other
contexts.
</para>
<programlisting>
[incoming_calls]
<lineannotation>; We always want callers to be able to get to the extensions.</lineannotation>
include => worker_extensions
<lineannotation>; Normal IVR menu</lineannotation>
include => day_menu|08:00-17:00|Mon-Fri|*|*
<lineannotation>; Tue-Fri mornings are normal after hours</lineannotation>
<lineannotation>; Mon-Thu nights are normal after hours</lineannotation>
include => night_menu|00:00-08:00|Tue-Fri|*|*
include => night_menu|17:00-24:00|Mon-Thu|*|*
<lineannotation>; Mon morning is part of a weekend menu.</lineannotation>
include => weekend_menu|00:00-08:00|Mon|*|*
<lineannotation>; Fri evening starts the weekend</lineannotation>
include => weekend_menu|17:00-24:00|Fri|*|*
<lineannotation>; and Sat-Sun are weekend times also.</lineannotation>
include => weekend_menu|*|sat-sun|*|*
[internal_restricted_callers]
<lineannotation>; our employees should be able to contact our other employees</lineannotation>
include => worker_extensions
<lineannotation>; only internal callers can call out, and this is restricted to</lineannotation>
<lineannotation>; local calls</lineannotation>
include => outbound_local_context
[internal_unrestricted_callers]
<lineannotation>; our employees should be able to contact our other employees</lineannotation>
include => worker_extensions
<lineannotation>; only internal callers can call out</lineannotation>
include => outbound_local_context
include => outbound_toll_context
</programlisting>
<para>
From this example you should be able to notice that contexts can be
used to reduce retyping sections as in the worker_extensions being
included in all the example contexts.
</para>
<para>
Also demonstrated here is the ability to separate privileges. Calls
coming from outside of our system are not given the ability to call
out to other phone numbers. Also you will notice the ability to
separate your internal users from having the same abilities to call
out. You may not want anyone but your executives to be able to call
long distance or even international.
</para>
</sect3>
<sect3>
<title>Extensions</title>
<para>
The extension definitions are very much like subroutines in
programming. You will define them as the steps a call will take as
it progresses though your dial plan. A single extension line will
contain the extension number or special letter you are defining, a
priority number that is very much like old basic programming,
the function you need to be applied, and any of the arguments to be
passed to the function. The priority numbers must be consecutive for
the call to progress from one to the next. Here is an example of a
extension definition.
</para>
<programlisting>
[sample_context]
exten => s,1,Wait(1)
exten => s,2,Answer()
exten => s,3,Background(hello_prompt)
</programlisting>
<para>
There are 4 special extensions to know about.
</para>
<simplelist>
<member>'s' - start</member>
<member>'i' - invalid</member>
<member>'t' - timeout</member>
<member>'h' - hangup</member>
</simplelist>
<para>
The start extension is for most calls that are initiated with no
other known information. This is true for calls on normal home
lines, or non digital lines.
</para>
<para>
Hangup is where calls will go to when hangup is detected, or where
you can send calls that you want to hangup on.
</para>
<para>
Timeout is for when a user is presented with a menu and they do not
respond. In the timeout extension you will want to decide if you
wish to repeat your menu, or just send the call to a hangup so as
to free up the line.
</para>
<para>
Invalid is for when Asterisk has determined that the input from the
call is not valid for the current context. You may wish to play a
prompt explaining the extension was invalid, and then send the call
back to the extension that contains the menu prompts.
</para>
<programlisting>
[My_home_incoming_context]
include => my_extensions
<lineannotation>; Make sure we wait long enough for the CallerID to be received.</lineannotation>
exten => s,1,wait(1)
<lineannotation>; Answer the line so that the line is available to play audio on.</lineannotation>
exten => s,2,Answer()
exten => s,3,DigitTimeout(15)
exten => s,4,ResponseTimeout(10)
<lineannotation>; Announce who we are, and what to do.</lineannotation>
exten => s,5,Background(Hello_prompt)
<lineannotation>; Here is where a caller is expected to enter an extension</lineannotation>
exten => i,1,Background(invalid_extension)
exten => i,2,Goto(s,5)
exten => t,1,Background(slow_user)
exten => t,2,Goto(s,5)
exten => h,1,hangup()
[my_extensions]
<lineannotation>; ring my extension for 25 seconds only</lineannotation>
exten => 1,1,Dial(Zap/2,25)
<lineannotation>; if dial falls through, I didn't answer, so play unavailable message</lineannotation>
exten => 1,2,Voicemail(u1)
<lineannotation>; If they left a message, hangup
now.</lineannotation>
exten => 1,3,hangup()
<lineannotation>; Now if dial failed due to the line being busy, play the busy message</lineannotation>
exten => 1,102,Voicemail(b1)
<lineannotation>; again, if the message is left,
hangup.</lineannotation>
exten => 1,103,hangup()
<lineannotation>; This wouldn't be a PBX without many more, but they look the same as above.</lineannotation>
</programlisting>
<para>
Here you should see the exception of the priority numbers just
incrementing by 1. Dial will jump to the next priority + 100 if the
dial failed.
</para>
</sect3>
<sect3>
<title>Variables</title>
<para>
There are 2 types of variables in Asterisk. The first kind is a
per call variable. They are either during call set up, or by
functions in extension definitions such as SetVar. The Second kind of
variables are global, and are defined either in the global
section of the extensions.conf file, or by the function
SetGlobalVar encountered in a extension definition.
</para>
<para>
Variables can be used for many things. They can be used to help
reduce typing, or they can be used to limit looping in an error
condition too long. When using the value of a variable, you
denote it with a dollar sign and the variable name surrounded
by curly braces.
</para>
<programlisting>
[global]
Lief=Zap/3
Critch=Zap/4
Wassim=Zap/5
ALL=${Lief}&${Critch}&${Wassim}
[extensions]
exten => 1,1,Dial(${Lief})
exten => 2,1,Dial(${Critch})
exten => 3,1,Dial(${Wassim})
[incoming]
include => extensions
exten => s,1,Wait(1)
exten => s,2,Answer()
exten => s,3,Background(hello)
<lineannotation>; This is where the user can't decide who to call, so we ring everyone</lineannotation>
exten => t,1,Dial(${ALL)
</programlisting>
<para>
In this pretty simple example, You can see how it would be
easy to change how to dial to someone and have it propagate to
the ALL variable. You should also note that it was possible to
concatenate the variables just by placing them next to each
other.
</para>
<para>
It is also possible to do simple expressions. These expressions
are evaluated when placed within square brackets. Expressions
are used to either combine values together via addition,
subtraction, multiplication, division, or to evaluate truth for
use with a GotoIf function for call flow.
</para>
</sect3>
<sect3>
<title>Macros</title>
<para>
When you combine variables with a special form of contexts, you
get macros. Macros, like in C, are expanded in the place they
are called. Macros are defined much like a normal context except
the name is prepended by "marcro-". The arguments you send to
this macro will be in variables such as ARG1 and ARG2. There is
also a special variable called MACRO_EXTEN so you know where
you are being called from.
</para>
<programlisting>
[globals]
Lief=Zap/3
Critch=Zap/4
Wassim=Zap/5
ALL=${Lief}&${Critch}&${Wassim}
[macro-stdexten]
exten => s,1,Dial(${ARG1},20)
exten => s,2,Voicemail(u${MACRO_EXTEN})
exten => s,3,Hangup()
exten => s,102,Voicemail(b${MACRO_EXTEN})
exten => s,103,Hangup()
[extensions]
<lineannotation>; Let the first to answer the phone be the operator</lineannotation>
exten => 0,1,Macro(stdexten,${ALL}
exten => 1,1,Macro(stdexten,${Lief}
exten => 2,1,Macro(stdexten,${Critch}
exten => 3,1,Macro(stdexten,${Wassim}
</programlisting>
<para>
It should come as no surprise that this is yet another way of
reducing typing. We defined the 5 steps that we want taken for
each of the extensions in one place only. This helps also in
reducing typing mistakes.
</para>
</sect3>
<sect3>
<title>Call flow</title>
<para>
This is where we put a few more pieces together to pull some of
these concepts into a more interesting example. We also need to
cover how to create menus.
</para>
<para>
Dial plans take time to develop due to the need to think about
how it affects other sections. Key presses will attempt to be
matched to an extension as long as there is a possibility for
the current pattern to be further matched. Any time you have
ambiguous matches where the digits type can match one extension
exactly and another partially, you will have to wait for the
timeout to go to the shorter extension match. So it is usually
important to designate certain digit ranges for certain
functions.
</para>
<para>
You may be used to noticing that 9 is associated with dialing
an outside line. This is due to the fact that in a local
calling area, the exchanges could over lap other sections of
your dialplan. Similarly you may have noticed that with in
certain companies, all the extensions will start with a
specific number. Like the 9, the specific number will denote
the type of function you are about to match against.
</para>
<para>
When you are choosing some of your dial plan, you should keep an
eye on expandability. Going through a change in dial plan can
cause a major headache to the users on your system. Something
as simple as choosing the range used for extensions, will
determine the maximum number of extensions you can expand to
before having to change things around.
</para>
<para>
For example, if you choose single digit extensions, there will
only be up to 9 options when you consider 1 entry will be used
for selecting an outgoing line. It isn't uncommon for a
moderately sized company to choose 4 digit extensions all
starting with the same digit. This will allow them 1000
extensions with only using a single leading digit.
</para>
<para>
Another part that makes the extensions file so versatile is the
pattern matching ability. Patterns are defined by placing an
underscore as the first character of the extension definition.
Exact matches can be typed as is, the letter 'X' matches all
digits, and the letter 'N' matches 2-9. This is especially
useful when defining outside phone number availability.
</para>
<programlisting>
[global]
Lief=Zap/2
Critch=Zap/3
Wassim=Zap/4
Jared=Zap/5
Brian=Zap/6
Support=${Wassim}&${Critch}&${Brian}
Sales=${Lief}&${Jared}
ALL=${Sales}&${Support}
[macro-stdexten]
exten => s,1,Dial(${ARG1},20)
exten => s,2,Voicemail(u${MACRO_EXTEN})
exten => s,3,Hangup()
exten => s,102,Voicemail(b${MACRO_EXTEN})
exten => s,103,Hangup()
[extensions]
<lineannotation>; Let the first to answer the phone be the operator</lineannotation>
exten => 0,1,Macro(stdexten,${ALL}
exten => 5001,1,Macro(stdexten,${Lief}
exten => 5002,1,Macro(stdexten,${Critch}
exten => 5003,1,Macro(stdexten,${Wassim}
exten => 5004,1,Macro(stdexten,${Jared}
exten => 5005,1,Macro(stdexten,${Brian}
[incoming]
include => extensions
exten => s,1,Wait(1)
exten => s,2,Answer()
exten => s,3,Background(hello)
exten => 1,1,Goto(Sales,s,1)
exten => 2,1,Goto(Support,s,1)
<lineannotation>; This is where the user can't decide who to call, so we ring everyone</lineannotation>
exten => t,1,Dial(${ALL)
[Sales]
include => extensions
exten => s,1,Background(Sales_blurb)
exten => 1,1,Macro(stdexten,${Lief})
exten => 2,1,Macro(stdexten,${Jared})
exten => t,1,Hangup()
[Support]
include => extensions
exten => s,1,Background(Support_blurb)
exten => 1,1,Macro(stdexten,${Wassim})
exten => 2,1,Macro(stdexten,${Critch})
exten => 2,1,Macro(stdexten,${Brian})
exten => t,1,Hangup()
[internal]
include => extensions
exten => _9NXXXXXX,1,Dial(${Trunk}/${EXTEN})
exten => _91NXXNXXXXXX,1,Dial(${Trunk}/${EXTEN})
</programlisting>
</sect3>
</sect2>
</sect1>
</chapter>
--=-GmN7wBJWNCijcLvIiY8h--