Mon Jun 27 16:50:59 2011

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"

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_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 },}


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

enum readexten_option_flags

Enumerator:
OPT_SKIP 
OPT_INDICATION 
OPT_NOANSWER 

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 };


Function Documentation

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 }


Variable Documentation

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]

Definition at line 125 of file app_readexten.c.

Referenced by readexten_exec().


Generated on Mon Jun 27 16:50:59 2011 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7