Asterisk - The Open Source Telephony Project GIT-master-2de1a68
Enumerations | Functions | Variables
app_disa.c File Reference

DISA – Direct Inward System Access Application. More...

#include "asterisk.h"
#include <math.h>
#include <sys/time.h>
#include "asterisk/lock.h"
#include "asterisk/file.h"
#include "asterisk/channel.h"
#include "asterisk/app.h"
#include "asterisk/indications.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/translate.h"
#include "asterisk/ulaw.h"
#include "asterisk/callerid.h"
#include "asterisk/stringfields.h"
Include dependency graph for app_disa.c:

Go to the source code of this file.

Enumerations

enum  { NOANSWER_FLAG = (1 << 0) , POUND_TO_END_FLAG = (1 << 1) }
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static int disa_exec (struct ast_channel *chan, const char *data)
 
static int load_module (void)
 
static void play_dialtone (struct ast_channel *chan, char *mailbox)
 
static int unload_module (void)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "DISA (Direct Inward System Access) Application" , .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 const char app [] = "DISA"
 
static const struct ast_app_option app_opts [128] = { [ 'n' ] = { .flag = NOANSWER_FLAG }, [ 'p' ] = { .flag = POUND_TO_END_FLAG }, }
 
static const struct ast_module_infoast_module_info = &__mod_info
 

Detailed Description

DISA – Direct Inward System Access Application.

Author
Jim Dixon jim@l.nosp@m.ambd.nosp@m.atel..nosp@m.com

Definition in file app_disa.c.

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
NOANSWER_FLAG 
POUND_TO_END_FLAG 

Definition at line 118 of file app_disa.c.

118 {
119 NOANSWER_FLAG = (1 << 0),
120 POUND_TO_END_FLAG = (1 << 1),
121};
@ NOANSWER_FLAG
Definition: app_disa.c:119
@ POUND_TO_END_FLAG
Definition: app_disa.c:120

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 419 of file app_disa.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 419 of file app_disa.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 419 of file app_disa.c.

◆ disa_exec()

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

Definition at line 146 of file app_disa.c.

