[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=&gt;interface
			<lineannotation>; object was defined with attribute and attribute2</lineannotation>

			attribute2=""
			object2=&gt;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 =&gt; worker_extensions
				
				<lineannotation>; Normal IVR menu</lineannotation>
				include =&gt; 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 =&gt; night_menu|00:00-08:00|Tue-Fri|*|*
				include =&gt; night_menu|17:00-24:00|Mon-Thu|*|*
				
				<lineannotation>; Mon morning is part of a weekend menu.</lineannotation>
				include =&gt; weekend_menu|00:00-08:00|Mon|*|*
				<lineannotation>; Fri evening starts the weekend</lineannotation>
				include =&gt; weekend_menu|17:00-24:00|Fri|*|*
				<lineannotation>; and Sat-Sun are weekend times also.</lineannotation>
				include =&gt; weekend_menu|*|sat-sun|*|*
	
				[internal_restricted_callers]
				<lineannotation>; our employees should be able to contact our other employees</lineannotation>
				include =&gt; worker_extensions
	
				<lineannotation>; only internal callers can call out, and this is restricted to</lineannotation>
				<lineannotation>; local calls</lineannotation>
				include =&gt; outbound_local_context
	
				[internal_unrestricted_callers]
				<lineannotation>; our employees should be able to contact our other employees</lineannotation>
				include =&gt; worker_extensions
	
				<lineannotation>; only internal callers can call out</lineannotation>
				include =&gt; outbound_local_context
				include =&gt; 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 =&gt; s,1,Wait(1)
				exten =&gt; s,2,Answer()
				exten =&gt; 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 =&gt; my_extensions
				
				<lineannotation>; Make sure we wait long enough for the CallerID to be received.</lineannotation>
				exten =&gt; s,1,wait(1)
				<lineannotation>; Answer the line so that the line is available to play audio on.</lineannotation>
				exten =&gt; s,2,Answer()
				exten =&gt; s,3,DigitTimeout(15)
				exten =&gt; s,4,ResponseTimeout(10)
				<lineannotation>; Announce who we are, and what to do.</lineannotation>
				exten =&gt; s,5,Background(Hello_prompt)
				<lineannotation>; Here is where a caller is expected to enter an extension</lineannotation>

				exten =&gt; i,1,Background(invalid_extension)
				exten =&gt; i,2,Goto(s,5)
	
				exten =&gt; t,1,Background(slow_user)
				exten =&gt; t,2,Goto(s,5)
	
				exten =&gt; h,1,hangup()
	
	
				[my_extensions]
				<lineannotation>; ring my extension for 25 seconds only</lineannotation>
				exten =&gt; 1,1,Dial(Zap/2,25)
				<lineannotation>; if dial falls through, I didn't answer, so play unavailable message</lineannotation>
				exten =&gt; 1,2,Voicemail(u1)
				<lineannotation>; If they left a message, hangup
				now.</lineannotation>
				exten =&gt; 1,3,hangup()
				
				<lineannotation>; Now if dial failed due to the line being busy, play the busy message</lineannotation>
				exten =&gt; 1,102,Voicemail(b1)
				<lineannotation>; again, if the message is left,
				hangup.</lineannotation>
				exten =&gt; 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 =&gt; 1,1,Dial(${Lief})
				exten =&gt; 2,1,Dial(${Critch})
				exten =&gt; 3,1,Dial(${Wassim})

				[incoming]
				include =&gt; extensions
				
				exten =&gt; s,1,Wait(1)
				exten =&gt; s,2,Answer()
				exten =&gt; s,3,Background(hello)

				<lineannotation>; This is where the user can't decide who to call, so we ring everyone</lineannotation>
				exten =&gt; 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 =&gt; s,1,Dial(${ARG1},20)
				exten =&gt; s,2,Voicemail(u${MACRO_EXTEN})
				exten =&gt; s,3,Hangup()
				exten =&gt; s,102,Voicemail(b${MACRO_EXTEN})
				exten =&gt; s,103,Hangup()
				
				[extensions]
				<lineannotation>; Let the first to answer the phone be the operator</lineannotation>
				exten =&gt; 0,1,Macro(stdexten,${ALL}
				exten =&gt; 1,1,Macro(stdexten,${Lief}
				exten =&gt; 2,1,Macro(stdexten,${Critch}
				exten =&gt; 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 =&gt; s,1,Dial(${ARG1},20)
				exten =&gt; s,2,Voicemail(u${MACRO_EXTEN})
				exten =&gt; s,3,Hangup()
				exten =&gt; s,102,Voicemail(b${MACRO_EXTEN})
				exten =&gt; s,103,Hangup()
				
				[extensions]
				<lineannotation>; Let the first to answer the phone be the operator</lineannotation>
				exten =&gt; 0,1,Macro(stdexten,${ALL}
				exten =&gt; 5001,1,Macro(stdexten,${Lief}
				exten =&gt; 5002,1,Macro(stdexten,${Critch}
				exten =&gt; 5003,1,Macro(stdexten,${Wassim}
				exten =&gt; 5004,1,Macro(stdexten,${Jared}
				exten =&gt; 5005,1,Macro(stdexten,${Brian}

				[incoming]
				include =&gt; extensions
				
				exten =&gt; s,1,Wait(1)
				exten =&gt; s,2,Answer()
				exten =&gt; s,3,Background(hello)

				exten =&gt; 1,1,Goto(Sales,s,1)
				exten =&gt; 2,1,Goto(Support,s,1)

				<lineannotation>; This is where the user can't decide who to call, so we ring everyone</lineannotation>
				exten =&gt; t,1,Dial(${ALL)
				
				[Sales]
				include =&gt; extensions
				
				exten =&gt; s,1,Background(Sales_blurb)

				exten =&gt; 1,1,Macro(stdexten,${Lief})
				exten =&gt; 2,1,Macro(stdexten,${Jared})

				exten =&gt; t,1,Hangup()
				
				[Support]
				include =&gt; extensions
				
				exten =&gt; s,1,Background(Support_blurb)

				exten =&gt; 1,1,Macro(stdexten,${Wassim})
				exten =&gt; 2,1,Macro(stdexten,${Critch})
				exten =&gt; 2,1,Macro(stdexten,${Brian})

				exten =&gt; t,1,Hangup()
				
				[internal]
				include =&gt; extensions
				
				exten =&gt; _9NXXXXXX,1,Dial(${Trunk}/${EXTEN})
				exten =&gt; _91NXXNXXXXXX,1,Dial(${Trunk}/${EXTEN})
				</programlisting>
			</sect3>
		</sect2>
	</sect1>
</chapter>

--=-GmN7wBJWNCijcLvIiY8h--