[Asterisk-Dev] app_disa2: Feedback requested
Steven Critchfield
critch at basesys.com
Sun Nov 2 09:22:48 MST 2003
While not commenting o the code itself, Why not place all the
information in a specified config file and then either match context to
the config file, or something similar. If you created a nice one line
config line per entry then you could later on easily migrate this to a
database or other storage abstraction layer. Also the idea of a userid
on top of the password would be a good idea.
Just some thoughts. So far I still don't need access to DISA, so take
that into consideration when you think about my suggestions.
On Sun, 2003-11-02 at 04:53, Eric Wieling wrote:
> 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;
> }
--
Steven Critchfield <critch at basesys.com>
More information about the asterisk-dev
mailing list