147{
148 int i = 0, j, k = 0, did_ignore = 0, special_noanswer = 0;
149 int firstdigittimeout = (ast_channel_pbx(chan) ? ast_channel_pbx(chan)->rtimeoutms : 20000);
150 int digittimeout = (ast_channel_pbx(chan) ? ast_channel_pbx(chan)->dtimeoutms : 10000);
151 struct ast_flags flags;
152 char *tmp, exten[AST_MAX_EXTENSION] = "", acctcode[20]="";
153 char pwline[256];
154 char ourcidname[256],ourcidnum[256];
155 struct ast_frame *f;
156 struct timeval lastdigittime;
157 int res;
158 FILE *fp;
160 AST_APP_ARG(passcode);
162 AST_APP_ARG(cid);
165 );
166
167 if (ast_strlen_zero(data)) {
168 ast_log(LOG_WARNING, "DISA requires an argument (passcode/passcode file)\n");
169 return -1;
170 }
171
172 ast_debug(1, "Digittimeout: %d\n", digittimeout);
173 ast_debug(1, "Responsetimeout: %d\n", firstdigittimeout);
174
175 tmp = ast_strdupa(data);
176
178
179 if (ast_strlen_zero(args.context))
180 args.context = "disa";
181 if (ast_strlen_zero(args.mailbox))
182 args.mailbox = "";
183 if (!ast_strlen_zero(args.options)) {
184 ast_app_parse_options(app_opts, &flags, NULL, args.options);
185 } else {
186 /* Coverity - This uninit_use should be ignored since this macro initializes the flags */
188 }
189
190
191 ast_debug(1, "Mailbox: %s\n",args.mailbox);
192
193 if (!ast_test_flag(&flags, NOANSWER_FLAG)) {
194 if (ast_channel_state(chan) != AST_STATE_UP) {
195 /* answer */
196 ast_answer(chan);
197 }
198 } else special_noanswer = 1;
199
200 ast_debug(1, "Context: %s\n",args.context);
201
202 if (!strcasecmp(args.passcode, "no-password")) {
203 k |= 1; /* We have the password */
204 ast_debug(1, "DISA no-password login success\n");
205 }
206
207 lastdigittime = ast_tvnow();
208
209 play_dialtone(chan, args.mailbox);
210
212
213 for (;;) {
214 /* if outa time, give em reorder */
215 if (ast_tvdiff_ms(ast_tvnow(), lastdigittime) > ((k&2) ? digittimeout : firstdigittimeout)) {
216 ast_debug(1,"DISA %s entry timeout on chan %s\n",
217 ((k&1) ? "extension" : "password"),ast_channel_name(chan));
218 break;
219 }
220
221 if ((res = ast_waitfor(chan, -1)) < 0) {
222 ast_debug(1, "Waitfor returned %d\n", res);
223 continue;
224 }
225
226 if (!(f = ast_read(chan))) {
228 return -1;
229 }
230
232 if (f->data.uint32)
234 ast_frfree(f);
236 return -1;
237 }
238
239 /* If the frame coming in is not DTMF, just drop it and continue */
240 if (f->frametype != AST_FRAME_DTMF) {
241 ast_frfree(f);
242 continue;
243 }
244
245 j = f->subclass.integer; /* save digit */
246 ast_frfree(f);
247
248 if (!i) {
249 k |= 2; /* We have the first digit */
250 ast_playtones_stop(chan);
251 }
252
253 lastdigittime = ast_tvnow();
254
255 /* got a DTMF tone */
256 if (i < AST_MAX_EXTENSION) { /* if still valid number of digits */
257 if (!(k&1)) { /* if in password state */
258 if (j == '#') { /* end of password */
259 /* see if this is an integer */
260 if (sscanf(args.passcode,"%30d",&j) < 1) { /* nope, it must be a filename */
261 fp = fopen(args.passcode,"r");
262 if (!fp) {
263 ast_log(LOG_WARNING,"DISA password file %s not found on chan %s\n",args.passcode,ast_channel_name(chan));
265 return -1;
266 }
267 pwline[0] = 0;
268 while(fgets(pwline,sizeof(pwline) - 1,fp)) {
269 if (!pwline[0])
270 continue;
271 if (pwline[strlen(pwline) - 1] == '\n')
272 pwline[strlen(pwline) - 1] = 0;
273 if (!pwline[0])
274 continue;
275 /* skip comments */
276 if (pwline[0] == '#')
277 continue;
278 if (pwline[0] == ';')
279 continue;
280
282
283 ast_debug(1, "Mailbox: %s\n",args.mailbox);
284
285 /* password must be in valid format (numeric) */
286 if (sscanf(args.passcode,"%30d", &j) < 1)
287 continue;
288 /* if we got it */
289 if (!strcmp(exten,args.passcode)) {
290 if (ast_strlen_zero(args.context))
291 args.context = "disa";
292 if (ast_strlen_zero(args.mailbox))
293 args.mailbox = "";
294 break;
295 }
296 }
297 fclose(fp);
298 }
299 /* compare the two */
300 if (strcmp(exten,args.passcode)) {
301 ast_log(LOG_WARNING,"DISA on chan %s got bad password %s\n",ast_channel_name(chan),exten);
302 goto reorder;
303
304 }
305 /* password good, set to dial state */
306 ast_debug(1,"DISA on chan %s password is good\n",ast_channel_name(chan));
307 play_dialtone(chan, args.mailbox);
308
309 k|=1; /* In number mode */
310 i = 0; /* re-set buffer pointer */
311 exten[sizeof(acctcode)] = 0;
312 ast_copy_string(acctcode, exten, sizeof(acctcode));
313 exten[0] = 0;
314 ast_debug(1,"Successful DISA log-in on chan %s\n", ast_channel_name(chan));
315 continue;
316 }
317 } else {
318 if (j == '#') { /* end of extension .. maybe */
319 if (i == 0
320 && (ast_matchmore_extension(chan, args.context, "#", 1,
321 S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))
322 || ast_exists_extension(chan, args.context, "#", 1,
323 S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))) ) {
324 /* Let the # be the part of, or the entire extension */
325 } else {
326 break;
327 }
328 }
329 }
330
331 exten[i++] = j; /* save digit */
332 exten[i] = 0;
333 if (!(k&1))
334 continue; /* if getting password, continue doing it */
335 /* if this exists */
336
337 /* user wants end of number, remove # */
338 if (ast_test_flag(&flags, POUND_TO_END_FLAG) && j == '#') {
339 exten[--i] = 0;
340 break;
341 }
342
343 if (ast_ignore_pattern(args.context, exten)) {
344 play_dialtone(chan, "");
345 did_ignore = 1;
346 } else
347 if (did_ignore) {
348 ast_playtones_stop(chan);
349 did_ignore = 0;
350 }
351
352 /* if can do some more, do it */
353 if (!ast_matchmore_extension(chan, args.context, exten, 1,
354 S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))) {
355 break;
356 }
357 }
358 }
359
361
362 if (k == 3) {
363 int recheck = 0;
364
365 if (!ast_exists_extension(chan, args.context, exten, 1,
366 S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))) {
367 pbx_builtin_setvar_helper(chan, "INVALID_EXTEN", exten);
368 exten[0] = 'i';
369 exten[1] = '\0';
370 recheck = 1;
371 }
372 if (!recheck
373 || ast_exists_extension(chan, args.context, exten, 1,
374 S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))) {
375 ast_playtones_stop(chan);
376 /* We're authenticated and have a target extension */
377 if (!ast_strlen_zero(args.cid)) {
378 ast_callerid_split(args.cid, ourcidname, sizeof(ourcidname), ourcidnum, sizeof(ourcidnum));
379 ast_set_callerid(chan, ourcidnum, ourcidname, ourcidnum);
380 }
381
382 if (!ast_strlen_zero(acctcode)) {
383 ast_channel_lock(chan);
384 ast_channel_accountcode_set(chan, acctcode);
385 ast_channel_unlock(chan);
386 }
387
388 if (ast_pbx_exec_application(chan, "ResetCDR", special_noanswer ? "" : "e")) {
389 ast_log(AST_LOG_NOTICE, "ResetCDR application not found; CDR will not be reset\n");
390 }
391 ast_explicit_goto(chan, args.context, exten, 1);
392 return 0;
393 }
394 }
395
396 /* Received invalid, but no "i" extension exists in the given context */
397
398reorder:
399 /* Play congestion for a bit */
401 ast_safe_sleep(chan, 10*1000);
402
403 ast_playtones_stop(chan);
404
405 return -1;
406}
static const struct ast_app_option app_opts[128]
Definition: app_disa.c:126
static void play_dialtone(struct ast_channel *chan, char *mailbox)
Definition: app_disa.c: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 int tmp()
Definition: bt_open.c:389
int ast_callerid_split(const char *src, char *name, int namelen, char *num, int numlen)
Definition: callerid.c:1193
const char * ast_channel_name(const struct ast_channel *chan)
void ast_channel_clear_flag(struct ast_channel *chan, unsigned int flag)
Clear a flag on a channel.
Definition: channel.c:11033
#define ast_channel_lock(chan)
Definition: channel.h:2922
int ast_waitfor(struct ast_channel *chan, int ms)
Wait for input on a channel.
Definition: channel.c:3162
struct ast_frame * ast_read(struct ast_channel *chan)
Reads a frame.
Definition: channel.c:4256
void ast_set_callerid(struct ast_channel *chan, const char *cid_num, const char *cid_name, const char *cid_ani)
Set caller ID number, name and ANI and generate AMI event.
Definition: channel.c:7333
void ast_channel_set_flag(struct ast_channel *chan, unsigned int flag)
Set a flag on a channel.
Definition: channel.c:11026
@ AST_FLAG_END_DTMF_ONLY
Definition: channel.h:1007
struct ast_pbx * ast_channel_pbx(const struct ast_channel *chan)
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
void ast_channel_hangupcause_set(struct ast_channel *chan, int value)
int ast_answer(struct ast_channel *chan)
Answer a channel.
Definition: channel.c:2805
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
Definition: channel.c:4276
int ast_safe_sleep(struct ast_channel *chan, int ms)
Wait for a specified amount of time, looking for hangups.
Definition: channel.c:1574
#define ast_channel_unlock(chan)
Definition: channel.h:2923
#define AST_MAX_EXTENSION
Definition: channel.h:134
ast_channel_state
ast_channel states
Definition: channelstate.h:35
@ AST_STATE_UP
Definition: channelstate.h:42
#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_FRAME_DTMF
#define ast_frfree(fr)
@ AST_FRAME_CONTROL
@ AST_CONTROL_CONGESTION
@ AST_CONTROL_HANGUP
#define ast_debug(level,...)
Log a DEBUG message.
#define AST_LOG_NOTICE
#define LOG_WARNING
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: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_pbx_exec_application(struct ast_channel *chan, const char *app_name, const char *app_args)
Execute an application.
Definition: pbx_app.c:501
int ast_explicit_goto(struct ast_channel *chan, const char *context, const char *exten, int priority)
Definition: pbx.c:6945
int ast_ignore_pattern(const char *context, const char *pattern)
Checks to see if a number should be ignored.
Definition: pbx.c:6879
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
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
Structure used to handle boolean flags.
Definition: utils.h:199
unsigned int flags
Definition: utils.h:200
Data structure associated with a single frame of data.
struct ast_frame_subclass subclass
union ast_frame::@226 data
enum ast_frame_type frametype
int rtimeoutms
Definition: pbx.h:216
int dtimeoutms
Definition: pbx.h:215
Number structure.
Definition: app_followme.c:154
const char * args
static struct test_options options
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:107
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define ast_clear_flag(p, flag)
Definition: utils.h:77
#define AST_FLAGS_ALL
Definition: utils.h:196

