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  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 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 = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, .support_level = AST_MODULE_SUPPORT_CORE, }
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

Enumerator:
OPT_SKIP 
OPT_INDICATION 
OPT_NOANSWER 

Definition at line 101 of file app_readexten.c.

00101                             {
00102    OPT_SKIP = (1 << 0),
00103    OPT_INDICATION = (1 << 1),
00104    OPT_NOANSWER = (1 << 2),
00105 };


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 280 of file app_readexten.c.

static void __unreg_module ( void   )  [static]

Definition at line 280 of file app_readexten.c.

static int load_module ( void   )  [static]

Definition at line 274 of file app_readexten.c.

References ast_register_application_xml, and readexten_exec().

00275 {
00276    int res = ast_register_application_xml(app, readexten_exec);
00277    return res;
00278 }

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

Definition at line 115 of file app_readexten.c.

References ast_answer(), AST_APP_ARG, ast_app_parse_options(), ast_channel_caller(), ast_channel_context(), ast_channel_language(), ast_channel_name(), ast_channel_pbx(), ast_channel_zone(), 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::context, context, ast_tone_zone_sound::data, ast_pbx::dtimeoutms, exten, LOG_WARNING, NULL, OPT_INDICATION, OPT_NOANSWER, OPT_SKIP, pbx_builtin_setvar_helper(), readexten_app_options, ast_pbx::rtimeoutms, S_COR, status, and timeout.

Referenced by load_module().

