aboutsummaryrefslogtreecommitdiffstats
path: root/doc/README.ael
blob: 9fa99e52e115040c7a983259e91755713a395f0d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
The Asterisk Extension Language
===================================

Over time, people have been pushing to add features to extensions.conf to make
it more like a programming language.  AEL is intended to provide an actual
programming language that can be used to write an Asterisk dialplan.

Getting Started
-------------------------
The AEL parser (pbx_ael.so) is completely separate from the module
that parses extensions.conf (pbx_config.so).  To use AEL, the only thing that
has to be done is the module pbx_ael.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.ael' in /etc/asterisk/.
Both extensions.conf and extensions.ael can be used in conjunction with each 
other if that is what is desired.  Some users may want to keep extensions.conf
for the features that are configured in the 'general' section of 
extensions.conf.


Reloading extensions.ael
-------------------------
To reload extensions.ael, the following command can be issued at the CLI.

	*CLI> reload pbx_ael.so


Contexts
-------------------------
Contexts in AEL represent a set of extensions in the same way that they do
in extensions.conf.

context default {

};


Extensions
-------------------------
To specify an extension in a context, the following syntax is used.  If more
than one application is be 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);
	};
	_5XXX => NoOp(it's a pattern!);
};


Includes
-------------------------
Contexts can be included in other contexts.  All included contexts are listed
within a single block.

context default {
	includes {
		local;
		longdistance;
		international;
	};
};


Dialplan Switches
-------------------------
Switches are listed in their own block within a context.

context default {
	switches {
		DUNDi/e164;
		IAX2/box5;
	};
	eswitches {
		IAX2/context@${CURSERVER};
	};
};


Ignorepat
-------------------------
ignorepat can be used to instruct channel drivers to not cancel dialtone upon
receipt of a particular 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 a value.

Global variables are set in their own block.

globals {
	CONSOLE=Console/dsp;
	TRUNK=Zap/g2;
};

Variables can be set within extensions as well.

context foo {
	555 => {
		x=5;
		y=blah;
		NoOp(x is ${x} and y is ${y} !);
	};
};

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.

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;
		};
	};
};


Conditionals
-------------------------
AEL supports if and switch statements.  Note that if you have an else 
clause, you MUST place braces around the non-else portion of the if 
statement.

context conditional {
	_8XXX => {
		Dial(SIP/${EXTEN});
		if (${DIALSTATUS} = "BUSY") {
			Voicemail(${EXTEN}|b);
		} else
			Voicemail(${EXTEN}|u);
	};
	_777X => {
		switch (${EXTEN}) {
			case 7771:
				NoOp(You called 7771!);
				break;
			case 7772:
				NoOp(You called 7772!);
				break;
			case 7773:
				NoOp(You called 7773!);
				// fall through
			default:
				NoOp(In the default clause!);
		};
	};
};


goto and labels
-------------------------
This is an example of how to do a goto in AEL.

context gotoexample {
	s => {
begin:
		NoOp(Infinite Loop!  yay!);
		Wait(1);
		goto begin;
	};
};


Macros
-------------------------
A macro is defined in its own block like this.  The arguments to the macro are
specified with the name of the macro.  They are then reffered to by that same
name.  A catch block can be specified to catch special extensions.

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 preceeding the macro name with an ampersand.

context example {
	_5XXX => &std-exten(${EXTEN}, "IAX2");
};


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 => {
		Playback(demo-abouttotry);
		Dial(IAX2/guest@misery.digium.com);
		Playback(demo-nogo);
		goto s|instructions;
	};
	600 => {
		Playback(demo-echotest);
		Echo();
		Playback(demo-echodone);
		goto s|instructions;
	};
	# => {
hangup:
		Playback(demo-thanks);
		Hangup();
	};
	t => goto #|hangup;
	i => Playback(invalid);
};