Asterisk - The Open Source Telephony Project GIT-master-8f1982c
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros Modules Pages
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 106 of file app_readexten.c.

106 {
107 OPT_SKIP = (1 << 0),
108 OPT_INDICATION = (1 << 1),
109 OPT_NOANSWER = (1 << 2),
110 OPT_POUND_TO_END = (1 << 3),
111};
@ OPT_NOANSWER
@ OPT_INDICATION
@ OPT_SKIP
@ OPT_POUND_TO_END

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 291 of file app_readexten.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 291 of file app_readexten.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 291 of file app_readexten.c.

◆ load_module()

static int load_module ( void  )
static

Definition at line 285 of file app_readexten.c.

286{
288 return res;
289}
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:640

References app, ast_register_application_xml, and readexten_exec().

◆ readexten_exec()

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

Definition at line 122 of file app_readexten.c.

123{
124 int res = 0;
125 char exten[256] = "";
126 int maxdigits = sizeof(exten) - 1;
127 int timeout = 0, digit_timeout = 0, x = 0;
128 char *argcopy = NULL, *status = "";
129 struct ast_tone_zone_sound *ts = NULL;
130 struct ast_flags flags = {0};
131
132 AST_DECLARE_APP_ARGS(arglist,
133 AST_APP_ARG(variable);
134 AST_APP_ARG(filename);
137 AST_APP_ARG(timeout);
138 );
139
140 if (ast_strlen_zero(data)) {
141 ast_log(LOG_WARNING, "ReadExten requires at least one argument\n");
142 pbx_builtin_setvar_helper(chan, "READEXTENSTATUS", "ERROR");
143 return 0;
144 }
145
146 argcopy = ast_strdupa(data);
147 AST_STANDARD_APP_ARGS(arglist, argcopy);
148
149 if (ast_strlen_zero(arglist.variable)) {
150 ast_log(LOG_WARNING, "Usage: ReadExten(variable[,filename[,context[,options[,timeout]]]])\n");
151 pbx_builtin_setvar_helper(chan, "READEXTENSTATUS", "ERROR");
152 return 0;
153 }
154
155 if (ast_strlen_zero(arglist.filename)) {
156 arglist.filename = NULL;
157 }
158
159 if (ast_strlen_zero(arglist.context)) {
160 arglist.context = ast_strdupa(ast_channel_context(chan));
161 }
162
163 if (!ast_strlen_zero(arglist.options)) {
165 }
166
167 if (!ast_strlen_zero(arglist.timeout)) {
168 timeout = atoi(arglist.timeout);
169 if (timeout > 0)
170 timeout *= 1000;
171 }
172
173 if (timeout <= 0)
174 timeout = ast_channel_pbx(chan) ? ast_channel_pbx(chan)->rtimeoutms : 10000;
175
176 digit_timeout = ast_channel_pbx(chan) ? ast_channel_pbx(chan)->dtimeoutms : 5000;
177
178 if (ast_test_flag(&flags, OPT_INDICATION) && !ast_strlen_zero(arglist.filename)) {
179 ts = ast_get_indication_tone(ast_channel_zone(chan), arglist.filename);
180 }
181
182 do {
183 if (ast_channel_state(chan) != AST_STATE_UP) {
185 /* At the user's option, skip if the line is not up */
186 pbx_builtin_setvar_helper(chan, arglist.variable, "");
187 status = "SKIP";
188 break;
189 } else if (!ast_test_flag(&flags, OPT_NOANSWER)) {
190 /* Otherwise answer unless we're supposed to read while on-hook */
191 res = ast_answer(chan);
192 }
193 }
194
195 if (res < 0) {
196 status = "HANGUP";
197 break;
198 }
199
200 ast_playtones_stop(chan);
201 ast_stopstream(chan);
202
203 if (ts && ts->data[0]) {
204 res = ast_playtones_start(chan, 0, ts->data, 0);
205 } else if (arglist.filename) {
206 if (ast_test_flag(&flags, OPT_INDICATION) && ast_fileexists(arglist.filename, NULL, ast_channel_language(chan)) <= 0) {
207 /*
208 * We were asked to play an indication that did not exist in the config.
209 * If no such file exists, play it as a tonelist. With any luck they won't
210 * have a file named "350+440.ulaw"
211 * (but honestly, who would do something so silly?)
212 */
213 res = ast_playtones_start(chan, 0, arglist.filename, 0);
214 } else {
215 res = ast_streamfile(chan, arglist.filename, ast_channel_language(chan));
216 }
217 }
218
219 for (x = 0; x < maxdigits; x++) {
220 ast_debug(3, "extension so far: '%s', timeout: %d\n", exten, timeout);
221 res = ast_waitfordigit(chan, timeout);
222
223 ast_playtones_stop(chan);
224 ast_stopstream(chan);
225 timeout = digit_timeout;
226
227 if (res < 1) { /* timeout expired or hangup */
228 if (ast_check_hangup(chan)) {
229 status = "HANGUP";
230 } else if (x == 0) {
231 pbx_builtin_setvar_helper(chan, arglist.variable, "t");
232 status = "TIMEOUT";
233 }
234 break;
235 }
236
237 if (ast_test_flag(&flags, OPT_POUND_TO_END) && res == '#') {
238 exten[x] = 0;
239 break;
240 }
241
242 exten[x] = res;
243 if (!ast_matchmore_extension(chan, arglist.context, exten, 1 /* priority */,
244 S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))) {
245 if (!ast_exists_extension(chan, arglist.context, exten, 1,
246 S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))
247 && res == '#') {
248 exten[x] = '\0';
249 }
250 break;
251 }
252 }
253
255 break;
256
257 if (ast_exists_extension(chan, arglist.context, exten, 1,
258 S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))) {
259 ast_debug(3, "User entered valid extension '%s'\n", exten);
260 pbx_builtin_setvar_helper(chan, arglist.variable, exten);
261 status = "OK";
262 } else {
263 ast_debug(3, "User dialed invalid extension '%s' in context '%s' on %s\n", exten, arglist.context, ast_channel_name(chan));
264 pbx_builtin_setvar_helper(chan, arglist.variable, "i");
265 pbx_builtin_setvar_helper(chan, "INVALID_EXTEN", exten);
266 status = "INVALID";
267 }
268 } while (0);
269
270 if (ts) {
272 }
273
274 pbx_builtin_setvar_helper(chan, "READEXTENSTATUS", status);
275
276 return status[0] == 'H' ? -1 : 0;
277}
jack_status_t status
Definition: app_jack.c:149
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
int ast_waitfordigit(struct ast_channel *c, int ms)
Waits for a digit.
Definition: channel.c:3143
const char * ast_channel_name(const struct ast_channel *chan)
const char * ast_channel_context(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:444
struct ast_tone_zone * ast_channel_zone(const struct ast_channel *chan)
const char * ast_channel_language(const struct ast_channel *chan)
struct ast_pbx * ast_channel_pbx(const struct ast_channel *chan)
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
int ast_answer(struct ast_channel *chan)
Answer a channel.
Definition: channel.c:2774
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:1301
int ast_fileexists(const char *filename, const char *fmt, const char *preflang)
Checks for the existence of a given file.
Definition: file.c:1137
#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:3066
#define ast_debug(level,...)
Log a DEBUG message.
#define LOG_WARNING
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
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
void ast_playtones_stop(struct ast_channel *chan)
Stop playing tones on a channel.
Definition: indications.c:393
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:461
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:4190
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:4210
#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:217
int dtimeoutms
Definition: pbx.h:216
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:157
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(), voicemailpwcheck::context, ast_channel::context, ast_tone_zone_sound::data, ast_pbx::dtimeoutms, 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.

Referenced by load_module().

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 279 of file app_readexten.c.

280{
282 return res;
283}
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 291 of file app_readexten.c.

◆ app

char* app = "ReadExten"
static

Definition at line 120 of file app_readexten.c.

Referenced by load_module(), and unload_module().

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

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

Referenced by readexten_exec().