mirror of
https://github.com/asterisk/asterisk.git
synced 2025-10-20 19:53:10 +00:00
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:
74
main/cdr.c
74
main/cdr.c
@@ -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)
|
||||||
|
@@ -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 {
|
||||||
|
Reference in New Issue
Block a user