Fix incorrect billing duration reported when batch mode is enabled
authorMatthew Jordan <>
Thu, 11 Oct 2012 15:44:38 +0000 (15:44 +0000)
committerMatthew Jordan <>
Thu, 11 Oct 2012 15:44:38 +0000 (15:44 +0000)
Similar to r369351, the billing duration can be skewed when batch mode is
enabled.  This happened much more rarely than the duration, as it only
occured when the call was answered (thereby indicating an actual answer
time) and immediately hung up on (indicating a billsec of 0).  Since
a billing time of '0' can either mean that the call immediately ended
or that the CDR was improperly answered, we have to use additional information
to know whether or not we can trust the CDR billsec value.  Prior to this
patch, we looked to see if we had a valid answer time.  If we did, and
billsec was zero, we used the current time to calculate what billsec value
we could from the CDR being written.  If batch mode is enabled, this will
incorrectly report a billsec value being much greater than the actual
duration of the call.

Instead of relying on the presence of an answer time to know whether or not
we can re-calculate the billsec for the CDR, we now also use the presence
of the CDR's end time to know if we need to re-calculate or whether we can
trust the billsec value that we have.  This prevents erroneous jumps in the
billsec value, while still making sure that in the worst case, some billing
time will be calculated.

(closes issue AST-1016)
Reported by: Thomas Arimont
Tested by: Thomas Arimont

Merged revisions 374843 from

Merged revisions 374844 from

Merged revisions 374845 from

git-svn-id: 65c4cc65-6c06-0410-ace0-fbb531ad65f3


index a6ac5be..9c4efee 100644 (file)
@@ -306,9 +306,9 @@ void ast_cdr_getvar(struct ast_cdr *cdr, const char *name, char **ret, char *wor
                cdr_get_tv(cdr->end, raw ? NULL : fmt, workspace, workspacelen);
        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")) {
+       } else if (!strcasecmp(name, "billsec")) {
+               snprintf(workspace, workspacelen, "%ld", (cdr->billsec || !ast_tvzero(cdr->end) || ast_tvzero(cdr->answer)) ? cdr->billsec : (long)ast_tvdiff_ms(ast_tvnow(), cdr->answer) / 1000);     
+       } else if (!strcasecmp(name, "disposition")) {
                if (raw) {
                        snprintf(workspace, workspacelen, "%ld", cdr->disposition);
                } else {