[asterisk-commits] file: branch file/cdrbatchretry r38289 - in /team/file/cdrbatchretry: ./ cdr/...

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Wed Jul 26 18:58:59 MST 2006


Author: file
Date: Wed Jul 26 20:58:58 2006
New Revision: 38289

URL: http://svn.digium.com/view/asterisk?rev=38289&view=rev
Log:
Expand the CDR core so that a CDR engine can more accurately report back whether it was able to process the record or not. Right now there are 4 return values: SUCCESS, DISCARD, DEFER, and FAILED. SUCCESS means that everything went fine. DISCARD means the engine could not post the record, and never will be able to. DEFER means the engine can post the record but it doesn't want to at this time. FAILED means the engine tried to post the record, failed, and would like to try again later. If either DEFER or FAILED is returned the batch process will continue to try to post the CDR. NOTE: If it must be retried it will not be posted again to engines that have already returned SUCCESS or DISCARD.

Modified:
    team/file/cdrbatchretry/cdr.c
    team/file/cdrbatchretry/cdr/cdr_csv.c
    team/file/cdrbatchretry/cdr/cdr_custom.c
    team/file/cdrbatchretry/cdr/cdr_manager.c
    team/file/cdrbatchretry/cdr/cdr_odbc.c
    team/file/cdrbatchretry/cdr/cdr_pgsql.c
    team/file/cdrbatchretry/cdr/cdr_radius.c
    team/file/cdrbatchretry/cdr/cdr_sqlite.c
    team/file/cdrbatchretry/cdr/cdr_tds.c
    team/file/cdrbatchretry/include/asterisk/cdr.h

Modified: team/file/cdrbatchretry/cdr.c
URL: http://svn.digium.com/view/asterisk/team/file/cdrbatchretry/cdr.c?rev=38289&r1=38288&r2=38289&view=diff
==============================================================================
--- team/file/cdrbatchretry/cdr.c (original)
+++ team/file/cdrbatchretry/cdr.c Wed Jul 26 20:58:58 2006
@@ -59,7 +59,10 @@
 int ast_default_amaflags = AST_CDR_DOCUMENTATION;
 char ast_default_accountcode[AST_MAX_ACCOUNT_CODE] = "";
 
+#define MAX_ENGINES 256
+
 struct ast_cdr_beitem {
+	unsigned int num;
 	char name[20];
 	char desc[80];
 	ast_cdrbe be;
@@ -67,17 +70,16 @@
 };
 
 static AST_LIST_HEAD_STATIC(be_list, ast_cdr_beitem);
+static unsigned int be_num = 0;
 
 struct ast_cdr_batch_item {
 	struct ast_cdr *cdr;
-	struct ast_cdr_batch_item *next;
+	int engine[MAX_ENGINES];
+	AST_LIST_ENTRY(ast_cdr_batch_item) list;
 };
 
-static struct ast_cdr_batch {
-	int size;
-	struct ast_cdr_batch_item *head;
-	struct ast_cdr_batch_item *tail;
-} *batch = NULL;
+static AST_LIST_HEAD_STATIC(batch_list, ast_cdr_batch_item);
+static int batch_list_size = 0;
 
 static struct sched_context *sched;
 static int cdr_sched = -1;
@@ -95,8 +97,6 @@
 static int batchscheduleronly;
 static int batchsafeshutdown;
 
-AST_MUTEX_DEFINE_STATIC(cdr_batch_lock);
-
 /* these are used to wake up the CDR thread when there's work to do */
 AST_MUTEX_DEFINE_STATIC(cdr_pending_lock);
 static ast_cond_t cdr_pending_cond;
@@ -136,6 +136,8 @@
 	ast_copy_string(i->desc, desc, sizeof(i->desc));
 
 	AST_LIST_LOCK(&be_list);
+	i->num = be_num++;
+	ast_log(LOG_NOTICE, "Up to %d\n", be_num);
 	AST_LIST_INSERT_HEAD(&be_list, i, list);
 	AST_LIST_UNLOCK(&be_list);
 
@@ -789,38 +791,63 @@
 	return ret;
 }
 
