[asterisk-commits] murf: branch murf/CDRfix5 r69516 - in /team/murf/CDRfix5: apps/ channels/ fun...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu Jun 14 23:45:05 CDT 2007


Author: murf
Date: Thu Jun 14 23:45:04 2007
New Revision: 69516

URL: http://svn.digium.com/view/asterisk?view=rev&rev=69516
Log:
I added the CDRabort(handle) func to free an allocated CDR without posting it. Thought it might come in handy. I am doing an experiment to see if I can provide another CDR field that would group all CDR connected by forwarding, by having a common value amongst them. But it's not going well at all.

Modified:
    team/murf/CDRfix5/apps/app_forkcdr.c
    team/murf/CDRfix5/channels/chan_zap.c
    team/murf/CDRfix5/funcs/func_cdr.c
    team/murf/CDRfix5/include/asterisk/cdr.h
    team/murf/CDRfix5/include/asterisk/channel.h
    team/murf/CDRfix5/main/cdr.c
    team/murf/CDRfix5/main/channel.c
    team/murf/CDRfix5/res/res_features.c

Modified: team/murf/CDRfix5/apps/app_forkcdr.c
URL: http://svn.digium.com/view/asterisk/team/murf/CDRfix5/apps/app_forkcdr.c?view=diff&rev=69516&r1=69515&r2=69516
==============================================================================
--- team/murf/CDRfix5/apps/app_forkcdr.c (original)
+++ team/murf/CDRfix5/apps/app_forkcdr.c Thu Jun 14 23:45:04 2007
@@ -89,6 +89,8 @@
 	if (!ast_strlen_zero(data))
 		ast_set2_flag(chan->cdr, strchr(data, 'v'), AST_CDR_FLAG_KEEP_VARS);
 	
+	ast_log(LOG_ERROR,"ForkCDR is obsolesced. It will probably not yield correct results any more. Use CDRstart(), CDRanswer(), and CDRclose() functions instead!\n");
+	
 	ast_cdr_fork(chan);
 
 	ast_module_user_remove(u);

Modified: team/murf/CDRfix5/channels/chan_zap.c
URL: http://svn.digium.com/view/asterisk/team/murf/CDRfix5/channels/chan_zap.c?view=diff&rev=69516&r1=69515&r2=69516
==============================================================================
--- team/murf/CDRfix5/channels/chan_zap.c (original)
+++ team/murf/CDRfix5/channels/chan_zap.c Thu Jun 14 23:45:04 2007
@@ -4570,6 +4570,10 @@
 							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);
+							if (option_verbose > 2)
+								ast_verbose(VERBOSE_PREFIX_3 "Other is %s, 3way link=%s, real link=%s\n",
+											other->name, p->subs[SUB_THREEWAY].owner->linkedid, p->subs[SUB_REAL].owner->linkedid);
+							ast_channel_set_linkgroup(p->subs[SUB_THREEWAY].owner, p->subs[SUB_REAL].owner);
 #ifdef CDR_FIX_NOT_ANYMORE
 							if (other)
 								ast_verbose(VERBOSE_PREFIX_3 "way3bridge is %d, and bridged to %s\n",

Modified: team/murf/CDRfix5/funcs/func_cdr.c
URL: http://svn.digium.com/view/asterisk/team/murf/CDRfix5/funcs/func_cdr.c?view=diff&rev=69516&r1=69515&r2=69516
==============================================================================
--- team/murf/CDRfix5/funcs/func_cdr.c (original)
+++ team/murf/CDRfix5/funcs/func_cdr.c Thu Jun 14 23:45:04 2007
@@ -169,6 +169,8 @@
 			}
 		} else if (!strcasecmp(args.variable, "uniqueid"))
 			ast_copy_string(cdr->uniqueid, value, sizeof(cdr->uniqueid));
+		else if (!strcasecmp(args.variable, "linkedid"))
+			ast_copy_string(cdr->linkedid, value, sizeof(cdr->linkedid));
 		else
 			ast_cdr_setvar(cdr, args.variable, value, ast_test_flag(&flags, OPT_RECURSIVE));
 		return 0;
@@ -196,6 +198,7 @@
 "     dcontext      end            uniqueid\n"
 "     dstchannel    duration       userfield\n"
 "     lastapp       billsec        channel\n"
