[Asterisk-Dev] app_disa2: Feedback requested
Eric Wieling
eric at fnords.org
Sun Nov 2 03:53:12 MST 2003
I'm working on rewriting app_disa and would like some feedback on my
code. I pretty much don't know what I'm doing, so any Asterisk specific
comments would be greatly appreciated. I'll try attaching the source,
it's not all that big. Yes, a fair number of features are not
implemented (mostly password and config file features), but I wanted to
see if I can get some feedback before I go much further with it.
--Eric
/*
* Asterisk -- A telephony toolkit for Linux.
*
* DISA -- Direct Inward System Access Application 11/01/2003
*
* Copyright (C) 2003, Eric Wieling
*
* Eric Wieling <eric at fnords.org>
*
* This program is free software, distributed under the terms of
* the GNU General Public License
*/
/*
Valid parameters are:
password=NUMERIC-PASSWORD|no-password
context=CONTEXT
mailbox=MAILBOX[@VOICEMAIL-CONTEXT]
callerid="NAME" <NUMBER>
accountcode=ACCOUNTCODE
config=FILE
Parameters may be abbreviated by using the first 4 characters of the
parameter name.
Parameters are seperated by a , (comma) or a | (pipe symbol). At a
minimum the password= or config= parameter must be specified. To specify
no password, use password=no-password. The mailbox= and callerid= are
the only parameters that may have empty values. If any parameter (except
mailbox= or callerid=) is specified, it must have a value.
If the mailbox= parameter is used and the specified mailbox has new
voicemail, it will be indicated by an interrupted (stutter) dialtone
after the password is entered.
Passwords should be terminated by a # (pound). If the user does not dial
# at the end of their password they will have to wait for DigitTimeout.
If a config file is specified, no other parameters are
allowed. In the config file a # (pound) sign as the first
character of the line indicates a comment.
Examples:
DISA2(password=no-password)
DISA2(config=/etc/asterisk/disa.conf)
DISA(password=1234,context=extensions,mailbox=2000)
*/
#include <asterisk/file.h>
#include <asterisk/logger.h>
#include <asterisk/channel.h>
#include <asterisk/pbx.h>
#include <asterisk/module.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
#include <asterisk/app.h>
#include <asterisk/indications.h>
#include <asterisk/options.h>
static char *tdesc = "DISA (Direct Inward System Access) Application";
static char *app = "DISA2";
static char *synopsis = "DISA (Direct Inward System Access)";
static char *descrip =
"A description of this application has not (yet) been written.\n";
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
static int disa_exec(struct ast_channel *chan, void *data)
{
int res = 0;
int len = 0;
char *cmdline = NULL;
char *_strtok_ptr = NULL;
char *tmp = NULL;
char *password = NULL;
char *mailbox = NULL;
char *context = NULL;
char *callerid = NULL;
char *accountcode = NULL;
char exten[AST_MAX_EXTENSION] = "";
struct localuser *u;
struct tone_zone_sound *ts;
/* Parse our parameters */
cmdline = (char *) strdup(data);
tmp = (char *) strtok_r(cmdline, "=|", &_strtok_ptr);
while (tmp != NULL) {
if (strcmp("password", tmp) == 0) {
tmp = (char *) strtok_r(NULL, "=|", &_strtok_ptr);
if (tmp == NULL) {
ast_log(LOG_NOTICE, "DISA2: Password parameter, but no password value! Exiting!\n");
return -1;
} else {
password = (char *) strdup(tmp);
}
} else if (strcmp("context", tmp) == 0) {
tmp = (char *) strtok_r(NULL, "=|", &_strtok_ptr);
if (tmp == NULL) {
ast_log(LOG_NOTICE, "DISA2: Context parameter, but no context value! Exiting!\n");
return -1;
} else {
context = (char *) strdup(tmp);
}
} else if (strcmp("accountcode", tmp) == 0) {
tmp = (char *) strtok_r(NULL, "=|", &_strtok_ptr);
if (tmp == NULL) {
ast_log(LOG_NOTICE, "DISA2: Account code parameter, but no account code value! Exiting!\n");
return -1;
} else {
accountcode = (char *) strdup(tmp);
}
} else if (strcmp("mailbox", tmp) == 0) {
tmp = (char *) strtok_r(NULL, "=|", &_strtok_ptr);
if (tmp == NULL) {
mailbox = NULL;
} else {
mailbox = (char *) strdup(tmp);
}
} else if (strcmp("callerid", tmp) == 0) {
tmp = (char *) strtok_r(NULL, "=|", &_strtok_ptr);
if (tmp == NULL) {
callerid = NULL;
} else {
callerid = (char *) strdup(tmp);
}
}
tmp = (char *) strtok_r(NULL, "=|", &_strtok_ptr);
}
if (password == NULL) {
ast_log(LOG_NOTICE, "DISA2: No password specified! Exiting!.\n");
return -1;
}
if (context == NULL) {
ast_log(LOG_NOTICE, "DISA2: No context specified, setting to \"disa\".\n");
context = "disa";
}
if (accountcode == NULL) {
accountcode = chan->accountcode;
}
ast_log(LOG_DEBUG, "DISA2: context=%s, mailbox=%s, password=%s, accountcode=%s, callerid=%s", context, mailbox, password, accountcode, callerid);
LOCAL_USER_ADD(u);
if (chan->_state != AST_STATE_UP) {
res = ast_answer(chan);
if (res != 0) {
LOCAL_USER_REMOVE(u);
return -1;
}
}
if (mailbox != NULL) {
if (ast_app_has_voicemail(mailbox)) {
ts = ast_get_indication_tone(chan->zone, "dialrecall");
} else {
ts = ast_get_indication_tone(chan->zone, "dial");
}
} else {
ts = ast_get_indication_tone(chan->zone, "dial");
}
if (ts && ts->data[0]) {
res = ast_playtones_start(chan, 0, ts->data, 0);
} else {
res = ast_playtones_start(chan, 0, "dial", 0);
}
if (res) {
ast_log(LOG_NOTICE,"Unable to start playtones\n");
return res;
}
while(len < AST_MAX_EXTENSION-1) {
res = ast_waitfordigit(chan, 10000);
if (res < 0) {
ast_log(LOG_NOTICE, "Channel hung up.\n");
LOCAL_USER_REMOVE(u);
return -1;
}
if (res == 0) {
ast_log(LOG_NOTICE, "Timeout waiting for digits.\n");
break;
}
ast_log(LOG_NOTICE, "Got digit = %c\n", (char) res);
exten[len++] = res;
exten[len] = '\0';
if (ast_ignore_pattern(context, exten) == 0) {
ast_log(LOG_NOTICE, "Stoping dialtone.\n");
ast_playtones_stop(chan);
} else {
ast_log(LOG_NOTICE, "Continueing dialtone.\n");
ts = ast_get_indication_tone(chan->zone, "dial");
if (ts && ts->data[0]) {
res = ast_playtones_start(chan, 0, ts->data, 0);
} else {
res = ast_playtones_start(chan, 0, "dial", 0);
}
if (res) {
ast_log(LOG_NOTICE,"Unable to start playtones\n");
return res;
}
}
if (ast_matchmore_extension(chan, context, exten, 1, NULL) == 0) {
ast_log(LOG_NOTICE,"Extension %s will not match any more digits\n", exten);
break;
}
}
if (ast_exists_extension(chan, context, exten, 1, chan->callerid)) {
ast_log(LOG_NOTICE,"Extension %s exists.\n", exten);
} else {
ast_log(LOG_NOTICE,"Extension %s does not exist.\n", exten);
pbx_builtin_setvar_helper(chan, "INVALID_EXTEN", exten);
strcpy(chan->exten,"i");
chan->priority = 0;
LOCAL_USER_REMOVE(u);
return 0;
}
strcpy(chan->exten,exten);
strcpy(chan->context,context);
strcpy(chan->accountcode,accountcode);
chan->priority = 0;
LOCAL_USER_REMOVE(u);
return 0;
}
int unload_module(void)
{
STANDARD_HANGUP_LOCALUSERS;
return ast_unregister_application(app);
}
int load_module(void)
{
return ast_register_application(app, disa_exec, synopsis, descrip);
}
char *description(void)
{
return tdesc;
}
int usecount(void)
{
int res;
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}
--
Sample configs, scripts, more : http://www.fnords.org/~eric/asterisk/
BTEL Consulting 504-899-1387 or 850-484-4545 or 877-677-9643
More information about the asterisk-dev
mailing list