Merge "astobj2: Create function to copy weak proxied objects from container."
[asterisk/asterisk.git] / apps / app_dictate.c
old mode 100755 (executable)
new mode 100644 (file)
index 9cadf85..d184512
@@ -5,7 +5,7 @@
  *
  * Anthony Minessale II <anthmct@yahoo.com>
  *
- * Donated by Sangoma Technologies <http://www.samgoma.com>
+ * Donated by Sangoma Technologies <http://www.sangoma.com>
  *
  * See http://www.asterisk.org for more information about
  * the Asterisk project. Please do not directly contact
  * at the top of the source tree.
  */
 
-/*
+/*! \file
+ *
+ * \brief Virtual Dictation Machine Application For Asterisk
  *
- * Virtual Dictation Machine Application For Asterisk
+ * \author Anthony Minessale II <anthmct@yahoo.com>
  *
+ * \ingroup applications
  */
 
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <sys/stat.h>  /* for mkdir */
+/*** MODULEINFO
+       <support_level>extended</support_level>
+ ***/
 
 #include "asterisk.h"
 
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
+#include <sys/stat.h>
 
+#include "asterisk/paths.h" /* use ast_config_AST_SPOOL_DIR */
 #include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
 #include "asterisk/pbx.h"
 #include "asterisk/module.h"
 #include "asterisk/say.h"
-#include "asterisk/lock.h"
 #include "asterisk/app.h"
+#include "asterisk/format_cache.h"
 
-static char *tdesc = "Virtual Dictation Machine";
-static char *app = "Dictate";
-static char *synopsis = "Virtual Dictation Machine";
-static char *desc = "  Dictate([<base_dir>])\n"
-"Start dictation machine using optional base dir for files.\n";
+/*** DOCUMENTATION
+       <application name="Dictate" language="en_US">
+               <synopsis>
+                       Virtual Dictation Machine.
+               </synopsis>
+               <syntax>
+                       <parameter name="base_dir" />
+                       <parameter name="filename" />
+               </syntax>
+               <description>
+                       <para>Start dictation machine using optional <replaceable>base_dir</replaceable> for files.</para>
+               </description>
+       </application>
+ ***/
 