-/*! \note Don't call without cdr_batch_lock */
-static void reset_batch(void)
-{
-	batch->size = 0;
-	batch->head = NULL;
-	batch->tail = NULL;
-}
-
-/*! \note Don't call without cdr_batch_lock */
-static int init_batch(void)
-{
-	/* This is the single meta-batch used to keep track of all CDRs during the entire life of the program */
-	if (!(batch = ast_malloc(sizeof(*batch))))
-		return -1;
-
-	reset_batch();
-
-	return 0;
-}
-
 static void *do_batch_backend_process(void *data)
 {
-	struct ast_cdr_batch_item *processeditem;
-	struct ast_cdr_batch_item *batchitem = data;
-
-	/* Push each CDR into storage mechanism(s) and free all the memory */
-	while (batchitem) {
-		post_cdr(batchitem->cdr);
-		ast_cdr_free(batchitem->cdr);
-		processeditem = batchitem;
-		batchitem = batchitem->next;
-		free(processeditem);
+	char *chan = NULL;
+	int res = AST_CDR_ENGINE_SUCCESS, defer = 0;
+	struct ast_cdr_batch_item *batch_item = data;
+	struct ast_cdr_beitem *be = NULL;
+	AST_LIST_HEAD_NOLOCK(local_batch_list, ast_cdr_batch_item) local_batch_list;
+
+	if (!batch_item) {
+		return NULL;
+	}
+
+	/* This is sort of cheeky but add it to the head of the list so we can easily iterate through */
+	AST_LIST_HEAD_INIT_NOLOCK(&local_batch_list);
+	AST_LIST_INSERT_TAIL(&local_batch_list, batch_item, list);
+
+	/* Thankfully we don't need to hold the lock on the above since it only exists to us */
+	while ((batch_item = AST_LIST_REMOVE_HEAD(&local_batch_list, list))) {
+		/* Reset defer state to 0 */
+		defer = 0;
+		/* Now we have to process this batched item */
+		chan = S_OR(batch_item->cdr->channel, "<unknown>");
+		/* If this item has not been processed through the regular points before, do so */
+		if (!ast_test_flag(batch_item->cdr, AST_CDR_FLAG_RETRY)) {
+			check_post(batch_item->cdr);
+			if (ast_tvzero(batch_item->cdr->end))
+				ast_log(LOG_WARNING, "CDR on channel '%s' lacks end\n", chan);
+			if (ast_tvzero(batch_item->cdr->start))
+				ast_log(LOG_WARNING, "CDR on channel '%s' lacks start\n", chan);
+			ast_set_flag(batch_item->cdr, AST_CDR_FLAG_RETRY);
+		}
+		/* Hand this off to each backend and check the result */
+		AST_LIST_LOCK(&be_list);
+		AST_LIST_TRAVERSE(&be_list, be, list) {
+			/* Okay, we pass this CDR off to the engine if not already done and check the result */
+			if (!batch_item->engine[be->num]) {
+				res = be->be(batch_item->cdr);
+				if (res == AST_CDR_ENGINE_SUCCESS || res == AST_CDR_ENGINE_DISCARD) {
+					batch_item->engine[be->num] = 1;
+				} else if (res == AST_CDR_ENGINE_DEFER || res == AST_CDR_ENGINE_FAILED) {
+					/* Continue processing through the engines, but rerun this CDR record again */
+					defer = 1;
+				}
+			}
+		}
+		AST_LIST_UNLOCK(&be_list);
+		/* Okay... if we need to defer this entry for another attempt, do so... otherwise drop it */
+		if (defer) {
+			/* Insert it into the regular batch list */
+			AST_LIST_LOCK(&batch_list);
+			AST_LIST_INSERT_HEAD(&batch_list, batch_item, list);
+			AST_LIST_UNLOCK(&batch_list);
+		} else {
+			/* Deallocate this entry... it's gone */
+			ast_cdr_free(batch_item->cdr);
+			free(batch_item);
+		}
 	}
 
 	return NULL;
@@ -828,32 +855,36 @@
 
 void ast_cdr_submit_batch(int shutdown)
 {
-	struct ast_cdr_batch_item *oldbatchitems = NULL;
+	struct ast_cdr_batch_item *batch_item = NULL;
 	pthread_attr_t attr;
 	pthread_t batch_post_thread = AST_PTHREADT_NULL;
 
 	/* if there's no batch, or no CDRs in the batch, then there's nothing to do */
-	if (!batch || !batch->head)
+	AST_LIST_LOCK(&batch_list);
+	if (AST_LIST_EMPTY(&batch_list)) {
+		AST_LIST_UNLOCK(&batch_list);
 		return;
-
-	/* move the old CDRs aside, and prepare a new CDR batch */
-	ast_mutex_lock(&cdr_batch_lock);
-	oldbatchitems = batch->head;
-	reset_batch();
-	ast_mutex_unlock(&cdr_batch_lock);
+	}
+
+	/* Essentially we plop off the head of this list and deal with it */
+	batch_item = AST_LIST_FIRST(&batch_list);
+	/* Now reinitialize the batch list */
+	AST_LIST_HEAD_INIT(&batch_list);
+	batch_list_size = 0;
+	AST_LIST_UNLOCK(&batch_list);
 
 	/* if configured, spawn a new thread to post these CDRs,
 	   also try to save as much as possible if we are shutting down safely */
 	if (batchscheduleronly || shutdown) {
 		if (option_debug)
 			ast_log(LOG_DEBUG, "CDR single-threaded batch processing begins now\n");
-		do_batch_backend_process(oldbatchitems);
+		do_batch_backend_process(batch_item);
 	} else {
 		pthread_attr_init(&attr);
 		pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
-		if (ast_pthread_create(&batch_post_thread, &attr, do_batch_backend_process, oldbatchitems)) {
+		if (ast_pthread_create(&batch_post_thread, &attr, do_batch_backend_process, batch_item)) {
 			ast_log(LOG_WARNING, "CDR processing thread could not detach, now trying in this thread\n");
-			do_batch_backend_process(oldbatchitems);
+			do_batch_backend_process(batch_item);
 		} else {
 			if (option_debug)
 				ast_log(LOG_DEBUG, "CDR multi-threaded batch processing begins now\n");
@@ -885,8 +916,9 @@
 
 void ast_cdr_detach(struct ast_cdr *cdr)
 {
-	struct ast_cdr_batch_item *newtail;
-	int curr;
+	struct ast_cdr *cur_cdr = cdr;
+	struct ast_cdr_batch_item *batch_item = NULL;
+	int cur = 0;
 
 	/* maybe they disabled CDR stuff completely, so just drop it */
 	if (!enabled) {
@@ -908,31 +940,28 @@
 	if (option_debug)
 		ast_log(LOG_DEBUG, "CDR detaching from this thread\n");
 
-	/* we'll need a new tail for every CDR */
-	if (!(newtail = ast_calloc(1, sizeof(*newtail)))) {
-		post_cdr(cdr);
-		ast_cdr_free(cdr);
-		return;
-	}
-
-	/* don't traverse a whole list (just keep track of the tail) */
-	ast_mutex_lock(&cdr_batch_lock);
-	if (!batch)
-		init_batch();
-	if (!batch->head) {
-		/* new batch is empty, so point the head at the new tail */
-		batch->head = newtail;
-	} else {
-		/* already got a batch with something in it, so just append a new tail */
-		batch->tail->next = newtail;
-	}
-	newtail->cdr = cdr;
-	batch->tail = newtail;
-	curr = batch->size++;
-	ast_mutex_unlock(&cdr_batch_lock);
-
-	/* if we have enough stuff to post, then do it */
-	if (curr >= (batchsize - 1))
+	/* In order for proper batch caching to work, these have to be separate entries in the list... so insert each separately if present */
+	while (cur_cdr) {
+		/* Allocate a new batched item */
+		if (!(batch_item = ast_calloc(1, sizeof(*batch_item)))) {
+			/* Failed to allocate the memory so post it here and abort all further attempts */
+			post_cdr(cur_cdr);
+			ast_cdr_free(cur_cdr);
+			break;
+		}
+		/* Attach CDR record to batched item */
+		batch_item->cdr = cur_cdr;
+		/* Insert into list and increment batch list size */
+		AST_LIST_LOCK(&batch_list);
+		AST_LIST_INSERT_HEAD(&batch_list, batch_item, list);
+		cur = batch_list_size++;
+		AST_LIST_UNLOCK(&batch_list);
+		/* Move on to next CDR record */
+		cur_cdr = cur_cdr->next;
+	}
+
+	/* If we have enough stuff to post, then do it */
+	if (cur >= (batchsize - 1))
 		submit_unscheduled_batch();
 }
 
@@ -964,9 +993,9 @@
 
 static int handle_cli_status(int fd, int argc, char *argv[])
 {
-	struct ast_cdr_beitem *beitem=NULL;
-	int cnt=0;
-	long nextbatchtime=0;
+	struct ast_cdr_beitem *beitem = NULL;
+	int cnt = 0;
+	long nextbatchtime = 0;
 
 	if (argc > 2)
 		return RESULT_SHOWUSAGE;
@@ -975,8 +1004,9 @@
 	ast_cli(fd, "CDR mode: %s\n", batchmode ? "batch" : "simple");
 	if (enabled) {
 		if (batchmode) {
-			if (batch)
-				cnt = batch->size;
+			AST_LIST_LOCK(&batch_list);
+			cnt = batch_list_size;
+			AST_LIST_UNLOCK(&batch_list);
 			if (cdr_sched > -1)
 				nextbatchtime = ast_sched_when(sched, cdr_sched);
 			ast_cli(fd, "CDR safe shut down: %s\n", batchsafeshutdown ? "enabled" : "disabled");
@@ -1041,7 +1071,7 @@
 	int was_batchmode;
 	int res=0;
 
-	ast_mutex_lock(&cdr_batch_lock);
+	AST_LIST_LOCK(&batch_list);
 
 	batchsize = BATCH_SIZE_DEFAULT;
 	batchtime = BATCH_TIME_DEFAULT;
@@ -1131,7 +1161,7 @@
 		res = 0;
 	}
 
-	ast_mutex_unlock(&cdr_batch_lock);
+	AST_LIST_UNLOCK(&batch_list);
 	ast_config_destroy(config);
 
 	return res;
@@ -1150,11 +1180,6 @@
 	ast_cli_register(&cli_status);
 
 	res = do_reload();
-	if (res) {
-		ast_mutex_lock(&cdr_batch_lock);
-		res = init_batch();
-		ast_mutex_unlock(&cdr_batch_lock);
-	}
 
 	return res;
 }

Modified: team/file/cdrbatchretry/cdr/cdr_csv.c
URL: http://svn.digium.com/view/asterisk/team/file/cdrbatchretry/cdr/cdr_csv.c?rev=38289&r1=38288&r2=38289&view=diff
==============================================================================
--- team/file/cdrbatchretry/cdr/cdr_csv.c (original)
+++ team/file/cdrbatchretry/cdr/cdr_csv.c Wed Jul 26 20:58:58 2006
@@ -308,7 +308,7 @@
 				ast_log(LOG_WARNING, "Unable to write CSV record to account file '%s' : %s\n", cdr->accountcode, strerror(errno));
 		}
 	}
-	return 0;
+	return AST_CDR_ENGINE_SUCCESS;
 }
 
 static const char *description(void)

Modified: team/file/cdrbatchretry/cdr/cdr_custom.c
URL: http://svn.digium.com/view/asterisk/team/file/cdrbatchretry/cdr/cdr_custom.c?rev=38289&r1=38288&r2=38289&view=diff
==============================================================================
--- team/file/cdrbatchretry/cdr/cdr_custom.c (original)
+++ team/file/cdrbatchretry/cdr/cdr_custom.c Wed Jul 26 20:58:58 2006
@@ -113,7 +113,7 @@
 
 	/* Abort if no master file is specified */
 	if (ast_strlen_zero(master))
-		return 0;
+		return AST_CDR_ENGINE_DISCARD;
 
 	memset(buf, 0 , sizeof(buf));
 	/* Quite possibly the first use of a static struct ast_channel, we need it so the var funcs will work */
@@ -134,7 +134,7 @@
 		fclose(mf);
 		mf = NULL;
 	}
-	return 0;
+	return AST_CDR_ENGINE_SUCCESS;
 }
 
 static const char *description(void)

Modified: team/file/cdrbatchretry/cdr/cdr_manager.c
URL: http://svn.digium.com/view/asterisk/team/file/cdrbatchretry/cdr/cdr_manager.c?rev=38289&r1=38288&r2=38289&view=diff
==============================================================================
--- team/file/cdrbatchretry/cdr/cdr_manager.c (original)
+++ team/file/cdrbatchretry/cdr/cdr_manager.c Wed Jul 26 20:58:58 2006
@@ -92,7 +92,7 @@
 	char strEndTime[80] = "";
 	
 	if (!enablecdr)
-		return 0;
+		return AST_CDR_ENGINE_DISCARD;
 
 	t = cdr->start.tv_sec;
 	localtime_r(&t, &timeresult);
@@ -132,7 +132,7 @@
 	    cdr->duration, cdr->billsec, ast_cdr_disp2str(cdr->disposition), 
 	    ast_cdr_flags2str(cdr->amaflags), cdr->uniqueid, cdr->userfield);
 	    	
-	return 0;
+	return AST_CDR_ENGINE_SUCCESS;
 }
 
 static const char *description(void)

Modified: team/file/cdrbatchretry/cdr/cdr_odbc.c
URL: http://svn.digium.com/view/asterisk/team/file/cdrbatchretry/cdr/cdr_odbc.c?rev=38289&r1=38288&r2=38289&view=diff
==============================================================================
--- team/file/cdrbatchretry/cdr/cdr_odbc.c (original)
+++ team/file/cdrbatchretry/cdr/cdr_odbc.c Wed Jul 26 20:58:58 2006
@@ -94,7 +94,7 @@
 {
 	int ODBC_res;
 	char sqlcmd[2048] = "", timestr[128];
-	int res = 0;
+	int res = 0, state = AST_CDR_ENGINE_SUCCESS;
 	struct tm tm;
 
 	if (usegmtime) 
@@ -122,7 +122,7 @@
 		if (res < 0) {
 			odbc_disconnect();
 			ast_mutex_unlock(&odbc_lock);
-			return 0;
+			return AST_CDR_ENGINE_FAILED;
 		}				
 	}
 
@@ -134,7 +134,7 @@
 		SQLFreeHandle(SQL_HANDLE_STMT, ODBC_stmt);
 		odbc_disconnect();
 		ast_mutex_unlock(&odbc_lock);
-		return 0;
+		return AST_CDR_ENGINE_DISCARD;
 	}
 
 	/* We really should only have to do this once.  But for some
@@ -149,7 +149,7 @@
 		SQLFreeHandle(SQL_HANDLE_STMT, ODBC_stmt);
 		odbc_disconnect();
 		ast_mutex_unlock(&odbc_lock);
-		return 0;
+		return AST_CDR_ENGINE_DISCARD;
 	}
 
 	SQLBindParameter(ODBC_stmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(timestr), 0, &timestr, 0, NULL);
@@ -195,6 +195,7 @@
 				if (res < 0) {
 					if (option_verbose > 10)
 						ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: Query FAILED Call not logged!\n");
+					state = AST_CDR_ENGINE_FAILED;
 				}
 			}
 		}
@@ -204,7 +205,7 @@
 	}
 	SQLFreeHandle(SQL_HANDLE_STMT, ODBC_stmt);
 	ast_mutex_unlock(&odbc_lock);
-	return 0;
+	return state;
 }
 
 static const char *description(void)

Modified: team/file/cdrbatchretry/cdr/cdr_pgsql.c
URL: http://svn.digium.com/view/asterisk/team/file/cdrbatchretry/cdr/cdr_pgsql.c?rev=38289&r1=38288&r2=38289&view=diff
==============================================================================
--- team/file/cdrbatchretry/cdr/cdr_pgsql.c (original)
+++ team/file/cdrbatchretry/cdr/cdr_pgsql.c Wed Jul 26 20:58:58 2006
@@ -75,6 +75,7 @@
 	struct tm tm;
 	char sqlcmd[2048] = "", timestr[128];
 	char *pgerror;
+	int res = AST_CDR_ENGINE_SUCCESS;
 
 	ast_mutex_lock(&pgsql_lock);
 
@@ -89,6 +90,7 @@
 			pgerror = PQerrorMessage(conn);
 			ast_log(LOG_ERROR, "cdr_pgsql: Unable to connect to database server %s.  Calls will not be logged!\n", pghostname);
                         ast_log(LOG_ERROR, "cdr_pgsql: Reason: %s\n", pgerror);
+			res = AST_CDR_ENGINE_FAILED;
 		}
 	}
 
@@ -118,7 +120,8 @@
 		if ((!clid) || (!dcontext) || (!channel) || (!dstchannel) || (!lastapp) || (!lastdata) || (!uniqueid) || (!userfield)) {
 			ast_log(LOG_ERROR, "cdr_pgsql:  Out of memory error (insert fails)\n");
 			ast_mutex_unlock(&pgsql_lock);
-			return -1;
+			/* Chances of us being able to do this in the future are slim... bad things are going to happen */
+			return AST_CDR_ENGINE_DISCARD;
 		}
 
 		if (option_debug > 1)
