Fri Nov 12 11:51:14 2010

Asterisk developer's documentation


app_readexten.c File Reference

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"
Include dependency graph for app_readexten.c:

Go to the source code of this file.

Enumerations

enum  { 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, void *data)
static int unload_module (void)

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .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 = "0901e4e500243c855563a2d78b0c03e4" , .load = load_module, .unload = unload_module, }
static struct ast_custom_function acf_isexten
static char * app = "ReadExten"
static struct ast_module_infoast_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 },}
enum { ... }  readexten_option_flags

Detailed Description

Trivial application to read an extension into a variable.

Author:
David Chappell <David.Chappell@trincoll.edu>

Definition in file app_readexten.c.


Enumeration Type Documentation

anonymous enum
Enumerator:
OPT_SKIP 
OPT_INDICATION 
OPT_NOANSWER 

Definition at line 114 of file app_readexten.c.

00114      {
00115    OPT_SKIP = (1 << 0),
00116    OPT_INDICATION = (1 << 1),
00117    OPT_NOANSWER = (1 << 2),
00118 } readexten_option_flags;


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 315 of file app_readexten.c.

static void __unreg_module ( void   )  [static]

Definition at line 315 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 263 of file app_readexten.c.

References AST_APP_ARG, ast_copy_string(), AST_DECLARE_APP_ARGS, ast_exists_extension(), ast_log(), AST_STANDARD_APP_ARGS, ast_strlen_zero(), ast_channel::cid, ast_callerid::cid_num, ast_channel::context, context, and LOG_WARNING.

00264 {
00265    int priority_int;
00266    AST_DECLARE_APP_ARGS(args,
00267       AST_APP_ARG(context);
00268       AST_APP_ARG(extension);
00269       AST_APP_ARG(priority);
00270    );
00271 
00272    AST_STANDARD_APP_ARGS(args, parse);
00273 
00274    if (ast_strlen_zero(args.context))
00275       args.context = chan->context;
00276 
00277    if (ast_strlen_zero(args.extension)) {
00278       ast_log(LOG_WARNING, "Syntax: VALID_EXTEN([<context>],<extension>[,<priority>]) - missing argument <extension>!\n");
00279       return -1;
00280    }
00281 
00282    if (ast_strlen_zero(args.priority))
00283       priority_int = 1;
00284    else
00285       priority_int = atoi(args.priority);
00286 
00287    if (ast_exists_extension(chan, args.context, args.extension, priority_int, chan->cid.cid_num))
00288        ast_copy_string(buffer, "1", buflen);
00289    else
00290        ast_copy_string(buffer, "0", buflen);
00291 
00292    return 0;
00293 }

static int load_module ( void   )  [static]

Definition at line 308 of file app_readexten.c.

References ast_custom_function_register, ast_register_application_xml, and readexten_exec().

00309 {
00310    int res = ast_register_application_xml(app, readexten_exec);
00311    res |= ast_custom_function_register(&acf_isexten);
00312    return res;
00313 }

static int readexten_exec ( struct ast_channel chan,
void *  data 
) [static]

Definition at line 128 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_get_indication_tone(), ast_log(), ast_matchmore_extension(), ast_playtones_start(), ast_playtones_stop(), AST_STANDARD_APP_ARGS, AST_STATE_UP, ast_stopstream(), ast_streamfile(), ast_strlen_zero(), ast_test_flag, ast_tone_zone_sound_unref(), ast_waitfordigit(), ast_channel::cid, ast_callerid::cid_num, ast_channel::context, context, ast_tone_zone_sound::data, ast_pbx::dtimeoutms, exten, ast_channel::language, LOG_WARNING, ast_channel::name, OPT_INDICATION, OPT_NOANSWER, OPT_SKIP, ast_channel::pbx, pbx_builtin_setvar_helper(), readexten_app_options, ast_pbx::rtimeoutms, status, and ast_channel::zone.

Referenced by load_module().

