123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234 |
- /*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2004 - 2005, Holger Schurig
- *
- *
- * Ideas taken from other cdr_*.c files
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
- /*! \file
- *
- * \brief Store CDR records in a SQLite database.
- *
- * \author Holger Schurig <hs4233@mail.mn-solutions.de>
- *
- * See also
- * \arg \ref Config_cdr
- * \arg http://www.sqlite.org/
- *
- * Creates the database and table on-the-fly
- * \ingroup cdr_drivers
- */
- #include <sys/types.h>
- #include <unistd.h>
- #include <string.h>
- #include <stdlib.h>
- #include <sqlite.h>
- #include "asterisk.h"
- ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
- #include "asterisk/channel.h"
- #include "asterisk/module.h"
- #include "asterisk/logger.h"
- #include "asterisk/utils.h"
- #define LOG_UNIQUEID 0
- #define LOG_USERFIELD 0
- /* When you change the DATE_FORMAT, be sure to change the CHAR(19) below to something else */
- #define DATE_FORMAT "%Y-%m-%d %T"
- static char *desc = "SQLite CDR Backend";
- static char *name = "sqlite";
- static sqlite* db = NULL;
- AST_MUTEX_DEFINE_STATIC(sqlite_lock);
- /*! \brief SQL table format */
- static char sql_create_table[] = "CREATE TABLE cdr ("
- " AcctId INTEGER PRIMARY KEY,"
- " clid VARCHAR(80),"
- " src VARCHAR(80),"
- " dst VARCHAR(80),"
- " dcontext VARCHAR(80),"
- " channel VARCHAR(80),"
- " dstchannel VARCHAR(80),"
- " lastapp VARCHAR(80),"
- " lastdata VARCHAR(80),"
- " start CHAR(19),"
- " answer CHAR(19),"
- " end CHAR(19),"
- " duration INTEGER,"
- " billsec INTEGER,"
- " disposition INTEGER,"
- " amaflags INTEGER,"
- " accountcode VARCHAR(20)"
- #if LOG_UNIQUEID
- " ,uniqueid VARCHAR(32)"
- #endif
- #if LOG_USERFIELD
- " ,userfield VARCHAR(255)"
- #endif
- ");";
- static int sqlite_log(struct ast_cdr *cdr)
- {
- int res = 0;
- char *zErr = 0;
- struct tm tm;
- time_t t;
- char startstr[80], answerstr[80], endstr[80];
- int count;
- ast_mutex_lock(&sqlite_lock);
- t = cdr->start.tv_sec;
- localtime_r(&t, &tm);
- strftime(startstr, sizeof(startstr), DATE_FORMAT, &tm);
- t = cdr->answer.tv_sec;
- localtime_r(&t, &tm);
- strftime(answerstr, sizeof(answerstr), DATE_FORMAT, &tm);
- t = cdr->end.tv_sec;
- localtime_r(&t, &tm);
- strftime(endstr, sizeof(endstr), DATE_FORMAT, &tm);
- for(count=0; count<5; count++) {
- res = sqlite_exec_printf(db,
- "INSERT INTO cdr ("
- "clid,src,dst,dcontext,"
- "channel,dstchannel,lastapp,lastdata, "
- "start,answer,end,"
- "duration,billsec,disposition,amaflags, "
- "accountcode"
- # if LOG_UNIQUEID
- ",uniqueid"
- # endif
- # if LOG_USERFIELD
- ",userfield"
- # endif
- ") VALUES ("
- "'%q', '%q', '%q', '%q', "
- "'%q', '%q', '%q', '%q', "
- "'%q', '%q', '%q', "
- "%d, %d, %d, %d, "
- "'%q'"
- # if LOG_UNIQUEID
- ",'%q'"
- # endif
- # if LOG_USERFIELD
- ",'%q'"
- # endif
- ")", NULL, NULL, &zErr,
- cdr->clid, cdr->src, cdr->dst, cdr->dcontext,
- cdr->channel, cdr->dstchannel, cdr->lastapp, cdr->lastdata,
- startstr, answerstr, endstr,
- cdr->duration, cdr->billsec, cdr->disposition, cdr->amaflags,
- cdr->accountcode
- # if LOG_UNIQUEID
- ,cdr->uniqueid
- # endif
- # if LOG_USERFIELD
- ,cdr->userfield
- # endif
- );
- if (res != SQLITE_BUSY && res != SQLITE_LOCKED)
- break;
- usleep(200);
- }
-
- if (zErr) {
- ast_log(LOG_ERROR, "cdr_sqlite: %s\n", zErr);
- free(zErr);
- }
- ast_mutex_unlock(&sqlite_lock);
- return res;
- }
- char *description(void)
- {
- return desc;
- }
- int unload_module(void)
- {
- if (db)
- sqlite_close(db);
- ast_cdr_unregister(name);
- return 0;
- }
- int load_module(void)
- {
- char *zErr;
- char fn[PATH_MAX];
- int res;
- /* is the database there? */
- snprintf(fn, sizeof(fn), "%s/cdr.db", ast_config_AST_LOG_DIR);
- db = sqlite_open(fn, 0660, &zErr);
- if (!db) {
- ast_log(LOG_ERROR, "cdr_sqlite: %s\n", zErr);
- free(zErr);
- return -1;
- }
- /* is the table there? */
- res = sqlite_exec(db, "SELECT COUNT(AcctId) FROM cdr;", NULL, NULL, NULL);
- if (res) {
- res = sqlite_exec(db, sql_create_table, NULL, NULL, &zErr);
- if (res) {
- ast_log(LOG_ERROR, "cdr_sqlite: Unable to create table 'cdr': %s\n", zErr);
- free(zErr);
- goto err;
- }
- /* TODO: here we should probably create an index */
- }
-
- res = ast_cdr_register(name, desc, sqlite_log);
- if (res) {
- ast_log(LOG_ERROR, "Unable to register SQLite CDR handling\n");
- return -1;
- }
- return 0;
- err:
- if (db)
- sqlite_close(db);
- return -1;
- }
- int reload(void)
- {
- return 0;
- }
- int usecount(void)
- {
- return 0;
- }
- char *key()
- {
- return ASTERISK_GPL_KEY;
- }
|