README.ael 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. The Asterisk Extension Language
  2. ===================================
  3. Over time, people have been pushing to add features to extensions.conf to make
  4. it more like a programming language. AEL is intended to provide an actual
  5. programming language that can be used to write an Asterisk dialplan.
  6. Getting Started
  7. -------------------------
  8. The AEL parser (pbx_ael.so) is completely separate from the module
  9. that parses extensions.conf (pbx_config.so). To use AEL, the only thing that
  10. has to be done is the module pbx_ael.so must be loaded by Asterisk. This will
  11. be done automatically if using 'autoload=yes' in /etc/asterisk/modules.conf.
  12. When the module is loaded, it will look for 'extensions.ael' in /etc/asterisk/.
  13. Both extensions.conf and extensions.ael can be used in conjunction with each
  14. other if that is what is desired. Some users may want to keep extensions.conf
  15. for the features that are configured in the 'general' section of
  16. extensions.conf.
  17. Reloading extensions.ael
  18. -------------------------
  19. To reload extensions.ael, the following command can be issued at the CLI.
  20. *CLI> reload pbx_ael.so
  21. Contexts
  22. -------------------------
  23. Contexts in AEL represent a set of extensions in the same way that they do
  24. in extensions.conf.
  25. context default {
  26. };
  27. Extensions
  28. -------------------------
  29. To specify an extension in a context, the following syntax is used. If more
  30. than one application is be called in an extension, they can be listed in order
  31. inside of a block.
  32. context default {
  33. 1234 => Playback(tt-monkeys);
  34. 8000 => {
  35. NoOp(one);
  36. NoOp(two);
  37. NoOp(three);
  38. };
  39. _5XXX => NoOp(it's a pattern!);
  40. };
  41. Includes
  42. -------------------------
  43. Contexts can be included in other contexts. All included contexts are listed
  44. within a single block.
  45. context default {
  46. includes {
  47. local;
  48. longdistance;
  49. international;
  50. };
  51. };
  52. Dialplan Switches
  53. -------------------------
  54. Switches are listed in their own block within a context.
  55. context default {
  56. switches {
  57. DUNDi/e164;
  58. IAX2/box5;
  59. };
  60. eswitches {
  61. IAX2/context@${CURSERVER};
  62. };
  63. };
  64. Ignorepat
  65. -------------------------
  66. ignorepat can be used to instruct channel drivers to not cancel dialtone upon
  67. receipt of a particular pattern. The most commonly used example is '9'.
  68. context outgoing {
  69. ignorepat => 9;
  70. };
  71. Variables
  72. -------------------------
  73. Variables in Asterisk do not have a type, so to define a variable, it just has
  74. to be specified with a value.
  75. Global variables are set in their own block.
  76. globals {
  77. CONSOLE=Console/dsp;
  78. TRUNK=Zap/g2;
  79. };
  80. Variables can be set within extensions as well.
  81. context foo {
  82. 555 => {
  83. x=5;
  84. y=blah;
  85. NoOp(x is ${x} and y is ${y} !);
  86. };
  87. };
  88. Writing to a dialplan function is treated the same as writing to a variable.
  89. context blah {
  90. s => {
  91. CALLERID(name)=ChickenMan;
  92. NoOp(My name is ${CALLERID(name)} !);
  93. };
  94. };
  95. Loops
  96. -------------------------
  97. AEL has implementations of 'for' and 'while' loops.
  98. context loops {
  99. 1 => {
  100. for (x=0; ${x} < 3; x=${x} + 1) {
  101. Verbose(x is ${x} !);
  102. };
  103. };
  104. 2 => {
  105. y=10;
  106. while (${y} >= 0) {
  107. Verbose(y is ${y} !);
  108. y=${y}-1;
  109. };
  110. };
  111. };
  112. Conditionals
  113. -------------------------
  114. AEL supports if and switch statements. Note that if you have an else
  115. clause, you MUST place braces around the non-else portion of the if
  116. statement.
  117. context conditional {
  118. _8XXX => {
  119. Dial(SIP/${EXTEN});
  120. if (${DIALSTATUS} = "BUSY") {
  121. Voicemail(${EXTEN}|b);
  122. } else
  123. Voicemail(${EXTEN}|u);
  124. };
  125. _777X => {
  126. switch (${EXTEN}) {
  127. case 7771:
  128. NoOp(You called 7771!);
  129. break;
  130. case 7772:
  131. NoOp(You called 7772!);
  132. break;
  133. case 7773:
  134. NoOp(You called 7773!);
  135. // fall through
  136. default:
  137. NoOp(In the default clause!);
  138. };
  139. };
  140. };
  141. goto and labels
  142. -------------------------
  143. This is an example of how to do a goto in AEL.
  144. context gotoexample {
  145. s => {
  146. begin:
  147. NoOp(Infinite Loop! yay!);
  148. Wait(1);
  149. goto begin;
  150. };
  151. };
  152. Macros
  153. -------------------------
  154. A macro is defined in its own block like this. The arguments to the macro are
  155. specified with the name of the macro. They are then reffered to by that same
  156. name. A catch block can be specified to catch special extensions.
  157. macro std-exten( ext , dev ) {
  158. Dial(${dev}/${ext},20);
  159. switch(${DIALSTATUS) {
  160. case BUSY:
  161. Voicemail(b${ext});
  162. break;
  163. default:
  164. Voicemail(u${ext});
  165. };
  166. catch a {
  167. VoiceMailMain(${ext});
  168. return;
  169. };
  170. };
  171. A macro is then called by preceeding the macro name with an ampersand.
  172. context example {
  173. _5XXX => &std-exten(${EXTEN}, "IAX2");
  174. };
  175. Examples
  176. ------------------------
  177. context demo {
  178. s => {
  179. Wait(1);
  180. Answer();
  181. TIMEOUT(digit)=5;
  182. TIMEOUT(response)=10;
  183. restart:
  184. Background(demo-congrats);
  185. instructions:
  186. for (x=0; ${x} < 3; x=${x} + 1) {
  187. Background(demo-instruct);
  188. WaitExten();
  189. };
  190. };
  191. 2 => {
  192. Background(demo-moreinfo);
  193. goto s|instructions;
  194. };
  195. 3 => {
  196. LANGUAGE()=fr;
  197. goto s|restart;
  198. };
  199. 500 => {
  200. Playback(demo-abouttotry);
  201. Dial(IAX2/guest@misery.digium.com);
  202. Playback(demo-nogo);
  203. goto s|instructions;
  204. };
  205. 600 => {
  206. Playback(demo-echotest);
  207. Echo();
  208. Playback(demo-echodone);
  209. goto s|instructions;
  210. };
  211. # => {
  212. hangup:
  213. Playback(demo-thanks);
  214. Hangup();
  215. };
  216. t => goto #|hangup;
  217. i => Playback(invalid);
  218. };
  219. Syntax Note
  220. ------------------------
  221. Please note that all opening {'s are on the same line as the keyword. For
  222. the time being, that syntax is mandatory. We are looking at ways to allow
  223. other syntax in the future for flexibility, but for now, that is the way
  224. you must write AEL clauses.