Asterisk.org: Developer Documentation (28 Oct 2009)

Wed Oct 28 15:48:25 2009

## Asterisk developer's documentation

# cdr_sqlite.c File Reference

Store CDR records in a SQLite database. More...

`#include <sys/types.h>`
`#include <stdio.h>`
`#include <unistd.h>`
`#include <string.h>`
`#include <stdlib.h>`
`#include <sqlite.h>`
`#include "asterisk.h"`
`#include "asterisk/channel.h"`
`#include "asterisk/module.h"`
`#include "asterisk/logger.h"`
`#include "asterisk/utils.h"`

Include dependency graph for cdr_sqlite.c:

Go to the source code of this file.

## Defines

#define | DATE_FORMAT "%Y-%m-%d %T"
#define | LOG_UNIQUEID 0
#define | LOG_USERFIELD 0

## Functions

| AST_MUTEX_DEFINE_STATIC (sqlite_lock)
char * | description (void)
| Provides a description of the module.
char * | key ()
| Returns the ASTERISK_GPL_KEY.
int | load_module (void)
| Initialize the module.
int | reload (void)
| Reload stuff.
static int | sqlite_log (struct ast_cdr *cdr)
int | unload_module (void)
| Cleanup all module structures, sockets, etc.
int | usecount (void)
| Provides a usecount.

## Variables

static sqlite * | db = NULL
static char * | desc = "SQLite CDR Backend"
static char * | name = "sqlite"
static char | sql_create_table []
| SQL table format.

## Detailed Description

Store CDR records in a SQLite database.

Author:
  Holger Schurig <hs4233@mail.mn-solutions.de>

See also

- CDR configuration
- http://www.sqlite.org/

Creates the database and table on-the-fly

Definition in file cdr_sqlite.c.

## Define Documentation

#define DATE_FORMAT "%Y-%m-%d %T"

Definition at line 55 of file cdr_sqlite.c.

#define LOG_UNIQUEID 0

Definition at line 51 of file cdr_sqlite.c.

Referenced by sqlite_log().

#define LOG_USERFIELD 0

Definition at line 52 of file cdr_sqlite.c.

Referenced by sqlite_log().

## Function Documentation

AST_MUTEX_DEFINE_STATIC | ( | sqlite_lock |  | ) |

char* description | ( | void |  | ) |

Provides a description of the module.

Returns:
  a short description of your module

Definition at line 167 of file cdr_sqlite.c.

    00168 {
    00169    return desc;
    00170 }

char* key | ( | void |  | ) |

Returns the ASTERISK_GPL_KEY.

This returns the ASTERISK_GPL_KEY, signifiying that you agree to the terms of the GPL stated in the ASTERISK_GPL_KEY. Your module will not load if it does not return the EXACT message:

     char *key(void) {
             return ASTERISK_GPL_KEY;
     }

Returns:
  ASTERISK_GPL_KEY

Definition at line 231 of file cdr_sqlite.c.

References ASTERISK_GPL_KEY.

    00232 {
    00233    return ASTERISK_GPL_KEY;
    00234 }

int load_module | ( | void |  | ) |

Initialize the module.

This function is called at module load time. Put all code in here that needs to set up your module's hardware, software, registrations, etc.

Returns:
  This function should return 0 on success and non-zero on failure. If the module is not loaded successfully, Asterisk will call its unload_module() function.

Initialize the Agents module. This function is being called by Asterisk when loading the module. Among other thing it registers applications, cli commands and reads the cofiguration file.

Returns:
  int Always 0.

TE STUFF END

Definition at line 180 of file cdr_sqlite.c.

References ast_cdr_register(), ast_config_AST_LOG_DIR, ast_log(), free, LOG_ERROR, and sqlite_log().

    00181 {
    00182    char *zErr;
    00183    char fn[PATH_MAX];
    00184    int res;
    00185
    00186    /* is the database there? */
    00187    snprintf(fn, sizeof(fn), "%s/cdr.db", ast_config_AST_LOG_DIR);
    00188    db = sqlite_open(fn, 0660, &zErr);
    00189    if (!db) {
    00190       ast_log(LOG_ERROR, "cdr_sqlite: %s\n", zErr);
    00191       free(zErr);
    00192       return -1;
    00193    }
    00194
    00195    /* is the table there? */
    00196    res = sqlite_exec(db, "SELECT COUNT(AcctId) FROM cdr;", NULL, NULL, NULL);
    00197    if (res) {
    00198       res = sqlite_exec(db, sql_create_table, NULL, NULL, &zErr);
    00199       if (res) {
    00200          ast_log(LOG_ERROR, "cdr_sqlite: Unable to create table 'cdr': %s\n", zErr);
    00201          free(zErr);
    00202          goto err;
    00203       }
    00204
    00205       /* TODO: here we should probably create an index */
    00206    }
    00207
    00208    res = ast_cdr_register(name, desc, sqlite_log);
    00209    if (res) {
    00210       ast_log(LOG_ERROR, "Unable to register SQLite CDR handling\n");
    00211       return -1;
    00212    }
    00213    return 0;
    00214
    00215 err:
    00216    if (db)
    00217       sqlite_close(db);
    00218    return -1;
    00219 }

int reload | ( | void |  | ) |

Reload stuff.

This function is where any reload routines take place. Re-read config files, change signalling, whatever is appropriate on a reload.

