From: Steve Murphy Date: Thu, 31 Jul 2008 19:23:42 +0000 (+0000) Subject: (closes issue #11849) X-Git-Tag: 1.4.22-rc1~46 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=08450d1a93d56d944f04f5ee87dcde6db6e5b5af;p=thirdparty%2Fasterisk.git (closes issue #11849) Reported by: greyvoip Tested by: murf OK, a few days of debugging, a bunch of instrumentation in chan_sip, main/channel.c, main/pbx.c, etc. and 5 solid notebook pages of notes later, I have made the small tweek necc. to get the start time right on the second CDR when: A Calls B B answ. A hits Xfer button on sip phone, A dials C and hits the OK button, A hangs up C answers ringing phone B and C converse B and/or C hangs up But does not harm the scenario where: A Calls B B answ. B hits xfer button on sip phone, B dials C and hits the OK button, B hangs up C answers ringing phone A and C converse A and/or C hangs up The difference in start times on the second CDR is because of a Masquerade on the B channel when the xfer number is sent. It ends up replacing the CDR on the B channel with a duplicate, which ends up getting tossed out. We keep a pointer to the first CDR, and update *that* after the bridge closes. But, only if the CDR has changed. I hope this change is specific enough not to muck up any current CDR-based apps. In my defence, I assert that the previous information was wrong, and this change fixes it, and possibly other similar scenarios. I wonder if I should be doing the same thing for the channel, as I did for the peer, but I can't think of a scenario this might affect. I leave it, then, as an exersize for the users, to find the scenario where the chan's CDR changes and loses the proper start time. git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.4@134883 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- diff --git a/res/res_features.c b/res/res_features.c index d1a481eeec..e326a89606 100644 --- a/res/res_features.c +++ b/res/res_features.c @@ -1405,6 +1405,7 @@ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast struct ast_option_header *aoh; struct ast_bridge_config backup_config; struct ast_cdr *bridge_cdr = NULL; + struct ast_cdr *orig_peer_cdr = NULL; memset(&backup_config, 0, sizeof(backup_config)); @@ -1442,6 +1443,7 @@ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast ast_copy_string(orig_channame,chan->name,sizeof(orig_channame)); ast_copy_string(orig_peername,peer->name,sizeof(orig_peername)); + orig_peer_cdr = peer->cdr; if (!chan->cdr || (chan->cdr && !ast_test_flag(chan->cdr, AST_CDR_FLAG_POST_DISABLED))) { @@ -1476,8 +1478,9 @@ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast 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) + if (peer->cdr) { ast_set_flag(peer->cdr, AST_CDR_FLAG_BRIDGED); + } } for (;;) { @@ -1652,12 +1655,18 @@ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast ast_cdr_detach(bridge_cdr); /* just in case, these channels get bridged again before hangup */ - if (chan->cdr) + if (chan->cdr) { ast_cdr_specialized_reset(chan->cdr,0); - if (peer->cdr) - ast_cdr_specialized_reset(peer->cdr,0); + } + if (peer->cdr) { + if (orig_peer_cdr && peer->cdr != orig_peer_cdr) { + /* this can only happen if there was a transfer, methinks */ + ast_cdr_specialized_reset(orig_peer_cdr,0); + } else { + ast_cdr_specialized_reset(peer->cdr,0); + } + } } - return res; }