@@ -150,7 +153,7 @@
 				ast_log(LOG_ERROR, "cdr_pgsql: Reason: %s\n", pgerror);
 				connected = 0;
 				ast_mutex_unlock(&pgsql_lock);
-				return -1;
+				return AST_CDR_ENGINE_FAILED;
 			}
 		}
 		result = PQexec(conn, sqlcmd);
@@ -169,14 +172,15 @@
 					pgerror = PQresultErrorMessage(result);
 					ast_log(LOG_ERROR,"cdr_pgsql: HARD ERROR!  Attempted reconnection failed.  DROPPING CALL RECORD!\n");
 					ast_log(LOG_ERROR,"cdr_pgsql: Reason: %s\n", pgerror);
+					res = AST_CDR_ENGINE_FAILED;
 				}
 			}
 			ast_mutex_unlock(&pgsql_lock);
-			return -1;
+			return res;
 		}
 	}
 	ast_mutex_unlock(&pgsql_lock);
-	return 0;
+	return res;
 }
 
 static const char *description(void)

Modified: team/file/cdrbatchretry/cdr/cdr_radius.c
URL: http://svn.digium.com/view/asterisk/team/file/cdrbatchretry/cdr/cdr_radius.c?rev=38289&r1=38288&r2=38289&view=diff
==============================================================================
--- team/file/cdrbatchretry/cdr/cdr_radius.c (original)
+++ team/file/cdrbatchretry/cdr/cdr_radius.c Wed Jul 26 20:58:58 2006
@@ -102,43 +102,43 @@
 	char *tmp;
 
 	if (!rc_avpair_add(rh, send, PW_ACCT_STATUS_TYPE, &recordtype, 0, 0))
