Thu Apr 28 2011 17:13:38

Asterisk developer's documentation


app_read.c File Reference

Trivial application to read a variable. More...

#include "asterisk.h"
#include "asterisk/file.h"
#include "asterisk/pbx.h"
#include "asterisk/channel.h"
#include "asterisk/app.h"
#include "asterisk/module.h"
#include "asterisk/indications.h"
Include dependency graph for app_read.c:

Go to the source code of this file.

Defines

#define ast_next_data(instr, ptr, delim)   if((ptr=strchr(instr,delim))) { *(ptr) = '\0' ; ptr++;}

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 load_module (void)
static int read_exec (struct ast_channel *chan, void *data)
static int unload_module (void)

Variables

static struct ast_module_info
__MODULE_INFO_SECTION 
__mod_info = { __MODULE_INFO_GLOBALS .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Read Variable Application" , .key = ASTERISK_GPL_KEY , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, }
static char * app = "Read"
static struct ast_module_infoast_module_info = &__mod_info
static struct ast_app_option read_app_options [128] = { [ 's' ] = { .flag = OPT_SKIP }, [ 'i' ] = { .flag = OPT_INDICATION }, [ 'n' ] = { .flag = OPT_NOANSWER },}
enum { ... }  read_option_flags

Detailed Description

Trivial application to read a variable.

Author:
Mark Spencer <markster@digium.com>

Definition in file app_read.c.


Define Documentation

#define ast_next_data (   instr,
  ptr,
  delim 
)    if((ptr=strchr(instr,delim))) { *(ptr) = '\0' ; ptr++;}

Definition at line 125 of file app_read.c.


Enumeration Type Documentation

anonymous enum
Enumerator:
OPT_SKIP 
OPT_INDICATION 
OPT_NOANSWER 

Definition at line 111 of file app_read.c.

     {
   OPT_SKIP = (1 << 0),
   OPT_INDICATION = (1 << 1),
   OPT_NOANSWER = (1 << 2),
} read_option_flags;

Function Documentation

static void __reg_module ( void  ) [static]

Definition at line 281 of file app_read.c.

static void __unreg_module ( void  ) [static]

Definition at line 281 of file app_read.c.

static int load_module ( void  ) [static]

Definition at line 276 of file app_read.c.

References ast_register_application_xml, and read_exec().

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

Definition at line 127 of file app_read.c.

