123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253 |
- /*
- * 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>
- * SQLite http://www.sqlite.org/
- *
- * See also
- * \arg \ref Config_cdr
- * \arg http://www.sqlite.org/
- *
- * Creates the database and table on-the-fly
- * \ingroup cdr_drivers
- *
- * \note This module has been marked deprecated in favor for cdr_sqlite3_custom
- */
- /*** MODULEINFO
- <depend>sqlite</depend>
- <defaultenabled>no</defaultenabled>
- <support_level>deprecated</support_level>
- <replacement>sqlite3_custom</replacement>
- ***/
- #include "asterisk.h"
- ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
- #include <sqlite.h>
- #include "asterisk/channel.h"
- #include "asterisk/module.h"
- #include "asterisk/utils.h"
- #include "asterisk/paths.h"
- #define LOG_UNIQUEID 0
- #define LOG_USERFIELD 0
- #define LOG_HRTIME 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 const char name[] = "sqlite";
- static sqlite* db = NULL;
- AST_MUTEX_DEFINE_STATIC(sqlite_lock);
- /*! \brief SQL table format */
- static const 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),"
- #if LOG_HRTIME
- " duration FLOAT,"
- " billsec FLOAT,"
- #else
- " duration INTEGER,"
- " billsec INTEGER,"
- #endif
- " disposition INTEGER,"
- " amaflags INTEGER,"
- " accountcode VARCHAR(20)"
- #if LOG_UNIQUEID
- " ,uniqueid VARCHAR(32)"
- #endif
- #if LOG_USERFIELD
- " ,userfield VARCHAR(255)"
- #endif
- ");";
- static void format_date(char *buffer, size_t length, struct timeval *when)
- {
- struct ast_tm tm;
- ast_localtime(when, &tm, NULL);
- ast_strftime(buffer, length, DATE_FORMAT, &tm);
- }
- static int sqlite_log(struct ast_cdr *cdr)
- {
- int res = 0;
- char *zErr = 0;
- char startstr[80], answerstr[80], endstr[80];
- int count;
- #if LOG_HRTIME
- double hrbillsec = 0.0;
- double hrduration;
- #endif
- ast_mutex_lock(&sqlite_lock);
- format_date(startstr, sizeof(startstr), &cdr->start);
- format_date(answerstr, sizeof(answerstr), &cdr->answer);
- format_date(endstr, sizeof(endstr), &cdr->end);
- #if LOG_HRTIME
- if (!ast_tvzero(cdr->answer)) {
- hrbillsec = (double) ast_tvdiff_us(cdr->end, cdr->answer) / 1000000.0;
- }
- hrduration = (double) ast_tvdiff_us(cdr->end, cdr->start) / 1000000.0;
- #endif
- 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', "
- #if LOG_HRTIME
- "%f, %f, %d, %d, "
- #else
- "%d, %d, %d, %d, "
- #endif
- "'%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,
- #if LOG_HRTIME
- hrduration, hrbillsec, cdr->disposition, cdr->amaflags,
- #else
- cdr->duration, cdr->billsec, cdr->disposition, cdr->amaflags,
- #endif
- 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);
- ast_free(zErr);
- }
- ast_mutex_unlock(&sqlite_lock);
- return res;
- }
- static int unload_module(void)
- {
- if (ast_cdr_unregister(name)) {
- return -1;
- }
- if (db) {
- sqlite_close(db);
- }
- return 0;
- }
- static int load_module(void)
- {
- char *zErr;
- char fn[PATH_MAX];
- int res;
- ast_log(LOG_NOTICE, "This module has been marked deprecated in favor of "
- "using cdr_sqlite3_custom.\n");
- /* is the database there? */
- snprintf(fn, sizeof(fn), "%s/cdr.db", ast_config_AST_LOG_DIR);
- db = sqlite_open(fn, AST_FILE_MODE, &zErr);
- if (!db) {
- ast_log(LOG_ERROR, "cdr_sqlite: %s\n", zErr);
- ast_free(zErr);
- return AST_MODULE_LOAD_DECLINE;
- }
- /* 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);
- ast_free(zErr);
- goto err;
- }
- /* TODO: here we should probably create an index */
- }
- res = ast_cdr_register(name, ast_module_info->description, sqlite_log);
- if (res) {
- ast_log(LOG_ERROR, "Unable to register SQLite CDR handling\n");
- return AST_MODULE_LOAD_DECLINE;
- }
- return AST_MODULE_LOAD_SUCCESS;
- err:
- if (db)
- sqlite_close(db);
- return AST_MODULE_LOAD_DECLINE;
- }
- AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "SQLite CDR Backend",
- .support_level = AST_MODULE_SUPPORT_DEPRECATED,
- .load = load_module,
- .unload = unload_module,
- .load_pri = AST_MODPRI_CDR_DRIVER,
- );
|