[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