+"     linkedid\n"
 "All of the above variables are read-only, except for accountcode,\n"
 "userfield, and amaflags. You may, however,  supply\n"
 "a name not on the above list, and create your own\n"
@@ -341,6 +344,52 @@
 	.read = function_cdr_close
 };
 
+static int function_cdr_abort(struct ast_channel *chan, const char *cmd,
+								   char *parse, char *buf, size_t len)
+{
+	struct ast_cdr *cdr;
+	
+	AST_DECLARE_APP_ARGS(args,
+			     AST_APP_ARG(handle);
+	);
+
+	buf[0] = '\0';
+
+	if (ast_strlen_zero(parse)) {
+		ast_log(LOG_WARNING, "CDRabort requires an argument, CDRabort(<handle>)\n");
+		return -1;
+	}
+
+	AST_STANDARD_APP_ARGS(args, parse);
+
+	if (args.argc < 1) {
+		ast_log(LOG_WARNING, "CDRabort requires an argument, CDRabort(<handle>)\n");
+		return -1;
+	}
+
+	cdr = (struct ast_cdr*)strtoul(args.handle, NULL, 10);
+	
+	if (!cdr)
+		return 0;
+
+	ast_cdr_free(cdr);
+
+	buf[0] = 0;
+	
+	return 0;
+}
+
+static struct ast_custom_function cdr_abort_function = {
+	.name = "CDRabort",
+	.synopsis = "Sets the Answer time in the CDR associated with the supplied handle to the current time",
+	.syntax = "CDRabort(handle)",
+	.desc =
+	"This function will Set the start time to the current time in the CDR associated with the argument 'handle'.\n"
+	" This func will return the handle.\n",
+	.read = function_cdr_abort
+};
+
+
 
 static int unload_module(void)
 {
@@ -350,6 +399,7 @@
 	res |= ast_custom_function_unregister(&cdr_create_function);
 	res |= ast_custom_function_unregister(&cdr_answer_function);
 	res |= ast_custom_function_unregister(&cdr_close_function);
+	res |= ast_custom_function_unregister(&cdr_abort_function);
 	return res;
 }
 
@@ -361,6 +411,7 @@
 	res |= ast_custom_function_register(&cdr_create_function);
 	res |= ast_custom_function_register(&cdr_answer_function);
 	res |= ast_custom_function_register(&cdr_close_function);
+	res |= ast_custom_function_register(&cdr_abort_function);
 	return res;
 }
 

Modified: team/murf/CDRfix5/include/asterisk/cdr.h
URL: http://svn.digium.com/view/asterisk/team/murf/CDRfix5/include/asterisk/cdr.h?view=diff&rev=69516&r1=69515&r2=69516
==============================================================================
--- team/murf/CDRfix5/include/asterisk/cdr.h (original)
+++ team/murf/CDRfix5/include/asterisk/cdr.h Thu Jun 14 23:45:04 2007
@@ -87,6 +87,8 @@
 	unsigned int flags;				
 	/* Unique Channel Identifier */
 	char uniqueid[32];
+	/* Linked group Identifier */
+	char linkedid[32];
 	/* User field */
 	char userfield[AST_MAX_USER_FIELD];
 

Modified: team/murf/CDRfix5/include/asterisk/channel.h
URL: http://svn.digium.com/view/asterisk/team/murf/CDRfix5/include/asterisk/channel.h?view=diff&rev=69516&r1=69515&r2=69516
==============================================================================
--- team/murf/CDRfix5/include/asterisk/channel.h (original)
+++ team/murf/CDRfix5/include/asterisk/channel.h Thu Jun 14 23:45:04 2007
@@ -394,6 +394,7 @@
 		AST_STRING_FIELD(accountcode);		/*!< Account code for billing */
 		AST_STRING_FIELD(call_forward);		/*!< Where to forward to if asked to dial on this interface */
 		AST_STRING_FIELD(uniqueid);		/*!< Unique Channel Identifier */
+		AST_STRING_FIELD(linkedid);		/*!< Linked Channel Identifier -- gets propagated by linkage */
 	);
 	
 	/*! \brief File descriptor for channel -- Drivers will poll on these file descriptors, so at least one must be non -1.  See \ref AstFileDesc */
@@ -1445,4 +1446,9 @@
 }
 #endif
 
+/*!
+  \brief propagate the linked id between chan and peer
+ */
+void ast_channel_set_linkgroup(struct ast_channel *chan, struct ast_channel *peer);
+
 #endif /* _ASTERISK_CHANNEL_H */

