Trivial application to read an extension into a variable. More...
#include "asterisk.h"
#include "asterisk/file.h"
#include "asterisk/pbx.h"
#include "asterisk/app.h"
#include "asterisk/module.h"
#include "asterisk/indications.h"
#include "asterisk/channel.h"
Go to the source code of this file.
Enumerations | |
enum | readexten_option_flags { OPT_SKIP = (1 << 0), OPT_INDICATION = (1 << 1), OPT_NOANSWER = (1 << 2) } |
Functions | |
static int | acf_isexten_exec (struct ast_channel *chan, const char *cmd, char *parse, char *buffer, size_t buflen) |
AST_APP_OPTIONS (readexten_app_options,{AST_APP_OPTION('s', OPT_SKIP), AST_APP_OPTION('i', OPT_INDICATION), AST_APP_OPTION('n', OPT_NOANSWER),}) | |
AST_MODULE_INFO_STANDARD (ASTERISK_GPL_KEY,"Read and evaluate extension validity") | |
static int | load_module (void) |
static int | readexten_exec (struct ast_channel *chan, const char *data) |
static int | unload_module (void) |
Variables | |
static struct ast_custom_function | acf_isexten |
static char * | app = "ReadExten" |
Trivial application to read an extension into a variable.
Definition in file app_readexten.c.
Definition at line 119 of file app_readexten.c.
00119 { 00120 OPT_SKIP = (1 << 0), 00121 OPT_INDICATION = (1 << 1), 00122 OPT_NOANSWER = (1 << 2), 00123 };
static int acf_isexten_exec | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | parse, | |||
char * | buffer, | |||
size_t | buflen | |||
) | [static] |
Definition at line 283 of file app_readexten.c.
References args, AST_APP_ARG, ast_copy_string(), AST_DECLARE_APP_ARGS, ast_exists_extension(), ast_log(), AST_STANDARD_APP_ARGS, ast_strlen_zero(), ast_channel::caller, ast_channel::context, context, ast_party_caller::id, LOG_WARNING, ast_party_id::number, S_COR, ast_party_number::str, and ast_party_number::valid.
00284 { 00285 int priority_int; 00286 AST_DECLARE_APP_ARGS(args, 00287 AST_APP_ARG(context); 00288 AST_APP_ARG(extension); 00289 AST_APP_ARG(priority); 00290 ); 00291 00292 AST_STANDARD_APP_ARGS(args, parse); 00293 00294 if (ast_strlen_zero(args.context)) 00295 args.context = chan->context; 00296 00297 if (ast_strlen_zero(args.extension)) { 00298 ast_log(LOG_WARNING, "Syntax: VALID_EXTEN([<context>],<extension>[,<priority>]) - missing argument <extension>!\n"); 00299 return -1; 00300 } 00301 00302 if (ast_strlen_zero(args.priority)) 00303 priority_int = 1; 00304 else 00305 priority_int = atoi(args.priority); 00306 00307 if (ast_exists_extension(chan, args.context, args.extension, priority_int, 00308 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 00309 ast_copy_string(buffer, "1", buflen); 00310 } else { 00311 ast_copy_string(buffer, "0", buflen); 00312 } 00313 00314 return 0; 00315 }
AST_APP_OPTIONS | ( | readexten_app_options | ) |
AST_MODULE_INFO_STANDARD | ( | ASTERISK_GPL_KEY | , | |
"Read and evaluate extension validity" | ||||
) |
static int load_module | ( | void | ) | [static] |
Definition at line 330 of file app_readexten.c.
References ast_custom_function_register, ast_register_application_xml, and readexten_exec().
00331 { 00332 int res = ast_register_application_xml(app, readexten_exec); 00333 res |= ast_custom_function_register(&acf_isexten); 00334 return res; 00335 }
static int readexten_exec | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 133 of file app_readexten.c.
References ast_channel::_state, ast_answer(), AST_APP_ARG, ast_app_parse_options(), ast_check_hangup(), ast_debug, AST_DECLARE_APP_ARGS, ast_exists_extension(), ast_fileexists(), ast_get_indication_tone(), ast_log(), ast_matchmore_extension(), ast_playtones_start(), ast_playtones_stop(), AST_STANDARD_APP_ARGS, AST_STATE_UP, ast_stopstream(), ast_strdupa, ast_streamfile(), ast_strlen_zero(), ast_test_flag, ast_tone_zone_sound_unref(), ast_waitfordigit(), ast_channel::caller, ast_channel::context, context, ast_tone_zone_sound::data, ast_pbx::dtimeoutms, exten, ast_party_caller::id, LOG_WARNING, ast_party_id::number, OPT_INDICATION, OPT_NOANSWER, OPT_SKIP, ast_channel::pbx, pbx_builtin_setvar_helper(), ast_pbx::rtimeoutms, S_COR, status, ast_party_number::str, ast_party_number::valid, and ast_channel::zone.
Referenced by load_module().
00134 { 00135 int res = 0; 00136 char exten[256] = ""; 00137 int maxdigits = sizeof(exten) - 1; 00138 int timeout = 0, digit_timeout = 0, x = 0; 00139 char *argcopy = NULL, *status = ""; 00140 struct ast_tone_zone_sound *ts = NULL; 00141 struct ast_flags flags = {0}; 00142 00143 AST_DECLARE_APP_ARGS(arglist, 00144 AST_APP_ARG(variable); 00145 AST_APP_ARG(filename); 00146 AST_APP_ARG(context); 00147 AST_APP_ARG(options); 00148 AST_APP_ARG(timeout); 00149 ); 00150 00151 if (ast_strlen_zero(data)) { 00152 ast_log(LOG_WARNING, "ReadExten requires at least one argument\n"); 00153 pbx_builtin_setvar_helper(chan, "READEXTENSTATUS", "ERROR"); 00154 return 0; 00155 } 00156 00157 argcopy = ast_strdupa(data); 00158 AST_STANDARD_APP_ARGS(arglist, argcopy); 00159 00160 if (ast_strlen_zero(arglist.variable)) { 00161 ast_log(LOG_WARNING, "Usage: ReadExten(variable[,filename[,context[,options[,timeout]]]])\n"); 00162 pbx_builtin_setvar_helper(chan, "READEXTENSTATUS", "ERROR"); 00163 return 0; 00164 } 00165 00166 if (ast_strlen_zero(arglist.filename)) 00167 arglist.filename = NULL; 00168 00169 if (ast_strlen_zero(arglist.context)) 00170 arglist.context = chan->context; 00171 00172 if (!ast_strlen_zero(arglist.options)) 00173 ast_app_parse_options(readexten_app_options, &flags, NULL, arglist.options); 00174 00175 if (!ast_strlen_zero(arglist.timeout)) { 00176 timeout = atoi(arglist.timeout); 00177 if (timeout > 0) 00178 timeout *= 1000; 00179 } 00180 00181 if (timeout <= 0) 00182 timeout = chan->pbx ? chan->pbx->rtimeoutms : 10000; 00183 00184 if (digit_timeout <= 0) 00185 digit_timeout = chan->pbx ? chan->pbx->dtimeoutms : 5000; 00186 00187 if (ast_test_flag(&flags, OPT_INDICATION) && !ast_strlen_zero(arglist.filename)) { 00188 ts = ast_get_indication_tone(chan->zone, arglist.filename); 00189 } 00190 00191 do { 00192 if (chan->_state != AST_STATE_UP) { 00193 if (ast_test_flag(&flags, OPT_SKIP)) { 00194 /* At the user's option, skip if the line is not up */ 00195 pbx_builtin_setvar_helper(chan, arglist.variable, ""); 00196 status = "SKIP"; 00197 break; 00198 } else if (!ast_test_flag(&flags, OPT_NOANSWER)) { 00199 /* Otherwise answer unless we're supposed to read while on-hook */ 00200 res = ast_answer(chan); 00201 } 00202 } 00203 00204 if (res < 0) { 00205 status = "HANGUP"; 00206 break; 00207 } 00208 00209 ast_playtones_stop(chan); 00210 ast_stopstream(chan); 00211 00212 if (ts && ts->data[0]) { 00213 res = ast_playtones_start(chan, 0, ts->data, 0); 00214 } else if (arglist.filename) { 00215 if (ast_test_flag(&flags, OPT_INDICATION) && ast_fileexists(arglist.filename, NULL, chan->language) <= 0) { 00216 /* 00217 * We were asked to play an indication that did not exist in the config. 00218 * If no such file exists, play it as a tonelist. With any luck they won't 00219 * have a file named "350+440.ulaw" 00220 * (but honestly, who would do something so silly?) 00221 */ 00222 res = ast_playtones_start(chan, 0, arglist.filename, 0); 00223 } else { 00224 res = ast_streamfile(chan, arglist.filename, chan->language); 00225 } 00226 } 00227 00228 for (x = 0; x < maxdigits; x++) { 00229 ast_debug(3, "extension so far: '%s', timeout: %d\n", exten, timeout); 00230 res = ast_waitfordigit(chan, timeout); 00231 00232 ast_playtones_stop(chan); 00233 ast_stopstream(chan); 00234 timeout = digit_timeout; 00235 00236 if (res < 1) { /* timeout expired or hangup */ 00237 if (ast_check_hangup(chan)) { 00238 status = "HANGUP"; 00239 } else if (x == 0) { 00240 pbx_builtin_setvar_helper(chan, arglist.variable, "t"); 00241 status = "TIMEOUT"; 00242 } 00243 break; 00244 } 00245 00246 exten[x] = res; 00247 if (!ast_matchmore_extension(chan, arglist.context, exten, 1 /* priority */, 00248 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 00249 if (!ast_exists_extension(chan, arglist.context, exten, 1, 00250 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL)) 00251 && res == '#') { 00252 exten[x] = '\0'; 00253 } 00254 break; 00255 } 00256 } 00257 00258 if (!ast_strlen_zero(status)) 00259 break; 00260 00261 if (ast_exists_extension(chan, arglist.context, exten, 1, 00262 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 00263 ast_debug(3, "User entered valid extension '%s'\n", exten); 00264 pbx_builtin_setvar_helper(chan, arglist.variable, exten); 00265 status = "OK"; 00266 } else { 00267 ast_debug(3, "User dialed invalid extension '%s' in context '%s' on %s\n", exten, arglist.context, chan->name); 00268 pbx_builtin_setvar_helper(chan, arglist.variable, "i"); 00269 pbx_builtin_setvar_helper(chan, "INVALID_EXTEN", exten); 00270 status = "INVALID"; 00271 } 00272 } while (0); 00273 00274 if (ts) { 00275 ts = ast_tone_zone_sound_unref(ts); 00276 } 00277 00278 pbx_builtin_setvar_helper(chan, "READEXTENSTATUS", status); 00279 00280 return status[0] == 'H' ? -1 : 0; 00281 }
static int unload_module | ( | void | ) | [static] |
Definition at line 322 of file app_readexten.c.
References ast_custom_function_unregister(), and ast_unregister_application().
00323 { 00324 int res = ast_unregister_application(app); 00325 res |= ast_custom_function_unregister(&acf_isexten); 00326 00327 return res; 00328 }
struct ast_custom_function acf_isexten [static] |
{ .name = "VALID_EXTEN", .read = acf_isexten_exec, }
Definition at line 317 of file app_readexten.c.
char* app = "ReadExten" [static] |
Definition at line 131 of file app_readexten.c.