-		return -1;
+		return AST_CDR_ENGINE_DISCARD;
 
 	/* Account code */
 	if (!rc_avpair_add(rh, send, PW_AST_ACCT_CODE, &cdr->accountcode, strlen(cdr->accountcode), VENDOR_CODE))
-		return -1;
+		return AST_CDR_ENGINE_DISCARD;
 
  	/* Source */
 	if (!rc_avpair_add(rh, send, PW_AST_SRC, &cdr->src, strlen(cdr->src), VENDOR_CODE))
-		return -1;
+		return AST_CDR_ENGINE_DISCARD;
 
  	/* Destination */
 	if (!rc_avpair_add(rh, send, PW_AST_DST, &cdr->dst, strlen(cdr->dst), VENDOR_CODE))
-		return -1;
+		return AST_CDR_ENGINE_DISCARD;
 
  	/* Destination context */
 	if (!rc_avpair_add(rh, send, PW_AST_DST_CTX, &cdr->dcontext, strlen(cdr->dcontext), VENDOR_CODE))
-		return -1;
+		return AST_CDR_ENGINE_DISCARD;
 
 	/* Caller ID */
 	if (!rc_avpair_add(rh, send, PW_AST_CLID, &cdr->clid, strlen(cdr->clid), VENDOR_CODE))
