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