Modified: team/murf/CDRfix5/main/cdr.c
URL: http://svn.digium.com/view/asterisk/team/murf/CDRfix5/main/cdr.c?view=diff&rev=69516&r1=69515&r2=69516
==============================================================================
--- team/murf/CDRfix5/main/cdr.c (original)
+++ team/murf/CDRfix5/main/cdr.c Thu Jun 14 23:45:04 2007
@@ -274,6 +274,8 @@
 		ast_copy_string(workspace, cdr->accountcode, workspacelen);
 	else if (!strcasecmp(name, "uniqueid"))
 		ast_copy_string(workspace, cdr->uniqueid, workspacelen);
+	else if (!strcasecmp(name, "linkedid"))
+		ast_copy_string(workspace, cdr->linkedid, workspacelen);
 	else if (!strcasecmp(name, "userfield"))
 		ast_copy_string(workspace, cdr->userfield, workspacelen);
 	else if ((varbuf = ast_cdr_getvar_internal(cdr, name, recur)))
@@ -288,7 +290,7 @@
 /* readonly cdr variables */
 static	const char *cdr_readonly_vars[] = { "clid", "src", "dst", "dcontext", "channel", "dstchannel",
 				    "lastapp", "lastdata", "start", "answer", "end", "duration",
-				    "billsec", "disposition", "amaflags", "accountcode", "uniqueid",
+					"billsec", "disposition", "amaflags", "accountcode", "uniqueid", "linkedid",
 				    "userfield", NULL };
 /*! Set a CDR channel variable 
 	\note You can't set the CDR variables that belong to the actual CDR record, like "billsec".
@@ -778,10 +780,12 @@
 			cdr->amaflags = c->amaflags ? c->amaflags :  ast_default_amaflags;
 			ast_copy_string(cdr->accountcode, c->accountcode, sizeof(cdr->accountcode));
 			/* Destination information */
-			ast_copy_string(cdr->dst, c->exten, sizeof(cdr->dst));
-			ast_copy_string(cdr->dcontext, c->context, sizeof(cdr->dcontext));
+			ast_copy_string(cdr->dst, S_OR(c->macroexten,c->exten), sizeof(cdr->dst));
+			ast_copy_string(cdr->dcontext, S_OR(c->macrocontext,c->context), sizeof(cdr->dcontext));
 			/* Unique call identifier */
 			ast_copy_string(cdr->uniqueid, c->uniqueid, sizeof(cdr->uniqueid));
+			/* Linked call identifier */
+			ast_copy_string(cdr->linkedid, c->linkedid, sizeof(cdr->linkedid));
 		}
 	}
 	return 0;
@@ -894,6 +898,7 @@
 
 			/* Copy account code et-al */	
 			ast_copy_string(cdr->accountcode, c->accountcode, sizeof(cdr->accountcode));
+			ast_copy_string(cdr->linkedid, c->linkedid, sizeof(cdr->linkedid));
 			if (!ast_check_hangup(c) && strcmp(S_OR(c->macroexten, c->exten),"h") != 0) {
 				/* Destination information */ /* XXX privilege macro* ? */
 				ast_copy_string(cdr->dst, S_OR(c->macroexten, c->exten), sizeof(cdr->dst));

Modified: team/murf/CDRfix5/main/channel.c
URL: http://svn.digium.com/view/asterisk/team/murf/CDRfix5/main/channel.c?view=diff&rev=69516&r1=69515&r2=69516
==============================================================================
--- team/murf/CDRfix5/main/channel.c (original)
+++ team/murf/CDRfix5/main/channel.c Thu Jun 14 23:45:04 2007
@@ -3394,6 +3394,28 @@
 }
 
 /*!
+  \brief Propagate the linked id from one channel to the other
+
+*/
+void ast_channel_set_linkgroup(struct ast_channel *chan, struct ast_channel *peer)
+{
+	if (ast_strlen_zero(chan->linkedid) && ast_strlen_zero(peer->linkedid)) {
+		ast_string_field_set(chan, linkedid, chan->uniqueid);
+		ast_string_field_set(peer, linkedid, chan->uniqueid);
+	} else if (!ast_strlen_zero(chan->linkedid) && ast_strlen_zero(peer->linkedid)) {
+		ast_string_field_set(peer, linkedid, chan->linkedid);
+	} else if (ast_strlen_zero(chan->linkedid) && !ast_strlen_zero(peer->linkedid)) {
+		ast_string_field_set(chan, linkedid, peer->linkedid);
+	} else {
+		if (strcmp(chan->linkedid,peer->linkedid)!= 0)
+			ast_log(LOG_WARNING,"linkid clash between (chan)%s and (peer) %s.\n",
+					chan->linkedid, peer->linkedid);
+		ast_string_field_set(peer, linkedid, chan->linkedid); /* let the chan take precedence, then */
+	}
+}
+
+	
+/*!
   \brief Masquerade a channel
 
   \note Assumes channel will be locked when called
@@ -3456,6 +3478,9 @@
 
 	/* Mangle the name of the clone channel */
 	ast_string_field_set(clone, name, masqn);
