make app_queue 1.2 jump compliant (issue #5580)
[asterisk/asterisk.git] / apps / app_controlplayback.c
index b8e68a3..6cd577d 100755 (executable)
 /*! \file
  * \brief Trivial application to control playback of a sound file
  * 
+ * \ingroup applications
  */
  
-#include <string.h>
 #include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
 
 #include "asterisk.h"
 
@@ -37,6 +39,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #include "asterisk/module.h"
 #include "asterisk/translate.h"
 #include "asterisk/utils.h"
+#include "asterisk/options.h"
 
 static const char *tdesc = "Control Playback Application";
 
@@ -45,13 +48,17 @@ static const char *app = "ControlPlayback";
 static const char *synopsis = "Play a file with fast forward and rewind";
 
 static const char *descrip = 
-"ControlPlayback(filename[|skipms[|ffchar[|rewchar[|stopchar[|pausechar[|restartchar]]]]]]):\n"
-"  Plays  back  a  given  filename (do not put extension). Options may also\n"
+"ControlPlayback(filename[|skipms[|ffchar[|rewchar[|stopchar[|pausechar[|restartchar[|option]]]]]]]):\n"
+"  Plays back a given filename (do not put extension). Options may also\n"
 "  be included following a pipe symbol.  You can use * and # to rewind and\n"
 "  fast forward the playback specified. If 'stopchar' is added the file will\n"
 "  terminate playback when 'stopchar' is pressed. If 'restartchar' is added, the file\n"
-"  will restart when 'restartchar' is pressed. Returns -1 if the channel\n"
-"  was hung up. if the file does not exist jumps to n+101 if it present.\n\n"
+"  will restart when 'restartchar' is pressed.\n"
+"  The option string may contain the following character:\n"
+"       'j' -- jump to +101 priority if the file requested isn't found.\n"
+"  This application sets the following channel variable upon completion:\n"
+"     CPLAYBACKSTATUS       The status of the attempt as a text string, one of\n"
+"             SUCCESS | USERSTOPPED | ERROR\n"
 "  Example:  exten => 1234,1,ControlPlayback(file|4000|*|#|1|0|5)\n\n";
 
 STANDARD_LOCAL_USER;
@@ -65,12 +72,12 @@ static int is_on_phonepad(char key)
 
 static int controlplayback_exec(struct ast_channel *chan, void *data)
 {
-       int res = 0;
+       int res = 0, priority_jump = 0;
        int skipms = 0;
        struct localuser *u;
        char *tmp;
        int argc;
-       char *argv[7];
+       char *argv[8];
        enum arg_ids {
                arg_file = 0,
                arg_skip = 1,
@@ -79,9 +86,10 @@ static int controlplayback_exec(struct ast_channel *chan, void *data)
                arg_stop = 4,
                arg_pause = 5,
                arg_restart = 6,
+               options = 7,
        };
        
-       if (!data || ast_strlen_zero(data)) {
+       if (ast_strlen_zero(data)) {
                ast_log(LOG_WARNING, "ControlPlayback requires an argument (filename)\n");
                return -1;
        }
@@ -91,7 +99,7 @@ static int controlplayback_exec(struct ast_channel *chan, void *data)
        tmp = ast_strdupa(data);
        memset(argv, 0, sizeof(argv));
 
-       argc = ast_separate_app_args(tmp, '|', argv, sizeof(argv) / sizeof(argv[0]));
+       argc = ast_app_separate_args(tmp, '|', argv, sizeof(argv) / sizeof(argv[0]));
 
        if (argc < 1) {
                ast_log(LOG_WARNING, "ControlPlayback requires an argument (filename)\n");
@@ -114,15 +122,28 @@ static int controlplayback_exec(struct ast_channel *chan, void *data)
        if (argv[arg_restart] && !is_on_phonepad(*argv[arg_restart]))
                argv[arg_restart] = NULL;
 
+       if (argv[options]) {
+               if (strchr(argv[options], 'j'))
+                       priority_jump = 1;
+       }
+
        res = ast_control_streamfile(chan, argv[arg_file], argv[arg_fwd], argv[arg_rev], argv[arg_stop], argv[arg_pause], argv[arg_restart], skipms);
 
        /* If we stopped on one of our stop keys, return 0  */
-       if (argv[arg_stop] && strchr(argv[arg_stop], res)) 
+       if (argv[arg_stop] && strchr(argv[arg_stop], res)) {
                res = 0;
-
-       if (res < 0) {
-               if (ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101))
+               pbx_builtin_setvar_helper(chan, "CPLAYBACKSTATUS", "USERSTOPPED");
+       } else {
+               if (res < 0) {
+                       if (priority_jump || option_priority_jumping) {
+                               if (!ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101)) {
+                                       ast_log(LOG_WARNING, "ControlPlayback tried to jump to priority n+101 as requested, but priority didn't exist\n");
+                               }
+                       }
                        res = 0;
+                       pbx_builtin_setvar_helper(chan, "CPLAYBACKSTATUS", "ERROR");
+               } else
+                       pbx_builtin_setvar_helper(chan, "CPLAYBACKSTATUS", "SUCCESS");
        }
 
        LOCAL_USER_REMOVE(u);