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 #include <sys/types.h>
00035
00036 #include <stdio.h>
00037 #include <unistd.h>
00038 #include <string.h>
00039 #include <stdlib.h>
00040 #include <sqlite.h>
00041
00042 #include "asterisk.h"
00043
00044 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 23898 $")
00045
00046 #include "asterisk/channel.h"
00047 #include "asterisk/module.h"
00048 #include "asterisk/logger.h"
00049 #include "asterisk/utils.h"
00050
00051 #define LOG_UNIQUEID 0
00052 #define LOG_USERFIELD 0
00053
00054
00055 #define DATE_FORMAT "%Y-%m-%d %T"
00056
00057 static char *desc = "SQLite CDR Backend";
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 int sqlite_log(struct ast_cdr *cdr)
00091 {
00092 int res = 0;
00093 char *zErr = 0;
00094 struct tm tm;
00095 time_t t;
00096 char startstr[80], answerstr[80], endstr[80];
00097 int count;
00098
00099 ast_mutex_lock(&sqlite_lock);
00100
00101 t = cdr->start.tv_sec;
00102 localtime_r(&t, &tm);
00103 strftime(startstr, sizeof(startstr), DATE_FORMAT, &tm);
00104
00105 t = cdr->answer.tv_sec;
00106 localtime_r(&t, &tm);
00107 strftime(answerstr, sizeof(answerstr), DATE_FORMAT, &tm);
00108
00109 t = cdr->end.tv_sec;
00110 localtime_r(&t, &tm);
00111 strftime(endstr, sizeof(endstr), DATE_FORMAT, &tm);
00112
00113 for(count=0; count<5; count++) {
00114 res = sqlite_exec_printf(db,
00115 "INSERT INTO cdr ("
00116 "clid,src,dst,dcontext,"
00117 "channel,dstchannel,lastapp,lastdata, "
00118 "start,answer,end,"
00119 "duration,billsec,disposition,amaflags, "
00120 "accountcode"
00121 # if LOG_UNIQUEID
00122 ",uniqueid"
00123 # endif
00124 # if LOG_USERFIELD
00125 ",userfield"
00126 # endif
00127 ") VALUES ("
00128 "'%q', '%q', '%q', '%q', "
00129 "'%q', '%q', '%q', '%q', "
00130 "'%q', '%q', '%q', "
00131 "%d, %d, %d, %d, "
00132 "'%q'"
00133 # if LOG_UNIQUEID
00134 ",'%q'"
00135 # endif
00136 # if LOG_USERFIELD
00137 ",'%q'"
00138 # endif
00139 ")", NULL, NULL, &zErr,
00140 cdr->clid, cdr->src, cdr->dst, cdr->dcontext,
00141 cdr->channel, cdr->dstchannel, cdr->lastapp, cdr->lastdata,
00142 startstr, answerstr, endstr,
00143 cdr->duration, cdr->billsec, cdr->disposition, cdr->amaflags,
00144 cdr->accountcode
00145 # if LOG_UNIQUEID
00146 ,cdr->uniqueid
00147 # endif
00148 # if LOG_USERFIELD
00149 ,cdr->userfield
00150 # endif
00151 );
00152 if (res != SQLITE_BUSY && res != SQLITE_LOCKED)
00153 break;
00154 usleep(200);
00155 }
00156
00157 if (zErr) {
00158 ast_log(LOG_ERROR, "cdr_sqlite: %s\n", zErr);
00159 free(zErr);
00160 }
00161
00162 ast_mutex_unlock(&sqlite_lock);
00163 return res;
00164 }
00165
00166
00167 char *description(void)
00168 {
00169 return desc;
00170 }
00171
00172 int unload_module(void)
00173 {
00174 if (db)
00175 sqlite_close(db);
00176 ast_cdr_unregister(name);
00177 return 0;
00178 }
00179
00180 int load_module(void)
00181 {
00182 char *zErr;
00183 char fn[PATH_MAX];
00184 int res;
00185
00186
00187 snprintf(fn, sizeof(fn), "%s/cdr.db", ast_config_AST_LOG_DIR);
00188 db = sqlite_open(fn, 0660, &zErr);
00189 if (!db) {
00190 ast_log(LOG_ERROR, "cdr_sqlite: %s\n", zErr);
00191 free(zErr);
00192 return -1;
00193 }
00194
00195
00196 res = sqlite_exec(db, "SELECT COUNT(AcctId) FROM cdr;", NULL, NULL, NULL);
00197 if (res) {
00198 res = sqlite_exec(db, sql_create_table, NULL, NULL, &zErr);
00199 if (res) {
00200 ast_log(LOG_ERROR, "cdr_sqlite: Unable to create table 'cdr': %s\n", zErr);
00201 free(zErr);
00202 goto err;
00203 }
00204
00205
00206 }
00207
00208 res = ast_cdr_register(name, desc, sqlite_log);
00209 if (res) {
00210 ast_log(LOG_ERROR, "Unable to register SQLite CDR handling\n");
00211 return -1;
00212 }
00213 return 0;
00214
00215 err:
00216 if (db)
00217 sqlite_close(db);
00218 return -1;
00219 }
00220
00221 int reload(void)
00222 {
00223 return 0;
00224 }
00225
00226 int usecount(void)
00227 {
00228 return 0;
00229 }
00230
00231 char *key()
00232 {
00233 return ASTERISK_GPL_KEY;
00234 }