#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 void | __reg_module (void) |
static void | __unreg_module (void) |
static int | acf_isexten_exec (struct ast_channel *chan, const char *cmd, char *parse, char *buffer, size_t buflen) |
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_module_info | __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Read and evaluate extension validity" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "8586c2a7d357cb591cc3a6607a8f62d1" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, } |
static struct ast_custom_function | acf_isexten |
static char * | app = "ReadExten" |
static struct ast_module_info * | ast_module_info = &__mod_info |
static struct ast_app_option | readexten_app_options [128] = { [ 's' ] = { .flag = OPT_SKIP }, [ 'i' ] = { .flag = OPT_INDICATION }, [ 'n' ] = { .flag = OPT_NOANSWER },} |
Definition in file app_readexten.c.
Definition at line 115 of file app_readexten.c.
00115 { 00116 OPT_SKIP = (1 << 0), 00117 OPT_INDICATION = (1 << 1), 00118 OPT_NOANSWER = (1 << 2), 00119 };
static void __reg_module | ( | void | ) | [static] |
Definition at line 333 of file app_readexten.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 333 of file app_readexten.c.
static int acf_isexten_exec | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | parse, | |||
char * | buffer, | |||
size_t | buflen | |||
) | [static] |
Definition at line 279 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.
00280 { 00281 int priority_int; 00282 AST_DECLARE_APP_ARGS(args, 00283 AST_APP_ARG(context); 00284 AST_APP_ARG(extension); 00285 AST_APP_ARG(priority); 00286 ); 00287 00288 AST_STANDARD_APP_ARGS(args, parse); 00289 00290 if (ast_strlen_zero(args.context)) 00291 args.context = chan->context; 00292 00293 if (ast_strlen_zero(args.extension)) { 00294 ast_log(LOG_WARNING, "Syntax: VALID_EXTEN([<context>],<extension>[,<priority>]) - missing argument <extension>!\n"); 00295 return -1; 00296 } 00297 00298 if (ast_strlen_zero(args.priority)) 00299 priority_int = 1; 00300 else 00301 priority_int = atoi(args.priority); 00302 00303 if (ast_exists_extension(chan, args.context, args.extension, priority_int, 00304 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 00305 ast_copy_string(buffer, "1", buflen); 00306 } else { 00307 ast_copy_string(buffer, "0", buflen); 00308 } 00309 00310 return 0; 00311 }
static int load_module | ( | void | ) | [static] |
Definition at line 326 of file app_readexten.c.
References acf_isexten, ast_custom_function_register, ast_register_application_xml, and readexten_exec().
00327 { 00328 int res = ast_register_application_xml(app, readexten_exec); 00329 res |= ast_custom_function_register(&acf_isexten); 00330 return res; 00331 }
static int readexten_exec | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 129 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_flags::flags, ast_party_caller::id, ast_channel::language, LOG_WARNING, ast_channel::name, ast_party_id::number, OPT_INDICATION, OPT_NOANSWER, OPT_SKIP, ast_channel::pbx, pbx_builtin_setvar_helper(), readexten_app_options, ast_pbx::rtimeoutms, S_COR, status, ast_party_number::str, ast_party_number::valid, and ast_channel::zone.
Referenced by load_module().
00130 { 00131 int res = 0; 00132 char exten[256] = ""; 00133 int maxdigits = sizeof(exten) - 1; 00134 int timeout = 0, digit_timeout = 0, x = 0; 00135 char *argcopy = NULL, *status = ""; 00136 struct ast_tone_zone_sound *ts = NULL; 00137 struct ast_flags flags = {0}; 00138 00139 AST_DECLARE_APP_ARGS(arglist, 00140 AST_APP_ARG(variable); 00141 AST_APP_ARG(filename); 00142 AST_APP_ARG(context); 00143 AST_APP_ARG(options); 00144 AST_APP_ARG(timeout); 00145 ); 00146 00147 if (ast_strlen_zero(data)) { 00148 ast_log(LOG_WARNING, "ReadExten requires at least one argument\n"); 00149 pbx_builtin_setvar_helper(chan, "READEXTENSTATUS", "ERROR"); 00150 return 0; 00151 } 00152 00153 argcopy = ast_strdupa(data); 00154 AST_STANDARD_APP_ARGS(arglist, argcopy); 00155 00156 if (ast_strlen_zero(arglist.variable)) { 00157 ast_log(LOG_WARNING, "Usage: ReadExten(variable[,filename[,context[,options[,timeout]]]])\n"); 00158 pbx_builtin_setvar_helper(chan, "READEXTENSTATUS", "ERROR"); 00159 return 0; 00160 } 00161 00162 if (ast_strlen_zero(arglist.filename)) 00163 arglist.filename = NULL; 00164 00165 if (ast_strlen_zero(arglist.context)) 00166 arglist.context = chan->context; 00167 00168 if (!ast_strlen_zero(arglist.options)) 00169 ast_app_parse_options(readexten_app_options, &flags, NULL, arglist.options); 00170 00171 if (!ast_strlen_zero(arglist.timeout)) { 00172 timeout = atoi(arglist.timeout); 00173 if (timeout > 0) 00174 timeout *= 1000; 00175 } 00176 00177 if (timeout <= 0) 00178 timeout = chan->pbx ? chan->pbx->rtimeoutms : 10000; 00179 00180 if (digit_timeout <= 0) 00181 digit_timeout = chan->pbx ? chan->pbx->dtimeoutms : 5000; 00182 00183 if (ast_test_flag(&flags, OPT_INDICATION) && !ast_strlen_zero(arglist.filename)) { 00184 ts = ast_get_indication_tone(chan->zone, arglist.filename); 00185 } 00186 00187 do { 00188 if (chan->_state != AST_STATE_UP) { 00189 if (ast_test_flag(&flags, OPT_SKIP)) { 00190 /* At the user's option, skip if the line is not up */ 00191 pbx_builtin_setvar_helper(chan, arglist.variable, ""); 00192 status = "SKIP"; 00193 break; 00194 } else if (!ast_test_flag(&flags, OPT_NOANSWER)) { 00195 /* Otherwise answer unless we're supposed to read while on-hook */ 00196 res = ast_answer(chan); 00197 } 00198 } 00199 00200 if (res < 0) { 00201 status = "HANGUP"; 00202 break; 00203 } 00204 00205 ast_playtones_stop(chan); 00206 ast_stopstream(chan); 00207 00208 if (ts && ts->data[0]) { 00209 res = ast_playtones_start(chan, 0, ts->data, 0); 00210 } else if (arglist.filename) { 00211 if (ast_test_flag(&flags, OPT_INDICATION) && ast_fileexists(arglist.filename, NULL, chan->language) <= 0) { 00212 /* 00213 * We were asked to play an indication that did not exist in the config. 00214 * If no such file exists, play it as a tonelist. With any luck they won't 00215 * have a file named "350+440.ulaw" 00216 * (but honestly, who would do something so silly?) 00217 */ 00218 res = ast_playtones_start(chan, 0, arglist.filename, 0); 00219 } else { 00220 res = ast_streamfile(chan, arglist.filename, chan->language); 00221 } 00222 } 00223 00224 for (x = 0; x < maxdigits; x++) { 00225 ast_debug(3, "extension so far: '%s', timeout: %d\n", exten, timeout); 00226 res = ast_waitfordigit(chan, timeout); 00227 00228 ast_playtones_stop(chan); 00229 ast_stopstream(chan); 00230 timeout = digit_timeout; 00231 00232 if (res < 1) { /* timeout expired or hangup */ 00233 if (ast_check_hangup(chan)) { 00234 status = "HANGUP"; 00235 } else if (x == 0) { 00236 pbx_builtin_setvar_helper(chan, arglist.variable, "t"); 00237 status = "TIMEOUT"; 00238 } 00239 break; 00240 } 00241 00242 exten[x] = res; 00243 if (!ast_matchmore_extension(chan, arglist.context, exten, 1 /* priority */, 00244 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 00245 if (!ast_exists_extension(chan, arglist.context, exten, 1, 00246 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL)) 00247 && res == '#') { 00248 exten[x] = '\0'; 00249 } 00250 break; 00251 } 00252 } 00253 00254 if (!ast_strlen_zero(status)) 00255 break; 00256 00257 if (ast_exists_extension(chan, arglist.context, exten, 1, 00258 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 00259 ast_debug(3, "User entered valid extension '%s'\n", exten); 00260 pbx_builtin_setvar_helper(chan, arglist.variable, exten); 00261 status = "OK"; 00262 } else { 00263 ast_debug(3, "User dialed invalid extension '%s' in context '%s' on %s\n", exten, arglist.context, chan->name); 00264 pbx_builtin_setvar_helper(chan, arglist.variable, "i"); 00265 pbx_builtin_setvar_helper(chan, "INVALID_EXTEN", exten); 00266 status = "INVALID"; 00267 } 00268 } while (0); 00269 00270 if (ts) { 00271 ts = ast_tone_zone_sound_unref(ts); 00272 } 00273 00274 pbx_builtin_setvar_helper(chan, "READEXTENSTATUS", status); 00275 00276 return status[0] == 'H' ? -1 : 0; 00277 }
static int unload_module | ( | void | ) | [static] |
Definition at line 318 of file app_readexten.c.
References acf_isexten, ast_custom_function_unregister(), and ast_unregister_application().
00319 { 00320 int res = ast_unregister_application(app); 00321 res |= ast_custom_function_unregister(&acf_isexten); 00322 00323 return res; 00324 }
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Read and evaluate extension validity" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "8586c2a7d357cb591cc3a6607a8f62d1" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, } [static] |
Definition at line 333 of file app_readexten.c.
struct ast_custom_function acf_isexten [static] |
Initial value:
{ .name = "VALID_EXTEN", .read = acf_isexten_exec, }
Definition at line 313 of file app_readexten.c.
Referenced by load_module(), and unload_module().
char* app = "ReadExten" [static] |
Definition at line 127 of file app_readexten.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 333 of file app_readexten.c.
struct ast_app_option readexten_app_options[128] = { [ 's' ] = { .flag = OPT_SKIP }, [ 'i' ] = { .flag = OPT_INDICATION }, [ 'n' ] = { .flag = OPT_NOANSWER },} [static] |