51#define DATE_FORMAT "%Y-%m-%d %T"
53static const char name[] =
"ODBC";
72 char sqlcmd[2048] =
"", timestr[128], new_columns[120] =
"", new_values[7] =
"";
81 snprintf(new_columns,
sizeof(new_columns),
"%s",
",peeraccount,linkedid,sequence");
82 snprintf(new_values,
sizeof(new_values),
"%s",
",?,?,?");
86 snprintf(sqlcmd,
sizeof(sqlcmd),
"INSERT INTO %s "
87 "(calldate,clid,src,dst,dcontext,channel,dstchannel,lastapp,"
88 "lastdata,duration,billsec,disposition,amaflags,accountcode,uniqueid,userfield%s) "
89 "VALUES ({ts '%s'},?,?,?,?,?,?,?,?,?,?,?,?,?,?,?%s)",
table, new_columns, timestr, new_values);
91 snprintf(sqlcmd,
sizeof(sqlcmd),
"INSERT INTO %s "
92 "(calldate,clid,src,dst,dcontext,channel,dstchannel,lastapp,lastdata,"
93 "duration,billsec,disposition,amaflags,accountcode%s) "
94 "VALUES ({ts '%s'},?,?,?,?,?,?,?,?,?,?,?,?,?%s)",
table, new_columns, timestr, new_values);
97 ODBC_res = SQLAllocHandle(SQL_HANDLE_STMT, obj->
con, &stmt);
99 if ((ODBC_res != SQL_SUCCESS) && (ODBC_res != SQL_SUCCESS_WITH_INFO)) {
101 SQLFreeHandle(SQL_HANDLE_STMT, stmt);
105 SQLBindParameter(stmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR,
sizeof(cdr->
clid), 0, cdr->
clid, 0,
NULL);
106 SQLBindParameter(stmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR,
sizeof(cdr->
src), 0, cdr->
src, 0,
NULL);
107 SQLBindParameter(stmt, 3, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR,
sizeof(cdr->
dst), 0, cdr->
dst, 0,
NULL);
108 SQLBindParameter(stmt, 4, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR,
sizeof(cdr->
dcontext), 0, cdr->
dcontext, 0,
NULL);
109 SQLBindParameter(stmt, 5, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR,
sizeof(cdr->
channel), 0, cdr->
channel, 0,
NULL);
110 SQLBindParameter(stmt, 6, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR,
sizeof(cdr->
dstchannel), 0, cdr->
dstchannel, 0,
NULL);
111 SQLBindParameter(stmt, 7, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR,
sizeof(cdr->
lastapp), 0, cdr->
lastapp, 0,
NULL);
112 SQLBindParameter(stmt, 8, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR,
sizeof(cdr->
lastdata), 0, cdr->
lastdata, 0,
NULL);
115 double hrbillsec = 0.0;
123 SQLBindParameter(stmt, 9, SQL_PARAM_INPUT, SQL_C_DOUBLE, SQL_FLOAT, 0, 0, &hrduration, 0,
NULL);
124 SQLBindParameter(stmt, 10, SQL_PARAM_INPUT, SQL_C_DOUBLE, SQL_FLOAT, 0, 0, &hrbillsec, 0,
NULL);
126 SQLBindParameter(stmt, 9, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &cdr->
duration, 0,
NULL);
127 SQLBindParameter(stmt, 10, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &cdr->
billsec, 0,
NULL);
133 SQLBindParameter(stmt, 11, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(disposition) + 1, 0, disposition, 0,
NULL);
135 SQLBindParameter(stmt, 11, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &cdr->
disposition, 0,
NULL);
137 SQLBindParameter(stmt, 12, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &cdr->
amaflags, 0,
NULL);
142 SQLBindParameter(stmt, 14, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR,
sizeof(cdr->
uniqueid), 0, cdr->
uniqueid, 0,
NULL);
143 SQLBindParameter(stmt, 15, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR,
sizeof(cdr->
userfield), 0, cdr->
userfield, 0,
NULL);
149 SQLBindParameter(stmt, i + 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR,
sizeof(cdr->
linkedid), 0, cdr->
linkedid, 0,
NULL);
150 SQLBindParameter(stmt, i + 2, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &cdr->
sequence, 0,
NULL);
155 if ((ODBC_res != SQL_SUCCESS) && (ODBC_res != SQL_SUCCESS_WITH_INFO)) {
156 ast_log(
LOG_WARNING,
"cdr_odbc: Error in ExecDirect: %d, query is: %s\n", ODBC_res, sqlcmd);
157 SQLFreeHandle(SQL_HANDLE_STMT, stmt);
179 SQLRowCount(stmt, &rows);
180 SQLFreeHandle(SQL_HANDLE_STMT, stmt);
232 ast_debug(1,
"cdr_odbc: Logging uniqueid\n");
235 ast_debug(1,
"cdr_odbc: Not logging uniqueid\n");
240 ast_debug(1,
"cdr_odbc: Logging in GMT\n");
243 ast_debug(1,
"cdr_odbc: Logging in local time\n");
248 ast_debug(1,
"cdr_odbc: Logging billsec and duration fields as floats\n");
251 ast_debug(1,
"cdr_odbc: Logging billsec and duration fields as integers\n");
276 ast_debug(1,
"cdr_odbc: Add new cdr columns\n");
279 ast_debug(1,
"cdr_odbc: Not add new cdr columns\n");
328 .
requires =
"cdr,res_odbc",
Asterisk main include file. File version handling, generic pbx functions.
#define ast_strdup(str)
A wrapper for strdup()
#define ast_strdupa(s)
duplicate a string in memory from the stack
int ast_cdr_backend_unsuspend(const char *name)
Unsuspend a CDR backend.
int ast_cdr_unregister(const char *name)
Unregister a CDR handling engine.
const char * ast_cdr_disp2str(int disposition)
Disposition to a string.
int ast_cdr_register(const char *name, const char *desc, ast_cdrbe be)
Register a CDR handling engine.
int ast_cdr_backend_suspend(const char *name)
Suspend a CDR backend temporarily.
@ CONFIG_DISPOSITIONSTRING
static int odbc_log(struct ast_cdr *cdr)
static const char config_file[]
static int load_module(void)
static int unload_module(void)
static struct ast_flags config
static SQLHSTMT execute_cb(struct odbc_obj *obj, void *data)
static int odbc_load_module(int reload)
General Asterisk PBX channel definitions.
Configuration File Parser.
#define ast_config_load(filename, flags)
Load a config file.
#define CONFIG_STATUS_FILEUNCHANGED
#define CONFIG_STATUS_FILEINVALID
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
const char * ast_variable_retrieve(struct ast_config *config, const char *category, const char *variable)
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category_name)
@ CONFIG_FLAG_FILEUNCHANGED
#define ast_debug(level,...)
Log a DEBUG message.
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
int ast_strftime(char *buf, size_t len, const char *format, const struct ast_tm *tm)
Special version of strftime(3) that handles fractions of a second. Takes the same arguments as strfti...
Asterisk module definitions.
#define AST_MODULE_INFO(keystr, flags_to_set, desc, fields...)
@ AST_MODULE_SUPPORT_EXTENDED
#define ASTERISK_GPL_KEY
The text the key() function should return.
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
void ast_odbc_release_obj(struct odbc_obj *obj)
Releases an ODBC object previously allocated by ast_odbc_request_obj()
SQLHSTMT ast_odbc_direct_execute(struct odbc_obj *obj, SQLHSTMT(*exec_cb)(struct odbc_obj *obj, void *data), void *data)
Executes an non prepared statement and returns the resulting statement handle.
SQLRETURN ast_odbc_execute_sql(struct odbc_obj *obj, SQLHSTMT *stmt, const char *sql)
Execute a unprepared SQL query.
#define ast_odbc_request_obj(name, check)
Get a ODBC connection object.
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true"....
Responsible for call detail data.
char dstchannel[AST_MAX_EXTENSION]
char lastdata[AST_MAX_EXTENSION]
char linkedid[AST_MAX_UNIQUEID]
char userfield[AST_MAX_USER_FIELD]
char channel[AST_MAX_EXTENSION]
char peeraccount[AST_MAX_ACCOUNT_CODE]
char src[AST_MAX_EXTENSION]
char dst[AST_MAX_EXTENSION]
char clid[AST_MAX_EXTENSION]
char uniqueid[AST_MAX_UNIQUEID]
char accountcode[AST_MAX_ACCOUNT_CODE]
char lastapp[AST_MAX_EXTENSION]
char dcontext[AST_MAX_EXTENSION]
Structure used to handle boolean flags.
Structure for variables, used for configurations and for channel variables.
int64_t ast_tvdiff_us(struct timeval end, struct timeval start)
Computes the difference (in microseconds) between two struct timeval instances.
int ast_tvzero(const struct timeval t)
Returns true if the argument is 0,0.
#define ast_test_flag(p, flag)
#define ast_clear_flag(p, flag)
#define ast_set_flag(p, flag)