Asterisk - The Open Source Telephony Project GIT-master-0deac78
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 <since>
46 <version>13.8.0</version>
47 </since>
48 <synopsis>
49 Answer a channel if ringing.
50 </synopsis>
51 <syntax>
52 <parameter name="delay">
53 <para>Asterisk will wait this number of milliseconds before returning to
54 the dialplan after answering the call.</para>
55 <para>The minimum is 500 ms. To answer immediately without waiting for media,
56 use the i option.</para>
57 </parameter>
58 <parameter name="options">
59 <optionlist>
60 <option name="i">
61 <para>Answer the channel immediately without waiting for media.</para>
62 </option>
63 </optionlist>
64 </parameter>
65 </syntax>
66 <description>
67 <para>If the call has not been answered, this application will
68 answer it. Otherwise, it has no effect on the call.</para>
69 <para>By default, Asterisk will wait for media for up to 500 ms, or
70 the user specified delay, whichever is longer. If you do not want
71 to wait for media at all, use the i option.</para>
72 </description>
73 <see-also>
74 <ref type="application">Hangup</ref>
75 </see-also>
76 </application>
77 <application name="BackGround" language="en_US">
78 <since>
79 <version>13.8.0</version>
80 </since>
81 <synopsis>
82 Play an audio file while waiting for digits of an extension to go to.
83 </synopsis>
84 <syntax>
85 <parameter name="filenames" required="true" argsep="&amp;">
86 <para>Ampersand separated list of filenames. If the filename
87 is a relative filename (it does not begin with a slash), it
88 will be searched for in the Asterisk sounds directory. If the
89 filename is able to be parsed as a URL, Asterisk will
90 download the file and then begin playback on it. To include a
91 literal <literal>&amp;</literal> in the URL you can enclose
92 the URL in single quotes.</para>
93 <argument name="filename1" required="true" />
94 <argument name="filename2" multiple="true" />
95 </parameter>
96 <parameter name="options">
97 <optionlist>
98 <option name="s">
99 <para>Causes the playback of the message to be skipped
100 if the channel is not in the <literal>up</literal> state (i.e. it
101 hasn't been answered yet). If this happens, the
102 application will return immediately.</para>
103 </option>
104 <option name="n">
105 <para>Don't answer the channel before playing the files.</para>
106 </option>
107 <option name="m">
108 <para>Only break if a digit hit matches a one digit
109 extension in the destination context.</para>
110 </option>
111 <option name="p">
112 <para>Do not allow playback to be interrupted with digits.</para>
113 </option>
114 </optionlist>
115 </parameter>
116 <parameter name="langoverride">
117 <para>Explicitly specifies which language to attempt to use for the requested sound files.</para>
118 </parameter>
119 <parameter name="context">
120 <para>This is the dialplan context that this application will use when exiting
121 to a dialed extension.</para>
122 </parameter>
123 </syntax>
124 <description>
125 <para>This application will play the given list of files <emphasis>(do not put extension)</emphasis>
126 while waiting for an extension to be dialed by the calling channel. To continue waiting
127 for digits after this application has finished playing files, the <literal>WaitExten</literal>
128 application should be used.</para>
129 <para>If one of the requested sound files does not exist, call processing will be terminated.</para>
130 <para>This application sets the following channel variable upon completion:</para>
131 <variablelist>
132 <variable name="BACKGROUNDSTATUS">
133 <para>The status of the background attempt as a text string.</para>
134 <value name="SUCCESS" />
135 <value name="FAILED" />
136 </variable>
137 </variablelist>
138 </description>
139 <see-also>
140 <ref type="application">ControlPlayback</ref>
141 <ref type="application">WaitExten</ref>
142 <ref type="application">BackgroundDetect</ref>
143 <ref type="function">TIMEOUT</ref>
144 </see-also>
145 </application>
146 <application name="Busy" language="en_US">
147 <since>
148 <version>13.8.0</version>
149 </since>
150 <synopsis>
151 Indicate the Busy condition.
152 </synopsis>
153 <syntax>
154 <parameter name="timeout">
155 <para>If specified, the calling channel will be hung up after the specified number of seconds.
156 Otherwise, this application will wait until the calling channel hangs up.</para>
157 </parameter>
158 </syntax>
159 <description>
160 <para>This application will indicate the busy condition to the calling channel.</para>
161 </description>
162 <see-also>
163 <ref type="application">Congestion</ref>
164 <ref type="application">Progress</ref>
165 <ref type="application">PlayTones</ref>
166 <ref type="application">Hangup</ref>
167 </see-also>
168 </application>
169 <application name="Congestion" language="en_US">
170 <since>
171 <version>13.8.0</version>
172 </since>
173 <synopsis>
174 Indicate the Congestion condition.
175 </synopsis>
176 <syntax>
177 <parameter name="timeout">
178 <para>If specified, the calling channel will be hung up after the specified number of seconds.
179 Otherwise, this application will wait until the calling channel hangs up.</para>
180 </parameter>
181 </syntax>
182 <description>
183 <para>This application will indicate the congestion condition to the calling channel.</para>
184 </description>
185 <see-also>
186 <ref type="application">Busy</ref>
187 <ref type="application">Progress</ref>
188 <ref type="application">PlayTones</ref>
189 <ref type="application">Hangup</ref>
190 </see-also>
191 </application>
192 <application name="ExecIfTime" language="en_US">
193 <since>
194 <version>13.8.0</version>
195 </since>
196 <synopsis>
197 Conditional application execution based on the current time.
198 </synopsis>
199 <syntax argsep="?">
200 <parameter name="day_condition" required="true">
201 <argument name="times" required="true" />
202 <argument name="weekdays" required="true" />
203 <argument name="mdays" required="true" />
204 <argument name="months" required="true" />
205 <argument name="timezone" required="false" />
206 </parameter>
207 <parameter name="appname" required="true" hasparams="optional">
208 <argument name="appargs" required="true" />
209 </parameter>
210 </syntax>
211 <description>
212 <para>This application will execute the specified dialplan application, with optional
213 arguments, if the current time matches the given time specification.</para>
214 </description>
215 <see-also>
216 <ref type="application">Exec</ref>
217 <ref type="application">ExecIf</ref>
218 <ref type="application">TryExec</ref>
219 <ref type="application">GotoIfTime</ref>
220 </see-also>
221 </application>
222 <application name="Goto" language="en_US">
223 <since>
224 <version>13.8.0</version>
225 </since>
226 <synopsis>
227 Jump to a particular priority, extension, or context.
228 </synopsis>
229 <syntax>
230 <parameter name="context" documentationtype="dialplan_context" />
231 <parameter name="extension" documentationtype="dialplan_extension" />
232 <parameter name="priority" documentationtype="dialplan_priority" required="true" />
233 </syntax>
234 <description>
235 <para>This application will set the current context, extension, and priority in the channel structure.
236 After it completes, the pbx engine will continue dialplan execution at the specified location.
237 If no specific <replaceable>extension</replaceable>, or <replaceable>extension</replaceable> and
238 <replaceable>context</replaceable>, are specified, then this application will
239 just set the specified <replaceable>priority</replaceable> of the current extension.</para>
240 <para>At least a <replaceable>priority</replaceable> is required as an argument, or the goto will
241 return a <literal>-1</literal>, and the channel and call will be terminated.</para>
242 <para>If the location that is put into the channel information is bogus, and asterisk cannot
243 find that location in the dialplan, then the execution engine will try to find and execute the code in
244 the <literal>i</literal> (invalid) extension in the current context. If that does not exist, it will try to execute the
245 <literal>h</literal> extension. If neither the <literal>h</literal> nor <literal>i</literal> extensions
246 have been defined, the channel is hung up, and the execution of instructions on the channel is terminated.
247 What this means is that, for example, you specify a context that does not exist, then
248 it will not be possible to find the <literal>h</literal> or <literal>i</literal> extensions,
249 and the call will terminate!</para>
250 </description>
251 <see-also>
252 <ref type="application">GotoIf</ref>
253 <ref type="application">GotoIfTime</ref>
254 <ref type="application">Gosub</ref>
255 </see-also>
256 </application>
257 <application name="GotoIf" language="en_US">
258 <since>
259 <version>13.8.0</version>
260 </since>
261 <synopsis>
262 Conditional goto.
263 </synopsis>
264 <syntax argsep="?">
265 <parameter name="condition" required="true" />
266 <parameter name="destination" required="true" argsep=":">
267 <argument name="labeliftrue">
268 <para>Continue at <replaceable>labeliftrue</replaceable> if the condition is true.
269 Takes the form similar to Goto() of [[context,]extension,]priority.</para>
270 </argument>
271 <argument name="labeliffalse">
272 <para>Continue at <replaceable>labeliffalse</replaceable> if the condition is false.
273 Takes the form similar to Goto() of [[context,]extension,]priority.</para>
274 </argument>
275 </parameter>
276 </syntax>
277 <description>
278 <para>This application will set the current context, extension, and priority in the channel structure
279 based on the evaluation of the given condition. After this application completes, the
280 pbx engine will continue dialplan execution at the specified location in the dialplan.
281 The labels are specified with the same syntax as used within the Goto application.
282 If the label chosen by the condition is omitted, no jump is performed, and the execution passes to the
283 next instruction. If the target location is bogus, and does not exist, the execution engine will try
284 to find and execute the code in the <literal>i</literal> (invalid) extension in the current context.
285 If that does not exist, it will try to execute the <literal>h</literal> extension.
286 If neither the <literal>h</literal> nor <literal>i</literal> extensions have been defined,
287 the channel is hung up, and the execution of instructions on the channel is terminated.
288 Remember that this command can set the current context, and if the context specified
289 does not exist, then it will not be able to find any 'h' or 'i' extensions there, and
290 the channel and call will both be terminated!.</para>
291 </description>
292 <see-also>
293 <ref type="application">Goto</ref>
294 <ref type="application">GotoIfTime</ref>
295 <ref type="application">GosubIf</ref>
296 </see-also>
297 </application>
298 <application name="GotoIfTime" language="en_US">
299 <since>
300 <version>13.8.0</version>
301 </since>
302 <synopsis>
303 Conditional Goto based on the current time.
304 </synopsis>
305 <syntax argsep="?">
306 <parameter name="condition" required="true">
307 <argument name="times" required="true" />
308 <argument name="weekdays" required="true" />
309 <argument name="mdays" required="true" />
310 <argument name="months" required="true" />
311 <argument name="timezone" required="false" />
312 </parameter>
313 <parameter name="destination" required="true" argsep=":">
314 <argument name="labeliftrue">
315 <para>Continue at <replaceable>labeliftrue</replaceable> if the condition is true.
316 Takes the form similar to Goto() of [[context,]extension,]priority.</para>
317 </argument>
318 <argument name="labeliffalse">
319 <para>Continue at <replaceable>labeliffalse</replaceable> if the condition is false.
320 Takes the form similar to Goto() of [[context,]extension,]priority.</para>
321 </argument>
322 </parameter>
323 </syntax>
324 <description>
325 <para>This application will set the context, extension, and priority in the channel structure
326 based on the evaluation of the given time specification. After this application completes,
327 the pbx engine will continue dialplan execution at the specified location in the dialplan.
328 If the current time is within the given time specification, the channel will continue at
329 <replaceable>labeliftrue</replaceable>. Otherwise the channel will continue at <replaceable>labeliffalse</replaceable>.
330 If the label chosen by the condition is omitted, no jump is performed, and execution passes to the next
331 instruction. If the target jump location is bogus, the same actions would be taken as for <literal>Goto</literal>.
332 Further information on the time specification can be found in examples
333 illustrating how to do time-based context includes in the dialplan.</para>
334 </description>
335 <see-also>
336 <ref type="application">GotoIf</ref>
337 <ref type="application">Goto</ref>
338 <ref type="function">IFTIME</ref>
339 <ref type="function">TESTTIME</ref>
340 </see-also>
341 </application>
342 <application name="Hangup" language="en_US">
343 <since>
344 <version>13.8.0</version>
345 </since>
346 <synopsis>
347 Hang up the calling channel.
348 </synopsis>
349 <syntax>
350 <parameter name="causecode">
351 <para>If a <replaceable>causecode</replaceable> is given the channel's
352 hangup cause will be set to the given value.</para>
353 </parameter>
354 </syntax>
355 <description>
356 <para>This application will hang up the calling channel.</para>
357 </description>
358 <see-also>
359 <ref type="application">Answer</ref>
360 <ref type="application">Busy</ref>
361 <ref type="application">Congestion</ref>
362 </see-also>
363 </application>
364 <application name="Incomplete" language="en_US">
365 <since>
366 <version>13.8.0</version>
367 </since>
368 <synopsis>
369 Returns AST_PBX_INCOMPLETE value.
370 </synopsis>
371 <syntax>
372 <parameter name="n">
373 <para>If specified, then Incomplete will not attempt to answer the channel first.</para>
374 <note><para>Most channel types need to be in Answer state in order to receive DTMF.</para></note>
375 </parameter>
376 </syntax>
377 <description>
378 <para>Signals the PBX routines that the previous matched extension is incomplete
379 and that further input should be allowed before matching can be considered
380 to be complete. Can be used within a pattern match when certain criteria warrants
381 a longer match.</para>
382 </description>
383 </application>
384 <application name="NoOp" language="en_US">
385 <since>
386 <version>13.8.0</version>
387 </since>
388 <synopsis>
389 Do Nothing (No Operation).
390 </synopsis>
391 <syntax>
392 <parameter name="text">
393 <para>Any text provided can be viewed at the Asterisk CLI.</para>
394 </parameter>
395 </syntax>
396 <description>
397 <para>This application does nothing. However, it is useful for debugging purposes.</para>
398 <para>This method can be used to see the evaluations of variables or functions without having any effect.</para>
399 </description>
400 <see-also>
401 <ref type="application">Verbose</ref>
402 <ref type="application">Log</ref>
403 </see-also>
404 </application>
405 <application name="Proceeding" language="en_US">
406 <since>
407 <version>13.8.0</version>
408 </since>
409 <synopsis>
410 Indicate proceeding.
411 </synopsis>
412 <syntax />
413 <description>
414 <para>This application will request that a proceeding message be provided to the calling channel.</para>
415 </description>
416 </application>
417 <application name="Progress" language="en_US">
418 <since>
419 <version>13.8.0</version>
420 </since>
421 <synopsis>
422 Indicate progress.
423 </synopsis>
424 <syntax />
425 <description>
426 <para>This application will request that in-band progress information be provided to the calling channel.</para>
427 </description>
428 <see-also>
429 <ref type="application">Busy</ref>
430 <ref type="application">Congestion</ref>
431 <ref type="application">Ringing</ref>
432 <ref type="application">PlayTones</ref>
433 </see-also>
434 </application>
435 <application name="RaiseException" language="en_US">
436 <since>
437 <version>13.8.0</version>
438 </since>
439 <synopsis>
440 Handle an exceptional condition.
441 </synopsis>
442 <syntax>
443 <parameter name="reason" required="true" />
444 </syntax>
445 <description>
446 <para>This application will jump to the <literal>e</literal> extension in the current context, setting the
447 dialplan function EXCEPTION(). If the <literal>e</literal> extension does not exist, the call will hangup.</para>
448 </description>
449 <see-also>
450 <ref type="function">EXCEPTION</ref>
451 </see-also>
452 </application>
453 <application name="Ringing" language="en_US">
454 <since>
455 <version>13.8.0</version>
456 </since>
457 <synopsis>
458 Indicate ringing tone.
459 </synopsis>
460 <syntax />
461 <description>
462 <para>This application will request that the channel indicate a ringing tone to the user.</para>
463 </description>
464 <see-also>
465 <ref type="application">Busy</ref>
466 <ref type="application">Congestion</ref>
467 <ref type="application">Progress</ref>
468 <ref type="application">PlayTones</ref>
469 </see-also>
470 </application>
471 <application name="SayAlpha" language="en_US">
472 <since>
473 <version>13.8.0</version>
474 </since>
475 <synopsis>
476 Say Alpha.
477 </synopsis>
478 <syntax>
479 <parameter name="string" required="true" />
480 </syntax>
481 <description>
482 <para>This application will play the sounds that correspond to the letters
483 of the given <replaceable>string</replaceable>. If the channel variable
484 <variable>SAY_DTMF_INTERRUPT</variable> is set to 'true' (case insensitive),
485 then this application will react to DTMF in the same way as
486 <literal>BackGround</literal>.</para>
487 </description>
488 <see-also>
489 <ref type="application">SayDigits</ref>
490 <ref type="application">SayMoney</ref>
491 <ref type="application">SayNumber</ref>
492 <ref type="application">SayOrdinal</ref>
493 <ref type="application">SayPhonetic</ref>
494 <ref type="function">CHANNEL</ref>
495 <ref type="function">SAYFILES</ref>
496 </see-also>
497 </application>
498 <application name="SayAlphaCase" language="en_US">
499 <since>
500 <version>13.8.0</version>
501 </since>
502 <synopsis>
503 Say Alpha.
504 </synopsis>
505 <syntax>
506 <parameter name="casetype" required="true" >
507 <enumlist>
508 <enum name="a">
509 <para>Case sensitive (all) pronunciation.
510 (Ex: SayAlphaCase(a,aBc); - lowercase a uppercase b lowercase c).</para>
511 </enum>
512 <enum name="l">
513 <para>Case sensitive (lower) pronunciation.
514 (Ex: SayAlphaCase(l,aBc); - lowercase a b lowercase c).</para>
515 </enum>
516 <enum name="n">
517 <para>Case insensitive pronunciation. Equivalent to SayAlpha.
518 (Ex: SayAlphaCase(n,aBc) - a b c).</para>
519 </enum>
520 <enum name="u">
521 <para>Case sensitive (upper) pronunciation.
522 (Ex: SayAlphaCase(u,aBc); - a uppercase b c).</para>
523 </enum>
524 </enumlist>
525 </parameter>
526 <parameter name="string" required="true" />
527 </syntax>
528 <description>
529 <para>This application will play the sounds that correspond to the letters of the
530 given <replaceable>string</replaceable>. Optionally, a <replaceable>casetype</replaceable> may be
531 specified. This will be used for case-insensitive or case-sensitive pronunciations. If the channel
532 variable <variable>SAY_DTMF_INTERRUPT</variable> is set to 'true' (case insensitive), then this
533 application will react to DTMF in the same way as <literal>BackGround</literal>.</para>
534 </description>
535 <see-also>
536 <ref type="application">SayDigits</ref>
537 <ref type="application">SayMoney</ref>
538 <ref type="application">SayNumber</ref>
539 <ref type="application">SayOrdinal</ref>
540 <ref type="application">SayPhonetic</ref>
541 <ref type="application">SayAlpha</ref>
542 <ref type="function">CHANNEL</ref>
543 </see-also>
544 </application>
545 <application name="SayDigits" language="en_US">
546 <since>
547 <version>13.8.0</version>
548 </since>
549 <synopsis>
550 Say Digits.
551 </synopsis>
552 <syntax>
553 <parameter name="digits" required="true" />
554 </syntax>
555 <description>
556 <para>This application will play the sounds that correspond to the digits of
557 the given number. This will use the language that is currently set for the channel.
558 If the channel variable <variable>SAY_DTMF_INTERRUPT</variable> is set to 'true'
559 (case insensitive), then this application will react to DTMF in the same way as
560 <literal>BackGround</literal>.</para>
561 </description>
562 <see-also>
563 <ref type="application">SayAlpha</ref>
564 <ref type="application">SayMoney</ref>
565 <ref type="application">SayNumber</ref>
566 <ref type="application">SayOrdinal</ref>
567 <ref type="application">SayPhonetic</ref>
568 <ref type="function">CHANNEL</ref>
569 <ref type="function">SAYFILES</ref>
570 </see-also>
571 </application>
572 <application name="SayMoney" language="en_US">
573 <since>
574 <version>16.21.0</version>
575 <version>18.7.0</version>
576 </since>
577 <synopsis>
578 Say Money.
579 </synopsis>
580 <syntax>
581 <parameter name="dollars" required="true" />
582 </syntax>
583 <description>
584 <para>This application will play the currency sounds for the given floating point number
585 in the current language. Currently only English and US Dollars is supported.
586 If the channel variable <variable>SAY_DTMF_INTERRUPT</variable> is set to 'true'
587 (case insensitive), then this application will react to DTMF in the same way as
588 <literal>BackGround</literal>.</para>
589 </description>
590 <see-also>
591 <ref type="application">SayAlpha</ref>
592 <ref type="application">SayNumber</ref>
593 <ref type="application">SayOrdinal</ref>
594 <ref type="application">SayPhonetic</ref>
595 <ref type="function">CHANNEL</ref>
596 <ref type="function">SAYFILES</ref>
597 </see-also>
598 </application>
599 <application name="SayNumber" language="en_US">
600 <since>
601 <version>13.8.0</version>
602 </since>
603 <synopsis>
604 Say Number.
605 </synopsis>
606 <syntax>
607 <parameter name="digits" required="true" />
608 <parameter name="gender" />
609 </syntax>
610 <description>
611 <para>This application will play the sounds that correspond to the given
612 <replaceable>digits</replaceable>. Optionally, a <replaceable>gender</replaceable> may be
613 specified. This will use the language that is currently set for the channel. See the CHANNEL()
614 function for more information on setting the language for the channel. If the channel variable
615 <variable>SAY_DTMF_INTERRUPT</variable> is set to 'true' (case insensitive), then this
616 application will react to DTMF in the same way as <literal>BackGround</literal>.</para>
617 </description>
618 <see-also>
619 <ref type="application">SayAlpha</ref>
620 <ref type="application">SayDigits</ref>
621 <ref type="application">SayMoney</ref>
622 <ref type="application">SayPhonetic</ref>
623 <ref type="function">CHANNEL</ref>
624 <ref type="function">SAYFILES</ref>
625 </see-also>
626 </application>
627 <application name="SayOrdinal" language="en_US">
628 <since>
629 <version>16.21.0</version>
630 <version>18.7.0</version>
631 </since>
632 <synopsis>
633 Say Ordinal Number.
634 </synopsis>
635 <syntax>
636 <parameter name="digits" required="true" />
637 <parameter name="gender" />
638 </syntax>
639 <description>
640 <para>This application will play the ordinal sounds that correspond to the given
641 <replaceable>digits</replaceable> (e.g. 1st, 42nd). Currently only English is supported.</para>
642 <para>Optionally, a <replaceable>gender</replaceable> may be
643 specified. This will use the language that is currently set for the channel. See the CHANNEL()
644 function for more information on setting the language for the channel. If the channel variable
645 <variable>SAY_DTMF_INTERRUPT</variable> is set to 'true' (case insensitive), then this
646 application will react to DTMF in the same way as <literal>BackGround</literal>.</para>
647 </description>
648 <see-also>
649 <ref type="application">SayAlpha</ref>
650 <ref type="application">SayDigits</ref>
651 <ref type="application">SayMoney</ref>
652 <ref type="application">SayNumber</ref>
653 <ref type="application">SayPhonetic</ref>
654 <ref type="function">CHANNEL</ref>
655 <ref type="function">SAYFILES</ref>
656 </see-also>
657 </application>
658 <application name="SayPhonetic" language="en_US">
659 <since>
660 <version>13.8.0</version>
661 </since>
662 <synopsis>
663 Say Phonetic.
664 </synopsis>
665 <syntax>
666 <parameter name="string" required="true" />
667 </syntax>
668 <description>
669 <para>This application will play the sounds from the phonetic alphabet that correspond to the
670 letters in the given <replaceable>string</replaceable>. If the channel variable
671 <variable>SAY_DTMF_INTERRUPT</variable> is set to 'true' (case insensitive), then this
672 application will react to DTMF in the same way as <literal>BackGround</literal>.</para>
673 </description>
674 <see-also>
675 <ref type="application">SayAlpha</ref>
676 <ref type="application">SayDigits</ref>
677 <ref type="application">SayMoney</ref>
678 <ref type="application">SayNumber</ref>
679 <ref type="application">SayOrdinal</ref>
680 <ref type="function">SAYFILES</ref>
681 </see-also>
682 </application>
683 <application name="Wait" language="en_US">
684 <since>
685 <version>13.8.0</version>
686 </since>
687 <synopsis>
688 Waits for some time.
689 </synopsis>
690 <syntax>
691 <parameter name="seconds" required="true">
692 <para>Can be passed with fractions of a second. For example, <literal>1.5</literal> will ask the
693 application to wait for 1.5 seconds.</para>
694 </parameter>
695 </syntax>
696 <description>
697 <para>This application waits for a specified number of <replaceable>seconds</replaceable>.</para>
698 </description>
699 </application>
700 <application name="WaitDigit" language="en_US">
701 <since>
702 <version>15.0.0</version>
703 </since>
704 <synopsis>
705 Waits for a digit to be entered.
706 </synopsis>
707 <syntax>
708 <parameter name="seconds">
709 <para>Can be passed with fractions of a second. For example, <literal>1.5</literal> will ask the
710 application to wait for 1.5 seconds.</para>
711 </parameter>
712 <parameter name="digits">
713 <para>Digits to accept, all others are ignored.</para>
714 </parameter>
715 </syntax>
716 <description>
717 <para>This application waits for the user to press one of the accepted
718 <replaceable>digits</replaceable> for a specified number of
719 <replaceable>seconds</replaceable>.</para>
720 <variablelist>
721 <variable name="WAITDIGITSTATUS">
722 <para>This is the final status of the command</para>
723 <value name="ERROR">Parameters are invalid.</value>
724 <value name="DTMF">An accepted digit was received.</value>
725 <value name="TIMEOUT">The timeout passed before any acceptable digits were received.</value>
726 <value name="CANCEL">The channel has hungup or was redirected.</value>
727 </variable>
728 <variable name="WAITDIGITRESULT">
729 <para>The digit that was received, only set if
730 <variable>WAITDIGITSTATUS</variable> is <literal>DTMF</literal>.</para>
731 </variable>
732 </variablelist>
733 </description>
734 <see-also>
735 <ref type="application">Wait</ref>
736 <ref type="application">WaitExten</ref>
737 </see-also>
738 </application>
739 <application name="WaitExten" language="en_US">
740 <since>
741 <version>13.8.0</version>
742 </since>
743 <synopsis>
744 Waits for an extension to be entered.
745 </synopsis>
746 <syntax>
747 <parameter name="seconds">
748 <para>Can be passed with fractions of a second. For example, <literal>1.5</literal> will ask the
749 application to wait for 1.5 seconds.</para>
750 </parameter>
751 <parameter name="options">
752 <optionlist>
753 <option name="m">
754 <para>Provide music on hold to the caller while waiting for an extension.</para>
755 <argument name="x">
756 <para>Specify the class for music on hold. <emphasis>CHANNEL(musicclass) will
757 be used instead if set</emphasis></para>
758 </argument>
759 </option>
760 <option name="d">
761 <para>Play indications tone on channel while waiting for digits.</para>
762 <argument name="x">
763 <para>Specify the indications tone to play.
764 Default is <literal>dial</literal> tone.</para>
765 </argument>
766 </option>
767 </optionlist>
768 </parameter>
769 </syntax>
770 <description>
771 <para>This application waits for the user to enter a new extension for a specified number
772 of <replaceable>seconds</replaceable>.</para>
773 </description>
774 <see-also>
775 <ref type="application">BackGround</ref>
776 <ref type="function">TIMEOUT</ref>
777 </see-also>
778 </application>
779 ***/
780
781#define BACKGROUND_SKIP (1 << 0)
782#define BACKGROUND_NOANSWER (1 << 1)
783#define BACKGROUND_MATCHEXTEN (1 << 2)
784#define BACKGROUND_PLAYBACK (1 << 3)
785
791});
792
793enum {
794 WAITEXTEN_MOH = (1 << 0),
796};
797
801 /* note: this entry _MUST_ be the last one in the enum */
803};
804
808});
809
810int pbx_builtin_raise_exception(struct ast_channel *chan, const char *reason)
811{
812 /* Priority will become 1, next time through the AUTOLOOP */
813 return raise_exception(chan, reason, 0);
814}
815
816/*!
817 * \ingroup applications
818 */
819static int pbx_builtin_proceeding(struct ast_channel *chan, const char *data)
820{
822 return 0;
823}
824
825/*!
826 * \ingroup applications
827 */
828static int pbx_builtin_progress(struct ast_channel *chan, const char *data)
829{
831 return 0;
832}
833
834/*!
835 * \ingroup applications
836 */
837static int pbx_builtin_ringing(struct ast_channel *chan, const char *data)
838{
840 return 0;
841}
842
843/*!
844 * \ingroup applications
845 */
846int indicate_busy(struct ast_channel *chan, const char *data)
847{
849 /* Don't change state of an UP channel, just indicate
850 busy in audio */
851 ast_channel_lock(chan);
852 if (ast_channel_state(chan) != AST_STATE_UP) {
855 }
856 ast_channel_unlock(chan);
857 wait_for_hangup(chan, data);
858 return -1;
859}
860
861/*!
862 * \ingroup applications
863 */
864int indicate_congestion(struct ast_channel *chan, const char *data)
865{
867 /* Don't change state of an UP channel, just indicate
868 congestion in audio */
869 ast_channel_lock(chan);
870 if (ast_channel_state(chan) != AST_STATE_UP) {
873 }
874 ast_channel_unlock(chan);
875 wait_for_hangup(chan, data);
876 return -1;
877}
878
879/*!
880 * \ingroup applications
881 */
882static int pbx_builtin_answer(struct ast_channel *chan, const char *data)
883{
884 int delay = 0;
885 char *parse;
887 AST_APP_ARG(delay);
889 );
890
891 if (ast_strlen_zero(data)) {
892 return __ast_answer(chan, 0);
893 }
894
895 parse = ast_strdupa(data);
896
898
899 if (!ast_strlen_zero(args.delay) && (ast_channel_state(chan) != AST_STATE_UP))
900 delay = atoi(data);
901
902 if (delay < 0) {
903 delay = 0;
904 }
905
906 if (!ast_strlen_zero(args.options) && !strcmp(args.options, "i")) {
907 return ast_raw_answer(chan);
908 }
909
910 return __ast_answer(chan, delay);
911}
912
913static int pbx_builtin_incomplete(struct ast_channel *chan, const char *data)
914{
915 const char *options = data;
916 int answer = 1;
917
918 /* Some channels can receive DTMF in unanswered state; some cannot */
919 if (!ast_strlen_zero(options) && strchr(options, 'n')) {
920 answer = 0;
921 }
922
923 /* If the channel is hungup, stop waiting */
924 if (ast_check_hangup(chan)) {
925 return -1;
926 } else if (ast_channel_state(chan) != AST_STATE_UP && answer) {
927 __ast_answer(chan, 0);
928 }
929
931
932 return AST_PBX_INCOMPLETE;
933}
934
935/*!
936 * \ingroup applications
937 */
938static int pbx_builtin_hangup(struct ast_channel *chan, const char *data)
939{
940 int cause;
941
942 ast_set_hangupsource(chan, "dialplan/builtin", 0);
943
944 if (!ast_strlen_zero(data)) {
945 cause = ast_str2cause(data);
946 if (cause <= 0) {
947 if (sscanf(data, "%30d", &cause) != 1 || cause <= 0) {
948 ast_log(LOG_WARNING, "Invalid cause given to Hangup(): \"%s\"\n", data);
949 cause = 0;
950 }
951 }
952 } else {
953 cause = 0;
954 }
955
956 ast_channel_lock(chan);
957 if (cause <= 0) {
958 cause = ast_channel_hangupcause(chan);
959 if (cause <= 0) {
961 }
962 }
963 ast_channel_hangupcause_set(chan, cause);
965 ast_channel_unlock(chan);
966
967 return -1;
968}
969
970/*! Goto
971 * \ingroup applications
972 */
973static int pbx_builtin_goto(struct ast_channel *chan, const char *data)
974{
975 int res = ast_parseable_goto(chan, data);
976 if (!res)
977 ast_verb(3, "Goto (%s,%s,%d)\n", ast_channel_context(chan), ast_channel_exten(chan), ast_channel_priority(chan) + 1);
978 return res;
979}
980
981/*!
982 * \ingroup applications
983 */
984static int pbx_builtin_gotoiftime(struct ast_channel *chan, const char *data)
985{
986 char *s, *ts, *branch1, *branch2, *branch;
987 struct ast_timing timing;
988 const char *ctime;
989 struct timeval tv = ast_tvnow();
990 long timesecs;
991
992 if (!chan) {
993 ast_log(LOG_WARNING, "GotoIfTime requires a channel on which to operate\n");
994 return -1;
995 }
996
997 if (ast_strlen_zero(data)) {
998 ast_log(LOG_WARNING, "GotoIfTime requires an argument:\n <time range>,<days of week>,<days of month>,<months>[,<timezone>]?'labeliftrue':'labeliffalse'\n");
999 return -1;
1000 }
1001
1002 ts = s = ast_strdupa(data);
1003
1004 ast_channel_lock(chan);
1005 if ((ctime = pbx_builtin_getvar_helper(chan, "TESTTIME")) && sscanf(ctime, "%ld", &timesecs) == 1) {
1006 tv.tv_sec = timesecs;
1007 } else if (ctime) {
1008 ast_log(LOG_WARNING, "Using current time to evaluate\n");
1009 /* Reset when unparseable */
1010 pbx_builtin_setvar_helper(chan, "TESTTIME", NULL);
1011 }
1012 ast_channel_unlock(chan);
1013
1014 /* Separate the Goto path */
1015 strsep(&ts, "?");
1016 branch1 = strsep(&ts,":");
1017 branch2 = strsep(&ts,"");
1018
1019 /* struct ast_include include contained garbage here, fixed by zeroing it on get_timerange */
1020 if (ast_build_timing(&timing, s) && ast_check_timing2(&timing, tv)) {
1021 branch = branch1;
1022 } else {
1023 branch = branch2;
1024 }
1025 ast_destroy_timing(&timing);
1026
1027 if (ast_strlen_zero(branch)) {
1028 ast_debug(1, "Not taking any branch\n");
1029 return 0;
1030 }
1031
1032 return pbx_builtin_goto(chan, branch);
1033}
1034
1035/*!
1036 * \ingroup applications
1037 */
1038static int pbx_builtin_execiftime(struct ast_channel *chan, const char *data)
1039{
1040 char *s, *appname;
1041 struct ast_timing timing;
1042 static const char * const usage = "ExecIfTime requires an argument:\n <time range>,<days of week>,<days of month>,<months>[,<timezone>]?<appname>[(<appargs>)]";
1043
1044 if (ast_strlen_zero(data)) {
1045 ast_log(LOG_WARNING, "%s\n", usage);
1046 return -1;
1047 }
1048
1049 appname = ast_strdupa(data);
1050
1051 s = strsep(&appname, "?"); /* Separate the timerange and application name/data */
1052 if (!appname) { /* missing application */
1053 ast_log(LOG_WARNING, "%s\n", usage);
1054 return -1;
1055 }
1056
1057 if (!ast_build_timing(&timing, s)) {
1058 ast_log(LOG_WARNING, "Invalid Time Spec: %s\nCorrect usage: %s\n", s, usage);
1059 ast_destroy_timing(&timing);
1060 return -1;
1061 }
1062
1063 if (!ast_check_timing(&timing)) { /* outside the valid time window, just return */
1064 ast_destroy_timing(&timing);
1065 return 0;
1066 }
1067 ast_destroy_timing(&timing);
1068
1069 /* now split appname(appargs) */
1070 if ((s = strchr(appname, '('))) {
1071 char *e;
1072 *s++ = '\0';
1073 if ((e = strrchr(s, ')')))
1074 *e = '\0';
1075 else
1076 ast_log(LOG_WARNING, "Failed to find closing parenthesis\n");
1077 }
1078
1079 return ast_pbx_exec_application(chan, appname, S_OR(s, ""));
1080}
1081
1082/*!
1083 * \ingroup applications
1084 */
1085static int pbx_builtin_wait(struct ast_channel *chan, const char *data)
1086{
1087 int ms;
1088
1089 /* Wait for "n" seconds */
1090 if (!ast_app_parse_timelen(data, &ms, TIMELEN_SECONDS) && ms > 0) {
1091 return ast_safe_sleep(chan, ms);
1092 }
1093 return 0;
1094}
1095
1096/*!
1097 * \ingroup applications
1098 */
1099static int pbx_builtin_waitdigit(struct ast_channel *chan, const char *data)
1100{
1101 int res;
1102 int ms;
1103 char *parse;
1105 AST_APP_ARG(timeout);
1106 AST_APP_ARG(digits);
1107 );
1108
1109 parse = ast_strdupa(data);
1111
1112 if (ast_app_parse_timelen(args.timeout, &ms, TIMELEN_SECONDS) || ms < 0) {
1113 pbx_builtin_setvar_helper(chan, "WAITDIGITSTATUS", "ERROR");
1114 return 0;
1115 }
1116
1117 /* Wait for "n" seconds */
1118 res = ast_waitfordigit_full(chan, ms, S_OR(args.digits, AST_DIGIT_ANY), -1, -1);
1119 if (res < 0) {
1120 pbx_builtin_setvar_helper(chan, "WAITDIGITSTATUS", "CANCEL");
1121 return -1;
1122 }
1123
1124 if (res == 0) {
1125 pbx_builtin_setvar_helper(chan, "WAITDIGITSTATUS", "TIMEOUT");
1126 } else {
1127 char key[2];
1128
1129 snprintf(key, sizeof(key), "%c", res);
1130 pbx_builtin_setvar_helper(chan, "WAITDIGITRESULT", key);
1131 pbx_builtin_setvar_helper(chan, "WAITDIGITSTATUS", "DTMF");
1132 }
1133
1134 return 0;
1135}
1136
1137/*!
1138 * \ingroup applications
1139 */
1140static int pbx_builtin_waitexten(struct ast_channel *chan, const char *data)
1141{
1142 int ms, res;
1143 struct ast_flags flags = {0};
1144 char *opt_args[WAITEXTEN_ARRAY_SIZE];
1145 char *parse;
1147 AST_APP_ARG(timeout);
1149 );
1150
1151 if (!ast_strlen_zero(data)) {
1152 parse = ast_strdupa(data);
1154 } else
1155 memset(&args, 0, sizeof(args));
1156
1157 if (args.options)
1158 ast_app_parse_options(waitexten_opts, &flags, opt_args, args.options);
1159
1161 if (ast_strlen_zero(opt_args[WAITEXTEN_ARG_MOH])) {
1162 ast_log(LOG_WARNING, "The 'm' option has been specified for WaitExten without a class.\n");
1163 }
1165 !ast_strlen_zero(opt_args[WAITEXTEN_ARG_MOH]) ? strlen(opt_args[WAITEXTEN_ARG_MOH]) + 1 : 0);
1166 } else if (ast_test_flag(&flags, WAITEXTEN_DIALTONE)) {
1167 const char *tone = !ast_strlen_zero(opt_args[WAITEXTEN_ARG_DIALTONE]) ? opt_args[WAITEXTEN_ARG_DIALTONE] : "dial";
1169 if (ts) {
1170 ast_playtones_start(chan, 0, ts->data, 0);
1172 } else {
1173 ast_tonepair_start(chan, 350, 440, 0, 0);
1174 }
1175 }
1176 /* Wait for "n" seconds */
1177 if (!ast_app_parse_timelen(args.timeout, &ms, TIMELEN_SECONDS) && ms > 0) {
1178 /* Yay! */
1179 } else if (ast_channel_pbx(chan)) {
1180 ms = ast_channel_pbx(chan)->rtimeoutms;
1181 } else {
1182 ms = 10000;
1183 }
1184
1185 res = ast_waitfordigit(chan, ms);
1186 if (!res) {
1187 if (ast_check_hangup(chan)) {
1188 /* Call is hungup for some reason. */
1189 res = -1;
1190 } else if (ast_exists_extension(chan, ast_channel_context(chan), ast_channel_exten(chan), ast_channel_priority(chan) + 1,
1191 S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))) {
1192 ast_verb(3, "Timeout on %s, continuing...\n", ast_channel_name(chan));
1193 } else if (ast_exists_extension(chan, ast_channel_context(chan), "t", 1,
1194 S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))) {
1195 ast_verb(3, "Timeout on %s, going to 't'\n", ast_channel_name(chan));
1196 set_ext_pri(chan, "t", 0); /* 0 will become 1, next time through the loop */
1197 } else if (ast_exists_extension(chan, ast_channel_context(chan), "e", 1,
1198 S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))) {
1199 raise_exception(chan, "RESPONSETIMEOUT", 0); /* 0 will become 1, next time through the loop */
1200 } else {
1201 ast_log(LOG_WARNING, "Timeout but no rule 't' or 'e' in context '%s'\n",
1202 ast_channel_context(chan));
1203 res = -1;
1204 }
1205 }
1206
1207 if (ast_test_flag(&flags, WAITEXTEN_MOH))
1209 else if (ast_test_flag(&flags, WAITEXTEN_DIALTONE))
1210 ast_playtones_stop(chan);
1211
1212 return res;
1213}
1214
1215/*!
1216 * \ingroup applications
1217 */
1218static int pbx_builtin_background(struct ast_channel *chan, const char *data)
1219{
1220 int res = 0;
1221 int mres = 0;
1222 struct ast_flags flags = {0};
1223 char *parse, exten[2] = "";
1225 AST_APP_ARG(filename);
1227 AST_APP_ARG(lang);
1229 );
1230
1231 if (ast_strlen_zero(data)) {
1232 ast_log(LOG_WARNING, "Background requires an argument (filename)\n");
1233 return -1;
1234 }
1235
1236 parse = ast_strdupa(data);
1237
1239
1240 if (ast_strlen_zero(args.lang))
1241 args.lang = (char *)ast_channel_language(chan); /* XXX this is const */
1242
1243 if (ast_strlen_zero(args.context)) {
1244 ast_channel_lock(chan);
1245 args.context = ast_strdupa(ast_channel_context(chan));
1246 ast_channel_unlock(chan);
1247 }
1248
1249 if (args.options) {
1250 if (!strcasecmp(args.options, "skip"))
1251 flags.flags = BACKGROUND_SKIP;
1252 else if (!strcasecmp(args.options, "noanswer"))
1253 flags.flags = BACKGROUND_NOANSWER;
1254 else
1256 }
1257
1258 /* Answer if need be */
1259 if (ast_channel_state(chan) != AST_STATE_UP) {
1261 goto done;
1262 } else if (!ast_test_flag(&flags, BACKGROUND_NOANSWER)) {
1263 res = ast_answer(chan);
1264 }
1265 }
1266
1267 if (!res) {
1268 char *back = ast_strip(args.filename);
1269 char *front;
1270
1271 ast_stopstream(chan); /* Stop anything playing */
1272 /* Stream the list of files */
1273 while (!res && (front = ast_strsep(&back, '&', AST_STRSEP_STRIP | AST_STRSEP_TRIM))) {
1274 if ( (res = ast_streamfile(chan, front, args.lang)) ) {
1275 ast_log(LOG_WARNING, "ast_streamfile failed on %s for %s\n", ast_channel_name(chan), (char*)data);
1276 res = 0;
1277 mres = 1;
1278 break;
1279 }
1281 res = ast_waitstream(chan, "");
1283 res = ast_waitstream_exten(chan, args.context);
1284 } else {
1285 res = ast_waitstream(chan, AST_DIGIT_ANY);
1286 }
1287 ast_stopstream(chan);
1288 }
1289 }
1290
1291 /* If ast_waitstream didn't give us back a digit, there is nothing else to do */
1292 if (res <= 0) {
1293 goto done;
1294 }
1295
1296 exten[0] = res;
1297
1298 /*
1299 * If the single digit DTMF is an extension in the specified context, then
1300 * go there and signal no DTMF. Otherwise, we should exit with that DTMF.
1301 * We'll simply seek that extension in the calling context. Previously,
1302 * someone complained about the behavior as it related to the interior of a
1303 * Gosub routine, and the fix (#14011) inadvertently broke FreePBX
1304 * (#14940). This change should fix both of these situations, but with the
1305 * possible incompatibility that if a single digit extension does not exist
1306 * (but a longer extension COULD have matched), it would have previously
1307 * gone immediately to the "i" extension, but will now need to wait for a
1308 * timeout.
1309 *
1310 * Later, we had to add a flag to disable this workaround, because AGI
1311 * users can EXEC Background and reasonably expect that the DTMF code will
1312 * be returned (see #16434).
1313 */
1315 && ast_canmatch_extension(chan, args.context, exten, 1,
1316 S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))
1317 && !ast_matchmore_extension(chan, args.context, exten, 1,
1318 S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))) {
1319 char buf[2] = { 0, };
1320 snprintf(buf, sizeof(buf), "%c", res);
1322 ast_channel_context_set(chan, args.context);
1323 ast_channel_priority_set(chan, 0);
1324 res = 0;
1325 }
1326done:
1327 pbx_builtin_setvar_helper(chan, "BACKGROUNDSTATUS", mres ? "FAILED" : "SUCCESS");
1328 return res;
1329}
1330
1331static int pbx_builtin_noop(struct ast_channel *chan, const char *data)
1332{
1333 return 0;
1334}
1335
1336static int pbx_builtin_gotoif(struct ast_channel *chan, const char *data)
1337{
1338 char *condition, *branch1, *branch2, *branch;
1339 char *stringp;
1340
1341 if (ast_strlen_zero(data)) {
1342 ast_log(LOG_WARNING, "Ignoring, since there is no variable to check\n");
1343 return 0;
1344 }
1345
1346 stringp = ast_strdupa(data);
1347 condition = strsep(&stringp,"?");
1348 branch1 = strsep(&stringp,":");
1349 branch2 = strsep(&stringp,"");
1350 branch = pbx_checkcondition(condition) ? branch1 : branch2;
1351
1352 if (ast_strlen_zero(branch)) {
1353 ast_debug(1, "Not taking any branch\n");
1354 return 0;
1355 }
1356
1357 return pbx_builtin_goto(chan, branch);
1358}
1359
1360/*!
1361 * \brief Determine if DTMF interruption was requested.
1362 *
1363 * If the SAY_DTMF_INTERRUPT channel variable is truthy, the caller has
1364 * requested DTMF interruption be enabled.
1365 *
1366 * \param chan the channel to examine
1367 *
1368 * \retval -1 if DTMF interruption was requested
1369 * \retval 0 if DTMF interruption was not requested
1370 */
1371static int permit_dtmf_interrupt(struct ast_channel *chan)
1372{
1373 int interrupt;
1374
1375 ast_channel_lock(chan);
1376 interrupt = ast_true(pbx_builtin_getvar_helper(chan, "SAY_DTMF_INTERRUPT"));
1377 ast_channel_unlock(chan);
1378
1379 return interrupt;
1380}
1381
1382static int pbx_builtin_saynumber(struct ast_channel *chan, const char *data)
1383{
1384 char tmp[256];
1385 char *number = tmp;
1386 int number_val;
1387 char *options;
1388 int res;
1389 int interrupt = permit_dtmf_interrupt(chan);
1390
1391 if (ast_strlen_zero(data)) {
1392 ast_log(LOG_WARNING, "SayNumber requires an argument (number)\n");
1393 return -1;
1394 }
1395 ast_copy_string(tmp, data, sizeof(tmp));
1396 strsep(&number, ",");
1397
1398 if (ast_str_to_int(tmp, &number_val)) {
1399 ast_log(LOG_WARNING, "argument '%s' to SayNumber could not be parsed as a number.\n", tmp);
1400 return 0;
1401 }
1402
1403 options = strsep(&number, ",");
1404 if (options) {
1405 if ( strcasecmp(options, "f") && strcasecmp(options, "m") &&
1406 strcasecmp(options, "c") && strcasecmp(options, "n") ) {
1407 ast_log(LOG_WARNING, "SayNumber gender option is either 'f', 'm', 'c' or 'n'\n");
1408 return -1;
1409 }
1410 }
1411
1412 res = ast_say_number(chan, number_val, interrupt ? AST_DIGIT_ANY : "", ast_channel_language(chan), options);
1413
1414 if (res < 0 && !ast_check_hangup_locked(chan)) {
1415 ast_log(LOG_WARNING, "We were unable to say the number %s, is it too large?\n", tmp);
1416 }
1417
1418 return interrupt ? res : 0;
1419}
1420
1421static int pbx_builtin_sayordinal(struct ast_channel *chan, const char *data)
1422{
1423 char tmp[256];
1424 char *number = tmp;
1425 int number_val;
1426 char *options;
1427 int res;
1428 int interrupt = permit_dtmf_interrupt(chan);
1429
1430 if (ast_strlen_zero(data)) {
1431 ast_log(LOG_WARNING, "SayOrdinal requires an argument (number)\n");
1432 return -1;
1433 }
1434 ast_copy_string(tmp, data, sizeof(tmp));
1435 strsep(&number, ",");
1436
1437 if (ast_str_to_int(tmp, &number_val)) {
1438 ast_log(LOG_WARNING, "argument '%s' to SayOrdinal could not be parsed as a number.\n", tmp);
1439 return 0;
1440 }
1441
1442 options = strsep(&number, ",");
1443 if (options) {
1444 if ( strcasecmp(options, "f") && strcasecmp(options, "m") &&
1445 strcasecmp(options, "c") && strcasecmp(options, "n") ) {
1446 ast_log(LOG_WARNING, "SayOrdinal gender option is either 'f', 'm', 'c' or 'n'\n");
1447 return -1;
1448 }
1449 }
1450
1451 res = ast_say_ordinal(chan, number_val, interrupt ? AST_DIGIT_ANY : "", ast_channel_language(chan), options);
1452
1453 if (res < 0 && !ast_check_hangup_locked(chan)) {
1454 ast_log(LOG_WARNING, "We were unable to say the number %s, is it too large?\n", tmp);
1455 }
1456
1457 return interrupt ? res : 0;
1458}
1459
1460static int pbx_builtin_saydigits(struct ast_channel *chan, const char *data)
1461{
1462 int res = 0;
1463
1464 if (data) {
1465 res = ast_say_digit_str(chan, data, permit_dtmf_interrupt(chan) ? AST_DIGIT_ANY : "", ast_channel_language(chan));
1466 }
1467
1468 return res;
1469}
1470
1471static int pbx_builtin_saymoney(struct ast_channel *chan, const char *data)
1472{
1473 int res = 0;
1474
1475 if (data) {
1476 res = ast_say_money_str(chan, data, permit_dtmf_interrupt(chan) ? AST_DIGIT_ANY : "", ast_channel_language(chan));
1477 }
1478
1479 return res;
1480}
1481
1482static int pbx_builtin_saycharacters_case(struct ast_channel *chan, const char *data)
1483{
1484 int res = 0;
1485 int sensitivity = 0;
1486 char *parse;
1487
1490 AST_APP_ARG(characters);
1491 );
1492
1493 if (ast_strlen_zero(data)) {
1494 ast_log(LOG_WARNING, "SayAlphaCase requires two arguments (options, characters)\n");
1495 return 0;
1496 }
1497
1498 parse = ast_strdupa(data);
1500
1501 if (!args.options || strlen(args.options) != 1) {
1502 ast_log(LOG_WARNING, "SayAlphaCase options are mutually exclusive and required\n");
1503 return 0;
1504 }
1505
1506 switch (args.options[0]) {
1507 case 'a':
1508 sensitivity = AST_SAY_CASE_ALL;
1509 break;
1510 case 'l':
1511 sensitivity = AST_SAY_CASE_LOWER;
1512 break;
1513 case 'n':
1514 sensitivity = AST_SAY_CASE_NONE;
1515 break;
1516 case 'u':
1517 sensitivity = AST_SAY_CASE_UPPER;
1518 break;
1519 default:
1520 ast_log(LOG_WARNING, "Invalid option: '%s'\n", args.options);
1521 return 0;
1522 }
1523
1524 res = ast_say_character_str(chan, args.characters, permit_dtmf_interrupt(chan) ? AST_DIGIT_ANY : "", ast_channel_language(chan), sensitivity);
1525
1526 return res;
1527}
1528
1529static int pbx_builtin_saycharacters(struct ast_channel *chan, const char *data)
1530{
1531 int res = 0;
1532
1533 if (data) {
1535 }
1536
1537 return res;
1538}
1539
1540static int pbx_builtin_sayphonetic(struct ast_channel *chan, const char *data)
1541{
1542 int res = 0;
1543
1544 if (data) {
1546 }
1547
1548 return res;
1549}
1550
1551/*! \brief Declaration of builtin applications */
1554 int (*execute)(struct ast_channel *chan, const char *data);
1555} builtins[] =
1556{
1557 /* These applications are built into the PBX core and do not
1558 need separate modules */
1559
1560 { "Answer", pbx_builtin_answer },
1561 { "BackGround", pbx_builtin_background },
1562 { "Busy", indicate_busy },
1563 { "Congestion", indicate_congestion },
1564 { "ExecIfTime", pbx_builtin_execiftime },
1565 { "Goto", pbx_builtin_goto },
1566 { "GotoIf", pbx_builtin_gotoif },
1567 { "GotoIfTime", pbx_builtin_gotoiftime },
1568 { "Hangup", pbx_builtin_hangup },
1569 { "Incomplete", pbx_builtin_incomplete },
1570 { "NoOp", pbx_builtin_noop },
1571 { "Proceeding", pbx_builtin_proceeding },
1572 { "Progress", pbx_builtin_progress },
1573 { "RaiseException", pbx_builtin_raise_exception },
1574 { "Ringing", pbx_builtin_ringing },
1575 { "SayAlpha", pbx_builtin_saycharacters },
1576 { "SayAlphaCase", pbx_builtin_saycharacters_case },
1577 { "SayDigits", pbx_builtin_saydigits },
1578 { "SayMoney", pbx_builtin_saymoney },
1579 { "SayNumber", pbx_builtin_saynumber },
1580 { "SayOrdinal", pbx_builtin_sayordinal },
1581 { "SayPhonetic", pbx_builtin_sayphonetic },
1582 { "Wait", pbx_builtin_wait },
1583 { "WaitDigit", pbx_builtin_waitdigit },
1584 { "WaitExten", pbx_builtin_waitexten }
1586
1587static void unload_pbx_builtins(void)
1588{
1589 int x;
1590
1591 /* Unregister builtin applications */
1592 for (x = 0; x < ARRAY_LEN(builtins); x++) {
1594 }
1595}
1596
1598{
1599 int x;
1600
1601 /* Register builtin applications */
1602 for (x = 0; x < ARRAY_LEN(builtins); x++) {
1604 ast_log(LOG_ERROR, "Unable to register builtin application '%s'\n", builtins[x].name);
1605 return -1;
1606 }
1607 }
1608
1610
1611 return 0;
1612}
Prototypes for public functions only of internal interest,.
read_option_flags
Definition: app_mf.c:188
char * strsep(char **str, const char *delims)
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
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:3145
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:2666
int ast_tonepair_start(struct ast_channel *chan, int freq1, int freq2, int duration, int vol)
Definition: channel.c:7564
#define ast_channel_lock(chan)
Definition: channel.h:2972
struct ast_flags * ast_channel_flags(struct ast_channel *chan)
int ast_channel_priority(const struct ast_channel *chan)
@ AST_FLAG_DISABLE_WORKAROUNDS
Definition: channel.h:1042
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)
@ AST_SOFTHANGUP_EXPLICIT
Definition: channel.h:1168
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:4621
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:2469
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:2428
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:2776
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
Definition: channel.c:4243
int ast_safe_sleep(struct ast_channel *chan, int ms)
Wait for a specified amount of time, looking for hangups.
Definition: channel.c:1542
const char * ast_channel_exten(const struct ast_channel *chan)
#define ast_channel_unlock(chan)
Definition: channel.h:2973
int ast_raw_answer(struct ast_channel *chan)
Answer a channel.
Definition: channel.c:2661
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:3209
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:7368
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:223
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1312
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:1893
#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:1874
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:485
static int pbx_builtin_hangup(struct ast_channel *chan, const char *data)
Definition: pbx_builtins.c:938
int indicate_busy(struct ast_channel *chan, const char *data)
Definition: pbx_builtins.c:846
static int pbx_builtin_ringing(struct ast_channel *chan, const char *data)
Definition: pbx_builtins.c:837
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:882
static int pbx_builtin_proceeding(struct ast_channel *chan, const char *data)
Definition: pbx_builtins.c:819
static int pbx_builtin_wait(struct ast_channel *chan, const char *data)
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:828
static int pbx_builtin_gotoiftime(struct ast_channel *chan, const char *data)
Definition: pbx_builtins.c:984
static int pbx_builtin_execiftime(struct ast_channel *chan, const char *data)
int indicate_congestion(struct ast_channel *chan, const char *data)
Definition: pbx_builtins.c:864
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:973
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
@ 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:104
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:8253
int raise_exception(struct ast_channel *chan, const char *reason, int priority)
Definition: pbx.c:2821
void set_ext_pri(struct ast_channel *c, const char *exten, int pri)
Definition: pbx.c:4285
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:3804
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:3998
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:4196
#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:4211
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:4216
int pbx_checkcondition(const char *condition)
Evaluate a condition.
Definition: pbx.c:8307
int ast_parseable_goto(struct ast_channel *chan, const char *goto_string)
Definition: pbx.c:8891
@ WAITEXTEN_DIALTONE
Definition: pbx_builtins.c:795
@ WAITEXTEN_MOH
Definition: pbx_builtins.c:794
static int pbx_builtin_incomplete(struct ast_channel *chan, const char *data)
Definition: pbx_builtins.c:913
#define BACKGROUND_NOANSWER
Definition: pbx_builtins.c:782
struct pbx_builtin builtins[]
static int pbx_builtin_gotoif(struct ast_channel *chan, const char *data)
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:808
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:810
#define BACKGROUND_PLAYBACK
Definition: pbx_builtins.c:784
#define BACKGROUND_SKIP
Definition: pbx_builtins.c:781
#define BACKGROUND_MATCHEXTEN
Definition: pbx_builtins.c:783
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:791
static int pbx_builtin_sayphonetic(struct ast_channel *chan, const char *data)
static int pbx_builtin_saycharacters(struct ast_channel *chan, const char *data)
@ WAITEXTEN_ARG_DIALTONE
Definition: pbx_builtins.c:800
@ WAITEXTEN_ARRAY_SIZE
Definition: pbx_builtins.c:802
@ WAITEXTEN_ARG_MOH
Definition: pbx_builtins.c:799
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:8279
int ast_say_phonetic_str(struct ast_channel *chan, const char *num, const char *ints, const char *lang)
Definition: channel.c:8291
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:8255
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:8285
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:8249
@ 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:8273
#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:2235
#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:1871
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:217
unsigned int flags
Definition: utils.h:218
int rtimeoutms
Definition: pbx.h:217
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:157
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:703