Asterisk - The Open Source Telephony Project  GIT-master-9ed6387
pbx_builtins.c
Go to the documentation of this file.
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2015 Fairview 5 Engineering, LLC
5  *
6  * George Joseph <george.joseph@fairview5.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18 
19 /*! \file
20  *
21  * \brief Core PBX builtin routines.
22  *
23  * \author George Joseph <george.joseph@fairview5.com>
24  */
25 
26 /*** MODULEINFO
27  <support_level>core</support_level>
28  ***/
29 
30 #include "asterisk.h"
31 
32 #include "asterisk/_private.h"
33 #include "asterisk/pbx.h"
34 #include "asterisk/causes.h"
35 #include "asterisk/indications.h"
37 #include "asterisk/say.h"
38 #include "asterisk/app.h"
39 #include "asterisk/module.h"
40 #include "pbx_private.h"
41 
42 /*** DOCUMENTATION
43  <application name="Answer" language="en_US">
44  <synopsis>
45  Answer a channel if ringing.
46  </synopsis>
47  <syntax>
48  <parameter name="delay">
49  <para>Asterisk will wait this number of milliseconds before returning to
50  the dialplan after answering the call.</para>
51  </parameter>
52  </syntax>
53  <description>
54  <para>If the call has not been answered, this application will
55  answer it. Otherwise, it has no effect on the call.</para>
56  </description>
57  <see-also>
58  <ref type="application">Hangup</ref>
59  </see-also>
60  </application>
61  <application name="BackGround" language="en_US">
62  <synopsis>
63  Play an audio file while waiting for digits of an extension to go to.
64  </synopsis>
65  <syntax>
66  <parameter name="filenames" required="true" argsep="&amp;">
67  <argument name="filename1" required="true" />
68  <argument name="filename2" multiple="true" />
69  </parameter>
70  <parameter name="options">
71  <optionlist>
72  <option name="s">
73  <para>Causes the playback of the message to be skipped
74  if the channel is not in the <literal>up</literal> state (i.e. it
75  hasn't been answered yet). If this happens, the
76  application will return immediately.</para>
77  </option>
78  <option name="n">
79  <para>Don't answer the channel before playing the files.</para>
80  </option>
81  <option name="m">
82  <para>Only break if a digit hit matches a one digit
83  extension in the destination context.</para>
84  </option>
85  </optionlist>
86  </parameter>
87  <parameter name="langoverride">
88  <para>Explicitly specifies which language to attempt to use for the requested sound files.</para>
89  </parameter>
90  <parameter name="context">
91  <para>This is the dialplan context that this application will use when exiting
92  to a dialed extension.</para>
93  </parameter>
94  </syntax>
95  <description>
96  <para>This application will play the given list of files <emphasis>(do not put extension)</emphasis>
97  while waiting for an extension to be dialed by the calling channel. To continue waiting
98  for digits after this application has finished playing files, the <literal>WaitExten</literal>
99  application should be used.</para>
100  <para>If one of the requested sound files does not exist, call processing will be terminated.</para>
101  <para>This application sets the following channel variable upon completion:</para>
102  <variablelist>
103  <variable name="BACKGROUNDSTATUS">
104  <para>The status of the background attempt as a text string.</para>
105  <value name="SUCCESS" />
106  <value name="FAILED" />
107  </variable>
108  </variablelist>
109  </description>
110  <see-also>
111  <ref type="application">ControlPlayback</ref>
112  <ref type="application">WaitExten</ref>
113  <ref type="application">BackgroundDetect</ref>
114  <ref type="function">TIMEOUT</ref>
115  </see-also>
116  </application>
117  <application name="Busy" language="en_US">
118  <synopsis>
119  Indicate the Busy condition.
120  </synopsis>
121  <syntax>
122  <parameter name="timeout">
123  <para>If specified, the calling channel will be hung up after the specified number of seconds.
124  Otherwise, this application will wait until the calling channel hangs up.</para>
125  </parameter>
126  </syntax>
127  <description>
128  <para>This application will indicate the busy condition to the calling channel.</para>
129  </description>
130  <see-also>
131  <ref type="application">Congestion</ref>
132  <ref type="application">Progress</ref>
133  <ref type="application">Playtones</ref>
134  <ref type="application">Hangup</ref>
135  </see-also>
136  </application>
137  <application name="Congestion" language="en_US">
138  <synopsis>
139  Indicate the Congestion condition.
140  </synopsis>
141  <syntax>
142  <parameter name="timeout">
143  <para>If specified, the calling channel will be hung up after the specified number of seconds.
144  Otherwise, this application will wait until the calling channel hangs up.</para>
145  </parameter>
146  </syntax>
147  <description>
148  <para>This application will indicate the congestion condition to the calling channel.</para>
149  </description>
150  <see-also>
151  <ref type="application">Busy</ref>
152  <ref type="application">Progress</ref>
153  <ref type="application">Playtones</ref>
154  <ref type="application">Hangup</ref>
155  </see-also>
156  </application>
157  <application name="ExecIfTime" language="en_US">
158  <synopsis>
159  Conditional application execution based on the current time.
160  </synopsis>
161  <syntax argsep="?">
162  <parameter name="day_condition" required="true">
163  <argument name="times" required="true" />
164  <argument name="weekdays" required="true" />
165  <argument name="mdays" required="true" />
166  <argument name="months" required="true" />
167  <argument name="timezone" required="false" />
168  </parameter>
169  <parameter name="appname" required="true" hasparams="optional">
170  <argument name="appargs" required="true" />
171  </parameter>
172  </syntax>
173  <description>
174  <para>This application will execute the specified dialplan application, with optional
175  arguments, if the current time matches the given time specification.</para>
176  </description>
177  <see-also>
178  <ref type="application">Exec</ref>
179  <ref type="application">ExecIf</ref>
180  <ref type="application">TryExec</ref>
181  <ref type="application">GotoIfTime</ref>
182  </see-also>
183  </application>
184  <application name="Goto" language="en_US">
185  <synopsis>
186  Jump to a particular priority, extension, or context.
187  </synopsis>
188  <syntax>
189  <parameter name="context" />
190  <parameter name="extensions" />
191  <parameter name="priority" required="true" />
192  </syntax>
193  <description>
194  <para>This application will set the current context, extension, and priority in the channel structure.
195  After it completes, the pbx engine will continue dialplan execution at the specified location.
196  If no specific <replaceable>extension</replaceable>, or <replaceable>extension</replaceable> and
197  <replaceable>context</replaceable>, are specified, then this application will
198  just set the specified <replaceable>priority</replaceable> of the current extension.</para>
199  <para>At least a <replaceable>priority</replaceable> is required as an argument, or the goto will
200  return a <literal>-1</literal>, and the channel and call will be terminated.</para>
201  <para>If the location that is put into the channel information is bogus, and asterisk cannot
202  find that location in the dialplan, then the execution engine will try to find and execute the code in
203  the <literal>i</literal> (invalid) extension in the current context. If that does not exist, it will try to execute the
204  <literal>h</literal> extension. If neither the <literal>h</literal> nor <literal>i</literal> extensions
205  have been defined, the channel is hung up, and the execution of instructions on the channel is terminated.
206  What this means is that, for example, you specify a context that does not exist, then
207  it will not be possible to find the <literal>h</literal> or <literal>i</literal> extensions,
208  and the call will terminate!</para>
209  </description>
210  <see-also>
211  <ref type="application">GotoIf</ref>
212  <ref type="application">GotoIfTime</ref>
213  <ref type="application">Gosub</ref>
214  <ref type="application">Macro</ref>
215  </see-also>
216  </application>
217  <application name="GotoIf" language="en_US">
218  <synopsis>
219  Conditional goto.
220  </synopsis>
221  <syntax argsep="?">
222  <parameter name="condition" required="true" />
223  <parameter name="destination" required="true" argsep=":">
224  <argument name="labeliftrue">
225  <para>Continue at <replaceable>labeliftrue</replaceable> if the condition is true.
226  Takes the form similar to Goto() of [[context,]extension,]priority.</para>
227  </argument>
228  <argument name="labeliffalse">
229  <para>Continue at <replaceable>labeliffalse</replaceable> if the condition is false.
230  Takes the form similar to Goto() of [[context,]extension,]priority.</para>
231  </argument>
232  </parameter>
233  </syntax>
234  <description>
235  <para>This application will set the current context, extension, and priority in the channel structure
236  based on the evaluation of the given condition. After this application completes, the
237  pbx engine will continue dialplan execution at the specified location in the dialplan.
238  The labels are specified with the same syntax as used within the Goto application.
239  If the label chosen by the condition is omitted, no jump is performed, and the execution passes to the
240  next instruction. If the target location is bogus, and does not exist, the execution engine will try
241  to find and execute the code in the <literal>i</literal> (invalid) extension in the current context.
242  If that does not exist, it will try to execute the <literal>h</literal> extension.
243  If neither the <literal>h</literal> nor <literal>i</literal> extensions have been defined,
244  the channel is hung up, and the execution of instructions on the channel is terminated.
245  Remember that this command can set the current context, and if the context specified
246  does not exist, then it will not be able to find any 'h' or 'i' extensions there, and
247  the channel and call will both be terminated!.</para>
248  </description>
249  <see-also>
250  <ref type="application">Goto</ref>
251  <ref type="application">GotoIfTime</ref>
252  <ref type="application">GosubIf</ref>
253  <ref type="application">MacroIf</ref>
254  </see-also>
255  </application>
256  <application name="GotoIfTime" language="en_US">
257  <synopsis>
258  Conditional Goto based on the current time.
259  </synopsis>
260  <syntax argsep="?">
261  <parameter name="condition" required="true">
262  <argument name="times" required="true" />
263  <argument name="weekdays" required="true" />
264  <argument name="mdays" required="true" />
265  <argument name="months" required="true" />
266  <argument name="timezone" required="false" />
267  </parameter>
268  <parameter name="destination" required="true" argsep=":">
269  <argument name="labeliftrue">
270  <para>Continue at <replaceable>labeliftrue</replaceable> if the condition is true.
271  Takes the form similar to Goto() of [[context,]extension,]priority.</para>
272  </argument>
273  <argument name="labeliffalse">
274  <para>Continue at <replaceable>labeliffalse</replaceable> if the condition is false.
275  Takes the form similar to Goto() of [[context,]extension,]priority.</para>
276  </argument>
277  </parameter>
278  </syntax>
279  <description>
280  <para>This application will set the context, extension, and priority in the channel structure
281  based on the evaluation of the given time specification. After this application completes,
282  the pbx engine will continue dialplan execution at the specified location in the dialplan.
283  If the current time is within the given time specification, the channel will continue at
284  <replaceable>labeliftrue</replaceable>. Otherwise the channel will continue at <replaceable>labeliffalse</replaceable>.
285  If the label chosen by the condition is omitted, no jump is performed, and execution passes to the next
286  instruction. If the target jump location is bogus, the same actions would be taken as for <literal>Goto</literal>.
287  Further information on the time specification can be found in examples
288  illustrating how to do time-based context includes in the dialplan.</para>
289  </description>
290  <see-also>
291  <ref type="application">GotoIf</ref>
292  <ref type="application">Goto</ref>
293  <ref type="function">IFTIME</ref>
294  <ref type="function">TESTTIME</ref>
295  </see-also>
296  </application>
297  <application name="ImportVar" language="en_US">
298  <synopsis>
299  Import a variable from a channel into a new variable.
300  </synopsis>
301  <syntax argsep="=">
302  <parameter name="newvar" required="true" />
303  <parameter name="vardata" required="true">
304  <argument name="channelname" required="true" />
305  <argument name="variable" required="true" />
306  </parameter>
307  </syntax>
308  <description>
309  <para>This application imports a <replaceable>variable</replaceable> from the specified
310  <replaceable>channel</replaceable> (as opposed to the current one) and stores it as a variable
311  (<replaceable>newvar</replaceable>) in the current channel (the channel that is calling this
312  application). Variables created by this application have the same inheritance properties as those
313  created with the <literal>Set</literal> application.</para>
314  </description>
315  <see-also>
316  <ref type="application">Set</ref>
317  </see-also>
318  </application>
319  <application name="Hangup" language="en_US">
320  <synopsis>
321  Hang up the calling channel.
322  </synopsis>
323  <syntax>
324  <parameter name="causecode">
325  <para>If a <replaceable>causecode</replaceable> is given the channel's
326  hangup cause will be set to the given value.</para>
327  </parameter>
328  </syntax>
329  <description>
330  <para>This application will hang up the calling channel.</para>
331  </description>
332  <see-also>
333  <ref type="application">Answer</ref>
334  <ref type="application">Busy</ref>
335  <ref type="application">Congestion</ref>
336  </see-also>
337  </application>
338  <application name="Incomplete" language="en_US">
339  <synopsis>
340  Returns AST_PBX_INCOMPLETE value.
341  </synopsis>
342  <syntax>
343  <parameter name="n">
344  <para>If specified, then Incomplete will not attempt to answer the channel first.</para>
345  <note><para>Most channel types need to be in Answer state in order to receive DTMF.</para></note>
346  </parameter>
347  </syntax>
348  <description>
349  <para>Signals the PBX routines that the previous matched extension is incomplete
350  and that further input should be allowed before matching can be considered
351  to be complete. Can be used within a pattern match when certain criteria warrants
352  a longer match.</para>
353  </description>
354  </application>
355  <application name="NoOp" language="en_US">
356  <synopsis>
357  Do Nothing (No Operation).
358  </synopsis>
359  <syntax>
360  <parameter name="text">
361  <para>Any text provided can be viewed at the Asterisk CLI.</para>
362  </parameter>
363  </syntax>
364  <description>
365  <para>This application does nothing. However, it is useful for debugging purposes.</para>
366  <para>This method can be used to see the evaluations of variables or functions without having any effect.</para>
367  </description>
368  <see-also>
369  <ref type="application">Verbose</ref>
370  <ref type="application">Log</ref>
371  </see-also>
372  </application>
373  <application name="Proceeding" language="en_US">
374  <synopsis>
375  Indicate proceeding.
376  </synopsis>
377  <syntax />
378  <description>
379  <para>This application will request that a proceeding message be provided to the calling channel.</para>
380  </description>
381  </application>
382  <application name="Progress" language="en_US">
383  <synopsis>
384  Indicate progress.
385  </synopsis>
386  <syntax />
387  <description>
388  <para>This application will request that in-band progress information be provided to the calling channel.</para>
389  </description>
390  <see-also>
391  <ref type="application">Busy</ref>
392  <ref type="application">Congestion</ref>
393  <ref type="application">Ringing</ref>
394  <ref type="application">Playtones</ref>
395  </see-also>
396  </application>
397  <application name="RaiseException" language="en_US">
398  <synopsis>
399  Handle an exceptional condition.
400  </synopsis>
401  <syntax>
402  <parameter name="reason" required="true" />
403  </syntax>
404  <description>
405  <para>This application will jump to the <literal>e</literal> extension in the current context, setting the
406  dialplan function EXCEPTION(). If the <literal>e</literal> extension does not exist, the call will hangup.</para>
407  </description>
408  <see-also>
409  <ref type="function">Exception</ref>
410  </see-also>
411  </application>
412  <application name="Ringing" language="en_US">
413  <synopsis>
414  Indicate ringing tone.
415  </synopsis>
416  <syntax />
417  <description>
418  <para>This application will request that the channel indicate a ringing tone to the user.</para>
419  </description>
420  <see-also>
421  <ref type="application">Busy</ref>
422  <ref type="application">Congestion</ref>
423  <ref type="application">Progress</ref>
424  <ref type="application">Playtones</ref>
425  </see-also>
426  </application>
427  <application name="SayAlpha" language="en_US">
428  <synopsis>
429  Say Alpha.
430  </synopsis>
431  <syntax>
432  <parameter name="string" required="true" />
433  </syntax>
434  <description>
435  <para>This application will play the sounds that correspond to the letters
436  of the given <replaceable>string</replaceable>. If the channel variable
437  <variable>SAY_DTMF_INTERRUPT</variable> is set to 'true' (case insensitive),
438  then this application will react to DTMF in the same way as
439  <literal>Background</literal>.</para>
440  </description>
441  <see-also>
442  <ref type="application">SayDigits</ref>
443  <ref type="application">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 
662 });
663 
664 #define WAITEXTEN_MOH (1 << 0)
665 #define WAITEXTEN_DIALTONE (1 << 1)
666 
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 {
684  return 0;
685 }
686 
687 /*!
688  * \ingroup applications
689  */
690 static int pbx_builtin_progress(struct ast_channel *chan, const char *data)
691 {
693  return 0;
694 }
695 
696 /*!
697  * \ingroup applications
698  */
699 static int pbx_builtin_ringing(struct ast_channel *chan, const char *data)
700 {
702  return 0;
703 }
704 
705 /*!
706  * \ingroup applications
707  */
708 int indicate_busy(struct ast_channel *chan, const char *data)
709 {
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) {
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 {
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) {
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;
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 
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 {
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) {
851  }
852  }
853  ast_channel_hangupcause_set(chan, cause);
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;
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;
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))
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] = "";
1120  AST_APP_ARG(filename);
1122  AST_APP_ARG(lang);
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  */
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 
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 {
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++) {
1501  }
1502 }
1503 
1505 {
1506  int x;
1507 
1508  /* Register builtin applications */
1509  for (x = 0; x < ARRAY_LEN(builtins); x++) {
1511  ast_log(LOG_ERROR, "Unable to register builtin application '%s'\n", builtins[x].name);
1512  return -1;
1513  }
1514  }
1515 
1517 
1518  return 0;
1519 }
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
int ast_safe_sleep(struct ast_channel *chan, int ms)
Wait for a specified amount of time, looking for hangups.
Definition: channel.c:1554
Tone Indication Support.
int ast_matchmore_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Looks to see if adding anything to this extension might match something. (exists ^ canmatch) ...
Definition: pbx.c:4190
#define ast_channel_lock(chan)
Definition: channel.h:2837
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:118
Main Channel structure associated with a channel.
static int pbx_builtin_saynumber(struct ast_channel *chan, const char *data)
int ast_check_timing2(const struct ast_timing *i, const struct timeval tv)
Evaluate a pre-constructed bitmap as to whether a particular time falls within the range specified...
Definition: pbx_timing.c:251
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
static int pbx_builtin_progress(struct ast_channel *chan, const char *data)
Definition: pbx_builtins.c:690
Asterisk main include file. File version handling, generic pbx functions.
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
#define BACKGROUND_MATCHEXTEN
Definition: pbx_builtins.c:654
static int amaflags
Definition: chan_iax2.c:432
int pbx_builtin_raise_exception(struct ast_channel *chan, const char *reason)
Definition: pbx_builtins.c:672
Private include file for pbx.
int pbx_exec(struct ast_channel *c, struct ast_app *app, const char *data)
Execute an application.
Definition: pbx_app.c:471
#define AST_DIGIT_ANY
Definition: file.h:48
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2873
#define ast_test_flag(p, flag)
Definition: utils.h:63
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
Definition: channel.c:4271
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
static int pbx_builtin_hangup(struct ast_channel *chan, const char *data)
Definition: pbx_builtins.c:828
void ast_channel_hangupcause_set(struct ast_channel *chan, int value)
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
#define LOG_WARNING
Definition: logger.h:274
static int pbx_builtin_waitexten(struct ast_channel *chan, const char *data)
static int timeout
Definition: cdr_mysql.c:86
static int tmp()
Definition: bt_open.c:389
unsigned int flags
Definition: utils.h:200
static int pbx_builtin_importvar(struct ast_channel *chan, const char *data)
struct ast_tone_zone * ast_channel_zone(const struct ast_channel *chan)
#define AST_LOG_WARNING
Definition: logger.h:279
static int pbx_builtin_ringing(struct ast_channel *chan, const char *data)
Definition: pbx_builtins.c:699
int pbx_checkcondition(const char *condition)
Evaluate a condition.
Definition: pbx.c:8302
int ast_say_digit_str(struct ast_channel *chan, const char *num, const char *ints, const char *lang)
says digits of a string
Definition: channel.c:8194
static int pbx_builtin_saycharacters(struct ast_channel *chan, const char *data)
ast_channel_state
ast_channel states
Definition: channelstate.h:35
int ast_indicate_data(struct ast_channel *chan, int condition, const void *data, size_t datalen)
Indicates condition of channel, with payload.
Definition: channel.c:4647
static int pbx_builtin_background(struct ast_channel *chan, const char *data)
#define WAITEXTEN_MOH
Definition: pbx_builtins.c:664
static int pbx_builtin_saycharacters_case(struct ast_channel *chan, const char *data)
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
Definition: muted.c:95
const char * args
void ast_playtones_stop(struct ast_channel *chan)
Stop playing tones on a channel.
Definition: indications.c:393
#define NULL
Definition: resample.c:96
const char * data
int value
Definition: syslog.c:37
static int pbx_builtin_sayphonetic(struct ast_channel *chan, const char *data)
int ast_unregister_application(const char *app)
Unregister an application.
Definition: pbx_app.c:392
int ast_channel_priority(const struct ast_channel *chan)
int load_pbx_builtins(void)
#define ast_verb(level,...)
Definition: logger.h:455
static int pbx_builtin_gotoiftime(struct ast_channel *chan, const char *data)
Definition: pbx_builtins.c:874
int ast_canmatch_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Looks for a valid matching extension.
Definition: pbx.c:4185
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
void wait_for_hangup(struct ast_channel *chan, const void *data)
Definition: pbx.c:8248
#define AST_APP_OPTIONS(holder, options...)
Declares an array of options for an application.
int done
Definition: test_amihooks.c:48
Number structure.
Definition: app_followme.c:154
enum ama_flags ast_channel_string2amaflag(const char *flag)
Convert a string to a detail record AMA flag.
Definition: channel.c:4354
int indicate_congestion(struct ast_channel *chan, const char *data)
Definition: pbx_builtins.c:726
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:444
#define ast_log
Definition: astobj2.c:42
static int pbx_builtin_execiftime(struct ast_channel *chan, const char *data)
Definition: pbx_builtins.c:928
int raise_exception(struct ast_channel *chan, const char *reason, int priority)
Definition: pbx.c:2806
int ast_register_cleanup(void(*func)(void))
Register a function to be executed before Asterisk gracefully exits.
Definition: clicompat.c:19
void ast_set_hangupsource(struct ast_channel *chan, const char *source, int force)
Set the source of the hangup in this channel and it&#39;s bridge.
Definition: channel.c:2479
struct ast_pbx * ast_channel_pbx(const struct ast_channel *chan)
int ast_parseable_goto(struct ast_channel *chan, const char *goto_string)
Definition: pbx.c:8840
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
Definition: strings.h:219
#define AST_CAUSE_NORMAL_CLEARING
Definition: causes.h:105
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:85
static int pbx_builtin_wait(struct ast_channel *chan, const char *data)
Definition: pbx_builtins.c:982
static int pbx_builtin_incomplete(struct ast_channel *chan, const char *data)
Definition: pbx_builtins.c:775
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
static struct ast_tone_zone_sound * ast_tone_zone_sound_unref(struct ast_tone_zone_sound *ts)
Release a reference to an ast_tone_zone_sound.
Definition: indications.h:227
int indicate_busy(struct ast_channel *chan, const char *data)
Definition: pbx_builtins.c:708
void ast_channel_amaflags_set(struct ast_channel *chan, enum ama_flags value)
static int pbx_builtin_setamaflags(struct ast_channel *chan, const char *data)
Definition: pbx_builtins.c:800
static const struct ast_app_option background_opts[128]
Definition: pbx_builtins.c:662
int ast_say_character_str(struct ast_channel *chan, const char *num, const char *ints, const char *lang, enum ast_say_case_sensitivity sensitivity)
function to pronounce character and phonetic strings
Definition: channel.c:8200
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
Definition: pbx.c:4170
static int answer(void *data)
Definition: chan_pjsip.c:680
struct pbx_builtin builtins[]
int ast_app_parse_options(const struct ast_app_option *options, struct ast_flags *flags, char **args, char *optstr)
Parses a string containing application options and sets flags/arguments.
Definition: main/app.c:2829
const char * ast_channel_exten(const struct ast_channel *chan)
Core PBX routines and definitions.
int(* execute)(struct ast_channel *chan, const char *data)
int ast_check_hangup(struct ast_channel *chan)
Check to see if a channel is needing hang up.
Definition: channel.c:441
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:290
static int pbx_builtin_gotoif(struct ast_channel *chan, const char *data)
#define BACKGROUND_PLAYBACK
Definition: pbx_builtins.c:655
#define AST_PBX_INCOMPLETE
Definition: pbx.h:51
void set_ext_pri(struct ast_channel *c, const char *exten, int pri)
Definition: pbx.c:4259
#define LOG_ERROR
Definition: logger.h:285
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true". This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1".
Definition: main/utils.c:1822
#define AST_MAX_APP
Definition: pbx.h:40
char * usage
Definition: utils/frame.c:37
#define AST_APP_OPTION_ARG(option, flagno, argno)
Declares an application option that accepts an argument.
static int pbx_builtin_answer(struct ast_channel *chan, const char *data)
Definition: pbx_builtins.c:744
int ast_check_timing(const struct ast_timing *i)
Evaluate a pre-constructed bitmap as to whether the current time falls within the range specified...
Definition: extconf.c:4002
Description of a tone.
Definition: indications.h:35
struct ast_tone_zone_sound * ast_get_indication_tone(const struct ast_tone_zone *zone, const char *indication)
Locate a tone zone sound.
Definition: indications.c:455
static const struct ast_app_option waitexten_opts[128]
Definition: pbx_builtins.c:670
#define BACKGROUND_SKIP
Definition: pbx_builtins.c:652
int __ast_answer(struct ast_channel *chan, unsigned int delay)
Answer a channel, with a selectable delay before returning.
Definition: channel.c:2670
static void unload_pbx_builtins(void)
static int pbx_builtin_proceeding(struct ast_channel *chan, const char *data)
Definition: pbx_builtins.c:681
int ast_softhangup_nolock(struct ast_channel *chan, int reason)
Softly hangup up a channel (no channel lock)
Definition: channel.c:2438
#define ast_strlen_zero(a)
Definition: muted.c:73
int ast_destroy_timing(struct ast_timing *i)
Deallocates memory structures associated with a timing bitmap.
Definition: pbx_timing.c:285
#define ast_channel_unlock(chan)
Definition: channel.h:2838
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1872
#define VAR_BUF_SIZE
Definition: pbx_private.h:68
static const char name[]
Definition: cdr_mysql.c:74
Prototypes for public functions only of internal interest,.
Structure used to handle boolean flags.
Definition: utils.h:199
int ast_build_timing(struct ast_timing *i, const char *info)
Construct a timing bitmap, for use in time-based conditionals.
Definition: extconf.c:3808
int ast_say_phonetic_str(struct ast_channel *chan, const char *num, const char *ints, const char *lang)
Definition: channel.c:8206
void ast_channel_exten_set(struct ast_channel *chan, const char *value)
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
int ast_waitfordigit(struct ast_channel *c, int ms)
Waits for a digit.
Definition: channel.c:3150
char name[AST_MAX_APP]
char * strsep(char **str, const char *delims)
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8176
int ast_channel_hangupcause(const struct ast_channel *chan)
void ast_channel_context_set(struct ast_channel *chan, const char *value)
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
ast_app: A registered application
Definition: pbx_app.c:45
static int pbx_builtin_goto(struct ast_channel *chan, const char *data)
Definition: pbx_builtins.c:863
const char * ast_channel_name(const struct ast_channel *chan)
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1775
int ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
Definition: channel.c:7325
int ast_answer(struct ast_channel *chan)
Answer a channel.
Definition: channel.c:2780
void pbx_substitute_variables_helper(struct ast_channel *c, const char *cp1, char *cp2, int count)
Definition: ael_main.c:211
static int pbx_builtin_noop(struct ast_channel *chan, const char *data)
#define AST_CAUSE_BUSY
Definition: causes.h:148
Internal Asterisk hangup causes.
const char * ast_channel_language(const struct ast_channel *chan)
int ast_register_application2(const char *app, int(*execute)(struct ast_channel *, const char *), const char *synopsis, const char *description, void *mod)
Register an application.
Definition: pbx_app.c:103
#define BACKGROUND_NOANSWER
Definition: pbx_builtins.c:653
int ast_playtones_start(struct ast_channel *chan, int vol, const char *tonelist, int interruptible)
Start playing a list of tones on a channel.
Definition: indications.c:302
int ast_tonepair_start(struct ast_channel *chan, int freq1, int freq2, int duration, int vol)
Definition: channel.c:7521
const char * ast_channel_context(const struct ast_channel *chan)
const char * data
Description of a tone.
Definition: indications.h:52
int ast_str2cause(const char *name) attribute_pure
Convert the string form of a cause code to a number.
Definition: channel.c:621
char x
Definition: extconf.c:81
static struct test_options options
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116
struct ast_flags * ast_channel_flags(struct ast_channel *chan)
#define AST_APP_OPTION(option, flagno)
Declares an application option that does not accept an argument.
int ast_app_parse_timelen(const char *timestr, int *result, enum ast_timelen defunit)
Common routine to parse time lengths, with optional time unit specifier.
Definition: main/app.c:3036
static int pbx_builtin_saydigits(struct ast_channel *chan, const char *data)
struct ast_app * pbx_findapp(const char *app)
Look up an application.
Definition: ael_main.c:165
Say numbers and dates (maybe words one day too)
static int pbx_builtin_waitdigit(struct ast_channel *chan, const char *data)
Definition: pbx_builtins.c:996
void ast_channel_priority_set(struct ast_channel *chan, int value)
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
Definition: channel.c:1439
static const char app[]
Definition: app_mysql.c:62
Asterisk module definitions.
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
Application convenience functions, designed to give consistent look and feel to Asterisk apps...
#define AST_CAUSE_CONGESTION
Definition: causes.h:152
int ast_waitfordigit_full(struct ast_channel *c, int ms, const char *breakon, int audiofd, int ctrlfd)
Wait for a digit Same as ast_waitfordigit() with audio fd for outputting read audio and ctrlfd to mon...
Definition: channel.c:3214
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:187
#define WAITEXTEN_DIALTONE
Definition: pbx_builtins.c:665
Declaration of builtin applications.
int ast_waitstream_exten(struct ast_channel *c, const char *context)
Waits for a stream to stop or digit matching a valid one digit exten to be pressed.
Definition: file.c:1794
#define AST_APP_ARG(name)
Define an application argument.
int rtimeoutms
Definition: pbx.h:213