Asterisk - The Open Source Telephony Project GIT-master-8924258
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros Modules Pages
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 <literal>dial</literal> indications tone on channel while waiting
762 for digits.</para>
763 </option>
764 </optionlist>
765 </parameter>
766 </syntax>
767 <description>
768 <para>This application waits for the user to enter a new extension for a specified number
769 of <replaceable>seconds</replaceable>.</para>
770 </description>
771 <see-also>
772 <ref type="application">BackGround</ref>
773 <ref type="function">TIMEOUT</ref>
774 </see-also>
775 </application>
776 ***/
777
778#define BACKGROUND_SKIP (1 << 0)
779#define BACKGROUND_NOANSWER (1 << 1)
780#define BACKGROUND_MATCHEXTEN (1 << 2)
781#define BACKGROUND_PLAYBACK (1 << 3)
782
788});
789
790#define WAITEXTEN_MOH (1 << 0)
791#define WAITEXTEN_DIALTONE (1 << 1)
792
796});
797
798int pbx_builtin_raise_exception(struct ast_channel *chan, const char *reason)
799{
800 /* Priority will become 1, next time through the AUTOLOOP */
801 return raise_exception(chan, reason, 0);
802}
803
804/*!
805 * \ingroup applications
806 */
807static int pbx_builtin_proceeding(struct ast_channel *chan, const char *data)
808{
810 return 0;
811}
812
813/*!
814 * \ingroup applications
815 */
816static int pbx_builtin_progress(struct ast_channel *chan, const char *data)
817{
819 return 0;
820}
821
822/*!
823 * \ingroup applications
824 */
825static int pbx_builtin_ringing(struct ast_channel *chan, const char *data)
826{
828 return 0;
829}
830
831/*!
832 * \ingroup applications
833 */
834int indicate_busy(struct ast_channel *chan, const char *data)
835{
837 /* Don't change state of an UP channel, just indicate
838 busy in audio */
839 ast_channel_lock(chan);
840 if (ast_channel_state(chan) != AST_STATE_UP) {
843 }
844 ast_channel_unlock(chan);
845 wait_for_hangup(chan, data);
846 return -1;
847}
848
849/*!
850 * \ingroup applications
851 */
852int indicate_congestion(struct ast_channel *chan, const char *data)
853{
855 /* Don't change state of an UP channel, just indicate
856 congestion in audio */
857 ast_channel_lock(chan);
858 if (ast_channel_state(chan) != AST_STATE_UP) {
861 }
862 ast_channel_unlock(chan);
863 wait_for_hangup(chan, data);
864 return -1;
865}
866
867/*!
868 * \ingroup applications
869 */
870static int pbx_builtin_answer(struct ast_channel *chan, const char *data)
871{
872 int delay = 0;
873 char *parse;
875 AST_APP_ARG(delay);
877 );
878
879 if (ast_strlen_zero(data)) {
880 return __ast_answer(chan, 0);
881 }
882
883 parse = ast_strdupa(data);
884
886
887 if (!ast_strlen_zero(args.delay) && (ast_channel_state(chan) != AST_STATE_UP))
888 delay = atoi(data);
889
890 if (delay < 0) {
891 delay = 0;
892 }
893
894 if (!ast_strlen_zero(args.options) && !strcmp(args.options, "i")) {
895 return ast_raw_answer(chan);
896 }
897
898 return __ast_answer(chan, delay);
899}
900
901static int pbx_builtin_incomplete(struct ast_channel *chan, const char *data)
902{
903 const char *options = data;
904 int answer = 1;
905
906 /* Some channels can receive DTMF in unanswered state; some cannot */
907 if (!ast_strlen_zero(options) && strchr(options, 'n')) {
908 answer = 0;
909 }
910
911 /* If the channel is hungup, stop waiting */
912 if (ast_check_hangup(chan)) {
913 return -1;
914 } else if (ast_channel_state(chan) != AST_STATE_UP && answer) {
915 __ast_answer(chan, 0);
916 }
917
919
920 return AST_PBX_INCOMPLETE;
921}
922
923/*!
924 * \ingroup applications
925 */
926static int pbx_builtin_hangup(struct ast_channel *chan, const char *data)
927{
928 int cause;
929
930 ast_set_hangupsource(chan, "dialplan/builtin", 0);
931
932 if (!ast_strlen_zero(data)) {
933 cause = ast_str2cause(data);
934 if (cause <= 0) {
935 if (sscanf(data, "%30d", &cause) != 1 || cause <= 0) {
936 ast_log(LOG_WARNING, "Invalid cause given to Hangup(): \"%s\"\n", data);
937 cause = 0;
938 }
939 }
940 } else {
941 cause = 0;
942 }
943
944 ast_channel_lock(chan);
945 if (cause <= 0) {
946 cause = ast_channel_hangupcause(chan);
947 if (cause <= 0) {
949 }
950 }
951 ast_channel_hangupcause_set(chan, cause);
953 ast_channel_unlock(chan);
954
955 return -1;
956}
957
958/*! Goto
959 * \ingroup applications
960 */
961static int pbx_builtin_goto(struct ast_channel *chan, const char *data)
962{
963 int res = ast_parseable_goto(chan, data);
964 if (!res)
965 ast_verb(3, "Goto (%s,%s,%d)\n", ast_channel_context(chan), ast_channel_exten(chan), ast_channel_priority(chan) + 1);
966 return res;
967}
968
969/*!
970 * \ingroup applications
971 */
972static int pbx_builtin_gotoiftime(struct ast_channel *chan, const char *data)
973{
974 char *s, *ts, *branch1, *branch2, *branch;
975 struct ast_timing timing;
976 const char *ctime;
977 struct timeval tv = ast_tvnow();
978 long timesecs;
979
980 if (!chan) {
981 ast_log(LOG_WARNING, "GotoIfTime requires a channel on which to operate\n");
982 return -1;
983 }
984
985 if (ast_strlen_zero(data)) {
986 ast_log(LOG_WARNING, "GotoIfTime requires an argument:\n <time range>,<days of week>,<days of month>,<months>[,<timezone>]?'labeliftrue':'labeliffalse'\n");
987 return -1;
988 }
989
990 ts = s = ast_strdupa(data);
991
992 ast_channel_lock(chan);
993 if ((ctime = pbx_builtin_getvar_helper(chan, "TESTTIME")) && sscanf(ctime, "%ld", &timesecs) == 1) {
994 tv.tv_sec = timesecs;
995 } else if (ctime) {
996 ast_log(LOG_WARNING, "Using current time to evaluate\n");
997 /* Reset when unparseable */
998 pbx_builtin_setvar_helper(chan, "TESTTIME", NULL);
999 }
1000 ast_channel_unlock(chan);
1001
1002 /* Separate the Goto path */
1003 strsep(&ts, "?");
1004 branch1 = strsep(&ts,":");
1005 branch2 = strsep(&ts,"");
1006
1007 /* struct ast_include include contained garbage here, fixed by zeroing it on get_timerange */
1008 if (ast_build_timing(&timing, s) && ast_check_timing2(&timing, tv)) {
1009 branch = branch1;
1010 } else {
1011 branch = branch2;
1012 }
1013 ast_destroy_timing(&timing);
1014
1015 if (ast_strlen_zero(branch)) {
1016 ast_debug(1, "Not taking any branch\n");
1017 return 0;
1018 }
1019
1020 return pbx_builtin_goto(chan, branch);
1021}
1022
1023/*!
1024 * \ingroup applications
1025 */
1026static int pbx_builtin_execiftime(struct ast_channel *chan, const char *data)
1027{
1028 char *s, *appname;
1029 struct ast_timing timing;
1030 static const char * const usage = "ExecIfTime requires an argument:\n <time range>,<days of week>,<days of month>,<months>[,<timezone>]?<appname>[(<appargs>)]";
1031
1032 if (ast_strlen_zero(data)) {
1033 ast_log(LOG_WARNING, "%s\n", usage);
1034 return -1;
1035 }
1036
1037 appname = ast_strdupa(data);
1038
1039 s = strsep(&appname, "?"); /* Separate the timerange and application name/data */
1040 if (!appname) { /* missing application */
1041 ast_log(LOG_WARNING, "%s\n", usage);
1042 return -1;
1043 }
1044
1045 if (!ast_build_timing(&timing, s)) {
1046 ast_log(LOG_WARNING, "Invalid Time Spec: %s\nCorrect usage: %s\n", s, usage);
1047 ast_destroy_timing(&timing);
1048 return -1;
1049 }
1050
1051 if (!ast_check_timing(&timing)) { /* outside the valid time window, just return */
1052 ast_destroy_timing(&timing);
1053 return 0;
1054 }
1055 ast_destroy_timing(&timing);
1056
1057 /* now split appname(appargs) */
1058 if ((s = strchr(appname, '('))) {
1059 char *e;
1060 *s++ = '\0';
1061 if ((e = strrchr(s, ')')))
1062 *e = '\0';
1063 else
1064 ast_log(LOG_WARNING, "Failed to find closing parenthesis\n");
1065 }
1066
1067 return ast_pbx_exec_application(chan, appname, S_OR(s, ""));
1068}
1069
1070/*!
1071 * \ingroup applications
1072 */
1073static int pbx_builtin_wait(struct ast_channel *chan, const char *data)
1074{
1075 int ms;
1076
1077 /* Wait for "n" seconds */
1078 if (!ast_app_parse_timelen(data, &ms, TIMELEN_SECONDS) && ms > 0) {
1079 return ast_safe_sleep(chan, ms);
1080 }
1081 return 0;
1082}
1083
1084/*!
1085 * \ingroup applications
1086 */
1087static int pbx_builtin_waitdigit(struct ast_channel *chan, const char *data)
1088{
1089 int res;
1090 int ms;
1091 char *parse;
1093 AST_APP_ARG(timeout);
1094 AST_APP_ARG(digits);
1095 );
1096
1097 parse = ast_strdupa(data);
1099
1100 if (ast_app_parse_timelen(args.timeout, &ms, TIMELEN_SECONDS) || ms < 0) {
1101 pbx_builtin_setvar_helper(chan, "WAITDIGITSTATUS", "ERROR");
1102 return 0;
1103 }
1104
1105 /* Wait for "n" seconds */
1106 res = ast_waitfordigit_full(chan, ms, S_OR(args.digits, AST_DIGIT_ANY), -1, -1);
1107 if (res < 0) {
1108 pbx_builtin_setvar_helper(chan, "WAITDIGITSTATUS", "CANCEL");
1109 return -1;
1110 }
1111
1112 if (res == 0) {
1113 pbx_builtin_setvar_helper(chan, "WAITDIGITSTATUS", "TIMEOUT");
1114 } else {
1115 char key[2];
1116
1117 snprintf(key, sizeof(key), "%c", res);
1118 pbx_builtin_setvar_helper(chan, "WAITDIGITRESULT", key);
1119 pbx_builtin_setvar_helper(chan, "WAITDIGITSTATUS", "DTMF");
1120 }
1121
1122 return 0;
1123}
1124
1125/*!
1126 * \ingroup applications
1127 */
1128static int pbx_builtin_waitexten(struct ast_channel *chan, const char *data)
1129{
1130 int ms, res;
1131 struct ast_flags flags = {0};
1132 char *opts[1] = { NULL };
1133 char *parse;
1135 AST_APP_ARG(timeout);
1137 );
1138
1139 if (!ast_strlen_zero(data)) {
1140 parse = ast_strdupa(data);
1142 } else
1143 memset(&args, 0, sizeof(args));
1144
1145 if (args.options)
1147
1148 if (ast_test_flag(&flags, WAITEXTEN_MOH) && !opts[0] ) {
1149 ast_log(LOG_WARNING, "The 'm' option has been specified for WaitExten without a class.\n");
1150 } else if (ast_test_flag(&flags, WAITEXTEN_MOH)) {
1152 !ast_strlen_zero(opts[0]) ? strlen(opts[0]) + 1 : 0);
1153 } else if (ast_test_flag(&flags, WAITEXTEN_DIALTONE)) {
1155 if (ts) {
1156 ast_playtones_start(chan, 0, ts->data, 0);
1158 } else {
1159 ast_tonepair_start(chan, 350, 440, 0, 0);
1160 }
1161 }
1162 /* Wait for "n" seconds */
1163 if (!ast_app_parse_timelen(args.timeout, &ms, TIMELEN_SECONDS) && ms > 0) {
1164 /* Yay! */
1165 } else if (ast_channel_pbx(chan)) {
1166 ms = ast_channel_pbx(chan)->rtimeoutms;
1167 } else {
1168 ms = 10000;
1169 }
1170
1171 res = ast_waitfordigit(chan, ms);
1172 if (!res) {
1173 if (ast_check_hangup(chan)) {
1174 /* Call is hungup for some reason. */
1175 res = -1;
1176 } else if (ast_exists_extension(chan, ast_channel_context(chan), ast_channel_exten(chan), ast_channel_priority(chan) + 1,
1177 S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))) {
1178 ast_verb(3, "Timeout on %s, continuing...\n", ast_channel_name(chan));
1179 } else if (ast_exists_extension(chan, ast_channel_context(chan), "t", 1,
1180 S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))) {
1181 ast_verb(3, "Timeout on %s, going to 't'\n", ast_channel_name(chan));
1182 set_ext_pri(chan, "t", 0); /* 0 will become 1, next time through the loop */
1183 } else if (ast_exists_extension(chan, ast_channel_context(chan), "e", 1,
1184 S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))) {
1185 raise_exception(chan, "RESPONSETIMEOUT", 0); /* 0 will become 1, next time through the loop */
1186 } else {
1187 ast_log(LOG_WARNING, "Timeout but no rule 't' or 'e' in context '%s'\n",
1188 ast_channel_context(chan));
1189 res = -1;
1190 }
1191 }
1192
1193 if (ast_test_flag(&flags, WAITEXTEN_MOH))
1195 else if (ast_test_flag(&flags, WAITEXTEN_DIALTONE))
1196 ast_playtones_stop(chan);
1197
1198 return res;
1199}
1200
1201/*!
1202 * \ingroup applications
1203 */
1204static int pbx_builtin_background(struct ast_channel *chan, const char *data)
1205{
1206 int res = 0;
1207 int mres = 0;
1208 struct ast_flags flags = {0};
1209 char *parse, exten[2] = "";
1211 AST_APP_ARG(filename);
1213 AST_APP_ARG(lang);
1215 );
1216
1217 if (ast_strlen_zero(data)) {
1218 ast_log(LOG_WARNING, "Background requires an argument (filename)\n");
1219 return -1;
1220 }
1221
1222 parse = ast_strdupa(data);
1223
1225
1226 if (ast_strlen_zero(args.lang))
1227 args.lang = (char *)ast_channel_language(chan); /* XXX this is const */
1228
1229 if (ast_strlen_zero(args.context)) {
1230 ast_channel_lock(chan);
1231 args.context = ast_strdupa(ast_channel_context(chan));
1232 ast_channel_unlock(chan);
1233 }
1234
1235 if (args.options) {
1236 if (!strcasecmp(args.options, "skip"))
1237 flags.flags = BACKGROUND_SKIP;
1238 else if (!strcasecmp(args.options, "noanswer"))
1239 flags.flags = BACKGROUND_NOANSWER;
1240 else
1242 }
1243
1244 /* Answer if need be */
1245 if (ast_channel_state(chan) != AST_STATE_UP) {
1247 goto done;
1248 } else if (!ast_test_flag(&flags, BACKGROUND_NOANSWER)) {
1249 res = ast_answer(chan);
1250 }
1251 }
1252
1253 if (!res) {
1254 char *back = ast_strip(args.filename);
1255 char *front;
1256
1257 ast_stopstream(chan); /* Stop anything playing */
1258 /* Stream the list of files */
1259 while (!res && (front = ast_strsep(&back, '&', AST_STRSEP_STRIP | AST_STRSEP_TRIM))) {
1260 if ( (res = ast_streamfile(chan, front, args.lang)) ) {
1261 ast_log(LOG_WARNING, "ast_streamfile failed on %s for %s\n", ast_channel_name(chan), (char*)data);
1262 res = 0;
1263 mres = 1;
1264 break;
1265 }
1267 res = ast_waitstream(chan, "");
1269 res = ast_waitstream_exten(chan, args.context);
1270 } else {
1271 res = ast_waitstream(chan, AST_DIGIT_ANY);
1272 }
1273 ast_stopstream(chan);
1274 }
1275 }
1276
1277 /* If ast_waitstream didn't give us back a digit, there is nothing else to do */
1278 if (res <= 0) {
1279 goto done;
1280 }
1281
1282 exten[0] = res;
1283
1284 /*
1285 * If the single digit DTMF is an extension in the specified context, then
1286 * go there and signal no DTMF. Otherwise, we should exit with that DTMF.
1287 * We'll simply seek that extension in the calling context. Previously,
1288 * someone complained about the behavior as it related to the interior of a
1289 * Gosub routine, and the fix (#14011) inadvertently broke FreePBX
1290 * (#14940). This change should fix both of these situations, but with the
1291 * possible incompatibility that if a single digit extension does not exist
1292 * (but a longer extension COULD have matched), it would have previously
1293 * gone immediately to the "i" extension, but will now need to wait for a
1294 * timeout.
1295 *
1296 * Later, we had to add a flag to disable this workaround, because AGI
1297 * users can EXEC Background and reasonably expect that the DTMF code will
1298 * be returned (see #16434).
1299 */
1301 && ast_canmatch_extension(chan, args.context, exten, 1,
1302 S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))
1303 && !ast_matchmore_extension(chan, args.context, exten, 1,
1304 S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))) {
1305 char buf[2] = { 0, };
1306 snprintf(buf, sizeof(buf), "%c", res);
1308 ast_channel_context_set(chan, args.context);
1309 ast_channel_priority_set(chan, 0);
1310 res = 0;
1311 }
1312done:
1313 pbx_builtin_setvar_helper(chan, "BACKGROUNDSTATUS", mres ? "FAILED" : "SUCCESS");
1314 return res;
1315}
1316
1317static int pbx_builtin_noop(struct ast_channel *chan, const char *data)
1318{
1319 return 0;
1320}
1321
1322static int pbx_builtin_gotoif(struct ast_channel *chan, const char *data)
1323{
1324 char *condition, *branch1, *branch2, *branch;
1325 char *stringp;
1326
1327 if (ast_strlen_zero(data)) {
1328 ast_log(LOG_WARNING, "Ignoring, since there is no variable to check\n");
1329 return 0;
1330 }
1331
1332 stringp = ast_strdupa(data);
1333 condition = strsep(&stringp,"?");
1334 branch1 = strsep(&stringp,":");
1335 branch2 = strsep(&stringp,"");
1336 branch = pbx_checkcondition(condition) ? branch1 : branch2;
1337
1338 if (ast_strlen_zero(branch)) {
1339 ast_debug(1, "Not taking any branch\n");
1340 return 0;
1341 }
1342
1343 return pbx_builtin_goto(chan, branch);
1344}
1345
1346/*!
1347 * \brief Determine if DTMF interruption was requested.
1348 *
1349 * If the SAY_DTMF_INTERRUPT channel variable is truthy, the caller has
1350 * requested DTMF interruption be enabled.
1351 *
1352 * \param chan the channel to examine
1353 *
1354 * \retval -1 if DTMF interruption was requested
1355 * \retval 0 if DTMF interruption was not requested
1356 */
1357static int permit_dtmf_interrupt(struct ast_channel *chan)
1358{
1359 int interrupt;
1360
1361 ast_channel_lock(chan);
1362 interrupt = ast_true(pbx_builtin_getvar_helper(chan, "SAY_DTMF_INTERRUPT"));
1363 ast_channel_unlock(chan);
1364
1365 return interrupt;
1366}
1367
1368static int pbx_builtin_saynumber(struct ast_channel *chan, const char *data)
1369{
1370 char tmp[256];
1371 char *number = tmp;
1372 int number_val;
1373 char *options;
1374 int res;
1375 int interrupt = permit_dtmf_interrupt(chan);
1376
1377 if (ast_strlen_zero(data)) {
1378 ast_log(LOG_WARNING, "SayNumber requires an argument (number)\n");
1379 return -1;
1380 }
1381 ast_copy_string(tmp, data, sizeof(tmp));
1382 strsep(&number, ",");
1383
1384 if (ast_str_to_int(tmp, &number_val)) {
1385 ast_log(LOG_WARNING, "argument '%s' to SayNumber could not be parsed as a number.\n", tmp);
1386 return 0;
1387 }
1388
1389 options = strsep(&number, ",");
1390 if (options) {
1391 if ( strcasecmp(options, "f") && strcasecmp(options, "m") &&
1392 strcasecmp(options, "c") && strcasecmp(options, "n") ) {
1393 ast_log(LOG_WARNING, "SayNumber gender option is either 'f', 'm', 'c' or 'n'\n");
1394 return -1;
1395 }
1396 }
1397
1398 res = ast_say_number(chan, number_val, interrupt ? AST_DIGIT_ANY : "", ast_channel_language(chan), options);
1399
1400 if (res < 0 && !ast_check_hangup_locked(chan)) {
1401 ast_log(LOG_WARNING, "We were unable to say the number %s, is it too large?\n", tmp);
1402 }
1403
1404 return interrupt ? res : 0;
1405}
1406
1407static int pbx_builtin_sayordinal(struct ast_channel *chan, const char *data)
1408{
1409 char tmp[256];
1410 char *number = tmp;
1411 int number_val;
1412 char *options;
1413 int res;
1414 int interrupt = permit_dtmf_interrupt(chan);
1415
1416 if (ast_strlen_zero(data)) {
1417 ast_log(LOG_WARNING, "SayOrdinal requires an argument (number)\n");
1418 return -1;
1419 }
1420 ast_copy_string(tmp, data, sizeof(tmp));
1421 strsep(&number, ",");
1422
1423 if (ast_str_to_int(tmp, &number_val)) {
1424 ast_log(LOG_WARNING, "argument '%s' to SayOrdinal could not be parsed as a number.\n", tmp);
1425 return 0;
1426 }
1427
1428 options = strsep(&number, ",");
1429 if (options) {
1430 if ( strcasecmp(options, "f") && strcasecmp(options, "m") &&
1431 strcasecmp(options, "c") && strcasecmp(options, "n") ) {
1432 ast_log(LOG_WARNING, "SayOrdinal gender option is either 'f', 'm', 'c' or 'n'\n");
1433 return -1;
1434 }
1435 }
1436
1437 res = ast_say_ordinal(chan, number_val, interrupt ? AST_DIGIT_ANY : "", ast_channel_language(chan), options);
1438
1439 if (res < 0 && !ast_check_hangup_locked(chan)) {
1440 ast_log(LOG_WARNING, "We were unable to say the number %s, is it too large?\n", tmp);
1441 }
1442
1443 return interrupt ? res : 0;
1444}
1445
1446static int pbx_builtin_saydigits(struct ast_channel *chan, const char *data)
1447{
1448 int res = 0;
1449
1450 if (data) {
1451 res = ast_say_digit_str(chan, data, permit_dtmf_interrupt(chan) ? AST_DIGIT_ANY : "", ast_channel_language(chan));
1452 }
1453
1454 return res;
1455}
1456
1457static int pbx_builtin_saymoney(struct ast_channel *chan, const char *data)
1458{
1459 int res = 0;
1460
1461 if (data) {
1462 res = ast_say_money_str(chan, data, permit_dtmf_interrupt(chan) ? AST_DIGIT_ANY : "", ast_channel_language(chan));
1463 }
1464
1465 return res;
1466}
1467
1468static int pbx_builtin_saycharacters_case(struct ast_channel *chan, const char *data)
1469{
1470 int res = 0;
1471 int sensitivity = 0;
1472 char *parse;
1473
1476 AST_APP_ARG(characters);
1477 );
1478
1479 if (ast_strlen_zero(data)) {
1480 ast_log(LOG_WARNING, "SayAlphaCase requires two arguments (options, characters)\n");
1481 return 0;
1482 }
1483
1484 parse = ast_strdupa(data);
1486
1487 if (!args.options || strlen(args.options) != 1) {
1488 ast_log(LOG_WARNING, "SayAlphaCase options are mutually exclusive and required\n");
1489 return 0;
1490 }
1491
1492 switch (args.options[0]) {
1493 case 'a':
1494 sensitivity = AST_SAY_CASE_ALL;
1495 break;
1496 case 'l':
1497 sensitivity = AST_SAY_CASE_LOWER;
1498 break;
1499 case 'n':
1500 sensitivity = AST_SAY_CASE_NONE;
1501 break;
1502 case 'u':
1503 sensitivity = AST_SAY_CASE_UPPER;
1504 break;
1505 default:
1506 ast_log(LOG_WARNING, "Invalid option: '%s'\n", args.options);
1507 return 0;
1508 }
1509
1510 res = ast_say_character_str(chan, args.characters, permit_dtmf_interrupt(chan) ? AST_DIGIT_ANY : "", ast_channel_language(chan), sensitivity);
1511
1512 return res;
1513}
1514
1515static int pbx_builtin_saycharacters(struct ast_channel *chan, const char *data)
1516{
1517 int res = 0;
1518
1519 if (data) {
1521 }
1522
1523 return res;
1524}
1525
1526static int pbx_builtin_sayphonetic(struct ast_channel *chan, const char *data)
1527{
1528 int res = 0;
1529
1530 if (data) {
1532 }
1533
1534 return res;
1535}
1536
1537/*! \brief Declaration of builtin applications */
1540 int (*execute)(struct ast_channel *chan, const char *data);
1541} builtins[] =
1542{
1543 /* These applications are built into the PBX core and do not
1544 need separate modules */
1545
1546 { "Answer", pbx_builtin_answer },
1547 { "BackGround", pbx_builtin_background },
1548 { "Busy", indicate_busy },
1549 { "Congestion", indicate_congestion },
1550 { "ExecIfTime", pbx_builtin_execiftime },
1551 { "Goto", pbx_builtin_goto },
1552 { "GotoIf", pbx_builtin_gotoif },
1553 { "GotoIfTime", pbx_builtin_gotoiftime },
1554 { "Hangup", pbx_builtin_hangup },
1555 { "Incomplete", pbx_builtin_incomplete },
1556 { "NoOp", pbx_builtin_noop },
1557 { "Proceeding", pbx_builtin_proceeding },
1558 { "Progress", pbx_builtin_progress },
1559 { "RaiseException", pbx_builtin_raise_exception },
1560 { "Ringing", pbx_builtin_ringing },
1561 { "SayAlpha", pbx_builtin_saycharacters },
1562 { "SayAlphaCase", pbx_builtin_saycharacters_case },
1563 { "SayDigits", pbx_builtin_saydigits },
1564 { "SayMoney", pbx_builtin_saymoney },
1565 { "SayNumber", pbx_builtin_saynumber },
1566 { "SayOrdinal", pbx_builtin_sayordinal },
1567 { "SayPhonetic", pbx_builtin_sayphonetic },
1568 { "Wait", pbx_builtin_wait },
1569 { "WaitDigit", pbx_builtin_waitdigit },
1570 { "WaitExten", pbx_builtin_waitexten }
1572
1573static void unload_pbx_builtins(void)
1574{
1575 int x;
1576
1577 /* Unregister builtin applications */
1578 for (x = 0; x < ARRAY_LEN(builtins); x++) {
1580 }
1581}
1582
1584{
1585 int x;
1586
1587 /* Register builtin applications */
1588 for (x = 0; x < ARRAY_LEN(builtins); x++) {
1590 ast_log(LOG_ERROR, "Unable to register builtin application '%s'\n", builtins[x].name);
1591 return -1;
1592 }
1593 }
1594
1596
1597 return 0;
1598}
Prototypes for public functions only of internal interest,.
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:3203
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:2724
int ast_tonepair_start(struct ast_channel *chan, int freq1, int freq2, int duration, int vol)
Definition: channel.c:7603
#define ast_channel_lock(chan)
Definition: channel.h:2970
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:4670
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:2528
@ AST_FLAG_DISABLE_WORKAROUNDS
Definition: channel.h:1042
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:2487
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:2834
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
Definition: channel.c:4294
int ast_safe_sleep(struct ast_channel *chan, int ms)
Wait for a specified amount of time, looking for hangups.
Definition: channel.c:1601
const char * ast_channel_exten(const struct ast_channel *chan)
#define ast_channel_unlock(chan)
Definition: channel.h:2971
int ast_raw_answer(struct ast_channel *chan)
Answer a channel.
Definition: channel.c:2719
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:3267
@ AST_SOFTHANGUP_EXPLICIT
Definition: channel.h:1168
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:7407
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:1301
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:1867
#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:1848
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:926
int indicate_busy(struct ast_channel *chan, const char *data)
Definition: pbx_builtins.c:834
static int pbx_builtin_ringing(struct ast_channel *chan, const char *data)
Definition: pbx_builtins.c:825
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:870
static int pbx_builtin_proceeding(struct ast_channel *chan, const char *data)
Definition: pbx_builtins.c:807
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:816
static int pbx_builtin_gotoiftime(struct ast_channel *chan, const char *data)
Definition: pbx_builtins.c:972
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:852
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:961
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:8243
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:4279
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:4190
#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:4205
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:4210
int pbx_checkcondition(const char *condition)
Evaluate a condition.
Definition: pbx.c:8297
int ast_parseable_goto(struct ast_channel *chan, const char *goto_string)
Definition: pbx.c:8881
#define WAITEXTEN_MOH
Definition: pbx_builtins.c:790
static int pbx_builtin_incomplete(struct ast_channel *chan, const char *data)
Definition: pbx_builtins.c:901
#define BACKGROUND_NOANSWER
Definition: pbx_builtins.c:779
struct pbx_builtin builtins[]
static int pbx_builtin_gotoif(struct ast_channel *chan, const char *data)
#define WAITEXTEN_DIALTONE
Definition: pbx_builtins.c:791
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:796
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:798
#define BACKGROUND_PLAYBACK
Definition: pbx_builtins.c:781
#define BACKGROUND_SKIP
Definition: pbx_builtins.c:778
#define BACKGROUND_MATCHEXTEN
Definition: pbx_builtins.c:780
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:788
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:8291
int ast_say_phonetic_str(struct ast_channel *chan, const char *num, const char *ints, const char *lang)
Definition: channel.c:8303
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:8267
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:8297
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:8261
@ 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:8285
#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: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:666