Wed Jan 8 2020 09:49:55

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 = "ac1f6a56484a8820659555499174e588" , .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.nosp@m..Cha.nosp@m.ppell.nosp@m.@tri.nosp@m.ncoll.nosp@m..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.

119  {
120  OPT_SKIP = (1 << 0),
121  OPT_INDICATION = (1 << 1),
122  OPT_NOANSWER = (1 << 2),
123 };

Function Documentation

static void __reg_module ( void  )
static

Definition at line 342 of file app_readexten.c.

static void __unreg_module ( void  )
static

Definition at line 342 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, context, ast_channel::context, ast_party_caller::id, LOG_WARNING, ast_party_id::number, S_COR, ast_party_number::str, and ast_party_number::valid.

284 {
285  int priority_int;
289  AST_APP_ARG(priority);
290  );
291 
292  if (!chan) {
293  ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
294  return -1;
295  }
296 
298 
299  if (ast_strlen_zero(args.context))
300  args.context = chan->context;
301 
302  if (ast_strlen_zero(args.extension)) {
303  ast_log(LOG_WARNING, "Syntax: VALID_EXTEN([<context>],<extension>[,<priority>]) - missing argument <extension>!\n");
304  return -1;
305  }
306 
307  if (ast_strlen_zero(args.priority))
308  priority_int = 1;
309  else
310  priority_int = atoi(args.priority);
311 
312  if (ast_exists_extension(chan, args.context, args.extension, priority_int,
313  S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
314  ast_copy_string(buffer, "1", buflen);
315  } else {
316  ast_copy_string(buffer, "0", buflen);
317  }
318 
319  return 0;
320 }
char * str
Subscriber phone number (Malloced)
Definition: channel.h:241
struct ast_party_caller caller
Channel Caller ID information.
Definition: channel.h:804
char context[AST_MAX_CONTEXT]
Definition: channel.h:868
#define LOG_WARNING
Definition: logger.h:144
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
Definition: app.h:572
struct ast_party_id id
Caller party ID.
Definition: channel.h:370
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#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:83
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:5400
static struct @350 args
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1858
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
#define AST_APP_ARG(name)
Define an application argument.
Definition: app.h:555
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
Definition: app.h:604
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:247
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:292
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().

336 {
339  return res;
340 }
static int readexten_exec(struct ast_channel *chan, const char *data)
static char * app
static struct ast_custom_function acf_isexten
#define ast_custom_function_register(acf)
Register a custom function.
Definition: pbx.h:1164
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
Definition: module.h:437
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, context, ast_channel::context, ast_tone_zone_sound::data, ast_pbx::dtimeoutms, exten, 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().

