summaryrefslogtreecommitdiff
path: root/main/pbx.c
diff options
context:
space:
mode:
authorGeorge Joseph <george.joseph@fairview5.com>2015-12-28 18:18:01 -0700
committerGeorge Joseph <george.joseph@fairview5.com>2015-12-30 20:24:02 -0700
commit5e67e51c6ae6a89f0d011809940da6c90e281e4d (patch)
tree987e0622ddbbe0e7627ea49e0da77c78cde04d50 /main/pbx.c
parent410c5ee0fc5f1ba8bc25ca6e2cdc11527f36b1b7 (diff)
main/pbx: Move pbx_builtin dialplan applications to pbx_builtins.c
We joked about splitting pbx.c into multiple files but this first step was fairly easy. All of the pbx_builtin dialplan applications have been moved into pbx_builtins.c and a new pbx_private.h file was added. load_pbx_builtins() is called by asterisk.c just after load_pbx(). A few functions were renamed and are cross-exposed between the 2 source files. Change-Id: I87066be3dbf7f5822942ac1449d98cc43fc7561a
Diffstat (limited to 'main/pbx.c')
-rw-r--r--main/pbx.c1484
1 files changed, 8 insertions, 1476 deletions
diff --git a/main/pbx.c b/main/pbx.c
index 202940e11..c54eca81d 100644
--- a/main/pbx.c
+++ b/main/pbx.c
@@ -73,6 +73,7 @@ ASTERISK_REGISTER_FILE()
#include "asterisk/stasis_channels.h"
#include "asterisk/dial.h"
#include "asterisk/vector.h"
+#include "pbx_private.h"
/*!
* \note I M P O R T A N T :
@@ -96,637 +97,6 @@ ASTERISK_REGISTER_FILE()
*/
/*** DOCUMENTATION
- <application name="Answer" language="en_US">
- <synopsis>
- Answer a channel if ringing.
- </synopsis>
- <syntax>
- <parameter name="delay">
- <para>Asterisk will wait this number of milliseconds before returning to
- the dialplan after answering the call.</para>
- </parameter>
- </syntax>
- <description>
- <para>If the call has not been answered, this application will
- answer it. Otherwise, it has no effect on the call.</para>
- </description>
- <see-also>
- <ref type="application">Hangup</ref>
- </see-also>
- </application>
- <application name="BackGround" language="en_US">
- <synopsis>
- Play an audio file while waiting for digits of an extension to go to.
- </synopsis>
- <syntax>
- <parameter name="filenames" required="true" argsep="&amp;">
- <argument name="filename1" required="true" />
- <argument name="filename2" multiple="true" />
- </parameter>
- <parameter name="options">
- <optionlist>
- <option name="s">
- <para>Causes the playback of the message to be skipped
- if the channel is not in the <literal>up</literal> state (i.e. it
- hasn't been answered yet). If this happens, the
- application will return immediately.</para>
- </option>
- <option name="n">
- <para>Don't answer the channel before playing the files.</para>
- </option>
- <option name="m">
- <para>Only break if a digit hit matches a one digit
- extension in the destination context.</para>
- </option>
- </optionlist>
- </parameter>
- <parameter name="langoverride">
- <para>Explicitly specifies which language to attempt to use for the requested sound files.</para>
- </parameter>
- <parameter name="context">
- <para>This is the dialplan context that this application will use when exiting
- to a dialed extension.</para>
- </parameter>
- </syntax>
- <description>
- <para>This application will play the given list of files <emphasis>(do not put extension)</emphasis>
- while waiting for an extension to be dialed by the calling channel. To continue waiting
- for digits after this application has finished playing files, the <literal>WaitExten</literal>
- application should be used.</para>
- <para>If one of the requested sound files does not exist, call processing will be terminated.</para>
- <para>This application sets the following channel variable upon completion:</para>
- <variablelist>
- <variable name="BACKGROUNDSTATUS">
- <para>The status of the background attempt as a text string.</para>
- <value name="SUCCESS" />
- <value name="FAILED" />
- </variable>
- </variablelist>
- </description>
- <see-also>
- <ref type="application">ControlPlayback</ref>
- <ref type="application">WaitExten</ref>
- <ref type="application">BackgroundDetect</ref>
- <ref type="function">TIMEOUT</ref>
- </see-also>
- </application>
- <application name="Busy" language="en_US">
- <synopsis>
- Indicate the Busy condition.
- </synopsis>
- <syntax>
- <parameter name="timeout">
- <para>If specified, the calling channel will be hung up after the specified number of seconds.
- Otherwise, this application will wait until the calling channel hangs up.</para>
- </parameter>
- </syntax>
- <description>
- <para>This application will indicate the busy condition to the calling channel.</para>
- </description>
- <see-also>
- <ref type="application">Congestion</ref>
- <ref type="application">Progress</ref>
- <ref type="application">Playtones</ref>
- <ref type="application">Hangup</ref>
- </see-also>
- </application>
- <application name="Congestion" language="en_US">
- <synopsis>
- Indicate the Congestion condition.
- </synopsis>
- <syntax>
- <parameter name="timeout">
- <para>If specified, the calling channel will be hung up after the specified number of seconds.
- Otherwise, this application will wait until the calling channel hangs up.</para>
- </parameter>
- </syntax>
- <description>
- <para>This application will indicate the congestion condition to the calling channel.</para>
- </description>
- <see-also>
- <ref type="application">Busy</ref>
- <ref type="application">Progress</ref>
- <ref type="application">Playtones</ref>
- <ref type="application">Hangup</ref>
- </see-also>
- </application>
- <application name="ExecIfTime" language="en_US">
- <synopsis>
- Conditional application execution based on the current time.
- </synopsis>
- <syntax argsep="?">
- <parameter name="day_condition" required="true">
- <argument name="times" required="true" />
- <argument name="weekdays" required="true" />
- <argument name="mdays" required="true" />
- <argument name="months" required="true" />
- <argument name="timezone" required="false" />
- </parameter>
- <parameter name="appname" required="true" hasparams="optional">
- <argument name="appargs" required="true" />
- </parameter>
- </syntax>
- <description>
- <para>This application will execute the specified dialplan application, with optional
- arguments, if the current time matches the given time specification.</para>
- </description>
- <see-also>
- <ref type="application">Exec</ref>
- <ref type="application">ExecIf</ref>
- <ref type="application">TryExec</ref>
- <ref type="application">GotoIfTime</ref>
- </see-also>
- </application>
- <application name="Goto" language="en_US">
- <synopsis>
- Jump to a particular priority, extension, or context.
- </synopsis>
- <syntax>
- <parameter name="context" />
- <parameter name="extensions" />
- <parameter name="priority" required="true" />
- </syntax>
- <description>
- <para>This application will set the current context, extension, and priority in the channel structure.
- After it completes, the pbx engine will continue dialplan execution at the specified location.
- If no specific <replaceable>extension</replaceable>, or <replaceable>extension</replaceable> and
- <replaceable>context</replaceable>, are specified, then this application will
- just set the specified <replaceable>priority</replaceable> of the current extension.</para>
- <para>At least a <replaceable>priority</replaceable> is required as an argument, or the goto will
- return a <literal>-1</literal>, and the channel and call will be terminated.</para>
- <para>If the location that is put into the channel information is bogus, and asterisk cannot
- find that location in the dialplan, then the execution engine will try to find and execute the code in
- the <literal>i</literal> (invalid) extension in the current context. If that does not exist, it will try to execute the
- <literal>h</literal> extension. If neither the <literal>h</literal> nor <literal>i</literal> extensions
- have been defined, the channel is hung up, and the execution of instructions on the channel is terminated.
- What this means is that, for example, you specify a context that does not exist, then
- it will not be possible to find the <literal>h</literal> or <literal>i</literal> extensions,
- and the call will terminate!</para>
- </description>
- <see-also>
- <ref type="application">GotoIf</ref>
- <ref type="application">GotoIfTime</ref>
- <ref type="application">Gosub</ref>
- <ref type="application">Macro</ref>
- </see-also>
- </application>
- <application name="GotoIf" language="en_US">
- <synopsis>
- Conditional goto.
- </synopsis>
- <syntax argsep="?">
- <parameter name="condition" required="true" />
- <parameter name="destination" required="true" argsep=":">
- <argument name="labeliftrue">
- <para>Continue at <replaceable>labeliftrue</replaceable> if the condition is true.
- Takes the form similar to Goto() of [[context,]extension,]priority.</para>
- </argument>
- <argument name="labeliffalse">
- <para>Continue at <replaceable>labeliffalse</replaceable> if the condition is false.
- Takes the form similar to Goto() of [[context,]extension,]priority.</para>
- </argument>
- </parameter>
- </syntax>
- <description>
- <para>This application will set the current context, extension, and priority in the channel structure
- based on the evaluation of the given condition. After this application completes, the
- pbx engine will continue dialplan execution at the specified location in the dialplan.
- The labels are specified with the same syntax as used within the Goto application.
- If the label chosen by the condition is omitted, no jump is performed, and the execution passes to the
- next instruction. If the target location is bogus, and does not exist, the execution engine will try
- to find and execute the code in the <literal>i</literal> (invalid) extension in the current context.
- If that does not exist, it will try to execute the <literal>h</literal> extension.
- If neither the <literal>h</literal> nor <literal>i</literal> extensions have been defined,
- the channel is hung up, and the execution of instructions on the channel is terminated.
- Remember that this command can set the current context, and if the context specified
- does not exist, then it will not be able to find any 'h' or 'i' extensions there, and
- the channel and call will both be terminated!.</para>
- </description>
- <see-also>
- <ref type="application">Goto</ref>
- <ref type="application">GotoIfTime</ref>
- <ref type="application">GosubIf</ref>
- <ref type="application">MacroIf</ref>
- </see-also>
- </application>
- <application name="GotoIfTime" language="en_US">
- <synopsis>
- Conditional Goto based on the current time.
- </synopsis>
- <syntax argsep="?">
- <parameter name="condition" required="true">
- <argument name="times" required="true" />
- <argument name="weekdays" required="true" />
- <argument name="mdays" required="true" />
- <argument name="months" required="true" />
- <argument name="timezone" required="false" />
- </parameter>
- <parameter name="destination" required="true" argsep=":">
- <argument name="labeliftrue">
- <para>Continue at <replaceable>labeliftrue</replaceable> if the condition is true.
- Takes the form similar to Goto() of [[context,]extension,]priority.</para>
- </argument>
- <argument name="labeliffalse">
- <para>Continue at <replaceable>labeliffalse</replaceable> if the condition is false.
- Takes the form similar to Goto() of [[context,]extension,]priority.</para>
- </argument>
- </parameter>
- </syntax>
- <description>
- <para>This application will set the context, extension, and priority in the channel structure
- based on the evaluation of the given time specification. After this application completes,
- the pbx engine will continue dialplan execution at the specified location in the dialplan.
- If the current time is within the given time specification, the channel will continue at
- <replaceable>labeliftrue</replaceable>. Otherwise the channel will continue at <replaceable>labeliffalse</replaceable>.
- If the label chosen by the condition is omitted, no jump is performed, and execution passes to the next
- instruction. If the target jump location is bogus, the same actions would be taken as for <literal>Goto</literal>.
- Further information on the time specification can be found in examples
- illustrating how to do time-based context includes in the dialplan.</para>
- </description>
- <see-also>
- <ref type="application">GotoIf</ref>
- <ref type="application">Goto</ref>
- <ref type="function">IFTIME</ref>
- <ref type="function">TESTTIME</ref>
- </see-also>
- </application>
- <application name="ImportVar" language="en_US">
- <synopsis>
- Import a variable from a channel into a new variable.
- </synopsis>
- <syntax argsep="=">
- <parameter name="newvar" required="true" />
- <parameter name="vardata" required="true">
- <argument name="channelname" required="true" />
- <argument name="variable" required="true" />
- </parameter>
- </syntax>
- <description>
- <para>This application imports a <replaceable>variable</replaceable> from the specified
- <replaceable>channel</replaceable> (as opposed to the current one) and stores it as a variable
- (<replaceable>newvar</replaceable>) in the current channel (the channel that is calling this
- application). Variables created by this application have the same inheritance properties as those
- created with the <literal>Set</literal> application.</para>
- </description>
- <see-also>
- <ref type="application">Set</ref>
- </see-also>
- </application>
- <application name="Hangup" language="en_US">
- <synopsis>
- Hang up the calling channel.
- </synopsis>
- <syntax>
- <parameter name="causecode">
- <para>If a <replaceable>causecode</replaceable> is given the channel's
- hangup cause will be set to the given value.</para>
- </parameter>
- </syntax>
- <description>
- <para>This application will hang up the calling channel.</para>
- </description>
- <see-also>
- <ref type="application">Answer</ref>
- <ref type="application">Busy</ref>
- <ref type="application">Congestion</ref>
- </see-also>
- </application>
- <application name="Incomplete" language="en_US">
- <synopsis>
- Returns AST_PBX_INCOMPLETE value.
- </synopsis>
- <syntax>
- <parameter name="n">
- <para>If specified, then Incomplete will not attempt to answer the channel first.</para>
- <note><para>Most channel types need to be in Answer state in order to receive DTMF.</para></note>
- </parameter>
- </syntax>
- <description>
- <para>Signals the PBX routines that the previous matched extension is incomplete
- and that further input should be allowed before matching can be considered
- to be complete. Can be used within a pattern match when certain criteria warrants
- a longer match.</para>
- </description>
- </application>
- <application name="NoOp" language="en_US">
- <synopsis>
- Do Nothing (No Operation).
- </synopsis>
- <syntax>
- <parameter name="text">
- <para>Any text provided can be viewed at the Asterisk CLI.</para>
- </parameter>
- </syntax>
- <description>
- <para>This application does nothing. However, it is useful for debugging purposes.</para>
- <para>This method can be used to see the evaluations of variables or functions without having any effect.</para>
- </description>
- <see-also>
- <ref type="application">Verbose</ref>
- <ref type="application">Log</ref>
- </see-also>
- </application>
- <application name="Proceeding" language="en_US">
- <synopsis>
- Indicate proceeding.
- </synopsis>
- <syntax />
- <description>
- <para>This application will request that a proceeding message be provided to the calling channel.</para>
- </description>
- </application>
- <application name="Progress" language="en_US">
- <synopsis>
- Indicate progress.
- </synopsis>
- <syntax />
- <description>
- <para>This application will request that in-band progress information be provided to the calling channel.</para>
- </description>
- <see-also>
- <ref type="application">Busy</ref>
- <ref type="application">Congestion</ref>
- <ref type="application">Ringing</ref>
- <ref type="application">Playtones</ref>
- </see-also>
- </application>
- <application name="RaiseException" language="en_US">
- <synopsis>
- Handle an exceptional condition.
- </synopsis>
- <syntax>
- <parameter name="reason" required="true" />
- </syntax>
- <description>
- <para>This application will jump to the <literal>e</literal> extension in the current context, setting the
- dialplan function EXCEPTION(). If the <literal>e</literal> extension does not exist, the call will hangup.</para>
- </description>
- <see-also>
- <ref type="function">Exception</ref>
- </see-also>
- </application>
- <application name="Ringing" language="en_US">
- <synopsis>
- Indicate ringing tone.
- </synopsis>
- <syntax />
- <description>
- <para>This application will request that the channel indicate a ringing tone to the user.</para>
- </description>
- <see-also>
- <ref type="application">Busy</ref>
- <ref type="application">Congestion</ref>
- <ref type="application">Progress</ref>
- <ref type="application">Playtones</ref>
- </see-also>
- </application>
- <application name="SayAlpha" language="en_US">
- <synopsis>
- Say Alpha.
- </synopsis>
- <syntax>
- <parameter name="string" required="true" />
- </syntax>
- <description>
- <para>This application will play the sounds that correspond to the letters
- of the given <replaceable>string</replaceable>. If the channel variable
- <variable>SAY_DTMF_INTERRUPT</variable> is set to 'true' (case insensitive),
- then this application will react to DTMF in the same way as
- <literal>Background</literal>.</para>
- </description>
- <see-also>
- <ref type="application">SayDigits</ref>
- <ref type="application">SayNumber</ref>
- <ref type="application">SayPhonetic</ref>
- <ref type="function">CHANNEL</ref>
- </see-also>
- </application>
- <application name="SayAlphaCase" language="en_US">
- <synopsis>
- Say Alpha.
- </synopsis>
- <syntax>
- <parameter name="casetype" required="true" >
- <enumlist>
- <enum name="a">
- <para>Case sensitive (all) pronunciation.
- (Ex: SayAlphaCase(a,aBc); - lowercase a uppercase b lowercase c).</para>
- </enum>
- <enum name="l">
- <para>Case sensitive (lower) pronunciation.
- (Ex: SayAlphaCase(l,aBc); - lowercase a b lowercase c).</para>
- </enum>
- <enum name="n">
- <para>Case insensitive pronunciation. Equivalent to SayAlpha.
- (Ex: SayAlphaCase(n,aBc) - a b c).</para>
- </enum>
- <enum name="u">
- <para>Case sensitive (upper) pronunciation.
- (Ex: SayAlphaCase(u,aBc); - a uppercase b c).</para>
- </enum>
- </enumlist>
- </parameter>
- <parameter name="string" required="true" />
- </syntax>
- <description>
- <para>This application will play the sounds that correspond to the letters of the
- given <replaceable>string</replaceable>. Optionally, a <replaceable>casetype</replaceable> may be
- specified. This will be used for case-insensitive or case-sensitive pronunciations. If the channel
- variable <variable>SAY_DTMF_INTERRUPT</variable> is set to 'true' (case insensitive), then this
- application will react to DTMF in the same way as <literal>Background</literal>.</para>
- </description>
- <see-also>
- <ref type="application">SayDigits</ref>
- <ref type="application">SayNumber</ref>
- <ref type="application">SayPhonetic</ref>
- <ref type="application">SayAlpha</ref>
- <ref type="function">CHANNEL</ref>
- </see-also>
- </application>
- <application name="SayDigits" language="en_US">
- <synopsis>
- Say Digits.
- </synopsis>
- <syntax>
- <parameter name="digits" required="true" />
- </syntax>
- <description>
- <para>This application will play the sounds that correspond to the digits of
- the given number. This will use the language that is currently set for the channel.
- If the channel variable <variable>SAY_DTMF_INTERRUPT</variable> is set to 'true'
- (case insensitive), then this application will react to DTMF in the same way as
- <literal>Background</literal>.</para>
- </description>
- <see-also>
- <ref type="application">SayAlpha</ref>
- <ref type="application">SayNumber</ref>
- <ref type="application">SayPhonetic</ref>
- <ref type="function">CHANNEL</ref>
- </see-also>
- </application>
- <application name="SayNumber" language="en_US">
- <synopsis>
- Say Number.
- </synopsis>
- <syntax>
- <parameter name="digits" required="true" />
- <parameter name="gender" />
- </syntax>
- <description>
- <para>This application will play the sounds that correspond to the given
- <replaceable>digits</replaceable>. Optionally, a <replaceable>gender</replaceable> may be
- specified. This will use the language that is currently set for the channel. See the CHANNEL()
- function for more information on setting the language for the channel. If the channel variable
- <variable>SAY_DTMF_INTERRUPT</variable> is set to 'true' (case insensitive), then this
- application will react to DTMF in the same way as <literal>Background</literal>.</para>
- </description>
- <see-also>
- <ref type="application">SayAlpha</ref>
- <ref type="application">SayDigits</ref>
- <ref type="application">SayPhonetic</ref>
- <ref type="function">CHANNEL</ref>
- </see-also>
- </application>
- <application name="SayPhonetic" language="en_US">
- <synopsis>
- Say Phonetic.
- </synopsis>
- <syntax>
- <parameter name="string" required="true" />
- </syntax>
- <description>
- <para>This application will play the sounds from the phonetic alphabet that correspond to the
- letters in the given <replaceable>string</replaceable>. If the channel variable
- <variable>SAY_DTMF_INTERRUPT</variable> is set to 'true' (case insensitive), then this
- application will react to DTMF in the same way as <literal>Background</literal>.</para>
- </description>
- <see-also>
- <ref type="application">SayAlpha</ref>
- <ref type="application">SayDigits</ref>
- <ref type="application">SayNumber</ref>
- </see-also>
- </application>
- <application name="Set" language="en_US">
- <synopsis>
- Set channel variable or function value.
- </synopsis>
- <syntax argsep="=">
- <parameter name="name" required="true" />
- <parameter name="value" required="true" />
- </syntax>
- <description>
- <para>This function can be used to set the value of channel variables or dialplan functions.
- When setting variables, if the variable name is prefixed with <literal>_</literal>,
- the variable will be inherited into channels created from the current channel.
- If the variable name is prefixed with <literal>__</literal>, the variable will be
- inherited into channels created from the current channel and all children channels.</para>
- <note><para>If (and only if), in <filename>/etc/asterisk/asterisk.conf</filename>, you have
- a <literal>[compat]</literal> category, and you have <literal>app_set = 1.4</literal> under that, then
- the behavior of this app changes, and strips surrounding quotes from the right hand side as
- it did previously in 1.4.
- The advantages of not stripping out quoting, and not caring about the separator characters (comma and vertical bar)
- were sufficient to make these changes in 1.6. Confusion about how many backslashes would be needed to properly
- protect separators and quotes in various database access strings has been greatly
- reduced by these changes.</para></note>
- </description>
- <see-also>
- <ref type="application">MSet</ref>
- <ref type="function">GLOBAL</ref>
- <ref type="function">SET</ref>
- <ref type="function">ENV</ref>
- </see-also>
- </application>
- <application name="MSet" language="en_US">
- <synopsis>
- Set channel variable(s) or function value(s).
- </synopsis>
- <syntax>
- <parameter name="set1" required="true" argsep="=">
- <argument name="name1" required="true" />
- <argument name="value1" required="true" />
- </parameter>
- <parameter name="set2" multiple="true" argsep="=">
- <argument name="name2" required="true" />
- <argument name="value2" required="true" />
- </parameter>
- </syntax>
- <description>
- <para>This function can be used to set the value of channel variables or dialplan functions.
- When setting variables, if the variable name is prefixed with <literal>_</literal>,
- the variable will be inherited into channels created from the current channel
- If the variable name is prefixed with <literal>__</literal>, the variable will be
- inherited into channels created from the current channel and all children channels.
- MSet behaves in a similar fashion to the way Set worked in 1.2/1.4 and is thus
- prone to doing things that you may not expect. For example, it strips surrounding
- double-quotes from the right-hand side (value). If you need to put a separator
- character (comma or vert-bar), you will need to escape them by inserting a backslash
- before them. Avoid its use if possible.</para>
- </description>
- <see-also>
- <ref type="application">Set</ref>
- </see-also>
- </application>
- <application name="SetAMAFlags" language="en_US">
- <synopsis>
- Set the AMA Flags.
- </synopsis>
- <syntax>
- <parameter name="flag" />
- </syntax>
- <description>
- <para>This application will set the channel's AMA Flags for billing purposes.</para>
- <warning><para>This application is deprecated. Please use the CHANNEL function instead.</para></warning>
- </description>
- <see-also>
- <ref type="function">CDR</ref>
- <ref type="function">CHANNEL</ref>
- </see-also>
- </application>
- <application name="Wait" language="en_US">
- <synopsis>
- Waits for some time.
- </synopsis>
- <syntax>
- <parameter name="seconds" required="true">
- <para>Can be passed with fractions of a second. For example, <literal>1.5</literal> will ask the
- application to wait for 1.5 seconds.</para>
- </parameter>
- </syntax>
- <description>
- <para>This application waits for a specified number of <replaceable>seconds</replaceable>.</para>
- </description>
- </application>
- <application name="WaitExten" language="en_US">
- <synopsis>
- Waits for an extension to be entered.
- </synopsis>
- <syntax>
- <parameter name="seconds">
- <para>Can be passed with fractions of a second. For example, <literal>1.5</literal> will ask the
- application to wait for 1.5 seconds.</para>
- </parameter>
- <parameter name="options">
- <optionlist>
- <option name="m">
- <para>Provide music on hold to the caller while waiting for an extension.</para>
- <argument name="x">
- <para>Specify the class for music on hold. <emphasis>CHANNEL(musicclass) will
- be used instead if set</emphasis></para>
- </argument>
- </option>
- </optionlist>
- </parameter>
- </syntax>
- <description>
- <para>This application waits for the user to enter a new extension for a specified number
- of <replaceable>seconds</replaceable>.</para>
- <xi:include xpointer="xpointer(/docs/application[@name='Macro']/description/warning[2])" />
- </description>
- <see-also>
- <ref type="application">Background</ref>
- <ref type="function">TIMEOUT</ref>
- </see-also>
- </application>
<function name="EXCEPTION" language="en_US">
<synopsis>
Retrieve the details of the current dialplan exception.
@@ -850,32 +220,10 @@ ASTERISK_REGISTER_FILE()
#define SWITCH_DATA_LENGTH 256
-#define VAR_BUF_SIZE 4096
-
#define VAR_NORMAL 1
#define VAR_SOFTTRAN 2
#define VAR_HARDTRAN 3
-#define BACKGROUND_SKIP (1 << 0)
-#define BACKGROUND_NOANSWER (1 << 1)
-#define BACKGROUND_MATCHEXTEN (1 << 2)
-#define BACKGROUND_PLAYBACK (1 << 3)
-
-AST_APP_OPTIONS(background_opts, {
- AST_APP_OPTION('s', BACKGROUND_SKIP),
- AST_APP_OPTION('n', BACKGROUND_NOANSWER),
- AST_APP_OPTION('m', BACKGROUND_MATCHEXTEN),
- AST_APP_OPTION('p', BACKGROUND_PLAYBACK),
-});
-
-#define WAITEXTEN_MOH (1 << 0)
-#define WAITEXTEN_DIALTONE (1 << 1)
-
-AST_APP_OPTIONS(waitexten_opts, {
- AST_APP_OPTION_ARG('m', WAITEXTEN_MOH, 0),
- AST_APP_OPTION_ARG('d', WAITEXTEN_DIALTONE, 0),
-});
-
struct ast_context;
struct ast_app;
@@ -1263,34 +611,10 @@ struct pbx_exception {
int priority; /*!< Priority associated with this exception */
};
-static int pbx_builtin_answer(struct ast_channel *, const char *);
-static int pbx_builtin_goto(struct ast_channel *, const char *);
-static int pbx_builtin_hangup(struct ast_channel *, const char *);
-static int pbx_builtin_background(struct ast_channel *, const char *);
-static int pbx_builtin_wait(struct ast_channel *, const char *);
-static int pbx_builtin_waitexten(struct ast_channel *, const char *);
-static int pbx_builtin_incomplete(struct ast_channel *, const char *);
-static int pbx_builtin_setamaflags(struct ast_channel *, const char *);
-static int pbx_builtin_ringing(struct ast_channel *, const char *);
-static int pbx_builtin_proceeding(struct ast_channel *, const char *);
-static int pbx_builtin_progress(struct ast_channel *, const char *);
-static int pbx_builtin_congestion(struct ast_channel *, const char *);
-static int pbx_builtin_busy(struct ast_channel *, const char *);
-static int pbx_builtin_noop(struct ast_channel *, const char *);
-static int pbx_builtin_gotoif(struct ast_channel *, const char *);
-static int pbx_builtin_gotoiftime(struct ast_channel *, const char *);
-static int pbx_builtin_execiftime(struct ast_channel *, const char *);
-static int pbx_builtin_saynumber(struct ast_channel *, const char *);
-static int pbx_builtin_saydigits(struct ast_channel *, const char *);
-static int pbx_builtin_saycharacters(struct ast_channel *, const char *);
-static int pbx_builtin_saycharacters_case(struct ast_channel *, const char *);
-static int pbx_builtin_sayphonetic(struct ast_channel *, const char *);
static int matchcid(const char *cidpattern, const char *callerid);
#ifdef NEED_DEBUG
static void log_match_char_tree(struct match_char *node, char *prefix); /* for use anywhere */
#endif
-static int pbx_builtin_importvar(struct ast_channel *, const char *);
-static void set_ext_pri(struct ast_channel *c, const char *exten, int pri);
static void new_find_extension(const char *str, struct scoreboard *score,
struct match_char *tree, int length, int spec, const char *callerid,
const char *label, enum ext_match_t action);
@@ -1442,43 +766,6 @@ static int totalcalls;
*/
static AST_RWLIST_HEAD_STATIC(acf_root, ast_custom_function);
-/*! \brief Declaration of builtin applications */
-static struct pbx_builtin {
- char name[AST_MAX_APP];
- int (*execute)(struct ast_channel *chan, const char *data);
-} builtins[] =
-{
- /* These applications are built into the PBX core and do not
- need separate modules */
-
- { "Answer", pbx_builtin_answer },
- { "BackGround", pbx_builtin_background },
- { "Busy", pbx_builtin_busy },
- { "Congestion", pbx_builtin_congestion },
- { "ExecIfTime", pbx_builtin_execiftime },
- { "Goto", pbx_builtin_goto },
- { "GotoIf", pbx_builtin_gotoif },
- { "GotoIfTime", pbx_builtin_gotoiftime },
- { "ImportVar", pbx_builtin_importvar },
- { "Hangup", pbx_builtin_hangup },
- { "Incomplete", pbx_builtin_incomplete },
- { "NoOp", pbx_builtin_noop },
- { "Proceeding", pbx_builtin_proceeding },
- { "Progress", pbx_builtin_progress },
- { "RaiseException", pbx_builtin_raise_exception },
- { "Ringing", pbx_builtin_ringing },
- { "SayAlpha", pbx_builtin_saycharacters },
- { "SayAlphaCase", pbx_builtin_saycharacters_case },
- { "SayDigits", pbx_builtin_saydigits },
- { "SayNumber", pbx_builtin_saynumber },
- { "SayPhonetic", pbx_builtin_sayphonetic },
- { "Set", pbx_builtin_setvar },
- { "MSet", pbx_builtin_setvar_multiple },
- { "SetAMAFlags", pbx_builtin_setamaflags },
- { "Wait", pbx_builtin_wait },
- { "WaitExten", pbx_builtin_waitexten }
-};
-
static struct ast_context *contexts;
static struct ast_hashtab *contexts_table = NULL;
@@ -3822,7 +3109,7 @@ static const struct ast_datastore_info exception_store_info = {
* \retval 0 on success.
* \retval -1 on error.
*/
-static int raise_exception(struct ast_channel *chan, const char *reason, int priority)
+int raise_exception(struct ast_channel *chan, const char *reason, int priority)
{
struct ast_datastore *ds = ast_channel_datastore_find(chan, &exception_store_info, NULL);
struct pbx_exception *exception = NULL;
@@ -3848,12 +3135,6 @@ static int raise_exception(struct ast_channel *chan, const char *reason, int pri
return 0;
}
-int pbx_builtin_raise_exception(struct ast_channel *chan, const char *reason)
-{
- /* Priority will become 1, next time through the AUTOLOOP */
- return raise_exception(chan, reason, 0);
-}
-
static int acf_exception_read(struct ast_channel *chan, const char *name, char *data, char *buf, size_t buflen)
{
struct ast_datastore *ds = ast_channel_datastore_find(chan, &exception_store_info, NULL);
@@ -6463,7 +5744,7 @@ static char *handle_show_hangup_all(struct ast_cli_entry *e, int cmd, struct ast
}
/*! helper function to set extension and priority */
-static void set_ext_pri(struct ast_channel *c, const char *exten, int pri)
+void set_ext_pri(struct ast_channel *c, const char *exten, int pri)
{
ast_channel_lock(c);
ast_channel_exten_set(c, exten);
@@ -6723,11 +6004,11 @@ static enum ast_pbx_result __ast_pbx_run(struct ast_channel *c,
status = "UNKNOWN";
ast_verb(3, "Auto fallthrough, channel '%s' status is '%s'\n", ast_channel_name(c), status);
if (!strcasecmp(status, "CONGESTION"))
- res = pbx_builtin_congestion(c, "10");
+ res = indicate_congestion(c, "10");
else if (!strcasecmp(status, "CHANUNAVAIL"))
- res = pbx_builtin_congestion(c, "10");
+ res = indicate_congestion(c, "10");
else if (!strcasecmp(status, "BUSY"))
- res = pbx_builtin_busy(c, "10");
+ res = indicate_busy(c, "10");
error = 1; /* XXX disable message */
break; /* exit from the 'for' loop */
}
@@ -11047,7 +10328,7 @@ void ast_context_destroy(struct ast_context *con, const char *registrar)
ast_unlock_contexts();
}
-static void wait_for_hangup(struct ast_channel *chan, const void *data)
+void wait_for_hangup(struct ast_channel *chan, const void *data)
{
int res;
struct ast_frame *f;
@@ -11070,188 +10351,6 @@ static void wait_for_hangup(struct ast_channel *chan, const void *data)
}
/*!
- * \ingroup applications
- */
-static int pbx_builtin_proceeding(struct ast_channel *chan, const char *data)
-{
- ast_indicate(chan, AST_CONTROL_PROCEEDING);
- return 0;
-}
-
-/*!
- * \ingroup applications
- */
-static int pbx_builtin_progress(struct ast_channel *chan, const char *data)
-{
- ast_indicate(chan, AST_CONTROL_PROGRESS);
- return 0;
-}
-
-/*!
- * \ingroup applications
- */
-static int pbx_builtin_ringing(struct ast_channel *chan, const char *data)
-{
- ast_indicate(chan, AST_CONTROL_RINGING);
- return 0;
-}
-
-/*!
- * \ingroup applications
- */
-static int pbx_builtin_busy(struct ast_channel *chan, const char *data)
-{
- ast_indicate(chan, AST_CONTROL_BUSY);
- /* Don't change state of an UP channel, just indicate
- busy in audio */
- ast_channel_lock(chan);
- if (ast_channel_state(chan) != AST_STATE_UP) {
- ast_channel_hangupcause_set(chan, AST_CAUSE_BUSY);
- ast_setstate(chan, AST_STATE_BUSY);
- }
- ast_channel_unlock(chan);
- wait_for_hangup(chan, data);
- return -1;
-}
-
-/*!
- * \ingroup applications
- */
-static int pbx_builtin_congestion(struct ast_channel *chan, const char *data)
-{
- ast_indicate(chan, AST_CONTROL_CONGESTION);
- /* Don't change state of an UP channel, just indicate
- congestion in audio */
- ast_channel_lock(chan);
- if (ast_channel_state(chan) != AST_STATE_UP) {
- ast_channel_hangupcause_set(chan, AST_CAUSE_CONGESTION);
- ast_setstate(chan, AST_STATE_BUSY);
- }
- ast_channel_unlock(chan);
- wait_for_hangup(chan, data);
- return -1;
-}
-
-/*!
- * \ingroup applications
- */
-static int pbx_builtin_answer(struct ast_channel *chan, const char *data)
-{
- int delay = 0;
- char *parse;
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(delay);
- AST_APP_ARG(answer_cdr);
- );
-
- if (ast_strlen_zero(data)) {
- return __ast_answer(chan, 0);
- }
-
- parse = ast_strdupa(data);
-
- AST_STANDARD_APP_ARGS(args, parse);
-
- if (!ast_strlen_zero(args.delay) && (ast_channel_state(chan) != AST_STATE_UP))
- delay = atoi(data);
-
- if (delay < 0) {
- delay = 0;
- }
-
- if (!ast_strlen_zero(args.answer_cdr) && !strcasecmp(args.answer_cdr, "nocdr")) {
- ast_log(AST_LOG_WARNING, "The nocdr option for the Answer application has been removed and is no longer supported.\n");
- }
-
- return __ast_answer(chan, delay);
-}
-
-static int pbx_builtin_incomplete(struct ast_channel *chan, const char *data)
-{
- const char *options = data;
- int answer = 1;
-
- /* Some channels can receive DTMF in unanswered state; some cannot */
- if (!ast_strlen_zero(options) && strchr(options, 'n')) {
- answer = 0;
- }
-
- /* If the channel is hungup, stop waiting */
- if (ast_check_hangup(chan)) {
- return -1;
- } else if (ast_channel_state(chan) != AST_STATE_UP && answer) {
- __ast_answer(chan, 0);
- }
-
- ast_indicate(chan, AST_CONTROL_INCOMPLETE);
-
- return AST_PBX_INCOMPLETE;
-}
-
-/*!
- * \ingroup applications
- */
-static int pbx_builtin_setamaflags(struct ast_channel *chan, const char *data)
-{
- ast_log(AST_LOG_WARNING, "The SetAMAFlags application is deprecated. Please use the CHANNEL function instead.\n");
-
- if (ast_strlen_zero(data)) {
- ast_log(AST_LOG_WARNING, "No parameter passed to SetAMAFlags\n");
- return 0;
- }
- /* Copy the AMA Flags as specified */
- ast_channel_lock(chan);
- if (isdigit(data[0])) {
- int amaflags;
- if (sscanf(data, "%30d", &amaflags) != 1) {
- ast_log(AST_LOG_WARNING, "Unable to set AMA flags on channel %s\n", ast_channel_name(chan));
- ast_channel_unlock(chan);
- return 0;
- }
- ast_channel_amaflags_set(chan, amaflags);
- } else {
- ast_channel_amaflags_set(chan, ast_channel_string2amaflag(data));
- }
- ast_channel_unlock(chan);
- return 0;
-}
-
-/*!
- * \ingroup applications
- */
-static int pbx_builtin_hangup(struct ast_channel *chan, const char *data)
-{
- int cause;
-
- ast_set_hangupsource(chan, "dialplan/builtin", 0);
-
- if (!ast_strlen_zero(data)) {
- cause = ast_str2cause(data);
- if (cause <= 0) {
- if (sscanf(data, "%30d", &cause) != 1 || cause <= 0) {
- ast_log(LOG_WARNING, "Invalid cause given to Hangup(): \"%s\"\n", data);
- cause = 0;
- }
- }
- } else {
- cause = 0;
- }
-
- ast_channel_lock(chan);
- if (cause <= 0) {
- cause = ast_channel_hangupcause(chan);
- if (cause <= 0) {
- cause = AST_CAUSE_NORMAL_CLEARING;
- }
- }
- ast_channel_hangupcause_set(chan, cause);
- ast_softhangup_nolock(chan, AST_SOFTHANGUP_EXPLICIT);
- ast_channel_unlock(chan);
-
- return -1;
-}
-
-/*!
* \ingroup functions
*/
static int testtime_write(struct ast_channel *chan, const char *cmd, char *var, const char *value)
@@ -11283,333 +10382,6 @@ static struct ast_custom_function testtime_function = {
.write = testtime_write,
};
-/*!
- * \ingroup applications
- */
-static int pbx_builtin_gotoiftime(struct ast_channel *chan, const char *data)
-{
- char *s, *ts, *branch1, *branch2, *branch;
- struct ast_timing timing;
- const char *ctime;
- struct timeval tv = ast_tvnow();
- long timesecs;
-
- if (!chan) {
- ast_log(LOG_WARNING, "GotoIfTime requires a channel on which to operate\n");
- return -1;
- }
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "GotoIfTime requires an argument:\n <time range>,<days of week>,<days of month>,<months>[,<timezone>]?'labeliftrue':'labeliffalse'\n");
- return -1;
- }
-
- ts = s = ast_strdupa(data);
-
- ast_channel_lock(chan);
- if ((ctime = pbx_builtin_getvar_helper(chan, "TESTTIME")) && sscanf(ctime, "%ld", &timesecs) == 1) {
- tv.tv_sec = timesecs;
- } else if (ctime) {
- ast_log(LOG_WARNING, "Using current time to evaluate\n");
- /* Reset when unparseable */
- pbx_builtin_setvar_helper(chan, "TESTTIME", NULL);
- }
- ast_channel_unlock(chan);
-
- /* Separate the Goto path */
- strsep(&ts, "?");
- branch1 = strsep(&ts,":");
- branch2 = strsep(&ts,"");
-
- /* struct ast_include include contained garbage here, fixed by zeroing it on get_timerange */
- if (ast_build_timing(&timing, s) && ast_check_timing2(&timing, tv)) {
- branch = branch1;
- } else {
- branch = branch2;
- }
- ast_destroy_timing(&timing);
-
- if (ast_strlen_zero(branch)) {
- ast_debug(1, "Not taking any branch\n");
- return 0;
- }
-
- return pbx_builtin_goto(chan, branch);
-}
-
-/*!
- * \ingroup applications
- */
-static int pbx_builtin_execiftime(struct ast_channel *chan, const char *data)
-{
- char *s, *appname;
- struct ast_timing timing;
- struct ast_app *app;
- static const char * const usage = "ExecIfTime requires an argument:\n <time range>,<days of week>,<days of month>,<months>[,<timezone>]?<appname>[(<appargs>)]";
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "%s\n", usage);
- return -1;
- }
-
- appname = ast_strdupa(data);
-
- s = strsep(&appname, "?"); /* Separate the timerange and application name/data */
- if (!appname) { /* missing application */
- ast_log(LOG_WARNING, "%s\n", usage);
- return -1;
- }
-
- if (!ast_build_timing(&timing, s)) {
- ast_log(LOG_WARNING, "Invalid Time Spec: %s\nCorrect usage: %s\n", s, usage);
- ast_destroy_timing(&timing);
- return -1;
- }
-
- if (!ast_check_timing(&timing)) { /* outside the valid time window, just return */
- ast_destroy_timing(&timing);
- return 0;
- }
- ast_destroy_timing(&timing);
-
- /* now split appname(appargs) */
- if ((s = strchr(appname, '('))) {
- char *e;
- *s++ = '\0';
- if ((e = strrchr(s, ')')))
- *e = '\0';
- else
- ast_log(LOG_WARNING, "Failed to find closing parenthesis\n");
- }
-
-
- if ((app = pbx_findapp(appname))) {
- return pbx_exec(chan, app, S_OR(s, ""));
- } else {
- ast_log(LOG_WARNING, "Cannot locate application %s\n", appname);
- return -1;
- }
-}
-
-/*!
- * \ingroup applications
- */
-static int pbx_builtin_wait(struct ast_channel *chan, const char *data)
-{
- int ms;
-
- /* Wait for "n" seconds */
- if (!ast_app_parse_timelen(data, &ms, TIMELEN_SECONDS) && ms > 0) {
- return ast_safe_sleep(chan, ms);
- }
- return 0;
-}
-
-/*!
- * \ingroup applications
- */
-static int pbx_builtin_waitexten(struct ast_channel *chan, const char *data)
-{
- int ms, res;
- struct ast_flags flags = {0};
- char *opts[1] = { NULL };
- char *parse;
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(timeout);
- AST_APP_ARG(options);
- );
-
- if (!ast_strlen_zero(data)) {
- parse = ast_strdupa(data);
- AST_STANDARD_APP_ARGS(args, parse);
- } else
- memset(&args, 0, sizeof(args));
-
- if (args.options)
- ast_app_parse_options(waitexten_opts, &flags, opts, args.options);
-
- if (ast_test_flag(&flags, WAITEXTEN_MOH) && !opts[0] ) {
- ast_log(LOG_WARNING, "The 'm' option has been specified for WaitExten without a class.\n");
- } else if (ast_test_flag(&flags, WAITEXTEN_MOH)) {
- ast_indicate_data(chan, AST_CONTROL_HOLD, S_OR(opts[0], NULL),
- !ast_strlen_zero(opts[0]) ? strlen(opts[0]) + 1 : 0);
- } else if (ast_test_flag(&flags, WAITEXTEN_DIALTONE)) {
- struct ast_tone_zone_sound *ts = ast_get_indication_tone(ast_channel_zone(chan), "dial");
- if (ts) {
- ast_playtones_start(chan, 0, ts->data, 0);
- ts = ast_tone_zone_sound_unref(ts);
- } else {
- ast_tonepair_start(chan, 350, 440, 0, 0);
- }
- }
- /* Wait for "n" seconds */
- if (!ast_app_parse_timelen(args.timeout, &ms, TIMELEN_SECONDS) && ms > 0) {
- /* Yay! */
- } else if (ast_channel_pbx(chan)) {
- ms = ast_channel_pbx(chan)->rtimeoutms;
- } else {
- ms = 10000;
- }
-
- res = ast_waitfordigit(chan, ms);
- if (!res) {
- if (ast_check_hangup(chan)) {
- /* Call is hungup for some reason. */
- res = -1;
- } else if (ast_exists_extension(chan, ast_channel_context(chan), ast_channel_exten(chan), ast_channel_priority(chan) + 1,
- S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))) {
- ast_verb(3, "Timeout on %s, continuing...\n", ast_channel_name(chan));
- } else if (ast_exists_extension(chan, ast_channel_context(chan), "t", 1,
- S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))) {
- ast_verb(3, "Timeout on %s, going to 't'\n", ast_channel_name(chan));
- set_ext_pri(chan, "t", 0); /* 0 will become 1, next time through the loop */
- } else if (ast_exists_extension(chan, ast_channel_context(chan), "e", 1,
- S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))) {
- raise_exception(chan, "RESPONSETIMEOUT", 0); /* 0 will become 1, next time through the loop */
- } else {
- ast_log(LOG_WARNING, "Timeout but no rule 't' or 'e' in context '%s'\n",
- ast_channel_context(chan));
- res = -1;
- }
- }
-
- if (ast_test_flag(&flags, WAITEXTEN_MOH))
- ast_indicate(chan, AST_CONTROL_UNHOLD);
- else if (ast_test_flag(&flags, WAITEXTEN_DIALTONE))
- ast_playtones_stop(chan);
-
- return res;
-}
-
-/*!
- * \ingroup applications
- */
-static int pbx_builtin_background(struct ast_channel *chan, const char *data)
-{
- int res = 0;
- int mres = 0;
- struct ast_flags flags = {0};
- char *parse, exten[2] = "";
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(filename);
- AST_APP_ARG(options);
- AST_APP_ARG(lang);
- AST_APP_ARG(context);
- );
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "Background requires an argument (filename)\n");
- return -1;
- }
-
- parse = ast_strdupa(data);
-
- AST_STANDARD_APP_ARGS(args, parse);
-
- if (ast_strlen_zero(args.lang))
- args.lang = (char *)ast_channel_language(chan); /* XXX this is const */
-
- if (ast_strlen_zero(args.context)) {
- const char *context;
- ast_channel_lock(chan);
- if ((context = pbx_builtin_getvar_helper(chan, "MACRO_CONTEXT"))) {
- args.context = ast_strdupa(context);
- } else {
- args.context = ast_strdupa(ast_channel_context(chan));
- }
- ast_channel_unlock(chan);
- }
-
- if (args.options) {
- if (!strcasecmp(args.options, "skip"))
- flags.flags = BACKGROUND_SKIP;
- else if (!strcasecmp(args.options, "noanswer"))
- flags.flags = BACKGROUND_NOANSWER;
- else
- ast_app_parse_options(background_opts, &flags, NULL, args.options);
- }
-
- /* Answer if need be */
- if (ast_channel_state(chan) != AST_STATE_UP) {
- if (ast_test_flag(&flags, BACKGROUND_SKIP)) {
- goto done;
- } else if (!ast_test_flag(&flags, BACKGROUND_NOANSWER)) {
- res = ast_answer(chan);
- }
- }
-
- if (!res) {
- char *back = ast_strip(args.filename);
- char *front;
-
- ast_stopstream(chan); /* Stop anything playing */
- /* Stream the list of files */
- while (!res && (front = strsep(&back, "&")) ) {
- if ( (res = ast_streamfile(chan, front, args.lang)) ) {
- ast_log(LOG_WARNING, "ast_streamfile failed on %s for %s\n", ast_channel_name(chan), (char*)data);
- res = 0;
- mres = 1;
- break;
- }
- if (ast_test_flag(&flags, BACKGROUND_PLAYBACK)) {
- res = ast_waitstream(chan, "");
- } else if (ast_test_flag(&flags, BACKGROUND_MATCHEXTEN)) {
- res = ast_waitstream_exten(chan, args.context);
- } else {
- res = ast_waitstream(chan, AST_DIGIT_ANY);
- }
- ast_stopstream(chan);
- }
- }
-
- /*
- * If the single digit DTMF is an extension in the specified context, then
- * go there and signal no DTMF. Otherwise, we should exit with that DTMF.
- * If we're in Macro, we'll exit and seek that DTMF as the beginning of an
- * extension in the Macro's calling context. If we're not in Macro, then
- * we'll simply seek that extension in the calling context. Previously,
- * someone complained about the behavior as it related to the interior of a
- * Gosub routine, and the fix (#14011) inadvertently broke FreePBX
- * (#14940). This change should fix both of these situations, but with the
- * possible incompatibility that if a single digit extension does not exist
- * (but a longer extension COULD have matched), it would have previously
- * gone immediately to the "i" extension, but will now need to wait for a
- * timeout.
- *
- * Later, we had to add a flag to disable this workaround, because AGI
- * users can EXEC Background and reasonably expect that the DTMF code will
- * be returned (see #16434).
- */
- if (!ast_test_flag(ast_channel_flags(chan), AST_FLAG_DISABLE_WORKAROUNDS)
- && (exten[0] = res)
- && ast_canmatch_extension(chan, args.context, exten, 1,
- S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))
- && !ast_matchmore_extension(chan, args.context, exten, 1,
- S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))) {
- char buf[2] = { 0, };
- snprintf(buf, sizeof(buf), "%c", res);
- ast_channel_exten_set(chan, buf);
- ast_channel_context_set(chan, args.context);
- ast_channel_priority_set(chan, 0);
- res = 0;
- }
-done:
- pbx_builtin_setvar_helper(chan, "BACKGROUNDSTATUS", mres ? "FAILED" : "SUCCESS");
- return res;
-}
-
-/*! Goto
- * \ingroup applications
- */
-static int pbx_builtin_goto(struct ast_channel *chan, const char *data)
-{
- int res = ast_parseable_goto(chan, data);
- if (!res)
- ast_verb(3, "Goto (%s,%s,%d)\n", ast_channel_context(chan), ast_channel_exten(chan), ast_channel_priority(chan) + 1);
- return res;
-}
-
-
int pbx_builtin_serialize_variables(struct ast_channel *chan, struct ast_str **buf)
{
struct ast_var_t *variables;
@@ -11832,46 +10604,6 @@ int pbx_builtin_setvar_multiple(struct ast_channel *chan, const char *vdata)
return 0;
}
-int pbx_builtin_importvar(struct ast_channel *chan, const char *data)
-{
- char *name;
- char *value;
- char *channel;
- char tmp[VAR_BUF_SIZE];
- static int deprecation_warning = 0;
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "Ignoring, since there is no variable to set\n");
- return 0;
- }
- tmp[0] = 0;
- if (!deprecation_warning) {
- ast_log(LOG_WARNING, "ImportVar is deprecated. Please use Set(varname=${IMPORT(channel,variable)}) instead.\n");
- deprecation_warning = 1;
- }
-
- value = ast_strdupa(data);
- name = strsep(&value,"=");
- channel = strsep(&value,",");
- if (channel && value && name) { /*! \todo XXX should do !ast_strlen_zero(..) of the args ? */
- struct ast_channel *chan2 = ast_channel_get_by_name(channel);
- if (chan2) {
- char *s = ast_alloca(strlen(value) + 4);
- sprintf(s, "${%s}", value);
- pbx_substitute_variables_helper(chan2, s, tmp, sizeof(tmp) - 1);
- chan2 = ast_channel_unref(chan2);
- }
- pbx_builtin_setvar_helper(chan, name, tmp);
- }
-
- return(0);
-}
-
-static int pbx_builtin_noop(struct ast_channel *chan, const char *data)
-{
- return 0;
-}
-
void pbx_builtin_clear_globals(void)
{
struct ast_var_t *vardata;
@@ -11894,191 +10626,6 @@ int pbx_checkcondition(const char *condition)
}
}
-static int pbx_builtin_gotoif(struct ast_channel *chan, const char *data)
-{
- char *condition, *branch1, *branch2, *branch;
- char *stringp;
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "Ignoring, since there is no variable to check\n");
- return 0;
- }
-
- stringp = ast_strdupa(data);
- condition = strsep(&stringp,"?");
- branch1 = strsep(&stringp,":");
- branch2 = strsep(&stringp,"");
- branch = pbx_checkcondition(condition) ? branch1 : branch2;
-
- if (ast_strlen_zero(branch)) {
- ast_debug(1, "Not taking any branch\n");
- return 0;
- }
-
- return pbx_builtin_goto(chan, branch);
-}
-
-static int pbx_builtin_saynumber(struct ast_channel *chan, const char *data)
-{
- char tmp[256];
- char *number = tmp;
- int number_val;
- char *options;
- int res;
- int interrupt = 0;
- const char *interrupt_string;
-
- ast_channel_lock(chan);
- interrupt_string = pbx_builtin_getvar_helper(chan, "SAY_DTMF_INTERRUPT");
- if (ast_true(interrupt_string)) {
- interrupt = 1;
- }
- ast_channel_unlock(chan);
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "SayNumber requires an argument (number)\n");
- return -1;
- }
- ast_copy_string(tmp, data, sizeof(tmp));
- strsep(&number, ",");
-
- if (sscanf(tmp, "%d", &number_val) != 1) {
- ast_log(LOG_WARNING, "argument '%s' to SayNumber could not be parsed as a number.\n", tmp);
- return 0;
- }
-
- options = strsep(&number, ",");
- if (options) {
- if ( strcasecmp(options, "f") && strcasecmp(options, "m") &&
- strcasecmp(options, "c") && strcasecmp(options, "n") ) {
- ast_log(LOG_WARNING, "SayNumber gender option is either 'f', 'm', 'c' or 'n'\n");
- return -1;
- }
- }
-
- res = ast_say_number(chan, number_val, interrupt ? AST_DIGIT_ANY : "", ast_channel_language(chan), options);
-
- if (res < 0) {
- ast_log(LOG_WARNING, "We were unable to say the number %s, is it too large?\n", tmp);
- }
-
- return interrupt ? res : 0;
-}
-
-static int pbx_builtin_saydigits(struct ast_channel *chan, const char *data)
-{
- int res = 0;
- int interrupt = 0;
- const char *interrupt_string;
-
- ast_channel_lock(chan);
- interrupt_string = pbx_builtin_getvar_helper(chan, "SAY_DTMF_INTERRUPT");
- if (ast_true(interrupt_string)) {
- interrupt = 1;
- }
- ast_channel_unlock(chan);
-
- if (data) {
- res = ast_say_digit_str(chan, data, interrupt ? AST_DIGIT_ANY : "", ast_channel_language(chan));
- }
-
- return res;
-}
-
-static int pbx_builtin_saycharacters_case(struct ast_channel *chan, const char *data)
-{
- int res = 0;
- int sensitivity = 0;
- char *parse;
- int interrupt = 0;
- const char *interrupt_string;
-
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(options);
- AST_APP_ARG(characters);
- );
-
- ast_channel_lock(chan);
- interrupt_string = pbx_builtin_getvar_helper(chan, "SAY_DTMF_INTERRUPT");
- if (ast_true(interrupt_string)) {
- interrupt = 1;
- }
- ast_channel_unlock(chan);
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "SayAlphaCase requires two arguments (options, characters)\n");
- return 0;
- }
-
- parse = ast_strdupa(data);
- AST_STANDARD_APP_ARGS(args, parse);
-
- if (!args.options || strlen(args.options) != 1) {
- ast_log(LOG_WARNING, "SayAlphaCase options are mutually exclusive and required\n");
- return 0;
- }
-
- switch (args.options[0]) {
- case 'a':
- sensitivity = AST_SAY_CASE_ALL;
- break;
- case 'l':
- sensitivity = AST_SAY_CASE_LOWER;
- break;
- case 'n':
- sensitivity = AST_SAY_CASE_NONE;
- break;
- case 'u':
- sensitivity = AST_SAY_CASE_UPPER;
- break;
- default:
- ast_log(LOG_WARNING, "Invalid option: '%s'\n", args.options);
- return 0;
- }
-
- res = ast_say_character_str(chan, args.characters, interrupt ? AST_DIGIT_ANY : "", ast_channel_language(chan), sensitivity);
-
- return res;
-}
-
-static int pbx_builtin_saycharacters(struct ast_channel *chan, const char *data)
-{
- int res = 0;
- int interrupt = 0;
- const char *interrupt_string;
-
- ast_channel_lock(chan);
- interrupt_string = pbx_builtin_getvar_helper(chan, "SAY_DTMF_INTERRUPT");
- if (ast_true(interrupt_string)) {
- interrupt = 1;
- }
- ast_channel_unlock(chan);
-
- if (data) {
- res = ast_say_character_str(chan, data, interrupt ? AST_DIGIT_ANY : "", ast_channel_language(chan), AST_SAY_CASE_NONE);
- }
-
- return res;
-}
-
-static int pbx_builtin_sayphonetic(struct ast_channel *chan, const char *data)
-{
- int res = 0;
- int interrupt = 0;
- const char *interrupt_string;
-
- ast_channel_lock(chan);
- interrupt_string = pbx_builtin_getvar_helper(chan, "SAY_DTMF_INTERRUPT");
- if (ast_true(interrupt_string)) {
- interrupt = 1;
- }
- ast_channel_unlock(chan);
-
- if (data)
- res = ast_say_phonetic_str(chan, data, interrupt ? AST_DIGIT_ANY : "", ast_channel_language(chan));
- return res;
-}
-
static void presence_state_cb(void *unused, struct stasis_subscription *sub, struct stasis_message *msg)
{
struct ast_presence_state_message *presence_state;
@@ -12315,15 +10862,9 @@ static int action_extensionstatelist(struct mansession *s, const struct message
*/
static void unload_pbx(void)
{
- int x;
-
presence_state_sub = stasis_unsubscribe_and_join(presence_state_sub);
device_state_sub = stasis_unsubscribe_and_join(device_state_sub);
- /* Unregister builtin applications */
- for (x = 0; x < ARRAY_LEN(builtins); x++) {
- ast_unregister_application(builtins[x].name);
- }
ast_manager_unregister("ShowDialPlan");
ast_manager_unregister("ExtensionStateList");
ast_cli_unregister_multiple(pbx_cli, ARRAY_LEN(pbx_cli));
@@ -12335,27 +10876,18 @@ static void unload_pbx(void)
int load_pbx(void)
{
int res = 0;
- int x;
ast_register_cleanup(unload_pbx);
/* Initialize the PBX */
ast_verb(1, "Asterisk PBX Core Initializing\n");
- ast_verb(2, "Registering builtin applications and functions:\n");
+ ast_verb(2, "Registering builtin functions:\n");
ast_cli_register_multiple(pbx_cli, ARRAY_LEN(pbx_cli));
ast_data_register_multiple_core(pbx_data_providers, ARRAY_LEN(pbx_data_providers));
__ast_custom_function_register(&exception_function, NULL);
__ast_custom_function_register(&testtime_function, NULL);
- /* Register builtin applications */
- for (x = 0; x < ARRAY_LEN(builtins); x++) {
- if (ast_register_application2(builtins[x].name, builtins[x].execute, NULL, NULL, NULL)) {
- ast_log(LOG_ERROR, "Unable to register builtin application '%s'\n", builtins[x].name);
- return -1;
- }
- }
-
/* Register manager application */
res |= ast_manager_register_xml_core("ShowDialPlan", EVENT_FLAG_CONFIG | EVENT_FLAG_REPORTING, manager_show_dialplan);
res |= ast_manager_register_xml_core("ExtensionStateList", EVENT_FLAG_CALL | EVENT_FLAG_REPORTING, action_extensionstatelist);