-		return -1;
+		return AST_CDR_ENGINE_DISCARD;
 
 	/* Channel */
 	if (!rc_avpair_add(rh, send, PW_AST_CHAN, &cdr->channel, strlen(cdr->channel), VENDOR_CODE))
-		return -1;
+		return AST_CDR_ENGINE_DISCARD;
 
 	/* Destination Channel */
 	if (!rc_avpair_add(rh, send, PW_AST_DST_CHAN, &cdr->dstchannel, strlen(cdr->dstchannel), VENDOR_CODE))
-		return -1;
+		return AST_CDR_ENGINE_DISCARD;
 
 	/* Last Application */
 	if (!rc_avpair_add(rh, send, PW_AST_LAST_APP, &cdr->lastapp, strlen(cdr->lastapp), VENDOR_CODE))
-		return -1;
+		return AST_CDR_ENGINE_DISCARD;
 
 	/* Last Data */
 	if (!rc_avpair_add(rh, send, PW_AST_LAST_DATA, &cdr->lastdata, strlen(cdr->lastdata), VENDOR_CODE))
-		return -1;
+		return AST_CDR_ENGINE_DISCARD;
 
 
 	/* Start Time */
@@ -148,7 +148,7 @@
 		localtime_r(&(cdr->start.tv_sec), &tm);
 	strftime(timestr, sizeof(timestr), DATE_FORMAT, &tm);
 	if (!rc_avpair_add(rh, send, PW_AST_START_TIME, timestr, strlen(timestr), VENDOR_CODE))
