asterisk ael2
TRANSCRIPT
-
8/3/2019 Asterisk AEL2
1/39
Asterisk AEL2
Page Contents
y Asterisk Extension Language v.2y AEL2 Announcements and Newsy The Asterisk Extension Language v.2
o Asterisk in a Nutshello Getting Startedo Reloading extensions.ael2o Debuggingo AELPARSEo General Notes about Syntaxo Keywordso Applicationso Commentso Extensionso Includeso #includeo Dialplan Switcheso Ignorepato Variableso Loopso Conditionalso Break, Continue, and Returno goto, jump, and labelso M
acroso Exampleso Semantic Checkso Differences with the original version of AELo Hints and Bugso The Full Power of AEL and AEL2o Exampleso AEL2 BNFo AEL2 Bug Report Historyo AEL2 Enhancement Request History
Asterisk Extension Language v.2AEL v.2 is intended to provide an actual programming language that can be used to write anAsterisk dialplan. Itfurther extends AEL, and provides more flexible syntax, better error messages, and some missingfunctionality.AEL v.2 is a new version of the AEL compiler, written by Steve Murphy. It was originally
-
8/3/2019 Asterisk AEL2
2/39
introduced as a large asterisk patch in the Asterisk bug database. See: Bug 6021.
AEL is really the merger of 4 different 'languages', or syntaxes:
y The first and most obvious is the AEL v.2 syntax itself. A BNF is provided near the endof t
his document.
y The second syntax is the Expression Syntax, which is normally handled by Asteriskextension engine, as expressions enclosed in $[...]. The right hand side of assignments arewrapped in $[ ... ] by AEL, and so are the if and while expressions, among others.
y The third syntax is the Variable Reference Syntax, the stuff enclosed in ${..} curlybraces. It's a bit more involved than just putting a variable name in there. You can includeone of dozens of 'functions', and their arguments, and there are even some stringmanipulation notation in there.
y The last syntax that underlies AEL/AEL2, and is not used directly in AEL/AEL2, is theExtension Language Syntax. The extension language is what you see inextensions.conf, and AEL2 compiles the higher level AEL2 language into extensions and
priorities, and passes them via function calls into Asterisk. Embedded in t
his language isthe Application/AGI commands, of which one application call per step, or priority can be
made. You can think of this as a "macro assembler" language, that AEL2 will compileinto.
Any programmer of AEL should be familiar with it's syntax, of course, as well as the Expressionsyntax, and the Variable syntax. There are references to Wiki pages covering these, down in the"The Power of AEL" section below.
AEL2 Announcements and News
NEW: For 1.2 users who'd like to have access to AEL2, I've got a better idea. The old way wasto "svn diffhttp://svn.digium.com/svn/asterisk/branches/1.2http://svn.digium.com/svn/asterisk/team/murf/AEL2-1.2 > AEL.patch", and then apply the patchto your current 1.2 based source with "patch -p0 < AEL.patch"; this is a bit of a hassle, as thatbranch is brought back into sync with 1.2 on a weekly or monthly basis. An easier approachwould be to:
svn co http://svn.digium.com/svn/asterisk/team/murf/AEL2-1.2/patches
And then, in the 1.2 source directory, you can simply:
patch -p0 < patches/diffs.AEL2.patch
-
8/3/2019 Asterisk AEL2
3/39
which will apply the changes.
Good news for all you AEL2 fans out there! A couple of weeks ago, I dropped a bug in Murf'sear about adding an option to dump the parsed AEL code into a file, basically a "compile"option. Well, he coded it, we've both tested it, and it seems solid, so it's now in the trunk! just use
aelparse as usual and add the -w option if you want to dump t
he file extensions.conf.aeldump.
Handy for coding in AEL2 but still being able to easily deliver to clients who aren't able orwilling to use AEL2 in their Asterisk implementation! -Rushowr
AEL2 has replaced AEL in the trunkversion of Asterisk. You now get it automatically whenyou svn checkout asterisk! It's upward compatible with the original AEL, but adds severalfeatures, and removes some limitations.
y Please note that AEL (See Asterisk AEL ) is stepping out of the "Experimental" stage.Please help us to make it solid and useful by using it!!
The Asterisk Extension Language v.2
Asterisk in a Nutshell
Asterisk acts as a server. Devices involved in telephony, like Zapata cards, orVoip phones, allindicate some context that should be activated in their behalf. See the config file formats forIAX, SIP, zapata.conf, etc. They all help describe a device, and they all specify a context to
activate when somebody picks up a phone, or a call comes in from the phone company, or a voipphone, etc.
ContextsContexts are a grouping of extensions.
Contexts can also include other contexts. Think of it as a sort of merge operation at runtime,whereby the included context's extensions are added to the contexts making the inclusion.
Extensions and prioritiesA Context contains zero or more Extensions. There are several predefined extensions. The "s"
extension is the "start" extension, and when a device activates a context the "s" extension is theone that is going to be run. Other extensions are the timeout "t" extension, the invalid response,or "i" extension, and there's a "fax" extension. For instance, a normal call will activate the "s"extension, but an incoming FAX call will come into the "fax" extension, if it exists. (BTW,asterisk can tell it's a fax call by the little "beep" that the calling fax machine emits every somany seconds.).
Extensions contain several priorities, which are individual instructions to perform. Some are as
-
8/3/2019 Asterisk AEL2
4/39
simple as setting a variable to a value. Others are as complex as initiating the Voicemailapplication, for instance. Priorities are executed in order.
When the 's" extension completes, asterisk waits until the timeout for a response. If the responsematches an extension's pattern in the context, then control is transferred to that extension.
Usually the responses are tones emitted w
hen a user presses a button on t
heir p
hone. Forinstance, a context associated with a desk phone might not have any "s" extension. It just plays a
dialtone until someone starts hitting numbers on the keypad, gather the number, find a matchingextension, and begin executing it. That extension might Dial out over a connected telephone linefor the user, and then connect the two lines together.
The extensions can also contain "goto" or "jump" commands to skip to extensions in othercontexts. Conditionals provide the ability to react to different stimiuli, and there you have it.
Macros
Think of a macro as a combination of a context wit
hone nameless extension, and a subroutine.
Ithas arguments like a subroutine might. A macro call can be made within an extension, and the
individual statements in the macro are executed until a return statement is executed. At thispoint, execution returns to the next statement after the macro call.Macros can call other macros.And they work just like function calls.
ApplicationsApplication calls, like "Dial()", or "Hangup()", or "Answer()", are available for users to use toaccomplish the work of the dialplan. There are over 145 of them at the moment this was written,and the list grows as new needs and wants are uncovered. Some applications do fairly simplethings, some provide amazingly complex services.
Hopefully, the above objects will allow you do anything you need to in the Asteriskenvironment!
Getting Started
In the following discussion, if you are using the "trunk" version of Asterisk, please note
that AEL2 replaced the original AEL implementation.
So, anywhere in the following discussion where "ael2" or "AEL2" is mentioned, you woulduse "ael" or "AEL" instead. For instance, in thediscussion below, you could type in the command "ael2 reload" if you are using Asterisk
version 1.2.x; but on "trunk" versions of asterisk, you would use "ael reload".
However, for those installing AEL2 into 1.2 versions of Asterisk, should note that 'ael2' and'AEL2' should be used as-is.
-
8/3/2019 Asterisk AEL2
5/39
The AEL2 parser (pbx_ael2.so) is completely separate from the module that parsesextensions.conf (pbx_config.so). To use AEL2, the only thing that has to be done is the modulepbx_ael2.so must be loaded by Asterisk. This will be done automatically if using 'autoload=yes'in /etc/asterisk/modules.conf. When the module is loaded, it will look for 'extensions.ael2' in/etc/asterisk/. extensions.conf and extensions.ael and extensions.ael2 can be used in conjunction
with
each
other if t
hat is w
hat is desired. Some users may want to keep extensions.conf for t
hefeatures that are configured in the 'general' section of extensions.conf.
Reloading extensions.ael2
To reload extensions.ael2, the following command can be issued at the CLI.
y CLI> ael2 reload
Debugging
Right at this moment, the following commands are available, but do nothing:
Enable AEL2 contexts debug
y CLI> ael2 debug contexts
Enable AEL2 macros debug
y CLI> ael2 debug macros
Enable AEL2 read debug
y CLI> ael2 debug read
Enable AEL2 tokens debug
y CLI> ael2 debug tokens
Disable AEL2 debug messages
-
8/3/2019 Asterisk AEL2
6/39
y CLI> ael2 no debug
If things are going wrong in your dialplan, you can use the following facilities to debug your file:
1. Th
e messages log in /var/log/asterisk (from the c
hecks done at load time).2. The "dialplan show" command in asterisk
3. The standalone executable, "aelparse" built in the utils/ dir in the source.
You can also use the "aelparse" program to check your extensions.ael2 file before feeding it toasterisk. Wouldn't it be nice to eliminate most errors before giving the file to asterisk?
AELPARSE
You should never place code in /etc/extensions.ael without first testing it with aelparse!!
The aelparse program is built in the utils/ directory of the asterisk source. It is a standaloneexecutable, and accepts only the options -d, -w, -q, and -n.
y -d: Using this option says, instead of reading the file "extensions.ael2" (in the trunkversion, that would be "extensions.ael") from /etc/asterisk (or wherever the config filesare normally kept) aelparse will instead look in the current directory. This is very useful
for testing your dialplan somewhere other than your production directory.y -w: Convert the input dialplan file (extensions.ael2) to extensions.conf format, and dump
the file in the current directory under the file name "extensions.conf.aeldump". Why onearth would you ever want to do this? Well, you could take that file and use it on 1.2 orearlier asterisk systems! You don't have to program dialplans in extensions.conf formatany more!
y -n: Don't display the function calls to build the extensions in asterisk.y -q: (implies -n). Pretty much, only show warnings and errors.
General Notes about Syntax
Note that the syntax and style are a little more free-form. The opening '{' (curly-braces) do nothave to be on the same line as the keyword that precedes them. Statements can be split across
-
8/3/2019 Asterisk AEL2
7/39
lines, as long as tokens are not broken by doing so. More than one statement can be included ona single line. Whatever you think is best!
You can just as easily say,
if(${x}=1){NoOp(hello!);goto s|3;}else{NoOp(
Goodbye!);goto s|12;}
as you can say:
if(${x}=1){NoOp(hello!);goto s|3;}else{
NoOp(G
oodbye!);goto s|12;}
or:
if (${x}=1){NoOp(hello!);goto s|3;} else {NoOp(Goodbye!);goto s|12;}
or:
if (${x}=1) {NoOp(hello!); goto s|3;} else {NoOp(Goodbye!); goto s|12;}
or even:
if(${x}=1){NoOp(hello!);goto s|3;}
-
8/3/2019 Asterisk AEL2
8/39
else{NoOp(Goodbye!);goto s|12;}
Keywords
The AEL keywords are case-sensitive. If an application name and a keyword overlap, there isprobably a good reason, and you should consider replacing the application call with an AEL2statement. If you do not wish to do so, you can still use the application, by using a capitalizedletter somewhere in its name. In the Asterisk extension language, application names are not case-sensitive.
The following are keywords in the AEL2 language:
y abstracty contexty macroy globalsy ignorepaty switchy ify ifTimey elsey randomy gotoy jumpy returny breaky continuey regexteny hinty fory whiley casey patterny default NOTE: the "default" keyword can be used as a context name, for those who
would like to do so.y catchy switchesy eswitchesy includes
-
8/3/2019 Asterisk AEL2
9/39
Applications
The file /var/lib/asterisk/applist contains entries for over 140 applications, including arguments,the names of variables the application can or will set, the options, and the list of arguments,optional and required. If you use an application that is not in the list, you can simply add one,following the syntax of other entries.
Don't fall in love with the specs in the applist file. The format of the file, the entries themselveswill change in time.
CommentsComments begin with // and end with the end of the line. Comments are removed by the lexicalscanner, and will not be recognized in places where it is busy gathering expressions to wrap in $,or inside application call argument lists. The safest place to put comments is after terminatingsemicolons, or on otherwise empty lines.
NEW! You can use C-style comments that begin with '/*' and end with '*/' in AEL files. Thesecomments can span lines, if so desired!Example:/* this is a
multiline comment th
atmakes little or no sense!*/
Extensions
To specify an extension in a context, the following syntax is used. If more than one application isbe called in an extension, they can be listed in order inside of a block.
context default {1234 => Playback(tt-monkeys);8000 => {NoOp(one);NoOp(two);NoOp(three);};
-
8/3/2019 Asterisk AEL2
10/39
_5XXX => NoOp(it's a pattern!);}
Two optional items have been added to the AEL2 syntax, that allow the specification ofhints,
and a keyword, regexten, that will force t
he numbering of priorities to start at 2.
context default {regexten _5XXX => NoOp(it's a pattern!);}
context default {hint(Sip/1) _5XXX => NoOp(it's a pattern!);}
context default {regexten hint(Sip/1) _5XXX => NoOp(it's a pattern!);}
The regexten must come before the hint if they are both present.
NEW: You can add the callerID to the extension name for matching by adding a slash (/)followed by the CallerID to match after the extension name.
context zoombo {819/7079953345 => { NoOp(hello, 3345); }}
In the above, the 819/7079953345 extension will only be matched if the CallerID is 7079953345,and the dialed number is 819. Hopefully you have another 819 extension defined for all thosewho wish 819, that are not so lucky as to have 7079953345 as theirCallerID!
Includes
Contexts can be included in other contexts. All included contexts are listed wit
hin a single block.
context default {includes {local;longdistance;international;
-
8/3/2019 Asterisk AEL2
11/39
}}
Time-limited inclusions can be specified, as in extensions.conf format, with the fields
described in the wiki page Asterisk cmd
Goto
IfT
ime.
context default {includes {local;longdistance|16:00-23:59|mon-fri|*|*;international;}}
#include
You can include other files with the #include "filepath" construct.
1. include "/etc/asterisk/testfor.ael2"
An interesting property of the #include, is that you can use it almost anywhere in the .ael2 file. Itis possible to include the contents of a file in a macro, context, or even extension. The #includedoes not have to occur at the beginning of a line. Included files can include other files, up to 50levels deep. If the path provided in quotes is a relative path, the parser looks in the config filedirectory for the file (usually /etc/asterisk).
NEW in 1.4 and trunk versions! You can use 'globbing' patterns (as in UNIX shell commands) toinclude multiple files with a single #include directive:
1. include "t2/*.ael"2. include "t3/x[1-5]*"3. include "t4/abc?.ael"4. include "t5/{t1,t2,t3}.ael"
-
8/3/2019 Asterisk AEL2
12/39
will include all the files that end with ".ael" in the t2 directory; all files in t3 that begin with x1,x2, x3, x4, or x5; and t4/abc.ael, and any other file in t4 that starts with abc, ends with ".ael", andhas one other character in between; and t1.ael, t2.ael, and t3.ael in the t5 directory.
Dialplan Switches
Switches are listed in their own block within a context. For clues as to what these are used for,see Asterisk - dual servers, and Asterisk config extensions.conf.
context default {switches {
DUNDi/e164;IAX2/box5;};eswitches {IAX2/context@${CURSERVER};}}
Ignorepat
ignorepat can be used to instruct channel drivers to not cancel dial tone upon receipt of aparticular pattern. The most commonly used example is '9'.
context outgoing {ignorepat => 9;}
Variables
Variables in Asterisk do not have a type, so to define a variable, it just has to be specified with avalue. Global variables are set in their own block.
-
8/3/2019 Asterisk AEL2
13/39
globals {CONSOLE=Console/dsp;TRUNK=Zap/g2;}
Variables can be set within extensions as well.
context foo {555 => {x=5;y=blah;divexample=10/2NoOp(x is ${x} and y is ${y} !);}}
NOTE: AEL wraps the right hand side of an assignment with $[ ] to allow expressions to beused If this is unwanted, you can protect the right hand side from being wrapped by using theSet() application. Read the README.variables about the requirements and behavior of $[ ]expressions.
NOTE:These things are wrapped up in a $[ ] expression: The while() test; the if() test; themiddle expression in the for( x; y; z) statement (the y expression); Assignments the right handside, so a = b -> Set(a=$[b])
Writing to a dialplan function is treated the same as writing to a variable.
context blah {s => {CALLERID(name)=ChickenMan;NoOp(My name is ${CALLERID(name)} !);}}
Loops
AEL has implementations of 'for' and 'while' loops.
-
8/3/2019 Asterisk AEL2
14/39
context loops {1 => {for (x=0; ${x} < 3; x=${x} + 1) {Verbose(x is ${x} !);
}}2 => {y=10;while (${y} >= 0) {
Verbose(y is ${y} !);y=${y}-1;}}}
NOTE:The conditional expression (the "${y} >= 0" above) is wrapped in $[ ] so it can beevaluated.NOTE:The for loop test expression (the "${x} < 3" above) is wrapped in $[ ] so it can beevaluated.NOTE:In for loops, both the init and increment expressions are embedded in a Set() call if an '='is found anywhere in the expression. Otherwise, they are treated as app calls.
Conditionals
AEL2 supports ifand switch statements, like AEL, but adds ifTime, and random. Unlike theoriginal AEL, though, you do NOT need to put curly braces arounda single statement in the "true" branch of an if(), the random(), or an ifTime() statement. Theif(), ifTime(), and random() statements allow optionalelse clause.
context conditional {_8XXX => {Dial(SIP/${EXTEN});
if ("${DIALSTATUS}" = "BUSY"){NoOp(yessir);Voicemail(${EXTEN}|b);}elseVoicemail(${EXTEN}|u);ifTime (14:00-25:00|sat-sun|*|*)
-
8/3/2019 Asterisk AEL2
15/39
Voicemail(${EXTEN}|b);else{Voicemail(${EXTEN}|u);NoOp(hi, there!);
}random(51) NoOp(This should appear 51% of the time);
random( 60 ){NoOp( This should appear 60% of the time );}else{random(75){
NoOp(Th
is should appear 30% of t
he time! );}
else{NoOp( This should appear 10% of the time! );}}}_777X => {switch (${EXTEN}) {case 7771:NoOp(You called 7771!);break;case 7772:NoOp(You called 7772!);break;case 7773:NoOp(You called 7773!);// fall thru-pattern 777[4-9]:NoOp(You called 777 something!);default:NoOp(In the default clause!);}}}
NOTE:The conditional expression in if() statements (the "${DIALSTATUS}" = "BUSY"above) is wrapped by the compiler in $[ ] for evaluation.
-
8/3/2019 Asterisk AEL2
16/39
NOTE: Neither the switch nor case values are wrapped in $[ ]; they can be constants, or ${var}type references only.NOTE: AEL2 generates each case as a separate extension. case clauses with no terminating'break', or 'goto', have a goto inserted, to the next clause, which creates a 'fall thru' effect.NOTE: AEL2 introduces the ifTime keyword/statement, which works just like the if() statement,
but the expression is a time value, exactly like t
hat used by t
he application
Goto
IfT
ime(). SeeAsterisk cmd GotoIfTimeNOTE:The pattern statement makes sure the new extension that is created has an '_' preceding itto make sure asterisk recognizes the extension name as a pattern.NOTE: Every character enclosed by the switch expression's parenthesis are included verbatim inthe labels generated. So watch out for spaces!NOTE: Previous to version 0.13, the random statement used the "Random()" application, whichhas been deprecated. It now uses the RAND() function instead, in the GotoIfapplication.NOTE: NEW: if the expression in the switch(expr) is null, this will end up in the default case, ifit is specified. If there is no matching case, in a switch statement, the dialplan will most likelyterminate with a hangup.
Break, Continue, and Return
Three keywords, break, continue, and return, are included in the syntax to provide flow ofcontrol to loops, and switches.
The break can be used in switches and loops, to jump to the end of the loop or switch.
The continue can be used in loops (while and for) to immediately jump to the end of the loop. Inthe case of a for loop, the increment and test will then be performed. In the case of the whileloop, the continue will jump to the test at the top of the loop.
Examples:
context loops {1 => {for (x=0; ${x} < 3; x=${x} + 1) {
Verbose(x is ${x} !);if( ${x} == 2 && ${y} == 17)break;if(${x} == 2 && ${y} == 16)continue; /*keep going */}}2 => {
-
8/3/2019 Asterisk AEL2
17/39
y=10;while (${y} >= 0) {Verbose(y is ${y} !);if (${z} {begin:NoOp(Infinite Loop! yay!);Wait(1);goto begin; // go to label in same extension}3 => {goto s|begin; // go to label in different extension
}4 => {goto gotoexample|s|begin; // overkill go to label in same context
}}
-
8/3/2019 Asterisk AEL2
18/39
context gotoexample2 {s => {end:goto gotoexample|s|begin; // go to label in different context}
}
You can use the special label of "1" in the goto and jump statements. It means the "first"statement in the extension. I would not advise trying to use numeric labels other than "1" ingoto's or jumps, nor would I advise declaring a "1" label anywhere! As a matter of fact, it wouldbe bad form to declare a numeric label, and it might conflict with the priority numbers usedinternally by asterisk.
The syntax of the jump statement is: jump extension[,priority][@context] If priority is absent, itdefaults to "1". If context is not present, it is assumed to be the same as that which contains the"jump".
context jumpexample {s => {begin:NoOp(Infinite Loop! yay!);Wait(1);jump s; // go to first priority in same extension}3 => {jump s,begin; // go to the begin label in different extension}4 => {jump s,begin@jumpexample; // overkill go to label in same context}5 => {jump 4@jumpexample; // jump to first prio in extension 4;}}
context jumpexample2 {s => {end:
jump s@jumpexample; // go to the s extension in different context}}
NOTE: goto labels follow the same requirements as the Goto() application, except the last valuehas to be a label. If the label does not exist, you will have run-time errors. If the label exists, butin a different extension, you have to specify both the extension name and label in the goto, as in:goto s|z; if the label is in a different context, you specify context|extension|label. There is a note
-
8/3/2019 Asterisk AEL2
19/39
about using goto's in a switch statement below...NOTE AEL2 introduces the special label "1", which is the beginning context number for mostextensions.NOTE: NEW: As of 30 Mar2006, goto syntax now accepts commas in the place of vertical bars.You must either use vertical bars as separators, or commas. You cannot mix them. Thus, either
"goto gotoexample|s|begin" or "goto gotoexample,s,begin", but NOT
"goto gotoexample,s|begin"
Macros
A macro is defined in its own block like this. The arguments to the macro are specified with thename of the macro. They are then referred to by that same name. A catch block can be specifiedto catch special extensions.
Alittle more about 'catch'. A macro is converted to a regular context, and all its code normally
goes into the 's' extension.
Defining a catch allows you to define other extensions in the macro context. For example, youcan define the 'h' extensionforhangups, and 'i' for invalid input, etc. To 'catch' events that might happen during theexecution of a macro.
macro std-exten( ext , dev ) {Dial(${dev}/${ext},20);switch(${DIALSTATUS}) {
case BUSY:Voicemail(b${ext});break;default:Voicemail(u${ext});
}
catch a {VoiceMailMain(${ext});return;
}}
A macro is then called by preceding the macro name with an ampersand. Empty arguments canbe passed simply with nothing between comments (0.11).
-
8/3/2019 Asterisk AEL2
20/39
context example {_5XXX => &std-exten(${EXTEN}, "IAX2");_6XXX => &std-exten(, "IAX2");_7XXX => &std-exten(${EXTEN},);
_8XXX => &std-exten(,);}
NOTE: Until release 1.4 was forked, and in 1.4 and previous, AEL2 used the Macro()application to implement this construct in the dialplan. Macros have a serious limitation, in thatone cannot recursively nest macro calls deeper than 7 levels, due to limitations on thread stackallocation sizes. To get around this limitation, from the time 1.4 is/was forked from trunk, theAEL2 compiler will implement macros withGosub() application calls, which pose no such limitson call depth. The new methodology will be available on trunk and releases 1.6 and above.
Examples
context demo {s => {Wait(1);Answer();TIMEOUT(digit)=5;
TIMEOUT(response)=10;restart:Background(demo-congrats);instructions:for (x=0; ${x} < 3; x=${x} + 1) {Background(demo-instruct);WaitExten();}}2 => {Background(demo-moreinfo);
goto s|instructions;}3 => {LANGUAGE()=fr;goto s|restart;}
500 => {
-
8/3/2019 Asterisk AEL2
21/39
Playback(demo-abouttotry);Dial(IAX2/[email protected]);Playback(demo-nogo);goto s|instructions;}
600 => {Playback(demo-echotest);Echo();Playback(demo-echodone);goto s|instructions;}
1. => {hangup:Playback(demo-thanks);H
angup();}t => goto #|hangup;i => Playback(invalid);}
Semantic Checks
AEL2, after parsing, but before compiling, traverses the dialplan tree, and makes several checks:
y (if the application argument analyzer is working: the presence of the 'j' option is reportedas error.
y if options are specified, that are not available in an application.y if you specify too many arguments to an application.y a required argument is not present in an application call.y Switch-case using "known" variables that applications set, that does not cover all the
possible values. (a "default" case will solve this problem. Each "unhandled" value islisted.
y a Switch construct is used, which is uses a known variable, and the application that wouldset that variable is not called in the same extension. This is a warning only...
y Macro calls to non-existent macros.y Macro calls to contexts.y Macro calls with argument count not matching the definition.y application call to macro.
-
8/3/2019 Asterisk AEL2
22/39
y application calls to "GotoIf", "GotoIfTime", "while", "endwhile", "Random", and"execIf", will generate a message to consider converting the call to AEL goto, while, etc.constructs.
y Calls to applications not in the "applist" database (installed in /var/lib/asterisk/applist" onmost systems).
ygoto a label in an empty extension.
y goto a non-existent label, either a within-extension, within-context, or in a differentcontext, or in any included contexts. Will even check "sister" context references.
y All the checks done on the time values in the dial plan, are done on the time values in theifTime() and includes times:
o the time range has to have two times separated by a dash;o the times have to be in range of 0 to 24 hours.o The weekdays have to match the internal list, if they are provided;o the day of the month, if provided, must be in range of 1 to 31;o the month name or names have to match those in the internal list.
y In an assignment statement, if the assignment is to a function, the function name used ischecked to see if it one of t
he currently known functions. A warning is issued if it is not.
y (0.5) If an expression is wrapped in $[ ... ], and the compiler will wrap it again, a warningis issued.
y (0.5) If an expression had operators (you know, +,-,*,/,%,!,etc), but no ${ } variables, awarning is issued. Maybe someone forgot to wrap a variable name?
y (0.12) check for duplicate context names.y (0.12) check for abstract contexts that are not included by any context.y (0.13) Issue a warning if a label is a numeric value.y (New) Make sure that labels are unique within extensions/macros.y (New) Issue hard error if a break is not in a loop or switch case.y (New) Issue hard error if a continue is not in a loop.y Empty extensions will issue a warning.y In release 1.6, labels outside of extensions orMacros will generate an error.y In release 1.6, return statements will only be allowed in macro definitions.y In release 1.6, a warning is generated if a macro definition does not contain a return
statement at the end of its contents. One is automatically inserted.y In release 1.6, a warning is generated if a goto is located in a macro, and the target is
outside the macro.y In release 1.6, a warning is issued, if a context referenced in 'includes' can't be found.
Differences with the original version of AEL
1. It reads in "/etc/asterisk/extensions.ael2", instead of extensions.ael (extensions.ael in thetrunk version) (Only in the 1.2 patch)
2. It is more free-form. The newline character means very little, and is pulled out of thewhite-space only for line numbers in error messages.
-
8/3/2019 Asterisk AEL2
23/39
3. It generates more error messages by this I mean that any difference between the inputand the grammar are reported, by file, line number, and column.
4. It checks the contents of $[ ] expressions (or what will end up being $[ ] expressions!) forsyntax errors. It also does matching paren/bracket counts.
5. It runs several semantic checks after the parsing is over, but before the compiling begins,see t
he list above.6. It handles #include "filepath" directives. ALMOST anywhere, in fact. You could
easily include a file in a context, in an extension, or at the root level. Files can beincluded in files that are included in files, down to 50 levels ofhierarchy...
7. LocalGoto's inside Switch statements automatically have the extension of the location ofthe switch statement appended to them.
8. A pretty printer function is available within pbx_ael2.so.9. In the utils directory, two standalone programs are supplied for debugging AEL files.
One is called "aelparse", and it reads in the /etc/asterisk/extensions.ael2 file, and showsthe results of syntax and semantic checking on stdout, and also shows the results ofcompilation to stdout. The other is "aelparse1", which uses the original ael compiler to do
the same work, reading in "/etc/asterisk/extensions.ael", using t
he original 'pbx_ael.so'instead.
10.AEL2 supports the "jump" statement, and the "pattern" statement in switch constructs.Hopefully these will be documented in the AEL README.
11.Added the "return" keyword, which will jump to the end of an extension/Macro.12.Added the ifTime (||| ) {} [else
{}] construct, which executes much like an if () statement, but the decision is based onthe current time, and the time spec provided in the ifTime. See the example above. (Note:all the other time-dependent Applications can be used via ifTime)
13.Added the optional time spec to the contexts in the includes construct. See examplesabove.
14.You don't have to wrap a single "true" statement in curly braces, as in the orignal AEL.An "else" is attached to the closest if. As usual, be careful about nested if statements!When in doubt, use curlies!
15.Added the syntax [regexten] [hint(channel)] to preceed an extension declaration. Seeexamples above, under "Extension". The regexten keyword will cause the priorities in theextension to begin with 2 instead of 1. The hint keyword will cause its arguments to beinserted in the extension under the hint priority. They are both optional, of course, but theorder is fixed at the moment-- the regexten must come before the hint, if they are bothpresent.
16.Empty case/default/pattern statements will "fall thru" as expected. (0.6)17.A trailing label in an extension, will automatically have a NoOp() added, to make sure
the label exists in the extension on Asterisk. (0.6)18.(0.9) the semicolon is no longer required after a closing brace! (i.e. "];" ===> "}". You
can have them there if you like, but they are not necessary. Someday they may berejected as a syntax error, maybe.
19.(0.9) the // comments are not recognized and removed in the spots where expressions aregathered, nor in application call arguments. You may have to move a comment if you geterrors in existing files.
-
8/3/2019 Asterisk AEL2
24/39
20.(0.10) the random statement has been added. Syntax: random ( ) [ else ]. The probability of the lucky-statement gettingexecuted is , which should evaluate to an integer between 0 and 100. If the isn't so lucky this time around, then the getsexecuted, if it is present.
21.Th
e $[...] expressionshave been en
hanced to inlcude t
he ==, ||, and && operators.
Theseoperators are exactly equivalent to the =, |, and & operators, respectively. Why? So the C,
Java, and C++ hackers feel at home here.
Hints and Bugs
''Note: Ihope that this section will end up just being "hints" by the time it is included!
y The safest way to check for a null strings is to say $[ "${x}" = "" ] The old way would doas shell scripts often do (but shouldn't, as that will yield the same problems as here), andappend something on both sides, like this: $[ ${x}foo = foo ]. The trouble with the oldway, is that, if x contains any spaces, then problems occur, usually syntax errors. It isbetter practice and safer to wrap all such tests with double quotes! Also, there are nowsome functions that can be used in a variable referenece, ISNULL(), and LEN(), that canbe used to test for an empty string: ${ISNULL(${x})} or $[ ${LEN(${x})} = 0 ].
y Assignment vs. Set(). Keep in mind that setting a variable to value can be done twodifferent ways. If you choose say 'x=y;', keep in mind that AEL2 will wrap the right-hand-side with $[]. So, when compiled into extension language format, the end result willbe 'Set(x=$[y])'. If you don't want this effect, then say "Set(x=y);" instead.
y Macro recursion depth. For large dialplans, or any other application that requires macroscalling macros calling macros to 7 or more levels deep, keep in mind that there is a limitas to how deeply you can nest macro calls. That limit is 7 levels. This shortcoming in theMacro() app is not limited to usage by AEL. In general, the Macro() application has thislimitation whether used by AEL, or just called straight from extensions.conf. Thealternative is to use the Gosub application instead. One shortcoming ofGosub in releases1.4 and previous, is that it did not accept any arguments. An enhancement to the Gosub()application will allow arguments to be passed and kept on a stack. This enhancement willbe available in release 1.6, and is fundamental to AEL being able to use Gosub instead ofMacro in generated dialplan code.
y Spaces in Set(). You can get the most unexpected and interesting errors if you put spacesin your Set() arguments. "Set( a = 1)" is not equivalent to "Set(a=1)". The variable namein the first case is " a ", and includes the spaces before and after. You will have to insurethat those spaces are present every time that variable is referenced. This is bad form!
-
8/3/2019 Asterisk AEL2
25/39
The Full Power of AEL and AEL2
A newcomer to Asterisk will look at the above constructs and descriptions, and ask, "Where's thestring manipulation functions?", "Where's all the cool operators that other languages have tooffer?", etc.
The answer is that the rich capabilities of Asterisk are made available through AEL, via:
y Applications: See Asterisk - documentation of application commandsy Functions: Functions were implemented inside ${ .. } variable references, and supply
many useful capabilities. See Asterisk Functionsy Expressions: An expression evaluation engine handles items wrapped inside $[...]. This
includes some string manipulation facilities, arithmetic expressions, etc. See AsteriskExpressions.
y Application Gateway Interface: Asterisk can fork external processes that communicatevia pipe. AGI applications can be written in any language. Very powerful applications
can be added this way. See Asterisk AGI.y Variables: Channels of communication have variables associated with them, and asterisk
provides some global variables. These can be manipulated and/or consulted by the abovemechanisms. See AsteriskVariables.
Examples
Here you can find some examples on
how to use AEL/AEL2 to create powerful dialplans: AELExample Snippets.
AEL2 BNF
First, some basic objects:
a lexical token consisting of characters matching this pattern: [-a-zA-Z0-9"_/.\\*\+!$#\\][-a-zA-Z0-9"_/.!\*\+\\{\}$#\\]*
a concatenation of up to 3 s.
all characters encountered until the character that follows the in the grammar.
-
8/3/2019 Asterisk AEL2
26/39
:==
:==
|
:== | | | ';'
:== 'context' '{' '}'| 'context' '{' '}'
| 'context' 'default' '{' '}'| 'context' 'default' '{' '}'| 'abstract' 'context' '{' '}'| 'abstract' 'context' '{' '}'| 'abstract' 'context' 'default' '{' '}'| 'abstract' 'context' 'default' '{' '}'
:== 'macro' '(' ')' '{' '}'| 'macro' '(' ')' '{' '}'| 'macro' '(' ')' '{' '}'| 'macro' '(' ')' '{' '}'
:== 'globals' '{' '}'| 'globals' '{' '}'
:== |
:== '=' ';'
:== | ','
:==
-
8/3/2019 Asterisk AEL2
27/39
|
:== |
| |
| | '=' ';'| ';'
:== 'ignorepat' '=>' ';'
:== '=>'
| 'regexten' '=>' | 'hint' '(' ')' '=>' | 'regexten' 'hint' '(' ')' '=>'
:== |
:== 'if' '(' ')'
:== 'random' '(' ')'
:== 'ifTime' '(' ':' ':' '|' '|' '|' ')'| 'ifTime' '(' '|' '|' '|' ')'
:== | |
:== 'switch' '(' ')' '{'
:== '{' '}'| '=' ';'| 'goto' ';'| 'jump' ';'| ':'| 'for' '(' ';' ';' ')'
-
8/3/2019 Asterisk AEL2
28/39
| 'while' '(' ')' | '}'| '}'| '&' macro_call ';'| ';'
| '=' ';'| 'break' ';'| 'return' ';'| 'continue' ';'| | 'else' | | 'else' | | 'else' | ';'
:== | '|' | '|' '|' | 'default' '|' '|' | ',' | ',' ',' | 'default' ',' ','
:== | ',' | ',' '@' | '@' | ',' '@' 'default'| '@' 'default'
:== '(' ')'| '(' ')'
:== '('
:== ')'| ')'
:== | ',' | /* nothing */| ',' /* nothing */
:==
-
8/3/2019 Asterisk AEL2
29/39
|
:== 'case' ':' | 'default' ':'
| 'pattern' ':' | 'case' ':'| 'default' ':'| 'pattern' ':'
:== |
:== | includes| 'catch' '{' '}'
:== 'switches' '{' '}'| 'switches' '{' '}'
:== 'eswitches' '{' '}'| 'eswitches' '{' '}'
:== ';'| ';'
:== ';'| '|' ':' ':' '|' '|' '|' ';'| '|' '|' '|' '|' ';'| ';'| '|' ':' ':' '|' '|' '|' ';'| '|' '|' '|' '|' ';'
:== | 'default'
:== 'includes' '{' '}'| 'includes' '{' '}'
-
8/3/2019 Asterisk AEL2
30/39
AEL2 Bug Report History
(note: RFT means "Ready forTest" in the following:)
Bug ID Category Severity Status
Last
Updated
Summary
0007721PBX/pbx_ael
minorclosed(murf)
08-12-06
AEL2 can't parse hint with the andchar (Zap/4&Zap5)
0007598PBX/pbx_ael
minorclosed(murf)
08-07-06
labels for goto not working inmacros
0007605PBX/pbx_ael
minorclosed(murf)
08-04-06
AEL2 parser doesn't see macros in.conf language files
0007635 PB
X/pbx_ael minor closed(murf) 08-01-06 For loop increment not workingright
0007474PBX/pbx_ael
majorclosed(murf)
07-06-06
AEL2 not properly escapingcommas
0007804PBX/pbx_ael
minorclosed(murf)
08-25-06
Various AEL crashes fixed
0008661PBX/pbx_ael
minorclosed(murf)
12-29-06
delimiter
0007714
PBX/pbx_ae
l tweak
closed
(murf)
08-14-
06
proposed alternative to switch-
case-extensions
0007715 PBX/pbx-ael featureclosed(murf)
08-10-06
support gosub & macros
0008004PBX/pbx_ael
minorclosed(murf)
09-22-06
supportAST_MODULE_LOAD_DECLINE
0008031PBX/pbx_ael
minorclosed(murf)
09-26-06
AEL load on debian
0008090 PBX/pbx_ael
crash closed(murf)
10-04-06
core dump loading AEL file
0008099PBX/pbx_ael
crashclosed(murf)
10-05-06
core on empty extension
0008128PBX/pbx_ael
majorclosed(murf)
10-13-06
switch fallthru fails w/ patterns
-
8/3/2019 Asterisk AEL2
31/39
0008836PBX/pbx_ael
minorclosed(murf)
01-22-07
reload nukes subscription tables
0009184PBX/pbx_ael
majorclosed(murf)
03-02-07
comma/escape issues again.
0009228PBX/pbx_ael
majorclosed(murf)
03-21-07
macro vs. Gosub: what aboutmacros in Dial?
0009316PBX/pbx_ael
minorclosed(murf)
03-20-07
AEL security risk via switch-case-extensions
00009373
PBX/pbx_ael
crashclosed(murf)
2007-03-27
A segmentation fault occurs whentwo context have the same name
0009419PBX/pbx_ael
minorclosed(murf)
2007-03-29
Global variables defined inextensions.ael not reloaded whendoing a reload, other parts of
dialplan are.
0009435PBX/pbx_ael
majorclosed(murf)
2007-04-02
(patch) "continue" doesn't performthe increment in "for" loops
0009452PBX/pbx_ael
minorclosed(murf)
2007-06-21
AEL doesn't load default context atfirst time
0009508PBX/pbx_ael
minorclosed(murf)
2007-07-03
ast_expr2.y fails on negative realnumbers
0009623PBX/pbx_ae
l
minorclosed
(murf)
2007-
05-03
AEL gives syntax error on @ in a
switch
0009805PBX/pbx_ael
minorclosed(murf)
2007-05-25
MACRO_EXTEN, MACRO_... isempty in AEL
0009881PBX/pbx_ael
minorclosed(murf)
2007-06-05
Switch construct breaks thedialplan flow if it doesn't have adefault case
0009883PBX/pbx_ael
minorclosed(murf)
2007-06-05
AEL macros do not allow"includes" construct
0010322
PBX/pbx_ae
l minor
closed
(murf)
2007-
07-27
(patch) Switch pbx_ael to generate
code with comma delimiters
0010411PBX/pbx_ael
minorclosed(murf)
2007-08-14
Variables in AEL2 context names
0010472PBX/pbx_ael
minorclosed(murf)
2007-12-21
conf2ael improvements
-
8/3/2019 Asterisk AEL2
32/39
0010498PBX/pbx_ael
minorclosed(murf)
2007-08-27
pbx_ael crashs asterisk whenunloading/loading
0010786PBX/pbx_ael
minorclosed(murf)
2007-09-22
#include directive does not work
0010787PBX/pbx_ael
majorclosed(murf)
2007-11-01
Impossible to make optional macroarguments in 1.4
0010788PBX/pbx_ael
majorclosed(murf)
2007-09-22
for loops broken
0010789PBX/pbx_ael
majorclosed(murf)
2007-09-22
No way to set a variable withoutmath
0010834PBX/pbx_ael
minorclosed(murf)
2007-10-03
(patch) Empty vars in AEL2switches lead to dropped calls
0010870 PBX/pbx_ael
minor closed(murf)
2007-10-03
AEL & CUT
0011005PBX/pbx_ael
tweakclosed(murf)
2007-10-24
glob #include uses base pathdifferent from non-glob #include
0011009PBX/pbx_ael
majorclosed(qwell)
2007-10-17
i extention not all times work
0011037PBX/pbx_ael
minorclosed(murf)
2007-10-23
hint to monitor meetme using aelsyntax
0011086PBX/pbx_ael feature
closed(murf)
2007-10-30
avoid nonexistent context warningswhen loading AEL
0011287PBX/pbx_ael
minorclosed(murf)
2007-12-20
Failed compile pbx_ael on solaris
0011329PBX/pbx_ael
minorclosed(murf)
2008-01-11
AEL macro argument variablesaren't properly quoted when set
0011903PBX/pbx_ael
minorclosed(murf)
2008-03-18
Wrong error file shown if includesused
0012238PBX/pbx_ae
lmajor
closed
(murf)
2008-
03-18
include block not loaded on
asterisk start
0012302PBX/pbx_ael
majorclosed(murf)
2008-03-27
${EXTEN} variable is corruptedwithin switch()
0012303PBX/pbx_ael
minorclosed(murf)
2008-03-26
digit extension pattern matches alsodialed string, that looks like patternitself
-
8/3/2019 Asterisk AEL2
33/39
0012467PBX/pbx_ael
minorclosed(murf)
2008-04-21
Can't add 0 in front of functionresult within if() block of AEL
0013046PBX/pbx_ael
crashclosed(murf)
2008-07-30
Asterisk segfault at startup/aelreload
0013051PBX/pbx_ael
minorclosed(murf)
2008-07-30
SIPPEER isn't working insideREGEX and IF
0013061PBX/pbx_ael
minorclosed(mvanbaak)
2008-07-12
random appears to be broken
0013090PBX/pbx_ael
minorclosed(murf)
2008-07-16
multiple "infinite loop" messagesbeing output by AEL compiler.
0013197PBX/pbx_ael
minorclosed(murf)
2008-07-30
STAT() inside IF() doesn't work
0013236PBX/pbx_ael
majorclosed(murf)
2008-08-07
doesn't set ~~EXTEN~~ on therigth place when a switch statementhas been found
0013305PBX/pbx_ael
crashclosed(murf)
2008-08-20
AEL while loop - high cpu usageand crash (private)
0013339PBX/pbx_ael
featureclosed(murf)
2008-09-08
AEL parser should trim RHS of anassignment
0013357
PBX/pbx_ae
l minor
closed
(murf)
2008-
09-04
AEL doesn't like using dialplan
function call as argument for 'jump'statement
0013407PBX/pbx_ael
minor closed2008-09-02
AEL switches inside macros notworking like extensions.conf's ones
0013416PBX/pbx_ael
minorclosed(murf)
2008-09-04
Function CUT doesn't work ifpassed as parameter to macro inAEL
0013765PBX/pbx_ael
minorclosed(murf)
2008-10-24
after return from child contextARG is cleared
AEL2 Enhancement Request History
-
8/3/2019 Asterisk AEL2
34/39
1. (Originally filed as bug 7606) Generate extensions.conf format ouput from aelparse
Status: Finished, -w option added to aelparse
Description: Standalone AEL2 compiler
Requested by: rushowr
2. (Originally filed as bug 7638) Reverse compiler from extensions.conf format to AEL format
Status: In Progress
Description: how hard would it be to write a reverse compiler for translating existing dialplan
files into .ael/.ael2 files?
Requested by: rushowr
Branch: http://svn.digium.com/svn/asterisk/team/murf/bug_7638
Discussion:
Murf:
Now, as to the reverse, converting extensions.conf to AEL: it is possible, but a lot of work. Think
of it this
way: what you are asking for is a reverse compiler. Given, for example, an assembly file,
produce the equivalent
C++ code that might have produced that assembly file. It's a bit easier (relatively) if you have
some nice constraints,
say you know the assembly file was generated with g++, and only one particular version of it, at
that. You could then
pattern match certain sequences in the assembler output back into C++ structures with reasonable
confidence.Others, you just synthesize something that would work.
But, incoming extensions.conf code does not follow such narrow limits.It would not be
uncommon to see subtle tricks being
used to accomplish some goal, which would be difficult for a human to interpret, let alone a
program. That being said, most
extensions code **is** pretty simple, and in most cases simple heuristics could cover a great
majority of the code. Stuff that
it can't grok could simply be copied verbatim into the output for a human to complete. Most of
the formatting and easy stuff
could be done by the translator and speed up the job of conversion tremendously.
I'm all for it. Such a program could help reduce the cost of converting to AEL, and aid the whole
community greatly.
29 Dec 2006; I've got the basics lined up for experiment 1 of this code, using the existing
-
8/3/2019 Asterisk AEL2
35/39
asterisk config file reading code
to pull in the extensions.conf; Experiment 2 will be to use benjk's ini file parser-- but it looks like
that would be a heck of a
lot more work to incorporate. So I'll go the easy route first. (And it wasn't that easy).
22 Mar 2007; Finally, I've refactored the code to get a standalone config file processor that
yields the internal structs
used by asterisk. The reverse compiler generates contexts, extensions, priorities, with no real
translation of gotos, loops,
etc. But it's a crude start.
3. Add a quiet option to aelparse-- it's too noisy!!!
Status: Finished: added -q option to aelparse
Description: I can't find the errors amid all the progress messages!
Requested by: rushowr
4. (originally filed as bug 7715) Replace the Gosub command with an internal AEL2 command?
Status: Completed in Trunk (will appear in 1.6).
Description: Replace the Gosub command with an internal AEL2 command?
Requested by: rushowr
Branch: team/murf/macrogosub
Discussion:
Rushowr:
I like the replacement goto statement, and jump is nice, but how hard would it be to create a
replacement forGosub?
I've been having issues with macros needing to call other macros (I use 'em like functions) but ifthere's more than one or two
deep, it won't work, and it's a pain. I'd love to see the ability to call a label or extension within
another context with a return
address saved so that when the end of the called context is hit, we return to the calling context.....
Another thing that would be AWESOME would be to make the AEL2 version of subroutine
handling allow supplying arguments
to the subroutine, kind of like a merge between the Asterisk macros and Gosub called contexts....
Basically, I'm dying for the
ability to define something like a function that when called, will save a return address AND
won't have the problems that Macros
have of not always working when they're called from within anotherMacro/Function.....
murf:
Macro **is** the right idea for this sort of thing-- let's spend some time and see why it's not
behaving right for you. We can open
-
8/3/2019 Asterisk AEL2
36/39
a bug, and supply a test case?
murf:
I am modifying the code in pbx_ael.c to generate Gosub() calls instead ofMacro() calls.
This is made possible by an upgrade provided by Corydon(Tilghman Lesher) to Gosub, so
that it can be called with arguments. The reason? The Application Macro() uses up a fair
amount of stack space to do its thing. If you go more than 7 levels deep in macros (via recursion
or subdivision of tasks) then safeguards will kick in and the calls will terminate early to keep
asterisk from crashing. Gosubs don't traverse the macro def "by hand" like Macro does, and
will allow a bit more "headroom". We are hoping about 20 levels of depth. The only problem
is that the coderhas to explicitly include "return" statements in their macros, or you'll have
pretty big problems!!!
Otherwise, there is little difference with previous usage. Macros are still declared the same
in AEL, they are just compiled differently underneat
hnow. Just make sure to put t
he return;
statement in the right spots! They will be converted to Return() application calls.
5. (originally filed as bug 7714) Alternative to naming new extensions when building a switch
conditionals
Status: ON HOLD Not going to do this as yet; the current method seems better at this time.
Description:Don't break switch cases into separate extensions?
Requested by: rushowr
Branch: not yet
Discussion:Rushowr:
The existing method of using multiple extensions to separate cases within the switch statement is
not the best. Have you thought about
just using n(labelname) directives? See the additional information box for my
examples/comparisons.
the n(label) labels are GREAT, and you can reference them just like we do within the AEL code
:)
AEL2's outputted code: (excess removed)
macro-endcall
exten => s,1,Goto(sw-10-${calltype}|1)
exten => s,2,NoOp(Finish switch-endcall-10)
exten => sw-10-in,1,Macro(setdispo|${callid})
exten => sw-10-out,1,Macro(dbconn|cdr|open)
-
8/3/2019 Asterisk AEL2
37/39
A suggested way to do this:
exten => s,1,Goto(${EXTEN}|${calltype})
exten => s,2,NoOp(Finish switch-endcall)
exten => s,n(in),Macro(setdispo|${callid})
exten => s,n,Return
exten => s,n(out),Macro(dbconn|cdr|open)
exten => s,n,Return
Murf:
As to the switch thing, as I call it...
Ihave definitely thought much on this issue while I was coding up AEL2...
but first and foremost, that was t
he way (using separate
extensions) the original AEL implemented switches, and
I didn't want to rock the boat.
Next, it does have a certain appeal. Besides the normal case and default
statements you can put in a switch, there is also the "pattern"
statement, which basically is just like a case, except that it prepends an
underscore in front of the extension name, allowing a pattern extension,
which is something you just cannot get with a simple switch...
switch(${NUMTODIAL}){
case 911:
verbose("Hey, an emergency!");
break;
case 411:
verbose("What, you need information?");
break;
pattern 307XXXXXXX:
verbose("Why on earth would you want to call Wyoming?");
break;
pattern 801XXXXXXX:
verbose("Why on earth would anyone call Utah?");
break;
default:
verbose(Ah, a discriminating caller, indeed!);
-
8/3/2019 Asterisk AEL2
38/39
break;
}
I guess if labels could define patterns, you could get the same affect.
Until then, you have to admit, the pattern statement is a nice feature.
Rushowr:
Hey, you're right! I completely forgot about the pattern matching abilities.
Your way definitely makes much more sense :)
pkempgen (via the Mantis bug tracker, 9316, 03-19-07 15:29):
You never know for sure that ${EXTEN} is what you
think it is because it mig
hthappen to be inside
a different extension - and Dial(SIP/sw-87-user) is
not what I expected :)
6. Multiline Commenting
Status: finished
Description: Enhance the AEL2 parser to allow for a multiline comment keyword set.
Requested by: rushowr
Branch: already committed to trunk
Discussion: C style comments are now supported: example: /* this is a comment */
7. New keyword: subroutine
Status: Will not be done, sort of... see above about Macro/Gosub
Description: Enhancement to the context keyword, if context is prefaced by subroutine force
'return' statements within that context to use the subroutine command Return.
Requested by: rushowr
Branch: not yet
Discussion: Due to memory constraints built into asterisk, we will implement macros as gosubs
instead. See above.
8. #Include wildcards
Status: Finished
Description: Allow #including wildcards like the rest of the Asterisk configs. This allows things
like: #include "people/*.conf"
Requested by: Luke-Jr
Discussion/Notes:
-
8/3/2019 Asterisk AEL2
39/39
rushowr: I know that #include is already implemented, haven't personally tested wildcards
because I wasn't aware you could wildcard includes at all. Will test or check with murph
murf: I finished this. Is it in just trunk, or did I add it to 1.4 also?
9. Optimize AEL generated extensions.conf code by leaving out the NoOp() markers
Status: Not Yet Begun
Description: The NoOps() that are output to mark the end of if, while, switch, etc statements are
unnecc. please remove them.
Requested by: yarns (bug 13422)
Discussion/Notes:
10. allow macros to have variable numbers of arguments.
Status: Not yet begun.
Description: Allow macros to have a variable number of arguments
Requested by: SE
VER
ALDiscussion/Notes: I've been discouraging users from using ${ARG1}, ${ARG2}, etc inside
macros, in favor of using the name of the argument instead... eg. ${name}.
Since Gosub (in 1.6.x./trunk) is being used, users can use ${ARGx} to access such arguments,
but the AEL parser will reject extra arguments if included,
and complain about missing arguments if you include too few. I've been thinking about including
a new keyword, "...", which, if included as the last
argument in the macro definition, would turn off such checking for that and following
arguments.