+
+	/* share linked id's */
+	ast_channel_set_linkgroup(original, clone);
 	
 	/* Notify any managers of the change, first the masq then the other */
 	manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", newn, masqn, clone->uniqueid);

Modified: team/murf/CDRfix5/res/res_features.c
URL: http://svn.digium.com/view/asterisk/team/murf/CDRfix5/res/res_features.c?view=diff&rev=69516&r1=69515&r2=69516
==============================================================================
--- team/murf/CDRfix5/res/res_features.c (original)
+++ team/murf/CDRfix5/res/res_features.c Thu Jun 14 23:45:04 2007
@@ -1626,8 +1626,8 @@
 			(int)cdr->start.tv_sec, (int)cdr->answer.tv_sec, (int)cdr->end.tv_sec);
 	ast_log(LOG_NOTICE, "CDR: duration: %ld;  billsec: %ld;  disposition: %ld; amaflags: %ld;\n",
 			cdr->duration, cdr->billsec, cdr->disposition, cdr->amaflags);
-	ast_log(LOG_NOTICE, "CDR: acctcode: %s;  flags: %x;  uniqueid: %s; userfield: %s;\n",
-			cdr->accountcode, cdr->flags, cdr->uniqueid, cdr->userfield);
+	ast_log(LOG_NOTICE, "CDR: acctcode: %s;  flags: %x;  uniqueid: %s; userfield: %s; linkedID:%s\n",
+			cdr->accountcode, cdr->flags, cdr->uniqueid, cdr->userfield, cdr->linkedid);
 	ast_log(LOG_NOTICE, "CDR: next: %x;\n",
 			(unsigned int)cdr->next);
 	ast_log(LOG_NOTICE, "===== done ====\n");
@@ -1643,13 +1643,30 @@
 			chan->name, chan->appl, chan->data, chan->context, chan->exten, chan->priority);
 	ast_log(LOG_NOTICE, "CHAN: acctcode: %s;  dialcontext: %s; amaflags: %x; maccontxt: %s;  macexten: %s; macpri: %d;\n",
 			chan->accountcode, chan->dialcontext, chan->amaflags, chan->macrocontext, chan->macroexten, chan->macropriority);
-	ast_log(LOG_NOTICE, "CHAN: masq: %x;  masqr: %x; _bridge: %x; uniqueID: %s;\n",
-			(unsigned int)chan->masq, (unsigned int)chan->masqr, (unsigned int)chan->_bridge, chan->uniqueid);
+	ast_log(LOG_NOTICE, "CHAN: masq: %x;  masqr: %x; _bridge: %x; uniqueID: %s; linkedID:%s\n",
+			(unsigned int)chan->masq, (unsigned int)chan->masqr, (unsigned int)chan->_bridge, chan->uniqueid, chan->linkedid);
 	if (chan->masqr)
 		ast_log(LOG_NOTICE, "CHAN: masquerading as: %s;  cdr: %x;\n",
 				chan->masqr->name, (unsigned int)chan->masqr->cdr);
 		
 	ast_log(LOG_NOTICE, "===== done ====\n");
