Merge Steve Murphy's (murf) complete re-implementation of AEL, which is now no longer...
[asterisk/asterisk.git] / doc / ael.txt
1 The Asterisk Extension Language - v 2
2 =====================================
3
4 AEL is a specialized language intended purely for 
5 describing Asterisk dial plans.
6
7 The current version was written by Steve Murphy, and is a rewrite of 
8 the original version.
9
10 AEL is considered an EXPERIMENTAL Version. (yet is being
11 used in the field with success)
12
13 This new version further extends AEL, and
14 provides more flexible syntax, better error messages, and some missing
15 functionality.
16
17 AEL is really the merger of 4 different 'languages', or syntaxes:
18
19     * The first and most obvious is the AEL syntax itselft. A BNF is
20       provided near the end of this document.
21
22     * The second syntax is the Expression Syntax, which is normally
23      handled by Asterisk extension engine, as expressions enclosed in
24      $[...]. The right hand side of assignments are wrapped in $[ ... ] 
25      by AEL, and so are the if and while expressions, among others.
26
27     * The third syntax is the Variable Reference Syntax, the stuff
28       enclosed in ${..} curly braces. It's a bit more involved than just
29       putting a variable name in there. You can include one of dozens of
30       'functions', and their arguments, and there are even some string
31       manipulation notation in there.
32
33     * The last syntax that underlies AEL, and is not used
34       directly in AEL, is the Extension Language Syntax. The
35       extension language is what you see in extensions.conf, and AEL
36       compiles the higher level AEL language into extensions and
37       priorities, and passes them via function calls into
38       Asterisk. Embedded in this language is the Application/AGI
39       commands, of which one application call per step, or priority
40       can be made. You can think of this as a "macro assembler"
41       language, that AEL2 will compile into.
42
43
44 Any programmer of AEL should be familiar with it's syntax, of course,
45 as well as the Expression syntax, and the Variable syntax.
46
47 **************************
48 * Asterisk in a Nutshell *
49 **************************
50
51 Asterisk acts as a server. Devices involved in telephony, like Zapata
52 cards, or Voip phones, all indicate some context that should be
53 activated in their behalf. See the config file formats for IAX, SIP,
54 zapata.conf, etc. They all help describe a device, and they all
55 specify a context to activate when somebody picks up a phone, or a
56 call comes in from the phone company, or a voip phone, etc.
57
58 Contexts
59 --------
60
61 Contexts are a grouping of extensions.
62
63 Contexts can also include other contexts. Think of it as a sort of
64 merge operation at runtime, whereby the included context's extensions
65 are added to the contexts making the inclusion.
66
67 Extensions and priorities
68 -------------------------
69
70 A Context contains zero or more Extensions. There are several
71 predefined extensions. The "s" extension is the "start" extension, and
72 when a device activates a context the "s" extension is the one that is
73 going to be run. Other extensions are the timeout "t" extension, the
74 invalid response, or "i" extension, and there's a "fax" extension. For
75 instance, a normal call will activate the "s" extension, but an
76 incoming FAX call will come into the "fax" extension, if it
77 exists. (BTW, asterisk can tell it's a fax call by the little "beep"
78 that the calling fax machine emits every so many seconds.).
79
80 Extensions contain several priorities, which are individual
81 instructions to perform. Some are as simple as setting a variable to a
82 value. Others are as complex as initiating the Voicemail application,
83 for instance. Priorities are executed in order.
84
85 When the 's" extension completes, asterisk waits until the timeout for
86 a response. If the response matches an extension's pattern in the
87 context, then control is transferred to that extension. Usually the
88 responses are tones emitted when a user presses a button on their
89 phone. For instance, a context associated with a desk phone might not
90 have any "s" extension. It just plays a dialtone until someone starts
91 hitting numbers on the keypad, gather the number, find a matching
92 extension, and begin executing it. That extension might Dial out over
93 a connected telephone line for the user, and then connect the two
94 lines together.
95
96 The extensions can also contain "goto" or "jump" commands to skip to
97 extensions in other contexts. Conditionals provide the ability to
98 react to different stimiuli, and there you have it.
99
100 Macros
101 ------
102
103 Think of a macro as a combination of a context with one nameless
104 extension, and a subroutine. It has arguments like a subroutine
105 might. A macro call can be made within an extension, and the
106 individual statements there are executed until it ends. At this point,
107 execution returns to the next statement after the macro call. Macros
108 can call other macros. And they work just like function calls.
109
110 Applications
111 ------------
112
113 Application calls, like "Dial()", or "Hangup()", or "Answer()", are
114 available for users to use to accomplish the work of the
115 dialplan. There are over 145 of them at the moment this was written,
116 and the list grows as new needs and wants are uncovered. Some
117 applications do fairly simple things, some provide amazingly complex
118 services.
119
120 Hopefully, the above objects will allow you do anything you need to in
121 the Asterisk environment!
122
123
124 *******************
125 * Getting Started *
126 *******************
127
128 The AEL parser (pbx_ael.so) is completely separate from the module
129 that parses extensions.conf (pbx_config.so). To use AEL, the only
130 thing that has to be done is the module pbx_ael.so must be loaded by
131 Asterisk. This will be done automatically if using 'autoload=yes' in
132 /etc/asterisk/modules.conf. When the module is loaded, it will look
133 for 'extensions.ael' in /etc/asterisk/. extensions.conf and
134 extensions.ael can be used in conjunction with
135 each other if that is what is desired. Some users may want to keep
136 extensions.conf for the features that are configured in the 'general'
137 section of extensions.conf.
138
139 ------------------------------
140 - Reloading extensions.ael  -
141 ------------------------------
142
143 To reload extensions.ael, the following command can be issued at the
144 CLI:
145
146     *CLI> ael reload
147
148
149
150 *************
151 * Debugging *
152 *************
153
154 Right at this moment, the following commands are available, but do
155 nothing:
156
157 Enable AEL contexts debug
158    *CLI> ael debug contexts 
159
160 Enable AEL macros debug
161    *CLI> ael debug macros 
162
163 Enable AEL read debug
164    *CLI> ael debug read
165
166 Enable AEL tokens debug
167    *CLI> ael debug tokens 
168
169 Disable AEL debug messages
170    *CLI> ael no debug
171
172 If things are going wrong in your dialplan, you can use the following
173 facilities to debug your file:
174
175 1. The messages log in /var/log/asterisk. (from the checks done at load time).
176 2. the "show dialplan" command in asterisk
177 3. the standalone executable, "aelparse" built in the utils/ dir in the source.
178
179
180 *****************************
181 * About "aelparse"          *
182 *****************************
183
184 You can also use the "aelparse" program to check your extensions.ael
185 file before feeding it to asterisk. Wouldn't it be nice to eliminate
186 most errors before giving the file to asterisk?
187
188 aelparse is compiled in the utils directory of the asterisk release.
189 It isn't installed anywhere (yet). You can copy it to your favorite
190 spot in your PATH.
191
192 aelparse has two optional arguments:
193
194 -d   - Override the normal location of the config file dir, (usually
195        /etc/asterisk), and use the current directory instead as the
196        config file dir. Aelparse will then expect to find the file
197        "./extensions.ael" in the current directory, and any included
198        files in the current directory as well.
199
200 -n   - don't show all the function calls to set priorities and contexts
201        within asterisk. It will just show the errors and warnings from
202        the parsing and semantic checking phases.
203
204
205 ******************************
206 * General Notes about Syntax *
207 ******************************
208
209 Note that the syntax and style are now a little more free-form. The
210 opening '{' (curly-braces) do not have to be on the same line as the
211 keyword that precedes them. Statements can be split across lines, as
212 long as tokens are not broken by doing so. More than one statement can
213 be included on a single line. Whatever you think is best!
214
215 You can just as easily say,
216
217 if(${x}=1) { NoOp(hello!); goto s|3; } else { NoOp(Goodbye!); goto s|12; }
218
219 as you can say:
220
221 if(${x}=1)
222 {
223        NoOp(hello!);
224    goto s|3;
225 }
226 else
227 {
228        NoOp(Goodbye!);
229        goto s|12;
230 }
231
232 or:
233
234 if(${x}=1) {
235        NoOp(hello!);
236    goto s|3;
237 } else {
238        NoOp(Goodbye!);
239        goto s|12;
240 }
241
242 or:
243
244 if (${x}=1) {
245        NoOp(hello!); goto s|3;
246 } else {
247        NoOp(Goodbye!); goto s|12;
248 }
249
250 or even:
251
252 if
253 (${x}=1)
254 {
255 NoOp(hello!);
256 goto s|3;
257 }
258 else
259 {
260 NoOp(Goodbye!);
261 goto s|12;
262 }
263
264
265 ************
266 * Keywords *
267 ************
268
269 The AEL keywords are case-sensitive. If an application name and a
270 keyword overlap, there is probably good reason, and you should
271 consider replacing the application call with an AEL statement. If you
272 do not wish to do so, you can still use the application, by using a
273 capitalized letter somewhere in its name. In the Asterisk extension
274 language, application names are NOT case-sensitive.
275
276 The following are keywords in the AEL2 language:
277
278     * abstract
279     * context
280     * macro
281     * globals
282     * ignorepat
283     * switch
284     * if
285     * ifTime
286     * else
287     * random
288     * goto
289     * jump
290     * return
291     * break
292     * continue
293     * regexten
294     * hint
295     * for
296     * while
297     * case
298     * pattern
299     * default   NOTE: the "default" keyword can be used as a context name, 
300                       for those who would like to do so.
301     * catch
302     * switches
303     * eswitches
304     * includes 
305
306
307
308
309
310 Procedural Interface and Internals
311 ==================================
312
313 AEL first parses the extensions.ael file into a memory structure representing the file.
314 The entire file is represented by a tree of "pval" structures linked together.
315
316 This tree is then handed to the semantic check routine. 
317
318 Then the tree is handed to the compiler. 
319
320 After that, it is freed from memory.
321
322 A program could be written that could build a tree of pval structures, and
323 a pretty printing function is provided, that would dump the data to a file,
324 or the tree could be handed to the compiler to merge the data into the 
325 asterisk dialplan. The modularity of the design offers several opportunities
326 for developers to simplify apps to generate dialplan data.
327
328
329
330 =========================
331         AEL version 2 BNF
332 =========================
333
334
335
336 (hopefully, something close to bnf).
337
338 First, some basic objects
339
340 ------------------------
341
342 <word>    a lexical token consisting of characters matching this pattern: [-a-zA-Z0-9"_/.\<\>\*\+!$#\[\]][-a-zA-Z0-9"_/.!\*\+\<\>\{\}$#\[\]]*
343
344 <word3-list>  a concatenation of up to 3 <word>s.
345
346 <collected-word>  all characters encountered until the character that follows the <collected-word> in the grammar.
347
348 -------------------------
349
350 <file> :== <objects>
351
352 <objects> :== <object>
353            | <objects> <object>
354
355
356 <object> :==  <context>
357          | <macro>
358          | <globals>
359          | ';'
360
361
362 <context> :==  'context' <word> '{' <elements> '}'
363             | 'context' <word> '{' '}'
364             | 'context' 'default' '{' <elements> '}'
365             | 'context' 'default' '{' '}'
366             | 'abstract'  'context' <word> '{' <elements> '}'
367             | 'abstract'  'context' <word> '{' '}'
368             | 'abstract'  'context' 'default' '{' <elements> '}'
369             | 'abstract'  'context' 'default' '{' '}'
370
371
372 <macro> :== 'macro' <word> '(' <arglist> ')' '{' <macro_statements> '}'
373        | 'macro' <word> '(' <arglist> ')' '{'  '}'
374        | 'macro' <word> '(' ')' '{' <macro_statements> '}'
375        | 'macro' <word> '(' ')' '{'  '}'
376
377
378 <globals> :== 'globals' '{' <global_statements> '}'
379          | 'globals' '{' '}'
380
381
382 <global_statements> :== <global_statement>
383                    | <global_statements> <global_statement>
384
385
386 <global_statement> :== <word> '=' <collected-word> ';'
387
388
389 <arglist> :== <word>
390          | <arglist> ',' <word>
391
392
393 <elements> :==  <element>
394              | <elements> <element>
395
396
397 <element> :== <extension>
398          | <includes>
399          | <switches>
400          | <eswitches>
401          | <ignorepat>
402          | <word> '='  <collected-word> ';'
403          | ';'
404
405
406 <ignorepat> :== 'ignorepat' '=>' <word> ';'
407
408
409 <extension> :== <word> '=>' <statement>
410            | 'regexten' <word> '=>' <statement>
411            | 'hint' '(' <word3-list> ')' <word> '=>' <statement>
412            | 'regexten' 'hint' '(' <word3-list> ')' <word> '=>' <statement>
413
414
415 <statements> :== <statement>
416             | <statements> <statement>
417
418 <if_head> :== 'if' '('  <collected-word> ')'
419
420 <random_head> :== 'random' '(' <collected-word> ')'
421
422 <ifTime_head> :== 'ifTime' '(' <word3-list> ':' <word3-list> ':' <word3-list> '|' <word3-list> '|' <word3-list> '|' <word3-list> ')'
423                        | 'ifTime' '(' <word> '|' <word3-list> '|' <word3-list> '|' <word3-list> ')'
424
425
426 <word3-list> :== <word>
427        | <word> <word>
428        | <word> <word> <word>
429
430 <switch_head> :== 'switch' '(' <collected-word> ')'  '{'
431
432
433 <statement> :== '{' <statements> '}'
434        | <word> '='  <collected-word> ';'
435        | 'goto' <target> ';'
436        | 'jump' <jumptarget> ';'
437        | <word> ':'
438        | 'for' '('  <collected-word> ';'  <collected-word> ';' <collected-word> ')' <statement>
439        | 'while' '('  <collected-word> ')' <statement>
440        | <switch_head> '}'
441        | <switch_head> <case_statements> '}'
442        | '&' macro_call ';'
443        | <application_call> ';'
444        | <application_call> '='  <collected-word> ';'
445        | 'break' ';'
446        | 'return' ';'
447        | 'continue' ';'
448        | <random_head> <statement>
449        | <random_head> <statement> 'else' <statement>
450        | <if_head> <statement>
451        | <if_head> <statement> 'else' <statement>
452        | <ifTime_head> <statement>
453        | <ifTime_head> <statement> 'else' <statement>
454        | ';'
455
456 <target> :== <word>
457        | <word> '|' <word>
458        | <word> '|' <word> '|' <word>
459        | 'default' '|' <word> '|' <word>
460        | <word> ',' <word>
461        | <word> ',' <word> ',' <word>
462        | 'default' ',' <word> ',' <word>
463
464 <jumptarget> :== <word>
465                | <word> ',' <word>
466                | <word> ',' <word> '@' <word>
467                | <word> '@' <word>
468                | <word> ',' <word> '@' 'default'
469                | <word> '@' 'default'
470
471 <macro_call> :== <word> '(' <eval_arglist> ')'
472        | <word> '(' ')'
473
474 <application_call_head> :== <word>  '('
475
476 <application_call> :== <application_call_head> <eval_arglist> ')'
477        | <application_call_head> ')'
478
479 <eval_arglist> :==  <collected-word>
480        | <eval_arglist> ','  <collected-word>
481        |  /* nothing */
482        | <eval_arglist> ','  /* nothing */
483
484 <case_statements> :== <case_statement>
485        | <case_statements> <case_statement>
486
487
488 <case_statement> :== 'case' <word> ':' <statements>
489        | 'default' ':' <statements>
490        | 'pattern' <word> ':' <statements>
491        | 'case' <word> ':'
492        | 'default' ':'
493        | 'pattern' <word> ':'
494
495 <macro_statements> :== <macro_statement>
496        | <macro_statements> <macro_statement>
497
498 <macro_statement> :== <statement>
499        | 'catch' <word> '{' <statements> '}'
500
501 <switches> :== 'switches' '{' <switchlist> '}'
502        | 'switches' '{' '}'
503
504 <eswitches> :== 'eswitches' '{' <switchlist> '}'
505        | 'eswitches' '{'  '}'
506
507 <switchlist> :== <word> ';'
508        | <switchlist> <word> ';'
509
510 <includeslist> :== <includedname> ';'
511        | <includedname> '|' <word3-list> ':' <word3-list> ':' <word3-list> '|' <word3-list> '|' <word3-list> '|' <word3-list> ';'
512        | <includedname> '|' <word> '|' <word3-list> '|' <word3-list> '|' <word3-list> ';'
513        | <includeslist> <includedname> ';'
514        | <includeslist> <includedname> '|' <word3-list> ':' <word3-list> ':' <word3-list> '|' <word3-list> '|' <word3-list> '|' <word3-list> ';'
515        | <includeslist> <includedname> '|' <word> '|' <word3-list> '|' <word3-list> '|' <word3-list> ';'
516
517 <includedname> :== <word>
518         | 'default'
519
520 <includes> :== 'includes' '{' <includeslist> '}'
521        | 'includes' '{' '}'
522
523
524 **************************
525 * AEL Example USAGE *****
526 **************************
527
528 Comments
529 ========
530
531 Comments begin with // and end with the end of the line.
532
533 Comments are removed by the lexical scanner, and will not be
534 recognized in places where it is busy gathering expressions to wrap in
535 $[] , or inside application call argument lists. The safest place to put
536 comments is after terminating semicolons, or on otherwise empty lines.
537
538
539 Context
540 =======
541
542 Contexts in AEL represent a set of extensions in the same way that
543 they do in extensions.conf.
544
545
546 context default {
547
548 }
549
550
551 A context can be declared to be "abstract", in which case, this
552 declaration expresses the intent of the writer, that this context will
553 only be included by another context, and not "stand on its own". The
554 current effect of this keyword is to prevent "goto " statements from
555 being checked.
556
557
558 abstract context longdist {
559             _1NXXNXXXXXX => NoOp(generic long distance dialing actions in the US);
560 }
561
562
563
564 Extensions
565 ==========
566
567 To specify an extension in a context, the following syntax is used. If
568 more than one application is be called in an extension, they can be
569 listed in order inside of a block.
570
571
572 context default {
573     1234 => Playback(tt-monkeys);
574     8000 => {
575          NoOp(one);
576          NoOp(two);
577          NoOp(three);
578     };
579     _5XXX => NoOp(it's a pattern!);
580 }
581
582
583 Two optional items have been added to the AEL syntax, that allow the
584 specification of hints, and a keyword, regexten, that will force the
585 numbering of priorities to start at 2.
586
587
588 context default {
589
590     regexten _5XXX => NoOp(it's a pattern!);
591 }
592
593
594
595 context default {
596
597     hint(Sip/1) _5XXX => NoOp(it's a pattern!);
598 }
599
600
601
602 context default {
603
604     regexten hint(Sip/1) _5XXX => NoOp(it's a pattern!);
605 }
606
607
608 The regexten must come before the hint if they are both present.
609
610
611
612 Includes
613 ========
614
615 Contexts can be included in other contexts. All included contexts are
616 listed within a single block.
617
618
619 context default {
620     includes {
621          local;
622          longdistance;
623          international;
624     }
625 }
626
627
628 Time-limited inclusions can be specified, as in extensions.conf
629 format, with the fields described in the wiki page Asterisk cmd
630 GotoIfTime.
631
632
633 context default {
634     includes {
635          local;
636          longdistance|16:00-23:59|mon-fri|*|*;
637          international;
638     }
639 }
640
641
642 #include
643 ========
644
645 You can include other files with the #include "filepath" construct.
646
647
648    #include "/etc/asterisk/testfor.ael"
649
650
651 An interesting property of the #include, is that you can use it almost
652 anywhere in the .ael file. It is possible to include the contents of
653 a file in a macro, context, or even extension.  The #include does not
654 have to occur at the beginning of a line. Included files can include
655 other files, up to 50 levels deep. If the path provided in quotes is a
656 relative path, the parser looks in the config file directory for the
657 file (usually /etc/asterisk).
658
659
660
661 Dialplan Switches
662 =================
663
664 Switches are listed in their own block within a context. For clues as
665 to what these are used for, see Asterisk - dual servers, and Asterisk
666 config extensions.conf.
667
668
669 context default {
670     switches {
671          DUNDi/e164;
672          IAX2/box5;
673     };
674     eswitches {
675          IAX2/context@${CURSERVER};
676     }
677 }
678
679
680
681 Ignorepat
682 =========
683
684 ignorepat can be used to instruct channel drivers to not cancel
685 dialtone upon receipt of a particular pattern. The most commonly used
686 example is '9'.
687
688
689 context outgoing {
690     ignorepat => 9;
691 }
692
693
694
695
696 Variables
697 =========
698
699 Variables in Asterisk do not have a type, so to define a variable, it
700 just has to be specified with a value.
701
702 Global variables are set in their own block.
703
704
705 globals {
706     CONSOLE=Console/dsp;
707     TRUNK=Zap/g2;
708 }
709
710
711
712 Variables can be set within extensions as well.
713
714
715 context foo {
716     555 => {
717          x=5;
718          y=blah;
719          divexample=10/2
720          NoOp(x is ${x} and y is ${y} !);
721     }
722 }
723
724
725 NOTE: AEL wraps the right hand side of an assignment with $[ ] to allow 
726 expressions to be used If this is unwanted, you can protect the right hand 
727 side from being wrapped by using the Set() application. 
728 Read the README.variables about the requirements and behavior 
729 of $[ ] expressions.
730
731 NOTE: These things are wrapped up in a $[ ] expression: The while() test; 
732 the if() test; the middle expression in the for( x; y; z) statement 
733 (the y expression); Assignments - the right hand side, so a = b -> Set(a=$[b])
734
735 Writing to a dialplan function is treated the same as writing to a variable.
736
737
738 context blah {
739     s => {
740          CALLERID(name)=ChickenMan;
741          NoOp(My name is ${CALLERID(name)} !);
742     }
743
744
745
746
747 Loops
748 =====
749
750 AEL has implementations of 'for' and 'while' loops.
751
752
753 context loops {
754     1 => {
755          for (x=0; ${x} < 3; x=${x} + 1) {
756               Verbose(x is ${x} !);
757          }
758     }
759     2 => {
760          y=10;
761          while (${y} >= 0) {
762               Verbose(y is ${y} !);
763               y=${y}-1;
764          }
765     }
766 }
767
768
769 NOTE: The conditional expression (the "${y} >= 0" above) is wrapped in
770       $[ ] so it can be evaluated.  NOTE: The for loop test expression
771       (the "${x} < 3" above) is wrapped in $[ ] so it can be evaluated.
772
773
774
775 Conditionals
776 ============
777
778 AEL supports if and switch statements, like AEL, but adds ifTime, and
779 random. Unlike the original AEL, though, you do NOT need to put curly
780 braces around a single statement in the "true" branch of an if(), the
781 random(), or an ifTime() statement. The if(), ifTime(), and random()
782 statements allow optional else clause.
783
784
785 context conditional {
786     _8XXX => {
787          Dial(SIP/${EXTEN});
788          if ("${DIALSTATUS}" = "BUSY")
789          {
790               NoOp(yessir);
791               Voicemail(${EXTEN}|b);
792          }
793          else
794               Voicemail(${EXTEN}|u);
795          ifTime (14:00-25:00|sat-sun|*|*) 
796               Voicemail(${EXTEN}|b);
797          else
798          {
799               Voicemail(${EXTEN}|u);
800               NoOp(hi, there!);
801          }
802          random(51) NoOp(This should appear 51% of the time);
803
804          random( 60 )
805          {
806                        NoOp( This should appear 60% of the time );
807          }
808          else
809          {
810                        random(75)
811                        {
812                                NoOp( This should appear 30% of the time! );
813                        }
814                        else
815                        {
816                                NoOp( This should appear 10% of the time! );
817                        }
818           }
819     }
820     _777X => {
821          switch (${EXTEN}) {
822               case 7771:
823                    NoOp(You called 7771!);
824                    break;
825               case 7772:
826                    NoOp(You called 7772!);
827                    break;
828               case 7773:
829                    NoOp(You called 7773!);
830                    // fall thru-
831               pattern 777[4-9]:
832                     NoOp(You called 777 something!);
833               default:
834                    NoOp(In the default clause!);
835          }
836     }
837 }
838
839
840 NOTE: The conditional expression in if() statements (the
841       "${DIALSTATUS}" = "BUSY" above) is wrapped by the compiler in 
842       $[] for evaluation.
843
844 NOTE: Neither the switch nor case values are wrapped in $[ ]; they can
845       be constants, or ${var} type references only.
846
847 NOTE: AEL generates each case as a separate extension. case clauses
848       with no terminating 'break', or 'goto', have a goto inserted, to
849       the next clause, which creates a 'fall thru' effect.
850
851 NOTE: AEL introduces the ifTime keyword/statement, which works just
852       like the if() statement, but the expression is a time value,
853       exactly like that used by the application GotoIfTime(). See
854       Asterisk cmd GotoIfTime
855
856 NOTE: The pattern statement makes sure the new extension that is
857       created has an '_' preceding it to make sure asterisk recognizes
858       the extension name as a pattern.
859
860 NOTE: Every character enclosed by the switch expression's parenthesis
861       are included verbatim in the labels generated. So watch out for
862       spaces!
863
864 NOTE: NEW: Previous to version 0.13, the random statement used the
865       "Random()" application, which has been deprecated. It now uses
866       the RAND() function instead, in the GotoIf application.
867
868
869 Break, Continue, and Return
870 ===========================
871
872
873 Three keywords, break, continue, and return, are included in the
874 syntax to provide flow of control to loops, and switches.
875
876 The break can be used in switches and loops, to jump to the end of the
877 loop or switch.
878
879 The continue can be used in loops (while and for) to immediately jump
880 to the end of the loop. In the case of a for loop, the increment and
881 test will then be performed. In the case of the while loop, the
882 continue will jump to the test at the top of the loop.
883
884 The return keyword will cause an immediate jump to the end of the
885 context, or macro, and can be used anywhere.
886
887
888
889 goto, jump, and labels
890 ======================
891
892 This is an example of how to do a goto in AEL.
893
894
895 context gotoexample {
896     s => {
897 begin:
898          NoOp(Infinite Loop!  yay!);
899          Wait(1);
900          goto begin;    // go to label in same extension
901     }
902     3 => {
903             goto s|begin;   // go to label in different extension
904      }
905      4 => {
906             goto gotoexample|s|begin;  // overkill go to label in same context
907      }
908 }
909
910 context gotoexample2 {
911      s =>  {
912    end: 
913            goto gotoexample|s|begin;   // go to label in different context
914      }
915 }
916
917 You can use the special label of "1" in the goto and jump
918 statements. It means the "first" statement in the extension. I would
919 not advise trying to use numeric labels other than "1" in goto's or
920 jumps, nor would I advise declaring a "1" label anywhere! As a matter
921 of fact, it would be bad form to declare a numeric label, and it might
922 confllict with the priority numbers used internally by asterisk.
923
924 The syntax of the jump statement is: jump
925 extension[,priority][@context] If priority is absent, it defaults to
926 "1". If context is not present, it is assumed to be the same as that
927 which contains the "jump".
928
929
930 context gotoexample {
931     s => {
932 begin:
933          NoOp(Infinite Loop!  yay!);
934          Wait(1);
935          jump s;    // go to first extension in same extension
936     }
937     3 => {
938             jump s,begin;   // go to label in different extension
939      }
940      4 => {
941             jump s,begin@gotoexample;  // overkill go to label in same context
942      }
943 }
944
945 context gotoexample2 {
946      s =>  {
947    end: 
948            jump s@gotoexample;   // go to label in different context
949      }
950 }
951
952 NOTE: goto labels follow the same requirements as the Goto()
953       application, except the last value has to be a label. If the
954       label does not exist, you will have run-time errors. If the
955       label exists, but in a different extension, you have to specify
956       both the extension name and label in the goto, as in: goto s|z;
957       if the label is in a different context, you specify
958       context|extension|label. There is a note about using goto's in a
959       switch statement below...
960
961 NOTE  AEL introduces the special label "1", which is the beginning
962       context number for most extensions.
963
964 NOTE: A NEW addition to AEL: you can now use ',' instead of '|' to 
965       separate the items in the target address. You can't have a mix,
966       though, of '|' and ',' in the target. It's either one, or the other.
967
968
969
970
971 Macros
972 ======
973
974 A macro is defined in its own block like this. The arguments to the
975 macro are specified with the name of the macro. They are then referred
976 to by that same name. A catch block can be specified to catch special
977 extensions.
978
979
980 macro std-exten( ext , dev ) {
981        Dial(${dev}/${ext},20);
982        switch(${DIALSTATUS) {
983        case BUSY:
984                Voicemail(b${ext});
985                break;
986        default:
987                Voicemail(u${ext});
988
989        }
990        catch a {
991                VoiceMailMain(${ext});
992                return;
993        }
994 }
995
996
997 A macro is then called by preceeding the macro name with an
998 ampersand. Empty arguments can be passed simply with nothing between
999 comments(0.11).
1000
1001
1002 context example {
1003     _5XXX => &std-exten(${EXTEN}, "IAX2");
1004     _6XXX => &std-exten(, "IAX2");
1005     _7XXX => &std-exten(${EXTEN},);
1006     _8XXX => &std-exten(,);
1007 }
1008
1009
1010
1011 Examples
1012 ========
1013
1014
1015 context demo {
1016     s => {
1017          Wait(1);
1018          Answer();
1019          TIMEOUT(digit)=5;
1020          TIMEOUT(response)=10;
1021 restart:
1022          Background(demo-congrats);
1023 instructions:
1024          for (x=0; ${x} < 3; x=${x} + 1) {
1025               Background(demo-instruct);
1026               WaitExten();
1027          }
1028     }
1029     2 => {
1030          Background(demo-moreinfo);
1031          goto s|instructions;
1032     }
1033     3 => {
1034          LANGUAGE()=fr;
1035          goto s|restart;
1036     }
1037
1038     500 => {
1039          Playback(demo-abouttotry);
1040          Dial(IAX2/guest@misery.digium.com);
1041          Playback(demo-nogo);
1042          goto s|instructions;
1043     }
1044     600 => {
1045          Playback(demo-echotest);
1046          Echo();
1047          Playback(demo-echodone);
1048          goto s|instructions;
1049     }
1050     # => {
1051 hangup:
1052          Playback(demo-thanks);
1053          Hangup();
1054     }
1055     t => goto #|hangup;
1056     i => Playback(invalid);
1057 }
1058
1059
1060 Semantic Checks
1061 ===============
1062
1063
1064 AEL, after parsing, but before compiling, traverses the dialplan
1065 tree, and makes several checks:
1066
1067     * Macro calls to non-existent macros.
1068     * Macro calls to contexts.
1069     * Macro calls with argument count not matching the definition.
1070     * application call to macro. (missing the '&')
1071     * application calls to "GotoIf", "GotoIfTime", "while",
1072       "endwhile", "Random", and "execIf", will generate a message to
1073       consider converting the call to AEL goto, while, etc. constructs.
1074     * goto a label in an empty extension.
1075     * goto a non-existent label, either a within-extension,
1076       within-context, or in a different context, or in any included
1077       contexts. Will even check "sister" context references.
1078     * All the checks done on the time values in the dial plan, are
1079       done on the time values in the ifTime() and includes times:
1080           o the time range has to have two times separated by a dash;
1081           o the times have to be in range of 0 to 24 hours.
1082           o The weekdays have to match the internal list, if they are provided;
1083           o the day of the month, if provided, must be in range of 1 to 31;
1084           o the month name or names have to match those in the internal list. 
1085     * (0.5) If an expression is wrapped in $[ ... ], and the compiler
1086       will wrap it again, a warning is issued.
1087     * (0.5) If an expression had operators (you know,
1088       +,-,*,/,%,!,etc), but no ${ } variables, a warning is
1089       issued. Maybe someone forgot to wrap a variable name?
1090     * (0.12) check for duplicate context names.
1091     * (0.12) check for abstract contexts that are not included by any context.
1092     * (0.13) Issue a warning if a label is a numeric value. 
1093
1094 There are a subset of checks that have been removed until the proposed
1095 AAL (Asterisk Argument Language) is developed and incorporated into Asterisk.
1096 These checks will be:
1097
1098     * (if the application argument analyzer is working: the presence
1099       of the 'j' option is reported as error.
1100     * if options are specified, that are not available in an
1101       application.
1102     * if you specify too many arguments to an application.
1103     * a required argument is not present in an application call.
1104     * Switch-case using "known" variables that applications set, that
1105       does not cover all the possible values. (a "default" case will
1106       solve this problem. Each "unhandled" value is listed.
1107     * a Switch construct is used, which is uses a known variable, and
1108       the application that would set that variable is not called in
1109       the same extension. This is a warning only...
1110     * Calls to applications not in the "applist" database (installed
1111       in /var/lib/asterisk/applist" on most systems).
1112     * In an assignment statement, if the assignment is to a function,
1113       the function name used is checked to see if it one of the
1114       currently known functions. A warning is issued if it is not.
1115
1116
1117
1118 Differences with the original version of AEL
1119 ============================================
1120
1121    1. The $[...] expressions have been enhanced to inlcude the ==, ||,
1122       and && operators. These operators are exactly equivalent to the
1123       =, |, and & operators, respectively. Why? So the C, Java, C++
1124       hackers feel at home here.
1125    2. It is more free-form. The newline character means very little,
1126       and is pulled out of the white-space only for line numbers in
1127       error messages.
1128    3. It generates more error messages -- by this I mean that any
1129       difference between the input and the grammar are reported, by
1130       file, line number, and column.
1131    4. It checks the contents of $[ ] expressions (or what will end up
1132       being $[ ] expressions!) for syntax errors. It also does
1133       matching paren/bracket counts.
1134    5. It runs several semantic checks after the parsing is over, but
1135       before the compiling begins, see the list above.
1136    6. It handles #include "filepath" directives. -- ALMOST
1137       anywhere, in fact. You could easily include a file in a context,
1138       in an extension, or at the root level. Files can be included in
1139       files that are included in files, down to 50 levels of hierarchy...
1140    7. Local Goto's inside Switch statements automatically have the
1141       extension of the location of the switch statement appended to them.
1142    8. A pretty printer function is available within pbx_ael.so.
1143    9. In the utils directory, two standalone programs are supplied for
1144       debugging AEL files. One is called "aelparse", and it reads in
1145       the /etc/asterisk/extensions.ael file, and shows the results of
1146       syntax and semantic checking on stdout, and also shows the
1147       results of compilation to stdout. The other is "aelparse1",
1148       which uses the original ael compiler to do the same work,
1149       reading in "/etc/asterisk/extensions.ael", using the original
1150       'pbx_ael.so' instead.
1151   10. AEL supports the "jump" statement, and the "pattern" statement
1152       in switch constructs. Hopefully these will be documented in the
1153       AEL README.
1154   11. Added the "return" keyword, which will jump to the end of an
1155       extension/Macro.
1156   12. Added the ifTime (<time range>|<days of week>|<days of
1157       month>|<months> ) {} [else {}] construct, which executes much
1158       like an if () statement, but the decision is based on the
1159       current time, and the time spec provided in the ifTime. See the
1160       example above. (Note: all the other time-dependent Applications
1161       can be used via ifTime)
1162   13. Added the optional time spec to the contexts in the includes
1163       construct. See examples above.
1164   14. You don't have to wrap a single "true" statement in curly
1165       braces, as in the orignal AEL. An "else" is attached to the
1166       closest if. As usual, be careful about nested if statements!
1167       When in doubt, use curlies!
1168   15. Added the syntax [regexten] [hint(channel)] to preceed an
1169       extension declaration. See examples above, under
1170       "Extension". The regexten keyword will cause the priorities in
1171       the extension to begin with 2 instead of 1. The hint keyword
1172       will cause its arguments to be inserted in the extension under
1173       the hint priority. They are both optional, of course, but the
1174       order is fixed at the moment-- the regexten must come before the
1175       hint, if they are both present.
1176   16. Empty case/default/pattern statements will "fall thru" as
1177       expected. (0.6)
1178   17. A trailing label in an extension, will automatically have a
1179       NoOp() added, to make sure the label exists in the extension on
1180       Asterisk. (0.6)
1181   18. (0.9) the semicolon is no longer required after a closing brace!
1182       (i.e. "];" ===> "}". You can have them there if you like, but
1183       they are not necessary. Someday they may be rejected as a syntax
1184       error, maybe.
1185   19. (0.9) the // comments are not recognized and removed in the
1186       spots where expressions are gathered, nor in application call
1187       arguments. You may have to move a comment if you get errors in
1188       existing files.
1189   20. (0.10) the random statement has been added. Syntax: random (
1190       <expr> ) <lucky-statement> [ else <unlucky-statement> ]. The
1191       probability of the lucky-statement getting executed is <expr>,
1192       which should evaluate to an integer between 0 and 100. If the
1193       <lucky-statement> isn't so lucky this time around, then the
1194       <unlucky-statement> gets executed, if it is present.
1195
1196
1197
1198 Hints and Bugs
1199 ==============
1200
1201     * The safest way to check for a null strings is to say $[ "${x}" =
1202      "" ] The old way would do as shell scripts often do, and append
1203      something on both sides, like this: $[ ${x}foo = foo ]. The
1204      trouble with the old way, is that, if x contains any spaces, then
1205      problems occur, usually syntax errors. It is better practice and
1206      safer wrap all such tests with double quotes! Also, there are now
1207      some functions that can be used in a variable referenece,
1208      ISNULL(), and LEN(), that can be used to test for an empty string:
1209      ${ISNULL(${x})} or $[ ${LEN(${x}) = 0 ].
1210
1211     * Assignment vs. Set(). Keep in mind that setting a variable to
1212       value can be done two different ways. If you choose say 'x=y;',
1213       keep in mind that AEL will wrap the right-hand-side with
1214       $[]. So, when compiled into extension language format, the end
1215       result will be 'Set(x=$[y])'. If you don't want this effect,
1216       then say "Set(x=y);" instead.
1217
1218
1219 The Full Power of AEL
1220 ==============================
1221
1222 A newcomer to Asterisk will look at the above constructs and
1223 descriptions, and ask, "Where's the string manipulation functions?",
1224 "Where's all the cool operators that other languages have to offer?",
1225 etc.
1226
1227 The answer is that the rich capabilities of Asterisk are made
1228 available through AEL, via:
1229
1230     * Applications: See Asterisk - documentation of application
1231       commands
1232
1233     * Functions: Functions were implemented inside ${ .. } variable
1234       references, and supply many useful capabilities. 
1235
1236     * Expressions: An expression evaluation engine handles items
1237       wrapped inside $[...]. This includes some string manipulation
1238       facilities, arithmetic expressions, etc. 
1239
1240     * Application Gateway Interface: Asterisk can fork external
1241       processes that communicate via pipe. AGI applications can be
1242       written in any language. Very powerful applications can be added
1243       this way. 
1244
1245     * Variables: Channels of communication have variables associated
1246       with them, and asterisk provides some global variables. These can be
1247       manipulated and/or consulted by the above mechanisms. 
1248