[svn-commits] murf: branch group/newcdr r115108 - /team/group/newcdr/cel/
SVN commits to the Digium repositories
svn-commits at lists.digium.com
Thu May 1 18:22:09 CDT 2008
Author: murf
Date: Thu May 1 18:22:08 2008
New Revision: 115108
URL: http://svn.digium.com/view/asterisk?view=rev&rev=115108
Log:
updated cel_csv, cel_manager.c, and a bit of cel_odbc.c; more to come
Modified:
team/group/newcdr/cel/cel_csv.c
team/group/newcdr/cel/cel_custom.c
team/group/newcdr/cel/cel_manager.c
team/group/newcdr/cel/cel_odbc.c
Modified: team/group/newcdr/cel/cel_csv.c
URL: http://svn.digium.com/view/asterisk/team/group/newcdr/cel/cel_csv.c?view=diff&rev=115108&r1=115107&r2=115108
==============================================================================
--- team/group/newcdr/cel/cel_csv.c (original)
+++ team/group/newcdr/cel/cel_csv.c Thu May 1 18:22:08 2008
@@ -40,6 +40,7 @@
#include <unistd.h>
#include <time.h>
+#include "asterisk/paths.h" /* use ast_config_AST_LOG_DIR */
#include "asterisk/config.h"
#include "asterisk/channel.h"
#include "asterisk/cel.h"
@@ -48,6 +49,7 @@
#include "asterisk/options.h"
#include "asterisk/logger.h"
#include "asterisk/utils.h"
+#include "asterisk/lock.h"
#define CSV_LOG_DIR "/cel-csv"
#define CSV_MASTER "/Master.csv"
@@ -57,6 +59,7 @@
static int usegmtime = 0;
static int loguniqueid = 0;
static int loguserfield = 0;
+static int loaded = 0;
static char *config = "cel.conf";
static struct ast_event_sub *event_sub = 0;
@@ -87,12 +90,14 @@
static FILE *mf = NULL;
-
-static int load_config(void)
+AST_MUTEX_DEFINE_STATIC(mf_lock);
+AST_MUTEX_DEFINE_STATIC(acf_lock);
+
+static int load_config(int reload)
{
struct ast_config *cfg;
struct ast_variable *var;
- struct ast_flags config_flags = { 0 };
+ struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
const char *tmp;
usegmtime = 0;
@@ -104,7 +109,10 @@
if (!cfg) {
ast_log(LOG_WARNING, "unable to load config: %s\n", config);
return 0;
- }
+ } else if (cfg == CONFIG_STATUS_FILEUNCHANGED)
+ return 0;
+
+
var = ast_variable_browse(cfg, "csv");
if (!var) {
ast_config_destroy(cfg);
@@ -146,11 +154,13 @@
{
int pos = strlen(buf);
int spos = 0;
- int error = 0;
+ int error = -1;
+
if (pos >= bufsize - 4)
return -1;
+
buf[pos++] = '\"';
- error = -1;
+
while(pos < bufsize - 3) {
if (!s[spos]) {
error = 0;
@@ -161,9 +171,11 @@
buf[pos++] = s[spos];
spos++;
}
+
buf[pos++] = '\"';
buf[pos++] = ',';
buf[pos++] = '\0';
+
return error;
}
@@ -181,18 +193,22 @@
return 0;
} */
-static int append_date(char *buf, struct timeval t, size_t bufsize)
+static int append_date(char *buf, struct timeval tv, size_t bufsize)
{
char tmp[80] = "";
struct ast_tm tm;
+
if (strlen(buf) > bufsize - 3)
return -1;
- if (ast_tvzero(t)) {
+
+ if (ast_tvzero(tv)) {
strncat(buf, ",", bufsize - strlen(buf) - 1);
return 0;
}
- ast_localtime(&t, &tm, usegmtime? "GMT" : NULL);
+
+ ast_localtime(&tv, &tm, usegmtime ? "GMT" : NULL);
ast_strftime(tmp, sizeof(tmp), DATE_FORMAT, &tm);
+
return append_string(buf, tmp, bufsize);
}
@@ -206,7 +222,7 @@
{
buf[0] = '\0';
- /* Start Time */
+ /* Event Time */
append_date(buf, eventtime, bufsize);
/* EventType */
if (eventtype==CEL_USER_DEFINED)
@@ -253,17 +269,28 @@
{
char tmp[PATH_MAX];
FILE *f;
+
if (strchr(acc, '/') || (acc[0] == '.')) {
ast_log(LOG_WARNING, "Account code '%s' insecure for writing file\n", acc);
return -1;
}
- snprintf(tmp, sizeof(tmp), "%s/%s/%s.csv", (char *)ast_config_AST_LOG_DIR,CSV_LOG_DIR, acc);
+
+ snprintf(tmp, sizeof(tmp), "%s/%s/%s.csv", ast_config_AST_LOG_DIR,CSV_LOG_DIR, acc);
+
+ ast_mutex_lock(&acf_lock);
+
f = fopen(tmp, "a");
- if (!f)
+ if (!f) {
+ ast_mutex_unlock(&acf_lock);
+ ast_log(LOG_ERROR, "Unable to open file %s : %s\n", tmp, strerror(errno));
return -1;
+ }
+
fputs(s, f);
fflush(f);
fclose(f);
+ ast_mutex_unlock(&acf_lock);
+
return 0;
}
@@ -310,16 +337,17 @@
/* because of the absolutely unconditional need for the
highest reliability possible in writing billing records,
we open write and close the log file each time */
+ ast_mutex_lock(&mf_lock);
mf = fopen(csvmaster, "a");
if (!mf) {
ast_log(LOG_ERROR, "Unable to re-open master file %s : %s\n", csvmaster, strerror(errno));
- }
- if (mf) {
+ } else {
fputs(buf, mf);
fflush(mf); /* be particularly anal here */
fclose(mf);
mf = NULL;
}
+ ast_mutex_unlock(&mf_lock);
if (!ast_strlen_zero(accountcode)) {
if (writefile(buf, (char*)accountcode))
ast_log(LOG_WARNING, "Unable to write CSV record to account file '%s' : %s\n", accountcode, strerror(errno));
@@ -330,34 +358,48 @@
static int unload_module(void)
{
- if (mf)
+ if (mf) {
fclose(mf);
+ mf = NULL;
+ }
+
if (event_sub)
ast_event_unsubscribe(event_sub);
event_sub = 0;
-
+ loaded = 0;
return 0;
}
static int load_module(void)
{
- if(!load_config())
+ if(!load_config(0))
return AST_MODULE_LOAD_DECLINE;
event_sub = ast_event_subscribe(AST_EVENT_CEL, csv_log, "CSV Event Logging", NULL, AST_EVENT_IE_END);
if (!event_sub) {
ast_log(LOG_ERROR, "Unable to register CSV CEL handling\n");
- if (mf)
+ if (mf) {
+ mf = NULL;
fclose(mf);
- }
+ loaded = 0;
+ }
+ } else {
+ loaded = 1;
+ }
+
return 0;
}
static int reload(void)
{
- load_config();
-
+ if (load_config(1)) {
+ loaded = 1;
+ } else {
+ loaded = 0;
+ ast_log(LOG_WARNING, "No [csv] section in cel.conf.\n");
+ }
+
return 0;
}
Modified: team/group/newcdr/cel/cel_custom.c
URL: http://svn.digium.com/view/asterisk/team/group/newcdr/cel/cel_custom.c?view=diff&rev=115108&r1=115107&r2=115108
==============================================================================
--- team/group/newcdr/cel/cel_custom.c (original)
+++ team/group/newcdr/cel/cel_custom.c Thu May 1 18:22:08 2008
@@ -1,10 +1,10 @@
/*
* Asterisk -- An open source telephony toolkit.
*
- * Copyright (C) 2007, Digium, Inc.
+ * Copyright (C) 2008, Digium, Inc.
*
* Steve Murphy <murf at digium.com>
- * much borrowed from cdr code, author Mark Spencer
+ * much borrowed from cdr code (cdr_custom.c), author Mark Spencer
*
* See http://www.asterisk.org for more information about
* the Asterisk project. Please do not directly contact
@@ -42,6 +42,7 @@
#include <unistd.h>
#include <time.h>
+#include "asterisk/paths.h" /* use ast_config_AST_LOG_DIR */
#include "asterisk/channel.h"
#include "asterisk/cel.h"
#include "asterisk/module.h"
@@ -55,6 +56,7 @@
#define DATE_FORMAT "%Y-%m-%d %T"
AST_MUTEX_DEFINE_STATIC(lock);
+AST_MUTEX_DEFINE_STATIC(mf_lock);
static char *name = "cel-custom";
@@ -71,19 +73,22 @@
struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
int res = -1;
+ if ((cfg = ast_config_load("cdr_custom.conf", config_flags)) == CONFIG_STATUS_FILEUNCHANGED)
+ return 0;
+
strcpy(format, "");
strcpy(master, "");
- if((cfg = ast_config_load("cel_custom.conf", config_flags))) {
+ ast_mutex_lock(&lock);
+
+ if(cfg) {
var = ast_variable_browse(cfg, "mappings");
while(var) {
- ast_mutex_lock(&lock);
if (!ast_strlen_zero(var->name) && !ast_strlen_zero(var->value)) {
if (strlen(var->value) > (sizeof(format) - 1))
ast_log(LOG_WARNING, "Format string too long, will be truncated, at line %d\n", var->lineno);
ast_copy_string(format, var->value, sizeof(format) - 1);
strcat(format,"\n");
snprintf(master, sizeof(master),"%s/%s/%s", ast_config_AST_LOG_DIR, name, var->name);
- ast_mutex_unlock(&lock);
} else
ast_log(LOG_NOTICE, "Mapping must have both filename and format at line %d\n", var->lineno);
if (var->next)
@@ -98,6 +103,7 @@
else
ast_log(LOG_WARNING, "Failed to load configuration file. Module not activated.\n");
}
+ ast_mutex_unlock(&lock);
return res;
}
@@ -178,23 +184,26 @@
/* because of the absolutely unconditional need for the
highest reliability possible in writing billing records,
we open write and close the log file each time */
+ ast_mutex_lock(&mf_lock);
mf = fopen(master, "a");
if (!mf) {
ast_log(LOG_ERROR, "Unable to re-open master file %s : %s\n", master, strerror(errno));
- }
- if (mf) {
+ } else {
fputs(buf, mf);
fflush(mf); /* be particularly anal here */
fclose(mf);
mf = NULL;
}
+ ast_mutex_unlock(&mf_lock);
return;
}
static int unload_module(void)
{
- if (mf)
+ if (mf) {
fclose(mf);
+ mf = NULL;
+ }
if (event_sub)
ast_event_unsubscribe(event_sub);
event_sub = 0;
@@ -207,12 +216,15 @@
if (!load_config(0)) {
event_sub = ast_event_subscribe(AST_EVENT_CEL, custom_log, "Custom CSV logging", NULL, AST_EVENT_IE_END);
- if (!event_sub)
+ if (mf)
+ {
+ fclose(mf);
+ mf = NULL;
+ }
+ if (!event_sub) {
ast_log(LOG_ERROR, "Unable to register custom CEL handling\n");
- if (mf)
- fclose(mf);
- if (!event_sub)
return AST_MODULE_LOAD_DECLINE;
+ }
return 0;
} else
return AST_MODULE_LOAD_DECLINE;
Modified: team/group/newcdr/cel/cel_manager.c
URL: http://svn.digium.com/view/asterisk/team/group/newcdr/cel/cel_manager.c?view=diff&rev=115108&r1=115107&r2=115108
==============================================================================
--- team/group/newcdr/cel/cel_manager.c (original)
+++ team/group/newcdr/cel/cel_manager.c Thu May 1 18:22:08 2008
@@ -1,11 +1,11 @@
/*
* Asterisk -- An open source telephony toolkit.
*
- * Copyright (C) 2007 Digium, Inc
+ * Copyright (C) 2008 Digium, Inc
*
* Steve Murphy <murf at digium.com>
* who freely borrowed code from the cdr equivalents
- *
+ * (see cdr/cdr_manager.c)
* See http://www.asterisk.org for more information about
* the Asterisk project. Please do not directly contact
* any of the maintainers of this project for assistance;
@@ -48,34 +48,64 @@
#define DATE_FORMAT "%Y-%m-%d %T"
#define CONF_FILE "cel_manager.conf"
+#define CUSTOM_FIELDS_BUF_SIZE 1024
+
+struct ast_str *customfields;
+
static int enablecel = 0;
static struct ast_event_sub *event_sub = 0;
+static void manager_log(const struct ast_event *event, void *userdata);
static int load_config(int reload)
{
- char *cat;
+ char *cat = NULL;
struct ast_config *cfg;
struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
struct ast_variable *v;
+ int newenablecel = 0;
cfg = ast_config_load(CONF_FILE, config_flags);
+ if (cfg == CONFIG_STATUS_FILEUNCHANGED)
+ return 0;
+
+ if (reload && customfields) {
+ ast_free(customfields);
+ }
+ customfields = NULL;
+
if (!cfg) {
+ ast_log(LOG_WARNING, "Failed to load configuration file. Module not activated.\n");
/* Standard configuration */
enablecel = 0;
return 0;
}
- cat = ast_category_browse(cfg, NULL);
- while (cat) {
+ while ( (cat = ast_category_browse(cfg, cat)) ) {
if (!strcasecmp(cat, "general")) {
v = ast_variable_browse(cfg, cat);
while (v) {
if (!strcasecmp(v->name, "enabled")) {
- enablecel = ast_true(v->value);
+ newenablecel = ast_true(v->value);
}
v = v->next;
}
+
+ } else if (!strcasecmp(cat, "mappings")) {
+ customfields = ast_str_create(CUSTOM_FIELDS_BUF_SIZE);
+ v = ast_variable_browse(cfg, cat);
+ while (v) {
+ if (customfields && !ast_strlen_zero(v->name) && !ast_strlen_zero(v->value)) {
+ if( (customfields->used + strlen(v->value) + strlen(v->name) + 14) < customfields->len) {
+ ast_str_append(&customfields, -1, "%s: ${CDR(%s)}\r\n", v->value, v->name);
+ ast_log(LOG_NOTICE, "Added mapping %s: ${CDR(%s)}\n", v->value, v->name);
+ } else {
+ ast_log(LOG_WARNING, "No more buffer space to add other custom fields\n");
+ break;
+ }
+
+ }
+ }
}
/* Next category */
@@ -83,6 +113,19 @@
}
ast_config_destroy(cfg);
+
+ if (enablecel && !newenablecel) {
+ if (event_sub)
+ ast_event_unsubscribe(event_sub);
+ event_sub = 0;
+ } else if (!enablecel && newenablecel) {
+ event_sub = ast_event_subscribe(AST_EVENT_CEL, manager_log, "Manager Event Logging", NULL, AST_EVENT_IE_END);
+ if (!event_sub) {
+ ast_log(LOG_ERROR, "Unable to register Asterisk Call Manager CEL handling\n");
+ }
+ }
+ enablecel = newenablecel;
+
return 1;
}
@@ -156,6 +199,9 @@
{
if (event_sub)
ast_event_unsubscribe(event_sub);
+ if (customfields)
+ ast_free(customfields);
+ customfields = NULL;
event_sub = 0;
return 0;
}
@@ -166,14 +212,7 @@
if (!load_config(0))
return AST_MODULE_LOAD_DECLINE;
- event_sub = ast_event_subscribe(AST_EVENT_CEL, manager_log, "Manager Event Logging", NULL, AST_EVENT_IE_END);
- if (!event_sub) {
- ast_log(LOG_ERROR, "Unable to register Asterisk Call Manager CEL handling\n");
- }
- if (!event_sub)
- return AST_MODULE_LOAD_DECLINE;
- else
- return 0;
+ return AST_MODULE_LOAD_SUCCESS;
}
static int reload(void)
Modified: team/group/newcdr/cel/cel_odbc.c
URL: http://svn.digium.com/view/asterisk/team/group/newcdr/cel/cel_odbc.c?view=diff&rev=115108&r1=115107&r2=115108
==============================================================================
--- team/group/newcdr/cel/cel_odbc.c (original)
+++ team/group/newcdr/cel/cel_odbc.c Thu May 1 18:22:08 2008
@@ -1,7 +1,7 @@
/*
* Asterisk -- An open source telephony toolkit.
*
- * Copyright (C) 2007, Digium, Inc.
+ * Copyright (C) 2008, Digium, Inc.
*
* Brian K. West <brian at bkw.org> original CDR version
* Steve Murphy <murf at digium.com> Adaptation to CEL
@@ -31,6 +31,7 @@
/*** MODULEINFO
<depend>unixodbc</depend>
+ <depend>ltdl</depend>
***/
#include "asterisk.h"
@@ -56,16 +57,22 @@
#include <w32api/sqltypes.h>
#endif
+enum {
+ CONFIG_LOGUNIQUEID = 1 << 0,
+ CONFIG_USEGMTIME = 1 << 1,
+ CONFIG_DISPOSITIONSTRING = 1 << 2,
+};
#include "asterisk/config.h"
#include "asterisk/options.h"
#include "asterisk/channel.h"
#include "asterisk/cel.h"
#include "asterisk/module.h"
+#include "asterisk/res_odbc.h"
#include "asterisk/logger.h"
#define DATE_FORMAT "%Y-%m-%d %T"
-static char *config = "cel_odbc.conf";
+static char *config_file = "cel_odbc.conf";
static char *dsn = NULL, *username = NULL, *password = NULL, *table = NULL;
static int loguniqueid = 0;
static int usegmtime = 0;
@@ -82,6 +89,8 @@
static SQLHSTMT ODBC_stmt; /* global ODBC Statement Handle */
static struct ast_event_sub *event_sub = 0;
+static struct ast_flags config = { 0 };
+
static void odbc_disconnect(void)
{
SQLDisconnect(ODBC_con);
@@ -90,12 +99,13 @@
connected = 0;
}
-static void odbc_log(const struct ast_event *event, void *userdata)
-{
- int ODBC_res;
+static SQLHSTMT execute_cb(struct odbc_obj *obj, void *data)
+{
+ SQLRETURN ODBC_res;
char sqlcmd[2048] = "", timestr[128];
- int res = 0;
+ struct ast_event *event = data;
struct ast_tm tm;
+ SQLHSTMT stmt;
enum ast_cel_eventtype eventtype;
const char *userdefname = 0;
struct timeval eventtime = {0};
@@ -129,10 +139,8 @@
ast_localtime(&eventtime, &tm, usegmtime ? "GMT" : NULL);
- ast_mutex_lock(&odbc_lock);
ast_strftime(timestr, sizeof(timestr), DATE_FORMAT, &tm);
- memset(sqlcmd,0,2048);
- if (loguniqueid) {
+ if (ast_test_flag(&config, CONFIG_LOGUNIQUEID)) {
snprintf(sqlcmd,sizeof(sqlcmd),"INSERT INTO %s "
"(eventtime,eventtype,cidname,cidnum,cidani,cidrdnis,ciddnid,exten,context,channel,app,"
"appdata,amaflags,accountcode,userfield,peer,uniqueid) "
@@ -143,119 +151,77 @@
"amaflags,accountcode,userfield,peer) "
"VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", table);
}
-
- if (!connected) {
- res = odbc_init();
- if (res < 0) {
- odbc_disconnect();
- ast_mutex_unlock(&odbc_lock);
- return;
- }
- }
-
- ODBC_res = SQLAllocHandle(SQL_HANDLE_STMT, ODBC_con, &ODBC_stmt);
+
+ ODBC_res = SQLAllocHandle(SQL_HANDLE_STMT, obj->con, &stmt);
if ((ODBC_res != SQL_SUCCESS) && (ODBC_res != SQL_SUCCESS_WITH_INFO)) {
- if (option_verbose > 10)
- ast_verbose( VERBOSE_PREFIX_4 "cel_odbc: Failure in AllocStatement %d\n", ODBC_res);
- SQLFreeHandle(SQL_HANDLE_STMT, ODBC_stmt);
- odbc_disconnect();
- ast_mutex_unlock(&odbc_lock);
+ ast_verb(11, "cel_odbc: Failure in AllocStatement %d\n", ODBC_res);
+ SQLFreeHandle(SQL_HANDLE_STMT, stmt);
+ return NULL;
+ }
+
+ SQLBindParameter(stmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(timestr), 0, ×tr, 0, NULL);
+ SQLBindParameter(stmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(userdefname), 0, (char*)userdefname, 0, NULL);
+ SQLBindParameter(stmt, 3, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cid_name), 0, (char*)cid_name, 0, NULL);
+ SQLBindParameter(stmt, 4, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cid_num), 0, (char*)cid_num, 0, NULL);
+ SQLBindParameter(stmt, 5, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cid_ani), 0, (char*)cid_ani, 0, NULL);
+ SQLBindParameter(stmt, 6, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cid_rdnis), 0, (char*)cid_rdnis, 0, NULL);
+ SQLBindParameter(stmt, 7, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cid_dnid), 0, (char*)cid_dnid, 0, NULL);
+ SQLBindParameter(stmt, 8, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(exten), 0, (char*)exten, 0, NULL);
+ SQLBindParameter(stmt, 9, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(context), 0, (char*)context, 0, NULL);
+ SQLBindParameter(stmt, 10, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(channame), 0, (char*)channame, 0, NULL);
+ SQLBindParameter(stmt, 11, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(appname), 0, (char*)appname, 0, NULL);
+ SQLBindParameter(stmt, 12, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(appdata), 0, (char*)appdata, 0, NULL);
+ SQLBindParameter(stmt, 13, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, (int*)&amaflag, 0, NULL);
+ SQLBindParameter(stmt, 14, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(accountcode), 0, (char*)accountcode, 0, NULL);
+ SQLBindParameter(stmt, 15, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(userfield), 0, (char*)userfield, 0, NULL);
+ SQLBindParameter(stmt, 16, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(peer), 0, (char*)peer, 0, NULL);
+
+ if (ast_test_flag(&config, CONFIG_LOGUNIQUEID)) {
+ SQLBindParameter(stmt, 17, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(uniqueid), 0, (char*)uniqueid, 0, NULL);
+ }
+
+ ODBC_res = SQLExecDirect(stmt, (unsigned char *)sqlcmd, SQL_NTS);
+
+ if ((ODBC_res != SQL_SUCCESS) && (ODBC_res != SQL_SUCCESS_WITH_INFO)) {
+ ast_verb(11, "cdr_odbc: Error in ExecDirect: %d\n", ODBC_res);
+ SQLFreeHandle(SQL_HANDLE_STMT, stmt);
+ return NULL;
+ }
+
+ return stmt;
+}
+
+static void odbc_log(const struct ast_event *event, void *userdata)
+{
+ struct odbc_obj *obj = ast_odbc_request_obj(dsn, 0);
+ SQLHSTMT stmt;
+ if (!obj) {
+ ast_log(LOG_ERROR, "Unable to retrieve database handle. CDR failed.\n");
return;
}
-
- /* We really should only have to do this once. But for some
- strange reason if I don't it blows holes in memory like
- like a shotgun. So we just do this so its safe. */
-
- ODBC_res = SQLPrepare(ODBC_stmt, (unsigned char *)sqlcmd, SQL_NTS);
-
- if ((ODBC_res != SQL_SUCCESS) && (ODBC_res != SQL_SUCCESS_WITH_INFO)) {
- if (option_verbose > 10)
- ast_verbose( VERBOSE_PREFIX_4 "cel_odbc: Error in PREPARE %d\n", ODBC_res);
- SQLFreeHandle(SQL_HANDLE_STMT, ODBC_stmt);
- odbc_disconnect();
- ast_mutex_unlock(&odbc_lock);
- return;
- }
-
- SQLBindParameter(ODBC_stmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(timestr), 0, ×tr, 0, NULL);
- SQLBindParameter(ODBC_stmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(userdefname), 0, (char*)userdefname, 0, NULL);
- SQLBindParameter(ODBC_stmt, 3, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cid_name), 0, (char*)cid_name, 0, NULL);
- SQLBindParameter(ODBC_stmt, 4, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cid_num), 0, (char*)cid_num, 0, NULL);
- SQLBindParameter(ODBC_stmt, 5, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cid_ani), 0, (char*)cid_ani, 0, NULL);
- SQLBindParameter(ODBC_stmt, 6, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cid_rdnis), 0, (char*)cid_rdnis, 0, NULL);
- SQLBindParameter(ODBC_stmt, 7, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cid_dnid), 0, (char*)cid_dnid, 0, NULL);
- SQLBindParameter(ODBC_stmt, 8, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(exten), 0, (char*)exten, 0, NULL);
- SQLBindParameter(ODBC_stmt, 9, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(context), 0, (char*)context, 0, NULL);
- SQLBindParameter(ODBC_stmt, 10, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(channame), 0, (char*)channame, 0, NULL);
- SQLBindParameter(ODBC_stmt, 11, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(appname), 0, (char*)appname, 0, NULL);
- SQLBindParameter(ODBC_stmt, 12, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(appdata), 0, (char*)appdata, 0, NULL);
- SQLBindParameter(ODBC_stmt, 13, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, (int*)&amaflag, 0, NULL);
- SQLBindParameter(ODBC_stmt, 14, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(accountcode), 0, (char*)accountcode, 0, NULL);
- SQLBindParameter(ODBC_stmt, 15, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(userfield), 0, (char*)userfield, 0, NULL);
- SQLBindParameter(ODBC_stmt, 16, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(peer), 0, (char*)peer, 0, NULL);
-
- if (loguniqueid) {
- SQLBindParameter(ODBC_stmt, 17, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(uniqueid), 0, (char*)uniqueid, 0, NULL);
- }
-
- if (connected) {
- res = odbc_do_query();
- if (res < 0) {
- if (option_verbose > 10)
- ast_verbose( VERBOSE_PREFIX_4 "cel_odbc: Query FAILED Call not logged!\n");
- if (option_verbose > 10)
- ast_verbose( VERBOSE_PREFIX_4 "cel_odbc: Reconnecting to dsn %s\n", dsn);
- SQLDisconnect(ODBC_con);
- res = odbc_init();
- if (res < 0) {
- if (option_verbose > 10)
- ast_verbose( VERBOSE_PREFIX_4 "cel_odbc: %s has gone away!\n", dsn);
- odbc_disconnect();
- } else {
- if (option_verbose > 10)
- ast_verbose( VERBOSE_PREFIX_4 "cel_odbc: Trying Query again!\n");
- res = odbc_do_query();
- if (res < 0) {
- if (option_verbose > 10)
- ast_verbose( VERBOSE_PREFIX_4 "cel_odbc: Query FAILED Call not logged!\n");
- }
- }
- }
- } else {
- if (option_verbose > 10)
- ast_verbose( VERBOSE_PREFIX_4 "cel_odbc: Query FAILED Call not logged!\n");
- }
- SQLFreeHandle(SQL_HANDLE_STMT, ODBC_stmt);
- ast_mutex_unlock(&odbc_lock);
- return;
-}
+ stmt = ast_odbc_direct_execute(obj, execute_cb, event);
+ if (stmt) {
+ SQLLEN rows = 0;
+
+ SQLRowCount(stmt, &rows);
+ SQLFreeHandle(SQL_HANDLE_STMT, stmt);
+
+ if (rows == 0)
+ ast_log(LOG_WARNING, "CEL successfully ran, but inserted 0 rows?\n");
+ } else
+ ast_log(LOG_ERROR, "CEL direct execute failed\n");
+ ast_odbc_release_obj(obj);
+}
+
static int odbc_unload_module(void)
{
- ast_mutex_lock(&odbc_lock);
- if (connected) {
- if (option_verbose > 10)
- ast_verbose( VERBOSE_PREFIX_4 "cel_odbc: Disconnecting from %s\n", dsn);
- SQLFreeHandle(SQL_HANDLE_STMT, ODBC_stmt);
- odbc_disconnect();
- }
if (dsn) {
if (option_verbose > 10)
ast_verbose( VERBOSE_PREFIX_4 "cel_odbc: free dsn\n");
free(dsn);
}
- if (username) {
- if (option_verbose > 10)
- ast_verbose( VERBOSE_PREFIX_4 "cel_odbc: free username\n");
- free(username);
- }
- if (password) {
- if (option_verbose > 10)
- ast_verbose( VERBOSE_PREFIX_4 "cel_odbc: free password\n");
- free(password);
- }
if (table) {
if (option_verbose > 10)
ast_verbose( VERBOSE_PREFIX_4 "cel_odbc: free table\n");
@@ -265,7 +231,6 @@
if (event_sub)
ast_event_unsubscribe(event_sub);
event_sub = 0;
- ast_mutex_unlock(&odbc_lock);
return 0;
}
@@ -274,212 +239,91 @@
int res = 0;
struct ast_config *cfg;
struct ast_variable *var;
+ const char *tmp;
struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
- const char *tmp;
-
- ast_mutex_lock(&odbc_lock);
-
- cfg = ast_config_load(config, config_flags);
- if (!cfg) {
- ast_log(LOG_WARNING, "cel_odbc: Unable to load config for ODBC CEL's: %s\n", config);
- res = AST_MODULE_LOAD_DECLINE;
- goto out;
- }
-
- var = ast_variable_browse(cfg, "global");
- if (!var) {
- /* nothing configured */
- goto out;
- }
-
- tmp = ast_variable_retrieve(cfg,"global","dsn");
- if (tmp == NULL) {
- ast_log(LOG_WARNING,"cel_odbc: dsn not specified. Assuming asteriskdb\n");
- tmp = "asteriskdb";
- }
- dsn = strdup(tmp);
- if (dsn == NULL) {
- ast_log(LOG_ERROR,"cel_odbc: Out of memory error.\n");
- res = -1;
- goto out;
- }
-
- tmp = ast_variable_retrieve(cfg,"global","dispositionstring");
- if (tmp) {
- dispositionstring = ast_true(tmp);
- } else {
- dispositionstring = 0;
- }
-
- tmp = ast_variable_retrieve(cfg,"global","username");
- if (tmp) {
- username = strdup(tmp);
- if (username == NULL) {
+
+ do
+ {
+
+ cfg = ast_config_load(config_file, config_flags);
+ if (!cfg) {
+ ast_log(LOG_WARNING, "cel_odbc: Unable to load config for ODBC CEL's: %s\n", config_file);
+ res = AST_MODULE_LOAD_DECLINE;
+ break;
+ } else if (cfg == CONFIG_STATUS_FILEUNCHANGED)
+ break;
+
+ var = ast_variable_browse(cfg, "global");
+ if (!var) {
+ /* nothing configured */
+ break;
+ }
+
+ tmp = ast_variable_retrieve(cfg,"global","dsn");
+ if (tmp == NULL) {
+ ast_log(LOG_WARNING,"cel_odbc: dsn not specified. Assuming asteriskdb\n");
+ tmp = "asteriskdb";
+ }
+ if (dsn)
+ ast_free(dsn);
+ dsn = strdup(tmp);
+ if (dsn == NULL) {
ast_log(LOG_ERROR,"cel_odbc: Out of memory error.\n");
res = -1;
- goto out;
- }
- }
-
- tmp = ast_variable_retrieve(cfg,"global","password");
- if (tmp) {
- password = strdup(tmp);
- if (password == NULL) {
+ break;
+ }
+
+ tmp = ast_variable_retrieve(cfg,"global","dispositionstring");
+ if (ast_true(tmp)) {
+ ast_set_flag(&config, CONFIG_DISPOSITIONSTRING);
+ } else {
+ ast_clear_flag(&config, CONFIG_DISPOSITIONSTRING);
+ }
+
+ tmp = ast_variable_retrieve(cfg,"global","loguniqueid");
+ if (ast_true(tmp)) {
+ ast_set_flag(&config, CONFIG_LOGUNIQUEID);
+ ast_debug(1,"cel_odbc: Logging uniqueid\n");
+ } else {
+ ast_debug(1,"cel_odbc: Not logging uniqueid\n");
+ ast_clear_flag(&config, CONFIG_LOGUNIQUEID);
+ }
+
+ tmp = ast_variable_retrieve(cfg,"global","usegmtime");
+ if (ast_true(tmp)) {
+ ast_set_flag(&config, CONFIG_USEGMTIME);
+ ast_debug(1, "cdr_odbc: Logging in GMT\n");
+ } else {
+ ast_debug(1, "cdr_odbc: Logging in local time\n");
+ ast_clear_flag(&config, CONFIG_USEGMTIME);
+ }
+
+ tmp = ast_variable_retrieve(cfg,"global","table");
+ if (tmp == NULL) {
+ ast_log(LOG_WARNING,"cel_odbc: table not specified. Assuming cel\n");
+ tmp = "cel";
+ }
+ if (table)
+ ast_free(table);
+ table = strdup(tmp);
+ if (table == NULL) {
ast_log(LOG_ERROR,"cel_odbc: Out of memory error.\n");
res = -1;
- goto out;
- }
- }
-
- tmp = ast_variable_retrieve(cfg,"global","loguniqueid");
- if (tmp) {
- loguniqueid = ast_true(tmp);
- if (loguniqueid) {
- if (option_debug)
- ast_log(LOG_DEBUG,"cel_odbc: Logging uniqueid\n");
- } else {
- if (option_debug)
- ast_log(LOG_DEBUG,"cel_odbc: Not logging uniqueid\n");
- }
- } else {
- if (option_debug)
- ast_log(LOG_DEBUG,"cel_odbc: Not logging uniqueid\n");
- loguniqueid = 0;
- }
-
- tmp = ast_variable_retrieve(cfg,"global","usegmtime");
- if (tmp) {
- usegmtime = ast_true(tmp);
- if (usegmtime) {
- if (option_debug)
- ast_log(LOG_DEBUG,"cel_odbc: Logging in GMT\n");
- } else {
- if (option_debug)
- ast_log(LOG_DEBUG,"cel_odbc: Not logging in GMT\n");
- }
- } else {
- if (option_debug)
- ast_log(LOG_DEBUG,"cel_odbc: Not logging in GMT\n");
- usegmtime = 0;
- }
-
- tmp = ast_variable_retrieve(cfg,"global","table");
- if (tmp == NULL) {
- ast_log(LOG_WARNING,"cel_odbc: table not specified. Assuming cel\n");
- tmp = "cel";
- }
- table = strdup(tmp);
- if (table == NULL) {
- ast_log(LOG_ERROR,"cel_odbc: Out of memory error.\n");
- res = -1;
- goto out;
- }
-
- if (option_verbose > 2) {
- ast_verbose( VERBOSE_PREFIX_3 "cel_odbc: dsn is %s\n",dsn);
- if (username)
- {
- ast_verbose( VERBOSE_PREFIX_3 "cel_odbc: username is %s\n",username);
- ast_verbose( VERBOSE_PREFIX_3 "cel_odbc: password is [secret]\n");
- }
- else
- ast_verbose( VERBOSE_PREFIX_3 "cel_odbc: retreiving username and password from odbc config\n");
- ast_verbose( VERBOSE_PREFIX_3 "cel_odbc: table is %s\n",table);
- }
+ break;
+ }
+
+ ast_verb(3, "cdr_odbc: dsn is %s\n", dsn);
+ ast_verb(3, "cdr_odbc: table is %s\n", table);
+
+ event_sub = ast_event_subscribe(AST_EVENT_CEL, odbc_log, "CEL ODBC backend", NULL, AST_EVENT_IE_END);
+ if (!event_sub) {
+ ast_log(LOG_ERROR, "cel_odbc: Unable to register ODBC CEL handling\n");
+ }
+ } while(0);
- res = odbc_init();
- if (res < 0) {
- ast_log(LOG_ERROR, "cel_odbc: Unable to connect to datasource: %s\n", dsn);
- if (option_verbose > 2) {
- ast_verbose( VERBOSE_PREFIX_3 "cel_odbc: Unable to connect to datasource: %s\n", dsn);
- }
- }
- event_sub = ast_event_subscribe(AST_EVENT_CEL, odbc_log, "CEL ODBC backend", NULL, AST_EVENT_IE_END);
- if (!event_sub) {
- ast_log(LOG_ERROR, "cel_odbc: Unable to register ODBC CEL handling\n");
- }
-out:
- if (cfg)
+ if (cfg && cfg != CONFIG_STATUS_FILEUNCHANGED)
ast_config_destroy(cfg);
- ast_mutex_unlock(&odbc_lock);
- if (event_sub)
- return 0;
- else
- return AST_MODULE_LOAD_DECLINE;
-}
-
-static int odbc_do_query(void)
-{
- int ODBC_res;
-
- ODBC_res = SQLExecute(ODBC_stmt);
-
- if ((ODBC_res != SQL_SUCCESS) && (ODBC_res != SQL_SUCCESS_WITH_INFO)) {
- if (option_verbose > 10)
- ast_verbose( VERBOSE_PREFIX_4 "cel_odbc: Error in Query %d\n", ODBC_res);
- SQLFreeHandle(SQL_HANDLE_STMT, ODBC_stmt);
- odbc_disconnect();
- return -1;
- } else {
- if (option_verbose > 10)
- ast_verbose( VERBOSE_PREFIX_4 "cel_odbc: Query Successful!\n");
- connected = 1;
- }
- return 0;
-}
-
-static int odbc_init(void)
-{
- int ODBC_res;
-
- if (ODBC_env == SQL_NULL_HANDLE || connected == 0) {
- ODBC_res = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &ODBC_env);
- if ((ODBC_res != SQL_SUCCESS) && (ODBC_res != SQL_SUCCESS_WITH_INFO)) {
- if (option_verbose > 10)
- ast_verbose( VERBOSE_PREFIX_4 "cel_odbc: Error AllocHandle\n");
- connected = 0;
- return -1;
- }
-
- ODBC_res = SQLSetEnvAttr(ODBC_env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);
-
- if ((ODBC_res != SQL_SUCCESS) && (ODBC_res != SQL_SUCCESS_WITH_INFO)) {
- if (option_verbose > 10)
- ast_verbose( VERBOSE_PREFIX_4 "cel_odbc: Error SetEnv\n");
- SQLFreeHandle(SQL_HANDLE_ENV, ODBC_env);
- connected = 0;
- return -1;
- }
-
- ODBC_res = SQLAllocHandle(SQL_HANDLE_DBC, ODBC_env, &ODBC_con);
-
- if ((ODBC_res != SQL_SUCCESS) && (ODBC_res != SQL_SUCCESS_WITH_INFO)) {
- if (option_verbose > 10)
- ast_verbose( VERBOSE_PREFIX_4 "cel_odbc: Error AllocHDB %d\n", ODBC_res);
- SQLFreeHandle(SQL_HANDLE_ENV, ODBC_env);
- connected = 0;
- return -1;
- }
- SQLSetConnectAttr(ODBC_con, SQL_LOGIN_TIMEOUT, (SQLPOINTER *)10, 0);
- }
-
- /* Note that the username and password could be NULL here, but that is allowed in ODBC.
- In this case, the default username and password will be used from odbc.conf */
- ODBC_res = SQLConnect(ODBC_con, (SQLCHAR*)dsn, SQL_NTS, (SQLCHAR*)username, SQL_NTS, (SQLCHAR*)password, SQL_NTS);
-
- if ((ODBC_res != SQL_SUCCESS) && (ODBC_res != SQL_SUCCESS_WITH_INFO)) {
- if (option_verbose > 10)
- ast_verbose( VERBOSE_PREFIX_4 "cel_odbc: Error SQLConnect %d\n", ODBC_res);
- SQLFreeHandle(SQL_HANDLE_DBC, ODBC_con);
- SQLFreeHandle(SQL_HANDLE_ENV, ODBC_env);
- connected = 0;
- return -1;
- } else {
- if (option_verbose > 10)
- ast_verbose( VERBOSE_PREFIX_4 "cel_odbc: Connected to %s\n", dsn);
- connected = 1;
- }
- return 0;
+ return res;
}
static int load_module(void)
@@ -494,7 +338,6 @@
static int reload(void)
{
- odbc_unload_module();
return odbc_load_module(1);
}
More information about the svn-commits
mailing list