Sat Mar 10 01:54:36 2012

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 = "88eaa8f5c1bd988bedd71113385e0886" , .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 119 of file app_readexten.c.

00119                             {
00120    OPT_SKIP = (1 << 0),
00121    OPT_INDICATION = (1 << 1),
00122    OPT_NOANSWER = (1 << 2),
00123 };


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 337 of file app_readexten.c.

static void __unreg_module ( void   )  [static]

Definition at line 337 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 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 }

static int load_module ( void   )  [static]

Definition at line 330 of file app_readexten.c.

References acf_isexten, 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_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().

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


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 = "88eaa8f5c1bd988bedd71113385e0886" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, } [static]

Definition at line 337 of file app_readexten.c.

struct ast_custom_function acf_isexten [static]

Initial value:

 {
   .name = "VALID_EXTEN",
   .read = acf_isexten_exec,
}

Definition at line 317 of file app_readexten.c.

Referenced by load_module(), and unload_module().

char* app = "ReadExten" [static]

Definition at line 131 of file app_readexten.c.

struct ast_module_info* ast_module_info = &__mod_info [static]

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

Referenced by readexten_exec().


Generated on Sat Mar 10 01:54:36 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7