[svn-commits] murf: branch murf/CDRfix4 r119890 - in /team/murf/CDRfix4: channels/ include/...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Mon Jun 2 18:09:13 CDT 2008


Author: murf
Date: Mon Jun  2 18:09:12 2008
New Revision: 119890

URL: http://svn.digium.com/view/asterisk?view=rev&rev=119890
Log:
OK, here is just the fixes to 1.4 to replicate 1.2 behavior from CDRfix5. Tested via both double-xfer scenarios, looks good.

Modified:
    team/murf/CDRfix4/channels/chan_zap.c
    team/murf/CDRfix4/include/asterisk/cdr.h
    team/murf/CDRfix4/main/cdr.c
    team/murf/CDRfix4/main/channel.c
    team/murf/CDRfix4/main/pbx.c
    team/murf/CDRfix4/res/res_features.c

Modified: team/murf/CDRfix4/channels/chan_zap.c
URL: http://svn.digium.com/view/asterisk/team/murf/CDRfix4/channels/chan_zap.c?view=diff&rev=119890&r1=119889&r2=119890
==============================================================================
--- team/murf/CDRfix4/channels/chan_zap.c (original)
+++ team/murf/CDRfix4/channels/chan_zap.c Mon Jun  2 18:09:12 2008
@@ -3501,19 +3501,7 @@
 		if (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_RING) {
 			tone_zone_play_tone(p->subs[SUB_THREEWAY].zfd, ZT_TONE_RINGTONE);
 		}
-		if (p->subs[SUB_REAL].owner->cdr) {
-			/* Move CDR from second channel to current one */
-			p->subs[SUB_THREEWAY].owner->cdr =
-				ast_cdr_append(p->subs[SUB_THREEWAY].owner->cdr, p->subs[SUB_REAL].owner->cdr);
-			p->subs[SUB_REAL].owner->cdr = NULL;
-		}
-		if (ast_bridged_channel(p->subs[SUB_REAL].owner)->cdr) {
-			/* Move CDR from second channel's bridge to current one */
-			p->subs[SUB_THREEWAY].owner->cdr =
-				ast_cdr_append(p->subs[SUB_THREEWAY].owner->cdr, ast_bridged_channel(p->subs[SUB_REAL].owner)->cdr);
-			ast_bridged_channel(p->subs[SUB_REAL].owner)->cdr = NULL;
-		}
-		 if (ast_channel_masquerade(p->subs[SUB_THREEWAY].owner, ast_bridged_channel(p->subs[SUB_REAL].owner))) {
+		if (ast_channel_masquerade(p->subs[SUB_THREEWAY].owner, ast_bridged_channel(p->subs[SUB_REAL].owner))) {
 			ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n",
 					ast_bridged_channel(p->subs[SUB_REAL].owner)->name, p->subs[SUB_THREEWAY].owner->name);
 			return -1;
@@ -3528,18 +3516,6 @@
 		}
 		if (p->subs[SUB_REAL].owner->_state == AST_STATE_RING) {
 			tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE);
