Summary:ASTERISK-11783: CDR written with incorrect uniqueid
Reporter:Nick Barnes (bcnit)Labels:
Date Opened:2008-04-04 10:54:44Date Closed:2008-05-26 18:21:53
Versions:Frequency of
Description:Under certain circumstances, I am experiencing multiple CDRs with the same unique ID. This is 100% reproducible.

The situation is this:

SIP device A calls SIP device B, B puts A on hold and on a second line, dials C. B speaks to C and then transfers C to A by pressing the 'transfer' button on the phone (or hanging the handset up which performs a transfer automatically).

The unique ID which is duplicated is the one allocated to the original A to B call (it is duplicated onto the B to C call).

Dialplan debugging shows that when the call from B to C is made it is allocated a genuinely unique unique ID, but when this CDR comes to be written out, the unique ID is empty and is replaced with the unique ID of the original call (i.e. the first call from A to B).

If CDR logging to MySQL is configured as documented on the voip-info wiki (with the uniqueID field being the primary key), Asterisk can't write the duplicate record out to the database.


The CDRs are shown below in the order they were written to /var/log/asterisk/cdr-csv/Master.csv:

"873","237465823","237465273","from-sip-internal","""Nick"" <237465823>","SIP/237465823-08254ed0<ZOMBIE>","IAX2/trunk-2","Dial","IAX2/trunk/447984000000||L(3600000)TWrK","2008-04-04 14:03:15","2008-04-04 14:03:28","2008-04-04 14:03:41",26,13,"ANSWERED","DOCUMENTATION","1207317767.0",""

"873","237465823","237465273","from-sip-internal","""Nick"" <237465823>","SIP/237465823-082385e8","","","","2008-04-04 14:02:47","2008-04-04 14:02:54","2008-04-04 14:03:41",54,47,"ANSWERED","DOCUMENTATION","1207317767.1",""

"873","237465823","237465273","from-sip-internal","""Nick"" <237465823>","SIP/237465273-08231560","SIP/237465823-082385e8","Dial","SIP/237465823|20|L(3600000)TtWwrKk","2008-04-04 14:02:47","2008-04-04 14:02:54","2008-04-04 14:03:41",54,47,"ANSWERED","DOCUMENTATION","1207317767.0",""

"873","237465823","s","default","237465823","IAX2/trunk-2","SIP/237465273-08231560","","","2008-04-04 14:03:15","2008-04-04 14:03:28","2008-04-04 14:03:53",38,25,"ANSWERED","DOCUMENTATION","1207317795.3",""

A calls B - ${CDR(uniqueid)} is 1207317795.0 at the start and end of the call (h extension)
B calls C - ${CDR(uniqueid)} is 1207317795.2 at the start of the call and empty at the end (h extension). The CDR for this call is written as '1207317795.0'

Not only does 1207317795.2 get written out as 1207317795.0, but the total billable cost of the call from B to C is held in the CDR with unique ID of 1207317795.3 which has no information in it to be able to calculate the cost of the call (destination number, for example), nor does there appear to be any way within the dial plan to link the call with that unique ID. In addition, because the record with unique ID 1207317795.0 isn't written out (primary key issues, see above) to MySQL, the original call can't be billed either.

Unfortunately, CDR(uniqueid) is a read-only variable (from the dial plan anyway, it obviously isn't read-only to whatever's changing it) and so I can't just hack "Set(CDR(uniqueid)=${ORIGUID})" into the h extension of the dialplan (we couldn't anyway as we have to set "endbeforehexten=yes" in cdr.conf for other reasons).

We can get around two of the three problems by:

1 - Changing the 'uniqueid' field not to be a primary key.
2 - Storing the value of CDR(uniqueid) in CDR(userinfo) at the start of the call

but we can't get around the problem of not being able to bill for the entire duration of the call to C which I will report as a separate bug.

In summary, under certain curcumstances, the value of CDR(uniqueid) for a call is erased and a different value is used to replace it when the CDR is written out.
Comments:By: Steve Murphy (murf) 2008-04-09 18:14:17

I hate to say this, but the CDR system is really quite broken in Asterisk, when it comes to transfers, 3-way confs, and suchlike.

To assume a uniqueID will always be unique in CDR land, is not a good assumption. If you re-arrange your database to allow this field to be whatever it wants to be, you'll be better off. You might even be able to use matching uniqueID's to help sort out xfer situations.

By: Steve Murphy (murf) 2008-05-26 18:21:51

I've sat on this issue for a while to see if there's any community input on the issue, and have today decided to close it with "won't fix".

Why? because there is little I can do about it. The channel is assigned a new "uniqueid" when it is created, and keeps it until it is destroyed. This rule is, as far as I can tell, never broken. If that same channel is involved in several call legs (via xfers, etc.), then it would be foolish to try to set it to something different. You can surely wager that there are users now depending on this behavior in CDR applications. I promised I won't pull the rug out from under users in this way, and I will keep my promise in this case.

I think what you are looking for, is more of a call-leg unique number, which is most likely the row # in the database. In the newcdr branch (look for the CEL enhancement request in bugs.digium.com (#110099), we have just added the "linkedid" field, which will tie call-legs together in xfer situations.