[Asterisk-Users] Custom Application For Asterisk
Gulzar Hussain
gulzar10 at yahoo.com
Thu Aug 25 03:36:12 MST 2005
Hi All
I just completed a custom application for Asterisk (i
m not a C guru so i just copy codes from other
application and alter according to my needs)
attached files is the source file
this application is working fine but still i need you
people to give suggestion to improve it
Primary task of this application is to get a parameter
from extensions.conf, query sql server and play a
files according to the result
Thanks
(I have changed some code to make my code secure ;) )
__________________________________________________
Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com
-------------- next part --------------
#include <asterisk/lock.h>
#include <asterisk/file.h>
#include <asterisk/pbx.h>
#include <asterisk/app.h>
#include <asterisk/say.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <libpq-fe.h>
#include <asterisk/translate.h>
#include <asterisk/musiconhold.h>
#include <asterisk/callerid.h>
#include <sys/time.h>
#include <sys/signal.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <asterisk/config.h>
#include <asterisk/options.h>
#include <asterisk/channel.h>
#include <asterisk/module.h>
#include <asterisk/logger.h>
#include "../asterisk.h"
#include <unistd.h>
#include <time.h>
#include <math.h>
#include <tds.h>
#include <tdsconvert.h>
#include <ctype.h>
#if !defined(TDS_INT_EXIT)
#define TDS_PRE_0_62
#warning "You have older TDS, you should upgrade!"
#endif
#define DATE_FORMAT "%Y/%m/%d %T"
static char *config = "abcd.conf";
static char *tdesc = "abcd Application";
static char *app = "abcd";
static char *synopsis = "abcd New";
static char *descrip =
" abcd-IVR: Requires a user to enter a"
" number. and announce number according to query result\n";
static char abcdhostname[30] = "";
static char abcddbname[30] = "";
static char abcddbuser[30] = "";
static char abcdpassword[30] = "";
static char abcdcharset[30] = "";
static char abcdlanguage[30] = "";
#define DEFAULTCHARSET "iso_1"
#define DEFAULTLANGUAGE "us_english"
static int connected = 0;
static int mssql_connect(void);
static int mssql_disconnect(void);
static int play_file(struct ast_channel *chan, char *filename);
AST_MUTEX_DEFINE_STATIC(tdslock);
static TDSSOCKET *tds;
static TDSLOGIN *login;
static TDSCONTEXT *context;
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
struct abcd_user {
char moh[80];
char announce[80];
char context[80];
int handled;
time_t start;
int queuetimeout;
struct ast_channel *chan;
struct queue_ent *next;
};
static int abcd_exec(struct ast_channel *chan, void *data)
{
int retried = 0;
int res = 0;
int res_type;
int tdsret;
int rowtype;
int computeid;
int i;
int sucs = 0;
struct localuser *u;
char mysqlcmd[1024];
char myretnumber[6];
const void *value;
char resulttype[4];
if (!data) {
ast_log(LOG_WARNING, "abcd requires an argument (number)\n");
return -1;
}
LOCAL_USER_ADD(u);
ast_mutex_lock(&tdslock);
memset(mysqlcmd, 0, sizeof(mysqlcmd));
sprintf(mysqlcmd, "Select MyFunction(\'%s\') As result",((char *) data));
do {
if (!connected) {
if (mssql_connect())
ast_log(LOG_ERROR, "Failed to reconnect to SQL database.\n");
else
ast_log(LOG_WARNING, "Reconnected to SQL database.\n");
retried = 1;
}
if (!connected || (tds_submit_query(tds, mysqlcmd) != TDS_SUCCEED))
{
ast_verbose(VERBOSE_PREFIX_3 "Failed to query database.\n");
mssql_disconnect();
}
} while (!connected && !retried);
if (!connected) {
res = -1;
ast_mutex_unlock(&tdslock);
LOCAL_USER_REMOVE(u);
return res;
}
tdsret = tds_process_result_tokens(tds, &res_type, NULL);
switch (tdsret) {
case TDS_SUCCEED:
switch(res_type){
case TDS_DONE_RESULT:
break;
case TDS_DONEPROC_RESULT:
break;
case TDS_DONEINPROC_RESULT:
break;
case TDS_ROWFMT_RESULT:
while ((res=tds_process_row_tokens(tds, &rowtype, &computeid))==TDS_SUCCEED) {
for (i=0; i<tds->res_info->num_cols; i++) {
value = ((tds->res_info->current_row) + (tds->res_info->columns[i]->column_offset));
memset(resulttype, 0, sizeof(resulttype));
strncpy(resulttype, (const char *) value, 3);
memset(myretnumber, 0, sizeof(myretnumber));
strncpy(myretnumber, (const char *) (value+4), strlen((const char *) value)-4);
}
}
if(!strcmp(resulttype,"NEW")){
sprintf(mysqlcmd, "Execute MyStoredProc \'%s\'\0",((char *) data));
if ((tds_submit_query(tds, mysqlcmd) != TDS_SUCCEED) || (tds_process_simple_query(tds) != TDS_SUCCEED)) {
ast_verbose(VERBOSE_PREFIX_3 "Failed to query database.\n");
ast_mutex_unlock(&tdslock);
res = -1;
return res;
}
sprintf(mysqlcmd, "Select MyFunction(\'%s\') As result \0",((char *) data));
if ((tds_submit_query(tds, mysqlcmd) == TDS_SUCCEED)) {
tdsret = tds_process_result_tokens(tds, &res_type, NULL);
if(tdsret == TDS_SUCCEED && res_type == TDS_ROWFMT_RESULT) {
while ((res=tds_process_row_tokens(tds, &rowtype, &computeid))==TDS_SUCCEED) {
for (i=0; i<tds->res_info->num_cols; i++) {
value = ((tds->res_info->current_row) + (tds->res_info->columns[i]->column_offset));
strncpy(resulttype, (const char *) value, 3);
strncpy(myretnumber, (const char *) (value+4), strlen((const char *) value)-4);
}
}
}else {
ast_verbose(VERBOSE_PREFIX_3 "!TDS_ROWFMT_RESULT %d\n",tdsret);
}
}else {
ast_verbose(VERBOSE_PREFIX_3 "Failed to query database.\n");
}
ast_mutex_unlock(&tdslock);
sucs = 1;
res = play_file(chan, "abcd_yournumbernois");
res = ast_say_number(chan, atoi(myretnumber), AST_DIGIT_ANY, chan->language, (char *) NULL);
} else if(!strcmp(resulttype,"ALD")){
ast_mutex_unlock(&tdslock);
sucs = 1;
res = play_file(chan, "abcd_alreadynumber");
res = ast_say_number(chan, atoi(myretnumber), AST_DIGIT_ANY, chan->language, (char *) NULL);
} else if(!strcmp(resulttype,"WRG")){
ast_mutex_unlock(&tdslock);
sucs = 1;
ast_moh_stop(chan);
res = play_file(chan, "abcd_wrongnumber");
} else if(!strcmp(resulttype,"TMP")){
ast_mutex_unlock(&tdslock);
sucs = 1;
ast_moh_stop(chan);
res = play_file(chan, "abcd_numberclosed");
}
break;
case TDS_COMPUTEFMT_RESULT:
break;
case TDS_ROW_RESULT:
break;
case TDS_COMPUTE_RESULT:
break;
case TDS_PARAM_RESULT:
break;
case TDS_STATUS_RESULT:
break;
default:
break;
}
break;
case TDS_NO_MORE_RESULTS:
ast_verbose(VERBOSE_PREFIX_3 "TDS_NO_MORE_RESULTS \n");
break;
case TDS_FAIL:
ast_verbose(VERBOSE_PREFIX_3 "tds_process_result_tokens failed. \n");
res = -1;
ast_mutex_unlock(&tdslock);
return res;
}
if(sucs == 0) ast_mutex_unlock(&tdslock);
LOCAL_USER_REMOVE(u);
return res;
}
static int mssql_connect(void)
{
TDSCONNECTINFO *connection = NULL;
char query[128];
if (!(login = tds_alloc_login()))
{
ast_log(LOG_ERROR, "tds_alloc_login() failed.\n");
return -1;
}
tds_set_server(login, abcdhostname);
tds_set_user(login, abcddbuser);
tds_set_passwd(login, abcdpassword);
tds_set_app(login, "TSQL");
tds_set_library(login, "TDS-Library");
#ifndef TDS_PRE_0_62
tds_set_client_charset(login, abcdcharset);
#endif
tds_set_language(login, abcdlanguage);
tds_set_packet(login, 512);
tds_set_version(login, 7, 0);
if (!(context = tds_alloc_context())) {
ast_log(LOG_ERROR, "tds_alloc_context() failed.\n");
goto connect_fail;
}
if (!(tds = tds_alloc_socket(context, 512))) {
ast_log(LOG_ERROR, "tds_alloc_socket() failed.\n");
goto connect_fail;
}
tds_set_parent(tds, NULL);
connection = tds_read_config_info(tds, login, context->locale);
if (!connection) {
ast_log(LOG_ERROR, "tds_read_config() failed.\n");
goto connect_fail;
}
if (tds_connect(tds, connection) == TDS_FAIL) {
ast_log(LOG_ERROR, "Failed to connect to MSSQL server.\n");
tds = NULL;
tds_free_connect(connection);
connection = NULL;
goto connect_fail;
}
tds_free_connect(connection);
connection = NULL;
sprintf(query, "USE %s", abcddbname);
#ifdef TDS_PRE_0_62
if ((tds_submit_query(tds, query) != TDS_SUCCEED) || (tds_process_simple_query(tds, &result_type) != TDS_SUCCEED || result_type != TDS_CMD_SUCCEED)) {
#else
if ((tds_submit_query(tds, query) != TDS_SUCCEED) || (tds_process_simple_query(tds) != TDS_SUCCEED)) {
#endif
ast_log(LOG_ERROR, "Could not change database (%s)\n", abcddbname);
goto connect_fail;
}
connected = 1;
return 0;
connect_fail:
mssql_disconnect();
return -1;
}
static int mssql_disconnect(void)
{
if (tds) {
tds_free_socket(tds);
tds = NULL;
}
if (context) {
tds_free_context(context);
context = NULL;
}
if (login) {
tds_free_login(login);
login = NULL;
}
connected = 0;
return 0;
}
static int play_file(struct ast_channel *chan, char *filename)
{
int res;
ast_stopstream(chan);
res = ast_streamfile(chan, filename, chan->language);
if (!res)
res = ast_waitstream(chan, "");
else
res = 0;
if (res) {
ast_log(LOG_WARNING, "ast_streamfile failed on %s \n", chan->name);
res = 0;
}
ast_stopstream(chan);
return res;
}
int load_module(void)
{
struct ast_config *cfg;
char *s;
int res = 0;
cfg = ast_load(config);
if (!cfg) {
ast_log(LOG_NOTICE, "Unable to load config for abcd %s\n", config);
return 0;
}
if (!(s=ast_variable_retrieve(cfg, "global", "hostname"))) {
ast_log(LOG_ERROR,"abcd Database Server Hostname not specified.\n");
} else {
strncpy(abcdhostname, s, sizeof(abcdhostname) - 1);
}
if (!(s=ast_variable_retrieve(cfg, "global", "dbname"))) {
ast_log(LOG_ERROR,"abcd Database Name not specified.\n");
} else {
strncpy(abcddbname, s, sizeof(abcddbname) - 1);
}
if (!(s=ast_variable_retrieve(cfg, "global", "user"))) {
ast_log(LOG_ERROR,"abcd Database User Name not specified.\n");
} else {
strncpy(abcddbuser, s, sizeof(abcddbuser) - 1);
}
if (!(s=ast_variable_retrieve(cfg, "global", "password"))) {
ast_log(LOG_ERROR,"abcd Database User Password not specified.\n");
} else {
strncpy(abcdpassword, s, sizeof(abcdpassword) - 1);
}
if (!(s=ast_variable_retrieve(cfg, "global", "charset"))) {
strncpy(abcdcharset, DEFAULTCHARSET, sizeof(abcdcharset) - 1);
} else {
strncpy(abcdcharset, s, sizeof(abcdcharset) - 1);
}
if (!(s=ast_variable_retrieve(cfg, "global", "language"))) {
strncpy(abcdlanguage, DEFAULTLANGUAGE, sizeof(abcdlanguage) - 1);
} else {
strncpy(abcdlanguage, s, sizeof(abcdlanguage) - 1);
}
ast_destroy(cfg);
mssql_connect();
res = ast_register_application(app, abcd_exec, synopsis, descrip);
if (res){
ast_log(LOG_ERROR, "Unable to register abcd MSSQL handling\n");
}
return res;
}
int unload_module(void)
{
STANDARD_HANGUP_LOCALUSERS;
mssql_disconnect();
ast_unregister_application(app);
if (abcdhostname) free(abcdhostname);
if (abcddbname) free(abcddbname);
if (abcddbuser) free(abcddbuser);
if (abcdpassword) free(abcdpassword);
if (abcdcharset) free(abcdcharset);
if (abcdlanguage) free(abcdlanguage);
return 0;
}
int reload(void)
{
unload_module();
return load_module();
}
int usecount(void)
{
int res;
STANDARD_USECOUNT(res);
return res;
}
char *description(void) { return tdesc;}
char *key() { return ASTERISK_GPL_KEY; }
More information about the asterisk-users
mailing list