-		}
-		if (p->subs[SUB_THREEWAY].owner->cdr) {
-			/* Move CDR from second channel to current one */
-			p->subs[SUB_REAL].owner->cdr = 
-				ast_cdr_append(p->subs[SUB_REAL].owner->cdr, p->subs[SUB_THREEWAY].owner->cdr);
-			p->subs[SUB_THREEWAY].owner->cdr = NULL;
-		}
-		if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->cdr) {
-			/* Move CDR from second channel's bridge to current one */
-			p->subs[SUB_REAL].owner->cdr = 
-				ast_cdr_append(p->subs[SUB_REAL].owner->cdr, ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->cdr);
-			ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->cdr = NULL;
 		}
 		if (ast_channel_masquerade(p->subs[SUB_REAL].owner, ast_bridged_channel(p->subs[SUB_THREEWAY].owner))) {
 			ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n",
@@ -4290,6 +4266,17 @@
 							zt_enable_ec(p);
 							ast_hangup(chan);
 						} else {
+							struct ast_channel *other = ast_bridged_channel(p->subs[SUB_THREEWAY].owner);
+							int way3bridge = 0, cdr3way = 0;
+							
+							if (!other) {
+								other = ast_bridged_channel(p->subs[SUB_REAL].owner);
+							} else
+								way3bridge = 1;
+							
+							if (p->subs[SUB_THREEWAY].owner->cdr)
+								cdr3way = 1;
+							
 							if (option_verbose > 2)	
 								ast_verbose(VERBOSE_PREFIX_3 "Started three way call on channel %d\n", p->channel);
 							/* Start music on hold if appropriate */
@@ -4325,10 +4312,31 @@
 						if (((ast->pbx) || (ast->_state == AST_STATE_UP)) && 
 						    (p->transfertobusy || (ast->_state != AST_STATE_BUSY))) {
 							int otherindex = SUB_THREEWAY;
-
-							if (option_verbose > 2)
+							extern void ast_channel_log(char *title, struct ast_channel *chan);
+							extern void ast_cdr_log(char *title, struct ast_cdr *cdr);
+							struct ast_channel *other = ast_bridged_channel(p->subs[SUB_THREEWAY].owner);
+							int way3bridge = 0, cdr3way = 0;
+							
+#ifdef CDR_FIX_NOT_ANYMORE
+							struct ast_cdr *x2;
+#endif
+							
+							if (!other) {
+								other = ast_bridged_channel(p->subs[SUB_REAL].owner);
+							} else
+								way3bridge = 1;
+							
+							if (p->subs[SUB_THREEWAY].owner->cdr)
+								cdr3way = 1;
+							
+							if (option_verbose > 2) {
 								ast_verbose(VERBOSE_PREFIX_3 "Building conference on call on %s and %s\n", p->subs[SUB_THREEWAY].owner->name, p->subs[SUB_REAL].owner->name);
-							/* Put them in the threeway, and flip */
+								
+								ast_channel_log("+++++ 3WAY ===== SUB_THREEWAY channel:", p->subs[SUB_THREEWAY].owner);
+								ast_channel_log("+++++ 3WAY ===== SUB_REAL channel:", p->subs[SUB_REAL].owner);
+								ast_channel_log("+++++ 3WAY ===== 'other' channel:", other);
+							}
+							
 							p->subs[SUB_THREEWAY].inthreeway = 1;
 							p->subs[SUB_REAL].inthreeway = 1;
 							if (ast->_state == AST_STATE_UP) {

Modified: team/murf/CDRfix4/include/asterisk/cdr.h
URL: http://svn.digium.com/view/asterisk/team/murf/CDRfix4/include/asterisk/cdr.h?view=diff&rev=119890&r1=119889&r2=119890
==============================================================================
--- team/murf/CDRfix4/include/asterisk/cdr.h (original)
+++ team/murf/CDRfix4/include/asterisk/cdr.h Mon Jun  2 18:09:12 2008
@@ -24,12 +24,18 @@
 #define _ASTERISK_CDR_H
 
 #include <sys/time.h>
-#define AST_CDR_FLAG_KEEP_VARS			(1 << 0)
+
+/*! Flags */
+#define AST_CDR_FLAG_KEEP_VARS		(1 << 0)
 #define AST_CDR_FLAG_POSTED			(1 << 1)
 #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_POST_DISABLED	(1 << 4)
+#define AST_CDR_FLAG_BRIDGED		(1 << 5)
+#define AST_CDR_FLAG_MAIN			(1 << 6)
+#define AST_CDR_FLAG_ENABLE			(1 << 7)
+
+/*! Disposition */
 #define AST_CDR_NULL                0
 #define AST_CDR_FAILED				(1 << 0)
 #define AST_CDR_BUSY				(1 << 1)
@@ -39,10 +45,10 @@
 /*! AMA Flags */
 #define AST_CDR_OMIT				(1)
 #define AST_CDR_BILLING				(2)
-#define AST_CDR_DOCUMENTATION			(3)
+#define AST_CDR_DOCUMENTATION		(3)
 
 #define AST_MAX_USER_FIELD			256
-#define AST_MAX_ACCOUNT_CODE			20
+#define AST_MAX_ACCOUNT_CODE		20
 
 /* Include channel.h after relevant declarations it will need */
 #include "asterisk/channel.h"
@@ -272,6 +278,14 @@
  */
 void ast_cdr_reset(struct ast_cdr *cdr, struct ast_flags *flags);
 
+/*! Reset the detail record times, flags */
+/*!
+ * \param cdr which cdr to act upon
+ * \param flags |AST_CDR_FLAG_POSTED whether or not to post the cdr first before resetting it
+ *              |AST_CDR_FLAG_LOCKED whether or not to reset locked CDR's
+ */
+void ast_cdr_specialized_reset(struct ast_cdr *cdr, struct ast_flags *flags);
+
 /*! Flags to a string */
 /*!
  * \param flags binary flag

Modified: team/murf/CDRfix4/main/cdr.c
URL: http://svn.digium.com/view/asterisk/team/murf/CDRfix4/main/cdr.c?view=diff&rev=119890&r1=119889&r2=119890
==============================================================================
--- team/murf/CDRfix4/main/cdr.c (original)
+++ team/murf/CDRfix4/main/cdr.c Mon Jun  2 18:09:12 2008
@@ -779,6 +779,10 @@
 	for (; cdr; cdr = cdr->next) {
 		if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) {
 			check_post(cdr);
+			if (!app)
+				app = "";
+			if (!data)
+				data = "";
 			ast_copy_string(cdr->lastapp, S_OR(app, ""), sizeof(cdr->lastapp));
 			ast_copy_string(cdr->lastdata, S_OR(data, ""), sizeof(cdr->lastdata));
 		}
@@ -860,7 +864,11 @@
 			cdr->disposition = AST_CDR_FAILED;
 		} else
 			cdr->duration = cdr->end.tv_sec - cdr->start.tv_sec;
-		cdr->billsec = ast_tvzero(cdr->answer) ? 0 : cdr->end.tv_sec - cdr->answer.tv_sec;
+		if (ast_tvzero(cdr->answer)) {
+			ast_log(LOG_WARNING, "CDR on channel '%s' has no answer tune\n", S_OR(cdr->channel, "<unknown>"));
+			cdr->disposition = AST_CDR_FAILED;
+		} else
+			cdr->billsec = cdr->end.tv_sec - cdr->answer.tv_sec;
 	}
 }
 
@@ -1046,6 +1054,27 @@
 			cdr->disposition = AST_CDR_NULL;
 		}
 	}
+}
+
+void ast_cdr_specialized_reset(struct ast_cdr *cdr, struct ast_flags *_flags)
+{
+	struct ast_flags flags = { 0 };
+
+	if (_flags)
+		ast_copy_flags(&flags, _flags, AST_FLAGS_ALL);
+
+	if (_flags)
+		ast_copy_flags(&flags, _flags, AST_FLAGS_ALL);
+	
+	/* Reset to initial state */
+	ast_clear_flag(cdr, AST_FLAGS_ALL);	
+	memset(&cdr->start, 0, sizeof(cdr->start));
+	memset(&cdr->end, 0, sizeof(cdr->end));
+	memset(&cdr->answer, 0, sizeof(cdr->answer));
+	cdr->billsec = 0;
+	cdr->duration = 0;
+	ast_cdr_start(cdr);
+	cdr->disposition = AST_CDR_NULL;
 }
 
 struct ast_cdr *ast_cdr_append(struct ast_cdr *cdr, struct ast_cdr *newcdr) 

Modified: team/murf/CDRfix4/main/channel.c
URL: http://svn.digium.com/view/asterisk/team/murf/CDRfix4/main/channel.c?view=diff&rev=119890&r1=119889&r2=119890
==============================================================================
--- team/murf/CDRfix4/main/channel.c (original)
+++ team/murf/CDRfix4/main/channel.c Mon Jun  2 18:09:12 2008
@@ -1417,7 +1417,6 @@
 int ast_hangup(struct ast_channel *chan)
 {
 	int res = 0;
-	struct ast_cdr *cdr = NULL;
 
 	/* Don't actually hang up a channel that will masquerade as someone else, or
 	   if someone is going to masquerade as us */
@@ -1467,11 +1466,6 @@
 		chan->generator->release(chan, chan->generatordata);
 	chan->generatordata = NULL;
 	chan->generator = NULL;
-	if (chan->cdr) {		/* End the CDR if it hasn't already */
-		ast_cdr_end(chan->cdr);
-		cdr = chan->cdr;
-		chan->cdr = NULL;
-	}
 	if (ast_test_flag(chan, AST_FLAG_BLOCKING)) {
 		ast_log(LOG_WARNING, "Hard hangup called by thread %ld on %s, while fd "
 					"is blocked by thread %ld in procedure %s!  Expect a failure\n",
@@ -1499,10 +1493,13 @@
 			chan->hangupcause,
 			ast_cause2str(chan->hangupcause)
 			);
+
+	if (chan->cdr && !ast_test_flag(chan->cdr, AST_CDR_FLAG_BRIDGED) && !ast_test_flag(chan->cdr, AST_CDR_FLAG_POST_DISABLED) && chan->cdr->disposition != AST_CDR_NULL) {
+		ast_cdr_end(chan->cdr);
+		ast_cdr_detach(chan->cdr);
+	}
+	
 	ast_channel_free(chan);
-
-	if (cdr)
-		ast_cdr_detach(cdr);
 
 	return res;
 }
@@ -1530,7 +1527,6 @@
 		ast_cdr_answer(chan->cdr);
 		break;
 	case AST_STATE_UP:
-		ast_cdr_answer(chan->cdr);
 		break;
 	default:
 		break;
@@ -2100,15 +2096,7 @@
 				} else {
 					/* Answer the CDR */
 					ast_setstate(chan, AST_STATE_UP);
-					if (!chan->cdr) { /* up till now, this insertion hasn't been done. Therefore,
-										 to keep from throwing off the basic order of the universe,
-										 we will try to keep this cdr from getting posted. */
-						chan->cdr = ast_cdr_alloc();
-						ast_cdr_init(chan->cdr, chan);
-						ast_cdr_start(chan->cdr);
-					}
-					
-					ast_cdr_answer(chan->cdr);
+					/* removed a call to ast_cdr_answer(chan->cdr) from here. */
 				}
 			}
 			break;
@@ -2320,9 +2308,7 @@
 		chan->_softhangup |= AST_SOFTHANGUP_DEV;
 		if (chan->generator)
 			ast_deactivate_generator(chan);
-		/* End the CDR if appropriate */
-		if (chan->cdr)
-			ast_cdr_end(chan->cdr);
+		/* We no longer End the CDR here */
 	}
 
 	/* High bit prints debugging */
