ODBC CDR Backend. More...
#include "asterisk.h"#include <time.h>#include "asterisk/config.h"#include "asterisk/channel.h"#include "asterisk/cdr.h"#include "asterisk/module.h"#include "asterisk/res_odbc.h"
Go to the source code of this file.
Defines | |
| #define | DATE_FORMAT "%Y-%m-%d %T" |
Enumerations | |
| enum | { CONFIG_LOGUNIQUEID = 1 << 0, CONFIG_USEGMTIME = 1 << 1, CONFIG_DISPOSITIONSTRING = 1 << 2 } |
Functions | |
| static void | __reg_module (void) |
| static void | __unreg_module (void) |
| static SQLHSTMT | execute_cb (struct odbc_obj *obj, void *data) |
| static int | load_module (void) |
| static int | odbc_load_module (int reload) |
| static int | odbc_log (struct ast_cdr *cdr) |
| static int | reload (void) |
| static int | unload_module (void) |
Variables | |
| static struct ast_module_info | __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "ODBC CDR Backend" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .reload = reload, } |
| static struct ast_module_info * | ast_module_info = &__mod_info |
| static struct ast_flags | config = { 0 } |
| static char * | config_file = "cdr_odbc.conf" |
| static char * | dsn = NULL |
| static char * | name = "ODBC" |
| static char * | table = NULL |
| #define DATE_FORMAT "%Y-%m-%d %T" |
Definition at line 47 of file cdr_odbc.c.
Referenced by execute_cb().
| anonymous enum |
Definition at line 53 of file cdr_odbc.c.
{
CONFIG_LOGUNIQUEID = 1 << 0,
CONFIG_USEGMTIME = 1 << 1,
CONFIG_DISPOSITIONSTRING = 1 << 2,
};
| static void __reg_module | ( | void | ) | [static] |
Definition at line 263 of file cdr_odbc.c.
| static void __unreg_module | ( | void | ) | [static] |
Definition at line 263 of file cdr_odbc.c.
| static SQLHSTMT execute_cb | ( | struct odbc_obj * | obj, |
| void * | data | ||
| ) | [static] |
Definition at line 61 of file cdr_odbc.c.
References ast_cdr::accountcode, ast_cdr::amaflags, ast_cdr_disp2str(), ast_localtime(), ast_strftime(), ast_test_flag, ast_verb, ast_cdr::billsec, ast_cdr::channel, ast_cdr::clid, odbc_obj::con, CONFIG_DISPOSITIONSTRING, CONFIG_LOGUNIQUEID, CONFIG_USEGMTIME, DATE_FORMAT, ast_cdr::dcontext, ast_cdr::disposition, ast_cdr::dst, ast_cdr::dstchannel, ast_cdr::duration, ast_cdr::lastapp, ast_cdr::lastdata, ast_cdr::src, ast_cdr::start, ast_cdr::uniqueid, and ast_cdr::userfield.
Referenced by odbc_log().
{
struct ast_cdr *cdr = data;
SQLRETURN ODBC_res;
char sqlcmd[2048] = "", timestr[128];
struct ast_tm tm;
SQLHSTMT stmt;
ast_localtime(&cdr->start, &tm, ast_test_flag(&config, CONFIG_USEGMTIME) ? "GMT" : NULL);
ast_strftime(timestr, sizeof(timestr), DATE_FORMAT, &tm);
if (ast_test_flag(&config, CONFIG_LOGUNIQUEID)) {
snprintf(sqlcmd,sizeof(sqlcmd),"INSERT INTO %s "
"(calldate,clid,src,dst,dcontext,channel,dstchannel,lastapp,"
"lastdata,duration,billsec,disposition,amaflags,accountcode,uniqueid,userfield) "
"VALUES ({ts '%s'},?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", table, timestr);
} else {
snprintf(sqlcmd,sizeof(sqlcmd),"INSERT INTO %s "
"(calldate,clid,src,dst,dcontext,channel,dstchannel,lastapp,lastdata,"
"duration,billsec,disposition,amaflags,accountcode) "
"VALUES ({ts '%s'},?,?,?,?,?,?,?,?,?,?,?,?,?)", table, timestr);
}
ODBC_res = SQLAllocHandle(SQL_HANDLE_STMT, obj->con, &stmt);
if ((ODBC_res != SQL_SUCCESS) && (ODBC_res != SQL_SUCCESS_WITH_INFO)) {
ast_verb(11, "cdr_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(cdr->clid), 0, cdr->clid, 0, NULL);
SQLBindParameter(stmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->src), 0, cdr->src, 0, NULL);
SQLBindParameter(stmt, 3, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->dst), 0, cdr->dst, 0, NULL);
SQLBindParameter(stmt, 4, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->dcontext), 0, cdr->dcontext, 0, NULL);
SQLBindParameter(stmt, 5, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->channel), 0, cdr->channel, 0, NULL);
SQLBindParameter(stmt, 6, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->dstchannel), 0, cdr->dstchannel, 0, NULL);
SQLBindParameter(stmt, 7, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->lastapp), 0, cdr->lastapp, 0, NULL);
SQLBindParameter(stmt, 8, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->lastdata), 0, cdr->lastdata, 0, NULL);
SQLBindParameter(stmt, 9, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &cdr->duration, 0, NULL);
SQLBindParameter(stmt, 10, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &cdr->billsec, 0, NULL);
if (ast_test_flag(&config, CONFIG_DISPOSITIONSTRING))
SQLBindParameter(stmt, 11, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(ast_cdr_disp2str(cdr->disposition)) + 1, 0, ast_cdr_disp2str(cdr->disposition), 0, NULL);
else
SQLBindParameter(stmt, 11, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &cdr->disposition, 0, NULL);
SQLBindParameter(stmt, 12, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &cdr->amaflags, 0, NULL);
SQLBindParameter(stmt, 13, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->accountcode), 0, cdr->accountcode, 0, NULL);
if (ast_test_flag(&config, CONFIG_LOGUNIQUEID)) {
SQLBindParameter(stmt, 14, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->uniqueid), 0, cdr->uniqueid, 0, NULL);
SQLBindParameter(stmt, 15, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->userfield), 0, cdr->userfield, 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 int load_module | ( | void | ) | [static] |
Definition at line 233 of file cdr_odbc.c.
References odbc_load_module().
{
return odbc_load_module(0);
}
| static int odbc_load_module | ( | int | reload | ) | [static] |
Definition at line 151 of file cdr_odbc.c.
References ast_cdr_register(), ast_clear_flag, ast_config_destroy(), ast_config_load, ast_debug, ast_free, ast_log(), AST_MODULE_LOAD_DECLINE, ast_set_flag, ast_strdup, ast_true(), ast_variable_browse(), ast_variable_retrieve(), ast_verb, CONFIG_DISPOSITIONSTRING, CONFIG_FLAG_FILEUNCHANGED, CONFIG_LOGUNIQUEID, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, CONFIG_USEGMTIME, ast_module_info::description, LOG_ERROR, LOG_WARNING, odbc_log(), and var.
Referenced by load_module(), and reload().
{
int res = 0;
struct ast_config *cfg;
struct ast_variable *var;
const char *tmp;
struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
do {
cfg = ast_config_load(config_file, config_flags);
if (!cfg || cfg == CONFIG_STATUS_FILEINVALID) {
ast_log(LOG_WARNING, "cdr_odbc: Unable to load config for ODBC CDR'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;
}
if ((tmp = ast_variable_retrieve(cfg, "global", "dsn")) == NULL) {
ast_log(LOG_WARNING, "cdr_odbc: dsn not specified. Assuming asteriskdb\n");
tmp = "asteriskdb";
}
if (dsn)
ast_free(dsn);
dsn = ast_strdup(tmp);
if (dsn == NULL) {
res = -1;
break;
}
if (((tmp = ast_variable_retrieve(cfg, "global", "dispositionstring"))) && ast_true(tmp))
ast_set_flag(&config, CONFIG_DISPOSITIONSTRING);
else
ast_clear_flag(&config, CONFIG_DISPOSITIONSTRING);
if (((tmp = ast_variable_retrieve(cfg, "global", "loguniqueid"))) && ast_true(tmp)) {
ast_set_flag(&config, CONFIG_LOGUNIQUEID);
ast_debug(1, "cdr_odbc: Logging uniqueid\n");
} else {
ast_clear_flag(&config, CONFIG_LOGUNIQUEID);
ast_debug(1, "cdr_odbc: Not logging uniqueid\n");
}
if (((tmp = ast_variable_retrieve(cfg, "global", "usegmtime"))) && ast_true(tmp)) {
ast_set_flag(&config, CONFIG_USEGMTIME);
ast_debug(1, "cdr_odbc: Logging in GMT\n");
} else {
ast_clear_flag(&config, CONFIG_USEGMTIME);
ast_debug(1, "cdr_odbc: Logging in local time\n");
}
if ((tmp = ast_variable_retrieve(cfg, "global", "table")) == NULL) {
ast_log(LOG_WARNING, "cdr_odbc: table not specified. Assuming cdr\n");
tmp = "cdr";
}
if (table)
ast_free(table);
table = ast_strdup(tmp);
if (table == NULL) {
res = -1;
break;
}
ast_verb(3, "cdr_odbc: dsn is %s\n", dsn);
ast_verb(3, "cdr_odbc: table is %s\n", table);
res = ast_cdr_register(name, ast_module_info->description, odbc_log);
if (res) {
ast_log(LOG_ERROR, "cdr_odbc: Unable to register ODBC CDR handling\n");
}
} while (0);
if (cfg && cfg != CONFIG_STATUS_FILEUNCHANGED && cfg != CONFIG_STATUS_FILEINVALID)
ast_config_destroy(cfg);
return res;
}
| static int odbc_log | ( | struct ast_cdr * | cdr | ) | [static] |
Definition at line 126 of file cdr_odbc.c.
References ast_log(), ast_odbc_direct_execute(), ast_odbc_release_obj(), ast_odbc_request_obj(), execute_cb(), LOG_ERROR, and LOG_WARNING.
Referenced by odbc_load_module().
{
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 -1;
}
stmt = ast_odbc_direct_execute(obj, execute_cb, cdr);
if (stmt) {
SQLLEN rows = 0;
SQLRowCount(stmt, &rows);
SQLFreeHandle(SQL_HANDLE_STMT, stmt);
if (rows == 0)
ast_log(LOG_WARNING, "CDR successfully ran, but inserted 0 rows?\n");
} else
ast_log(LOG_ERROR, "CDR direct execute failed\n");
ast_odbc_release_obj(obj);
return 0;
}
| static int reload | ( | void | ) | [static] |
Definition at line 254 of file cdr_odbc.c.
References odbc_load_module().
{
return odbc_load_module(1);
}
| static int unload_module | ( | void | ) | [static] |
Definition at line 238 of file cdr_odbc.c.
References ast_cdr_unregister(), ast_free, and ast_verb.
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "ODBC CDR Backend" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .reload = reload, } [static] |
Definition at line 263 of file cdr_odbc.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 263 of file cdr_odbc.c.
Definition at line 59 of file cdr_odbc.c.
char* config_file = "cdr_odbc.conf" [static] |
Definition at line 50 of file cdr_odbc.c.
char* dsn = NULL [static] |
Definition at line 51 of file cdr_odbc.c.
Referenced by acf_odbc_read(), acf_odbc_write(), cli_odbc_read(), cli_odbc_write(), and init_acf_query().
char* name = "ODBC" [static] |
Definition at line 49 of file cdr_odbc.c.
| char * table = NULL |
Definition at line 51 of file cdr_odbc.c.
Referenced by ast_config_internal_load(), ast_destroy_realtime(), ast_load_realtime_helper(), ast_load_realtime_multientry(), ast_realtime_require_field(), ast_store_realtime(), ast_unload_realtime(), ast_update2_realtime(), ast_update_realtime(), config_module(), free_config(), quan(), read_config_maps(), realtime_common(), reload(), tds_load_module(), and update2_odbc().