References ast_channel::_state, ast_answer(), AST_APP_ARG, ast_app_getdata(), ast_app_parse_options(), ast_check_hangup(), AST_DECLARE_APP_ARGS, ast_get_indication_tone(), AST_GETDATA_COMPLETE, AST_GETDATA_EMPTY_END_TERMINATED, AST_GETDATA_INTERRUPTED, AST_GETDATA_TIMEOUT, ast_log(), ast_playtones_start(), ast_playtones_stop(), AST_STANDARD_APP_ARGS, AST_STATE_UP, ast_stopstream(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_tone_zone_sound_unref(), ast_verb, ast_waitfordigit(), ast_tone_zone_sound::data, LOG_WARNING, OPT_INDICATION, OPT_NOANSWER, OPT_SKIP, ast_channel::pbx, pbx_builtin_setvar_helper(), read_app_options, ast_pbx::rtimeoutms, status, and ast_channel::zone.

Referenced by load_module().

{
   int res = 0;
   char tmp[256] = "";
   int maxdigits = 255;
   int tries = 1, to = 0, x = 0;
   double tosec;
   char *argcopy = NULL;
   struct ast_tone_zone_sound *ts = NULL;
   struct ast_flags flags = {0};
   const char *status = "ERROR";

   AST_DECLARE_APP_ARGS(arglist,
      AST_APP_ARG(variable);
      AST_APP_ARG(filename);
      AST_APP_ARG(maxdigits);
      AST_APP_ARG(options);
      AST_APP_ARG(attempts);
      AST_APP_ARG(timeout);
   );
   
   pbx_builtin_setvar_helper(chan, "READSTATUS", status);
   if (ast_strlen_zero(data)) {
      ast_log(LOG_WARNING, "Read requires an argument (variable)\n");
      return 0;
   }
   
   argcopy = ast_strdupa(data);

   AST_STANDARD_APP_ARGS(arglist, argcopy);

   if (!ast_strlen_zero(arglist.options)) {
      ast_app_parse_options(read_app_options, &flags, NULL, arglist.options);
   }
   
   if (!ast_strlen_zero(arglist.attempts)) {
      tries = atoi(arglist.attempts);
      if (tries <= 0)
         tries = 1;
   }

   if (!ast_strlen_zero(arglist.timeout)) {
      tosec = atof(arglist.timeout);
      if (tosec <= 0)
         to = 0;
      else
         to = tosec * 1000.0;
   }

   if (ast_strlen_zero(arglist.filename)) {
      arglist.filename = NULL;
   }
   if (!ast_strlen_zero(arglist.maxdigits)) {
      maxdigits = atoi(arglist.maxdigits);
      if ((maxdigits < 1) || (maxdigits > 255)) {
         maxdigits = 255;
      } else
         ast_verb(3, "Accepting a maximum of %d digits.\n", maxdigits);
   }
   if (ast_strlen_zero(arglist.variable)) {
      ast_log(LOG_WARNING, "Invalid! Usage: Read(variable[,filename][,maxdigits][,option][,attempts][,timeout])\n\n");
      return 0;
   }
   if (ast_test_flag(&flags, OPT_INDICATION)) {
      if (!ast_strlen_zero(arglist.filename)) {
         ts = ast_get_indication_tone(chan->zone, arglist.filename);
      }
   }
   if (chan->_state != AST_STATE_UP) {
      if (ast_test_flag(&flags, OPT_SKIP)) {
         /* At the user's option, skip if the line is not up */
         pbx_builtin_setvar_helper(chan, arglist.variable, "");
         pbx_builtin_setvar_helper(chan, "READSTATUS", "SKIPPED");
         return 0;
      } else if (!ast_test_flag(&flags, OPT_NOANSWER)) {
         /* Otherwise answer unless we're supposed to read while on-hook */
         res = ast_answer(chan);
      }
   }
   if (!res) {
      while (tries && !res) {
         ast_stopstream(chan);
         if (ts && ts->data[0]) {
            if (!to)
               to = chan->pbx ? chan->pbx->rtimeoutms : 6000;
            res = ast_playtones_start(chan, 0, ts->data, 0);
            for (x = 0; x < maxdigits; ) {
               res = ast_waitfordigit(chan, to);
               ast_playtones_stop(chan);
               if (res < 1) {
                  if (res == 0)
                     status = "TIMEOUT";
                  tmp[x]='\0';
                  break;
               }
               tmp[x++] = res;
               if (tmp[x-1] == '#') {
                  tmp[x-1] = '\0';
                  status = "OK";
                  break;
               }
               if (x >= maxdigits) {
                  status = "OK";
               }
            }
         } else {
            res = ast_app_getdata(chan, arglist.filename, tmp, maxdigits, to);
            if (res == AST_GETDATA_COMPLETE || res == AST_GETDATA_EMPTY_END_TERMINATED)
               status = "OK";
            else if (res == AST_GETDATA_TIMEOUT)
               status = "TIMEOUT";
            else if (res == AST_GETDATA_INTERRUPTED)
               status = "INTERRUPTED";
         }
         if (res > -1) {
            pbx_builtin_setvar_helper(chan, arglist.variable, tmp);
            if (!ast_strlen_zero(tmp)) {
               ast_verb(3, "User entered '%s'\n", tmp);
               tries = 0;
            } else {
               tries--;
               if (tries)
                  ast_verb(3, "User entered nothing, %d chance%s left\n", tries, (tries != 1) ? "s" : "");
               else
                  ast_verb(3, "User entered nothing.\n");
            }
            res = 0;
         } else {
            pbx_builtin_setvar_helper(chan, arglist.variable, tmp);
            ast_verb(3, "User disconnected\n");
         }
      }
   }

   if (ts) {
      ts = ast_tone_zone_sound_unref(ts);
   }

   if (ast_check_hangup(chan))
      status = "HANGUP";
   pbx_builtin_setvar_helper(chan, "READSTATUS", status);
   return 0;
}
static int unload_module ( void  ) [static]

Definition at line 271 of file app_read.c.

References ast_unregister_application().


Variable Documentation

struct ast_module_info __MODULE_INFO_SECTION __mod_info = { __MODULE_INFO_GLOBALS .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Read Variable Application" , .key = ASTERISK_GPL_KEY , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, } [static]

Definition at line 281 of file app_read.c.

char* app = "Read" [static]

Definition at line 123 of file app_read.c.

Definition at line 281 of file app_read.c.

struct ast_app_option read_app_options[128] = { [ 's' ] = { .flag = OPT_SKIP }, [ 'i' ] = { .flag = OPT_INDICATION }, [ 'n' ] = { .flag = OPT_NOANSWER },} [static]

Definition at line 121 of file app_read.c.

Referenced by read_exec().

enum { ... } read_option_flags