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().