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