103 enum readexten_option_flags {
105 OPT_INDICATION = (1 << 1),
106 OPT_NOANSWER = (1 << 2),
107 OPT_POUND_TO_END = (1 << 3),
117 static char *app =
"ReadExten";
119 static int readexten_exec(
struct ast_channel *chan,
const char *data)
122 char exten[256] =
"";
123 int maxdigits =
sizeof(exten) - 1;
124 int timeout = 0, digit_timeout = 0, x = 0;
125 char *argcopy = NULL, *status =
"";
137 if (ast_strlen_zero(data)) {
138 ast_log(LOG_WARNING,
"ReadExten requires at least one argument\n");
146 if (ast_strlen_zero(arglist.variable)) {
147 ast_log(LOG_WARNING,
"Usage: ReadExten(variable[,filename[,context[,options[,timeout]]]])\n");
152 if (ast_strlen_zero(arglist.filename)) {
153 arglist.filename = NULL;
156 if (ast_strlen_zero(arglist.context)) {
157 arglist.context =
ast_strdupa(ast_channel_context(chan));
160 if (!ast_strlen_zero(arglist.options)) {
164 if (!ast_strlen_zero(arglist.timeout)) {
165 timeout = atoi(arglist.timeout);
171 timeout = ast_channel_pbx(chan) ? ast_channel_pbx(chan)->
rtimeoutms : 10000;
173 digit_timeout = ast_channel_pbx(chan) ? ast_channel_pbx(chan)->
dtimeoutms : 5000;
175 if (ast_test_flag(&flags, OPT_INDICATION) && !ast_strlen_zero(arglist.filename)) {
181 if (ast_test_flag(&flags, OPT_SKIP)) {
186 }
else if (!ast_test_flag(&flags, OPT_NOANSWER)) {
200 if (ts && ts->
data[0]) {
202 }
else if (arglist.filename) {
203 if (ast_test_flag(&flags, OPT_INDICATION) &&
ast_fileexists(arglist.filename, NULL, ast_channel_language(chan)) <= 0) {
212 res =
ast_streamfile(chan, arglist.filename, ast_channel_language(chan));
216 for (x = 0; x < maxdigits; x++) {
217 ast_debug(3,
"extension so far: '%s', timeout: %d\n", exten, timeout);
222 timeout = digit_timeout;
234 if (ast_test_flag(&flags, OPT_POUND_TO_END) && res ==
'#') {
241 S_COR(ast_channel_caller(chan)->
id.
number.valid, ast_channel_caller(chan)->
id.
number.str, NULL))) {
243 S_COR(ast_channel_caller(chan)->
id.
number.valid, ast_channel_caller(chan)->
id.
number.str, NULL))
251 if (!ast_strlen_zero(status))
255 S_COR(ast_channel_caller(chan)->
id.
number.valid, ast_channel_caller(chan)->
id.
number.str, NULL))) {
256 ast_debug(3,
"User entered valid extension '%s'\n", exten);
260 ast_debug(3,
"User dialed invalid extension '%s' in context '%s' on %s\n", exten, arglist.context, ast_channel_name(chan));
273 return status[0] ==
'H' ? -1 : 0;
276 static int unload_module(
void)
282 static int load_module(
void)
288 AST_MODULE_INFO_STANDARD(
ASTERISK_GPL_KEY,
"Read and evaluate extension validity");
int ast_matchmore_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Looks to see if adding anything to this extension might match something. (exists ^ canmatch) ...
Main Channel structure associated with a channel.
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Asterisk main include file. File version handling, generic pbx functions.
char context[AST_MAX_CONTEXT]
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the 'standard' argument separation process for an application.
ast_channel_state
ast_channel states
Generic File Format Support. Should be included by clients of the file handling routines. File service providers should instead include mod_format.h.
void ast_playtones_stop(struct ast_channel *chan)
Stop playing tones on a channel.
int ast_unregister_application(const char *app)
Unregister an application.
#define AST_APP_OPTIONS(holder, options...)
Declares an array of options for an application.
General Asterisk PBX channel definitions.
#define ast_strdupa(s)
duplicate a string in memory from the stack
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
static struct ast_tone_zone_sound * ast_tone_zone_sound_unref(struct ast_tone_zone_sound *ts)
Release a reference to an ast_tone_zone_sound.
#define ast_debug(level,...)
Log a DEBUG message.
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
int ast_app_parse_options(const struct ast_app_option *options, struct ast_flags *flags, char **args, char *optstr)
Parses a string containing application options and sets flags/arguments.
Core PBX routines and definitions.
int ast_check_hangup(struct ast_channel *chan)
Check to see if a channel is needing hang up.
struct ast_tone_zone_sound * ast_get_indication_tone(const struct ast_tone_zone *zone, const char *indication)
Locate a tone zone sound.
Structure used to handle boolean flags.
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
int ast_waitfordigit(struct ast_channel *c, int ms)
Waits for a digit.
int ast_fileexists(const char *filename, const char *fmt, const char *preflang)
Checks for the existence of a given file.
int ast_answer(struct ast_channel *chan)
Answer a channel.
int ast_playtones_start(struct ast_channel *chan, int vol, const char *tonelist, int interruptible)
Start playing a list of tones on a channel.
const char * data
Description of a tone.
#define AST_APP_OPTION(option, flagno)
Declares an application option that does not accept an argument.
#define ASTERISK_GPL_KEY
The text the key() function should return.
Asterisk module definitions.
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
Application convenience functions, designed to give consistent look and feel to Asterisk apps...
int ast_stopstream(struct ast_channel *c)
Stops a stream.
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
#define AST_APP_ARG(name)
Define an application argument.