Asterisk - The Open Source Telephony Project GIT-master-a358458
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

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 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) {
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
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) {
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
int ast_waitfordigit(struct ast_channel *c, int ms)
Waits for a digit.
Definition: channel.c:3175
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:445
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:2805
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:1293
int ast_fileexists(const char *filename, const char *fmt, const char *preflang)
Checks for the existence of a given file.
Definition: file.c:1129
#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:3056
#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:4175
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:4195
#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(), 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 276 of file app_readexten.c.

277{
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 288 of file app_readexten.c.

◆ app

char* app = "ReadExten"
static

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

Referenced by readexten_exec().