Fri Aug 17 00:17:23 2018

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 int acf_isexten_exec (struct ast_channel *chan, const char *cmd, char *parse, char *buffer, size_t buflen)
 AST_APP_OPTIONS (readexten_app_options,{AST_APP_OPTION('s', OPT_SKIP), AST_APP_OPTION('i', OPT_INDICATION), AST_APP_OPTION('n', OPT_NOANSWER),})
 AST_MODULE_INFO_STANDARD (ASTERISK_GPL_KEY,"Read and evaluate extension validity")
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_custom_function acf_isexten
static char * app = "ReadExten"

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 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 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    if (!chan) {
00293       ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
00294       return -1;
00295    }
00296 
00297    AST_STANDARD_APP_ARGS(args, parse);
00298 
00299    if (ast_strlen_zero(args.context))
00300       args.context = chan->context;
00301 
00302    if (ast_strlen_zero(args.extension)) {
00303       ast_log(LOG_WARNING, "Syntax: VALID_EXTEN([<context>],<extension>[,<priority>]) - missing argument <extension>!\n");
00304       return -1;
00305    }
00306 
00307    if (ast_strlen_zero(args.priority))
00308       priority_int = 1;
00309    else
00310       priority_int = atoi(args.priority);
00311 
00312    if (ast_exists_extension(chan, args.context, args.extension, priority_int,
00313       S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
00314        ast_copy_string(buffer, "1", buflen);
00315    } else {
00316        ast_copy_string(buffer, "0", buflen);
00317    }
00318 
00319    return 0;
00320 }

AST_APP_OPTIONS ( readexten_app_options   ) 
AST_MODULE_INFO_STANDARD ( ASTERISK_GPL_KEY  ,
"Read and evaluate extension validity"   
)
static int load_module ( void   )  [static]

Definition at line 335 of file app_readexten.c.

References ast_custom_function_register, ast_register_application_xml, and readexten_exec().

00336 {
00337    int res = ast_register_application_xml(app, readexten_exec);
00338    res |= ast_custom_function_register(&acf_isexten);
00339    return res;
00340 }

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_party_caller::id, LOG_WARNING, ast_party_id::number, OPT_INDICATION, OPT_NOANSWER, OPT_SKIP, ast_channel::pbx, pbx_builtin_setvar_helper(), 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 327 of file app_readexten.c.

References ast_custom_function_unregister(), and ast_unregister_application().

00328 {
00329    int res = ast_unregister_application(app);
00330    res |= ast_custom_function_unregister(&acf_isexten);
00331 
00332    return res; 
00333 }


Variable Documentation

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

Definition at line 322 of file app_readexten.c.

char* app = "ReadExten" [static]

Definition at line 131 of file app_readexten.c.


Generated on 17 Aug 2018 for Asterisk - The Open Source Telephony Project by  doxygen 1.6.1