References app_opts, args, ast_answer(), AST_APP_ARG, ast_app_parse_options(), ast_callerid_split(), ast_channel_caller(), ast_channel_clear_flag(), ast_channel_hangupcause_set(), ast_channel_lock, ast_channel_name(), ast_channel_pbx(), ast_channel_set_flag(), ast_channel_unlock, ast_clear_flag, AST_CONTROL_CONGESTION, AST_CONTROL_HANGUP, ast_copy_string(), ast_debug, AST_DECLARE_APP_ARGS, ast_exists_extension(), ast_explicit_goto(), AST_FLAG_END_DTMF_ONLY, AST_FLAGS_ALL, AST_FRAME_CONTROL, AST_FRAME_DTMF, ast_frfree, ast_ignore_pattern(), ast_indicate(), ast_log, AST_LOG_NOTICE, ast_matchmore_extension(), AST_MAX_EXTENSION, ast_pbx_exec_application(), ast_playtones_stop(), ast_read(), ast_safe_sleep(), ast_set_callerid(), AST_STANDARD_APP_ARGS, AST_STATE_UP, ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_tvdiff_ms(), ast_tvnow(), ast_waitfor(), voicemailpwcheck::context, ast_frame::data, ast_pbx::dtimeoutms, ast_flags::flags, ast_frame::frametype, ast_frame_subclass::integer, LOG_WARNING, voicemailpwcheck::mailbox, NOANSWER_FLAG, NULL, options, pbx_builtin_setvar_helper(), play_dialtone(), POUND_TO_END_FLAG, ast_pbx::rtimeoutms, S_COR, ast_frame::subclass, tmp(), and ast_frame::uint32.

