CDRAG Projects RTC Platforms (Accounting Guides)
This document describes CDR generation, normalization, search and export.
The platform generates usage information in the form of rated Call Detail Records (CDR). It is the responsibility of the Operator to import the rated CDRs into its own billing system and to generate printable invoices out of them.
The CDRs can be easily searched and grouped by various criteria and exported into comma separated value files. Accounting can be done postpaid (default option) or prepaid (enabled per SIP account). Postpaid accounts can have a monthly quota assigned to prevent fraud.
CDR Generation
Call detail records (CDRs) are generated from the SIP sessions going through the platform. A CDR contains relevant information about a SIP session from both signaling and data planes. The CDR is generated by combining several Radius requests from OpenSIPS and MediaProxy as follows:
Radius request | When | Component | Description |
---|---|---|---|
FAILED | First INVITE with negative code | OpenSIPS | Zero second (failed) session |
START | First INVITE with positive code | OpenSIPS | Start of new session |
STOP | BYE | OpenSIPS | Stop of existing session |
UPDATE | RTP stop | MediaProxy | Stop or timeout of existing RTP stream |
A CDR is generated for each SIP dialog. When serial forking is enabled (e.g. multiple outgoing gateways are tried for the same initial INVITE) or call diversions, there is a CDR generated for each attempt to complete the call, only one of the CDRs will have duration, should the call be successfull.
Radius logs
Radius requests generated by the platform are logged by the Freeradius server in the following places:
Directory | Log type |
---|---|
/var/log/freeradius/radacct/IP/detail-YYYYMM | Radius tickets contents |
/var/log/freeradius/radacct/radius.log | Radius errors |
The most relevant attribute of a CDR is the session duration. The cost for the session depends on this session duration. The sessions duration is determined by the Stop time and Start time of the SIP session. The Start time is considered the moment when the answer for the first INVITE has entered the SIP Proxy. Stop time is determined either by the presence of BYE message or in case BYE is missing from the last moment RTP has ben relayed though MediaProxy.
- First INVITE is answered with a positive code
- No BYE is received
- No RTP data has been relayed
Media timeout
If the RTP media has timed out (both parties stopped sending RTP) while no BYE has been received by the SIP Proxy:
- MediaProxy will set in the Radius UPDATE the MediaInfo Radius attribute to *timeout*
- MediaProxy will trigger the sending of a a BYE message via the dialog module of OpenSIPS
In this situation, the actual duration of the SIP session contains the period of the RTP stream plus the value of the timeout. The value of the timeout is determined by the connection tracking logic in the Linux kernel. At this moment there is no mechanism to store into the Radius database the value of this timeout, which is typically 180 seconds.
CDR tables
CDRs are stored in monthly tables in radius database. The tables are named radacctYYYYMM. Tables are automatically created by the Radius server at the beginning of each month.
CDR fields
Field | Type | Description | Notes |
---|---|---|---|
RadAcctId | bigint(21) | MySQL unque index auto-incremented | |
AcctSessionId | varchar(255) | SIP call-id header | |
AcctUniqueId | varchar(255) | Radius internal session id | |
UserName | varchar(64) | SIP Username | Matched against billing_customers.subscriber |
Realm | varchar(64) | SIP domain | Matched against billing_customers.domain |
NASIPAddress | varchar(15) | SIP Proxy IP | |
NASPortId | varchar(50) | SIP Proxy port | |
NASPortType | varchar(255) | not used | |
AcctStartTime | datetime | Session start time | |
AcctStopTime | datetime | Session stop time | |
AcctSessionTime | int(12) | Session duration used for rating | |
AcctAuthentic | varchar(32) | not used | |
ConnectInfo_start | varchar(32) | not used | |
ConnectInfo_stop | varchar(32) | not used | |
AcctInputOctets | bigint(12) | Relayed RTP through MediaProxy | |
AcctOutputOctets | bigint(12) | Relayed RTP through MediaProxy | |
CalledStationId | varchar(50) | SIP To header, the original dialed number | |
CallingStationId | varchar(50) | SIP From header | |
AcctTerminateCause | varchar(32) | SIP response code | |
ServiceType | varchar(32) | Sip-Session | |
ENUMtld | varchar(64) | ENUM top level domain used for lookup | |
FramedIPAddress | varchar(15) | not used | |
AcctStartDelay | int(12) | not used | |
AcctStopDelay | int(12) | not used | |
SipMethod | varchar(50) | SIP method | |
SipResponseCode | smallint(5) unsigned | Response code for INVITE | |
SipToTag | varchar(128) | SIP to tag | |
SipFromTag | varchar(128) | SIP from tag | |
SipTranslatedRequestURI | varchar(255) | Final network address after DNS lookup | |
SipUserAgents | varchar(255) | SIP user agents/servers reported by MediaProxy | |
SipApplicationType | varchar(255) | Media type (e.g. audio) | |
SipCodecs | varchar(255) | RTP codecs report by MediaProxy | |
SipRPID | varchar(255) | PSTN caller id | |
SipRPIDHeader | varchar(255) | not used | |
SourceIP | varchar(255) | Source IP of the session | Matched against billing_customers.gateway |
SourcePort | varchar(255) | Source port of the session | |
CanonicalURI | varchar(255) | Final logical destination used for rating | Matched against destinations table |
DelayTime | varchar(5) | not used | |
Timestamp | bigint(20) | Packet timestamp | |
DestinationId | varchar(15) | Normalized E.164 prefix | Calculated during normalization |
Rate | text | Description of rate calculation | Calculated during normalization |
Price | double(20,4) | Cost of the session | Calculated during normalization |
Normalized | enum('0','1') | If the CDR has been normalized | |
BillingId | varchar(255) | Reseller id used by trusted peers and SIP domains | Calculated during normalization |
MediaInfo | varchar(32) | Mediaproxy information | |
RTPStatistics | text | RTP statistics reported by some devices | |
FromHeader | varchar(128) | not used | |
UserAgent | varchar(128) | SIP User Agent and Server headers | |
Contact | varchar(128) | not used | |
CDR Normalization
A CDR is considered closed when the stop time has been determined. Once the CDR is closed, a normalization process cleans up the CDR fields and calculates the price of the session. The price and the way it was calculated is saved together with the CDR in the same table. It is possible to re-normalize the sessions at a later time, for instance when the tariffs need to be changed for the past period.
Normalization is performed periodically:
- Whenever CDRTool web search is used
- By the cron job /var/www/CDRTool/script/normalize.php
Once normalized, the CDRs are no longed modified, the normalization process marks each CDR that has been processed.
Operation | When | Platform component | Description |
---|---|---|---|
NORMALIZE | After CDR was closed | CDRTool | Rating is applied |
Un-normalized sessions
Some SIP sessions can remain in the CDR database in an un-normalized state. They show in CDRTool as "in progress". Such sessions have a start date but no end date. Such sessions cannot be normalized automatically by the CDR normalization process because there is no indication when they have actually stopped. A SIP session is considered stopped when either a BYE message has been received by the SIP Proxy or when the RTP media has stopped flowing between the end-points, which is detected by the MediaProxy. If the RTP media has not started yet and no BYE has arrived after the initial INVITE/200 OK/ACK, there is no physical indication for when the session has started or when it ended. Due to the nature of the SIP protocol and in particular the fact that the RTP media is carried separately from the SIP signaling, it is always possible to have SIP sessions that from a call completion perspective have started but never ended. Such situations occur outside the control of the operator responsible for the SIP service. You may chose to apply your own policy for such sessions like deleting or archiving them.
CDR Search
CDRs can be searched and displayed in CDRTool. Access to CDRTool can be provided to resellers or end-users of the platform.
Last placed and received calls are also available for every SIP account using SOAP/XML functions:
- SipPort → getCalls()
CDR Export
CDRs can be exported from CDRTool in comma separated values (CSV) format or by selecting the raw content of the MySQL radacctYYYYMM tables. Such operation can take time to complete and is advisable to use always a MySQL slave server for these queries.
Next Steps
Continue by:
- learning about Prepaid; or
- learning about Rating: Assignment; or
- learning about Rating: Logic.