-		return -1;
+		return AST_CDR_ENGINE_DISCARD;
 
 	/* Answer Time */
 	if (ast_test_flag(&global_flags, RADIUS_FLAG_USEGMTIME))
@@ -157,7 +157,7 @@
 		localtime_r(&(cdr->answer.tv_sec), &tm);
 	strftime(timestr, sizeof(timestr), DATE_FORMAT, &tm);
 	if (!rc_avpair_add(rh, send, PW_AST_ANSWER_TIME, timestr, strlen(timestr), VENDOR_CODE))
-		return -1;
+		return AST_CDR_ENGINE_DISCARD;
 
 	/* End Time */
 	if (ast_test_flag(&global_flags, RADIUS_FLAG_USEGMTIME))
@@ -166,60 +166,61 @@
 		localtime_r(&(cdr->end.tv_sec), &tm);
 	strftime(timestr, sizeof(timestr), DATE_FORMAT, &tm);
 	if (!rc_avpair_add(rh, send, PW_AST_END_TIME, timestr, strlen(timestr), VENDOR_CODE))
-		return -1;
+		return AST_CDR_ENGINE_DISCARD;
 
  	/* Duration */ 
 	if (!rc_avpair_add(rh, send, PW_AST_DURATION, &cdr->duration, 0, VENDOR_CODE))
