Asterisk - The Open Source Telephony Project GIT-master-d856a3e
pbx_builtins.c
Go to the documentation of this file.
1/*
2 * Asterisk -- An open source telephony toolkit.
3 *
4 * Copyright (C) 2015 Fairview 5 Engineering, LLC
5 *
6 * George Joseph <george.joseph@fairview5.com>
7 *
8 * See http://www.asterisk.org for more information about
9 * the Asterisk project. Please do not directly contact
10 * any of the maintainers of this project for assistance;
11 * the project provides a web site, mailing lists and IRC
12 * channels for your use.
13 *
14 * This program is free software, distributed under the terms of
15 * the GNU General Public License Version 2. See the LICENSE file
16 * at the top of the source tree.
17 */
18
19/*! \file
20 *
21 * \brief Core PBX builtin routines.
22 *
23 * \author George Joseph <george.joseph@fairview5.com>
24 */
25
26/*** MODULEINFO
27 <support_level>core</support_level>
28 ***/
29
30#include "asterisk.h"
31
32#include "asterisk/_private.h"
33#include "asterisk/pbx.h"
34#include "asterisk/causes.h"
37#include "asterisk/say.h"
38#include "asterisk/app.h"
39#include "asterisk/module.h"
41#include "pbx_private.h"
42
43/*** DOCUMENTATION
44 <application name="Answer" language="en_US">
45 <synopsis>
46 Answer a channel if ringing.
47 </synopsis>
48 <syntax>
49 <parameter name="delay">
50 <para>Asterisk will wait this number of milliseconds before returning to
51 the dialplan after answering the call.</para>
52 <para>The minimum is 500 ms. To answer immediately without waiting for media,
53 use the i option.</para>
54 </parameter>
55 <parameter name="options">
56 <optionlist>
57 <option name="i">
58 <para>Answer the channel immediately without waiting for media.</para>
59 </option>
60 </optionlist>
61 </parameter>
62 </syntax>
63 <description>
64 <para>If the call has not been answered, this application will
65 answer it. Otherwise, it has no effect on the call.</para>
66 <para>By default, Asterisk will wait for media for up to 500 ms, or
67 the user specified delay, whichever is longer. If you do not want
68 to wait for media at all, use the i option.</para>
69 </description>
70 <see-also>
71 <ref type="application">Hangup</ref>
72 </see-also>
73 </application>
74 <application name="BackGround" language="en_US">
75 <synopsis>
76 Play an audio file while waiting for digits of an extension to go to.
77 </synopsis>
78 <syntax>
79 <parameter name="filenames" required="true" argsep="&amp;">
80 <para>Ampersand separated list of filenames. If the filename
81 is a relative filename (it does not begin with a slash), it
82 will be searched for in the Asterisk sounds directory. If the
83 filename is able to be parsed as a URL, Asterisk will
84 download the file and then begin playback on it. To include a
85 literal <literal>&amp;</literal> in the URL you can enclose
86 the URL in single quotes.</para>
87 <argument name="filename1" required="true" />
88 <argument name="filename2" multiple="true" />
89 </parameter>
90 <parameter name="options">
91 <optionlist>
92 <option name="s">
93 <para>Causes the playback of the message to be skipped
94 if the channel is not in the <literal>up</literal> state (i.e. it
95 hasn't been answered yet). If this happens, the
96 application will return immediately.</para>
97 </option>
98 <option name="n">
99 <para>Don't answer the channel before playing the files.</para>
100 </option>
101 <option name="m">
102 <para>Only break if a digit hit matches a one digit
103 extension in the destination context.</para>
104 </option>
105 <option name="p">
106 <para>Do not allow playback to be interrupted with digits.</para>
107 </option>
108 </optionlist>
109 </parameter>
110 <parameter name="langoverride">
111 <para>Explicitly specifies which language to attempt to use for the requested sound files.</para>
112 </parameter>
113 <parameter name="context">
114 <para>This is the dialplan context that this application will use when exiting
115 to a dialed extension.</para>
116 </parameter>
117 </syntax>
118 <description>
119 <para>This application will play the given list of files <emphasis>(do not put extension)</emphasis>
120 while waiting for an extension to be dialed by the calling channel. To continue waiting
121 for digits after this application has finished playing files, the <literal>WaitExten</literal>
122 application should be used.</para>
123 <para>If one of the requested sound files does not exist, call processing will be terminated.</para>
124 <para>This application sets the following channel variable upon completion:</para>
125 <variablelist>
126 <variable name="BACKGROUNDSTATUS">
127 <para>The status of the background attempt as a text string.</para>
128 <value name="SUCCESS" />
129 <value name="FAILED" />
130 </variable>
131 </variablelist>
132 </description>
133 <see-also>
134 <ref type="application">ControlPlayback</ref>
135 <ref type="application">WaitExten</ref>
136 <ref type="application">BackgroundDetect</ref>
137 <ref type="function">TIMEOUT</ref>
138 </see-also>
139 </application>
140 <application name="Busy" language="en_US">
141 <synopsis>
142 Indicate the Busy condition.
143 </synopsis>
144 <syntax>
145 <parameter name="timeout">
146 <para>If specified, the calling channel will be hung up after the specified number of seconds.
147 Otherwise, this application will wait until the calling channel hangs up.</para>
148 </parameter>
149 </syntax>
150 <description>
151 <para>This application will indicate the busy condition to the calling channel.</para>
152 </description>
153 <see-also>
154 <ref type="application">Congestion</ref>
155 <ref type="application">Progress</ref>
156 <ref type="application">PlayTones</ref>
157 <ref type="application">Hangup</ref>
158 </see-also>
159 </application>
160 <application name="Congestion" language="en_US">
161 <synopsis>
162 Indicate the Congestion condition.
163 </synopsis>
164 <syntax>
165 <parameter name="timeout">
166 <para>If specified, the calling channel will be hung up after the specified number of seconds.
167 Otherwise, this application will wait until the calling channel hangs up.</para>
168 </parameter>
169 </syntax>
170 <description>
171 <para>This application will indicate the congestion condition to the calling channel.</para>
172 </description>
173 <see-also>
174 <ref type="application">Busy</ref>
175 <ref type="application">Progress</ref>
176 <ref type="application">PlayTones</ref>
177 <ref type="application">Hangup</ref>
178 </see-also>
179 </application>
180 <application name="ExecIfTime" language="en_US">
181 <synopsis>
182 Conditional application execution based on the current time.
183 </synopsis>
184 <syntax argsep="?">
185 <parameter name="day_condition" required="true">
186 <argument name="times" required="true" />
187 <argument name="weekdays" required="true" />
188 <argument name="mdays" required="true" />
189 <argument name="months" required="true" />
190 <argument name="timezone" required="false" />
191 </parameter>
192 <parameter name="appname" required="true" hasparams="optional">
193 <argument name="appargs" required="true" />
194 </parameter>
195 </syntax>
196 <description>
197 <para>This application will execute the specified dialplan application, with optional
198 arguments, if the current time matches the given time specification.</para>
199 </description>
200 <see-also>
201 <ref type="application">Exec</ref>
202 <ref type="application">ExecIf</ref>
203 <ref type="application">TryExec</ref>
204 <ref type="application">GotoIfTime</ref>
205 </see-also>
206 </application>
207 <application name="Goto" language="en_US">
208 <synopsis>
209 Jump to a particular priority, extension, or context.
210 </synopsis>
211 <syntax>
212 <parameter name="context" />
213 <parameter name="extensions" />
214 <parameter name="priority" required="true" />
215 </syntax>
216 <description>
217 <para>This application will set the current context, extension, and priority in the channel structure.
218 After it completes, the pbx engine will continue dialplan execution at the specified location.
219 If no specific <replaceable>extension</replaceable>, or <replaceable>extension</replaceable> and
220 <replaceable>context</replaceable>, are specified, then this application will
221 just set the specified <replaceable>priority</replaceable> of the current extension.</para>
222 <para>At least a <replaceable>priority</replaceable> is required as an argument, or the goto will
223 return a <literal>-1</literal>, and the channel and call will be terminated.</para>
224 <para>If the location that is put into the channel information is bogus, and asterisk cannot
225 find that location in the dialplan, then the execution engine will try to find and execute the code in
226 the <literal>i</literal> (invalid) extension in the current context. If that does not exist, it will try to execute the
227 <literal>h</literal> extension. If neither the <literal>h</literal> nor <literal>i</literal> extensions
228 have been defined, the channel is hung up, and the execution of instructions on the channel is terminated.
229 What this means is that, for example, you specify a context that does not exist, then
230 it will not be possible to find the <literal>h</literal> or <literal>i</literal> extensions,
231 and the call will terminate!</para>
232 </description>
233 <see-also>
234 <ref type="application">GotoIf</ref>
235 <ref type="application">GotoIfTime</ref>
236 <ref type="application">Gosub</ref>
237 </see-also>
238 </application>
239 <application name="GotoIf" language="en_US">
240 <synopsis>
241 Conditional goto.
242 </synopsis>
243 <syntax argsep="?">
244 <parameter name="condition" required="true" />
245 <parameter name="destination" required="true" argsep=":">
246 <argument name="labeliftrue">
247 <para>Continue at <replaceable>labeliftrue</replaceable> if the condition is true.
248 Takes the form similar to Goto() of [[context,]extension,]priority.</para>
249 </argument>
250 <argument name="labeliffalse">
251 <para>Continue at <replaceable>labeliffalse</replaceable> if the condition is false.
252 Takes the form similar to Goto() of [[context,]extension,]priority.</para>
253 </argument>
254 </parameter>
255 </syntax>
256 <description>
257 <para>This application will set the current context, extension, and priority in the channel structure
258 based on the evaluation of the given condition. After this application completes, the
259 pbx engine will continue dialplan execution at the specified location in the dialplan.
260 The labels are specified with the same syntax as used within the Goto application.
261 If the label chosen by the condition is omitted, no jump is performed, and the execution passes to the
262 next instruction. If the target location is bogus, and does not exist, the execution engine will try
263 to find and execute the code in the <literal>i</literal> (invalid) extension in the current context.
264 If that does not exist, it will try to execute the <literal>h</literal> extension.
265 If neither the <literal>h</literal> nor <literal>i</literal> extensions have been defined,
266 the channel is hung up, and the execution of instructions on the channel is terminated.
267 Remember that this command can set the current context, and if the context specified
268 does not exist, then it will not be able to find any 'h' or 'i' extensions there, and
269 the channel and call will both be terminated!.</para>
270 </description>
271 <see-also>
272 <ref type="application">Goto</ref>
273 <ref type="application">GotoIfTime</ref>
274 <ref type="application">GosubIf</ref>
275 </see-also>
276 </application>
277 <application name="GotoIfTime" language="en_US">
278 <synopsis>
279 Conditional Goto based on the current time.
280 </synopsis>
281 <syntax argsep="?">
282 <parameter name="condition" required="true">
283 <argument name="times" required="true" />
284 <argument name="weekdays" required="true" />
285 <argument name="mdays" required="true" />
286 <argument name="months" required="true" />
287 <argument name="timezone" required="false" />
288 </parameter>
289 <parameter name="destination" required="true" argsep=":">
290 <argument name="labeliftrue">
291 <para>Continue at <replaceable>labeliftrue</replaceable> if the condition is true.
292 Takes the form similar to Goto() of [[context,]extension,]priority.</para>
293 </argument>
294 <argument name="labeliffalse">
295 <para>Continue at <replaceable>labeliffalse</replaceable> if the condition is false.
296 Takes the form similar to Goto() of [[context,]extension,]priority.</para>
297 </argument>
298 </parameter>
299 </syntax>
300 <description>
301 <para>This application will set the context, extension, and priority in the channel structure
302 based on the evaluation of the given time specification. After this application completes,
303 the pbx engine will continue dialplan execution at the specified location in the dialplan.
304 If the current time is within the given time specification, the channel will continue at
305 <replaceable>labeliftrue</replaceable>. Otherwise the channel will continue at <replaceable>labeliffalse</replaceable>.
306 If the label chosen by the condition is omitted, no jump is performed, and execution passes to the next
307 instruction. If the target jump location is bogus, the same actions would be taken as for <literal>Goto</literal>.
308 Further information on the time specification can be found in examples
309 illustrating how to do time-based context includes in the dialplan.</para>
310 </description>
311 <see-also>
312 <ref type="application">GotoIf</ref>
313 <ref type="application">Goto</ref>
314 <ref type="function">IFTIME</ref>
315 <ref type="function">TESTTIME</ref>
316 </see-also>
317 </application>
318 <application name="Hangup" language="en_US">
319 <synopsis>
320 Hang up the calling channel.
321 </synopsis>
322 <syntax>
323 <parameter name="causecode">
324 <para>If a <replaceable>causecode</replaceable> is given the channel's
325 hangup cause will be set to the given value.</para>
326 </parameter>
327 </syntax>
328 <description>
329 <para>This application will hang up the calling channel.</para>
330 </description>
331 <see-also>
332 <ref type="application">Answer</ref>
333 <ref type="application">Busy</ref>
334 <ref type="application">Congestion</ref>
335 </see-also>
336 </application>
337 <application name="Incomplete" language="en_US">
338 <synopsis>
339 Returns AST_PBX_INCOMPLETE value.
340 </synopsis>
341 <syntax>
342 <parameter name="n">
343 <para>If specified, then Incomplete will not attempt to answer the channel first.</para>
344 <note><para>Most channel types need to be in Answer state in order to receive DTMF.</para></note>
345 </parameter>
346 </syntax>
347 <description>
348 <para>Signals the PBX routines that the previous matched extension is incomplete
349 and that further input should be allowed before matching can be considered
350 to be complete. Can be used within a pattern match when certain criteria warrants
351 a longer match.</para>
352 </description>
353 </application>
354 <application name="NoOp" language="en_US">
355 <synopsis>
356 Do Nothing (No Operation).
357 </synopsis>
358 <syntax>
359 <parameter name="text">
360 <para>Any text provided can be viewed at the Asterisk CLI.</para>
361 </parameter>
362 </syntax>
363 <description>
364 <para>This application does nothing. However, it is useful for debugging purposes.</para>
365 <para>This method can be used to see the evaluations of variables or functions without having any effect.</para>
366 </description>
367 <see-also>
368 <ref type="application">Verbose</ref>
369 <ref type="application">Log</ref>
370 </see-also>
371 </application>
372 <application name="Proceeding" language="en_US">
373 <synopsis>
374 Indicate proceeding.
375 </synopsis>
376 <syntax />
377 <description>
378 <para>This application will request that a proceeding message be provided to the calling channel.</para>
379 </description>
380 </application>
381 <application name="Progress" language="en_US">
382 <synopsis>
383 Indicate progress.
384 </synopsis>
385 <syntax />
386 <description>
387 <para>This application will request that in-band progress information be provided to the calling channel.</para>
388 </description>
389 <see-also>
390 <ref type="application">Busy</ref>
391 <ref type="application">Congestion</ref>
392 <ref type="application">Ringing</ref>
393 <ref type="application">PlayTones</ref>
394 </see-also>
395 </application>
396 <application name="RaiseException" language="en_US">
397 <synopsis>
398 Handle an exceptional condition.
399 </synopsis>
400 <syntax>
401 <parameter name="reason" required="true" />
402 </syntax>
403 <description>
404 <para>This application will jump to the <literal>e</literal> extension in the current context, setting the
405 dialplan function EXCEPTION(). If the <literal>e</literal> extension does not exist, the call will hangup.</para>
406 </description>
407 <see-also>
408 <ref type="function">EXCEPTION</ref>
409 </see-also>
410 </application>
411 <application name="Ringing" language="en_US">
412 <synopsis>
413 Indicate ringing tone.
414 </synopsis>
415 <syntax />
416 <description>
417 <para>This application will request that the channel indicate a ringing tone to the user.</para>
418 </description>
419 <see-also>
420 <ref type="application">Busy</ref>
421 <ref type="application">Congestion</ref>
422 <ref type="application">Progress</ref>
423 <ref type="application">PlayTones</ref>
424 </see-also>
425 </application>
426 <application name="SayAlpha" language="en_US">
427 <synopsis>
428 Say Alpha.
429 </synopsis>
430 <syntax>
431 <parameter name="string" required="true" />
432 </syntax>
433 <description>
434 <para>This application will play the sounds that correspond to the letters
435 of the given <replaceable>string</replaceable>. If the channel variable
436 <variable>SAY_DTMF_INTERRUPT</variable> is set to 'true' (case insensitive),
437 then this application will react to DTMF in the same way as
438 <literal>BackGround</literal>.</para>
439 </description>
440 <see-also>
441 <ref type="application">SayDigits</ref>
442 <ref type="application">SayMoney</ref>
443 <ref type="application">SayNumber</ref>
444 <ref type="application">SayOrdinal</ref>
445 <ref type="application">SayPhonetic</ref>
446 <ref type="function">CHANNEL</ref>
447 <ref type="function">SAYFILES</ref>
448 </see-also>
449 </application>
450 <application name="SayAlphaCase" language="en_US">
451 <synopsis>
452 Say Alpha.
453 </synopsis>
454 <syntax>
455 <parameter name="casetype" required="true" >
456 <enumlist>
457 <enum name="a">
458 <para>Case sensitive (all) pronunciation.
459 (Ex: SayAlphaCase(a,aBc); - lowercase a uppercase b lowercase c).</para>
460 </enum>
461 <enum name="l">
462 <para>Case sensitive (lower) pronunciation.
463 (Ex: SayAlphaCase(l,aBc); - lowercase a b lowercase c).</para>
464 </enum>
465 <enum name="n">
466 <para>Case insensitive pronunciation. Equivalent to SayAlpha.
467 (Ex: SayAlphaCase(n,aBc) - a b c).</para>
468 </enum>
469 <enum name="u">
470 <para>Case sensitive (upper) pronunciation.
471 (Ex: SayAlphaCase(u,aBc); - a uppercase b c).</para>
472 </enum>
473 </enumlist>
474 </parameter>
475 <parameter name="string" required="true" />
476 </syntax>
477 <description>
478 <para>This application will play the sounds that correspond to the letters of the
479 given <replaceable>string</replaceable>. Optionally, a <replaceable>casetype</replaceable> may be
480 specified. This will be used for case-insensitive or case-sensitive pronunciations. If the channel
481 variable <variable>SAY_DTMF_INTERRUPT</variable> is set to 'true' (case insensitive), then this
482 application will react to DTMF in the same way as <literal>BackGround</literal>.</para>
483 </description>
484 <see-also>
485 <ref type="application">SayDigits</ref>
486 <ref type="application">SayMoney</ref>
487 <ref type="application">SayNumber</ref>
488 <ref type="application">SayOrdinal</ref>
489 <ref type="application">SayPhonetic</ref>
490 <ref type="application">SayAlpha</ref>
491 <ref type="function">CHANNEL</ref>
492 </see-also>
493 </application>
494 <application name="SayDigits" language="en_US">
495 <synopsis>
496 Say Digits.
497 </synopsis>
498 <syntax>
499 <parameter name="digits" required="true" />
500 </syntax>
501 <description>
502 <para>This application will play the sounds that correspond to the digits of
503 the given number. This will use the language that is currently set for the channel.
504 If the channel variable <variable>SAY_DTMF_INTERRUPT</variable> is set to 'true'
505 (case insensitive), then this application will react to DTMF in the same way as
506 <literal>BackGround</literal>.</para>
507 </description>
508 <see-also>
509 <ref type="application">SayAlpha</ref>
510 <ref type="application">SayMoney</ref>
511 <ref type="application">SayNumber</ref>
512 <ref type="application">SayOrdinal</ref>
513 <ref type="application">SayPhonetic</ref>
514 <ref type="function">CHANNEL</ref>
515 <ref type="function">SAYFILES</ref>
516 </see-also>
517 </application>
518 <application name="SayMoney" language="en_US">
519 <synopsis>
520 Say Money.
521 </synopsis>
522 <syntax>
523 <parameter name="dollars" required="true" />
524 </syntax>
525 <description>
526 <para>This application will play the currency sounds for the given floating point number
527 in the current language. Currently only English and US Dollars is supported.
528 If the channel variable <variable>SAY_DTMF_INTERRUPT</variable> is set to 'true'
529 (case insensitive), then this application will react to DTMF in the same way as
530 <literal>BackGround</literal>.</para>
531 </description>
532 <see-also>
533 <ref type="application">SayAlpha</ref>
534 <ref type="application">SayNumber</ref>
535 <ref type="application">SayOrdinal</ref>
536 <ref type="application">SayPhonetic</ref>
537 <ref type="function">CHANNEL</ref>
538 <ref type="function">SAYFILES</ref>
539 </see-also>
540 </application>
541 <application name="SayNumber" language="en_US">
542 <synopsis>
543 Say Number.
544 </synopsis>
545 <syntax>
546 <parameter name="digits" required="true" />
547 <parameter name="gender" />
548 </syntax>
549 <description>
550 <para>This application will play the sounds that correspond to the given
551 <replaceable>digits</replaceable>. Optionally, a <replaceable>gender</replaceable> may be
552 specified. This will use the language that is currently set for the channel. See the CHANNEL()
553 function for more information on setting the language for the channel. If the channel variable
554 <variable>SAY_DTMF_INTERRUPT</variable> is set to 'true' (case insensitive), then this
555 application will react to DTMF in the same way as <literal>BackGround</literal>.</para>
556 </description>
557 <see-also>
558 <ref type="application">SayAlpha</ref>
559 <ref type="application">SayDigits</ref>
560 <ref type="application">SayMoney</ref>
561 <ref type="application">SayPhonetic</ref>
562 <ref type="function">CHANNEL</ref>
563 <ref type="function">SAYFILES</ref>
564 </see-also>
565 </application>
566 <application name="SayOrdinal" language="en_US">
567 <synopsis>
568 Say Ordinal Number.
569 </synopsis>
570 <syntax>
571 <parameter name="digits" required="true" />
572 <parameter name="gender" />
573 </syntax>
574 <description>
575 <para>This application will play the ordinal sounds that correspond to the given
576 <replaceable>digits</replaceable> (e.g. 1st, 42nd). Currently only English is supported.</para>
577 <para>Optionally, a <replaceable>gender</replaceable> may be
578 specified. This will use the language that is currently set for the channel. See the CHANNEL()
579 function for more information on setting the language for the channel. If the channel variable
580 <variable>SAY_DTMF_INTERRUPT</variable> is set to 'true' (case insensitive), then this
581 application will react to DTMF in the same way as <literal>BackGround</literal>.</para>
582 </description>
583 <see-also>
584 <ref type="application">SayAlpha</ref>
585 <ref type="application">SayDigits</ref>
586 <ref type="application">SayMoney</ref>
587 <ref type="application">SayNumber</ref>
588 <ref type="application">SayPhonetic</ref>
589 <ref type="function">CHANNEL</ref>
590 <ref type="function">SAYFILES</ref>
591 </see-also>
592 </application>
593 <application name="SayPhonetic" language="en_US">
594 <synopsis>
595 Say Phonetic.
596 </synopsis>
597 <syntax>
598 <parameter name="string" required="true" />
599 </syntax>
600 <description>
601 <para>This application will play the sounds from the phonetic alphabet that correspond to the
602 letters in the given <replaceable>string</replaceable>. If the channel variable
603 <variable>SAY_DTMF_INTERRUPT</variable> is set to 'true' (case insensitive), then this
604 application will react to DTMF in the same way as <literal>BackGround</literal>.</para>
605 </description>
606 <see-also>
607 <ref type="application">SayAlpha</ref>
608 <ref type="application">SayDigits</ref>
609 <ref type="application">SayMoney</ref>
610 <ref type="application">SayNumber</ref>
611 <ref type="application">SayOrdinal</ref>
612 <ref type="function">SAYFILES</ref>
613 </see-also>
614 </application>
615 <application name="Wait" language="en_US">
616 <synopsis>
617 Waits for some time.
618 </synopsis>
619 <syntax>
620 <parameter name="seconds" required="true">
621 <para>Can be passed with fractions of a second. For example, <literal>1.5</literal> will ask the
622 application to wait for 1.5 seconds.</para>
623 </parameter>
624 </syntax>
625 <description>
626 <para>This application waits for a specified number of <replaceable>seconds</replaceable>.</para>
627 </description>
628 </application>
629 <application name="WaitDigit" language="en_US">
630 <synopsis>
631 Waits for a digit to be entered.
632 </synopsis>
633 <syntax>
634 <parameter name="seconds">
635 <para>Can be passed with fractions of a second. For example, <literal>1.5</literal> will ask the
636 application to wait for 1.5 seconds.</para>
637 </parameter>
638 <parameter name="digits">
639 <para>Digits to accept, all others are ignored.</para>
640 </parameter>
641 </syntax>
642 <description>
643 <para>This application waits for the user to press one of the accepted
644 <replaceable>digits</replaceable> for a specified number of
645 <replaceable>seconds</replaceable>.</para>
646 <variablelist>
647 <variable name="WAITDIGITSTATUS">
648 <para>This is the final status of the command</para>
649 <value name="ERROR">Parameters are invalid.</value>
650 <value name="DTMF">An accepted digit was received.</value>
651 <value name="TIMEOUT">The timeout passed before any acceptable digits were received.</value>
652 <value name="CANCEL">The channel has hungup or was redirected.</value>
653 </variable>
654 <variable name="WAITDIGITRESULT">
655 <para>The digit that was received, only set if
656 <variable>WAITDIGITSTATUS</variable> is <literal>DTMF</literal>.</para>
657 </variable>
658 </variablelist>
659 </description>
660 <see-also>
661 <ref type="application">Wait</ref>
662 <ref type="application">WaitExten</ref>
663 </see-also>
664 </application>
665 <application name="WaitExten" language="en_US">
666 <synopsis>
667 Waits for an extension to be entered.
668 </synopsis>
669 <syntax>
670 <parameter name="seconds">
671 <para>Can be passed with fractions of a second. For example, <literal>1.5</literal> will ask the
672 application to wait for 1.5 seconds.</para>
673 </parameter>
674 <parameter name="options">
675 <optionlist>
676 <option name="m">
677 <para>Provide music on hold to the caller while waiting for an extension.</para>
678 <argument name="x">
679 <para>Specify the class for music on hold. <emphasis>CHANNEL(musicclass) will
680 be used instead if set</emphasis></para>
681 </argument>
682 </option>
683 <option name="d">
684 <para>Play <literal>dial</literal> indications tone on channel while waiting
685 for digits.</para>
686 </option>
687 </optionlist>
688 </parameter>
689 </syntax>
690 <description>
691 <para>This application waits for the user to enter a new extension for a specified number
692 of <replaceable>seconds</replaceable>.</para>
693 </description>
694 <see-also>
695 <ref type="application">BackGround</ref>
696 <ref type="function">TIMEOUT</ref>
697 </see-also>
698 </application>
699 ***/
700
701#define BACKGROUND_SKIP (1 << 0)
702#define BACKGROUND_NOANSWER (1 << 1)
703#define BACKGROUND_MATCHEXTEN (1 << 2)
704#define BACKGROUND_PLAYBACK (1 << 3)
705
711});
712
713#define WAITEXTEN_MOH (1 << 0)
714#define WAITEXTEN_DIALTONE (1 << 1)
715
719});
720
721int pbx_builtin_raise_exception(struct ast_channel *chan, const char *reason)
722{
723 /* Priority will become 1, next time through the AUTOLOOP */
724 return raise_exception(chan, reason, 0);
725}
726
727/*!
728 * \ingroup applications
729 */
730static int pbx_builtin_proceeding(struct ast_channel *chan, const char *data)
731{
733 return 0;
734}
735
736/*!
737 * \ingroup applications
738 */
739static int pbx_builtin_progress(struct ast_channel *chan, const char *data)
740{
742 return 0;
743}
744
745/*!
746 * \ingroup applications
747 */
748static int pbx_builtin_ringing(struct ast_channel *chan, const char *data)
749{
751 return 0;
752}
753
754/*!
755 * \ingroup applications
756 */
757int indicate_busy(struct ast_channel *chan, const char *data)
758{
760 /* Don't change state of an UP channel, just indicate
761 busy in audio */
762 ast_channel_lock(chan);
763 if (ast_channel_state(chan) != AST_STATE_UP) {
766 }
767 ast_channel_unlock(chan);
768 wait_for_hangup(chan, data);
769 return -1;
770}
771
772/*!
773 * \ingroup applications
774 */
775int indicate_congestion(struct ast_channel *chan, const char *data)
776{
778 /* Don't change state of an UP channel, just indicate
779 congestion in audio */
780 ast_channel_lock(chan);
781 if (ast_channel_state(chan) != AST_STATE_UP) {
784 }
785 ast_channel_unlock(chan);
786 wait_for_hangup(chan, data);
787 return -1;
788}
789
790/*!
791 * \ingroup applications
792 */
793static int pbx_builtin_answer(struct ast_channel *chan, const char *data)
794{
795 int delay = 0;
796 char *parse;
798 AST_APP_ARG(delay);
800 );
801
802 if (ast_strlen_zero(data)) {
803 return __ast_answer(chan, 0);
804 }
805
806 parse = ast_strdupa(data);
807
809
810 if (!ast_strlen_zero(args.delay) && (ast_channel_state(chan) != AST_STATE_UP))
811 delay = atoi(data);
812
813 if (delay < 0) {
814 delay = 0;
815 }
816
817 if (!ast_strlen_zero(args.options) && !strcmp(args.options, "i")) {
818 return ast_raw_answer(chan);
819 }
820
821 return __ast_answer(chan, delay);
822}
823
824static int pbx_builtin_incomplete(struct ast_channel *chan, const char *data)
825{
826 const char *options = data;
827 int answer = 1;
828
829 /* Some channels can receive DTMF in unanswered state; some cannot */
830 if (!ast_strlen_zero(options) && strchr(options, 'n')) {
831 answer = 0;
832 }
833
834 /* If the channel is hungup, stop waiting */
835 if (ast_check_hangup(chan)) {
836 return -1;
837 } else if (ast_channel_state(chan) != AST_STATE_UP && answer) {
838 __ast_answer(chan, 0);
839 }
840
842
843 return AST_PBX_INCOMPLETE;
844}
845
846/*!
847 * \ingroup applications
848 */
849static int pbx_builtin_hangup(struct ast_channel *chan, const char *data)
850{
851 int cause;
852
853 ast_set_hangupsource(chan, "dialplan/builtin", 0);
854
855 if (!ast_strlen_zero(data)) {
856 cause = ast_str2cause(data);
857 if (cause <= 0) {
858 if (sscanf(data, "%30d", &cause) != 1 || cause <= 0) {
859 ast_log(LOG_WARNING, "Invalid cause given to Hangup(): \"%s\"\n", data);
860 cause = 0;
861 }
862 }
863 } else {
864 cause = 0;
865 }
866
867 ast_channel_lock(chan);
868 if (cause <= 0) {
869 cause = ast_channel_hangupcause(chan);
870 if (cause <= 0) {
872 }
873 }
874 ast_channel_hangupcause_set(chan, cause);
876 ast_channel_unlock(chan);
877
878 return -1;
879}
880
881/*! Goto
882 * \ingroup applications
883 */
884static int pbx_builtin_goto(struct ast_channel *chan, const char *data)
885{
886 int res = ast_parseable_goto(chan, data);
887 if (!res)
888 ast_verb(3, "Goto (%s,%s,%d)\n", ast_channel_context(chan), ast_channel_exten(chan), ast_channel_priority(chan) + 1);
889 return res;
890}
891
892/*!
893 * \ingroup applications
894 */
895static int pbx_builtin_gotoiftime(struct ast_channel *chan, const char *data)
896{
897 char *s, *ts, *branch1, *branch2, *branch;
898 struct ast_timing timing;
899 const char *ctime;
900 struct timeval tv = ast_tvnow();
901 long timesecs;
902
903 if (!chan) {
904 ast_log(LOG_WARNING, "GotoIfTime requires a channel on which to operate\n");
905 return -1;
906 }
907
908 if (ast_strlen_zero(data)) {
909 ast_log(LOG_WARNING, "GotoIfTime requires an argument:\n <time range>,<days of week>,<days of month>,<months>[,<timezone>]?'labeliftrue':'labeliffalse'\n");
910 return -1;
911 }
912
913 ts = s = ast_strdupa(data);
914
915 ast_channel_lock(chan);
916 if ((ctime = pbx_builtin_getvar_helper(chan, "TESTTIME")) && sscanf(ctime, "%ld", &timesecs) == 1) {
917 tv.tv_sec = timesecs;
918 } else if (ctime) {
919 ast_log(LOG_WARNING, "Using current time to evaluate\n");
920 /* Reset when unparseable */
921 pbx_builtin_setvar_helper(chan, "TESTTIME", NULL);
922 }
923 ast_channel_unlock(chan);
924
925 /* Separate the Goto path */
926 strsep(&ts, "?");
927 branch1 = strsep(&ts,":");
928 branch2 = strsep(&ts,"");
929
930 /* struct ast_include include contained garbage here, fixed by zeroing it on get_timerange */
931 if (ast_build_timing(&timing, s) && ast_check_timing2(&timing, tv)) {
932 branch = branch1;
933 } else {
934 branch = branch2;
935 }
936 ast_destroy_timing(&timing);
937
938 if (ast_strlen_zero(branch)) {
939 ast_debug(1, "Not taking any branch\n");
940 return 0;
941 }
942
943 return pbx_builtin_goto(chan, branch);
944}
945
946/*!
947 * \ingroup applications
948 */
949static int pbx_builtin_execiftime(struct ast_channel *chan, const char *data)
950{
951 char *s, *appname;
952 struct ast_timing timing;
953 static const char * const usage = "ExecIfTime requires an argument:\n <time range>,<days of week>,<days of month>,<months>[,<timezone>]?<appname>[(<appargs>)]";
954
955 if (ast_strlen_zero(data)) {
956 ast_log(LOG_WARNING, "%s\n", usage);
957 return -1;
958 }
959
960 appname = ast_strdupa(data);
961
962 s = strsep(&appname, "?"); /* Separate the timerange and application name/data */
963 if (!appname) { /* missing application */
964 ast_log(LOG_WARNING, "%s\n", usage);
965 return -1;
966 }
967
968 if (!ast_build_timing(&timing, s)) {
969 ast_log(LOG_WARNING, "Invalid Time Spec: %s\nCorrect usage: %s\n", s, usage);
970 ast_destroy_timing(&timing);
971 return -1;
972 }
973
974 if (!ast_check_timing(&timing)) { /* outside the valid time window, just return */
975 ast_destroy_timing(&timing);
976 return 0;
977 }
978 ast_destroy_timing(&timing);
979
980 /* now split appname(appargs) */
981 if ((s = strchr(appname, '('))) {
982 char *e;
983 *s++ = '\0';
984 if ((e = strrchr(s, ')')))
985 *e = '\0';
986 else
987 ast_log(LOG_WARNING, "Failed to find closing parenthesis\n");
988 }
989
990 return ast_pbx_exec_application(chan, appname, S_OR(s, ""));
991}
992
993/*!
994 * \ingroup applications
995 */
996static int pbx_builtin_wait(struct ast_channel *chan, const char *data)
997{
998 int ms;
999
1000 /* Wait for "n" seconds */
1001 if (!ast_app_parse_timelen(data, &ms, TIMELEN_SECONDS) && ms > 0) {
1002 return ast_safe_sleep(chan, ms);
1003 }
1004 return 0;
1005}
1006
1007/*!
1008 * \ingroup applications
1009 */
1010static int pbx_builtin_waitdigit(struct ast_channel *chan, const char *data)
1011{
1012 int res;
1013 int ms;
1014 char *parse;
1016 AST_APP_ARG(timeout);
1017 AST_APP_ARG(digits);
1018 );
1019
1020 parse = ast_strdupa(data);
1022
1023 if (ast_app_parse_timelen(args.timeout, &ms, TIMELEN_SECONDS) || ms < 0) {
1024 pbx_builtin_setvar_helper(chan, "WAITDIGITSTATUS", "ERROR");
1025 return 0;
1026 }
1027
1028 /* Wait for "n" seconds */
1029 res = ast_waitfordigit_full(chan, ms, S_OR(args.digits, AST_DIGIT_ANY), -1, -1);
1030 if (res < 0) {
1031 pbx_builtin_setvar_helper(chan, "WAITDIGITSTATUS", "CANCEL");
1032 return -1;
1033 }
1034
1035 if (res == 0) {
1036 pbx_builtin_setvar_helper(chan, "WAITDIGITSTATUS", "TIMEOUT");
1037 } else {
1038 char key[2];
1039
1040 snprintf(key, sizeof(key), "%c", res);
1041 pbx_builtin_setvar_helper(chan, "WAITDIGITRESULT", key);
1042 pbx_builtin_setvar_helper(chan, "WAITDIGITSTATUS", "DTMF");
1043 }
1044
1045 return 0;
1046}
1047
1048/*!
1049 * \ingroup applications
1050 */
1051static int pbx_builtin_waitexten(struct ast_channel *chan, const char *data)
1052{
1053 int ms, res;
1054 struct ast_flags flags = {0};
1055 char *opts[1] = { NULL };
1056 char *parse;
1058 AST_APP_ARG(timeout);
1060 );
1061
1062 if (!ast_strlen_zero(data)) {
1063 parse = ast_strdupa(data);
1065 } else
1066 memset(&args, 0, sizeof(args));
1067
1068 if (args.options)
1070
1071 if (ast_test_flag(&flags, WAITEXTEN_MOH) && !opts[0] ) {
1072 ast_log(LOG_WARNING, "The 'm' option has been specified for WaitExten without a class.\n");
1073 } else if (ast_test_flag(&flags, WAITEXTEN_MOH)) {
1075 !ast_strlen_zero(opts[0]) ? strlen(opts[0]) + 1 : 0);
1076 } else if (ast_test_flag(&flags, WAITEXTEN_DIALTONE)) {
1078 if (ts) {
1079 ast_playtones_start(chan, 0, ts->data, 0);
1081 } else {
1082 ast_tonepair_start(chan, 350, 440, 0, 0);
1083 }
1084 }
1085 /* Wait for "n" seconds */
1086 if (!ast_app_parse_timelen(args.timeout, &ms, TIMELEN_SECONDS) && ms > 0) {
1087 /* Yay! */
1088 } else if (ast_channel_pbx(chan)) {
1089 ms = ast_channel_pbx(chan)->rtimeoutms;
1090 } else {
1091 ms = 10000;
1092 }
1093
1094 res = ast_waitfordigit(chan, ms);
1095 if (!res) {
1096 if (ast_check_hangup(chan)) {
1097 /* Call is hungup for some reason. */
1098 res = -1;
1099 } else if (ast_exists_extension(chan, ast_channel_context(chan), ast_channel_exten(chan), ast_channel_priority(chan) + 1,
1100 S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))) {
1101 ast_verb(3, "Timeout on %s, continuing...\n", ast_channel_name(chan));
1102 } else if (ast_exists_extension(chan, ast_channel_context(chan), "t", 1,
1103 S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))) {
1104 ast_verb(3, "Timeout on %s, going to 't'\n", ast_channel_name(chan));
1105 set_ext_pri(chan, "t", 0); /* 0 will become 1, next time through the loop */
1106 } else if (ast_exists_extension(chan, ast_channel_context(chan), "e", 1,
1107 S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))) {
1108 raise_exception(chan, "RESPONSETIMEOUT", 0); /* 0 will become 1, next time through the loop */
1109 } else {
1110 ast_log(LOG_WARNING, "Timeout but no rule 't' or 'e' in context '%s'\n",
1111 ast_channel_context(chan));
1112 res = -1;
1113 }
1114 }
1115
1116 if (ast_test_flag(&flags, WAITEXTEN_MOH))
1118 else if (ast_test_flag(&flags, WAITEXTEN_DIALTONE))
1119 ast_playtones_stop(chan);
1120
1121 return res;
1122}
1123
1124/*!
1125 * \ingroup applications
1126 */
1127static int pbx_builtin_background(struct ast_channel *chan, const char *data)
1128{
1129 int res = 0;
1130 int mres = 0;
1131 struct ast_flags flags = {0};
1132 char *parse, exten[2] = "";
1134 AST_APP_ARG(filename);
1136 AST_APP_ARG(lang);
1138 );
1139
1140 if (ast_strlen_zero(data)) {
1141 ast_log(LOG_WARNING, "Background requires an argument (filename)\n");
1142 return -1;
1143 }
1144
1145 parse = ast_strdupa(data);
1146
1148
1149 if (ast_strlen_zero(args.lang))
1150 args.lang = (char *)ast_channel_language(chan); /* XXX this is const */
1151
1152 if (ast_strlen_zero(args.context)) {
1153 ast_channel_lock(chan);
1154 args.context = ast_strdupa(ast_channel_context(chan));
1155 ast_channel_unlock(chan);
1156 }
1157
1158 if (args.options) {
1159 if (!strcasecmp(args.options, "skip"))
1160 flags.flags = BACKGROUND_SKIP;
1161 else if (!strcasecmp(args.options, "noanswer"))
1162 flags.flags = BACKGROUND_NOANSWER;
1163 else
1165 }
1166
1167 /* Answer if need be */
1168 if (ast_channel_state(chan) != AST_STATE_UP) {
1170 goto done;
1171 } else if (!ast_test_flag(&flags, BACKGROUND_NOANSWER)) {
1172 res = ast_answer(chan);
1173 }
1174 }
1175
1176 if (!res) {
1177 char *back = ast_strip(args.filename);
1178 char *front;
1179
1180 ast_stopstream(chan); /* Stop anything playing */
1181 /* Stream the list of files */
1182 while (!res && (front = ast_strsep(&back, '&', AST_STRSEP_STRIP | AST_STRSEP_TRIM))) {
1183 if ( (res = ast_streamfile(chan, front, args.lang)) ) {
1184 ast_log(LOG_WARNING, "ast_streamfile failed on %s for %s\n", ast_channel_name(chan), (char*)data);
1185 res = 0;
1186 mres = 1;
1187 break;
1188 }
1190 res = ast_waitstream(chan, "");
1192 res = ast_waitstream_exten(chan, args.context);
1193 } else {
1194 res = ast_waitstream(chan, AST_DIGIT_ANY);
1195 }
1196 ast_stopstream(chan);
1197 }
1198 }
1199
1200 /* If ast_waitstream didn't give us back a digit, there is nothing else to do */
1201 if (res <= 0) {
1202 goto done;
1203 }
1204
1205 exten[0] = res;
1206
1207 /*
1208 * If the single digit DTMF is an extension in the specified context, then
1209 * go there and signal no DTMF. Otherwise, we should exit with that DTMF.
1210 * We'll simply seek that extension in the calling context. Previously,
1211 * someone complained about the behavior as it related to the interior of a
1212 * Gosub routine, and the fix (#14011) inadvertently broke FreePBX
1213 * (#14940). This change should fix both of these situations, but with the
1214 * possible incompatibility that if a single digit extension does not exist
1215 * (but a longer extension COULD have matched), it would have previously
1216 * gone immediately to the "i" extension, but will now need to wait for a
1217 * timeout.
1218 *
1219 * Later, we had to add a flag to disable this workaround, because AGI
1220 * users can EXEC Background and reasonably expect that the DTMF code will
1221 * be returned (see #16434).
1222 */
1224 && ast_canmatch_extension(chan, args.context, exten, 1,
1225 S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))
1226 && !ast_matchmore_extension(chan, args.context, exten, 1,
1227 S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))) {
1228 char buf[2] = { 0, };
1229 snprintf(buf, sizeof(buf), "%c", res);
1231 ast_channel_context_set(chan, args.context);
1232 ast_channel_priority_set(chan, 0);
1233 res = 0;
1234 }
1235done:
1236 pbx_builtin_setvar_helper(chan, "BACKGROUNDSTATUS", mres ? "FAILED" : "SUCCESS");
1237 return res;
1238}
1239
1240static int pbx_builtin_noop(struct ast_channel *chan, const char *data)
1241{
1242 return 0;
1243}
1244
1245static int pbx_builtin_gotoif(struct ast_channel *chan, const char *data)
1246{
1247 char *condition, *branch1, *branch2, *branch;
1248 char *stringp;
1249
1250 if (ast_strlen_zero(data)) {
1251 ast_log(LOG_WARNING, "Ignoring, since there is no variable to check\n");
1252 return 0;
1253 }
1254
1255 stringp = ast_strdupa(data);
1256 condition = strsep(&stringp,"?");
1257 branch1 = strsep(&stringp,":");
1258 branch2 = strsep(&stringp,"");
1259 branch = pbx_checkcondition(condition) ? branch1 : branch2;
1260
1261 if (ast_strlen_zero(branch)) {
1262 ast_debug(1, "Not taking any branch\n");
1263 return 0;
1264 }
1265
1266 return pbx_builtin_goto(chan, branch);
1267}
1268
1269/*!
1270 * \brief Determine if DTMF interruption was requested.
1271 *
1272 * If the SAY_DTMF_INTERRUPT channel variable is truthy, the caller has
1273 * requested DTMF interruption be enabled.
1274 *
1275 * \param chan the channel to examine
1276 *
1277 * \retval -1 if DTMF interruption was requested
1278 * \retval 0 if DTMF interruption was not requested
1279 */
1280static int permit_dtmf_interrupt(struct ast_channel *chan)
1281{
1282 int interrupt;
1283
1284 ast_channel_lock(chan);
1285 interrupt = ast_true(pbx_builtin_getvar_helper(chan, "SAY_DTMF_INTERRUPT"));
1286 ast_channel_unlock(chan);
1287
1288 return interrupt;
1289}
1290
1291static int pbx_builtin_saynumber(struct ast_channel *chan, const char *data)
1292{
1293 char tmp[256];
1294 char *number = tmp;
1295 int number_val;
1296 char *options;
1297 int res;
1298 int interrupt = permit_dtmf_interrupt(chan);
1299
1300 if (ast_strlen_zero(data)) {
1301 ast_log(LOG_WARNING, "SayNumber requires an argument (number)\n");
1302 return -1;
1303 }
1304 ast_copy_string(tmp, data, sizeof(tmp));
1305 strsep(&number, ",");
1306
1307 if (ast_str_to_int(tmp, &number_val)) {
1308 ast_log(LOG_WARNING, "argument '%s' to SayNumber could not be parsed as a number.\n", tmp);
1309 return 0;
1310 }
1311
1312 options = strsep(&number, ",");
1313 if (options) {
1314 if ( strcasecmp(options, "f") && strcasecmp(options, "m") &&
1315 strcasecmp(options, "c") && strcasecmp(options, "n") ) {
1316 ast_log(LOG_WARNING, "SayNumber gender option is either 'f', 'm', 'c' or 'n'\n");
1317 return -1;
1318 }
1319 }
1320
1321 res = ast_say_number(chan, number_val, interrupt ? AST_DIGIT_ANY : "", ast_channel_language(chan), options);
1322
1323 if (res < 0 && !ast_check_hangup_locked(chan)) {
1324 ast_log(LOG_WARNING, "We were unable to say the number %s, is it too large?\n", tmp);
1325 }
1326
1327 return interrupt ? res : 0;
1328}
1329
1330static int pbx_builtin_sayordinal(struct ast_channel *chan, const char *data)
1331{
1332 char tmp[256];
1333 char *number = tmp;
1334 int number_val;
1335 char *options;
1336 int res;
1337 int interrupt = permit_dtmf_interrupt(chan);
1338
1339 if (ast_strlen_zero(data)) {
1340 ast_log(LOG_WARNING, "SayOrdinal requires an argument (number)\n");
1341 return -1;
1342 }
1343 ast_copy_string(tmp, data, sizeof(tmp));
1344 strsep(&number, ",");
1345
1346 if (ast_str_to_int(tmp, &number_val)) {
1347 ast_log(LOG_WARNING, "argument '%s' to SayOrdinal could not be parsed as a number.\n", tmp);
1348 return 0;
1349 }
1350
1351 options = strsep(&number, ",");
1352 if (options) {
1353 if ( strcasecmp(options, "f") && strcasecmp(options, "m") &&
1354 strcasecmp(options, "c") && strcasecmp(options, "n") ) {
1355 ast_log(LOG_WARNING, "SayOrdinal gender option is either 'f', 'm', 'c' or 'n'\n");
1356 return -1;
1357 }
1358 }
1359
1360 res = ast_say_ordinal(chan, number_val, interrupt ? AST_DIGIT_ANY : "", ast_channel_language(chan), options);
1361
1362 if (res < 0 && !ast_check_hangup_locked(chan)) {
1363 ast_log(LOG_WARNING, "We were unable to say the number %s, is it too large?\n", tmp);
1364 }
1365
1366 return interrupt ? res : 0;
1367}
1368
1369static int pbx_builtin_saydigits(struct ast_channel *chan, const char *data)
1370{
1371 int res = 0;
1372
1373 if (data) {
1374 res = ast_say_digit_str(chan, data, permit_dtmf_interrupt(chan) ? AST_DIGIT_ANY : "", ast_channel_language(chan));
1375 }
1376
1377 return res;
1378}
1379
1380static int pbx_builtin_saymoney(struct ast_channel *chan, const char *data)
1381{
1382 int res = 0;
1383
1384 if (data) {
1385 res = ast_say_money_str(chan, data, permit_dtmf_interrupt(chan) ? AST_DIGIT_ANY : "", ast_channel_language(chan));
1386 }
1387
1388 return res;
1389}
1390
1391static int pbx_builtin_saycharacters_case(struct ast_channel *chan, const char *data)
1392{
1393 int res = 0;
1394 int sensitivity = 0;
1395 char *parse;
1396
1399 AST_APP_ARG(characters);
1400 );
1401
1402 if (ast_strlen_zero(data)) {
1403 ast_log(LOG_WARNING, "SayAlphaCase requires two arguments (options, characters)\n");
1404 return 0;
1405 }
1406
1407 parse = ast_strdupa(data);
1409
1410 if (!args.options || strlen(args.options) != 1) {
1411 ast_log(LOG_WARNING, "SayAlphaCase options are mutually exclusive and required\n");
1412 return 0;
1413 }
1414
1415 switch (args.options[0]) {
1416 case 'a':
1417 sensitivity = AST_SAY_CASE_ALL;
1418 break;
1419 case 'l':
1420 sensitivity = AST_SAY_CASE_LOWER;
1421 break;
1422 case 'n':
1423 sensitivity = AST_SAY_CASE_NONE;
1424 break;
1425 case 'u':
1426 sensitivity = AST_SAY_CASE_UPPER;
1427 break;
1428 default:
1429 ast_log(LOG_WARNING, "Invalid option: '%s'\n", args.options);
1430 return 0;
1431 }
1432
1433 res = ast_say_character_str(chan, args.characters, permit_dtmf_interrupt(chan) ? AST_DIGIT_ANY : "", ast_channel_language(chan), sensitivity);
1434
1435 return res;
1436}
1437
1438static int pbx_builtin_saycharacters(struct ast_channel *chan, const char *data)
1439{
1440 int res = 0;
1441
1442 if (data) {
1444 }
1445
1446 return res;
1447}
1448
1449static int pbx_builtin_sayphonetic(struct ast_channel *chan, const char *data)
1450{
1451 int res = 0;
1452
1453 if (data) {
1455 }
1456
1457 return res;
1458}
1459
1460/*! \brief Declaration of builtin applications */
1463 int (*execute)(struct ast_channel *chan, const char *data);
1464} builtins[] =
1465{
1466 /* These applications are built into the PBX core and do not
1467 need separate modules */
1468
1469 { "Answer", pbx_builtin_answer },
1470 { "BackGround", pbx_builtin_background },
1471 { "Busy", indicate_busy },
1472 { "Congestion", indicate_congestion },
1473 { "ExecIfTime", pbx_builtin_execiftime },
1474 { "Goto", pbx_builtin_goto },
1475 { "GotoIf", pbx_builtin_gotoif },
1476 { "GotoIfTime", pbx_builtin_gotoiftime },
1477 { "Hangup", pbx_builtin_hangup },
1478 { "Incomplete", pbx_builtin_incomplete },
1479 { "NoOp", pbx_builtin_noop },
1480 { "Proceeding", pbx_builtin_proceeding },
1481 { "Progress", pbx_builtin_progress },
1482 { "RaiseException", pbx_builtin_raise_exception },
1483 { "Ringing", pbx_builtin_ringing },
1484 { "SayAlpha", pbx_builtin_saycharacters },
1485 { "SayAlphaCase", pbx_builtin_saycharacters_case },
1486 { "SayDigits", pbx_builtin_saydigits },
1487 { "SayMoney", pbx_builtin_saymoney },
1488 { "SayNumber", pbx_builtin_saynumber },
1489 { "SayOrdinal", pbx_builtin_sayordinal },
1490 { "SayPhonetic", pbx_builtin_sayphonetic },
1491 { "Wait", pbx_builtin_wait },
1492 { "WaitDigit", pbx_builtin_waitdigit },
1493 { "WaitExten", pbx_builtin_waitexten }
1495
1496static void unload_pbx_builtins(void)
1497{
1498 int x;
1499
1500 /* Unregister builtin applications */
1501 for (x = 0; x < ARRAY_LEN(builtins); x++) {
1503 }
1504}
1505
1507{
1508 int x;
1509
1510 /* Register builtin applications */
1511 for (x = 0; x < ARRAY_LEN(builtins); x++) {
1513 ast_log(LOG_ERROR, "Unable to register builtin application '%s'\n", builtins[x].name);
1514 return -1;
1515 }
1516 }
1517
1519
1520 return 0;
1521}
Prototypes for public functions only of internal interest,.
Asterisk main include file. File version handling, generic pbx functions.
int ast_register_cleanup(void(*func)(void))
Register a function to be executed before Asterisk gracefully exits.
Definition: clicompat.c:19
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
#define ast_log
Definition: astobj2.c:42
static int tmp()
Definition: bt_open.c:389
Internal Asterisk hangup causes.
#define AST_CAUSE_CONGESTION
Definition: causes.h:153
#define AST_CAUSE_BUSY
Definition: causes.h:149
#define AST_CAUSE_NORMAL_CLEARING
Definition: causes.h:106
static int answer(void *data)
Definition: chan_pjsip.c:687
void ast_channel_exten_set(struct ast_channel *chan, const char *value)
int ast_waitfordigit(struct ast_channel *c, int ms)
Waits for a digit.
Definition: channel.c:3194
int ast_str2cause(const char *name) attribute_pure
Convert the string form of a cause code to a number.
Definition: channel.c:625
const char * ast_channel_name(const struct ast_channel *chan)
int __ast_answer(struct ast_channel *chan, unsigned int delay)
Answer a channel, with a selectable delay before returning.
Definition: channel.c:2714
int ast_tonepair_start(struct ast_channel *chan, int freq1, int freq2, int duration, int vol)
Definition: channel.c:7604
#define ast_channel_lock(chan)
Definition: channel.h:2968
struct ast_flags * ast_channel_flags(struct ast_channel *chan)
int ast_channel_priority(const struct ast_channel *chan)
const char * ast_channel_context(const struct ast_channel *chan)
int ast_check_hangup_locked(struct ast_channel *chan)
Definition: channel.c:459
int ast_check_hangup(struct ast_channel *chan)
Check to see if a channel is needing hang up.
Definition: channel.c:445
int ast_channel_hangupcause(const struct ast_channel *chan)
int ast_indicate_data(struct ast_channel *chan, int condition, const void *data, size_t datalen)
Indicates condition of channel, with payload.
Definition: channel.c:4672
struct ast_tone_zone * ast_channel_zone(const struct ast_channel *chan)
void ast_set_hangupsource(struct ast_channel *chan, const char *source, int force)
Set the source of the hangup in this channel and it's bridge.
Definition: channel.c:2518
@ AST_SOFTHANGUP_EXPLICIT
Definition: channel.h:1168
const char * ast_channel_language(const struct ast_channel *chan)
void ast_channel_context_set(struct ast_channel *chan, const char *value)
int ast_softhangup_nolock(struct ast_channel *chan, int cause)
Softly hangup up a channel (no channel lock)
Definition: channel.c:2477
@ AST_FLAG_DISABLE_WORKAROUNDS
Definition: channel.h:1042
struct ast_pbx * ast_channel_pbx(const struct ast_channel *chan)
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
void ast_channel_priority_set(struct ast_channel *chan, int value)
void ast_channel_hangupcause_set(struct ast_channel *chan, int value)
int ast_answer(struct ast_channel *chan)
Answer a channel.
Definition: channel.c:2824
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
Definition: channel.c:4296
int ast_safe_sleep(struct ast_channel *chan, int ms)
Wait for a specified amount of time, looking for hangups.
Definition: channel.c:1593
const char * ast_channel_exten(const struct ast_channel *chan)
#define ast_channel_unlock(chan)
Definition: channel.h:2969
int ast_raw_answer(struct ast_channel *chan)
Answer a channel.
Definition: channel.c:2709
int ast_waitfordigit_full(struct ast_channel *c, int ms, const char *breakon, int audiofd, int ctrlfd)
Wait for a digit Same as ast_waitfordigit() with audio fd for outputting read audio and ctrlfd to mon...
Definition: channel.c:3258
ast_channel_state
ast_channel states
Definition: channelstate.h:35
@ AST_STATE_BUSY
Definition: channelstate.h:43
@ AST_STATE_UP
Definition: channelstate.h:42
int ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
Definition: channel.c:7408
Conversion utility functions.
int ast_str_to_int(const char *str, int *res)
Convert the given string to a signed integer.
Definition: conversions.c:44
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:222
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1293
int ast_waitstream_exten(struct ast_channel *c, const char *context)
Waits for a stream to stop or digit matching a valid one digit exten to be pressed.
Definition: file.c:1859
#define AST_DIGIT_ANY
Definition: file.h:48
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1840
static const char name[]
Definition: format_mp3.c:68
static SQLHSTMT execute(struct odbc_obj *obj, void *data, int silent)
Common execution function for SQL queries.
Definition: func_odbc.c:471
static int pbx_builtin_hangup(struct ast_channel *chan, const char *data)
Definition: pbx_builtins.c:849
int indicate_busy(struct ast_channel *chan, const char *data)
Definition: pbx_builtins.c:757
static int pbx_builtin_ringing(struct ast_channel *chan, const char *data)
Definition: pbx_builtins.c:748
static int pbx_builtin_waitexten(struct ast_channel *chan, const char *data)
static int pbx_builtin_answer(struct ast_channel *chan, const char *data)
Definition: pbx_builtins.c:793
static int pbx_builtin_proceeding(struct ast_channel *chan, const char *data)
Definition: pbx_builtins.c:730
static int pbx_builtin_wait(struct ast_channel *chan, const char *data)
Definition: pbx_builtins.c:996
static int pbx_builtin_background(struct ast_channel *chan, const char *data)
static int pbx_builtin_progress(struct ast_channel *chan, const char *data)
Definition: pbx_builtins.c:739
static int pbx_builtin_gotoiftime(struct ast_channel *chan, const char *data)
Definition: pbx_builtins.c:895
static int pbx_builtin_execiftime(struct ast_channel *chan, const char *data)
Definition: pbx_builtins.c:949
int indicate_congestion(struct ast_channel *chan, const char *data)
Definition: pbx_builtins.c:775
static int pbx_builtin_waitdigit(struct ast_channel *chan, const char *data)
static int pbx_builtin_goto(struct ast_channel *chan, const char *data)
Definition: pbx_builtins.c:884
Application convenience functions, designed to give consistent look and feel to Asterisk apps.
#define AST_APP_ARG(name)
Define an application argument.
int ast_app_parse_timelen(const char *timestr, int *result, enum ast_timelen defunit)
Common routine to parse time lengths, with optional time unit specifier.
Definition: main/app.c:3273
#define AST_APP_OPTIONS(holder, options...)
Declares an array of options for an application.
#define AST_APP_OPTION_ARG(option, flagno, argno)
Declares an application option that accepts an argument.
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the 'standard' argument separation process for an application.
@ TIMELEN_SECONDS
#define AST_APP_OPTION(option, flagno)
Declares an application option that does not accept an argument.
int ast_app_parse_options(const struct ast_app_option *options, struct ast_flags *flags, char **args, char *optstr)
Parses a string containing application options and sets flags/arguments.
Definition: main/app.c:3066
char * strsep(char **str, const char *delims)
@ AST_CONTROL_PROGRESS
@ AST_CONTROL_BUSY
@ AST_CONTROL_UNHOLD
@ AST_CONTROL_PROCEEDING
@ AST_CONTROL_CONGESTION
@ AST_CONTROL_RINGING
@ AST_CONTROL_HOLD
@ AST_CONTROL_INCOMPLETE
#define ast_debug(level,...)
Log a DEBUG message.
#define LOG_ERROR
#define ast_verb(level,...)
#define LOG_WARNING
Tone Indication Support.
static struct ast_tone_zone_sound * ast_tone_zone_sound_unref(struct ast_tone_zone_sound *ts)
Release a reference to an ast_tone_zone_sound.
Definition: indications.h:227
int ast_playtones_start(struct ast_channel *chan, int vol, const char *tonelist, int interruptible)
Start playing a list of tones on a channel.
Definition: indications.c:302
void ast_playtones_stop(struct ast_channel *chan)
Stop playing tones on a channel.
Definition: indications.c:393
struct ast_tone_zone_sound * ast_get_indication_tone(const struct ast_tone_zone *zone, const char *indication)
Locate a tone zone sound.
Definition: indications.c:461
Asterisk module definitions.
int ast_register_application2(const char *app, int(*execute)(struct ast_channel *, const char *), const char *synopsis, const char *description, void *mod)
Register an application.
Definition: pbx_app.c:103
int ast_unregister_application(const char *app)
Unregister an application.
Definition: pbx_app.c:392
void wait_for_hangup(struct ast_channel *chan, const void *data)
Definition: pbx.c:8228
int raise_exception(struct ast_channel *chan, const char *reason, int priority)
Definition: pbx.c:2806
void set_ext_pri(struct ast_channel *c, const char *exten, int pri)
Definition: pbx.c:4264
Core PBX routines and definitions.
int ast_build_timing(struct ast_timing *i, const char *info_in)
Construct a timing bitmap, for use in time-based conditionals.
Definition: extconf.c:3806
int ast_check_timing(const struct ast_timing *i)
Evaluate a pre-constructed bitmap as to whether the current time falls within the range specified.
Definition: extconf.c:4000
int ast_destroy_timing(struct ast_timing *i)
Deallocates memory structures associated with a timing bitmap.
Definition: pbx_timing.c:279
#define AST_MAX_APP
Definition: pbx.h:40
int ast_check_timing2(const struct ast_timing *i, const struct timeval tv)
Evaluate a pre-constructed bitmap as to whether a particular time falls within the range specified.
Definition: pbx_timing.c:245
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
Definition: pbx.c:4175
#define AST_PBX_INCOMPLETE
Definition: pbx.h:51
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name.
int ast_pbx_exec_application(struct ast_channel *chan, const char *app_name, const char *app_args)
Execute an application.
Definition: pbx_app.c:501
int ast_canmatch_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Looks for a valid matching extension.
Definition: pbx.c:4190
int ast_matchmore_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Looks to see if adding anything to this extension might match something. (exists ^ canmatch)
Definition: pbx.c:4195
int pbx_checkcondition(const char *condition)
Evaluate a condition.
Definition: pbx.c:8282
int ast_parseable_goto(struct ast_channel *chan, const char *goto_string)
Definition: pbx.c:8866
#define WAITEXTEN_MOH
Definition: pbx_builtins.c:713
static int pbx_builtin_incomplete(struct ast_channel *chan, const char *data)
Definition: pbx_builtins.c:824
#define BACKGROUND_NOANSWER
Definition: pbx_builtins.c:702
struct pbx_builtin builtins[]
static int pbx_builtin_gotoif(struct ast_channel *chan, const char *data)
#define WAITEXTEN_DIALTONE
Definition: pbx_builtins.c:714
static int pbx_builtin_noop(struct ast_channel *chan, const char *data)
static int pbx_builtin_saymoney(struct ast_channel *chan, const char *data)
static const struct ast_app_option waitexten_opts[128]
Definition: pbx_builtins.c:719
static int pbx_builtin_saydigits(struct ast_channel *chan, const char *data)
static void unload_pbx_builtins(void)
int load_pbx_builtins(void)
static int permit_dtmf_interrupt(struct ast_channel *chan)
Determine if DTMF interruption was requested.
int pbx_builtin_raise_exception(struct ast_channel *chan, const char *reason)
Definition: pbx_builtins.c:721
#define BACKGROUND_PLAYBACK
Definition: pbx_builtins.c:704
#define BACKGROUND_SKIP
Definition: pbx_builtins.c:701
#define BACKGROUND_MATCHEXTEN
Definition: pbx_builtins.c:703
static int pbx_builtin_sayordinal(struct ast_channel *chan, const char *data)
static const struct ast_app_option background_opts[128]
Definition: pbx_builtins.c:711
static int pbx_builtin_sayphonetic(struct ast_channel *chan, const char *data)
static int pbx_builtin_saycharacters(struct ast_channel *chan, const char *data)
static int pbx_builtin_saycharacters_case(struct ast_channel *chan, const char *data)
static int pbx_builtin_saynumber(struct ast_channel *chan, const char *data)
Private include file for pbx.
#define NULL
Definition: resample.c:96
Say numbers and dates (maybe words one day too)
int ast_say_money_str(struct ast_channel *chan, const char *num, const char *ints, const char *lang)
function to pronounce monetary amounts
Definition: channel.c:8287
int ast_say_phonetic_str(struct ast_channel *chan, const char *num, const char *ints, const char *lang)
Definition: channel.c:8299
int ast_say_ordinal(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says an ordinal number
Definition: channel.c:8263
int ast_say_character_str(struct ast_channel *chan, const char *num, const char *ints, const char *lang, enum ast_say_case_sensitivity sensitivity)
function to pronounce character and phonetic strings
Definition: channel.c:8293
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8257
@ AST_SAY_CASE_LOWER
Definition: say.h:183
@ AST_SAY_CASE_ALL
Definition: say.h:185
@ AST_SAY_CASE_UPPER
Definition: say.h:184
@ AST_SAY_CASE_NONE
Definition: say.h:182
int ast_say_digit_str(struct ast_channel *chan, const char *num, const char *ints, const char *lang)
says digits of a string
Definition: channel.c:8281
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
Definition: strings.h:80
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true"....
Definition: utils.c:2199
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:87
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
@ AST_STRSEP_TRIM
Definition: strings.h:256
@ AST_STRSEP_STRIP
Definition: strings.h:255
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
Definition: strings.h:223
char * ast_strsep(char **s, const char sep, uint32_t flags)
Act like strsep but ignore separators inside quotes.
Definition: utils.c:1835
Main Channel structure associated with a channel.
const char * data
char x
Definition: extconf.c:81
Structure used to handle boolean flags.
Definition: utils.h:199
unsigned int flags
Definition: utils.h:200
int rtimeoutms
Definition: pbx.h:216
Description of a tone.
Definition: indications.h:35
const char * data
Description of a tone.
Definition: indications.h:52
Number structure.
Definition: app_followme.c:154
Declaration of builtin applications.
int(* execute)(struct ast_channel *chan, const char *data)
char name[AST_MAX_APP]
int done
Definition: test_amihooks.c:48
const char * args
static struct test_options options
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159
char * usage
Definition: utils/frame.c:37
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define ARRAY_LEN(a)
Definition: utils.h:666