[asterisk-commits] seanbright: branch seanbright/NoLossCDR-Redux r104063 - in /team/seanbright/N...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Sat Feb 23 12:47:43 CST 2008
Author: seanbright
Date: Sat Feb 23 12:47:42 2008
New Revision: 104063
URL: http://svn.digium.com/view/asterisk?view=rev&rev=104063
Log:
Let's start simple. Just allow each CDR backend to have multiple sinks defined. Right now we just create a default sink and don't allow the CDR modules to add their own... that's next.
Modified:
team/seanbright/NoLossCDR-Redux/include/asterisk/cdr.h
team/seanbright/NoLossCDR-Redux/main/cdr.c
Modified: team/seanbright/NoLossCDR-Redux/include/asterisk/cdr.h
URL: http://svn.digium.com/view/asterisk/team/seanbright/NoLossCDR-Redux/include/asterisk/cdr.h?view=diff&rev=104063&r1=104062&r2=104063
==============================================================================
--- team/seanbright/NoLossCDR-Redux/include/asterisk/cdr.h (original)
+++ team/seanbright/NoLossCDR-Redux/include/asterisk/cdr.h Sat Feb 23 12:47:42 2008
@@ -107,7 +107,8 @@
int ast_cdr_copy_vars(struct ast_cdr *to_cdr, struct ast_cdr *from_cdr);
int ast_cdr_log_unanswered(void);
-typedef int (*ast_cdrbe)(struct ast_cdr *cdr);
+typedef int (*ast_cdr_backend_func)(struct ast_cdr *cdr);
+typedef void (*ast_cdr_backend_cleanup_func)(void *sink_config);
/*! \brief Return TRUE if CDR subsystem is enabled */
int check_cdr_enabled(void);
@@ -167,7 +168,7 @@
* \retval 0 on success.
* \retval -1 on error
*/
-int ast_cdr_register(const char *name, const char *desc, ast_cdrbe be);
+int ast_cdr_register(const char *name, const char *desc, ast_cdr_backend_func backend_func);
/*!
* \brief Unregister a CDR handling engine
Modified: team/seanbright/NoLossCDR-Redux/main/cdr.c
URL: http://svn.digium.com/view/asterisk/team/seanbright/NoLossCDR-Redux/main/cdr.c?view=diff&rev=104063&r1=104062&r2=104063
==============================================================================
--- team/seanbright/NoLossCDR-Redux/main/cdr.c (original)
+++ team/seanbright/NoLossCDR-Redux/main/cdr.c Sat Feb 23 12:47:42 2008
@@ -54,14 +54,24 @@
int ast_default_amaflags = AST_CDR_DOCUMENTATION;
char ast_default_accountcode[AST_MAX_ACCOUNT_CODE];
-struct ast_cdr_beitem {
+struct ast_cdr_backend_sink {
+ char name[20];
+ void *configuration;
+
+ AST_LIST_ENTRY(ast_cdr_backend_sink) list;
+};
+
+struct ast_cdr_backend {
char name[20];
char desc[80];
- ast_cdrbe be;
- AST_RWLIST_ENTRY(ast_cdr_beitem) list;
+ ast_cdr_backend_func write_cdr;
+ ast_cdr_backend_cleanup_func cleanup;
+
+ AST_LIST_HEAD_NOLOCK(, ast_cdr_backend_sink) sinks;
+ AST_RWLIST_ENTRY(ast_cdr_backend) list;
};
-static AST_RWLIST_HEAD_STATIC(be_list, ast_cdr_beitem);
+static AST_RWLIST_HEAD_STATIC(backends, ast_cdr_backend);
struct ast_cdr_batch_item {
struct ast_cdr *cdr;
@@ -107,59 +117,94 @@
return unanswered;
}
+static void create_default_sink(struct ast_cdr_backend *backend);
+
/*! Register a CDR driver. Each registered CDR driver generates a CDR
\return 0 on success, -1 on failure
*/
-int ast_cdr_register(const char *name, const char *desc, ast_cdrbe be)
-{
- struct ast_cdr_beitem *i = NULL;
+int ast_cdr_register(const char *name, const char *desc, ast_cdr_backend_func backend_func)
+{
+ struct ast_cdr_backend *backend = NULL;
if (!name)
return -1;
- if (!be) {
+ if (!backend_func) {
ast_log(LOG_WARNING, "CDR engine '%s' lacks backend\n", name);
return -1;
}
- AST_RWLIST_WRLOCK(&be_list);
- AST_RWLIST_TRAVERSE(&be_list, i, list) {
- if (!strcasecmp(name, i->name)) {
+ AST_RWLIST_WRLOCK(&backends);
+ AST_RWLIST_TRAVERSE(&backends, backend, list) {
+ if (!strcasecmp(name, backend->name)) {
ast_log(LOG_WARNING, "Already have a CDR backend called '%s'\n", name);
- AST_RWLIST_UNLOCK(&be_list);
+ AST_RWLIST_UNLOCK(&backends);
return -1;
}
}
- if (!(i = ast_calloc(1, sizeof(*i))))
+ if (!(backend = ast_calloc(1, sizeof(*backend)))) {
+ AST_RWLIST_UNLOCK(&backends);
return -1;
-
- i->be = be;
- ast_copy_string(i->name, name, sizeof(i->name));
- ast_copy_string(i->desc, desc, sizeof(i->desc));
-
- AST_RWLIST_INSERT_HEAD(&be_list, i, list);
- AST_RWLIST_UNLOCK(&be_list);
+ }
+
+ backend->write_cdr = backend_func;
+ backend->cleanup = NULL;
+
+ ast_copy_string(backend->name, name, sizeof(backend->name));
+ ast_copy_string(backend->desc, desc, sizeof(backend->desc));
+
+ /* Initialize our sink list */
+ AST_LIST_HEAD_INIT_NOLOCK(&backend->sinks);
+
+ /* Create a default sink */
+ create_default_sink(backend);
+
+ AST_RWLIST_INSERT_HEAD(&backends, backend, list);
+ AST_RWLIST_UNLOCK(&backends);
return 0;
+}
+
+static void create_default_sink(struct ast_cdr_backend *backend)
+{
+ struct ast_cdr_backend_sink *sink = NULL;
+
+ sink = ast_calloc(1, sizeof(*sink));
+ if (!sink) {
+ return;
+ }
+
+ ast_copy_string(sink->name, "(default)", sizeof(sink->name));
+
+ AST_LIST_INSERT_TAIL(&backend->sinks, sink, list);
+
+ return;
}
/*! unregister a CDR driver */
void ast_cdr_unregister(const char *name)
{
- struct ast_cdr_beitem *i = NULL;
-
- AST_RWLIST_WRLOCK(&be_list);
- AST_RWLIST_TRAVERSE_SAFE_BEGIN(&be_list, i, list) {
- if (!strcasecmp(name, i->name)) {
+ struct ast_cdr_backend *backend = NULL;
+
+ AST_RWLIST_WRLOCK(&backends);
+ AST_RWLIST_TRAVERSE_SAFE_BEGIN(&backends, backend, list) {
+ if (!strcasecmp(name, backend->name)) {
+ struct ast_cdr_backend_sink *sink = NULL;
+ AST_LIST_TRAVERSE_SAFE_BEGIN(&backend->sinks, sink, list) {
+ AST_RWLIST_REMOVE_CURRENT(list);
+ ast_verb(2, "Unregistered sink '%s' for CDR backend '%s'\n", sink->name, backend->name);
+ ast_free(sink);
+ }
+ AST_LIST_TRAVERSE_SAFE_END;
AST_RWLIST_REMOVE_CURRENT(list);
ast_verb(2, "Unregistered '%s' CDR backend\n", name);
- ast_free(i);
+ ast_free(backend);
break;
}
}
AST_RWLIST_TRAVERSE_SAFE_END;
- AST_RWLIST_UNLOCK(&be_list);
+ AST_RWLIST_UNLOCK(&backends);
}
/*! Duplicate a CDR record
@@ -985,24 +1030,27 @@
static void post_cdr(struct ast_cdr *cdr)
{
- char *chan;
- struct ast_cdr_beitem *i;
+ char *channel;
+ struct ast_cdr_backend *backend;
+ struct ast_cdr_backend_sink *sink;
for ( ; cdr ; cdr = cdr->next) {
- chan = S_OR(cdr->channel, "<unknown>");
+ channel = S_OR(cdr->channel, "<unknown>");
check_post(cdr);
if (ast_tvzero(cdr->end))
- ast_log(LOG_WARNING, "CDR on channel '%s' lacks end\n", chan);
+ ast_log(LOG_WARNING, "CDR on channel '%s' lacks end\n", channel);
if (ast_tvzero(cdr->start))
- ast_log(LOG_WARNING, "CDR on channel '%s' lacks start\n", chan);
+ ast_log(LOG_WARNING, "CDR on channel '%s' lacks start\n", channel);
ast_set_flag(cdr, AST_CDR_FLAG_POSTED);
if (ast_test_flag(cdr, AST_CDR_FLAG_POST_DISABLED))
continue;
- AST_RWLIST_RDLOCK(&be_list);
- AST_RWLIST_TRAVERSE(&be_list, i, list) {
- i->be(cdr);
- }
- AST_RWLIST_UNLOCK(&be_list);
+ AST_RWLIST_RDLOCK(&backends);
+ AST_RWLIST_TRAVERSE(&backends, backend, list) {
+ AST_LIST_TRAVERSE(&backend->sinks, sink, list) {
+ backend->write_cdr(cdr);
+ }
+ }
+ AST_RWLIST_UNLOCK(&backends);
}
}
@@ -1230,9 +1278,9 @@
static char *handle_cli_status(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
- struct ast_cdr_beitem *beitem=NULL;
- int cnt=0;
- long nextbatchtime=0;
+ struct ast_cdr_backend *backend = NULL;
+ int cnt = 0;
+ long nextbatchtime = 0;
switch (cmd) {
case CLI_INIT:
@@ -1264,11 +1312,11 @@
ast_cli(a->fd, "CDR maximum batch time: %d second%s\n", batchtime, ESS(batchtime));
ast_cli(a->fd, "CDR next scheduled batch processing time: %ld second%s\n", nextbatchtime, ESS(nextbatchtime));
}
- AST_RWLIST_RDLOCK(&be_list);
- AST_RWLIST_TRAVERSE(&be_list, beitem, list) {
- ast_cli(a->fd, "CDR registered backend: %s\n", beitem->name);
- }
- AST_RWLIST_UNLOCK(&be_list);
+ AST_RWLIST_RDLOCK(&backends);
+ AST_RWLIST_TRAVERSE(&backends, backend, list) {
+ ast_cli(a->fd, "CDR registered backend: %s\n", backend->name);
+ }
+ AST_RWLIST_UNLOCK(&backends);
}
return CLI_SUCCESS;
More information about the asterisk-commits
mailing list