-
-STANDARD_LOCAL_USER;
-LOCAL_USER_DECL;
+static const char app[] = "Dictate";
 
 typedef enum {
        DFLAG_RECORD = (1 << 0),
@@ -67,29 +75,31 @@ typedef enum {
 
 #define ast_toggle_flag(it,flag) if(ast_test_flag(it, flag)) ast_clear_flag(it, flag); else ast_set_flag(it, flag)
 
-static int play_and_wait(struct ast_channel *chan, char *file, char *digits) 
+static int play_and_wait(struct ast_channel *chan, char *file, char *digits)
 {
        int res = -1;
-       if (!ast_streamfile(chan, file, chan->language)) {
+       if (!ast_streamfile(chan, file, ast_channel_language(chan))) {
                res = ast_waitstream(chan, digits);
        }
        return res;
 }
 
-static int dictate_exec(struct ast_channel *chan, void *data)
+static int dictate_exec(struct ast_channel *chan, const char *data)
 {
-       char *mydata, *argv[2], *path = NULL, filein[256];
+       char *path = NULL, filein[256], *filename = "";
+       char *parse;
+       AST_DECLARE_APP_ARGS(args,
+               AST_APP_ARG(base);
+               AST_APP_ARG(filename);
+       );
        char dftbase[256];
        char *base;
        struct ast_flags flags = {0};
        struct ast_filestream *fs;
        struct ast_frame *f = NULL;
-       struct localuser *u;
        int ffactor = 320 * 80,
                res = 0,
-               argc = 0,
                done = 0,
-               oldr = 0,
                lastop = 0,
                samples = 0,
                speed = 1,
@@ -97,39 +107,49 @@ static int dictate_exec(struct ast_channel *chan, void *data)
                len = 0,
                maxlen = 0,
                mode = 0;
-               
+       struct ast_format *oldr;
 
        snprintf(dftbase, sizeof(dftbase), "%s/dictate", ast_config_AST_SPOOL_DIR);
-       if (data && !ast_strlen_zero(data) && (mydata = ast_strdupa(data))) {
-               argc = ast_separate_app_args(mydata, '|', argv, sizeof(argv) / sizeof(argv[0]));
-       }
-       
-       if (argc) {
-               base = argv[0];
+       if (!ast_strlen_zero(data)) {
+               parse = ast_strdupa(data);
+               AST_STANDARD_APP_ARGS(args, parse);
+       } else
+               args.argc = 0;
+
+       if (args.argc && !ast_strlen_zero(args.base)) {
+               base = args.base;
        } else {
                base = dftbase;
        }
-
-       oldr = chan->readformat;
-       if ((res = ast_set_read_format(chan, AST_FORMAT_SLINEAR)) < 0) {
+       if (args.argc > 1 && args.filename) {
+               filename = args.filename;
+       }
+       oldr = ao2_bump(ast_channel_readformat(chan));
+       if ((res = ast_set_read_format(chan, ast_format_slin)) < 0) {
                ast_log(LOG_WARNING, "Unable to set to linear mode.\n");
+               ao2_cleanup(oldr);
                return -1;
        }
 
-       LOCAL_USER_ADD(u);
-       ast_answer(chan);
+       if (ast_channel_state(chan) != AST_STATE_UP) {
+               ast_answer(chan);
+       }
        ast_safe_sleep(chan, 200);
-       for(res = 0; !res;) {
-               if (ast_app_getdata(chan, "dictate/enter_filename", filein, sizeof(filein), 0) || 
-                       ast_strlen_zero(filein)) {
-                       res = -1;
-                       break;
+       for (res = 0; !res;) {
+               if (ast_strlen_zero(filename)) {
+                       if (ast_app_getdata(chan, "dictate/enter_filename", filein, sizeof(filein), 0) ||
+                               ast_strlen_zero(filein)) {
+                               res = -1;
+                               break;
+                       }
+               } else {
+                       ast_copy_string(filein, filename, sizeof(filein));
+                       filename = "";
                }
-               
-               mkdir(base, 0755);
+               ast_mkdir(base, 0755);
                len = strlen(base) + strlen(filein) + 2;
                if (!path || len > maxlen) {
-                       path = alloca(len);
+                       path = ast_alloca(len);
                        memset(path, 0, len);
                        maxlen = len;
                } else {
@@ -137,7 +157,7 @@ static int dictate_exec(struct ast_channel *chan, void *data)
                }
 
                snprintf(path, len, "%s/%s", base, filein);
-               fs = ast_writefile(path, "raw", NULL, O_CREAT|O_APPEND, 0, 0700);
+               fs = ast_writefile(path, "raw", NULL, O_CREAT|O_APPEND, 0, AST_FILE_MODE);
                mode = DMODE_PLAY;
                memset(&flags, 0, sizeof(flags));
                ast_set_flag(&flags, DFLAG_PAUSE);
@@ -149,15 +169,15 @@ static int dictate_exec(struct ast_channel *chan, void *data)
                samples = 0;
                while (!done && ((res = ast_waitfor(chan, -1)) > -1) && fs && (f = ast_read(chan))) {
                        if (digit) {
-                               struct ast_frame fr = {AST_FRAME_DTMF, digit};
+                               struct ast_frame fr = {AST_FRAME_DTMF, { .integer = digit } };
                                ast_queue_frame(chan, &fr);
                                digit = 0;
                        }
-                       if ((f->frametype == AST_FRAME_DTMF)) {
+                       if (f->frametype == AST_FRAME_DTMF) {
                                int got = 1;
                                switch(mode) {
                                case DMODE_PLAY:
-                                       switch(f->subclass) {
+                                       switch (f->subclass.integer) {
                                        case '1':
                                                ast_set_flag(&flags, DFLAG_PAUSE);
                                                mode = DMODE_RECORD;
@@ -167,7 +187,7 @@ static int dictate_exec(struct ast_channel *chan, void *data)
                                                if (speed > 4) {
                                                        speed = 1;
                                                }
-                                               res = ast_say_number(chan, speed, AST_DIGIT_ANY, chan->language, (char *) NULL);
+                                               res = ast_say_number(chan, speed, AST_DIGIT_ANY, ast_channel_language(chan), NULL);
                                                break;
                                        case '7':
                                                samples -= ffactor;
@@ -180,13 +200,13 @@ static int dictate_exec(struct ast_channel *chan, void *data)
                                                samples += ffactor;
                                                ast_seekstream(fs, samples, SEEK_SET);
                                                break;
-                                               
+
                                        default:
                                                got = 0;
                                        }
                                        break;
                                case DMODE_RECORD:
-                                       switch(f->subclass) {
+                                       switch (f->subclass.integer) {
                                        case '1':
                                                ast_set_flag(&flags, DFLAG_PAUSE);
                                                mode = DMODE_PLAY;
@@ -203,7 +223,7 @@ static int dictate_exec(struct ast_channel *chan, void *data)
                                        got = 0;
                                }
                                if (!got) {
-                                       switch(f->subclass) {
+                                       switch (f->subclass.integer) {
                                        case '#':
                                                done = 1;
                                                continue;
@@ -236,7 +256,7 @@ static int dictate_exec(struct ast_channel *chan, void *data)
                                                break;
                                        }
                                }
-                               
+
                        } else if (f->frametype == AST_FRAME_VOICE) {
                                switch(mode) {
                                        struct ast_frame *fr;
@@ -254,9 +274,10 @@ static int dictate_exec(struct ast_channel *chan, void *data)
                                                if (lastop != DFLAG_PLAY) {
                                                        lastop = DFLAG_PLAY;
                                                        ast_closestream(fs);
-                                                       fs = ast_openstream(chan, path, chan->language);
+                                                       if (!(fs = ast_openstream(chan, path, ast_channel_language(chan))))
+                                                               break;
                                                        ast_seekstream(fs, samples, SEEK_SET);
-                                                       chan->stream = NULL;
+                                                       ast_channel_stream_set(chan, NULL);
                                                }
                                                lastop = DMODE_PLAY;
                                        }
@@ -278,7 +299,7 @@ static int dictate_exec(struct ast_channel *chan, void *data)
                                case DMODE_RECORD:
                                        if (lastop != DMODE_RECORD) {
                                                int oflags = O_CREAT | O_WRONLY;
-                                               if (ast_test_flag(&flags, DFLAG_PAUSE)) {                                               
+                                               if (ast_test_flag(&flags, DFLAG_PAUSE)) {
                                                        digit = play_and_wait(chan, "dictate/record_mode", AST_DIGIT_ANY);
                                                        if (digit == 0) {
                                                                digit = play_and_wait(chan, "dictate/paused", AST_DIGIT_ANY);
@@ -294,7 +315,7 @@ static int dictate_exec(struct ast_channel *chan, void *data)
                                                } else {
                                                        oflags |= O_APPEND;
                                                }
-                                               fs = ast_writefile(path, "raw", NULL, oflags, 0, 0700);
+                                               fs = ast_writefile(path, "raw", NULL, oflags, 0, AST_FILE_MODE);
                                                if (ast_test_flag(&flags, DFLAG_TRUNC)) {
                                                        ast_seekstream(fs, 0, SEEK_SET);
                                                        ast_clear_flag(&flags, DFLAG_TRUNC);
@@ -307,7 +328,7 @@ static int dictate_exec(struct ast_channel *chan, void *data)
                                        }
                                        break;
                                }
-                               
+
                        }
 
                        ast_frfree(f);
@@ -315,36 +336,21 @@ static int dictate_exec(struct ast_channel *chan, void *data)
        }
        if (oldr) {
                ast_set_read_format(chan, oldr);
+               ao2_ref(oldr, -1);
        }
-       LOCAL_USER_REMOVE(u);
-       return res;
-}
-
-int unload_module(void)
-{
-       STANDARD_HANGUP_LOCALUSERS;
-       return ast_unregister_application(app);
-}
-
-int load_module(void)
-{
-       return ast_register_application(app, dictate_exec, synopsis, desc);
-}
-
-char *description(void)
-{
-       return tdesc;
+       return 0;
 }
 
-int usecount(void)
+static int unload_module(void)
 {
        int res;
-       STANDARD_USECOUNT(res);
+       res = ast_unregister_application(app);
        return res;
 }
 
-char *key()
+static int load_module(void)
 {
-       return ASTERISK_GPL_KEY;
+       return ast_register_application_xml(app, dictate_exec);
 }
 
+AST_MODULE_INFO_STANDARD_EXTENDED(ASTERISK_GPL_KEY, "Virtual Dictation Machine");