Asterisk - The Open Source Telephony Project  GIT-master-a24979a
Enumerations | Functions | Variables
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) , OPT_POUND_TO_END = (1 << 3) }
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
struct ast_moduleAST_MODULE_SELF_SYM (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 const struct ast_module_infoast_module_info = &__mod_info
 
static const struct ast_app_option readexten_app_options [128] = { [ 's' ] = { .flag = OPT_SKIP }, [ 'i' ] = { .flag = OPT_INDICATION }, [ 'n' ] = { .flag = OPT_NOANSWER }, [ 'p' ] = { .flag = OPT_POUND_TO_END }, }
 

Detailed Description

Trivial application to read an extension into a variable.

Author
David Chappell David.nosp@m..Cha.nosp@m.ppell.nosp@m.@tri.nosp@m.ncoll.nosp@m..edu

Definition in file app_readexten.c.

Enumeration Type Documentation

◆ readexten_option_flags

Enumerator
OPT_SKIP 
OPT_INDICATION 
OPT_NOANSWER 
OPT_POUND_TO_END 

Definition at line 103 of file app_readexten.c.

103  {
104  OPT_SKIP = (1 << 0),
105  OPT_INDICATION = (1 << 1),
106  OPT_NOANSWER = (1 << 2),
107  OPT_POUND_TO_END = (1 << 3),
108 };
@ OPT_NOANSWER
@ OPT_INDICATION
@ OPT_SKIP
@ OPT_POUND_TO_END

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 288 of file app_readexten.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 288 of file app_readexten.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 288 of file app_readexten.c.

◆ load_module()

static int load_module ( void  )
static

Definition at line 282 of file app_readexten.c.

283 {
285  return res;
286 }
static char * app
static int readexten_exec(struct ast_channel *chan, const char *data)
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
Definition: module.h:626

◆ readexten_exec()

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

Definition at line 119 of file app_readexten.c.

120 {
121  int res = 0;
122  char exten[256] = "";
123  int maxdigits = sizeof(exten) - 1;
124  int timeout = 0, digit_timeout = 0, x = 0;
125  char *argcopy = NULL, *status = "";
126  struct ast_tone_zone_sound *ts = NULL;
127  struct ast_flags flags = {0};
128 
129  AST_DECLARE_APP_ARGS(arglist,
130  AST_APP_ARG(variable);
131  AST_APP_ARG(filename);
134  AST_APP_ARG(timeout);
135  );
136 
137  if (ast_strlen_zero(data)) {
138  ast_log(LOG_WARNING, "ReadExten requires at least one argument\n");
139  pbx_builtin_setvar_helper(chan, "READEXTENSTATUS", "ERROR");
140  return 0;
141  }
142 
143  argcopy = ast_strdupa(data);
144  AST_STANDARD_APP_ARGS(arglist, argcopy);
145 
146  if (ast_strlen_zero(arglist.variable)) {
147  ast_log(LOG_WARNING, "Usage: ReadExten(variable[,filename[,context[,options[,timeout]]]])\n");
148  pbx_builtin_setvar_helper(chan, "READEXTENSTATUS", "ERROR");
149  return 0;
150  }
151 
152  if (ast_strlen_zero(arglist.filename)) {
153  arglist.filename = NULL;
154  }
155 
156  if (ast_strlen_zero(arglist.context)) {
157  arglist.context = ast_strdupa(ast_channel_context(chan));
158  }
159 
160  if (!ast_strlen_zero(arglist.options)) {
162  }
163 
164  if (!ast_strlen_zero(arglist.timeout)) {
165  timeout = atoi(arglist.timeout);
166  if (timeout > 0)
167  timeout *= 1000;
168  }
169 
170  if (timeout <= 0)
171  timeout = ast_channel_pbx(chan) ? ast_channel_pbx(chan)->rtimeoutms : 10000;
172 
173  digit_timeout = ast_channel_pbx(chan) ? ast_channel_pbx(chan)->dtimeoutms : 5000;
174 
175  if (ast_test_flag(&flags, OPT_INDICATION) && !ast_strlen_zero(arglist.filename)) {
176  ts = ast_get_indication_tone(ast_channel_zone(chan), arglist.filename);
177  }
178 
179  do {
180  if (ast_channel_state(chan) != AST_STATE_UP) {
181  if (ast_test_flag(&flags, OPT_SKIP)) {
182  /* At the user's option, skip if the line is not up */
183  pbx_builtin_setvar_helper(chan, arglist.variable, "");
184  status = "SKIP";
185  break;
186  } else if (!ast_test_flag(&flags, OPT_NOANSWER)) {
187  /* Otherwise answer unless we're supposed to read while on-hook */
188  res = ast_answer(chan);
189  }
190  }
191 
192  if (res < 0) {
193  status = "HANGUP";
194  break;
195  }
196 
197  ast_playtones_stop(chan);
198  ast_stopstream(chan);
199 
200  if (ts && ts->data[0]) {
201  res = ast_playtones_start(chan, 0, ts->data, 0);
202  } else if (arglist.filename) {
203  if (ast_test_flag(&flags, OPT_INDICATION) && ast_fileexists(arglist.filename, NULL, ast_channel_language(chan)) <= 0) {
204  /*
205  * We were asked to play an indication that did not exist in the config.
206  * If no such file exists, play it as a tonelist. With any luck they won't
207  * have a file named "350+440.ulaw"
208  * (but honestly, who would do something so silly?)
209  */
210  res = ast_playtones_start(chan, 0, arglist.filename, 0);
211  } else {
212  res = ast_streamfile(chan, arglist.filename, ast_channel_language(chan));
213  }
214  }
215 
216  for (x = 0; x < maxdigits; x++) {
217  ast_debug(3, "extension so far: '%s', timeout: %d\n", exten, timeout);
218  res = ast_waitfordigit(chan, timeout);
219 
220  ast_playtones_stop(chan);
221  ast_stopstream(chan);
222  timeout = digit_timeout;
223 
224  if (res < 1) { /* timeout expired or hangup */
225  if (ast_check_hangup(chan)) {
226  status = "HANGUP";
227  } else if (x == 0) {
228  pbx_builtin_setvar_helper(chan, arglist.variable, "t");
229  status = "TIMEOUT";
230  }
231  break;
232  }
233 
234  if (ast_test_flag(&flags, OPT_POUND_TO_END) && res == '#') {
235  exten[x] = 0;
236  break;
237  }
238 
239  exten[x] = res;
240  if (!ast_matchmore_extension(chan, arglist.context, exten, 1 /* priority */,
241  S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))) {
242  if (!ast_exists_extension(chan, arglist.context, exten, 1,
243  S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))
244  && res == '#') {
245  exten[x] = '\0';
246  }
247  break;
248  }
249  }
250 
251  if (!ast_strlen_zero(status))
252  break;
253 
254  if (ast_exists_extension(chan, arglist.context, exten, 1,
255  S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))) {
256  ast_debug(3, "User entered valid extension '%s'\n", exten);
257  pbx_builtin_setvar_helper(chan, arglist.variable, exten);
258  status = "OK";
259  } else {
260  ast_debug(3, "User dialed invalid extension '%s' in context '%s' on %s\n", exten, arglist.context, ast_channel_name(chan));
261  pbx_builtin_setvar_helper(chan, arglist.variable, "i");
262  pbx_builtin_setvar_helper(chan, "INVALID_EXTEN", exten);
263  status = "INVALID";
264  }
265  } while (0);
266 
267  if (ts) {
268  ts = ast_tone_zone_sound_unref(ts);
269  }
270 
271  pbx_builtin_setvar_helper(chan, "READEXTENSTATUS", status);
272 
273  return status[0] == 'H' ? -1 : 0;
274 }
jack_status_t status
Definition: app_jack.c:146
static const struct ast_app_option readexten_app_options[128]
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
#define ast_log
Definition: astobj2.c:42
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:122
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:120
int ast_waitfordigit(struct ast_channel *c, int ms)
Waits for a digit.
Definition: channel.c:3176
struct ast_pbx * ast_channel_pbx(const struct ast_channel *chan)
const char * ast_channel_context(const struct ast_channel *chan)
struct ast_tone_zone * ast_channel_zone(const struct ast_channel *chan)
const char * ast_channel_name(const struct ast_channel *chan)
const char * ast_channel_language(const struct ast_channel *chan)
int ast_check_hangup(struct ast_channel *chan)
Check to see if a channel is needing hang up.
Definition: channel.c:445
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
int ast_answer(struct ast_channel *chan)
Answer a channel.
Definition: channel.c:2806
ast_channel_state
ast_channel states
Definition: channelstate.h:35
@ AST_STATE_UP
Definition: channelstate.h:42
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:222
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1291
int ast_fileexists(const char *filename, const char *fmt, const char *preflang)
Checks for the existence of a given file.
Definition: file.c:1127
#define AST_APP_ARG(name)
Define an application argument.
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the 'standard' argument separation process for an application.
int ast_app_parse_options(const struct ast_app_option *options, struct ast_flags *flags, char **args, char *optstr)
Parses a string containing application options and sets flags/arguments.
Definition: main/app.c:3126
#define ast_debug(level,...)
Log a DEBUG message.
#define LOG_WARNING
struct ast_tone_zone_sound * ast_get_indication_tone(const struct ast_tone_zone *zone, const char *indication)
Locate a tone zone sound.
Definition: indications.c:455
int ast_playtones_start(struct ast_channel *chan, int vol, const char *tonelist, int interruptible)
Start playing a list of tones on a channel.
Definition: indications.c:302
static struct ast_tone_zone_sound * ast_tone_zone_sound_unref(struct ast_tone_zone_sound *ts)
Release a reference to an ast_tone_zone_sound.
Definition: indications.h:227
void ast_playtones_stop(struct ast_channel *chan)
Stop playing tones on a channel.
Definition: indications.c:393
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
Definition: pbx.c:4182
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name.
int ast_matchmore_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Looks to see if adding anything to this extension might match something. (exists ^ canmatch)
Definition: pbx.c:4202
#define NULL
Definition: resample.c:96
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:87
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
Structure used to handle boolean flags.
Definition: utils.h:199
unsigned int flags
Definition: utils.h:200
int rtimeoutms
Definition: pbx.h:216
int dtimeoutms
Definition: pbx.h:215
Description of a tone.
Definition: indications.h:35
const char * data
Description of a tone.
Definition: indications.h:52
Number structure.
Definition: app_followme.c:154
static struct test_options options
#define ast_test_flag(p, flag)
Definition: utils.h:63

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(), context, ast_channel::context, ast_tone_zone_sound::data, ast_pbx::dtimeoutms, exten, ast_flags::flags, LOG_WARNING, NULL, OPT_INDICATION, OPT_NOANSWER, OPT_POUND_TO_END, OPT_SKIP, options, pbx_builtin_setvar_helper(), readexten_app_options, ast_pbx::rtimeoutms, S_COR, and status.

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 276 of file app_readexten.c.

277 {
278  int res = ast_unregister_application(app);
279  return res;
280 }
int ast_unregister_application(const char *app)
Unregister an application.
Definition: pbx_app.c:392

References app, and ast_unregister_application().

Variable Documentation

◆ __mod_info

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 282 of file app_readexten.c.

◆ app

char* app = "ReadExten"
static

Definition at line 117 of file app_readexten.c.

Referenced by unload_module().

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 288 of file app_readexten.c.

◆ readexten_app_options

const struct ast_app_option readexten_app_options[128] = { [ 's' ] = { .flag = OPT_SKIP }, [ 'i' ] = { .flag = OPT_INDICATION }, [ 'n' ] = { .flag = OPT_NOANSWER }, [ 'p' ] = { .flag = OPT_POUND_TO_END }, }
static

Definition at line 1 of file app_readexten.c.

Referenced by readexten_exec().