[Asterisk-doc] docs extensions.xml,1.5,1.6

websmith asterisk-doc@lists.digium.com
Tue, 18 May 2004 15:30:59 +0000


Comments:
Update of /cvsroot/asterisk/docs
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv21796

Modified Files:
	extensions.xml 
Log Message:
I submitted this doc to the mailing list on Jan. 15th, and then promptly forgot about it.  I'm checking it in now as something we can use to get going again.
Index: extensions.xml
===================================================================
RCS file: /cvsroot/asterisk/docs/extensions.xml,v
retrieving revision 1.5
retrieving revision 1.6
diff -C2 -d -r1.5 -r1.6
*** extensions.xml	19 Mar 2004 18:04:18 -0000	1.5
--- extensions.xml	18 May 2004 15:30:50 -0000	1.6
***************
*** 1,3 ****
--- 1,4 ----
  <chapter>
+ 	<!-- Chapter outline and examples written by Jared Smith -->
  	<title>Creating Dialplans</title>
  	<sect1>
***************
*** 6,10 ****
  		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>
  		<sect2>
--- 7,11 ----
  		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>
  		<sect2>
***************
*** 12,17 ****
  			<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
--- 13,18 ----
  			<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
***************
*** 31,83 ****
  			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 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>
  		</sect2>
  		<sect2>
--- 32,35 ----
***************
*** 94,106 ****
  			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>
--- 46,265 ----
  			extension definition.
  			</para>
+ 		</sect2>
+ 		<sect2>
+ 			<title>Priorities</title>
+ 			<para/>
+ 		</sect2>
+ 	</sect1>
+ 	<sect1>
+ 		<title>A simple example</title>
+ 		<para/>
+ 		<sect2>
+ 			<title>A simple 1FXOx1FXS setup</title>
+ 			<para/>
+ 		</sect2>
+ 		<sect2>
+ 			<title>The special 's' extension</title>
+ 			<para/>
+ 		</sect2>
+ 		<sect2>
+ 			<title>The <function>Playback()</function> and <function>Dial()</function> functions</title>
+ 			<para/>
+ 		</sect2>
+ 		<sect2>
+ 			<title>Handling Incoming Calls</title>
+ 			<informalexample>
  			<programlisting>
! 			[incoming]
! 			exten=&gt;s,1,Answer()<lineannotation> ; Answer the line</lineannotation>
! 			exten=&gt;s,2,Playback(welcome)<lineannotation> ; Play back the 'welcome' sound file</lineannotation>
! 			exten=&gt;s,3,Dial(Zap/2)<lineannotation> ; Dial the receptionist at channel Zap/2</lineannotation>
! 			</programlisting>
! 			</informalexample>	
! 		</sect2>
! 	</sect1>
! 	<sect1>
! 		<title>Adding Additional Functionality</title>
! 		<para/>
! 		<sect2>
! 			<title>Adding another FXS port</title>
! 			<informalexample>
! 			<programlisting>
! 			[incoming]
! 			exten=&gt;s,1,Answer()<lineannotation> ; Answer the line</lineannotation>
! 			exten=&gt;s,2,Playback(welcome)<lineannotation> ; Play back the 'welcome' sound file</lineannotation>
! 			exten=&gt;s,3,Dial(Zap/2&amp;Zap/3)<lineannotation> ; Dial both channels Zap/2 and Zap/3</lineannotation>
  			</programlisting>
+ 			</informalexample>	
+ 		</sect2>
+ 		<sect2>
+ 			<title>Creating Voice Menus</title>
  			<para>