+}
+
+void ast_channel_set_linkgroup(struct ast_channel *chan, struct ast_channel *peer)
+{
+	if (ast_strlen_zero(chan->linkedid) && ast_strlen_zero(peer->linkedid)) {
+		ast_string_field_set(chan, linkedid, chan->uniqueid);
+		ast_string_field_set(peer, linkedid, chan->uniqueid);
+	} else if (!ast_strlen_zero(chan->linkedid) && ast_strlen_zero(peer->linkedid)) {
+		ast_string_field_set(peer, linkedid, chan->linkedid);
+	} else if (ast_strlen_zero(chan->linkedid) && !ast_strlen_zero(peer->linkedid)) {
+		ast_string_field_set(chan, linkedid, peer->linkedid);
+	} else {
+		if (strcmp(chan->linkedid,peer->linkedid)!= 0)
+			ast_log(LOG_WARNING,"linkid clash between (chan)%s and (peer) %s.\n",
+					chan->linkedid, peer->linkedid);
+		ast_string_field_set(peer, linkedid, chan->linkedid); /* let the chan take precedence, then */
+	}
 }
 
 int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast_bridge_config *config)
@@ -1717,33 +1734,39 @@
 	ast_copy_string(orig_channame,chan->name,sizeof(orig_channame));
 	ast_copy_string(orig_peername,peer->name,sizeof(orig_peername));
 	
