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