Referenced by load_module().

◆ load_module()

static int load_module ( void  )
static

Definition at line 413 of file app_disa.c.

414{
417}
static const char app[]
Definition: app_disa.c:116
static int disa_exec(struct ast_channel *chan, const char *data)
Definition: app_disa.c:146
@ AST_MODULE_LOAD_SUCCESS
Definition: module.h:70
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
Definition: module.h:626

References app, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, ast_register_application_xml, and disa_exec().

◆ play_dialtone()

static void play_dialtone ( struct ast_channel chan,
char *  mailbox 
)
static

Definition at line 128 of file app_disa.c.

129{
130 struct ast_tone_zone_sound *ts = NULL;
131
133 ts = ast_get_indication_tone(ast_channel_zone(chan), "dialrecall");
134 } else {
135 ts = ast_get_indication_tone(ast_channel_zone(chan), "dial");
136 }
137
138 if (ts) {
139 ast_playtones_start(chan, 0, ts->data, 0);
141 } else {
142 ast_tonepair_start(chan, 350, 440, 0, 0);
143 }
144}
int ast_tonepair_start(struct ast_channel *chan, int freq1, int freq2, int duration, int vol)
Definition: channel.c:7581
struct ast_tone_zone * ast_channel_zone(const struct ast_channel *chan)
int ast_app_has_voicemail(const char *mailboxes, const char *folder)
Determine if a given mailbox has any voicemail If folder is NULL, defaults to "INBOX"....
Definition: main/app.c:582
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
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
Description of a tone.
Definition: indications.h:35
const char * data
Description of a tone.
Definition: indications.h:52

References ast_app_has_voicemail(), ast_channel_zone(), ast_get_indication_tone(), ast_playtones_start(), ast_tone_zone_sound_unref(), ast_tonepair_start(), ast_tone_zone_sound::data, voicemailpwcheck::mailbox, and NULL.

Referenced by disa_exec().

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 408 of file app_disa.c.

409{
411}
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 = "DISA (Direct Inward System Access) Application" , .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 419 of file app_disa.c.

◆ app

const char app[] = "DISA"
static

Definition at line 116 of file app_disa.c.

Referenced by load_module(), and unload_module().

◆ app_opts

const struct ast_app_option app_opts[128] = { [ 'n' ] = { .flag = NOANSWER_FLAG }, [ 'p' ] = { .flag = POUND_TO_END_FLAG }, }
static

Definition at line 126 of file app_disa.c.

Referenced by disa_exec().

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 419 of file app_disa.c.