-		return -1;
+		return AST_CDR_ENGINE_DISCARD;
 
 	/* Billable seconds */
 	if (!rc_avpair_add(rh, send, PW_AST_BILL_SEC, &cdr->billsec, 0, VENDOR_CODE))
-		return -1;
+		return AST_CDR_ENGINE_DISCARD;
 
 	/* Disposition */
 	tmp = ast_cdr_disp2str(cdr->disposition);
 	if (!rc_avpair_add(rh, send, PW_AST_DISPOSITION, tmp, strlen(tmp), VENDOR_CODE))
-		return -1;
+		return AST_CDR_ENGINE_DISCARD;
 
 	/* AMA Flags */
 	tmp = ast_cdr_flags2str(cdr->amaflags);
 	if (!rc_avpair_add(rh, send, PW_AST_AMA_FLAGS, tmp, strlen(tmp), VENDOR_CODE))
-		return -1;
+		return AST_CDR_ENGINE_DISCARD;
 
 	if (ast_test_flag(&global_flags, RADIUS_FLAG_LOGUNIQUEID)) {
 		/* Unique ID */
 		if (!rc_avpair_add(rh, send, PW_AST_UNIQUE_ID, &cdr->uniqueid, strlen(cdr->uniqueid), VENDOR_CODE))
-			return -1;
+			return AST_CDR_ENGINE_DISCARD;
 	}
 
 	if (ast_test_flag(&global_flags, RADIUS_FLAG_LOGUSERFIELD)) {
 		/* append the user field */
 		if (!rc_avpair_add(rh, send, PW_AST_USER_FIELD, &cdr->userfield, strlen(cdr->userfield), VENDOR_CODE))
-			return -1;
+			return AST_CDR_ENGINE_DISCARD;
 	}
 
 	/* Setting Acct-Session-Id & User-Name attributes for proper generation
 	   of Acct-Unique-Session-Id on server side */ 
 	/* Channel */
 	if (!rc_avpair_add(rh, send, PW_USER_NAME, &cdr->channel, strlen(cdr->channel), 0))
-		return -1;
+		return AST_CDR_ENGINE_DISCARD;
 
 	/* Unique ID */
 	if (!rc_avpair_add(rh, send, PW_ACCT_SESSION_ID, &cdr->uniqueid, strlen(cdr->uniqueid), 0))
