#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include "asterisk.h"
#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"
Go to the source code of this file.
Defines | |
#define | ast_toggle_flag(it, flag) if(ast_test_flag(it, flag)) ast_clear_flag(it, flag); else ast_set_flag(it, flag) |
Enumerations | |
enum | dflags { DFLAG_RECORD = (1 << 0), DFLAG_PLAY = (1 << 1), DFLAG_TRUNC = (1 << 2), DFLAG_PAUSE = (1 << 3) } |
enum | dmodes { DMODE_INIT, DMODE_RECORD, DMODE_PLAY } |
Functions | |
char * | description (void) |
Provides a description of the module. | |
static int | dictate_exec (struct ast_channel *chan, void *data) |
char * | key () |
Returns the ASTERISK_GPL_KEY. | |
int | load_module (void) |
Initialize the module. | |
static int | play_and_wait (struct ast_channel *chan, char *file, char *digits) |
int | unload_module (void) |
Cleanup all module structures, sockets, etc. | |
int | usecount (void) |
Provides a usecount. | |
Variables | |
static char * | app = "Dictate" |
static char * | desc |
LOCAL_USER_DECL | |
STANDARD_LOCAL_USER | |
static char * | synopsis = "Virtual Dictation Machine" |
static char * | tdesc = "Virtual Dictation Machine" |
Definition in file app_dictate.c.
|
Definition at line 70 of file app_dictate.c. |
|
Definition at line 57 of file app_dictate.c. 00057 { 00058 DFLAG_RECORD = (1 << 0), 00059 DFLAG_PLAY = (1 << 1), 00060 DFLAG_TRUNC = (1 << 2), 00061 DFLAG_PAUSE = (1 << 3), 00062 } dflags;
|
|
Definition at line 64 of file app_dictate.c. 00064 { 00065 DMODE_INIT, 00066 DMODE_RECORD, 00067 DMODE_PLAY 00068 } dmodes;
|
|
Provides a description of the module.
Definition at line 342 of file app_dictate.c. 00343 { 00344 return tdesc; 00345 }
|
|
Definition at line 81 of file app_dictate.c. References ast_answer(), ast_app_getdata(), ast_app_separate_args(), ast_config_AST_SPOOL_DIR, AST_FORMAT_SLINEAR, ast_log(), ast_safe_sleep(), ast_set_read_format(), ast_strdupa, ast_strlen_zero(), localuser::chan, ast_flags::flags, LOCAL_USER_ADD, LOCAL_USER_REMOVE, LOG_WARNING, and ast_channel::readformat. Referenced by load_module(). 00082 { 00083 char *mydata, *argv[2], *path = NULL, filein[256]; 00084 char dftbase[256]; 00085 char *base; 00086 struct ast_flags flags = {0}; 00087 struct ast_filestream *fs; 00088 struct ast_frame *f = NULL; 00089 struct localuser *u; 00090 int ffactor = 320 * 80, 00091 res = 0, 00092 argc = 0, 00093 done = 0, 00094 oldr = 0, 00095 lastop = 0, 00096 samples = 0, 00097 speed = 1, 00098 digit = 0, 00099 len = 0, 00100 maxlen = 0, 00101 mode = 0; 00102 00103 LOCAL_USER_ADD(u); 00104 00105 snprintf(dftbase, sizeof(dftbase), "%s/dictate", ast_config_AST_SPOOL_DIR); 00106 if (!ast_strlen_zero(data) && (mydata = ast_strdupa(data))) { 00107 argc = ast_app_separate_args(mydata, '|', argv, sizeof(argv) / sizeof(argv[0])); 00108 } 00109 00110 if (argc) { 00111 base = argv[0]; 00112 } else { 00113 base = dftbase; 00114 } 00115 00116 oldr = chan->readformat; 00117 if ((res = ast_set_read_format(chan, AST_FORMAT_SLINEAR)) < 0) { 00118 ast_log(LOG_WARNING, "Unable to set to linear mode.\n"); 00119 LOCAL_USER_REMOVE(u); 00120 return -1; 00121 } 00122 00123 ast_answer(chan); 00124 ast_safe_sleep(chan, 200); 00125 for(res = 0; !res;) { 00126 if (ast_app_getdata(chan, "dictate/enter_filename", filein, sizeof(filein), 0) || 00127 ast_strlen_zero(filein)) { 00128 res = -1; 00129 break; 00130 } 00131 00132 mkdir(base, 0755); 00133 len = strlen(base) + strlen(filein) + 2; 00134 if (!path || len > maxlen) { 00135 path = alloca(len); 00136 memset(path, 0, len); 00137 maxlen = len; 00138 } else { 00139 memset(path, 0, maxlen); 00140 } 00141 00142 snprintf(path, len, "%s/%s", base, filein); 00143 fs = ast_writefile(path, "raw", NULL, O_CREAT|O_APPEND, 0, 0700); 00144 mode = DMODE_PLAY; 00145 memset(&flags, 0, sizeof(flags)); 00146 ast_set_flag(&flags, DFLAG_PAUSE); 00147 digit = play_and_wait(chan, "dictate/forhelp", AST_DIGIT_ANY); 00148 done = 0; 00149 speed = 1; 00150 res = 0; 00151 lastop = 0; 00152 samples = 0; 00153 while (!done && ((res = ast_waitfor(chan, -1)) > -1) && fs && (f = ast_read(chan))) { 00154 if (digit) { 00155 struct ast_frame fr = {AST_FRAME_DTMF, digit}; 00156 ast_queue_frame(chan, &fr); 00157 digit = 0; 00158 } 00159 if ((f->frametype == AST_FRAME_DTMF)) { 00160 int got = 1; 00161 switch(mode) { 00162 case DMODE_PLAY: 00163 switch(f->subclass) { 00164 case '1': 00165 ast_set_flag(&flags, DFLAG_PAUSE); 00166 mode = DMODE_RECORD; 00167 break; 00168 case '2': 00169 speed++; 00170 if (speed > 4) { 00171 speed = 1; 00172 } 00173 res = ast_say_number(chan, speed, AST_DIGIT_ANY, chan->language, (char *) NULL); 00174 break; 00175 case '7': 00176 samples -= ffactor; 00177 if(samples < 0) { 00178 samples = 0; 00179 } 00180 ast_seekstream(fs, samples, SEEK_SET); 00181 break; 00182 case '8': 00183 samples += ffactor; 00184 ast_seekstream(fs, samples, SEEK_SET); 00185 break; 00186 00187 default: 00188 got = 0; 00189 } 00190 break; 00191 case DMODE_RECORD: 00192 switch(f->subclass) { 00193 case '1': 00194 ast_set_flag(&flags, DFLAG_PAUSE); 00195 mode = DMODE_PLAY; 00196 break; 00197 case '8': 00198 ast_toggle_flag(&flags, DFLAG_TRUNC); 00199 lastop = 0; 00200 break; 00201 default: 00202 got = 0; 00203 } 00204 break; 00205 default: 00206 got = 0; 00207 } 00208 if (!got) { 00209 switch(f->subclass) { 00210 case '#': 00211 done = 1; 00212 continue; 00213 break; 00214 case '*': 00215 ast_toggle_flag(&flags, DFLAG_PAUSE); 00216 if (ast_test_flag(&flags, DFLAG_PAUSE)) { 00217 digit = play_and_wait(chan, "dictate/pause", AST_DIGIT_ANY); 00218 } else { 00219 digit = play_and_wait(chan, mode == DMODE_PLAY ? "dictate/playback" : "dictate/record", AST_DIGIT_ANY); 00220 } 00221 break; 00222 case '0': 00223 ast_set_flag(&flags, DFLAG_PAUSE); 00224 digit = play_and_wait(chan, "dictate/paused", AST_DIGIT_ANY); 00225 switch(mode) { 00226 case DMODE_PLAY: 00227 digit = play_and_wait(chan, "dictate/play_help", AST_DIGIT_ANY); 00228 break; 00229 case DMODE_RECORD: 00230 digit = play_and_wait(chan, "dictate/record_help", AST_DIGIT_ANY); 00231 break; 00232 } 00233 if (digit == 0) { 00234 digit = play_and_wait(chan, "dictate/both_help", AST_DIGIT_ANY); 00235 } else if (digit < 0) { 00236 done = 1; 00237 break; 00238 } 00239 break; 00240 } 00241 } 00242 00243 } else if (f->frametype == AST_FRAME_VOICE) { 00244 switch(mode) { 00245 struct ast_frame *fr; 00246 int x; 00247 case DMODE_PLAY: 00248 if (lastop != DMODE_PLAY) { 00249 if (ast_test_flag(&flags, DFLAG_PAUSE)) { 00250 digit = play_and_wait(chan, "dictate/playback_mode", AST_DIGIT_ANY); 00251 if (digit == 0) { 00252 digit = play_and_wait(chan, "dictate/paused", AST_DIGIT_ANY); 00253 } else if (digit < 0) { 00254 break; 00255 } 00256 } 00257 if (lastop != DFLAG_PLAY) { 00258 lastop = DFLAG_PLAY; 00259 ast_closestream(fs); 00260 fs = ast_openstream(chan, path, chan->language); 00261 ast_seekstream(fs, samples, SEEK_SET); 00262 chan->stream = NULL; 00263 } 00264 lastop = DMODE_PLAY; 00265 } 00266 00267 if (!ast_test_flag(&flags, DFLAG_PAUSE)) { 00268 for (x = 0; x < speed; x++) { 00269 if ((fr = ast_readframe(fs))) { 00270 ast_write(chan, fr); 00271 samples += fr->samples; 00272 ast_frfree(fr); 00273 fr = NULL; 00274 } else { 00275 samples = 0; 00276 ast_seekstream(fs, 0, SEEK_SET); 00277 } 00278 } 00279 } 00280 break; 00281 case DMODE_RECORD: 00282 if (lastop != DMODE_RECORD) { 00283 int oflags = O_CREAT | O_WRONLY; 00284 if (ast_test_flag(&flags, DFLAG_PAUSE)) { 00285 digit = play_and_wait(chan, "dictate/record_mode", AST_DIGIT_ANY); 00286 if (digit == 0) { 00287 digit = play_and_wait(chan, "dictate/paused", AST_DIGIT_ANY); 00288 } else if (digit < 0) { 00289 break; 00290 } 00291 } 00292 lastop = DMODE_RECORD; 00293 ast_closestream(fs); 00294 if ( ast_test_flag(&flags, DFLAG_TRUNC)) { 00295 oflags |= O_TRUNC; 00296 digit = play_and_wait(chan, "dictate/truncating_audio", AST_DIGIT_ANY); 00297 } else { 00298 oflags |= O_APPEND; 00299 } 00300 fs = ast_writefile(path, "raw", NULL, oflags, 0, 0700); 00301 if (ast_test_flag(&flags, DFLAG_TRUNC)) { 00302 ast_seekstream(fs, 0, SEEK_SET); 00303 ast_clear_flag(&flags, DFLAG_TRUNC); 00304 } else { 00305 ast_seekstream(fs, 0, SEEK_END); 00306 } 00307 } 00308 if (!ast_test_flag(&flags, DFLAG_PAUSE)) { 00309 res = ast_writestream(fs, f); 00310 } 00311 break; 00312 } 00313 00314 } 00315 00316 ast_frfree(f); 00317 } 00318 } 00319 if (oldr) { 00320 ast_set_read_format(chan, oldr); 00321 } 00322 LOCAL_USER_REMOVE(u); 00323 return res; 00324 }
|
|
Returns the ASTERISK_GPL_KEY. This returns the ASTERISK_GPL_KEY, signifiying that you agree to the terms of the GPL stated in the ASTERISK_GPL_KEY. Your module will not load if it does not return the EXACT message:
char *key(void) { return ASTERISK_GPL_KEY; }
Definition at line 354 of file app_dictate.c. References ASTERISK_GPL_KEY. 00355 { 00356 return ASTERISK_GPL_KEY; 00357 }
|
|
Initialize the module. Initialize the Agents module. This function is being called by Asterisk when loading the module. Among other thing it registers applications, cli commands and reads the cofiguration file.
Definition at line 337 of file app_dictate.c. References ast_register_application(), and dictate_exec(). 00338 { 00339 return ast_register_application(app, dictate_exec, synopsis, desc); 00340 }
|
|
Definition at line 72 of file app_dictate.c. References ast_streamfile(), ast_waitstream(), and ast_channel::language. 00073 { 00074 int res = -1; 00075 if (!ast_streamfile(chan, file, chan->language)) { 00076 res = ast_waitstream(chan, digits); 00077 } 00078 return res; 00079 }
|
|
Cleanup all module structures, sockets, etc. This is called at exit. Any registrations and memory allocations need to be unregistered and free'd here. Nothing else will do these for you (until exit).
Definition at line 326 of file app_dictate.c. References ast_unregister_application(), and STANDARD_HANGUP_LOCALUSERS. 00327 { 00328 int res; 00329 00330 res = ast_unregister_application(app); 00331 00332 STANDARD_HANGUP_LOCALUSERS; 00333 00334 return res; 00335 }
|
|
Provides a usecount. This function will be called by various parts of asterisk. Basically, all it has to do is to return a usecount when called. You will need to maintain your usecount within the module somewhere. The usecount should be how many channels provided by this module are in use.
Definition at line 347 of file app_dictate.c. References STANDARD_USECOUNT. 00348 { 00349 int res; 00350 STANDARD_USECOUNT(res); 00351 return res; 00352 }
|
|
Definition at line 48 of file app_dictate.c. |
|
Initial value: " Dictate([<base_dir>])\n" "Start dictation machine using optional base dir for files.\n" Definition at line 50 of file app_dictate.c. |
|
Definition at line 55 of file app_dictate.c. |
|
Definition at line 54 of file app_dictate.c. |
|
Definition at line 49 of file app_dictate.c. |
|
Definition at line 47 of file app_dictate.c. |