Returns:
  The return value is not used.

Definition at line 221 of file cdr_sqlite.c.

    00222 {
    00223    return 0;
    00224 }

static int sqlite_log | ( | struct ast_cdr * | cdr | ) | `[static]`

Definition at line 90 of file cdr_sqlite.c.

References ast_cdr::accountcode, ast_cdr::amaflags, ast_cdr::answer, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_cdr::billsec, ast_cdr::channel, ast_cdr::clid, DATE_FORMAT, ast_cdr::dcontext, ast_cdr::disposition, ast_cdr::dst, ast_cdr::dstchannel, ast_cdr::duration, ast_cdr::end, free, ast_cdr::lastapp, ast_cdr::lastdata, LOG_ERROR, LOG_UNIQUEID, LOG_USERFIELD, ast_cdr::src, ast_cdr::start, t, ast_cdr::uniqueid, and ast_cdr::userfield.

Referenced by load_module().

    00091 {
    00092    int res = 0;
    00093    char *zErr = 0;
    00094    struct tm tm;
    00095    time_t t;
    00096    char startstr[80], answerstr[80], endstr[80];
    00097    int count;
    00098
    00099    ast_mutex_lock(&sqlite_lock);
    00100
    00101    t = cdr->start.tv_sec;
    00102    localtime_r(&t, &tm);
    00103    strftime(startstr, sizeof(startstr), DATE_FORMAT, &tm);
    00104
    00105    t = cdr->answer.tv_sec;
    00106    localtime_r(&t, &tm);
    00107    strftime(answerstr, sizeof(answerstr), DATE_FORMAT, &tm);
    00108
    00109    t = cdr->end.tv_sec;
    00110    localtime_r(&t, &tm);
    00111    strftime(endstr, sizeof(endstr), DATE_FORMAT, &tm);
    00112
    00113    for(count=0; count<5; count++) {
    00114       res = sqlite_exec_printf(db,
    00115          "INSERT INTO cdr ("
    00116             "clid,src,dst,dcontext,"
    00117             "channel,dstchannel,lastapp,lastdata, "
    00118             "start,answer,end,"
    00119             "duration,billsec,disposition,amaflags, "
    00120             "accountcode"
    00121 #           if LOG_UNIQUEID
    00122             ",uniqueid"
    00123 #           endif
    00124 #           if LOG_USERFIELD
    00125             ",userfield"
    00126 #           endif
    00127          ") VALUES ("
    00128             "'%q', '%q', '%q', '%q', "
    00129             "'%q', '%q', '%q', '%q', "
    00130             "'%q', '%q', '%q', "
    00131             "%d, %d, %d, %d, "
    00132             "'%q'"
    00133 #           if LOG_UNIQUEID
    00134             ",'%q'"
    00135 #           endif
    00136 #           if LOG_USERFIELD
    00137             ",'%q'"
    00138 #           endif
    00139          ")", NULL, NULL, &zErr,
    00140             cdr->clid, cdr->src, cdr->dst, cdr->dcontext,
    00141             cdr->channel, cdr->dstchannel, cdr->lastapp, cdr->lastdata,
    00142             startstr, answerstr, endstr,
    00143             cdr->duration, cdr->billsec, cdr->disposition, cdr->amaflags,
    00144             cdr->accountcode
    00145 #           if LOG_UNIQUEID
    00146             ,cdr->uniqueid
    00147 #           endif
    00148 #           if LOG_USERFIELD
    00149             ,cdr->userfield
    00150 #           endif
    00151          );
    00152       if (res != SQLITE_BUSY && res != SQLITE_LOCKED)
    00153          break;
    00154       usleep(200);
    00155    }
    00156
    00157    if (zErr) {
    00158       ast_log(LOG_ERROR, "cdr_sqlite: %s\n", zErr);
    00159       free(zErr);
    00160    }
    00161
    00162    ast_mutex_unlock(&sqlite_lock);
    00163    return res;
    00164 }

int unload_module | ( | void |  | ) |

Cleanup all module structures, sockets, etc.

This is called at exit. Any registrations and memory allocations need to be unregistered and free'd here. Nothing else will do these for you (until exit).

Returns:
  Zero on success, or non-zero on error.

Definition at line 172 of file cdr_sqlite.c.

References ast_cdr_unregister().

    00173 {
    00174    if (db)
    00175       sqlite_close(db);
    00176    ast_cdr_unregister(name);
    00177    return 0;
    00178 }

int usecount | ( | void |  | ) |

Provides a usecount.

This function will be called by various parts of asterisk. Basically, all it has to do is to return a usecount when called. You will need to maintain your usecount within the module somewhere. The usecount should be how many channels provided by this module are in use.

Returns:
  The module's usecount.

Definition at line 226 of file cdr_sqlite.c.

    00227 {
    00228    return 0;
    00229 }

## Variable Documentation

sqlite* db = NULL`[static]`

Definition at line 59 of file cdr_sqlite.c.

Referenced by ast_config_internal_load(), ast_load_realtime(), ast_load_realtime_multientry(), and ast_update_realtime().

char* desc = "SQLite CDR Backend"`[static]`

Definition at line 57 of file cdr_sqlite.c.

char* name = "sqlite"`[static]`

Definition at line 58 of file cdr_sqlite.c.

char sql_create_table[]`[static]`

SQL table format.

Definition at line 64 of file cdr_sqlite.c.