00116 {
00117    int res = 0;
00118    char exten[256] = "";
00119    int maxdigits = sizeof(exten) - 1;
00120    int timeout = 0, digit_timeout = 0, x = 0;
00121    char *argcopy = NULL, *status = "";
00122    struct ast_tone_zone_sound *ts = NULL;
00123    struct ast_flags flags = {0};
00124 
00125     AST_DECLARE_APP_ARGS(arglist,
00126       AST_APP_ARG(variable);
00127       AST_APP_ARG(filename);
00128       AST_APP_ARG(context);
00129       AST_APP_ARG(options);
00130       AST_APP_ARG(timeout);
00131    );
00132 
00133    if (ast_strlen_zero(data)) {
00134       ast_log(LOG_WARNING, "ReadExten requires at least one argument\n");
00135       pbx_builtin_setvar_helper(chan, "READEXTENSTATUS", "ERROR");
00136       return 0;
00137    }
00138 
00139    argcopy = ast_strdupa(data);
00140    AST_STANDARD_APP_ARGS(arglist, argcopy);
00141 
00142    if (ast_strlen_zero(arglist.variable)) {
00143       ast_log(LOG_WARNING, "Usage: ReadExten(variable[,filename[,context[,options[,timeout]]]])\n");
00144       pbx_builtin_setvar_helper(chan, "READEXTENSTATUS", "ERROR");
00145       return 0;
00146    }
00147 
00148    if (ast_strlen_zero(arglist.filename)) {
00149       arglist.filename = NULL;
00150    }
00151 
00152    if (ast_strlen_zero(arglist.context)) {
00153       arglist.context = ast_strdupa(ast_channel_context(chan));
00154    }
00155 
00156    if (!ast_strlen_zero(arglist.options)) {
00157       ast_app_parse_options(readexten_app_options, &flags, NULL, arglist.options);
00158    }
00159 
00160    if (!ast_strlen_zero(arglist.timeout)) {
00161       timeout = atoi(arglist.timeout);
00162       if (timeout > 0)
00163          timeout *= 1000;
00164    }
00165 
00166    if (timeout <= 0)
00167       timeout = ast_channel_pbx(chan) ? ast_channel_pbx(chan)->rtimeoutms : 10000;
00168 
00169    if (digit_timeout <= 0)
00170       digit_timeout = ast_channel_pbx(chan) ? ast_channel_pbx(chan)->dtimeoutms : 5000;
00171 
00172    if (ast_test_flag(&flags, OPT_INDICATION) && !ast_strlen_zero(arglist.filename)) {
00173       ts = ast_get_indication_tone(ast_channel_zone(chan), arglist.filename);
00174    }
00175 
00176    do {
00177       if (ast_channel_state(chan) != AST_STATE_UP) {
00178          if (ast_test_flag(&flags, OPT_SKIP)) {
00179             /* At the user's option, skip if the line is not up */
00180             pbx_builtin_setvar_helper(chan, arglist.variable, "");
00181             status = "SKIP";
00182             break;
00183          } else if (!ast_test_flag(&flags, OPT_NOANSWER)) {
00184             /* Otherwise answer unless we're supposed to read while on-hook */
00185             res = ast_answer(chan);
00186          }
00187       }
00188 
00189       if (res < 0) {
00190          status = "HANGUP";
00191          break;
00192       }
00193 
00194       ast_playtones_stop(chan);
00195       ast_stopstream(chan);
00196 
00197       if (ts && ts->data[0]) {
00198          res = ast_playtones_start(chan, 0, ts->data, 0);
00199       } else if (arglist.filename) {
00200          if (ast_test_flag(&flags, OPT_INDICATION) && ast_fileexists(arglist.filename, NULL, ast_channel_language(chan)) <= 0) {
00201             /*
00202              * We were asked to play an indication that did not exist in the config.
00203              * If no such file exists, play it as a tonelist.  With any luck they won't
00204              * have a file named "350+440.ulaw"
00205              * (but honestly, who would do something so silly?)
00206              */
00207             res = ast_playtones_start(chan, 0, arglist.filename, 0);
00208          } else {
00209             res = ast_streamfile(chan, arglist.filename, ast_channel_language(chan));
00210          }
00211       }
00212 
00213       for (x = 0; x < maxdigits; x++) {
00214          ast_debug(3, "extension so far: '%s', timeout: %d\n", exten, timeout);
00215          res = ast_waitfordigit(chan, timeout);
00216 
00217          ast_playtones_stop(chan);
00218          ast_stopstream(chan);
00219          timeout = digit_timeout;
00220 
00221          if (res < 1) {    /* timeout expired or hangup */
00222             if (ast_check_hangup(chan)) {
00223                status = "HANGUP";
00224             } else if (x == 0) {
00225                pbx_builtin_setvar_helper(chan, arglist.variable, "t");
00226                status = "TIMEOUT";
00227             }
00228             break;
00229          }
00230 
00231          exten[x] = res;
00232          if (!ast_matchmore_extension(chan, arglist.context, exten, 1 /* priority */,
00233             S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))) {
00234             if (!ast_exists_extension(chan, arglist.context, exten, 1,
00235                S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))
00236                && res == '#') {
00237                exten[x] = '\0';
00238             }
00239             break;
00240          }
00241       }
00242 
00243       if (!ast_strlen_zero(status))
00244          break;
00245 
00246       if (ast_exists_extension(chan, arglist.context, exten, 1,
00247          S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))) {
00248          ast_debug(3, "User entered valid extension '%s'\n", exten);
00249          pbx_builtin_setvar_helper(chan, arglist.variable, exten);
00250          status = "OK";
00251       } else {
00252          ast_debug(3, "User dialed invalid extension '%s' in context '%s' on %s\n", exten, arglist.context, ast_channel_name(chan));
00253          pbx_builtin_setvar_helper(chan, arglist.variable, "i");
00254          pbx_builtin_setvar_helper(chan, "INVALID_EXTEN", exten);
00255          status = "INVALID";
00256       }
00257    } while (0);
00258 
00259    if (ts) {
00260       ts = ast_tone_zone_sound_unref(ts);
00261    }
00262 
00263    pbx_builtin_setvar_helper(chan, "READEXTENSTATUS", status);
00264 
00265    return status[0] == 'H' ? -1 : 0;
00266 }

static int unload_module ( void   )  [static]

Definition at line 268 of file app_readexten.c.

References ast_unregister_application().

00269 {
00270    int res = ast_unregister_application(app);
00271    return res;
00272 }


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 = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, .support_level = AST_MODULE_SUPPORT_CORE, } [static]

Definition at line 280 of file app_readexten.c.

char* app = "ReadExten" [static]

Definition at line 113 of file app_readexten.c.

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

Referenced by readexten_exec().


Generated on Thu Apr 16 06:28:41 2015 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6