@@ -2882,15 +2868,6 @@
 	}
 	ast_set_callerid(chan, cid_num, cid_name, cid_num);
 
-	
-
-	if (!chan->cdr) { /* up till now, this insertion hasn't been done. Therefore,
-				to keep from throwing off the basic order of the universe,
-				we will try to keep this cdr from getting posted. */
-		chan->cdr = ast_cdr_alloc();
-		ast_cdr_init(chan->cdr, chan);
-		ast_cdr_start(chan->cdr);
-	}
 	if (ast_call(chan, data, 0)) {	/* ast_call failed... */
 		ast_log(LOG_NOTICE, "Unable to call channel %s/%s\n", type, (char *)data);
 	} else {
@@ -3639,8 +3616,6 @@
 			free(chan->cid.cid_ani);
 		chan->cid.cid_ani = ast_strdup(ani);
 	}
-	if (chan->cdr)
-		ast_cdr_setcid(chan->cdr, chan);
 	manager_event(EVENT_FLAG_CALL, "Newcallerid",
 				"Channel: %s\r\n"
 				"CallerID: %s\r\n"

Modified: team/murf/CDRfix4/main/pbx.c
URL: http://svn.digium.com/view/asterisk/team/murf/CDRfix4/main/pbx.c?view=diff&rev=119890&r1=119889&r2=119890
==============================================================================
--- team/murf/CDRfix4/main/pbx.c (original)
+++ team/murf/CDRfix4/main/pbx.c Mon Jun  2 18:09:12 2008
@@ -2371,17 +2371,6 @@
 	}
 	if (!(c->pbx = ast_calloc(1, sizeof(*c->pbx))))
 		return -1;
