#include "asterisk.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, CONFIG_HRTIME = 1 << 3, CONFIG_REGISTERED = 1 << 4 } |
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_LOAD_ORDER , .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 = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CDR_DRIVER, } |
static struct ast_module_info * | ast_module_info = &__mod_info |
static struct ast_flags | config = { 0 } |
static const char | config_file [] = "cdr_odbc.conf" |
static char * | dsn = NULL |
static const char | name [] = "ODBC" |
static char * | table = NULL |
Definition in file cdr_odbc.c.
#define DATE_FORMAT "%Y-%m-%d %T" |
Definition at line 46 of file cdr_odbc.c.
anonymous enum |
CONFIG_LOGUNIQUEID | |
CONFIG_USEGMTIME | |
CONFIG_DISPOSITIONSTRING | |
CONFIG_HRTIME | |
CONFIG_REGISTERED |
Definition at line 52 of file cdr_odbc.c.
00052 { 00053 CONFIG_LOGUNIQUEID = 1 << 0, 00054 CONFIG_USEGMTIME = 1 << 1, 00055 CONFIG_DISPOSITIONSTRING = 1 << 2, 00056 CONFIG_HRTIME = 1 << 3, 00057 CONFIG_REGISTERED = 1 << 4, 00058 };
static void __reg_module | ( | void | ) | [static] |
Definition at line 298 of file cdr_odbc.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 298 of file cdr_odbc.c.
static SQLHSTMT execute_cb | ( | struct odbc_obj * | obj, | |
void * | data | |||
) | [static] |
Definition at line 62 of file cdr_odbc.c.
References ast_cdr::accountcode, ast_cdr::amaflags, ast_cdr::answer, ast_cdr_disp2str(), ast_localtime(), ast_strftime(), ast_test_flag, ast_tvdiff_us(), ast_tvzero(), ast_verb, ast_cdr::billsec, ast_cdr::channel, ast_cdr::clid, odbc_obj::con, config, CONFIG_DISPOSITIONSTRING, CONFIG_HRTIME, CONFIG_LOGUNIQUEID, CONFIG_USEGMTIME, DATE_FORMAT, ast_cdr::dcontext, ast_cdr::disposition, ast_cdr::dst, ast_cdr::dstchannel, ast_cdr::duration, ast_cdr::end, ast_cdr::lastapp, ast_cdr::lastdata, ast_cdr::src, ast_cdr::start, ast_cdr::uniqueid, and ast_cdr::userfield.
Referenced by odbc_log().
00063 { 00064 struct ast_cdr *cdr = data; 00065 SQLRETURN ODBC_res; 00066 char sqlcmd[2048] = "", timestr[128]; 00067 struct ast_tm tm; 00068 SQLHSTMT stmt; 00069 00070 ast_localtime(&cdr->start, &tm, ast_test_flag(&config, CONFIG_USEGMTIME) ? "GMT" : NULL); 00071 ast_strftime(timestr, sizeof(timestr), DATE_FORMAT, &tm); 00072 00073 if (ast_test_flag(&config, CONFIG_LOGUNIQUEID)) { 00074 snprintf(sqlcmd,sizeof(sqlcmd),"INSERT INTO %s " 00075 "(calldate,clid,src,dst,dcontext,channel,dstchannel,lastapp," 00076 "lastdata,duration,billsec,disposition,amaflags,accountcode,uniqueid,userfield) " 00077 "VALUES ({ts '%s'},?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", table, timestr); 00078 } else { 00079 snprintf(sqlcmd,sizeof(sqlcmd),"INSERT INTO %s " 00080 "(calldate,clid,src,dst,dcontext,channel,dstchannel,lastapp,lastdata," 00081 "duration,billsec,disposition,amaflags,accountcode) " 00082 "VALUES ({ts '%s'},?,?,?,?,?,?,?,?,?,?,?,?,?)", table, timestr); 00083 } 00084 00085 ODBC_res = SQLAllocHandle(SQL_HANDLE_STMT, obj->con, &stmt); 00086 00087 if ((ODBC_res != SQL_SUCCESS) && (ODBC_res != SQL_SUCCESS_WITH_INFO)) { 00088 ast_verb(11, "cdr_odbc: Failure in AllocStatement %d\n", ODBC_res); 00089 SQLFreeHandle(SQL_HANDLE_STMT, stmt); 00090 return NULL; 00091 } 00092 00093 SQLBindParameter(stmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->clid), 0, cdr->clid, 0, NULL); 00094 SQLBindParameter(stmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->src), 0, cdr->src, 0, NULL); 00095 SQLBindParameter(stmt, 3, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->dst), 0, cdr->dst, 0, NULL); 00096 SQLBindParameter(stmt, 4, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->dcontext), 0, cdr->dcontext, 0, NULL); 00097 SQLBindParameter(stmt, 5, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->channel), 0, cdr->channel, 0, NULL); 00098 SQLBindParameter(stmt, 6, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->dstchannel), 0, cdr->dstchannel, 0, NULL); 00099 SQLBindParameter(stmt, 7, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->lastapp), 0, cdr->lastapp, 0, NULL); 00100 SQLBindParameter(stmt, 8, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->lastdata), 0, cdr->lastdata, 0, NULL); 00101 00102 if (ast_test_flag(&config, CONFIG_HRTIME)) { 00103 double hrbillsec = 0.0; 00104 double hrduration; 00105 00106 if (!ast_tvzero(cdr->answer)) { 00107 hrbillsec = (double) ast_tvdiff_us(cdr->end, cdr->answer) / 1000000.0; 00108 } 00109 hrduration = (double) ast_tvdiff_us(cdr->end, cdr->start) / 1000000.0; 00110 00111 SQLBindParameter(stmt, 9, SQL_PARAM_INPUT, SQL_C_DOUBLE, SQL_FLOAT, 0, 0, &hrduration, 0, NULL); 00112 SQLBindParameter(stmt, 10, SQL_PARAM_INPUT, SQL_C_DOUBLE, SQL_FLOAT, 0, 0, &hrbillsec, 0, NULL); 00113 } else { 00114 SQLBindParameter(stmt, 9, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &cdr->duration, 0, NULL); 00115 SQLBindParameter(stmt, 10, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &cdr->billsec, 0, NULL); 00116 } 00117 00118 if (ast_test_flag(&config, CONFIG_DISPOSITIONSTRING)) 00119 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); 00120 else 00121 SQLBindParameter(stmt, 11, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &cdr->disposition, 0, NULL); 00122 SQLBindParameter(stmt, 12, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &cdr->amaflags, 0, NULL); 00123 SQLBindParameter(stmt, 13, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->accountcode), 0, cdr->accountcode, 0, NULL); 00124 00125 if (ast_test_flag(&config, CONFIG_LOGUNIQUEID)) { 00126 SQLBindParameter(stmt, 14, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->uniqueid), 0, cdr->uniqueid, 0, NULL); 00127 SQLBindParameter(stmt, 15, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->userfield), 0, cdr->userfield, 0, NULL); 00128 } 00129 00130 ODBC_res = SQLExecDirect(stmt, (unsigned char *)sqlcmd, SQL_NTS); 00131 00132 if ((ODBC_res != SQL_SUCCESS) && (ODBC_res != SQL_SUCCESS_WITH_INFO)) { 00133 ast_verb(11, "cdr_odbc: Error in ExecDirect: %d\n", ODBC_res); 00134 SQLFreeHandle(SQL_HANDLE_STMT, stmt); 00135 return NULL; 00136 } 00137 00138 return stmt; 00139 }
static int load_module | ( | void | ) | [static] |
Definition at line 267 of file cdr_odbc.c.
References odbc_load_module().
00268 { 00269 return odbc_load_module(0); 00270 }
static int odbc_load_module | ( | int | reload | ) | [static] |
Definition at line 167 of file cdr_odbc.c.
References ast_cdr_register(), ast_cdr_unregister(), 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_test_flag, ast_true(), ast_variable_browse(), ast_variable_retrieve(), ast_verb, config, CONFIG_DISPOSITIONSTRING, CONFIG_FLAG_FILEUNCHANGED, CONFIG_HRTIME, CONFIG_LOGUNIQUEID, CONFIG_REGISTERED, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, CONFIG_USEGMTIME, LOG_ERROR, LOG_WARNING, odbc_log(), and var.
Referenced by load_module(), and reload().
00168 { 00169 int res = 0; 00170 struct ast_config *cfg; 00171 struct ast_variable *var; 00172 const char *tmp; 00173 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 }; 00174 00175 do { 00176 cfg = ast_config_load(config_file, config_flags); 00177 if (!cfg || cfg == CONFIG_STATUS_FILEINVALID) { 00178 ast_log(LOG_WARNING, "cdr_odbc: Unable to load config for ODBC CDR's: %s\n", config_file); 00179 res = AST_MODULE_LOAD_DECLINE; 00180 break; 00181 } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) 00182 break; 00183 00184 var = ast_variable_browse(cfg, "global"); 00185 if (!var) { 00186 /* nothing configured */ 00187 break; 00188 } 00189 00190 if ((tmp = ast_variable_retrieve(cfg, "global", "dsn")) == NULL) { 00191 ast_log(LOG_WARNING, "cdr_odbc: dsn not specified. Assuming asteriskdb\n"); 00192 tmp = "asteriskdb"; 00193 } 00194 if (dsn) 00195 ast_free(dsn); 00196 dsn = ast_strdup(tmp); 00197 if (dsn == NULL) { 00198 res = -1; 00199 break; 00200 } 00201 00202 if (((tmp = ast_variable_retrieve(cfg, "global", "dispositionstring"))) && ast_true(tmp)) 00203 ast_set_flag(&config, CONFIG_DISPOSITIONSTRING); 00204 else 00205 ast_clear_flag(&config, CONFIG_DISPOSITIONSTRING); 00206 00207 if (((tmp = ast_variable_retrieve(cfg, "global", "loguniqueid"))) && ast_true(tmp)) { 00208 ast_set_flag(&config, CONFIG_LOGUNIQUEID); 00209 ast_debug(1, "cdr_odbc: Logging uniqueid\n"); 00210 } else { 00211 ast_clear_flag(&config, CONFIG_LOGUNIQUEID); 00212 ast_debug(1, "cdr_odbc: Not logging uniqueid\n"); 00213 } 00214 00215 if (((tmp = ast_variable_retrieve(cfg, "global", "usegmtime"))) && ast_true(tmp)) { 00216 ast_set_flag(&config, CONFIG_USEGMTIME); 00217 ast_debug(1, "cdr_odbc: Logging in GMT\n"); 00218 } else { 00219 ast_clear_flag(&config, CONFIG_USEGMTIME); 00220 ast_debug(1, "cdr_odbc: Logging in local time\n"); 00221 } 00222 00223 if (((tmp = ast_variable_retrieve(cfg, "global", "hrtime"))) && ast_true(tmp)) { 00224 ast_set_flag(&config, CONFIG_HRTIME); 00225 ast_debug(1, "cdr_odbc: Logging billsec and duration fields as floats\n"); 00226 } else { 00227 ast_clear_flag(&config, CONFIG_HRTIME); 00228 ast_debug(1, "cdr_odbc: Logging billsec and duration fields as integers\n"); 00229 } 00230 00231 if ((tmp = ast_variable_retrieve(cfg, "global", "table")) == NULL) { 00232 ast_log(LOG_WARNING, "cdr_odbc: table not specified. Assuming cdr\n"); 00233 tmp = "cdr"; 00234 } 00235 if (table) 00236 ast_free(table); 00237 table = ast_strdup(tmp); 00238 if (table == NULL) { 00239 res = -1; 00240 break; 00241 } 00242 00243 ast_verb(3, "cdr_odbc: dsn is %s\n", dsn); 00244 ast_verb(3, "cdr_odbc: table is %s\n", table); 00245 00246 if (!ast_test_flag(&config, CONFIG_REGISTERED)) { 00247 res = ast_cdr_register(name, ast_module_info->description, odbc_log); 00248 if (res) { 00249 ast_log(LOG_ERROR, "cdr_odbc: Unable to register ODBC CDR handling\n"); 00250 } else { 00251 ast_set_flag(&config, CONFIG_REGISTERED); 00252 } 00253 } 00254 } while (0); 00255 00256 if (ast_test_flag(&config, CONFIG_REGISTERED) && (!cfg || dsn == NULL || table == NULL)) { 00257 ast_cdr_unregister(name); 00258 ast_clear_flag(&config, CONFIG_REGISTERED); 00259 } 00260 00261 if (cfg && cfg != CONFIG_STATUS_FILEUNCHANGED && cfg != CONFIG_STATUS_FILEINVALID) { 00262 ast_config_destroy(cfg); 00263 } 00264 return res; 00265 }
static int odbc_log | ( | struct ast_cdr * | cdr | ) | [static] |
Definition at line 142 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.
00143 { 00144 struct odbc_obj *obj = ast_odbc_request_obj(dsn, 0); 00145 SQLHSTMT stmt; 00146 00147 if (!obj) { 00148 ast_log(LOG_ERROR, "Unable to retrieve database handle. CDR failed.\n"); 00149 return -1; 00150 } 00151 00152 stmt = ast_odbc_direct_execute(obj, execute_cb, cdr); 00153 if (stmt) { 00154 SQLLEN rows = 0; 00155 00156 SQLRowCount(stmt, &rows); 00157 SQLFreeHandle(SQL_HANDLE_STMT, stmt); 00158 00159 if (rows == 0) 00160 ast_log(LOG_WARNING, "CDR successfully ran, but inserted 0 rows?\n"); 00161 } else 00162 ast_log(LOG_ERROR, "CDR direct execute failed\n"); 00163 ast_odbc_release_obj(obj); 00164 return 0; 00165 }
static int reload | ( | void | ) | [static] |
Definition at line 288 of file cdr_odbc.c.
References odbc_load_module().
00289 { 00290 return odbc_load_module(1); 00291 }
static int unload_module | ( | void | ) | [static] |
Definition at line 272 of file cdr_odbc.c.
References ast_cdr_unregister(), ast_free, and ast_verb.
00273 { 00274 ast_cdr_unregister(name); 00275 00276 if (dsn) { 00277 ast_verb(11, "cdr_odbc: free dsn\n"); 00278 ast_free(dsn); 00279 } 00280 if (table) { 00281 ast_verb(11, "cdr_odbc: free table\n"); 00282 ast_free(table); 00283 } 00284 00285 return 0; 00286 }
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .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 = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CDR_DRIVER, } [static] |
Definition at line 298 of file cdr_odbc.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 298 of file cdr_odbc.c.
Definition at line 60 of file cdr_odbc.c.
const char config_file[] = "cdr_odbc.conf" [static] |
Definition at line 49 of file cdr_odbc.c.
char* dsn = NULL [static] |
Definition at line 50 of file cdr_odbc.c.
Referenced by acf_odbc_read(), acf_odbc_write(), and init_acf_query().
const char name[] = "ODBC" [static] |
Definition at line 48 of file cdr_odbc.c.
char * table = NULL [static] |
Definition at line 50 of file cdr_odbc.c.
Referenced by ast_config_internal_load(), ast_destroy_realtime(), ast_load_realtime_helper(), ast_load_realtime_multientry(), ast_odbc_find_column(), ast_realtime_require_field(), ast_store_realtime(), ast_unload_realtime(), ast_update2_realtime(), ast_update_realtime(), destroy_table(), destroy_table_cache(), find_table(), free_config(), map_s_x(), map_x_s(), read_config_maps(), realtime_common(), reload(), require_pgsql(), tds_load_module(), unload_module(), update2_pgsql(), and update_pgsql().