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: 158072 $")
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 if (db)
00167 sqlite_close(db);
00168 ast_cdr_unregister(name);
00169 return 0;
00170 }
00171
00172 static int load_module(void)
00173 {
00174 char *zErr;
00175 char fn[PATH_MAX];
00176 int res;
00177
00178 ast_log(LOG_WARNING, "This module has been marked deprecated in favor of "
00179 "using cdr_sqlite3_custom. (May be removed after Asterisk 1.6)\n");
00180
00181
00182 snprintf(fn, sizeof(fn), "%s/cdr.db", ast_config_AST_LOG_DIR);
00183 db = sqlite_open(fn, AST_FILE_MODE, &zErr);
00184 if (!db) {
00185 ast_log(LOG_ERROR, "cdr_sqlite: %s\n", zErr);
00186 ast_free(zErr);
00187 return -1;
00188 }
00189
00190
00191 res = sqlite_exec(db, "SELECT COUNT(AcctId) FROM cdr;", NULL, NULL, NULL);
00192 if (res) {
00193 res = sqlite_exec(db, sql_create_table, NULL, NULL, &zErr);
00194 if (res) {
00195 ast_log(LOG_ERROR, "cdr_sqlite: Unable to create table 'cdr': %s\n", zErr);
00196 ast_free(zErr);
00197 goto err;
00198 }
00199
00200
00201 }
00202
00203 res = ast_cdr_register(name, ast_module_info->description, sqlite_log);
00204 if (res) {
00205 ast_log(LOG_ERROR, "Unable to register SQLite CDR handling\n");
00206 return -1;
00207 }
00208 return 0;
00209
00210 err:
00211 if (db)
00212 sqlite_close(db);
00213 return -1;
00214 }
00215
00216 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "SQLite CDR Backend");