This patch is meant to fix 8433; where clid and src are lost via bridging.

git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.4@71230 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
Steve Murphy
2007-06-23 03:29:48 +00:00
parent d0bc56b953
commit 6f6ffbb5c5
2 changed files with 77 additions and 10 deletions

View File

@@ -499,10 +499,66 @@ static void cdr_merge_vars(struct ast_cdr *to, struct ast_cdr *from)
void ast_cdr_merge(struct ast_cdr *to, struct ast_cdr *from) void ast_cdr_merge(struct ast_cdr *to, struct ast_cdr *from)
{ {
struct ast_cdr *tcdr; struct ast_cdr *zcdr;
struct ast_cdr *lto = NULL;
struct ast_cdr *lfrom = NULL;
int discard_from = 0;
if (!to || !from) if (!to || !from)
return; return;
/* don't merge into locked CDR's -- it's bad business */
if (ast_test_flag(to, AST_CDR_FLAG_LOCKED)) {
zcdr = to; /* safety valve? */
while (to->next) {
lto = to;
to = to->next;
}
if (ast_test_flag(to, AST_CDR_FLAG_LOCKED)) {
ast_log(LOG_WARNING, "Merging into locked CDR... no choice.");
to = zcdr; /* safety-- if all there are is locked CDR's, then.... ?? */
lto = NULL;
}
}
if (ast_test_flag(from, AST_CDR_FLAG_LOCKED)) {
discard_from = 1;
if (lto) {
struct ast_cdr *llfrom;
/* insert the from stuff after lto */
lto->next = from;
lfrom = from;
while (lfrom && lfrom->next) {
if (!lfrom->next->next)
llfrom = lfrom;
lfrom = lfrom->next;
}
/* rip off the last entry and put a copy of the to at the end */
llfrom->next = to;
from = lfrom;
} else {
/* save copy of the current *to cdr */
struct ast_cdr tcdr;
struct ast_cdr *llfrom;
memcpy(&tcdr, to, sizeof(tcdr));
/* copy in the locked from cdr */
memcpy(to, from, sizeof(*to));
lfrom = from;
while (lfrom && lfrom->next) {
if (!lfrom->next->next)
llfrom = lfrom;
lfrom = lfrom->next;
}
from->next = NULL;
/* rip off the last entry and put a copy of the to at the end */
if (llfrom == from)
to = to->next = ast_cdr_dup(&tcdr);
else
to = llfrom->next = ast_cdr_dup(&tcdr);
from = lfrom;
}
}
if (!ast_tvzero(from->start)) { if (!ast_tvzero(from->start)) {
if (!ast_tvzero(to->start)) { if (!ast_tvzero(to->start)) {
@@ -572,6 +628,10 @@ void ast_cdr_merge(struct ast_cdr *to, struct ast_cdr *from)
ast_copy_string(to->src, from->src, sizeof(to->src)); ast_copy_string(to->src, from->src, sizeof(to->src));
from->src[0] = 0; /* theft */ from->src[0] = 0; /* theft */
} }
if (ast_strlen_zero(to->clid) && !ast_strlen_zero(from->clid)) {
ast_copy_string(to->clid, from->clid, sizeof(to->clid));
from->clid[0] = 0; /* theft */
}
if (ast_strlen_zero(to->dst) && !ast_strlen_zero(from->dst)) { if (ast_strlen_zero(to->dst) && !ast_strlen_zero(from->dst)) {
ast_copy_string(to->dst, from->dst, sizeof(to->dst)); ast_copy_string(to->dst, from->dst, sizeof(to->dst));
from->dst[0] = 0; /* theft */ from->dst[0] = 0; /* theft */
@@ -606,12 +666,14 @@ void ast_cdr_merge(struct ast_cdr *to, struct ast_cdr *from)
/* last, but not least, we need to merge any forked CDRs to the 'to' cdr */ /* last, but not least, we need to merge any forked CDRs to the 'to' cdr */
while (from->next) { while (from->next) {
/* just rip 'em off the 'from' and insert them on the 'to' */ /* just rip 'em off the 'from' and insert them on the 'to' */
tcdr = from->next; zcdr = from->next;
from->next = tcdr->next; from->next = zcdr->next;
tcdr->next = NULL; zcdr->next = NULL;
/* tcdr is now ripped from the current list; */ /* zcdr is now ripped from the current list; */
ast_cdr_append(to, tcdr); ast_cdr_append(to, zcdr);
} }
if (discard_from)
ast_cdr_discard(from);
} }
void ast_cdr_start(struct ast_cdr *cdr) void ast_cdr_start(struct ast_cdr *cdr)

View File

@@ -1558,11 +1558,14 @@ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast
/* absorb the channel cdr */ /* absorb the channel cdr */
ast_cdr_merge(bridge_cdr, chan->cdr); ast_cdr_merge(bridge_cdr, chan->cdr);
ast_cdr_discard(chan->cdr); /* no posting these guys */ 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 */
/* absorb the peer cdr */ /* absorb the peer cdr */
ast_cdr_merge(bridge_cdr, peer->cdr); ast_cdr_merge(bridge_cdr, peer->cdr);
ast_cdr_discard(peer->cdr); /* no posting these guys */ 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; 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 */ 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) { } else if (chan->cdr) {
@@ -1570,14 +1573,16 @@ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast
ast_cdr_init(bridge_cdr,chan); ast_cdr_init(bridge_cdr,chan);
/* absorb this data */ /* absorb this data */
ast_cdr_merge(bridge_cdr, chan->cdr); ast_cdr_merge(bridge_cdr, chan->cdr);
ast_cdr_discard(chan->cdr); /* no posting these guys */ 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 */ 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) { } else if (peer->cdr) {
/* take the cdr from the peer - literally */ /* take the cdr from the peer - literally */
ast_cdr_init(bridge_cdr,peer); ast_cdr_init(bridge_cdr,peer);
/* absorb this data */ /* absorb this data */
ast_cdr_merge(bridge_cdr, peer->cdr); ast_cdr_merge(bridge_cdr, peer->cdr);
ast_cdr_discard(peer->cdr); /* no posting these guys */ 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 */
peer->cdr = NULL; 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 */ peer->cdr = bridge_cdr; /* make this available to the rest of the world via the chan while the call is in progress */
} else { } else {