-	if (c->amaflags) {
-		if (!c->cdr) {
-			c->cdr = ast_cdr_alloc();
-			if (!c->cdr) {
-				ast_log(LOG_WARNING, "Unable to create Call Detail Record\n");
-				free(c->pbx);
-				return -1;
-			}
-			ast_cdr_init(c->cdr, c);
-		}
-	}
 	/* Set reasonable defaults */
 	c->pbx->rtimeout = 10;
 	c->pbx->dtimeout = 5;
@@ -2406,8 +2395,6 @@
 			ast_copy_string(c->context, "default", sizeof(c->context));
 		}
 	}
-	if (c->cdr && ast_tvzero(c->cdr->start))
-		ast_cdr_start(c->cdr);
 	for (;;) {
 		char dst_exten[256];	/* buffer to accumulate digits */
 		int pos = 0;		/* XXX should check bounds */
@@ -2553,8 +2540,6 @@
 	if (res != AST_PBX_KEEPALIVE)
 		ast_softhangup(c, c->hangupcause ? c->hangupcause : AST_CAUSE_NORMAL_CLEARING);
 	if ((res != AST_PBX_KEEPALIVE) && ast_exists_extension(c, c->context, "h", 1, c->cid.cid_num)) {
-		if (c->cdr && ast_opt_end_cdr_before_h_exten)
-			ast_cdr_end(c->cdr);
 		set_ext_pri(c, "h", 1);
 		while(ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) {
 			if ((res = ast_spawn_extension(c, c->context, c->exten, c->priority, c->cid.cid_num))) {
@@ -5179,6 +5164,7 @@
 	if (sync) {
 		chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh);
 		if (chan) {
+#ifdef THIS_CODE_IS_NO_LONGER_NEEDED_METHINKS
 			if (!chan->cdr) { /* check if the channel already has a cdr record, if not give it one */
 				chan->cdr = ast_cdr_alloc();   /* allocate a cdr for the channel */
 				if(!chan->cdr) {
@@ -5191,6 +5177,7 @@
 				ast_cdr_init(chan->cdr, chan);  /* initilize our channel's cdr */
 				ast_cdr_start(chan->cdr);
 			}
+#endif
 			ast_set_variables(chan, vars);
 			if (account)
 				ast_cdr_setaccount(chan, account);
@@ -6409,7 +6396,6 @@
 		ipri = chan->priority + (ipri * mode);
 
 	ast_explicit_goto(chan, context, exten, ipri);
-	ast_cdr_update(chan);
 	return 0;
 
 }

Modified: team/murf/CDRfix4/res/res_features.c
URL: http://svn.digium.com/view/asterisk/team/murf/CDRfix4/res/res_features.c?view=diff&rev=119890&r1=119889&r2=119890
==============================================================================
--- team/murf/CDRfix4/res/res_features.c (original)
+++ team/murf/CDRfix4/res/res_features.c Mon Jun  2 18:09:12 2008
@@ -230,6 +230,8 @@
 	tobj->chan->data = tobj->peer->name;
 	tobj->peer->appl = "Transferred Call";
 	tobj->peer->data = tobj->chan->name;
+
+#ifdef NOMORE
 	if (tobj->chan->cdr) {
 		ast_cdr_reset(tobj->chan->cdr, NULL);
 		ast_cdr_setdestchan(tobj->chan->cdr, tobj->peer->name);
@@ -238,6 +240,7 @@
 		ast_cdr_reset(tobj->peer->cdr, NULL);
 		ast_cdr_setdestchan(tobj->peer->cdr, tobj->chan->name);
 	}
+#endif
 
 	ast_bridge_call(tobj->peer, tobj->chan, &tobj->bconfig);
 	ast_hangup(tobj->chan);
@@ -1185,13 +1188,6 @@
 		ast_string_field_set(chan, language, language);
 		ast_channel_inherit_variables(caller, chan);	
 		pbx_builtin_setvar_helper(chan, "TRANSFERERNAME", caller->name);
-		if (!chan->cdr) {
-			chan->cdr=ast_cdr_alloc();
-			if (chan->cdr) {
-				ast_cdr_init(chan->cdr, chan); /* initilize our channel's cdr */
-				ast_cdr_start(chan->cdr);
-			}
-		}
 			
 		if (!ast_call(chan, data, timeout)) {
 			struct timeval started;
@@ -1331,23 +1327,6 @@
 	if (outstate)
 		*outstate = state;
 
-	if (chan && res <= 0) {
-		if (chan->cdr || (chan->cdr = ast_cdr_alloc())) {
-			char tmp[256];
-			ast_cdr_init(chan->cdr, chan);
-			snprintf(tmp, 256, "%s/%s", type, (char *)data);
-			ast_cdr_setapp(chan->cdr,"Dial",tmp);
-			ast_cdr_update(chan);
-			ast_cdr_start(chan->cdr);
-			ast_cdr_end(chan->cdr);
-			/* If the cause wasn't handled properly */
-			if (ast_cdr_disposition(chan->cdr,chan->hangupcause))
-				ast_cdr_failed(chan->cdr);
-		} else {
-			ast_log(LOG_WARNING, "Unable to create Call Detail Record\n");
-		}
-	}
-	
 	return chan;
 }
 
@@ -1359,13 +1338,16 @@
 	struct ast_channel *who;
 	char chan_featurecode[FEATURE_MAX_LEN + 1]="";
 	char peer_featurecode[FEATURE_MAX_LEN + 1]="";
+	char orig_channame[AST_MAX_EXTENSION];
+	char orig_peername[AST_MAX_EXTENSION];
+
 	int res;
 	int diff;
 	int hasfeatures=0;
 	int hadfeatures=0;
 	struct ast_option_header *aoh;
 	struct ast_bridge_config backup_config;
-	struct ast_cdr *bridge_cdr;
+	struct ast_cdr *bridge_cdr = NULL;
 
 	memset(&backup_config, 0, sizeof(backup_config));
 
@@ -1400,27 +1382,52 @@
 	/* Answer if need be */
 	if (ast_answer(chan))
 		return -1;
-	peer->appl = "Bridged Call";
-	peer->data = chan->name;
-
-	/* copy the userfield from the B-leg to A-leg if applicable */
-	if (chan->cdr && peer->cdr && !ast_strlen_zero(peer->cdr->userfield)) {
-		char tmp[256];
-		if (!ast_strlen_zero(chan->cdr->userfield)) {
-			snprintf(tmp, sizeof(tmp), "%s;%s", chan->cdr->userfield, peer->cdr->userfield);
-			ast_cdr_appenduserfield(chan, tmp);
-		} else
-			ast_cdr_setuserfield(chan, peer->cdr->userfield);
-		/* free the peer's cdr without ast_cdr_free complaining */
-		free(peer->cdr);
-		peer->cdr = NULL;
-	}
-
+
+	ast_copy_string(orig_channame,chan->name,sizeof(orig_channame));
+	ast_copy_string(orig_peername,peer->name,sizeof(orig_peername));
+	
+	if (!chan->cdr || (chan->cdr && !ast_test_flag(chan->cdr, AST_CDR_FLAG_POST_DISABLED))) {
+			
+		if (chan->cdr) {
+			ast_set_flag(chan->cdr, AST_CDR_FLAG_MAIN);
+			ast_cdr_update(chan);
+			bridge_cdr = ast_cdr_dup(chan->cdr);
+			ast_copy_string(bridge_cdr->lastapp, chan->appl, sizeof(bridge_cdr->lastapp));
+			ast_copy_string(bridge_cdr->lastdata, chan->data, sizeof(bridge_cdr->lastdata));
+		} else {
+			/* better yet, in a xfer situation, find out why the chan cdr got zapped (pun unintentional) */
+			bridge_cdr = ast_cdr_alloc(); /* this should be really, really rare/impossible? */
+			ast_copy_string(bridge_cdr->channel, chan->name, sizeof(bridge_cdr->channel));
+			ast_copy_string(bridge_cdr->dstchannel, peer->name, sizeof(bridge_cdr->dstchannel));
+			ast_copy_string(bridge_cdr->uniqueid, chan->uniqueid, sizeof(bridge_cdr->uniqueid));
+			ast_copy_string(bridge_cdr->lastapp, chan->appl, sizeof(bridge_cdr->lastapp));
+			ast_copy_string(bridge_cdr->lastdata, chan->data, sizeof(bridge_cdr->lastdata));
+			ast_cdr_setcid(bridge_cdr, chan);
+			bridge_cdr->disposition = (chan->_state == AST_STATE_UP) ?  AST_CDR_ANSWERED : AST_CDR_NULL;
+			bridge_cdr->amaflags = chan->amaflags ? chan->amaflags :  ast_default_amaflags;
+			ast_copy_string(bridge_cdr->accountcode, chan->accountcode, sizeof(bridge_cdr->accountcode));
+			/* Destination information */
+			ast_copy_string(bridge_cdr->dst, chan->exten, sizeof(bridge_cdr->dst));
+			ast_copy_string(bridge_cdr->dcontext, chan->context, sizeof(bridge_cdr->dcontext));
+			if (peer->cdr) {
+				bridge_cdr->start = peer->cdr->start;
+				ast_copy_string(bridge_cdr->userfield, peer->cdr->userfield, sizeof(bridge_cdr->userfield));
+			} else {
+				ast_cdr_start(bridge_cdr);
+			}
+		}
+		ast_cdr_answer(bridge_cdr);
+		ast_cdr_answer(chan->cdr); /* for the sake of cli status checks */
+		ast_set_flag(chan->cdr, AST_CDR_FLAG_BRIDGED);
+		if (peer->cdr)
+			ast_set_flag(peer->cdr, AST_CDR_FLAG_BRIDGED);
+	}
+	
 	for (;;) {
 		struct ast_channel *other;	/* used later */
-
+		
 		res = ast_channel_bridge(chan, peer, config, &f, &who);
-
+		
 		if (config->feature_timer) {
 			/* Update time limit for next pass */
 			diff = ast_tvdiff_ms(ast_tvnow(), config->start_time);
@@ -1580,73 +1587,18 @@
 			ast_frfree(f);
 
 	}
-
-	/* arrange the cdrs */
-	bridge_cdr = ast_cdr_alloc();
-	if (bridge_cdr) {
-		if (chan->cdr && peer->cdr) { /* both of them? merge */
-			ast_channel_lock(chan);  /* lock the channel before modifing cdrs */
-			ast_cdr_init(bridge_cdr,chan); /* seems more logicaller to use the  destination as a base, but, really, it's random */
-			ast_cdr_start(bridge_cdr); /* now is the time to start */
-
-			/* absorb the channel cdr */
-			ast_cdr_merge(bridge_cdr, chan->cdr);
-			if (!ast_test_flag(chan->cdr, AST_CDR_FLAG_LOCKED)) 
-				ast_cdr_discard(chan->cdr); /* if locked cdrs are in chan, they are taken over in the merge */
-
-			chan->cdr = NULL; /* remove pointer to freed memory before releasing the lock */
-
-			ast_channel_unlock(chan);
-			
-			/* absorb the peer cdr */
-			ast_channel_lock(peer);
-			ast_cdr_merge(bridge_cdr, peer->cdr);
-			if (!ast_test_flag(peer->cdr, AST_CDR_FLAG_LOCKED))
-				ast_cdr_discard(peer->cdr); /* if locked cdrs are in peer, they are taken over in the merge */
-			
-			peer->cdr = NULL;
-			ast_channel_unlock(peer);
-
-			ast_channel_lock(chan);
-			chan->cdr = bridge_cdr; /* make this available to the rest of the world via the chan while the call is in progress */
-			ast_channel_unlock(chan);
-
-		} else if (chan->cdr) {
-
-			ast_channel_lock(chan); /* Lock before modifying CDR */
-			/* take the cdr from the channel - literally */
-			ast_cdr_init(bridge_cdr,chan);
-			/* absorb this data */
-			ast_cdr_merge(bridge_cdr, chan->cdr);
-			if (!ast_test_flag(chan->cdr, AST_CDR_FLAG_LOCKED))
-				ast_cdr_discard(chan->cdr); /* if locked cdrs are in chan, they are taken over in the merge */
-			chan->cdr = bridge_cdr; /* make this available to the rest of the world via the chan while the call is in progress */
-			ast_channel_unlock(chan);
-		} else if (peer->cdr) {
-			ast_channel_lock(peer); /* Lock before modifying CDR */
-			/* take the cdr from the peer - literally */
-			ast_cdr_init(bridge_cdr,peer);
-			/* absorb this data */
-			ast_cdr_merge(bridge_cdr, peer->cdr);
-			if (!ast_test_flag(peer->cdr, AST_CDR_FLAG_LOCKED))
-				ast_cdr_discard(peer->cdr); /* if locked cdrs are in chan, they are taken over in the merge */
-			peer->cdr = NULL;
-			peer->cdr = bridge_cdr; /* make this available to the rest of the world via the chan while the call is in progress */
-			ast_channel_unlock(peer);
-		} else {
-			ast_channel_lock(chan); /* Lock before modifying CDR */
-			/* make up a new cdr */
-			ast_cdr_init(bridge_cdr,chan); /* eh, just pick one of them */
-			chan->cdr = bridge_cdr; /*  */
-			ast_channel_unlock(chan);
-		}
-		if (ast_strlen_zero(bridge_cdr->dstchannel)) {
-			if (strcmp(bridge_cdr->channel, peer->name) != 0)
-				ast_cdr_setdestchan(bridge_cdr, peer->name);
-			else
-				ast_cdr_setdestchan(bridge_cdr, chan->name);
-		}
-	}
+	/* obey the NoCDR() wishes. */
+	if (!chan->cdr || (chan->cdr && !ast_test_flag(chan->cdr, AST_CDR_FLAG_POST_DISABLED))) {
+		
+		ast_cdr_end(bridge_cdr);
+		
+		ast_cdr_detach(bridge_cdr);
+		
+		/* just in case, these channels get bridged again before hangup */
+		ast_cdr_specialized_reset(chan->cdr,0);
+		ast_cdr_specialized_reset(peer->cdr,0);
+	}
+	
 	return res;
 }
 




More information about the svn-commits mailing list