Merge "rtp_engine: rtcp_report_to_json can overflow the ssrc integer value"
[asterisk/asterisk.git] / main / pbx_builtins.c
index 8d9f6b0..7f76b97 100644 (file)
@@ -29,8 +29,6 @@
 
 #include "asterisk.h"
 
-ASTERISK_REGISTER_FILE()
-
 #include "asterisk/_private.h"
 #include "asterisk/pbx.h"
 #include "asterisk/causes.h"
@@ -41,7 +39,7 @@ ASTERISK_REGISTER_FILE()
 #include "asterisk/module.h"
 #include "pbx_private.h"
 
- /*** DOCUMENTATION
+/*** DOCUMENTATION
        <application name="Answer" language="en_US">
                <synopsis>
                        Answer a channel if ringing.
@@ -552,66 +550,6 @@ ASTERISK_REGISTER_FILE()
                        <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.
@@ -642,6 +580,42 @@ ASTERISK_REGISTER_FILE()
                        <para>This application waits for a specified number of <replaceable>seconds</replaceable>.</para>
                </description>
        </application>
+       <application name="WaitDigit" language="en_US">
+               <synopsis>
+                       Waits for a digit 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="digits">
+                               <para>Digits to accept, all others are ignored.</para>
+                       </parameter>
+               </syntax>
+               <description>
+                       <para>This application waits for the user to press one of the accepted
+                       <replaceable>digits</replaceable> for a specified number of
+                       <replaceable>seconds</replaceable>.</para>
+                       <variablelist>
+                               <variable name="WAITDIGITSTATUS">
+                                       <para>This is the final status of the command</para>
+                                       <value name="ERROR">Parameters are invalid.</value>
+                                       <value name="DTMF">An accepted digit was received.</value>
+                                       <value name="TIMEOUT">The timeout passed before any acceptable digits were received.</value>
+                                       <value name="CANCEL">The channel has hungup or was redirected.</value>
+                               </variable>
+                               <variable name="WAITDIGITRESULT">
+                                       <para>The digit that was received, only set if
+                                       <variable>WAITDIGITSTATUS</variable> is <literal>DTMF</literal>.</para>
+                               </variable>
+                       </variablelist>
+               </description>
+               <see-also>
+                       <ref type="application">Wait</ref>
+                       <ref type="application">WaitExten</ref>
+               </see-also>
+       </application>
        <application name="WaitExten" language="en_US">
                <synopsis>
                        Waits for an extension to be entered.
@@ -1019,6 +993,47 @@ static int pbx_builtin_wait(struct ast_channel *chan, const char *data)
 /*!
  * \ingroup applications
  */
+static int pbx_builtin_waitdigit(struct ast_channel *chan, const char *data)
+{
+       int res;
+       int ms;
+       char *parse;
+       AST_DECLARE_APP_ARGS(args,
+               AST_APP_ARG(timeout);
+               AST_APP_ARG(digits);
+       );
+
+       parse = ast_strdupa(data);
+       AST_STANDARD_APP_ARGS(args, parse);
+
+       if (ast_app_parse_timelen(args.timeout, &ms, TIMELEN_SECONDS) || ms < 0) {
+               pbx_builtin_setvar_helper(chan, "WAITDIGITSTATUS", "ERROR");
+               return 0;
+       }
+
+       /* Wait for "n" seconds */
+       res = ast_waitfordigit_full(chan, ms, S_OR(args.digits, AST_DIGIT_ANY), -1, -1);
+       if (res < 0) {
+               pbx_builtin_setvar_helper(chan, "WAITDIGITSTATUS", "CANCEL");
+               return -1;
+       }
+
+       if (res == 0) {
+               pbx_builtin_setvar_helper(chan, "WAITDIGITSTATUS", "TIMEOUT");
+       } else {
+               char key[2];
+
+               snprintf(key, sizeof(key), "%c", res);
+               pbx_builtin_setvar_helper(chan, "WAITDIGITRESULT", key);
+               pbx_builtin_setvar_helper(chan, "WAITDIGITSTATUS", "DTMF");
+       }
+
+       return 0;
+}
+
+/*!
+ * \ingroup applications
+ */
 static int pbx_builtin_waitexten(struct ast_channel *chan, const char *data)
 {
        int ms, res;
@@ -1173,6 +1188,13 @@ static int pbx_builtin_background(struct ast_channel *chan, const char *data)
                }
        }
 
+       /* If ast_waitstream didn't give us back a digit, there is nothing else to do */
+       if (res <= 0) {
+               goto done;
+       }
+
+       exten[0] = res;
+
        /*
         * 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.
@@ -1192,7 +1214,6 @@ static int pbx_builtin_background(struct ast_channel *chan, const char *data)
         * 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,
@@ -1464,10 +1485,9 @@ struct pbx_builtin {
        { "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 },
+       { "WaitDigit",      pbx_builtin_waitdigit },
        { "WaitExten",      pbx_builtin_waitexten }
 };
 
@@ -1489,7 +1509,6 @@ int load_pbx_builtins(void)
        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);
-                       unload_pbx_builtins();
                        return -1;
                }
        }