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 __MODULE_INFO_SECTION | __mod_info = { __MODULE_INFO_GLOBALS .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "ODBC CDR Backend" , .key = ASTERISK_GPL_KEY , .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 __MODULE_INFO_SECTION __mod_info = { __MODULE_INFO_GLOBALS .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "ODBC CDR Backend" , .key = ASTERISK_GPL_KEY , .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().