134 {
135  int res = 0;
136  char exten[256] = "";
137  int maxdigits = sizeof(exten) - 1;
138  int timeout = 0, digit_timeout = 0, x = 0;
139  char *argcopy = NULL, *status = "";
140  struct ast_tone_zone_sound *ts = NULL;
141  struct ast_flags flags = {0};
142 
143  AST_DECLARE_APP_ARGS(arglist,
144  AST_APP_ARG(variable);
145  AST_APP_ARG(filename);
147  AST_APP_ARG(options);
148  AST_APP_ARG(timeout);
149  );
150 
151  if (ast_strlen_zero(data)) {
152  ast_log(LOG_WARNING, "ReadExten requires at least one argument\n");
153  pbx_builtin_setvar_helper(chan, "READEXTENSTATUS", "ERROR");
154  return 0;
155  }
156 
157  argcopy = ast_strdupa(data);
158  AST_STANDARD_APP_ARGS(arglist, argcopy);
159 
160  if (ast_strlen_zero(arglist.variable)) {
161  ast_log(LOG_WARNING, "Usage: ReadExten(variable[,filename[,context[,options[,timeout]]]])\n");
162  pbx_builtin_setvar_helper(chan, "READEXTENSTATUS", "ERROR");
163  return 0;
164  }
165 
166  if (ast_strlen_zero(arglist.filename))
167  arglist.filename = NULL;
168 
169  if (ast_strlen_zero(arglist.context))
170  arglist.context = chan->context;
171 
172  if (!ast_strlen_zero(arglist.options))
173  ast_app_parse_options(readexten_app_options, &flags, NULL, arglist.options);
174 
175  if (!ast_strlen_zero(arglist.timeout)) {
176  timeout = atoi(arglist.timeout);
177  if (timeout > 0)
178  timeout *= 1000;
179  }
180 
181  if (timeout <= 0)
182  timeout = chan->pbx ? chan->pbx->rtimeoutms : 10000;
183 
184  if (digit_timeout <= 0)
185  digit_timeout = chan->pbx ? chan->pbx->dtimeoutms : 5000;
186 
187  if (ast_test_flag(&flags, OPT_INDICATION) && !ast_strlen_zero(arglist.filename)) {
188  ts = ast_get_indication_tone(chan->zone, arglist.filename);
189  }
190 
191  do {
192  if (chan->_state != AST_STATE_UP) {
193  if (ast_test_flag(&flags, OPT_SKIP)) {
194  /* At the user's option, skip if the line is not up */
195  pbx_builtin_setvar_helper(chan, arglist.variable, "");
196  status = "SKIP";
197  break;
198  } else if (!ast_test_flag(&flags, OPT_NOANSWER)) {
199  /* Otherwise answer unless we're supposed to read while on-hook */
200  res = ast_answer(chan);
201  }
202  }
203 
204  if (res < 0) {
205  status = "HANGUP";
206  break;
207  }
208 
209  ast_playtones_stop(chan);
210  ast_stopstream(chan);
211 
212  if (ts && ts->data[0]) {
213  res = ast_playtones_start(chan, 0, ts->data, 0);
214  } else if (arglist.filename) {
215  if (ast_test_flag(&flags, OPT_INDICATION) && ast_fileexists(arglist.filename, NULL, chan->language) <= 0) {
216  /*
217  * We were asked to play an indication that did not exist in the config.
218  * If no such file exists, play it as a tonelist. With any luck they won't
219  * have a file named "350+440.ulaw"
220  * (but honestly, who would do something so silly?)
221  */
222  res = ast_playtones_start(chan, 0, arglist.filename, 0);
223  } else {
224  res = ast_streamfile(chan, arglist.filename, chan->language);
225  }
226  }
227 
228  for (x = 0; x < maxdigits; x++) {
229  ast_debug(3, "extension so far: '%s', timeout: %d\n", exten, timeout);
230  res = ast_waitfordigit(chan, timeout);
231 
232  ast_playtones_stop(chan);
233  ast_stopstream(chan);
234  timeout = digit_timeout;
235 
236  if (res < 1) { /* timeout expired or hangup */
237  if (ast_check_hangup(chan)) {
238  status = "HANGUP";
239  } else if (x == 0) {
240  pbx_builtin_setvar_helper(chan, arglist.variable, "t");
241  status = "TIMEOUT";
242  }
243  break;
244  }
245 
246  exten[x] = res;
247  if (!ast_matchmore_extension(chan, arglist.context, exten, 1 /* priority */,
248  S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
249  if (!ast_exists_extension(chan, arglist.context, exten, 1,
250  S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))
251  && res == '#') {
252  exten[x] = '\0';
253  }
254  break;
255  }
256  }
257 
258  if (!ast_strlen_zero(status))
259  break;
260 
261  if (ast_exists_extension(chan, arglist.context, exten, 1,
262  S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
263  ast_debug(3, "User entered valid extension '%s'\n", exten);
264  pbx_builtin_setvar_helper(chan, arglist.variable, exten);
265  status = "OK";
266  } else {
267  ast_debug(3, "User dialed invalid extension '%s' in context '%s' on %s\n", exten, arglist.context, chan->name);
268  pbx_builtin_setvar_helper(chan, arglist.variable, "i");
269  pbx_builtin_setvar_helper(chan, "INVALID_EXTEN", exten);
270  status = "INVALID";
271  }
272  } while (0);
273 
274  if (ts) {
275  ts = ast_tone_zone_sound_unref(ts);
276  }
277 
278  pbx_builtin_setvar_helper(chan, "READEXTENSTATUS", status);
279 
280  return status[0] == 'H' ? -1 : 0;
281 }
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:5420
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:109
char * str
Subscriber phone number (Malloced)
Definition: channel.h:241
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:946
struct ast_party_caller caller
Channel Caller ID information.
Definition: channel.h:804
struct ast_tone_zone * zone
Definition: channel.h:767
#define ast_test_flag(p, flag)
Definition: utils.h:63
char context[AST_MAX_CONTEXT]
Definition: channel.h:868
#define LOG_WARNING
Definition: logger.h:144
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: app.c:2101
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
Definition: app.h:572
unsigned int flags
Definition: utils.h:201
void ast_playtones_stop(struct ast_channel *chan)
Stop playing tones on a channel.
Definition: indications.c:411
struct ast_party_id id
Caller party ID.
Definition: channel.h:370
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#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:83
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:226
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:5400
int ast_check_hangup(struct ast_channel *chan)
Check to see if a channel is needing hang up.
Definition: channel.c:806
static struct ast_app_option readexten_app_options[128]
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
enum ast_channel_state _state
Definition: channel.h:839
Description of a tone.
Definition: indications.h:36
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:473
const ast_string_field name
Definition: channel.h:787
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
Structure used to handle boolean flags.
Definition: utils.h:200
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...
Definition: pbx.c:10546
int ast_waitfordigit(struct ast_channel *c, int ms)
Waits for a digit.
Definition: channel.c:3552
int dtimeoutms
Definition: pbx.h:180
int ast_fileexists(const char *filename, const char *fmt, const char *preflang)
Checks for the existence of a given file.
Definition: file.c:919
int ast_answer(struct ast_channel *chan)
Answer a channel.
Definition: channel.c:3086
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:319
const char * data
Description of a tone.
Definition: indications.h:53
#define AST_APP_ARG(name)
Define an application argument.
Definition: app.h:555
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
Definition: app.h:604
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:247
const ast_string_field language
Definition: channel.h:787
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:128
jack_status_t status
Definition: app_jack.c:143
struct ast_pbx * pbx
Definition: channel.h:761
int rtimeoutms
Definition: pbx.h:181
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:292
static int unload_module ( void  )
static

Definition at line 327 of file app_readexten.c.

References ast_custom_function_unregister(), and ast_unregister_application().

328 {
329  int res = ast_unregister_application(app);
331 
332  return res;
333 }
int ast_unregister_application(const char *app)
Unregister an application.
Definition: pbx.c:7705
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
Definition: pbx.c:3814
static char * app
static struct ast_custom_function acf_isexten

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

Definition at line 342 of file app_readexten.c.

struct ast_custom_function acf_isexten
static
Initial value:
= {
.name = "VALID_EXTEN",
}
static int acf_isexten_exec(struct ast_channel *chan, const char *cmd, char *parse, char *buffer, size_t buflen)

Definition at line 322 of file app_readexten.c.

char* app = "ReadExten"
static

Definition at line 131 of file app_readexten.c.

Definition at line 342 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().