core: Add digit filtering to ast_waitfordigit_full
[asterisk/asterisk.git] / main / pbx_builtins.c
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"
35 #include "asterisk/indications.h"
36 #include "asterisk/stasis_channels.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">SayNumber</ref>
444                         <ref type="application">SayPhonetic</ref>
445                         <ref type="function">CHANNEL</ref>
446                 </see-also>
447         </application>
448         <application name="SayAlphaCase" language="en_US">
449                 <synopsis>
450                         Say Alpha.
451                 </synopsis>
452                 <syntax>
453                         <parameter name="casetype" required="true" >
454                                 <enumlist>
455                                         <enum name="a">
456                                                 <para>Case sensitive (all) pronunciation.
457                                                 (Ex: SayAlphaCase(a,aBc); - lowercase a uppercase b lowercase c).</para>
458                                         </enum>
459                                         <enum name="l">
460                                                 <para>Case sensitive (lower) pronunciation.
461                                                 (Ex: SayAlphaCase(l,aBc); - lowercase a b lowercase c).</para>
462                                         </enum>
463                                         <enum name="n">
464                                                 <para>Case insensitive pronunciation. Equivalent to SayAlpha.
465                                                 (Ex: SayAlphaCase(n,aBc) - a b c).</para>
466                                         </enum>
467                                         <enum name="u">
468                                                 <para>Case sensitive (upper) pronunciation.
469                                                 (Ex: SayAlphaCase(u,aBc); - a uppercase b c).</para>
470                                         </enum>
471                                 </enumlist>
472                         </parameter>
473                         <parameter name="string" required="true" />
474                 </syntax>
475                 <description>
476                         <para>This application will play the sounds that correspond to the letters of the
477                         given <replaceable>string</replaceable>.  Optionally, a <replaceable>casetype</replaceable> may be
478                         specified.  This will be used for case-insensitive or case-sensitive pronunciations. If the channel
479                         variable <variable>SAY_DTMF_INTERRUPT</variable> is set to 'true' (case insensitive), then this
480                         application will react to DTMF in the same way as <literal>Background</literal>.</para>
481                 </description>
482                 <see-also>
483                         <ref type="application">SayDigits</ref>
484                         <ref type="application">SayNumber</ref>
485                         <ref type="application">SayPhonetic</ref>
486                         <ref type="application">SayAlpha</ref>
487                         <ref type="function">CHANNEL</ref>
488                 </see-also>
489         </application>
490         <application name="SayDigits" language="en_US">
491                 <synopsis>
492                         Say Digits.
493                 </synopsis>
494                 <syntax>
495                         <parameter name="digits" required="true" />
496                 </syntax>
497                 <description>
498                         <para>This application will play the sounds that correspond to the digits of
499                         the given number. This will use the language that is currently set for the channel.
500                         If the channel variable <variable>SAY_DTMF_INTERRUPT</variable> is set to 'true'
501                         (case insensitive), then this application will react to DTMF in the same way as
502                         <literal>Background</literal>.</para>
503                 </description>
504                 <see-also>
505                         <ref type="application">SayAlpha</ref>
506                         <ref type="application">SayNumber</ref>
507                         <ref type="application">SayPhonetic</ref>
508                         <ref type="function">CHANNEL</ref>
509                 </see-also>
510         </application>
511         <application name="SayNumber" language="en_US">
512                 <synopsis>
513                         Say Number.
514                 </synopsis>
515                 <syntax>
516                         <parameter name="digits" required="true" />
517                         <parameter name="gender" />
518                 </syntax>
519                 <description>
520                         <para>This application will play the sounds that correspond to the given
521                         <replaceable>digits</replaceable>. Optionally, a <replaceable>gender</replaceable> may be
522                         specified. This will use the language that is currently set for the channel. See the CHANNEL()
523                         function for more information on setting the language for the channel. If the channel variable
524                         <variable>SAY_DTMF_INTERRUPT</variable> is set to 'true' (case insensitive), then this
525                         application will react to DTMF in the same way as <literal>Background</literal>.</para>
526                 </description>
527                 <see-also>
528                         <ref type="application">SayAlpha</ref>
529                         <ref type="application">SayDigits</ref>
530                         <ref type="application">SayPhonetic</ref>
531                         <ref type="function">CHANNEL</ref>
532                 </see-also>
533         </application>
534         <application name="SayPhonetic" language="en_US">
535                 <synopsis>
536                         Say Phonetic.
537                 </synopsis>
538                 <syntax>
539                         <parameter name="string" required="true" />
540                 </syntax>
541                 <description>
542                         <para>This application will play the sounds from the phonetic alphabet that correspond to the
543                         letters in the given <replaceable>string</replaceable>. If the channel variable
544                         <variable>SAY_DTMF_INTERRUPT</variable> is set to 'true' (case insensitive), then this
545                         application will react to DTMF in the same way as <literal>Background</literal>.</para>
546                 </description>
547                 <see-also>
548                         <ref type="application">SayAlpha</ref>
549                         <ref type="application">SayDigits</ref>
550                         <ref type="application">SayNumber</ref>
551                 </see-also>
552         </application>
553         <application name="SetAMAFlags" language="en_US">
554                 <synopsis>
555                         Set the AMA Flags.
556                 </synopsis>
557                 <syntax>
558                         <parameter name="flag" />
559                 </syntax>
560                 <description>
561                         <para>This application will set the channel's AMA Flags for billing purposes.</para>
562                         <warning><para>This application is deprecated. Please use the CHANNEL function instead.</para></warning>
563                 </description>
564                 <see-also>
565                         <ref type="function">CDR</ref>
566                         <ref type="function">CHANNEL</ref>
567                 </see-also>
568         </application>
569         <application name="Wait" language="en_US">
570                 <synopsis>
571                         Waits for some time.
572                 </synopsis>
573                 <syntax>
574                         <parameter name="seconds" required="true">
575                                 <para>Can be passed with fractions of a second. For example, <literal>1.5</literal> will ask the
576                                 application to wait for 1.5 seconds.</para>
577                         </parameter>
578                 </syntax>
579                 <description>
580                         <para>This application waits for a specified number of <replaceable>seconds</replaceable>.</para>
581                 </description>
582         </application>
583         <application name="WaitDigit" language="en_US">
584                 <synopsis>
585                         Waits for a digit to be entered.
586                 </synopsis>
587                 <syntax>
588                         <parameter name="seconds">
589                                 <para>Can be passed with fractions of a second. For example, <literal>1.5</literal> will ask the
590                                 application to wait for 1.5 seconds.</para>
591                         </parameter>
592                         <parameter name="digits">
593                                 <para>Digits to accept, all others are ignored.</para>
594                         </parameter>
595                 </syntax>
596                 <description>
597                         <para>This application waits for the user to press one of the accepted
598                         <replaceable>digits</replaceable> for a specified number of
599                         <replaceable>seconds</replaceable>.</para>
600                         <variablelist>
601                                 <variable name="WAITDIGITSTATUS">
602                                         <para>This is the final status of the command</para>
603                                         <value name="ERROR">Parameters are invalid.</value>
604                                         <value name="DTMF">An accepted digit was received.</value>
605                                         <value name="TIMEOUT">The timeout passed before any acceptable digits were received.</value>
606                                         <value name="CANCEL">The channel has hungup or was redirected.</value>
607                                 </variable>
608                                 <variable name="WAITDIGITRESULT">
609                                         <para>The digit that was received, only set if
610                                         <variable>WAITDIGITSTATUS</variable> is <literal>DTMF</literal>.</para>
611                                 </variable>
612                         </variablelist>
613                 </description>
614                 <see-also>
615                         <ref type="application">Wait</ref>
616                         <ref type="application">WaitExten</ref>
617                 </see-also>
618         </application>
619         <application name="WaitExten" language="en_US">
620                 <synopsis>
621                         Waits for an extension to be entered.
622                 </synopsis>
623                 <syntax>
624                         <parameter name="seconds">
625                                 <para>Can be passed with fractions of a second. For example, <literal>1.5</literal> will ask the
626                                 application to wait for 1.5 seconds.</para>
627                         </parameter>
628                         <parameter name="options">
629                                 <optionlist>
630                                         <option name="m">
631                                                 <para>Provide music on hold to the caller while waiting for an extension.</para>
632                                                 <argument name="x">
633                                                         <para>Specify the class for music on hold. <emphasis>CHANNEL(musicclass) will
634                                                         be used instead if set</emphasis></para>
635                                                 </argument>
636                                         </option>
637                                 </optionlist>
638                         </parameter>
639                 </syntax>
640                 <description>
641                         <para>This application waits for the user to enter a new extension for a specified number
642                         of <replaceable>seconds</replaceable>.</para>
643                         <xi:include xpointer="xpointer(/docs/application[@name='Macro']/description/warning[2])" />
644                 </description>
645                 <see-also>
646                         <ref type="application">Background</ref>
647                         <ref type="function">TIMEOUT</ref>
648                 </see-also>
649         </application>
650  ***/
651
652 #define BACKGROUND_SKIP         (1 << 0)
653 #define BACKGROUND_NOANSWER     (1 << 1)
654 #define BACKGROUND_MATCHEXTEN   (1 << 2)
655 #define BACKGROUND_PLAYBACK     (1 << 3)
656
657 AST_APP_OPTIONS(background_opts, {
658         AST_APP_OPTION('s', BACKGROUND_SKIP),
659         AST_APP_OPTION('n', BACKGROUND_NOANSWER),
660         AST_APP_OPTION('m', BACKGROUND_MATCHEXTEN),
661         AST_APP_OPTION('p', BACKGROUND_PLAYBACK),
662 });
663
664 #define WAITEXTEN_MOH           (1 << 0)
665 #define WAITEXTEN_DIALTONE      (1 << 1)
666
667 AST_APP_OPTIONS(waitexten_opts, {
668         AST_APP_OPTION_ARG('m', WAITEXTEN_MOH, 0),
669         AST_APP_OPTION_ARG('d', WAITEXTEN_DIALTONE, 0),
670 });
671
672 int pbx_builtin_raise_exception(struct ast_channel *chan, const char *reason)
673 {
674         /* Priority will become 1, next time through the AUTOLOOP */
675         return raise_exception(chan, reason, 0);
676 }
677
678 /*!
679  * \ingroup applications
680  */
681 static int pbx_builtin_proceeding(struct ast_channel *chan, const char *data)
682 {
683         ast_indicate(chan, AST_CONTROL_PROCEEDING);
684         return 0;
685 }
686
687 /*!
688  * \ingroup applications
689  */
690 static int pbx_builtin_progress(struct ast_channel *chan, const char *data)
691 {
692         ast_indicate(chan, AST_CONTROL_PROGRESS);
693         return 0;
694 }
695
696 /*!
697  * \ingroup applications
698  */
699 static int pbx_builtin_ringing(struct ast_channel *chan, const char *data)
700 {
701         ast_indicate(chan, AST_CONTROL_RINGING);
702         return 0;
703 }
704
705 /*!
706  * \ingroup applications
707  */
708 int indicate_busy(struct ast_channel *chan, const char *data)
709 {
710         ast_indicate(chan, AST_CONTROL_BUSY);
711         /* Don't change state of an UP channel, just indicate
712            busy in audio */
713         ast_channel_lock(chan);
714         if (ast_channel_state(chan) != AST_STATE_UP) {
715                 ast_channel_hangupcause_set(chan, AST_CAUSE_BUSY);
716                 ast_setstate(chan, AST_STATE_BUSY);
717         }
718         ast_channel_unlock(chan);
719         wait_for_hangup(chan, data);
720         return -1;
721 }
722
723 /*!
724  * \ingroup applications
725  */
726 int indicate_congestion(struct ast_channel *chan, const char *data)
727 {
728         ast_indicate(chan, AST_CONTROL_CONGESTION);
729         /* Don't change state of an UP channel, just indicate
730            congestion in audio */
731         ast_channel_lock(chan);
732         if (ast_channel_state(chan) != AST_STATE_UP) {
733                 ast_channel_hangupcause_set(chan, AST_CAUSE_CONGESTION);
734                 ast_setstate(chan, AST_STATE_BUSY);
735         }
736         ast_channel_unlock(chan);
737         wait_for_hangup(chan, data);
738         return -1;
739 }
740
741 /*!
742  * \ingroup applications
743  */
744 static int pbx_builtin_answer(struct ast_channel *chan, const char *data)
745 {
746         int delay = 0;
747         char *parse;
748         AST_DECLARE_APP_ARGS(args,
749                 AST_APP_ARG(delay);
750                 AST_APP_ARG(answer_cdr);
751         );
752
753         if (ast_strlen_zero(data)) {
754                 return __ast_answer(chan, 0);
755         }
756
757         parse = ast_strdupa(data);
758
759         AST_STANDARD_APP_ARGS(args, parse);
760
761         if (!ast_strlen_zero(args.delay) && (ast_channel_state(chan) != AST_STATE_UP))
762                 delay = atoi(data);
763
764         if (delay < 0) {
765                 delay = 0;
766         }
767
768         if (!ast_strlen_zero(args.answer_cdr) && !strcasecmp(args.answer_cdr, "nocdr")) {
769                 ast_log(AST_LOG_WARNING, "The nocdr option for the Answer application has been removed and is no longer supported.\n");
770         }
771
772         return __ast_answer(chan, delay);
773 }
774
775 static int pbx_builtin_incomplete(struct ast_channel *chan, const char *data)
776 {
777         const char *options = data;
778         int answer = 1;
779
780         /* Some channels can receive DTMF in unanswered state; some cannot */
781         if (!ast_strlen_zero(options) && strchr(options, 'n')) {
782                 answer = 0;
783         }
784
785         /* If the channel is hungup, stop waiting */
786         if (ast_check_hangup(chan)) {
787                 return -1;
788         } else if (ast_channel_state(chan) != AST_STATE_UP && answer) {
789                 __ast_answer(chan, 0);
790         }
791
792         ast_indicate(chan, AST_CONTROL_INCOMPLETE);
793
794         return AST_PBX_INCOMPLETE;
795 }
796
797 /*!
798  * \ingroup applications
799  */
800 static int pbx_builtin_setamaflags(struct ast_channel *chan, const char *data)
801 {
802         ast_log(AST_LOG_WARNING, "The SetAMAFlags application is deprecated. Please use the CHANNEL function instead.\n");
803
804         if (ast_strlen_zero(data)) {
805                 ast_log(AST_LOG_WARNING, "No parameter passed to SetAMAFlags\n");
806                 return 0;
807         }
808         /* Copy the AMA Flags as specified */
809         ast_channel_lock(chan);
810         if (isdigit(data[0])) {
811                 int amaflags;
812                 if (sscanf(data, "%30d", &amaflags) != 1) {
813                         ast_log(AST_LOG_WARNING, "Unable to set AMA flags on channel %s\n", ast_channel_name(chan));
814                         ast_channel_unlock(chan);
815                         return 0;
816                 }
817                 ast_channel_amaflags_set(chan, amaflags);
818         } else {
819                 ast_channel_amaflags_set(chan, ast_channel_string2amaflag(data));
820         }
821         ast_channel_unlock(chan);
822         return 0;
823 }
824
825 /*!
826  * \ingroup applications
827  */
828 static int pbx_builtin_hangup(struct ast_channel *chan, const char *data)
829 {
830         int cause;
831
832         ast_set_hangupsource(chan, "dialplan/builtin", 0);
833
834         if (!ast_strlen_zero(data)) {
835                 cause = ast_str2cause(data);
836                 if (cause <= 0) {
837                         if (sscanf(data, "%30d", &cause) != 1 || cause <= 0) {
838                                 ast_log(LOG_WARNING, "Invalid cause given to Hangup(): \"%s\"\n", data);
839                                 cause = 0;
840                         }
841                 }
842         } else {
843                 cause = 0;
844         }
845
846         ast_channel_lock(chan);
847         if (cause <= 0) {
848                 cause = ast_channel_hangupcause(chan);
849                 if (cause <= 0) {
850                         cause = AST_CAUSE_NORMAL_CLEARING;
851                 }
852         }
853         ast_channel_hangupcause_set(chan, cause);
854         ast_softhangup_nolock(chan, AST_SOFTHANGUP_EXPLICIT);
855         ast_channel_unlock(chan);
856
857         return -1;
858 }
859
860 /*! Goto
861  * \ingroup applications
862  */
863 static int pbx_builtin_goto(struct ast_channel *chan, const char *data)
864 {
865         int res = ast_parseable_goto(chan, data);
866         if (!res)
867                 ast_verb(3, "Goto (%s,%s,%d)\n", ast_channel_context(chan), ast_channel_exten(chan), ast_channel_priority(chan) + 1);
868         return res;
869 }
870
871 /*!
872  * \ingroup applications
873  */
874 static int pbx_builtin_gotoiftime(struct ast_channel *chan, const char *data)
875 {
876         char *s, *ts, *branch1, *branch2, *branch;
877         struct ast_timing timing;
878         const char *ctime;
879         struct timeval tv = ast_tvnow();
880         long timesecs;
881
882         if (!chan) {
883                 ast_log(LOG_WARNING, "GotoIfTime requires a channel on which to operate\n");
884                 return -1;
885         }
886
887         if (ast_strlen_zero(data)) {
888                 ast_log(LOG_WARNING, "GotoIfTime requires an argument:\n  <time range>,<days of week>,<days of month>,<months>[,<timezone>]?'labeliftrue':'labeliffalse'\n");
889                 return -1;
890         }
891
892         ts = s = ast_strdupa(data);
893
894         ast_channel_lock(chan);
895         if ((ctime = pbx_builtin_getvar_helper(chan, "TESTTIME")) && sscanf(ctime, "%ld", &timesecs) == 1) {
896                 tv.tv_sec = timesecs;
897         } else if (ctime) {
898                 ast_log(LOG_WARNING, "Using current time to evaluate\n");
899                 /* Reset when unparseable */
900                 pbx_builtin_setvar_helper(chan, "TESTTIME", NULL);
901         }
902         ast_channel_unlock(chan);
903
904         /* Separate the Goto path */
905         strsep(&ts, "?");
906         branch1 = strsep(&ts,":");
907         branch2 = strsep(&ts,"");
908
909         /* struct ast_include include contained garbage here, fixed by zeroing it on get_timerange */
910         if (ast_build_timing(&timing, s) && ast_check_timing2(&timing, tv)) {
911                 branch = branch1;
912         } else {
913                 branch = branch2;
914         }
915         ast_destroy_timing(&timing);
916
917         if (ast_strlen_zero(branch)) {
918                 ast_debug(1, "Not taking any branch\n");
919                 return 0;
920         }
921
922         return pbx_builtin_goto(chan, branch);
923 }
924
925 /*!
926  * \ingroup applications
927  */
928 static int pbx_builtin_execiftime(struct ast_channel *chan, const char *data)
929 {
930         char *s, *appname;
931         struct ast_timing timing;
932         struct ast_app *app;
933         static const char * const usage = "ExecIfTime requires an argument:\n  <time range>,<days of week>,<days of month>,<months>[,<timezone>]?<appname>[(<appargs>)]";
934
935         if (ast_strlen_zero(data)) {
936                 ast_log(LOG_WARNING, "%s\n", usage);
937                 return -1;
938         }
939
940         appname = ast_strdupa(data);
941
942         s = strsep(&appname, "?");      /* Separate the timerange and application name/data */
943         if (!appname) { /* missing application */
944                 ast_log(LOG_WARNING, "%s\n", usage);
945                 return -1;
946         }
947
948         if (!ast_build_timing(&timing, s)) {
949                 ast_log(LOG_WARNING, "Invalid Time Spec: %s\nCorrect usage: %s\n", s, usage);
950                 ast_destroy_timing(&timing);
951                 return -1;
952         }
953
954         if (!ast_check_timing(&timing)) { /* outside the valid time window, just return */
955                 ast_destroy_timing(&timing);
956                 return 0;
957         }
958         ast_destroy_timing(&timing);
959
960         /* now split appname(appargs) */
961         if ((s = strchr(appname, '('))) {
962                 char *e;
963                 *s++ = '\0';
964                 if ((e = strrchr(s, ')')))
965                         *e = '\0';
966                 else
967                         ast_log(LOG_WARNING, "Failed to find closing parenthesis\n");
968         }
969
970
971         if ((app = pbx_findapp(appname))) {
972                 return pbx_exec(chan, app, S_OR(s, ""));
973         } else {
974                 ast_log(LOG_WARNING, "Cannot locate application %s\n", appname);
975                 return -1;
976         }
977 }
978
979 /*!
980  * \ingroup applications
981  */
982 static int pbx_builtin_wait(struct ast_channel *chan, const char *data)
983 {
984         int ms;
985
986         /* Wait for "n" seconds */
987         if (!ast_app_parse_timelen(data, &ms, TIMELEN_SECONDS) && ms > 0) {
988                 return ast_safe_sleep(chan, ms);
989         }
990         return 0;
991 }
992
993 /*!
994  * \ingroup applications
995  */
996 static int pbx_builtin_waitdigit(struct ast_channel *chan, const char *data)
997 {
998         int res;
999         int ms;
1000         char *parse;
1001         AST_DECLARE_APP_ARGS(args,
1002                 AST_APP_ARG(timeout);
1003                 AST_APP_ARG(digits);
1004         );
1005
1006         parse = ast_strdupa(data);
1007         AST_STANDARD_APP_ARGS(args, parse);
1008
1009         if (ast_app_parse_timelen(args.timeout, &ms, TIMELEN_SECONDS) || ms < 0) {
1010                 pbx_builtin_setvar_helper(chan, "WAITDIGITSTATUS", "ERROR");
1011                 return 0;
1012         }
1013
1014         /* Wait for "n" seconds */
1015         res = ast_waitfordigit_full(chan, ms, S_OR(args.digits, AST_DIGIT_ANY), -1, -1);
1016         if (res < 0) {
1017                 pbx_builtin_setvar_helper(chan, "WAITDIGITSTATUS", "CANCEL");
1018                 return -1;
1019         }
1020
1021         if (res == 0) {
1022                 pbx_builtin_setvar_helper(chan, "WAITDIGITSTATUS", "TIMEOUT");
1023         } else {
1024                 char key[2];
1025
1026                 snprintf(key, sizeof(key), "%c", res);
1027                 pbx_builtin_setvar_helper(chan, "WAITDIGITRESULT", key);
1028                 pbx_builtin_setvar_helper(chan, "WAITDIGITSTATUS", "DTMF");
1029         }
1030
1031         return 0;
1032 }
1033
1034 /*!
1035  * \ingroup applications
1036  */
1037 static int pbx_builtin_waitexten(struct ast_channel *chan, const char *data)
1038 {
1039         int ms, res;
1040         struct ast_flags flags = {0};
1041         char *opts[1] = { NULL };
1042         char *parse;
1043         AST_DECLARE_APP_ARGS(args,
1044                 AST_APP_ARG(timeout);
1045                 AST_APP_ARG(options);
1046         );
1047
1048         if (!ast_strlen_zero(data)) {
1049                 parse = ast_strdupa(data);
1050                 AST_STANDARD_APP_ARGS(args, parse);
1051         } else
1052                 memset(&args, 0, sizeof(args));
1053
1054         if (args.options)
1055                 ast_app_parse_options(waitexten_opts, &flags, opts, args.options);
1056
1057         if (ast_test_flag(&flags, WAITEXTEN_MOH) && !opts[0] ) {
1058                 ast_log(LOG_WARNING, "The 'm' option has been specified for WaitExten without a class.\n");
1059         } else if (ast_test_flag(&flags, WAITEXTEN_MOH)) {
1060                 ast_indicate_data(chan, AST_CONTROL_HOLD, S_OR(opts[0], NULL),
1061                         !ast_strlen_zero(opts[0]) ? strlen(opts[0]) + 1 : 0);
1062         } else if (ast_test_flag(&flags, WAITEXTEN_DIALTONE)) {
1063                 struct ast_tone_zone_sound *ts = ast_get_indication_tone(ast_channel_zone(chan), "dial");
1064                 if (ts) {
1065                         ast_playtones_start(chan, 0, ts->data, 0);
1066                         ts = ast_tone_zone_sound_unref(ts);
1067                 } else {
1068                         ast_tonepair_start(chan, 350, 440, 0, 0);
1069                 }
1070         }
1071         /* Wait for "n" seconds */
1072         if (!ast_app_parse_timelen(args.timeout, &ms, TIMELEN_SECONDS) && ms > 0) {
1073                 /* Yay! */
1074         } else if (ast_channel_pbx(chan)) {
1075                 ms = ast_channel_pbx(chan)->rtimeoutms;
1076         } else {
1077                 ms = 10000;
1078         }
1079
1080         res = ast_waitfordigit(chan, ms);
1081         if (!res) {
1082                 if (ast_check_hangup(chan)) {
1083                         /* Call is hungup for some reason. */
1084                         res = -1;
1085                 } else if (ast_exists_extension(chan, ast_channel_context(chan), ast_channel_exten(chan), ast_channel_priority(chan) + 1,
1086                         S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))) {
1087                         ast_verb(3, "Timeout on %s, continuing...\n", ast_channel_name(chan));
1088                 } else if (ast_exists_extension(chan, ast_channel_context(chan), "t", 1,
1089                         S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))) {
1090                         ast_verb(3, "Timeout on %s, going to 't'\n", ast_channel_name(chan));
1091                         set_ext_pri(chan, "t", 0); /* 0 will become 1, next time through the loop */
1092                 } else if (ast_exists_extension(chan, ast_channel_context(chan), "e", 1,
1093                         S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))) {
1094                         raise_exception(chan, "RESPONSETIMEOUT", 0); /* 0 will become 1, next time through the loop */
1095                 } else {
1096                         ast_log(LOG_WARNING, "Timeout but no rule 't' or 'e' in context '%s'\n",
1097                                 ast_channel_context(chan));
1098                         res = -1;
1099                 }
1100         }
1101
1102         if (ast_test_flag(&flags, WAITEXTEN_MOH))
1103                 ast_indicate(chan, AST_CONTROL_UNHOLD);
1104         else if (ast_test_flag(&flags, WAITEXTEN_DIALTONE))
1105                 ast_playtones_stop(chan);
1106
1107         return res;
1108 }
1109
1110 /*!
1111  * \ingroup applications
1112  */
1113 static int pbx_builtin_background(struct ast_channel *chan, const char *data)
1114 {
1115         int res = 0;
1116         int mres = 0;
1117         struct ast_flags flags = {0};
1118         char *parse, exten[2] = "";
1119         AST_DECLARE_APP_ARGS(args,
1120                 AST_APP_ARG(filename);
1121                 AST_APP_ARG(options);
1122                 AST_APP_ARG(lang);
1123                 AST_APP_ARG(context);
1124         );
1125
1126         if (ast_strlen_zero(data)) {
1127                 ast_log(LOG_WARNING, "Background requires an argument (filename)\n");
1128                 return -1;
1129         }
1130
1131         parse = ast_strdupa(data);
1132
1133         AST_STANDARD_APP_ARGS(args, parse);
1134
1135         if (ast_strlen_zero(args.lang))
1136                 args.lang = (char *)ast_channel_language(chan); /* XXX this is const */
1137
1138         if (ast_strlen_zero(args.context)) {
1139                 const char *context;
1140                 ast_channel_lock(chan);
1141                 if ((context = pbx_builtin_getvar_helper(chan, "MACRO_CONTEXT"))) {
1142                         args.context = ast_strdupa(context);
1143                 } else {
1144                         args.context = ast_strdupa(ast_channel_context(chan));
1145                 }
1146                 ast_channel_unlock(chan);
1147         }
1148
1149         if (args.options) {
1150                 if (!strcasecmp(args.options, "skip"))
1151                         flags.flags = BACKGROUND_SKIP;
1152                 else if (!strcasecmp(args.options, "noanswer"))
1153                         flags.flags = BACKGROUND_NOANSWER;
1154                 else
1155                         ast_app_parse_options(background_opts, &flags, NULL, args.options);
1156         }
1157
1158         /* Answer if need be */
1159         if (ast_channel_state(chan) != AST_STATE_UP) {
1160                 if (ast_test_flag(&flags, BACKGROUND_SKIP)) {
1161                         goto done;
1162                 } else if (!ast_test_flag(&flags, BACKGROUND_NOANSWER)) {
1163                         res = ast_answer(chan);
1164                 }
1165         }
1166
1167         if (!res) {
1168                 char *back = ast_strip(args.filename);
1169                 char *front;
1170
1171                 ast_stopstream(chan);           /* Stop anything playing */
1172                 /* Stream the list of files */
1173                 while (!res && (front = strsep(&back, "&")) ) {
1174                         if ( (res = ast_streamfile(chan, front, args.lang)) ) {
1175                                 ast_log(LOG_WARNING, "ast_streamfile failed on %s for %s\n", ast_channel_name(chan), (char*)data);
1176                                 res = 0;
1177                                 mres = 1;
1178                                 break;
1179                         }
1180                         if (ast_test_flag(&flags, BACKGROUND_PLAYBACK)) {
1181                                 res = ast_waitstream(chan, "");
1182                         } else if (ast_test_flag(&flags, BACKGROUND_MATCHEXTEN)) {
1183                                 res = ast_waitstream_exten(chan, args.context);
1184                         } else {
1185                                 res = ast_waitstream(chan, AST_DIGIT_ANY);
1186                         }
1187                         ast_stopstream(chan);
1188                 }
1189         }
1190
1191         /* If ast_waitstream didn't give us back a digit, there is nothing else to do */
1192         if (res <= 0) {
1193                 goto done;
1194         }
1195
1196         exten[0] = res;
1197
1198         /*
1199          * If the single digit DTMF is an extension in the specified context, then
1200          * go there and signal no DTMF.  Otherwise, we should exit with that DTMF.
1201          * If we're in Macro, we'll exit and seek that DTMF as the beginning of an
1202          * extension in the Macro's calling context.  If we're not in Macro, then
1203          * we'll simply seek that extension in the calling context.  Previously,
1204          * someone complained about the behavior as it related to the interior of a
1205          * Gosub routine, and the fix (#14011) inadvertently broke FreePBX
1206          * (#14940).  This change should fix both of these situations, but with the
1207          * possible incompatibility that if a single digit extension does not exist
1208          * (but a longer extension COULD have matched), it would have previously
1209          * gone immediately to the "i" extension, but will now need to wait for a
1210          * timeout.
1211          *
1212          * Later, we had to add a flag to disable this workaround, because AGI
1213          * users can EXEC Background and reasonably expect that the DTMF code will
1214          * be returned (see #16434).
1215          */
1216         if (!ast_test_flag(ast_channel_flags(chan), AST_FLAG_DISABLE_WORKAROUNDS)
1217                 && ast_canmatch_extension(chan, args.context, exten, 1,
1218                         S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))
1219                 && !ast_matchmore_extension(chan, args.context, exten, 1,
1220                         S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))) {
1221                 char buf[2] = { 0, };
1222                 snprintf(buf, sizeof(buf), "%c", res);
1223                 ast_channel_exten_set(chan, buf);
1224                 ast_channel_context_set(chan, args.context);
1225                 ast_channel_priority_set(chan, 0);
1226                 res = 0;
1227         }
1228 done:
1229         pbx_builtin_setvar_helper(chan, "BACKGROUNDSTATUS", mres ? "FAILED" : "SUCCESS");
1230         return res;
1231 }
1232
1233 static int pbx_builtin_noop(struct ast_channel *chan, const char *data)
1234 {
1235         return 0;
1236 }
1237
1238 static int pbx_builtin_gotoif(struct ast_channel *chan, const char *data)
1239 {
1240         char *condition, *branch1, *branch2, *branch;
1241         char *stringp;
1242
1243         if (ast_strlen_zero(data)) {
1244                 ast_log(LOG_WARNING, "Ignoring, since there is no variable to check\n");
1245                 return 0;
1246         }
1247
1248         stringp = ast_strdupa(data);
1249         condition = strsep(&stringp,"?");
1250         branch1 = strsep(&stringp,":");
1251         branch2 = strsep(&stringp,"");
1252         branch = pbx_checkcondition(condition) ? branch1 : branch2;
1253
1254         if (ast_strlen_zero(branch)) {
1255                 ast_debug(1, "Not taking any branch\n");
1256                 return 0;
1257         }
1258
1259         return pbx_builtin_goto(chan, branch);
1260 }
1261
1262 static int pbx_builtin_saynumber(struct ast_channel *chan, const char *data)
1263 {
1264         char tmp[256];
1265         char *number = tmp;
1266         int number_val;
1267         char *options;
1268         int res;
1269         int interrupt = 0;
1270         const char *interrupt_string;
1271
1272         ast_channel_lock(chan);
1273         interrupt_string = pbx_builtin_getvar_helper(chan, "SAY_DTMF_INTERRUPT");
1274         if (ast_true(interrupt_string)) {
1275                 interrupt = 1;
1276         }
1277         ast_channel_unlock(chan);
1278
1279         if (ast_strlen_zero(data)) {
1280                 ast_log(LOG_WARNING, "SayNumber requires an argument (number)\n");
1281                 return -1;
1282         }
1283         ast_copy_string(tmp, data, sizeof(tmp));
1284         strsep(&number, ",");
1285
1286         if (sscanf(tmp, "%d", &number_val) != 1) {
1287                 ast_log(LOG_WARNING, "argument '%s' to SayNumber could not be parsed as a number.\n", tmp);
1288                 return 0;
1289         }
1290
1291         options = strsep(&number, ",");
1292         if (options) {
1293                 if ( strcasecmp(options, "f") && strcasecmp(options, "m") &&
1294                         strcasecmp(options, "c") && strcasecmp(options, "n") ) {
1295                         ast_log(LOG_WARNING, "SayNumber gender option is either 'f', 'm', 'c' or 'n'\n");
1296                         return -1;
1297                 }
1298         }
1299
1300         res = ast_say_number(chan, number_val, interrupt ? AST_DIGIT_ANY : "", ast_channel_language(chan), options);
1301
1302         if (res < 0) {
1303                 ast_log(LOG_WARNING, "We were unable to say the number %s, is it too large?\n", tmp);
1304         }
1305
1306         return interrupt ? res : 0;
1307 }
1308
1309 static int pbx_builtin_saydigits(struct ast_channel *chan, const char *data)
1310 {
1311         int res = 0;
1312         int interrupt = 0;
1313         const char *interrupt_string;
1314
1315         ast_channel_lock(chan);
1316         interrupt_string = pbx_builtin_getvar_helper(chan, "SAY_DTMF_INTERRUPT");
1317         if (ast_true(interrupt_string)) {
1318                 interrupt = 1;
1319         }
1320         ast_channel_unlock(chan);
1321
1322         if (data) {
1323                 res = ast_say_digit_str(chan, data, interrupt ? AST_DIGIT_ANY : "", ast_channel_language(chan));
1324         }
1325
1326         return res;
1327 }
1328
1329 static int pbx_builtin_saycharacters_case(struct ast_channel *chan, const char *data)
1330 {
1331         int res = 0;
1332         int sensitivity = 0;
1333         char *parse;
1334         int interrupt = 0;
1335         const char *interrupt_string;
1336
1337         AST_DECLARE_APP_ARGS(args,
1338                 AST_APP_ARG(options);
1339                 AST_APP_ARG(characters);
1340         );
1341
1342         ast_channel_lock(chan);
1343         interrupt_string = pbx_builtin_getvar_helper(chan, "SAY_DTMF_INTERRUPT");
1344         if (ast_true(interrupt_string)) {
1345                 interrupt = 1;
1346         }
1347         ast_channel_unlock(chan);
1348
1349         if (ast_strlen_zero(data)) {
1350                 ast_log(LOG_WARNING, "SayAlphaCase requires two arguments (options, characters)\n");
1351                 return 0;
1352         }
1353
1354         parse = ast_strdupa(data);
1355         AST_STANDARD_APP_ARGS(args, parse);
1356
1357         if (!args.options || strlen(args.options) != 1) {
1358                 ast_log(LOG_WARNING, "SayAlphaCase options are mutually exclusive and required\n");
1359                 return 0;
1360         }
1361
1362         switch (args.options[0]) {
1363         case 'a':
1364                 sensitivity = AST_SAY_CASE_ALL;
1365                 break;
1366         case 'l':
1367                 sensitivity = AST_SAY_CASE_LOWER;
1368                 break;
1369         case 'n':
1370                 sensitivity = AST_SAY_CASE_NONE;
1371                 break;
1372         case 'u':
1373                 sensitivity = AST_SAY_CASE_UPPER;
1374                 break;
1375         default:
1376                 ast_log(LOG_WARNING, "Invalid option: '%s'\n", args.options);
1377                 return 0;
1378         }
1379
1380         res = ast_say_character_str(chan, args.characters, interrupt ? AST_DIGIT_ANY : "", ast_channel_language(chan), sensitivity);
1381
1382         return res;
1383 }
1384
1385 static int pbx_builtin_saycharacters(struct ast_channel *chan, const char *data)
1386 {
1387         int res = 0;
1388         int interrupt = 0;
1389         const char *interrupt_string;
1390
1391         ast_channel_lock(chan);
1392         interrupt_string = pbx_builtin_getvar_helper(chan, "SAY_DTMF_INTERRUPT");
1393         if (ast_true(interrupt_string)) {
1394                 interrupt = 1;
1395         }
1396         ast_channel_unlock(chan);
1397
1398         if (data) {
1399                 res = ast_say_character_str(chan, data, interrupt ? AST_DIGIT_ANY : "", ast_channel_language(chan), AST_SAY_CASE_NONE);
1400         }
1401
1402         return res;
1403 }
1404
1405 static int pbx_builtin_sayphonetic(struct ast_channel *chan, const char *data)
1406 {
1407         int res = 0;
1408         int interrupt = 0;
1409         const char *interrupt_string;
1410
1411         ast_channel_lock(chan);
1412         interrupt_string = pbx_builtin_getvar_helper(chan, "SAY_DTMF_INTERRUPT");
1413         if (ast_true(interrupt_string)) {
1414                 interrupt = 1;
1415         }
1416         ast_channel_unlock(chan);
1417
1418         if (data)
1419                 res = ast_say_phonetic_str(chan, data, interrupt ? AST_DIGIT_ANY : "", ast_channel_language(chan));
1420         return res;
1421 }
1422
1423 static int pbx_builtin_importvar(struct ast_channel *chan, const char *data)
1424 {
1425         char *name;
1426         char *value;
1427         char *channel;
1428         char tmp[VAR_BUF_SIZE];
1429         static int deprecation_warning = 0;
1430
1431         if (ast_strlen_zero(data)) {
1432                 ast_log(LOG_WARNING, "Ignoring, since there is no variable to set\n");
1433                 return 0;
1434         }
1435         tmp[0] = 0;
1436         if (!deprecation_warning) {
1437                 ast_log(LOG_WARNING, "ImportVar is deprecated.  Please use Set(varname=${IMPORT(channel,variable)}) instead.\n");
1438                 deprecation_warning = 1;
1439         }
1440
1441         value = ast_strdupa(data);
1442         name = strsep(&value,"=");
1443         channel = strsep(&value,",");
1444         if (channel && value && name) { /*! \todo XXX should do !ast_strlen_zero(..) of the args ? */
1445                 struct ast_channel *chan2 = ast_channel_get_by_name(channel);
1446                 if (chan2) {
1447                         char *s = ast_alloca(strlen(value) + 4);
1448                         sprintf(s, "${%s}", value);
1449                         pbx_substitute_variables_helper(chan2, s, tmp, sizeof(tmp) - 1);
1450                         chan2 = ast_channel_unref(chan2);
1451                 }
1452                 pbx_builtin_setvar_helper(chan, name, tmp);
1453         }
1454
1455         return(0);
1456 }
1457
1458 /*! \brief Declaration of builtin applications */
1459 struct pbx_builtin {
1460         char name[AST_MAX_APP];
1461         int (*execute)(struct ast_channel *chan, const char *data);
1462 } builtins[] =
1463 {
1464         /* These applications are built into the PBX core and do not
1465            need separate modules */
1466
1467         { "Answer",         pbx_builtin_answer },
1468         { "BackGround",     pbx_builtin_background },
1469         { "Busy",           indicate_busy },
1470         { "Congestion",     indicate_congestion },
1471         { "ExecIfTime",     pbx_builtin_execiftime },
1472         { "Goto",           pbx_builtin_goto },
1473         { "GotoIf",         pbx_builtin_gotoif },
1474         { "GotoIfTime",     pbx_builtin_gotoiftime },
1475         { "ImportVar",      pbx_builtin_importvar },
1476         { "Hangup",         pbx_builtin_hangup },
1477         { "Incomplete",     pbx_builtin_incomplete },
1478         { "NoOp",           pbx_builtin_noop },
1479         { "Proceeding",     pbx_builtin_proceeding },
1480         { "Progress",       pbx_builtin_progress },
1481         { "RaiseException", pbx_builtin_raise_exception },
1482         { "Ringing",        pbx_builtin_ringing },
1483         { "SayAlpha",       pbx_builtin_saycharacters },
1484         { "SayAlphaCase",   pbx_builtin_saycharacters_case },
1485         { "SayDigits",      pbx_builtin_saydigits },
1486         { "SayNumber",      pbx_builtin_saynumber },
1487         { "SayPhonetic",    pbx_builtin_sayphonetic },
1488         { "SetAMAFlags",    pbx_builtin_setamaflags },
1489         { "Wait",           pbx_builtin_wait },
1490         { "WaitDigit",      pbx_builtin_waitdigit },
1491         { "WaitExten",      pbx_builtin_waitexten }
1492 };
1493
1494 static void unload_pbx_builtins(void)
1495 {
1496         int x;
1497
1498         /* Unregister builtin applications */
1499         for (x = 0; x < ARRAY_LEN(builtins); x++) {
1500                 ast_unregister_application(builtins[x].name);
1501         }
1502 }
1503
1504 int load_pbx_builtins(void)
1505 {
1506         int x;
1507
1508         /* Register builtin applications */
1509         for (x = 0; x < ARRAY_LEN(builtins); x++) {
1510                 if (ast_register_application2(builtins[x].name, builtins[x].execute, NULL, NULL, NULL)) {
1511                         ast_log(LOG_ERROR, "Unable to register builtin application '%s'\n", builtins[x].name);
1512                         unload_pbx_builtins();
1513                         return -1;
1514                 }
1515         }
1516
1517         ast_register_cleanup(unload_pbx_builtins);
1518
1519         return 0;
1520 }