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