aboutsummaryrefslogtreecommitdiffstats
path: root/main/cdr.c
diff options
context:
space:
mode:
Diffstat (limited to 'main/cdr.c')
-rw-r--r--main/cdr.c71
1 files changed, 54 insertions, 17 deletions
diff --git a/main/cdr.c b/main/cdr.c
index e10f8fafe..f6a90c035 100644
--- a/main/cdr.c
+++ b/main/cdr.c
@@ -469,31 +469,80 @@ struct ast_cdr *ast_cdr_alloc(void)
return x;
}
+static void cdr_merge_vars(struct ast_cdr *to, struct ast_cdr *from)
+{
+ struct ast_var_t *variablesfrom,*variablesto;
+ struct varshead *headpfrom = &to->varshead;
+ struct varshead *headpto = &from->varshead;
+ AST_LIST_TRAVERSE_SAFE_BEGIN(headpfrom, variablesfrom, entries) {
+ /* for every var in from, stick it in to */
+ const char *fromvarname, *fromvarval;
+ const char *tovarname, *tovarval;
+ fromvarname = ast_var_name(variablesfrom);
+ fromvarval = ast_var_value(variablesfrom);
+ tovarname = 0;
+
+ /* now, quick see if that var is in the 'to' cdr already */
+ AST_LIST_TRAVERSE(headpto, variablesto, entries) {
+
+ /* now, quick see if that var is in the 'to' cdr already */
+ if ( strcasecmp(fromvarname, ast_var_name(variablesto)) == 0 ) {
+ tovarname = ast_var_name(variablesto);
+ tovarval = ast_var_value(variablesto);
+ break;
+ }
+ }
+ if (tovarname && strcasecmp(fromvarval,tovarval) != 0) { /* this message here to see how irritating the userbase finds it */
+ ast_log(LOG_NOTICE, "Merging CDR's: variable %s value %s dropped in favor of value %s\n", tovarname, fromvarval, tovarval);
+ continue;
+ } else if (tovarname && strcasecmp(fromvarval,tovarval) == 0) /* if they are the same, the job is done */
+ continue;
+
+ /*rip this var out of the from cdr, and stick it in the to cdr */
+ AST_LIST_REMOVE_CURRENT(headpfrom, entries);
+ AST_LIST_INSERT_HEAD(headpto, variablesfrom, entries);
+ }
+ AST_LIST_TRAVERSE_SAFE_END;
+}
+
void ast_cdr_merge(struct ast_cdr *to, struct ast_cdr *from)
{
if (!to || !from)
return;
+
if (!ast_tvzero(from->start)) {
if (!ast_tvzero(to->start)) {
if (ast_tvcmp(to->start, from->start) > 0 ) {
to->start = from->start; /* use the earliest time */
from->start = ast_tv(0,0); /* we actively "steal" these values */
- } else {
- ast_log(LOG_WARNING,"CDR start disagreement for %s\n", to->channel);
}
+ /* else nothing to do */
} else {
to->start = from->start;
from->start = ast_tv(0,0); /* we actively "steal" these values */
}
}
+ if (!ast_tvzero(from->answer)) {
+ if (!ast_tvzero(to->answer)) {
+ if (ast_tvcmp(to->answer, from->answer) > 0 ) {
+ to->answer = from->answer; /* use the earliest time */
+ from->answer = ast_tv(0,0); /* we actively "steal" these values */
+ }
+ /* we got the earliest answer time, so we'll settle for that? */
+ } else {
+ to->answer = from->answer;
+ from->answer = ast_tv(0,0); /* we actively "steal" these values */
+ }
+ }
if (!ast_tvzero(from->end)) {
if (!ast_tvzero(to->end)) {
if (ast_tvcmp(to->end, from->end) < 0 ) {
to->end = from->end; /* use the latest time */
from->end = ast_tv(0,0); /* we actively "steal" these values */
- } else {
- ast_log(LOG_WARNING,"CDR end disagreement for %s\n", to->channel);
+ to->duration = to->end.tv_sec - to->start.tv_sec; /* don't forget to update the duration, billsec, when we set end */
+ to->billsec = ast_tvzero(to->answer) ? 0 : to->end.tv_sec - to->answer.tv_sec;
}
+ /* else, nothing to do */
} else {
to->end = from->end;
from->end = ast_tv(0,0); /* we actively "steal" these values */
@@ -501,19 +550,6 @@ void ast_cdr_merge(struct ast_cdr *to, struct ast_cdr *from)
to->billsec = ast_tvzero(to->answer) ? 0 : to->end.tv_sec - to->answer.tv_sec;
}
}
- if (!ast_tvzero(from->answer)) {
- if (!ast_tvzero(to->answer)) {
- if (ast_tvcmp(to->answer, from->answer) > 0 ) {
- to->answer = from->answer; /* use the earliest time */
- from->answer = ast_tv(0,0); /* we actively "steal" these values */
- } else {
- ast_log(LOG_WARNING,"CDR answer disagreement for %s\n", to->channel);
- }
- } else {
- to->answer = from->answer;
- from->answer = ast_tv(0,0); /* we actively "steal" these values */
- }
- }
if (to->disposition < from->disposition) {
to->disposition = from->disposition;
from->disposition = AST_CDR_NOANSWER;
@@ -559,6 +595,7 @@ void ast_cdr_merge(struct ast_cdr *to, struct ast_cdr *from)
from->userfield[0] = 0; /* theft */
}
/* flags, varsead, ? */
+ cdr_merge_vars(from, to);
}
void ast_cdr_start(struct ast_cdr *cdr)