-		return -1;
-
-	return 0;
+		return AST_CDR_ENGINE_DISCARD;
+
+	return AST_CDR_ENGINE_SUCCESS;
 }
 
 static int radius_log(struct ast_cdr *cdr)
 {
-	int result = ERROR_RC;
+	int result = ERROR_RC, res = AST_CDR_ENGINE_SUCCESS;
 	VALUE_PAIR *send = NULL;
 
-	if (build_radius_record(&send, cdr)) {
+	res = build_radius_record(&send, cdr);
+	if (res != AST_CDR_ENGINE_SUCCESS) {
 		if (option_debug)
 			ast_log(LOG_DEBUG, "Unable to create RADIUS record. CDR not recorded!\n");
-		return result;
+		return res;
 	}
 	
 	result = rc_acct(rh, 0, send);

Modified: team/file/cdrbatchretry/cdr/cdr_sqlite.c
URL: http://svn.digium.com/view/asterisk/team/file/cdrbatchretry/cdr/cdr_sqlite.c?rev=38289&r1=38288&r2=38289&view=diff
==============================================================================
--- team/file/cdrbatchretry/cdr/cdr_sqlite.c (original)
+++ team/file/cdrbatchretry/cdr/cdr_sqlite.c Wed Jul 26 20:58:58 2006
@@ -163,7 +163,7 @@
 	}
 
 	ast_mutex_unlock(&sqlite_lock);
-	return res;
+	return AST_CDR_ENGINE_SUCCESS;
 }
 
 

Modified: team/file/cdrbatchretry/cdr/cdr_tds.c
URL: http://svn.digium.com/view/asterisk/team/file/cdrbatchretry/cdr/cdr_tds.c?rev=38289&r1=38288&r2=38289&view=diff
==============================================================================
--- team/file/cdrbatchretry/cdr/cdr_tds.c (original)
+++ team/file/cdrbatchretry/cdr/cdr_tds.c Wed Jul 26 20:58:58 2006
@@ -113,7 +113,7 @@
 {
 	char sqlcmd[2048], start[80], answer[80], end[80];
 	char *accountcode, *src, *dst, *dcontext, *clid, *channel, *dstchannel, *lastapp, *lastdata, *uniqueid;
-	int res = 0;
+	int res = AST_CDR_ENGINE_SUCCESS;
 	int retried = 0;
 #ifdef FREETDS_PRE_0_62
 	TDS_INT result_type;
@@ -217,8 +217,8 @@
 #endif
 		{
 			ast_log(LOG_ERROR, "Failed to insert Call Data Record into SQL database.\n");
-
 			mssql_disconnect();	/* this is ok even if we are already disconnected */
+			res = AST_CDR_ENGINE_DISCARD;
 		}
 	} while (!connected && !retried);
 

Modified: team/file/cdrbatchretry/include/asterisk/cdr.h
URL: http://svn.digium.com/view/asterisk/team/file/cdrbatchretry/include/asterisk/cdr.h?rev=38289&r1=38288&r2=38289&view=diff
==============================================================================
--- team/file/cdrbatchretry/include/asterisk/cdr.h (original)
+++ team/file/cdrbatchretry/include/asterisk/cdr.h Wed Jul 26 20:58:58 2006
@@ -29,6 +29,7 @@
 #define AST_CDR_FLAG_LOCKED			(1 << 2)
 #define AST_CDR_FLAG_CHILD			(1 << 3)
 #define AST_CDR_FLAG_POST_DISABLED		(1 << 4)
+#define AST_CDR_FLAG_RETRY                      (1 << 5)
 
 #define AST_CDR_NOANSWER			(1 << 0)
 #define AST_CDR_BUSY				(1 << 1)
@@ -42,6 +43,16 @@
 
 #define AST_MAX_USER_FIELD			256
 #define AST_MAX_ACCOUNT_CODE			20
+
+/*! Engine posting return values */
+/*! Engine was successful with posting the record */
+#define AST_CDR_ENGINE_SUCCESS                  0
+/*! Engine was unwilling to post this record and it should be retried later */
+#define AST_CDR_ENGINE_DEFER                    1
+/*! Engine failed to post CDR record */
+#define AST_CDR_ENGINE_FAILED                   2
+/*! Engine failed to post CDR record and never will be able to */
+#define AST_CDR_ENGINE_DISCARD                  3
 
 /* Include channel.h after relevant declarations it will need */
 #include "asterisk/channel.h"



More information about the asterisk-commits mailing list