--- cdr.c_orig 2010-04-23 00:49:07.000000000 +0300 +++ cdr.c 2010-06-03 15:03:58.000000000 +0300 @@ -260,6 +260,10 @@ snprintf(workspace, workspacelen, "%ld", cdr->duration); else if (!strcasecmp(name, "billsec")) snprintf(workspace, workspacelen, "%ld", cdr->billsec); + else if (!strcasecmp(name, "rduration")) + snprintf(workspace, workspacelen, "%f", cdr->rduration); + else if (!strcasecmp(name, "rbillsec")) + snprintf(workspace, workspacelen, "%f", cdr->rbillsec); else if (!strcasecmp(name, "disposition")) { if (raw) { snprintf(workspace, workspacelen, "%ld", cdr->disposition); @@ -291,7 +295,7 @@ static const char *cdr_readonly_vars[] = { "clid", "src", "dst", "dcontext", "channel", "dstchannel", "lastapp", "lastdata", "start", "answer", "end", "duration", "billsec", "disposition", "amaflags", "accountcode", "uniqueid", - "userfield", NULL }; + "userfield", "rduration", "rbillsec", NULL }; /*! Set a CDR channel variable \note You can't set the CDR variables that belong to the actual CDR record, like "billsec". */ @@ -600,6 +604,8 @@ from->end = ast_tv(0,0); /* we actively "steal" these values */ 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; + to->rduration = (to->end.tv_sec - to->start.tv_sec)*1.0 + (to->end.tv_usec - to->start.tv_usec)/1000000.0; + to->rbillsec = (to->end.tv_sec - to->answer.tv_sec)*1.0 + (to->end.tv_usec - to->answer.tv_usec)/1000000.0; } /* else, nothing to do */ } else { @@ -607,6 +613,8 @@ from->end = ast_tv(0,0); /* we actively "steal" these values */ to->duration = to->end.tv_sec - to->start.tv_sec; to->billsec = ast_tvzero(to->answer) ? 0 : to->end.tv_sec - to->answer.tv_sec; + to->rduration = (to->end.tv_sec - to->start.tv_sec)*1.0 + (to->end.tv_usec - to->start.tv_usec)/1000000.0; + to->rbillsec = ast_tvzero(to->answer) ? 0 : (to->end.tv_sec - to->answer.tv_sec)*1.0 + (to->end.tv_usec - to->answer.tv_usec)/1000000.0; } } if (to->disposition < from->disposition) { @@ -896,15 +904,19 @@ if (ast_tvzero(cdr->start)) { ast_log(LOG_WARNING, "CDR on channel '%s' has not started\n", S_OR(cdr->channel, "")); cdr->disposition = AST_CDR_FAILED; - } else + } else { cdr->duration = cdr->end.tv_sec - cdr->start.tv_sec; + cdr->rduration = (cdr->end.tv_sec - cdr->start.tv_sec)*1.0 + (cdr->end.tv_usec - cdr->start.tv_usec)/1000000.0; + } if (ast_tvzero(cdr->answer)) { if (cdr->disposition == AST_CDR_ANSWERED) { ast_log(LOG_WARNING, "CDR on channel '%s' has no answer time but is 'ANSWERED'\n", S_OR(cdr->channel, "")); cdr->disposition = AST_CDR_FAILED; } - } else + } else { cdr->billsec = cdr->end.tv_sec - cdr->answer.tv_sec; + cdr->rbillsec = (cdr->end.tv_sec - cdr->answer.tv_sec)*1.0 + (cdr->end.tv_usec - cdr->answer.tv_usec)/1000000.0; + } } } @@ -1094,6 +1106,8 @@ memset(&cdr->answer, 0, sizeof(cdr->answer)); cdr->billsec = 0; cdr->duration = 0; + cdr->rbillsec = 0; + cdr->rduration = 0; ast_cdr_start(cdr); cdr->disposition = AST_CDR_NOANSWER; } @@ -1120,6 +1134,8 @@ memset(&cdr->answer, 0, sizeof(cdr->answer)); cdr->billsec = 0; cdr->duration = 0; + cdr->rbillsec = 0; + cdr->rduration = 0; ast_cdr_start(cdr); cdr->disposition = AST_CDR_NULL; }