Added feature from bug #5573 and updated app_read

to be able to use indication tones, and argument 
parsing code. Documented possible problems this might
cause an older dialplans in UPGRADE.txt


git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@7818 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
Matt O'Gorman
2006-01-05 19:55:03 +00:00
parent a312561ff8
commit 7b680ef6d8
2 changed files with 78 additions and 56 deletions

View File

@@ -18,6 +18,9 @@ Applications:
* The application SetVar has been renamed to Set. The syntax SetVar was marked * The application SetVar has been renamed to Set. The syntax SetVar was marked
deprecated in version 1.2 and is no longer recognized in this version. deprecated in version 1.2 and is no longer recognized in this version.
* app_read has been updated to use the newer options codes, using "skip" or
"noanswer" will not work. Use s or n. Also there is a new feature i, for
using indication tones, so typing in skip would give you unexpected results.
Variables: Variables:
* The builtin variables ${CALLERID}, ${CALLERIDNAME}, ${CALLERIDNUM}, * The builtin variables ${CALLERID}, ${CALLERIDNAME}, ${CALLERIDNUM},

View File

@@ -43,6 +43,19 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/translate.h" #include "asterisk/translate.h"
#include "asterisk/options.h" #include "asterisk/options.h"
#include "asterisk/utils.h" #include "asterisk/utils.h"
#include "asterisk/indications.h"
enum {
OPT_SKIP = (1 << 0),
OPT_INDICATION = (1 << 1),
OPT_NOANSWER = (1 << 2),
} read_option_flags;
AST_APP_OPTIONS(read_app_options, {
AST_APP_OPTION('s', OPT_SKIP),
AST_APP_OPTION('i', OPT_INDICATION),
AST_APP_OPTION('n', OPT_NOANSWER),
});
static char *tdesc = "Read Variable Application"; static char *tdesc = "Read Variable Application";
@@ -54,14 +67,16 @@ static char *descrip =
" Read(variable[|filename][|maxdigits][|option][|attempts][|timeout])\n\n" " Read(variable[|filename][|maxdigits][|option][|attempts][|timeout])\n\n"
"Reads a #-terminated string of digits a certain number of times from the\n" "Reads a #-terminated string of digits a certain number of times from the\n"
"user in to the given variable.\n" "user in to the given variable.\n"
" filename -- file to play before reading digits.\n" " filename -- file to play before reading digits or tone with option i\n"
" maxdigits -- maximum acceptable number of digits. Stops reading after\n" " maxdigits -- maximum acceptable number of digits. Stops reading after\n"
" maxdigits have been entered (without requiring the user to\n" " maxdigits have been entered (without requiring the user to\n"
" press the '#' key).\n" " press the '#' key).\n"
" Defaults to 0 - no limit - wait for the user press the '#' key.\n" " Defaults to 0 - no limit - wait for the user press the '#' key.\n"
" Any value below 0 means the same. Max accepted value is 255.\n" " Any value below 0 means the same. Max accepted value is 255.\n"
" option -- may be 'skip' to return immediately if the line is not up,\n" " option -- options are 's' , 'i', 'n'\n"
" or 'noanswer' to read digits even if the line is not up.\n" " 's' to return immediately if the line is not up,\n"
" 'i' to play filename as an indication tone from your indications.conf\n"
" 'n' to read digits even if the line is not up.\n"
" attempts -- if greater than 1, that many attempts will be made in the \n" " attempts -- if greater than 1, that many attempts will be made in the \n"
" event no data is entered.\n" " event no data is entered.\n"
" timeout -- if greater than 0, that value will override the default timeout.\n\n" " timeout -- if greater than 0, that value will override the default timeout.\n\n"
@@ -78,21 +93,23 @@ static int read_exec(struct ast_channel *chan, void *data)
int res = 0; int res = 0;
struct localuser *u; struct localuser *u;
char tmp[256]; char tmp[256];
char *timeout = NULL;
char *varname = NULL;
char *filename = NULL;
char *loops;
char *maxdigitstr=NULL;
char *options=NULL;
int option_skip = 0;
int option_noanswer = 0;
int maxdigits=255; int maxdigits=255;
int tries = 1; int tries = 1;
int to = 0; int to = 0;
int x = 0; int x = 0;
char *argcopy = NULL; char *argcopy = NULL;
char *args[8]; struct tone_zone_sound *ts;
struct ast_flags flags = {0};
AST_DECLARE_APP_ARGS(arglist,
AST_APP_ARG(variable);
AST_APP_ARG(filename);
AST_APP_ARG(maxdigits);
AST_APP_ARG(options);
AST_APP_ARG(attempts);
AST_APP_ARG(timeout);
);
if (ast_strlen_zero(data)) { if (ast_strlen_zero(data)) {
ast_log(LOG_WARNING, "Read requires an argument (variable)\n"); ast_log(LOG_WARNING, "Read requires an argument (variable)\n");
return -1; return -1;
@@ -101,74 +118,57 @@ static int read_exec(struct ast_channel *chan, void *data)
LOCAL_USER_ADD(u); LOCAL_USER_ADD(u);
argcopy = ast_strdupa(data); argcopy = ast_strdupa(data);
if (!argcopy) {
ast_log(LOG_ERROR, "Out of memory\n");
LOCAL_USER_REMOVE(u);
return -1;
}
if (ast_app_separate_args(argcopy, '|', args, sizeof(args) / sizeof(args[0])) < 1) { AST_STANDARD_APP_ARGS(arglist, argcopy);
ast_log(LOG_WARNING, "Cannot Parse Arguments.\n");
LOCAL_USER_REMOVE(u);
return -1;
}
varname = args[x++];
filename = args[x++];
maxdigitstr = args[x++];
options = args[x++];
loops = args[x++];
timeout = args[x++];
if (options) { ast_verbose("\n var %s\nfilename %s\nmaxdigits %s\noptions %s\nattempts %s\ntimeout %s\n",arglist.variable,arglist.filename,arglist.maxdigits,arglist.options, arglist.attempts,arglist.timeout);
if (!strcasecmp(options, "skip"))
option_skip = 1;
else if (!strcasecmp(options, "noanswer"))
option_noanswer = 1;
else {
if (strchr(options, 's'))
option_skip = 1;
if (strchr(options, 'n'))
option_noanswer = 1;
}
}
if(loops) { if(arglist.options){
tries = atoi(loops); ast_app_parse_options(read_app_options, &flags, NULL, arglist.options);
}
if(arglist.attempts) {
tries = atoi(arglist.attempts);
if(tries <= 0) if(tries <= 0)
tries = 1; tries = 1;
} }
if(timeout) { if(arglist.timeout) {
to = atoi(timeout); to = atoi(arglist.timeout);
if (to <= 0) if (to <= 0)
to = 0; to = 0;
else else
to *= 1000; to *= 1000;
} }
if (ast_strlen_zero(filename)) if (ast_strlen_zero(arglist.filename)){
filename = NULL; arglist.filename = NULL;
if (maxdigitstr) { }
maxdigits = atoi(maxdigitstr); if (arglist.maxdigits) {
maxdigits = atoi(arglist.maxdigits);
if ((maxdigits<1) || (maxdigits>255)) { if ((maxdigits<1) || (maxdigits>255)) {
maxdigits = 255; maxdigits = 255;
} else if (option_verbose > 2) } else if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "Accepting a maximum of %d digits.\n", maxdigits); ast_verbose(VERBOSE_PREFIX_3 "Accepting a maximum of %d digits.\n", maxdigits);
} }
if (ast_strlen_zero(varname)) { if (ast_strlen_zero(arglist.variable)) {
ast_log(LOG_WARNING, "Invalid! Usage: Read(variable[|filename][|maxdigits][|option][|attempts][|timeout])\n\n"); ast_log(LOG_WARNING, "Invalid! Usage: Read(variable[|filename][|maxdigits][|option][|attempts][|timeout])\n\n");
LOCAL_USER_REMOVE(u); LOCAL_USER_REMOVE(u);
return -1; return -1;
} }
ts=NULL;
if(ast_test_flag(&flags,OPT_INDICATION)){
if(!ast_strlen_zero(arglist.filename)){
ts = ast_get_indication_tone(chan->zone,arglist.filename);
}
}
if (chan->_state != AST_STATE_UP) { if (chan->_state != AST_STATE_UP) {
if (option_skip) { if (ast_test_flag(&flags,OPT_SKIP)) {
/* At the user's option, skip if the line is not up */ /* At the user's option, skip if the line is not up */
pbx_builtin_setvar_helper(chan, varname, "\0"); pbx_builtin_setvar_helper(chan, arglist.variable, "\0");
LOCAL_USER_REMOVE(u); LOCAL_USER_REMOVE(u);
return 0; return 0;
} else if (!option_noanswer) { } else if (!ast_test_flag(&flags,OPT_NOANSWER)) {
/* Otherwise answer unless we're supposed to read while on-hook */ /* Otherwise answer unless we're supposed to read while on-hook */
res = ast_answer(chan); res = ast_answer(chan);
} }
@@ -176,9 +176,28 @@ static int read_exec(struct ast_channel *chan, void *data)
if (!res) { if (!res) {
while(tries && !res) { while(tries && !res) {
ast_stopstream(chan); ast_stopstream(chan);
res = ast_app_getdata(chan, filename, tmp, maxdigits, to); if (ts && ts->data[0]){
if(!to)
to = chan->pbx ? chan->pbx->rtimeout * 1000 : 6000;
res = ast_playtones_start(chan, 0, ts->data, 0);
for (x = 0; x < maxdigits; ){
res = ast_waitfordigit(chan, to);
ast_playtones_stop(chan);
if (res < 1){
tmp[x]='\0';
break;
}
tmp[x++] = res;
if (tmp[x-1] == '#'){
tmp[x-1] = '\0';
break;
}
}
} else {
res = ast_app_getdata(chan, arglist.filename, tmp, maxdigits, to);
}
if (res > -1) { if (res > -1) {
pbx_builtin_setvar_helper(chan, varname, tmp); pbx_builtin_setvar_helper(chan, arglist.variable, tmp);
if (!ast_strlen_zero(tmp)) { if (!ast_strlen_zero(tmp)) {
if (option_verbose > 2) if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "User entered '%s'\n", tmp); ast_verbose(VERBOSE_PREFIX_3 "User entered '%s'\n", tmp);