! 			[Explain what IVR is, and why we want it in our dial plan]
! 			[The <filename>menu</filename> file is a voice recording saying 
! 			"Press 1 for the Operator or 2 to speak with John"]
! 			</para>
! 		</sect2>
! 		<sect2>
! 			<title>Accepting User Input with the <function>Background()</function> Function</title>
! 			<para>
! 			[Explain the Background() application, and how it's different than Playback()]
  			</para>
+ 		</sect2>
+ 		<sect2>
+ 			<title>Adding a Voice Menu</title>
+ 			<para>
+ 			[Now that we understand IVR and the Background() app,
+ 			let's use them in our example.]
+ 			</para>
+ 			<informalexample>
+ 			<programlisting>
+ 			[incoming]
+ 			exten=&gt;s,1,Answer()<lineannotation> ; Answer the line</lineannotation>
+ 			exten=&gt;s,2,Playback(welcome)<lineannotation> ; Play back the 'welcome' sound file</lineannotation>
+ 			exten=&gt;s,3,Background(menu)<lineannotation> ; Play 'menu' file and accept input from caller</lineannotation>
+ 			exten=&gt;1,1,Dial(Zap/2)<lineannotation> ; Dial channels Zap/2 if the user dials 1</lineannotation>
+ 			exten=&gt;2,1,Dial(Zap/3)<lineannotation> ; Dial channels Zap/3 if the user dials 2</lineannotation>
+ 			</programlisting>
+ 			</informalexample>	
+ 		</sect2>
+ 		<sect2>
+ 			<title>Handling Calls Between Internal Users</title>
+ 			<para>
+ 			[Explain that we're going to add a second context, 
+ 			and use it for calling between internal extensions.]
+ 			</para>
+ 			<informalexample>
+ 			<programlisting>
+ 			[incoming]
+ 			exten=&gt;s,1,Answer()<lineannotation> ; Answer the line</lineannotation>
+ 			exten=&gt;s,2,Playback(welcome)<lineannotation> ; Play back the 'welcome' sound file</lineannotation>
+ 			exten=&gt;s,3,Background(menu)<lineannotation> ; Play 'menu' file and accept input from caller</lineannotation>
+ 			exten=&gt;1,1,Dial(Zap/2)<lineannotation> ; Dial channels Zap/2 if the user dials 1</lineannotation>
+ 			exten=&gt;2,1,Dial(Zap/3)<lineannotation> ; Dial channels Zap/3 if the user dials 2</lineannotation>
+ 
+ 			[internal]
+ 			exten=>&gt;1001,1,Dial(Zap/2)<lineannotation> ; Dialing extension 1001 calls channel Zap/2</lineannotation>
+ 			exten=>&gt;1002,1,Dial(Zap/3)<lineannotation> ; Dialing extension 1002 calls channel Zap/3</lineannotation>
+ 			</programlisting>
+ 			</informalexample>	
+ 		</sect2>
+ 	</sect1>
+ 	<sect1>
+ 		<title>Variables</title>
+ 		<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>
+ 		<para>
+ 		There are two types of variables, namely global variables and 
+ 		call variables.  As their names imply, global variables apply
+ 		to all extensions, while call variables only apply to the
+ 		current call in progress.
+ 		</para>
+ 		<sect2>
+ 			<title>Global Variables</title>
+ 			<para>
+ 			</para>
+ 		</sect2>
+ 		<sect2>
+ 			<title>Call Variables</title>
+ 			<para>
+ 			</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, or division.
+ 			</para>
+ 			<para>
+ 			[example of some simple variable expressions]
+ 			</para>
+ 			<para>
+ 			For more information on using expressions with variables, see
+ 			the <filename>README.variables</filename> file that comes with
+ 			the Asterisk source code.
+ 			</para>
+ 		</sect2>
+ 		<sect2>
+ 			<title>Adding Variables</title>
+ 			<para>
+ 			[Take our Widgets Inc. example and add variables for 
+ 			${RECEPTIONIST}, etc.]
+ 			</para>
+ 			<informalexample>
+ 			<programlisting>
+ 			[global]
+ 			RECEPTIONIST=Zap/2<lineannotation> ; Assign 'Zap/2' to the global variable ${RECEPTIONIST}</lineannotation>
+ 			JOHN=Zap/3<lineannotation>         ; Assign 'Zap/3' to the global variable ${JOHN}</lineannotation>
+ 
+ 			[incoming]
+ 			exten=&gt;s,1,Answer()
+ 			exten=&gt;s,2,Playback(welcome)
+ 			exten=&gt;s,3,Background(menu)
+ 			exten=&gt;1,1,Dial(${RECEPTIONIST})<lineannotation> ; Dial the channel assigned to ${RECEPTIONIST}</lineannotation>
+ 			exten=&gt;2,1,Dial(${JOHN})<lineannotation> ; Dial channel assigned to ${JOHN}</lineannotation>
+ 
+ 			[internal]
+ 			exten=>&gt;1001,1,Dial(Zap/2)<lineannotation> ; Dialing extension 1001 calls channel Zap/2</lineannotation>
+ 			exten=>&gt;1002,1,Dial(Zap/3)<lineannotation> ; Dialing extension 1002 calls channel Zap/3</lineannotation>
+ 			</programlisting>
+ 			</informalexample>	
+ 			<sidebar>
+ 			<title>A Useful Debugging Tip</title>
+ 			<para>
+ 			[As a sidebar, explain how you can use the NoOp() application to debug variables]
+ 			</para>
+ 			</sidebar>
+ 		</sect2>
+ 	</sect1>
+ 	<sect1>
+ 		<title>Macros</title>
+ 		<para/>
+ 		<sect2>
+ 			<title>What are Macros?</title>
+ 			<para/>
+ 		</sect2>
+ 		<sect2>
+ 			<title>Attributes of Macros</title>
+ 			<para>
+ 			[Macros start with "macro-"]
+ 			[Macros are expanded in place]
+ 			[Macros use the "s" extension]
+ 			[Variables are passed in as <replaceable>ARG1</replaceable>, <replaceable>ARG2</replaceable>, etc.]
+ 			</para>
+ 		</sect2>
+ 		<sect2>
+ 			<title>Adding Macros to our Dial Plan</title>
+ 			<para/>
+ 		</sect2>
+ 	</sect1>
+ 	<sect1>
+ 		<title>Call Flow</title>
+ 		<para/>
+ 		<sect2>
+ 			<title>Pattern Matching</title>
+ 			<para>
+ 			[Patterns start with "_"]
+ 			[More specific patterns take priority, don't they?]
+ 			[Explain the ${EXTEN} variable, along with the ${EXTEN:i:j} syntax]
+ 			[Example of a simple "outbound" context]
+ 			</para>
+ 		</sect2>
+ 		<sect2>
+ 			<title>Linking Contexts with Includes</title>
+ 			<para>
+ 			[How to do it]
+ 			[Order of includes count! Explain why...]
+ 			[Time-sensitive includes]
+ 			[OK, now let's "include" the "outbound" context inside of the "internal" context]
+ 			</para>
+ 		</sect2>
+ 		<sect2>
+ 			<title>The other special extensions (i,t,o,h,fax,???)</title>
  			<simplelist>
  			<member>'s' - start</member>
***************
*** 112,125 ****
  			<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. There are
! 			currently some problems to be aware of. Specifically the
  			variables about the call are lost as the information is
  			destroyed with the channel. 
  			</para>
  			<para>
  			Timeout is for when a user is presented with a menu and they do not
--- 271,288 ----
  			<para>
  			The start extension is for most calls that are initiated with no
! 			other known information.  
  			</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>
! 			<warning>
! 			<para>
! 			There are currently some problems to be aware of when
! 			using the 'h' extension. Specifically, the
  			variables about the call are lost as the information is
  			destroyed with the channel. 
  			</para>
+ 			</warning>
  			<para>
  			Timeout is for when a user is presented with a menu and they do not
***************
*** 144,429 ****
  			they had been cut off unintendedly.
  			</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>
  		</sect2>
! 	</sect1>
! 	<sect1>
! 		<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 [globals]
! 		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>
! 		[globals]
! 		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>
! 		<programlisting>
! 		[incoming]
! 		include =&gt; extensions
! 
! 		exten =&gt; s,1,Wait(1)
! 		exten =&gt; s,2,SetVar(counter=0)
! 		exten =&gt; s,3,Answer()
! 		exten =&gt; s,4,DigitTimeout(15)
! 		exten =&gt; s,5,ResponseTimeout(10)
! 		exten =&gt; s,6,Background(hello)
! 		
! 		exten =&gt; t,1,SetVar(counter=[${counter}+1])
! 		exten =&gt; t,2,Gotoif([${counter}&lt;3]?s,6:h,1)
! 
! 		exten =&gt; h,1,hangup() 
! 		</programlisting>
! 		<para>
! 		This example shows using the timeout to force the call to continue
! 		moving. In this case, we add 1 to the counter variable and decide if we
! 		exceeded an acceptable number of prompt repeats. If it exceeds this
! 		limit, then we push the call to the hangup extension and let it clean
! 		things up. 
! 		</para>
! 	</sect1>
! 	<sect1>
! 		<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>
! 	</sect1>
! 	<sect1>
! 		<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, at least in the USA. Others may be used to seeing 
! 		other digits such as 0. 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>
! 		[globals]
! 		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>
  	</sect1>
  </chapter>
--- 307,315 ----
  			they had been cut off unintendedly.
  			</para>
  		</sect2>
! 		<sect2>
! 			<title>Using Goto and GotoIf</title>
! 			<para/>
! 		</sect2>
  	</sect1>
  </chapter>