00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 #include "asterisk.h"
00042
00043 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 300574 $")
00044
00045 #include <sqlite.h>
00046
00047 #include "asterisk/channel.h"
00048 #include "asterisk/module.h"
00049 #include "asterisk/utils.h"
00050 #include "asterisk/paths.h"
00051
00052 #define LOG_UNIQUEID 0
00053 #define LOG_USERFIELD 0
00054
00055
00056 #define DATE_FORMAT "%Y-%m-%d %T"
00057
00058 static char *name = "sqlite";
00059 static sqlite* db = NULL;
00060
00061 AST_MUTEX_DEFINE_STATIC(sqlite_lock);
00062
00063
00064 static char sql_create_table[] = "CREATE TABLE cdr ("
00065 " AcctId INTEGER PRIMARY KEY,"
00066 " clid VARCHAR(80),"
00067 " src VARCHAR(80),"
00068 " dst VARCHAR(80),"
00069 " dcontext VARCHAR(80),"
00070 " channel VARCHAR(80),"
00071 " dstchannel VARCHAR(80),"
00072 " lastapp VARCHAR(80),"
00073 " lastdata VARCHAR(80),"
00074 " start CHAR(19),"
00075 " answer CHAR(19),"
00076 " end CHAR(19),"
00077 " duration INTEGER,"
00078 " billsec INTEGER,"
00079 " disposition INTEGER,"
00080 " amaflags INTEGER,"
00081 " accountcode VARCHAR(20)"
00082 #if LOG_UNIQUEID
00083 " ,uniqueid VARCHAR(32)"
00084 #endif
00085 #if LOG_USERFIELD
00086 " ,userfield VARCHAR(255)"
00087 #endif
00088 ");";
00089
00090 static void format_date(char *buffer, size_t length, struct timeval *when)
00091 {
00092 struct ast_tm tm;
00093
00094 ast_localtime(when, &tm, NULL);
00095 ast_strftime(buffer, length, DATE_FORMAT, &tm);
00096 }
00097
00098 static int sqlite_log(struct ast_cdr *cdr)
00099 {
00100 int res = 0;
00101 char *zErr = 0;
00102 char startstr[80], answerstr[80], endstr[80];
00103 int count;
00104
00105 ast_mutex_lock(&sqlite_lock);
00106
00107 format_date(startstr, sizeof(startstr), &cdr->start);
00108 format_date(answerstr, sizeof(answerstr), &cdr->answer);
00109 format_date(endstr, sizeof(endstr), &cdr->end);
00110
00111 for(count=0; count<5; count++) {
00112 res = sqlite_exec_printf(db,
00113 "INSERT INTO cdr ("
00114 "clid,src,dst,dcontext,"
00115 "channel,dstchannel,lastapp,lastdata, "
00116 "start,answer,end,"
00117 "duration,billsec,disposition,amaflags, "
00118 "accountcode"
00119 # if LOG_UNIQUEID
00120 ",uniqueid"
00121 # endif
00122 # if LOG_USERFIELD
00123 ",userfield"
00124 # endif
00125 ") VALUES ("
00126 "'%q', '%q', '%q', '%q', "
00127 "'%q', '%q', '%q', '%q', "
00128 "'%q', '%q', '%q', "
00129 "%d, %d, %d, %d, "
00130 "'%q'"
00131 # if LOG_UNIQUEID
00132 ",'%q'"
00133 # endif
00134 # if LOG_USERFIELD
00135 ",'%q'"
00136 # endif
00137 ")", NULL, NULL, &zErr,
00138 cdr->clid, cdr->src, cdr->dst, cdr->dcontext,
00139 cdr->channel, cdr->dstchannel, cdr->lastapp, cdr->lastdata,
00140 startstr, answerstr, endstr,
00141 cdr->duration, cdr->billsec, cdr->disposition, cdr->amaflags,
00142 cdr->accountcode
00143 # if LOG_UNIQUEID
00144 ,cdr->uniqueid
00145 # endif
00146 # if LOG_USERFIELD
00147 ,cdr->userfield
00148 # endif
00149 );
00150 if (res != SQLITE_BUSY && res != SQLITE_LOCKED)
00151 break;
00152 usleep(200);
00153 }
00154
00155 if (zErr) {
00156 ast_log(LOG_ERROR, "cdr_sqlite: %s\n", zErr);
00157 ast_free(zErr);
00158 }
00159
00160 ast_mutex_unlock(&sqlite_lock);
00161 return res;
00162 }
00163
00164 static int unload_module(void)
00165 {
00166 ast_cdr_unregister(name);
00167 if (db) {
00168 sqlite_close(db);
00169 }
00170 return 0;
00171 }
00172
00173 static int load_module(void)
00174 {
00175 char *zErr;
00176 char fn[PATH_MAX];
00177 int res;
00178
00179 ast_log(LOG_NOTICE, "This module has been marked deprecated in favor of "
00180 "using cdr_sqlite3_custom.\n");
00181
00182
00183 snprintf(fn, sizeof(fn), "%s/cdr.db", ast_config_AST_LOG_DIR);
00184 db = sqlite_open(fn, AST_FILE_MODE, &zErr);
00185 if (!db) {
00186 ast_log(LOG_ERROR, "cdr_sqlite: %s\n", zErr);
00187 ast_free(zErr);
00188 return -1;
00189 }
00190
00191
00192 res = sqlite_exec(db, "SELECT COUNT(AcctId) FROM cdr;", NULL, NULL, NULL);
00193 if (res) {
00194 res = sqlite_exec(db, sql_create_table, NULL, NULL, &zErr);
00195 if (res) {
00196 ast_log(LOG_ERROR, "cdr_sqlite: Unable to create table 'cdr': %s\n", zErr);
00197 ast_free(zErr);
00198 goto err;
00199 }
00200
00201
00202 }
00203
00204 res = ast_cdr_register(name, ast_module_info->description, sqlite_log);
00205 if (res) {
00206 ast_log(LOG_ERROR, "Unable to register SQLite CDR handling\n");
00207 return -1;
00208 }
00209 return 0;
00210
00211 err:
00212 if (db)
00213 sqlite_close(db);
00214 return -1;
00215 }
00216
00217 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "SQLite CDR Backend");