From bebdbf33819aad5b7bf181f3fddd2fb25bea59b1 Mon Sep 17 00:00:00 2001 From: Matthew Jordan Date: Mon, 25 Jun 2012 19:39:03 +0000 Subject: [PATCH] Fix incorrect duration reporting in CDRs created in batch mode Certain places in core/cdr.c would, if the duration value were 0, calculate the duration as being the delta between the current time and the time at which the CDR record was started. While this does not typically cause a problem in non-batch mode, this can cause an issue in batch mode where CDR records are gathered and written long after those calls have ended. In particular, this affects calls that were never answered, as those are expected to have a duration of 0. Often, this would result in CDR logs with a significant number of calls with lengthy durations, but dispositions of "BUSY". Note that this does not affect cdr_csv, as that backend does not use ast_cdr_getvar and instead directly reports the duration value. The affected core backends include cdr_apative_odbc and cdr_custom; other extended or deprecated CDR backends may potentially still directly manipulate the duration values. (issue ASTERISK-19860) Reported by: Thomas Arimont (issue AST-883) Reported by: Thomas Arimont Tested by: Matt Jordan Review: https://reviewboard.asterisk.org/r/1996/ ........ Merged revisions 369351 from http://svn.asterisk.org/svn/asterisk/branches/1.8 ........ Merged revisions 369369 from http://svn.asterisk.org/svn/asterisk/branches/10 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@369370 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- main/cdr.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/main/cdr.c b/main/cdr.c index 3fc8ef1dec..7847dc4562 100644 --- a/main/cdr.c +++ b/main/cdr.c @@ -301,9 +301,9 @@ void ast_cdr_getvar(struct ast_cdr *cdr, const char *name, char **ret, char *wor cdr_get_tv(cdr->answer, raw ? NULL : fmt, workspace, workspacelen); else if (!strcasecmp(name, "end")) cdr_get_tv(cdr->end, raw ? NULL : fmt, workspace, workspacelen); - else if (!strcasecmp(name, "duration")) - snprintf(workspace, workspacelen, "%ld", cdr->duration ? cdr->duration : (long)ast_tvdiff_ms(ast_tvnow(), cdr->start) / 1000); - else if (!strcasecmp(name, "billsec")) + else if (!strcasecmp(name, "duration")) { + snprintf(workspace, workspacelen, "%ld", cdr->end.tv_sec != 0 ? cdr->duration : (long)ast_tvdiff_ms(ast_tvnow(), cdr->start) / 1000); + } else if (!strcasecmp(name, "billsec")) snprintf(workspace, workspacelen, "%ld", cdr->billsec || cdr->answer.tv_sec == 0 ? cdr->billsec : (long)ast_tvdiff_ms(ast_tvnow(), cdr->answer) / 1000); else if (!strcasecmp(name, "disposition")) { if (raw) {