[svn-commits] seanbright: branch seanbright/NoLossCDR-Redux r104063 - in /team/seanbright/N...

SVN commits to the Digium repositories svn-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 svn-commits mailing list