[svn-commits] tilghman: trunk r501 - in /trunk: ./ configs/
SVN commits to the Digium repositories
svn-commits at lists.digium.com
Sun Dec 30 11:15:27 CST 2007
Author: tilghman
Date: Sun Dec 30 11:15:27 2007
New Revision: 501
URL: http://svn.digium.com/view/asterisk-addons?view=rev&rev=501
Log:
Make cdr_addon_mysql work like cdr_adaptive_odbc... dynamic columns
(Closes issue #11642)
Added:
trunk/UPGRADE.txt (with props)
Modified:
trunk/cdr_addon_mysql.c
trunk/configs/cdr_mysql.conf.sample
Added: trunk/UPGRADE.txt
URL: http://svn.digium.com/view/asterisk-addons/trunk/UPGRADE.txt?view=auto&rev=501
==============================================================================
--- trunk/UPGRADE.txt (added)
+++ trunk/UPGRADE.txt Sun Dec 30 11:15:27 2007
@@ -1,0 +1,18 @@
+cdr_addon_mysql
+===============
+ - Module has been completely revamped, with some options in the config file no
+ longer used and an additional new section called [aliases]. Please read the
+ sample config to familiarize yourself with these changes.
+ - Module now permits arbitrary columns to be created and populated, just like
+ cdr_adaptive_odbc, simply by adding the column to the table and defining the
+ corresponding CDR(<var>) variable. Aliases may be used to define
+ relationships between differently-named variables and columns (such as the
+ calldate column and the start CDR variable).
+ - The calldate column, as defined in the sample configuration, uses the start
+ time of the call, as opposed to the old behavior of using the end time.
+ However, you may get the old behavior for calldate, simply by changing the
+ alias to "end => calldate".
+ - Standard columns may also be excluded now, simply by dropping the column
+ name from the table, renaming the column, or aliasing the cdrname from a
+ nonexistent variable (e.g. foo => amaflags).
+
Propchange: trunk/UPGRADE.txt
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: trunk/UPGRADE.txt
------------------------------------------------------------------------------
svn:keywords = Id Date Author Revision
Propchange: trunk/UPGRADE.txt
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: trunk/cdr_addon_mysql.c
URL: http://svn.digium.com/view/asterisk-addons/trunk/cdr_addon_mysql.c?view=diff&rev=501&r1=500&r2=501
==============================================================================
--- trunk/cdr_addon_mysql.c (original)
+++ trunk/cdr_addon_mysql.c Sun Dec 30 11:15:27 2007
@@ -57,10 +57,7 @@
static char *name = "mysql";
static char *config = "cdr_mysql.conf";
-static struct ast_str *hostname = NULL, *dbname = NULL, *dbuser = NULL, *password = NULL, *dbsock = NULL, *dbtable = NULL,
- *calldate_field = NULL, *clid_field = NULL, *src_field = NULL, *dst_field = NULL, *dcontext_field = NULL, *channel_field = NULL,
- *dstchannel_field = NULL, *lastapp_field = NULL, *lastdata_field = NULL, *duration_field = NULL, *billsec_field =NULL,
- *disposition_field = NULL, *amaflags_field = NULL, *accountcode_field = NULL, *userfield_field = NULL, *uniqueid_field = NULL;
+static struct ast_str *hostname = NULL, *dbname = NULL, *dbuser = NULL, *password = NULL, *dbsock = NULL, *dbtable = NULL;
static struct ast_str *ssl_ca = NULL, *ssl_cert = NULL, *ssl_key = NULL;
@@ -69,9 +66,7 @@
static time_t connect_time = 0;
static int records = 0;
static int totalrecords = 0;
-static int userfield = 0;
static int timeout = 0;
-static int loguniqueid = 0;
AST_MUTEX_DEFINE_STATIC(mysql_lock);
@@ -82,7 +77,16 @@
static AST_LIST_HEAD_STATIC(unload_strings, unload_string);
-static MYSQL mysql;
+struct column {
+ char *name;
+ char *cdrname;
+ AST_LIST_ENTRY(column) list;
+};
+
+/* Protected with mysql_lock */
+static AST_LIST_HEAD_NOLOCK_STATIC(columns, column);
+
+static MYSQL mysql = { { NULL }, };
static char *handle_cli_cdr_mysql_status(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
@@ -142,22 +146,20 @@
static int mysql_log(struct ast_cdr *cdr)
{
- struct ast_tm tm;
- char *userfielddata = NULL;
- char sqlcmd[2048], timestr[128];
- char *clid=NULL, *dcontext=NULL, *channel=NULL, *dstchannel=NULL, *lastapp=NULL, *lastdata=NULL, *src=NULL, *dst=NULL, *accountcode=NULL, *tmp;
+ char sqldesc[128];
+ char *sql1 = ast_calloc(1, 4096), *sql2 = ast_calloc(1, 2048);
+ int sql1size = 4096, sql2size = 2048;
int retries = 5;
- char *uniqueid = NULL;
#if MYSQL_VERSION_ID >= 50013
my_bool my_bool_true = 1;
#endif
+ if (!sql1 || !sql2) {
+ ast_log(LOG_ERROR, "Memory error\n");
+ return -1;
+ }
+
ast_mutex_lock(&mysql_lock);
-
- memset(sqlcmd, 0, 2048);
-
- ast_localtime(&cdr->start, &tm, NULL);
- ast_strftime(timestr, sizeof(timestr), DATE_FORMAT, &tm);
db_reconnect:
if ((!connected) && (hostname || dbsock) && dbuser && password && dbname && dbtable ) {
@@ -173,11 +175,10 @@
ast_log(LOG_ERROR, "mysql_options returned (%d) %s\n", mysql_errno(&mysql), mysql_error(&mysql));
}
#endif
- tmp = dbsock ? dbsock->str : NULL;
if (ssl_ca || ssl_cert || ssl_key) {
- mysql_ssl_set (&mysql, ssl_key->str, ssl_cert->str, ssl_ca->str, NULL, NULL);
- }
- if (mysql_real_connect(&mysql, hostname->str, dbuser->str, password->str, dbname->str, dbport, tmp, ssl_ca ? CLIENT_SSL : 0)) {
+ mysql_ssl_set(&mysql, ssl_key ? ssl_key->str : NULL, ssl_cert ? ssl_cert->str : NULL, ssl_ca ? ssl_ca->str : NULL, NULL, NULL);
+ }
+ if (mysql_real_connect(&mysql, hostname->str, dbuser->str, password->str, dbname->str, dbport, dbsock ? dbsock->str : NULL, ssl_ca ? CLIENT_SSL : 0)) {
connected = 1;
connect_time = time(NULL);
records = 0;
@@ -207,62 +208,118 @@
}
}
- /* Maximum space needed would be if all characters needed to be escaped, plus a trailing NULL */
- /* WARNING: This code previously used mysql_real_escape_string, but the use of said function
- requires an active connection to a database. If we are not connected, then this function
- cannot be used. This is a problem since we need to store off the SQL statement into our
- spool file for later restoration.
- So the question is, what's the best way to handle this? This works for now.
- */
- if ((clid = alloca(strlen(cdr->clid) * 2 + 1)) != NULL)
- mysql_escape_string(clid, cdr->clid, strlen(cdr->clid));
- if ((dcontext = alloca(strlen(cdr->dcontext) * 2 + 1)) != NULL)
- mysql_escape_string(dcontext, cdr->dcontext, strlen(cdr->dcontext));
- if ((channel = alloca(strlen(cdr->channel) * 2 + 1)) != NULL)
- mysql_escape_string(channel, cdr->channel, strlen(cdr->channel));
- if ((dstchannel = alloca(strlen(cdr->dstchannel) * 2 + 1)) != NULL)
- mysql_escape_string(dstchannel, cdr->dstchannel, strlen(cdr->dstchannel));
- if ((lastapp = alloca(strlen(cdr->lastapp) * 2 + 1)) != NULL)
- mysql_escape_string(lastapp, cdr->lastapp, strlen(cdr->lastapp));
- if ((lastdata = alloca(strlen(cdr->lastdata) * 2 + 1)) != NULL)
- mysql_escape_string(lastdata, cdr->lastdata, strlen(cdr->lastdata));
- if (loguniqueid && (uniqueid = alloca(strlen(cdr->uniqueid) * 2 + 1)) != NULL)
- mysql_escape_string(uniqueid, cdr->uniqueid, strlen(cdr->uniqueid));
- if (userfield && ((userfielddata = alloca(strlen(cdr->userfield) * 2 + 1)) != NULL))
- mysql_escape_string(userfielddata, cdr->userfield, strlen(cdr->userfield));
- if ((src = alloca(strlen(cdr->src) * 2 + 1)) != NULL)
- mysql_escape_string(src, cdr->src, strlen(cdr->src));
- if ((dst = alloca(strlen(cdr->dst) * 2 + 1)) != NULL)
- mysql_escape_string(dst, cdr->dst, strlen(cdr->dst));
- if ((accountcode = alloca(strlen(cdr->accountcode) * 2 + 1)) != NULL)
- mysql_escape_string(accountcode, cdr->accountcode, strlen(cdr->accountcode));
-
- /* Check for all alloca failures above at once */
- if ((!clid) || (!dcontext) || (!channel) || (!dstchannel) || (!lastapp) || (!lastdata) || (!src) || (!dst) || (!accountcode) || (loguniqueid && !uniqueid) || (userfield && !userfielddata)) {
- ast_log(LOG_ERROR, "Out of memory error (insert fails)\n");
- ast_mutex_unlock(&mysql_lock);
- return -1;
- }
-
if (connected) {
+ MYSQL_ROW row;
+ MYSQL_RES *result;
+ int column_count = 0;
+
+ snprintf(sql1, sql1size, "INSERT INTO %s (", dbtable ? dbtable->str : "cdr");
+ strcpy(sql2, ") VALUES ('");
+
+ /* Get table description */
+ snprintf(sqldesc, sizeof(sqldesc), "DESC %s", dbtable ? dbtable->str : "cdr");
+ if (mysql_query(&mysql, sqldesc)) {
+ ast_log(LOG_ERROR, "Unable to query table description!!\n");
+ mysql_close(&mysql);
+ connected = 0;
+ goto log_exit;
+ }
+
+ if (!(result = mysql_store_result(&mysql))) {
+ ast_log(LOG_ERROR, "Unable to query table description!!\n");
+ mysql_close(&mysql);
+ connected = 0;
+ goto log_exit;
+ }
+
+ while ((row = mysql_fetch_row(result))) {
+ struct column *entry;
+ char *cdrname;
+ char workspace[2048], *value = NULL, *ptr;
+ int sql2len;
+
+ ast_debug(1, "Got a field '%s' of type '%s'\n", row[0], row[1]);
+ /* Check for an alias */
+ AST_LIST_TRAVERSE(&columns, entry, list) {
+ /* This would probably be better off as a hash */
+ if (!strcasecmp(entry->name, row[0]))
+ break;
+ }
+
+ cdrname = entry ? entry->cdrname : row[0];
+
+ /* Construct SQL */
+ if (column_count++) {
+ strcat(sql1, ",");
+ strcat(sql2, "','");
+ }
+
+ if (strlen(sql1) + 2 + strlen(row[0]) > sql1size) {
+ char *tmp = ast_realloc(sql1, sql1size * 2);
+ if (!tmp)
+ goto log_exit;
+ sql1size *= 2;
+ sql1 = tmp;
+ }
+ strcat(sql1, row[0]);
+
+ /* Need the type and value to determine if we want the raw value or not */
+ if ((!strcmp(cdrname, "start") ||
+ !strcmp(cdrname, "answer") ||
+ !strcmp(cdrname, "end") ||
+ !strcmp(cdrname, "disposition") ||
+ !strcmp(cdrname, "amaflags")) &&
+ (strstr(row[1], "int") ||
+ strstr(row[1], "dec") ||
+ strstr(row[1], "float") ||
+ strstr(row[1], "double") ||
+ strstr(row[1], "real") ||
+ strstr(row[1], "numeric") ||
+ strstr(row[1], "fixed")))
+ ast_cdr_getvar(cdr, cdrname, &value, workspace, sizeof(workspace), 0, 1);
+ else
+ ast_cdr_getvar(cdr, cdrname, &value, workspace, sizeof(workspace), 0, 0);
+
+ if (strlen(sql2) + (value ? strlen(value) * 2 : 0) + 4 > sql2size) {
+ char *tmp = ast_realloc(sql2, sql2size * 2);
+ if (!tmp)
+ goto log_exit;
+ sql2size *= 2;
+ sql2 = tmp;
+ }
+ if (value) {
+ /*!\note We're manually escaping here, to ensure that we know exactly
+ * how much space is used. Since we only accept ASCII strings at this
+ * point in time, there is no danger in this simplistic escape method,
+ * but I wouldn't recommend this technique for other databases or if
+ * we convert to an internal representation of UTF-8 sometime in the
+ * future.
+ */
+ sql2len = strlen(sql2);
+ for (ptr = value; *ptr; ptr++) {
+ if (*ptr == '\\' || *ptr == '\'')
+ sql2[sql2len++] = '\\';
+ sql2[sql2len++] = *ptr;
+ }
+ sql2[sql2len] = '\0';
+ }
+ }
+ mysql_free_result(result);
+
ast_debug(1, "Inserting a CDR record.\n");
-
- if (userfield && userfielddata) {
- if (loguniqueid)
- snprintf(sqlcmd, sizeof(sqlcmd), "INSERT INTO %s (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s) VALUES ('%s','%s','%s','%s','%s', '%s','%s','%s','%s',%ld,%ld,'%s',%ld,'%s','%s','%s')", dbtable->str, calldate_field->str, clid_field->str, src_field->str, dst_field->str, dcontext_field->str, channel_field->str, dstchannel_field->str, lastapp_field->str, lastdata_field->str, duration_field->str, billsec_field->str, disposition_field->str, amaflags_field->str, accountcode_field->str, uniqueid_field->str, userfield_field->str, timestr, clid, src, dst, dcontext, channel, dstchannel, lastapp, lastdata, cdr->duration, cdr->billsec, ast_cdr_disp2str(cdr->disposition), cdr->amaflags, accountcode, uniqueid, userfielddata);
- else
- snprintf(sqlcmd, sizeof(sqlcmd), "INSERT INTO %s (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s) VALUES ('%s','%s','%s','%s','%s', '%s','%s','%s','%s',%ld,%ld,'%s',%ld,'%s','%s')", dbtable->str, calldate_field->str, clid_field->str, src_field->str, dst_field->str, dcontext_field->str, channel_field->str, dstchannel_field->str, lastapp_field->str, lastdata_field->str, duration_field->str, billsec_field->str, disposition_field->str, amaflags_field->str, accountcode_field->str, userfield_field->str, timestr, clid, src, dst, dcontext, channel, dstchannel, lastapp, lastdata, cdr->duration, cdr->billsec, ast_cdr_disp2str(cdr->disposition), cdr->amaflags, accountcode, userfielddata);
- } else {
- if (loguniqueid)
- snprintf(sqlcmd, sizeof(sqlcmd), "INSERT INTO %s (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s) VALUES ('%s','%s','%s','%s','%s', '%s','%s','%s','%s',%ld,%ld,'%s',%ld,'%s','%s')", dbtable->str, calldate_field->str, clid_field->str, src_field->str, dst_field->str, dcontext_field->str, channel_field->str, dstchannel_field->str, lastapp_field->str, lastdata_field->str, duration_field->str, billsec_field->str, disposition_field->str, amaflags_field->str, accountcode_field->str, uniqueid_field->str, timestr, clid, src, dst, dcontext,channel, dstchannel, lastapp, lastdata, cdr->duration, cdr->billsec, ast_cdr_disp2str(cdr->disposition), cdr->amaflags, accountcode, uniqueid);
- else
- snprintf(sqlcmd, sizeof(sqlcmd), "INSERT INTO %s (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s) VALUES ('%s','%s','%s','%s','%s', '%s','%s','%s','%s',%ld,%ld,'%s',%ld,'%s')", dbtable->str, calldate_field->str, clid_field->str, src_field->str, dst_field->str, dcontext_field->str, channel_field->str, dstchannel_field->str, lastapp_field->str, lastdata_field->str, duration_field->str, billsec_field->str, disposition_field->str, amaflags_field->str, accountcode_field->str, timestr, clid, src, dst, dcontext, channel, dstchannel, lastapp, lastdata, cdr->duration, cdr->billsec, ast_cdr_disp2str(cdr->disposition), cdr->amaflags, accountcode);
- }
-
- ast_debug(1, "SQL command as follows: %s\n", sqlcmd);
-
- if (mysql_real_query(&mysql, sqlcmd, strlen(sqlcmd))) {
- ast_log(LOG_ERROR, "Failed to insert into database: (%d) %s", mysql_errno(&mysql), mysql_error(&mysql));
+ if (strlen(sql1) + 3 + strlen(sql2) > sql1size) {
+ char *tmp = ast_realloc(sql1, strlen(sql1) + 3 + strlen(sql2));
+ if (!tmp)
+ goto log_exit;
+ sql1 = tmp;
+ }
+ strcat(sql1, sql2);
+ strcat(sql1, "')");
+
+ ast_debug(1, "SQL command as follows: %s\n", sql1);
+
+ if (mysql_real_query(&mysql, sql1, strlen(sql1))) {
+ ast_log(LOG_ERROR, "Failed to insert into database: (%d) %s\n", mysql_errno(&mysql), mysql_error(&mysql));
mysql_close(&mysql);
connected = 0;
} else {
@@ -270,6 +327,9 @@
totalrecords++;
}
}
+log_exit:
+ ast_free(sql1);
+ ast_free(sql2);
ast_mutex_unlock(&mysql_lock);
return 0;
}
@@ -277,6 +337,7 @@
static int my_unload_module(void)
{
struct unload_string *us;
+ struct column *entry;
ast_cli_unregister_multiple(cdr_mysql_status_cli, sizeof(cdr_mysql_status_cli) / sizeof(struct ast_cli_entry));
@@ -292,7 +353,10 @@
ast_free(us);
}
AST_LIST_UNLOCK(&unload_strings);
-
+
+ while ((entry = AST_LIST_REMOVE_HEAD(&columns, list)))
+ ast_free(entry);
+
dbport = 0;
ast_cdr_unregister(name);
@@ -337,23 +401,13 @@
return 0;
}
-static int my_load_config_bool(struct ast_config *cfg, const char *category, const char *variable, int *field, int def)
-{
- const char *tmp;
-
- tmp = ast_variable_retrieve(cfg, category, variable);
-
- *field = tmp ? ast_true(tmp) : def;
-
- return 0;
-}
-
static int my_load_module(int reload)
{
int res;
struct ast_config *cfg;
struct ast_variable *var;
struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
+ struct column *entry;
char *temp;
#if MYSQL_VERSION_ID >= 50013
my_bool my_bool_true = 1;
@@ -390,31 +444,27 @@
res |= my_load_config_number(cfg, "global", "port", &dbport, 0);
res |= my_load_config_number(cfg, "global", "timeout", &timeout, 0);
- res |= my_load_config_number(cfg, "global", "userfield", &userfield, 0);
-
- res |= my_load_config_bool(cfg, "global", "loguniqueid", &loguniqueid, 0);
-
- res |= my_load_config_string(cfg, "global", "calldate_field", &calldate_field, "calldate");
- res |= my_load_config_string(cfg, "global", "clid_field", &clid_field, "clid");
- res |= my_load_config_string(cfg, "global", "src_field", &src_field, "src");
-
- res |= my_load_config_string(cfg, "global", "dst_field", &dst_field, "dst");
- res |= my_load_config_string(cfg, "global", "dcontext_field", &dcontext_field, "dcontext");
- res |= my_load_config_string(cfg, "global", "channel_field", &channel_field, "channel");
- res |= my_load_config_string(cfg, "global", "dstchannel_field", &dstchannel_field, "dstchannel");
- res |= my_load_config_string(cfg, "global", "lastapp_field", &lastapp_field, "lastapp");
- res |= my_load_config_string(cfg, "global", "lastdata_field", &lastdata_field, "lastdata");
- res |= my_load_config_string(cfg, "global", "duration_field", &duration_field, "duration");
- res |= my_load_config_string(cfg, "global", "billsec_field", &billsec_field, "billsec");
- res |= my_load_config_string(cfg, "global", "disposition_field", &disposition_field, "disposition");
- res |= my_load_config_string(cfg, "global", "amaflags_field", &amaflags_field, "amaflags");
- res |= my_load_config_string(cfg, "global", "accountcode_field", &accountcode_field, "accountcode");
- res |= my_load_config_string(cfg, "global", "userfield_field", &userfield_field, "userfield");
- res += my_load_config_string(cfg, "global", "uniqueid_field", &uniqueid_field, "uniqueid");
if (res < 0)
return AST_MODULE_LOAD_FAILURE;
-
+
+ /* Check for any aliases */
+ while ((entry = AST_LIST_REMOVE_HEAD(&columns, list)))
+ ast_free(entry);
+
+ for (var = ast_variable_browse(cfg, "aliases"); var; var = var->next) {
+ struct column *entry = ast_calloc(1, sizeof(*entry) + strlen(var->name) + 1 + strlen(var->value) + 1);
+ if (!entry)
+ continue;
+ entry->cdrname = (char *)entry + sizeof(*entry);
+ entry->name = (char *)entry + sizeof(*entry) + strlen(var->name) + 1;
+ strcpy(entry->cdrname, var->name);
+ strcpy(entry->name, var->value);
+
+ AST_LIST_INSERT_TAIL(&columns, entry, list);
+ ast_log(LOG_NOTICE, "Found an alias from CDR variable %s to DB column %s\n", entry->cdrname, entry->name);
+ }
+
ast_config_destroy(cfg);
ast_debug(1, "Got hostname of %s\n", hostname->str);
@@ -425,22 +475,6 @@
ast_debug(1, "Got user of %s\n", dbuser->str);
ast_debug(1, "Got dbname of %s\n", dbname->str);
ast_debug(1, "Got password of %s\n", password->str);
-
- ast_debug(1, "Got calldate field of %s\n", calldate_field->str);
- ast_debug(1, "Got clid field of %s\n", clid_field->str);
- ast_debug(1, "Got src field of %s\n", src_field->str);
- ast_debug(1, "Got dst field of %s\n", dst_field->str);
- ast_debug(1, "Got dcontext field of %s\n", dcontext_field->str);
- ast_debug(1, "Got channel field of %s\n", channel_field->str);
- ast_debug(1, "Got dstchannel field of %s\n", dstchannel_field->str);
- ast_debug(1, "Got lastapp field of %s\n", lastapp_field->str);
- ast_debug(1, "Got lastdata field of %s\n", lastdata_field->str);
- ast_debug(1, "Got duration field of %s\n", duration_field->str);
- ast_debug(1, "Got billsec field of %s\n", billsec_field->str);
- ast_debug(1, "Got amaflags field of %s\n", amaflags_field->str);
- ast_debug(1, "Got accountcode field of %s\n", accountcode_field->str);
- ast_debug(1, "Got userfield field of %s\n", userfield_field->str);
- ast_debug(1, "Got uniqueid field of %s\n", uniqueid_field->str);
mysql_init(&mysql);
Modified: trunk/configs/cdr_mysql.conf.sample
URL: http://svn.digium.com/view/asterisk-addons/trunk/configs/cdr_mysql.conf.sample?view=diff&rev=501&r1=500&r2=501
==============================================================================
--- trunk/configs/cdr_mysql.conf.sample (original)
+++ trunk/configs/cdr_mysql.conf.sample Sun Dec 30 11:15:27 2007
@@ -18,30 +18,28 @@
;user=asteriskcdruser
;port=3306
;sock=/tmp/mysql.sock
-;userfield=1
-;
-;loguniqueid=no ; Set to "yes" to enable logging the channel uniqueid
-;
-; You may also configure the field names used in the CDR table.
-;
-;calldate_field=calldate
-;clid_field=clid
-;src_field=src
-;dst_field=dst
-;dcontext_field=dcontext
-;channel_field=channel
-;dstchannel_field=dstchannel
-;lastapp_field=lastapp
-;lastdata_field=lastdata
-;duration_field=duration
-;billsec_field=billsec
-;disposition_field=disposition
-;amaflags_field=amaflags
-;accountcode_field=accountcode
-;userfield_field=userfield
-;uniqueid_field=uniqueid
;
; ssl connections (optional)
;ssl_ca=<path to CA cert>
;ssl_cert=<path to cert>
;ssl_key=<path to keyfile>
+;
+; You may also configure the field names used in the CDR table.
+;
+[aliases]
+start=calldate
+callerid=clid
+;src=src
+;dst=dst
+;dcontext=dcontext
+;channel=channel
+;dstchannel=dstchannel
+;lastapp=lastapp
+;lastdata=lastdata
+;duration=duration
+;billsec=billsec
+;disposition=disposition
+;amaflags=amaflags
+;accountcode=accountcode
+;userfield=userfield
+;uniqueid=uniqueid
More information about the svn-commits
mailing list