00129 {
00130    int res = 0;
00131    char exten[256] = "";
00132    int maxdigits = sizeof(exten) - 1;
00133    int timeout = 0, digit_timeout = 0, x = 0;
00134    char *argcopy = NULL, *status = "";
00135    struct ast_tone_zone_sound *ts = NULL;
00136    struct ast_flags flags = {0};
00137 
00138     AST_DECLARE_APP_ARGS(arglist,
00139       AST_APP_ARG(variable);
00140       AST_APP_ARG(filename);
00141       AST_APP_ARG(context);
00142       AST_APP_ARG(options);
00143       AST_APP_ARG(timeout);
00144    );
00145    
00146    if (ast_strlen_zero(data)) {
00147       ast_log(LOG_WARNING, "ReadExten requires at least one argument\n");
00148       pbx_builtin_setvar_helper(chan, "READEXTENSTATUS", "ERROR");
00149       return 0;
00150    }
00151 
00152    argcopy = ast_strdupa(data);
00153    AST_STANDARD_APP_ARGS(arglist, argcopy);
00154 
00155    if (ast_strlen_zero(arglist.variable)) {
00156       ast_log(LOG_WARNING, "Usage: ReadExten(variable[,filename[,context[,options[,timeout]]]])\n");
00157       pbx_builtin_setvar_helper(chan, "READEXTENSTATUS", "ERROR");
00158       return 0;
00159    }
00160 
00161    if (ast_strlen_zero(arglist.filename))
00162       arglist.filename = NULL;
00163 
00164    if (ast_strlen_zero(arglist.context))
00165       arglist.context = chan->context;
00166 
00167    if (!ast_strlen_zero(arglist.options))
00168       ast_app_parse_options(readexten_app_options, &flags, NULL, arglist.options);
00169 
00170    if (!ast_strlen_zero(arglist.timeout)) {
00171       timeout = atoi(arglist.timeout);
00172       if (timeout > 0)
00173          timeout *= 1000;
00174    }
00175 
00176    if (timeout <= 0)
00177       timeout = chan->pbx ? chan->pbx->rtimeoutms : 10000;
00178 
00179    if (digit_timeout <= 0)
00180       digit_timeout = chan->pbx ? chan->pbx->dtimeoutms : 5000;
00181 
00182    if (ast_test_flag(&flags, OPT_INDICATION) && !ast_strlen_zero(arglist.filename)) {
00183       ts = ast_get_indication_tone(chan->zone, arglist.filename);
00184    }
00185 
00186    do {
00187       if (chan->_state != AST_STATE_UP) {
00188          if (ast_test_flag(&flags, OPT_SKIP)) {
00189             /* At the user's option, skip if the line is not up */
00190             pbx_builtin_setvar_helper(chan, arglist.variable, "");
00191             status = "SKIP";
00192             break;
00193          } else if (!ast_test_flag(&flags, OPT_NOANSWER)) {
00194             /* Otherwise answer unless we're supposed to read while on-hook */
00195             res = ast_answer(chan);
00196          }
00197       }
00198 
00199       if (res < 0) {
00200          status = "HANGUP";
00201          break;
00202       }
00203 
00204       ast_playtones_stop(chan);
00205       ast_stopstream(chan);
00206 
00207       if (ts && ts->data[0])
00208          res = ast_playtones_start(chan, 0, ts->data, 0);
00209       else if (arglist.filename)
00210          res = ast_streamfile(chan, arglist.filename, chan->language);
00211 
00212       for (x = 0; x < maxdigits; x++) {
00213          ast_debug(3, "extension so far: '%s', timeout: %d\n", exten, timeout);
00214          res = ast_waitfordigit(chan, timeout);
00215 
00216          ast_playtones_stop(chan);
00217          ast_stopstream(chan);
00218          timeout = digit_timeout;
00219 
00220          if (res < 1) {    /* timeout expired or hangup */
00221             if (ast_check_hangup(chan)) {
00222                status = "HANGUP";
00223             } else {
00224                pbx_builtin_setvar_helper(chan, arglist.variable, "t");
00225                status = "TIMEOUT";
00226             }
00227             break;
00228          }
00229 
00230          exten[x] = res;
00231          if (!ast_matchmore_extension(chan, arglist.context, exten, 1 /* priority */, chan->cid.cid_num)) {
00232             if (!ast_exists_extension(chan, arglist.context, exten, 1, chan->cid.cid_num) && res == '#') {
00233                exten[x] = '\0';
00234             }
00235             break;
00236          }
00237       }
00238 
00239       if (!ast_strlen_zero(status))
00240          break;
00241 
00242       if (ast_exists_extension(chan, arglist.context, exten, 1, chan->cid.cid_num)) {
00243          ast_debug(3, "User entered valid extension '%s'\n", exten);
00244          pbx_builtin_setvar_helper(chan, arglist.variable, exten);
00245          status = "OK";
00246       } else {
00247          ast_debug(3, "User dialed invalid extension '%s' in context '%s' on %s\n", exten, arglist.context, chan->name);
00248          pbx_builtin_setvar_helper(chan, arglist.variable, "i");
00249          pbx_builtin_setvar_helper(chan, "INVALID_EXTEN", exten);
00250          status = "INVALID";
00251       }
00252    } while (0);
00253 
00254    if (ts) {
00255       ts = ast_tone_zone_sound_unref(ts);
00256    }
00257 
00258    pbx_builtin_setvar_helper(chan, "READEXTENSTATUS", status);
00259 
00260    return status[0] == 'H' ? -1 : 0;
00261 }

static int unload_module ( void   )  [static]

Definition at line 300 of file app_readexten.c.

References ast_custom_function_unregister(), and ast_unregister_application().

00301 {
00302    int res = ast_unregister_application(app);
00303    res |= ast_custom_function_unregister(&acf_isexten);
00304 
00305    return res; 
00306 }


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .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 = "0901e4e500243c855563a2d78b0c03e4" , .load = load_module, .unload = unload_module, } [static]

Definition at line 315 of file app_readexten.c.

Initial value:
 {
   .name = "VALID_EXTEN",
   .read = acf_isexten_exec,
}

Definition at line 295 of file app_readexten.c.

char* app = "ReadExten" [static]

Definition at line 126 of file app_readexten.c.

Definition at line 315 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]

Definition at line 124 of file app_readexten.c.

Referenced by readexten_exec().

enum { ... } readexten_option_flags

Generated by  doxygen 1.6.2