Mon Mar 20 08:20:08 2006

Asterisk developer's documentation


Main Page | Modules | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

cdr_sqlite.c

Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (C) 2004 - 2005, Holger Schurig
00005  *
00006  *
00007  * Ideas taken from other cdr_*.c files
00008  *
00009  * See http://www.asterisk.org for more information about
00010  * the Asterisk project. Please do not directly contact
00011  * any of the maintainers of this project for assistance;
00012  * the project provides a web site, mailing lists and IRC
00013  * channels for your use.
00014  *
00015  * This program is free software, distributed under the terms of
00016  * the GNU General Public License Version 2. See the LICENSE file
00017  * at the top of the source tree.
00018  */
00019 
00020 /*! \file
00021  *
00022  * \brief Store CDR records in a SQLite database.
00023  * 
00024  * \author Holger Schurig <hs4233@mail.mn-solutions.de>
00025  *
00026  * See also
00027  * \arg \ref Config_cdr
00028  * \arg http://www.sqlite.org/
00029  * 
00030  * Creates the database and table on-the-fly
00031  * \ingroup cdr_drivers
00032  */
00033 
00034 #include <sys/types.h>
00035 
00036 #include <unistd.h>
00037 #include <string.h>
00038 #include <stdlib.h>
00039 #include <sqlite.h>
00040 
00041 #include "asterisk.h"
00042 
00043 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 7221 $")
00044 
00045 #include "asterisk/channel.h"
00046 #include "asterisk/module.h"
00047 #include "asterisk/logger.h"
00048 #include "asterisk/utils.h"
00049 
00050 #define LOG_UNIQUEID 0
00051 #define LOG_USERFIELD   0
00052 
00053 /* When you change the DATE_FORMAT, be sure to change the CHAR(19) below to something else */
00054 #define DATE_FORMAT "%Y-%m-%d %T"
00055 
00056 static char *desc = "SQLite CDR Backend";
00057 static char *name = "sqlite";
00058 static sqlite* db = NULL;
00059 
00060 AST_MUTEX_DEFINE_STATIC(sqlite_lock);
00061 
00062 /*! \brief SQL table format */
00063 static char sql_create_table[] = "CREATE TABLE cdr ("
00064 "  AcctId      INTEGER PRIMARY KEY,"
00065 "  clid     VARCHAR(80),"
00066 "  src      VARCHAR(80),"
00067 "  dst      VARCHAR(80),"
00068 "  dcontext VARCHAR(80),"
00069 "  channel     VARCHAR(80),"
00070 "  dstchannel  VARCHAR(80),"
00071 "  lastapp     VARCHAR(80),"
00072 "  lastdata VARCHAR(80),"
00073 "  start    CHAR(19),"
00074 "  answer      CHAR(19),"
00075 "  end      CHAR(19),"
00076 "  duration INTEGER,"
00077 "  billsec     INTEGER,"
00078 "  disposition INTEGER,"
00079 "  amaflags INTEGER,"
00080 "  accountcode VARCHAR(20)"
00081 #if LOG_UNIQUEID
00082 "  ,uniqueid   VARCHAR(32)"
00083 #endif
00084 #if LOG_USERFIELD
00085 "  ,userfield  VARCHAR(255)"
00086 #endif
00087 ");";
00088 
00089 static int sqlite_log(struct ast_cdr *cdr)
00090 {
00091    int res = 0;
00092    char *zErr = 0;
00093    struct tm tm;
00094    time_t t;
00095    char startstr[80], answerstr[80], endstr[80];
00096    int count;
00097 
00098    ast_mutex_lock(&sqlite_lock);
00099 
00100    t = cdr->start.tv_sec;
00101    localtime_r(&t, &tm);
00102    strftime(startstr, sizeof(startstr), DATE_FORMAT, &tm);
00103 
00104    t = cdr->answer.tv_sec;
00105    localtime_r(&t, &tm);
00106    strftime(answerstr, sizeof(answerstr), DATE_FORMAT, &tm);
00107 
00108    t = cdr->end.tv_sec;
00109    localtime_r(&t, &tm);
00110    strftime(endstr, sizeof(endstr), DATE_FORMAT, &tm);
00111 
00112    for(count=0; count<5; count++) {
00113       res = sqlite_exec_printf(db,
00114          "INSERT INTO cdr ("
00115             "clid,src,dst,dcontext,"
00116             "channel,dstchannel,lastapp,lastdata, "
00117             "start,answer,end,"
00118             "duration,billsec,disposition,amaflags, "
00119             "accountcode"
00120 #           if LOG_UNIQUEID
00121             ",uniqueid"
00122 #           endif
00123 #           if LOG_USERFIELD
00124             ",userfield"
00125 #           endif
00126          ") VALUES ("
00127             "'%q', '%q', '%q', '%q', "
00128             "'%q', '%q', '%q', '%q', "
00129             "'%q', '%q', '%q', "
00130             "%d, %d, %d, %d, "
00131             "'%q'"
00132 #           if LOG_UNIQUEID
00133             ",'%q'"
00134 #           endif
00135 #           if LOG_USERFIELD
00136             ",'%q'"
00137 #           endif
00138          ")", NULL, NULL, &zErr,
00139             cdr->clid, cdr->src, cdr->dst, cdr->dcontext,
00140             cdr->channel, cdr->dstchannel, cdr->lastapp, cdr->lastdata,
00141             startstr, answerstr, endstr,
00142             cdr->duration, cdr->billsec, cdr->disposition, cdr->amaflags,
00143             cdr->accountcode
00144 #           if LOG_UNIQUEID
00145             ,cdr->uniqueid
00146 #           endif
00147 #           if LOG_USERFIELD
00148             ,cdr->userfield
00149 #           endif
00150          );
00151       if (res != SQLITE_BUSY && res != SQLITE_LOCKED)
00152          break;
00153       usleep(200);
00154    }
00155    
00156    if (zErr) {
00157       ast_log(LOG_ERROR, "cdr_sqlite: %s\n", zErr);
00158       free(zErr);
00159    }
00160 
00161    ast_mutex_unlock(&sqlite_lock);
00162    return res;
00163 }
00164 
00165 
00166 char *description(void)
00167 {
00168    return desc;
00169 }
00170 
00171 int unload_module(void)
00172 {
00173    if (db)
00174       sqlite_close(db);
00175    ast_cdr_unregister(name);
00176    return 0;
00177 }
00178 
00179 int load_module(void)
00180 {
00181    char *zErr;
00182    char fn[PATH_MAX];
00183    int res;
00184 
00185    /* is the database there? */
00186    snprintf(fn, sizeof(fn), "%s/cdr.db", ast_config_AST_LOG_DIR);
00187    db = sqlite_open(fn, 0660, &zErr);
00188    if (!db) {
00189       ast_log(LOG_ERROR, "cdr_sqlite: %s\n", zErr);
00190       free(zErr);
00191       return -1;
00192    }
00193 
00194    /* is the table there? */
00195    res = sqlite_exec(db, "SELECT COUNT(AcctId) FROM cdr;", NULL, NULL, NULL);
00196    if (res) {
00197       res = sqlite_exec(db, sql_create_table, NULL, NULL, &zErr);
00198       if (res) {
00199          ast_log(LOG_ERROR, "cdr_sqlite: Unable to create table 'cdr': %s\n", zErr);
00200          free(zErr);
00201          goto err;
00202       }
00203 
00204       /* TODO: here we should probably create an index */
00205    }
00206    
00207    res = ast_cdr_register(name, desc, sqlite_log);
00208    if (res) {
00209       ast_log(LOG_ERROR, "Unable to register SQLite CDR handling\n");
00210       return -1;
00211    }
00212    return 0;
00213 
00214 err:
00215    if (db)
00216       sqlite_close(db);
00217    return -1;
00218 }
00219 
00220 int reload(void)
00221 {
00222    return 0;
00223 }
00224 
00225 int usecount(void)
00226 {
00227    return 0;
00228 }
00229 
00230 char *key()
00231 {
00232    return ASTERISK_GPL_KEY;
00233 }

Generated on Mon Mar 20 08:20:08 2006 for Asterisk - the Open Source PBX by  doxygen 1.3.9.1