00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <stdlib.h>
00027 #include <stdio.h>
00028 #include <string.h>
00029
00030 #include "asterisk.h"
00031
00032 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 7221 $")
00033
00034 #include "asterisk/lock.h"
00035 #include "asterisk/file.h"
00036 #include "asterisk/logger.h"
00037 #include "asterisk/channel.h"
00038 #include "asterisk/pbx.h"
00039 #include "asterisk/app.h"
00040 #include "asterisk/module.h"
00041 #include "asterisk/translate.h"
00042 #include "asterisk/options.h"
00043 #include "asterisk/utils.h"
00044
00045 static char *tdesc = "Read Variable Application";
00046
00047 static char *app = "Read";
00048
00049 static char *synopsis = "Read a variable";
00050
00051 static char *descrip =
00052 " Read(variable[|filename][|maxdigits][|option][|attempts][|timeout])\n\n"
00053 "Reads a #-terminated string of digits a certain number of times from the\n"
00054 "user in to the given variable.\n"
00055 " filename -- file to play before reading digits.\n"
00056 " maxdigits -- maximum acceptable number of digits. Stops reading after\n"
00057 " maxdigits have been entered (without requiring the user to\n"
00058 " press the '#' key).\n"
00059 " Defaults to 0 - no limit - wait for the user press the '#' key.\n"
00060 " Any value below 0 means the same. Max accepted value is 255.\n"
00061 " option -- may be 'skip' to return immediately if the line is not up,\n"
00062 " or 'noanswer' to read digits even if the line is not up.\n"
00063 " attempts -- if greater than 1, that many attempts will be made in the \n"
00064 " event no data is entered.\n"
00065 " timeout -- if greater than 0, that value will override the default timeout.\n\n"
00066 "Read should disconnect if the function fails or errors out.\n";
00067
00068 STANDARD_LOCAL_USER;
00069
00070 LOCAL_USER_DECL;
00071
00072 #define ast_next_data(instr,ptr,delim) if((ptr=strchr(instr,delim))) { *(ptr) = '\0' ; ptr++;}
00073
00074 static int read_exec(struct ast_channel *chan, void *data)
00075 {
00076 int res = 0;
00077 struct localuser *u;
00078 char tmp[256];
00079 char *timeout = NULL;
00080 char *varname = NULL;
00081 char *filename = NULL;
00082 char *loops;
00083 char *maxdigitstr=NULL;
00084 char *options=NULL;
00085 int option_skip = 0;
00086 int option_noanswer = 0;
00087 int maxdigits=255;
00088 int tries = 1;
00089 int to = 0;
00090 int x = 0;
00091 char *argcopy = NULL;
00092 char *args[8];
00093
00094 if (ast_strlen_zero(data)) {
00095 ast_log(LOG_WARNING, "Read requires an argument (variable)\n");
00096 return -1;
00097 }
00098
00099 LOCAL_USER_ADD(u);
00100
00101 argcopy = ast_strdupa(data);
00102 if (!argcopy) {
00103 ast_log(LOG_ERROR, "Out of memory\n");
00104 LOCAL_USER_REMOVE(u);
00105 return -1;
00106 }
00107
00108 if (ast_app_separate_args(argcopy, '|', args, sizeof(args) / sizeof(args[0])) < 1) {
00109 ast_log(LOG_WARNING, "Cannot Parse Arguments.\n");
00110 LOCAL_USER_REMOVE(u);
00111 return -1;
00112 }
00113
00114 varname = args[x++];
00115 filename = args[x++];
00116 maxdigitstr = args[x++];
00117 options = args[x++];
00118 loops = args[x++];
00119 timeout = args[x++];
00120
00121 if (options) {
00122 if (!strcasecmp(options, "skip"))
00123 option_skip = 1;
00124 else if (!strcasecmp(options, "noanswer"))
00125 option_noanswer = 1;
00126 else {
00127 if (strchr(options, 's'))
00128 option_skip = 1;
00129 if (strchr(options, 'n'))
00130 option_noanswer = 1;
00131 }
00132 }
00133
00134 if(loops) {
00135 tries = atoi(loops);
00136 if(tries <= 0)
00137 tries = 1;
00138 }
00139
00140 if(timeout) {
00141 to = atoi(timeout);
00142 if (to <= 0)
00143 to = 0;
00144 else
00145 to *= 1000;
00146 }
00147
00148 if (ast_strlen_zero(filename))
00149 filename = NULL;
00150 if (maxdigitstr) {
00151 maxdigits = atoi(maxdigitstr);
00152 if ((maxdigits<1) || (maxdigits>255)) {
00153 maxdigits = 255;
00154 } else if (option_verbose > 2)
00155 ast_verbose(VERBOSE_PREFIX_3 "Accepting a maximum of %d digits.\n", maxdigits);
00156 }
00157 if (ast_strlen_zero(varname)) {
00158 ast_log(LOG_WARNING, "Invalid! Usage: Read(variable[|filename][|maxdigits][|option][|attempts][|timeout])\n\n");
00159 LOCAL_USER_REMOVE(u);
00160 return -1;
00161 }
00162
00163 if (chan->_state != AST_STATE_UP) {
00164 if (option_skip) {
00165
00166 pbx_builtin_setvar_helper(chan, varname, "\0");
00167 LOCAL_USER_REMOVE(u);
00168 return 0;
00169 } else if (!option_noanswer) {
00170
00171 res = ast_answer(chan);
00172 }
00173 }
00174 if (!res) {
00175 while(tries && !res) {
00176 ast_stopstream(chan);
00177 res = ast_app_getdata(chan, filename, tmp, maxdigits, to);
00178 if (res > -1) {
00179 pbx_builtin_setvar_helper(chan, varname, tmp);
00180 if (!ast_strlen_zero(tmp)) {
00181 if (option_verbose > 2)
00182 ast_verbose(VERBOSE_PREFIX_3 "User entered '%s'\n", tmp);
00183 tries = 0;
00184 } else {
00185 tries--;
00186 if (option_verbose > 2) {
00187 if (tries)
00188 ast_verbose(VERBOSE_PREFIX_3 "User entered nothing, %d chance%s left\n", tries, (tries != 1) ? "s" : "");
00189 else
00190 ast_verbose(VERBOSE_PREFIX_3 "User entered nothing.\n");
00191 }
00192 }
00193 res = 0;
00194 } else {
00195 if (option_verbose > 2)
00196 ast_verbose(VERBOSE_PREFIX_3 "User disconnected\n");
00197 }
00198 }
00199 }
00200 LOCAL_USER_REMOVE(u);
00201 return res;
00202 }
00203
00204 int unload_module(void)
00205 {
00206 int res;
00207
00208 res = ast_unregister_application(app);
00209
00210 STANDARD_HANGUP_LOCALUSERS;
00211
00212 return res;
00213 }
00214
00215 int load_module(void)
00216 {
00217 return ast_register_application(app, read_exec, synopsis, descrip);
00218 }
00219
00220 char *description(void)
00221 {
00222 return tdesc;
00223 }
00224
00225 int usecount(void)
00226 {
00227 int res;
00228 STANDARD_USECOUNT(res);
00229 return res;
00230 }
00231
00232 char *key()
00233 {
00234 return ASTERISK_GPL_KEY;
00235 }