[asterisk-bugs] [Asterisk 0013022]: CDR does not get written

Asterisk Bug Tracker noreply at bugs.digium.com
Fri Aug 1 10:11:31 CDT 2008


A NOTE has been added to this issue. 
====================================================================== 
http://bugs.digium.com/view.php?id=13022 
====================================================================== 
Reported By:                falves11
Assigned To:                murf
====================================================================== 
Project:                    Asterisk
Issue ID:                   13022
Category:                   CDR/General
Reproducibility:            always
Severity:                   major
Priority:                   normal
Status:                     assigned
Asterisk Version:           SVN 
SVN Branch (only for SVN checkouts, not tarball releases):  trunk 
SVN Revision (number only!): 128951 
Disclaimer on File?:        N/A 
Request Review:              
====================================================================== 
Date Submitted:             2008-07-08 08:59 CDT
Last Modified:              2008-08-01 10:11 CDT
====================================================================== 
Summary:                    CDR does not get written
Description: 
I upgraded to the current version, 128951, last night, and realized that
the CDR does not get written to the database unless I use "resetCDR(w)" in
the "h" extension, which constitutes a profound change from the past
behavior. For example, I have this dialplan:

[default]
exten
=>_X.,1,Set(ARRAY(CARRIERLIST,Z,NANI,CLIST,PLIST)=${MINIXEL_ROUTING(${EXTEN},${anix},${X})})
exten =>_X.,n,NoCDR()
exten =>_X.,n,GotoIf($[${Z} = 0]?default,rejected,1)
exten =>_X.,n,Set(CALLERID(all)=${NANI})
exten =>_X.,n,Set(TIMEOUT(absolute)=3600)
exten =>_X.,n,Set(i=1)
exten =>_X.,n,ForkCDR()
exten =>_X.,n,While($[${i} <= ${Z}])
exten =>_X.,n,Set(CDR(userfield)=${CLIST}${CUT(PLIST,-,${i})})
exten =>_X.,n,Set(CDR(accountcode)=${SIPIP:1})
exten =>_X.,n,Dial(${CUT(CARRIERLIST,-,${i})},45,L(3600000)) ;dial once
;exten =>_X.,n,Verbose(0,"${DIALSTATUS} Result: ${SIPIP:1}")
exten =>_X.,n,ResetCDR(w)
exten =>_X.,n,GotoIf($["${DIALSTATUS}" = "BUSY"]?default,dropcall,1)
exten =>_X.,n,GotoIf($["${DIALSTATUS}" = "NOANSWER"]?default,dropcall,1)
exten =>_X.,n,Set(i=$[${i} + 1])
exten =>_X.,n,EndWhile
exten =>_X.,n,Hangup(34)
exten => h,1,ResetCDR(w) ;THIS IS REQUIRED TO GET CDR IN TRUNK 128951
exten => dropcall,1,Hangup()
exten => rejected,1,Verbose(0,"Rejected:" ${destino}-From: ${SIPIP:1})
exten => rejected,2,Hangup(34)

====================================================================== 

---------------------------------------------------------------------- 
 (0090980) murf (administrator) - 2008-08-01 10:11
 http://bugs.digium.com/view.php?id=13022#c90980 
---------------------------------------------------------------------- 
Trunk inherited many things from 1.4, and 1.4 from 1.2, etc.

Since the beginning, NoCDR() was written to strip the CDR from a channel.

When it finished, you had a null CDR ptr on the channel.

ForkCDR, in the first few lines of its code, gets the CDR ptr from the
channel, and then traverses the next pointers on the cdr structs. So, if
the CDR ptr is null, it's guaranteed to crash.

Why it doesn't crash, is because at several points in the PBX engine, if 
the CDR pointer on the channel is null, it allocates a new one.

So, NoCDR() was really a misnomer. It didn't say "Don't give me a CDR at
all", it would say "Do a weird reset of the CDR".

The description for the command in (core show application NoCDR) says:
 "NoCDR(): This application will tell Asterisk not to maintain a CDR for
the current call."
was blatantly false, as the usual result of calling NoCDR(), was that
you'd get a CDR output for the call anyway!

What I did in trunk, was to make NoCDR work as advertised. I don't destroy
the cdr struct, I just mark it with "AST_CDR_FLAG_DISABLED"-- when it comes
time to post, the cdr is skipped and freed instead.

ForkCDR never explicitly reversed the action of a NoCDR. It was never
documented to, nor is there any code to do such. What you are seeing is the
fact that NoCDR() never really worked before, and now it does, which is
messing you up.

So, if ResetCDR(w) is doing the trick for you now, you might want to stick
with it! The 'w' will post the existing cdr to the backends, and leave you
with a freshly initialized cdr to work with (ideal for forkcdr, I guess). 

Issue History 
Date Modified    Username       Field                    Change               
====================================================================== 
2008-08-01 10:11 murf           Note Added: 0090980                          
======================================================================




More information about the asterisk-bugs mailing list