#include <asterisk/module.h>
#include <asterisk/translate.h>
#include <asterisk/options.h>
+#include <asterisk/utils.h>
#include <string.h>
#include <stdlib.h>
-#include <pthread.h>
static char *tdesc = "Read Variable Application";
static char *synopsis = "Read a variable";
static char *descrip =
-" Read(variable[|filename]): Reads a '#' terminated string of digits from\n"
-"the user, optionally playing a given filename first. Returns -1 on hangup or\n"
-"error and 0 otherwise.\n";
+" Read(variable[|filename][|maxdigits][|option])\n\n"
+"Reads a #-terminated string of digits from the user in to the given variable,\n"
+"optionally playing a given filename first.\n"
+" maxdigits -- maximum acceptable number of digits. Stops reading after\n"
+" maxdigits have been entered (without requiring the user to\n"
+" 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"
+" option -- may be 'skip' to return immediately if the line is not up,\n"
+" or 'noanswer' to read digits even if the line is not up.\n\n"
+"Returns -1 on hangup or error and 0 otherwise.\n";
STANDARD_LOCAL_USER;
int res = 0;
struct localuser *u;
char tmp[256];
- char tmp2[128]="";
+ char argdata[256] = "";
+ char *varname;
char *filename;
char *stringp;
- if (!data || !strlen((char *)data)) {
+ char *maxdigitstr;
+ char *options;
+ int option_skip = 0;
+ int option_noanswer = 0;
+ int maxdigits=255;
+ if (!data || ast_strlen_zero((char *)data)) {
ast_log(LOG_WARNING, "Read requires an argument (variable)\n");
return -1;
}
- strncpy(tmp, (char *)data, sizeof(tmp)-1);
- stringp=tmp;
- strsep(&stringp, "|");
+ strncpy(argdata, (char *)data, sizeof(argdata)-1);
+ stringp=argdata;
+ varname = strsep(&stringp, "|");
filename = strsep(&stringp, "|");
- if (!strlen(tmp)) {
+ maxdigitstr = strsep(&stringp,"|");
+ options = strsep(&stringp, "|");
+ if (options && !strcasecmp(options, "skip"))
+ option_skip = 1;
+ if (options && !strcasecmp(options, "noanswer"))
+ option_noanswer = 1;
+ if (!(filename) || ast_strlen_zero(filename))
+ filename = NULL;
+ if (maxdigitstr) {
+ maxdigits = atoi(maxdigitstr);
+ if ((maxdigits<1) || (maxdigits>255)) {
+ maxdigits = 255;
+ } else
+ ast_verbose(VERBOSE_PREFIX_3 "Accepting a maximum of %i digits.\n", maxdigits);
+ }
+ if (!(varname) || ast_strlen_zero(varname)) {
ast_log(LOG_WARNING, "Read requires an variable name\n");
return -1;
}
LOCAL_USER_ADD(u);
if (chan->_state != AST_STATE_UP) {
- /* Answer if the line isn't up. */
- res = ast_answer(chan);
+ if (option_skip) {
+ /* At the user's option, skip if the line is not up */
+ pbx_builtin_setvar_helper(chan, varname, "\0");
+ LOCAL_USER_REMOVE(u);
+ return 0;
+ } else if (!option_noanswer) {
+ /* Otherwise answer unless we're supposed to read while on-hook */
+ res = ast_answer(chan);
+ }
}
if (!res) {
ast_stopstream(chan);
- res = ast_app_getdata(chan, filename, tmp2, sizeof(tmp2) - 1, 0);
- if (!res)
- pbx_builtin_setvar_helper(chan, tmp, tmp2);
- ast_verbose(VERBOSE_PREFIX_3 "User entered '%s'\n", tmp2);
+ res = ast_app_getdata(chan, filename, tmp, maxdigits, 0);
+ if (res > -1) {
+ pbx_builtin_setvar_helper(chan, varname, tmp);
+ ast_verbose(VERBOSE_PREFIX_3 "User entered '%s'\n", tmp);
+ res = 0;
+ } else {
+ ast_verbose(VERBOSE_PREFIX_3 "User disconnected\n");
+ }
}
LOCAL_USER_REMOVE(u);
return res;