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