From c18da9963e2c253afea315b844be7e563b782988 Mon Sep 17 00:00:00 2001 From: mnicholson Date: Thu, 21 May 2009 15:25:50 +0000 Subject: This commit prevents cdr records with AST_CDR_FLAG_ANSLOCKED and AST_CDR_FLAG_LOCKED from being updated in certain cases. This is accomplished by adding two functions to update the answer time and disposition of calls that checks for the proper lock flags. These functions are used in the ast_bridge_call() function so that ForkCDR(A) calls are respected. This patch also modifies the way ast_bridge_call() chooses the cdr record to base the bridged_cdr on. Previously the first unlocked cdr record would be chosen, now instead the first cdr record is chosen and forked cdr records are moved to the bridge_cdr. This allows the original cdr record and any forked cdr records to be properly updated with answer and end times. (closes issue #13797) Reported by: sh0t Tested by: sh0t (closes issue #14744) Reported by: deepesh git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.4@195881 f38db490-d61c-443f-a65b-d21fe96a405b --- res/res_features.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'res') diff --git a/res/res_features.c b/res/res_features.c index cf2b8669d..1e98615f5 100644 --- a/res/res_features.c +++ b/res/res_features.c @@ -1668,8 +1668,8 @@ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast struct ast_bridge_config backup_config; struct ast_cdr *bridge_cdr = NULL; struct ast_cdr *orig_peer_cdr = NULL; - struct ast_cdr *chan_cdr = pick_unlocked_cdr(chan->cdr); /* the proper chan cdr, if there are forked cdrs */ - struct ast_cdr *peer_cdr = pick_unlocked_cdr(peer->cdr); /* the proper chan cdr, if there are forked cdrs */ + struct ast_cdr *chan_cdr = chan->cdr; /* the proper chan cdr, if there are forked cdrs */ + struct ast_cdr *peer_cdr = peer->cdr; /* the proper chan cdr, if there are forked cdrs */ struct ast_cdr *new_chan_cdr = NULL; /* the proper chan cdr, if there are forked cdrs */ struct ast_cdr *new_peer_cdr = NULL; /* the proper chan cdr, if there are forked cdrs */ @@ -1728,6 +1728,10 @@ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast ast_set_flag(chan_cdr, AST_CDR_FLAG_MAIN); ast_cdr_update(chan); bridge_cdr = ast_cdr_dup(chan_cdr); + /* rip any forked CDR's off of the chan_cdr and attach + * them to the bridge_cdr instead */ + bridge_cdr->next = chan_cdr->next; + chan_cdr->next = NULL; ast_copy_string(bridge_cdr->lastapp, S_OR(chan->appl, ""), sizeof(bridge_cdr->lastapp)); ast_copy_string(bridge_cdr->lastdata, S_OR(chan->data, ""), sizeof(bridge_cdr->lastdata)); } else { @@ -1759,11 +1763,11 @@ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast this is billable time for the call, even tho the caller hears nothing but ringing while the macro does its thing. */ if (peer_cdr && !ast_tvzero(peer_cdr->answer)) { - bridge_cdr->answer = peer_cdr->answer; - bridge_cdr->disposition = peer_cdr->disposition; + ast_cdr_setanswer(bridge_cdr, peer_cdr->answer); + ast_cdr_setdisposition(bridge_cdr, peer_cdr->disposition); if (chan_cdr) { - chan_cdr->answer = peer_cdr->answer; - chan_cdr->disposition = peer_cdr->disposition; + ast_cdr_setanswer(chan_cdr, peer_cdr->answer); + ast_cdr_setdisposition(chan_cdr, peer_cdr->disposition); } } else { ast_cdr_answer(bridge_cdr); -- cgit v1.2.3