-	if (chan->cdr) {
-		ast_set_flag(chan->cdr, AST_CDR_FLAG_MAIN);
-		bridge_cdr = ast_cdr_dup(chan->cdr);
-	} 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));
+	/* two channels are being marked as linked here */
+	ast_channel_set_linkgroup(chan,peer);
+	
+	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);
+			bridge_cdr = ast_cdr_dup(chan->cdr);
 		} else {
-			ast_cdr_start(bridge_cdr);
-		}
-	}
-
-	ast_cdr_answer(bridge_cdr);
+			/* 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_copy_string(bridge_cdr->linkedid,chan->linkedid,sizeof(bridge_cdr->linkedid));
+	}
 	
 	
 	for (;;) {
@@ -1899,117 +1922,75 @@
 			ast_frfree(f);
 
 	}
-	ast_channel_log("XXXXXXXXXXX  Post-bridge CHAN Channel info XXXXXXXXXXX", chan);
-	ast_channel_log("XXXXXXXXXXX  Post-bridge PEER Channel info XXXXXXXXXXX", peer);
-
-	ast_cdr_end(bridge_cdr);
-
+	/* obey the NoCDR() wishes. */
+	if (!chan->cdr || (chan->cdr && !ast_test_flag(chan->cdr, AST_CDR_FLAG_POST_DISABLED))) {
+
+		ast_channel_log("XXXXXXXXXXX  Post-bridge CHAN Channel info XXXXXXXXXXX", chan);
+		ast_channel_log("XXXXXXXXXXX  Post-bridge PEER Channel info XXXXXXXXXXX", peer);
+		
+		ast_cdr_end(bridge_cdr);
+		
 #ifdef CDR_FIX_NOT_ANYMORE
-	/* I'm not going to ask the channel drivers to track transfers -- That will come with 
-	   the "new" event-based cdr system someday -- I get the main facts by just generating
-	   a CDR for a bridge. This'll simplify life considerably, I hope */
-
-	/* last minute mods -- a transfer will change the CHAN to point to a different
-	   channel; recopy the src, clid info for CHAN into the bridge cdr now */
-	if (strcmp(orig_channame,chan->name) != 0 && (strlen(chan->name) <= 8 || strcmp(chan->name+strlen(chan->name)-8 ,"<ZOMBIE>") != 0)) {
-		ast_verbose(VERBOSE_PREFIX_3 "EO Bridge: Chan name changed. %s -> %s\n", orig_channame, chan->name);
-
-		ast_copy_string(bridge_cdr->channel, chan->name, sizeof(bridge_cdr->channel));
-		ast_copy_string(bridge_cdr->uniqueid, chan->uniqueid, sizeof(bridge_cdr->uniqueid));
-		ast_cdr_setcid(bridge_cdr, chan);
-		ast_copy_string(bridge_cdr->accountcode, chan->accountcode, sizeof(bridge_cdr->accountcode));
-	} else if (strcmp(orig_channame,chan->name) != 0 && strlen(chan->name) > 8 && strcmp(chan->name+strlen(chan->name)-8 ,"<ZOMBIE>") == 0) {
-		/* modify the lastapp, lastdata to reflect the Blind Xfer */
-		strcpy(bridge_cdr->lastapp,"BLINDXFER");
-		bridge_cdr->lastdata[0] = 0;
-	}
-	
-
-	if (chan->cdr && strcmp(orig_channame,chan->name) != 0 && !chan->masqr) { /* for when bridge ends after only 1 HF (blind assisted xfer) */
-		ast_verbose(VERBOSE_PREFIX_3 "Chan name change: blind xfer implied, reset start/answer\n");
-		bridge_cdr->start = chan->cdr->start;
-		bridge_cdr->answer = chan->cdr->start; /* the answer time got zeroed?!? */
-	}
-	
-	if (chan->masqr) {
-		/* push threewaycdr to the end of the list */
-		for (threewaycdr = chan->masqr->cdr; threewaycdr; threewaycdr=threewaycdr->next)
-		{
-			if (strcmp(threewaycdr->lastapp,"3WAY")==0) {
-				ast_verbose(VERBOSE_PREFIX_3 "Masq: 3WAY found\n");
-				strcpy(bridge_cdr->lastapp, threewaycdr->lastapp);
-				strcpy(bridge_cdr->lastdata, threewaycdr->lastdata);
-				bridge_cdr->start = threewaycdr->start;
-				bridge_cdr->answer = threewaycdr->answer;
-				strcpy(bridge_cdr->uniqueid, threewaycdr->uniqueid);
-				break;
+		/* I'm not going to ask the channel drivers to track transfers -- That will come with 
+		   the "new" event-based cdr system someday -- I get the main facts by just generating
+		   a CDR for a bridge. This'll simplify life considerably, I hope */
+		
+		/* last minute mods -- a transfer will change the CHAN to point to a different
+		   channel; recopy the src, clid info for CHAN into the bridge cdr now */
+		if (strcmp(orig_channame,chan->name) != 0 && (strlen(chan->name) <= 8 || strcmp(chan->name+strlen(chan->name)-8 ,"<ZOMBIE>") != 0)) {
+			ast_verbose(VERBOSE_PREFIX_3 "EO Bridge: Chan name changed. %s -> %s\n", orig_channame, chan->name);
+			
+			ast_copy_string(bridge_cdr->channel, chan->name, sizeof(bridge_cdr->channel));
+			ast_copy_string(bridge_cdr->uniqueid, chan->uniqueid, sizeof(bridge_cdr->uniqueid));
+			ast_cdr_setcid(bridge_cdr, chan);
+			ast_copy_string(bridge_cdr->accountcode, chan->accountcode, sizeof(bridge_cdr->accountcode));
+		} else if (strcmp(orig_channame,chan->name) != 0 && strlen(chan->name) > 8 && strcmp(chan->name+strlen(chan->name)-8 ,"<ZOMBIE>") == 0) {
+			/* modify the lastapp, lastdata to reflect the Blind Xfer */
+			strcpy(bridge_cdr->lastapp,"BLINDXFER");
+			bridge_cdr->lastdata[0] = 0;
+		}
+		
+		
+		if (chan->cdr && strcmp(orig_channame,chan->name) != 0 && !chan->masqr) { /* for when bridge ends after only 1 HF (blind assisted xfer) */
+			ast_verbose(VERBOSE_PREFIX_3 "Chan name change: blind xfer implied, reset start/answer\n");
+			bridge_cdr->start = chan->cdr->start;
+			bridge_cdr->answer = chan->cdr->start; /* the answer time got zeroed?!? */
+		}
+		
+		if (chan->masqr) {
+			/* push threewaycdr to the end of the list */
+			for (threewaycdr = chan->masqr->cdr; threewaycdr; threewaycdr=threewaycdr->next)
+			{
+				if (strcmp(threewaycdr->lastapp,"3WAY")==0) {
+					ast_verbose(VERBOSE_PREFIX_3 "Masq: 3WAY found\n");
+					strcpy(bridge_cdr->lastapp, threewaycdr->lastapp);
+					strcpy(bridge_cdr->lastdata, threewaycdr->lastdata);
+					bridge_cdr->start = threewaycdr->start;
+					bridge_cdr->answer = threewaycdr->answer;
+					strcpy(bridge_cdr->uniqueid, threewaycdr->uniqueid);
+					break;
+				}
 			}
 		}
-	}
 #endif
-
-	ast_cdr_log("Closing CDR attached to CHAN", chan->cdr);
-	ast_cdr_log("Closing CDR attached to PEER", peer->cdr);
-	if (chan->masqr && chan->masqr->cdr)
-		ast_cdr_log("Closing CDR attached to Masqueraded CHAN", chan->masqr->cdr);
-	if (chan->masqr && chan->masqr->cdr && chan->masqr->cdr->next)
-		ast_cdr_log("Closing NEXT CDR attached to Masqueraded CHAN", chan->masqr->cdr->next);
-	if (chan->masqr && chan->masqr->cdr && chan->masqr->cdr->next && chan->masqr->cdr->next->next)
-		ast_cdr_log("Closing NEXT NEXT CDR attached to Masqueraded CHAN", chan->masqr->cdr->next->next);
-	if (chan->masqr && chan->masqr->cdr && chan->masqr->cdr->next && chan->masqr->cdr->next->next && chan->masqr->cdr->next->next->next)
-		ast_cdr_log("Closing NEXT NEXT NEXT CDR attached to Masqueraded CHAN", chan->masqr->cdr->next->next->next);
-
-	ast_cdr_detach(bridge_cdr);
-
-	/* just in case, these channels get bridged again before hangup */
-	ast_cdr_sortof_reset(chan->cdr,0);
-	ast_cdr_sortof_reset(peer->cdr,0);
-
-#ifdef OLDCDR
-	/* arrange the cdrs: thoughts: leave CDRS in place, use a third cdr to publish; re-init the two cdrs, except for some items...*/
-	bridge_cdr = ast_cdr_alloc();
-	if (bridge_cdr) {
-		if (chan->cdr && peer->cdr) { /* both of them? merge */
-			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);
-			ast_cdr_discard(chan->cdr); /* no posting these guys */
-			
-			/* absorb the peer cdr */
-			ast_cdr_merge(bridge_cdr, peer->cdr);
-			ast_cdr_discard(peer->cdr); /* no posting these guys */
-			peer->cdr = NULL;
-			chan->cdr = bridge_cdr; /* make this available to the rest of the world via the chan while the call is in progress */
-		} else if (chan->cdr) {
-			/* take the cdr from the channel - literally */
-			ast_cdr_init(bridge_cdr,chan);
-			/* absorb this data */
-			ast_cdr_merge(bridge_cdr, chan->cdr);
-			ast_cdr_discard(chan->cdr); /* no posting these guys */
-			chan->cdr = bridge_cdr; /* make this available to the rest of the world via the chan while the call is in progress */
-		} else if (peer->cdr) {
-			/* take the cdr from the peer - literally */
-			ast_cdr_init(bridge_cdr,peer);
-			/* absorb this data */
-			ast_cdr_merge(bridge_cdr, peer->cdr);
-			ast_cdr_discard(peer->cdr); /* no posting these guys */
-			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 */
-		} else {
-			/* make up a new cdr */
-			ast_cdr_init(bridge_cdr,chan); /* eh, just pick one of them */
-			chan->cdr = bridge_cdr; /*  */
-		}
-		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);
-		}
-	}
-#endif
+		
+		ast_cdr_log("Closing CDR attached to CHAN", chan->cdr);
+		ast_cdr_log("Closing CDR attached to PEER", peer->cdr);
+		if (chan->masqr && chan->masqr->cdr)
+			ast_cdr_log("Closing CDR attached to Masqueraded CHAN", chan->masqr->cdr);
+		if (chan->masqr && chan->masqr->cdr && chan->masqr->cdr->next)
+			ast_cdr_log("Closing NEXT CDR attached to Masqueraded CHAN", chan->masqr->cdr->next);
+		if (chan->masqr && chan->masqr->cdr && chan->masqr->cdr->next && chan->masqr->cdr->next->next)
+			ast_cdr_log("Closing NEXT NEXT CDR attached to Masqueraded CHAN", chan->masqr->cdr->next->next);
+		if (chan->masqr && chan->masqr->cdr && chan->masqr->cdr->next && chan->masqr->cdr->next->next && chan->masqr->cdr->next->next->next)
+			ast_cdr_log("Closing NEXT NEXT NEXT CDR attached to Masqueraded CHAN", chan->masqr->cdr->next->next->next);
+		
+		ast_cdr_detach(bridge_cdr);
+	
+		/* just in case, these channels get bridged again before hangup */
+		ast_cdr_sortof_reset(chan->cdr,0);
+		ast_cdr_sortof_reset(peer->cdr,0);
+	}
 	return res;
 }
 




More information about the asterisk-commits mailing list