Call Detail Records
This document describes the Call Detail Record (CDR) subsystem in OmniMSC by Omnitouch. CDRs are generated in compliance with 3GPP TS 32.298 and provide the charging and audit trail for all circuit-switched services handled by the MSC.
For CDR-related configuration parameters, see Configuration Reference. For the CDR Statistics page in the web interface, see Control Panel Guide. For CDR-related Prometheus metrics and alarm events, see Metrics and Monitoring.
Overview
OmniMSC generates CDRs for voice calls, SMS transactions, location updates, and roaming events. Each CDR captures the subscriber identity, service details, timestamps, location, and termination cause for a single transaction. CDRs are collected in memory, buffered, and periodically flushed to files in ASN.1 BER format following the record structures defined in 3GPP TS 32.298.
The CDR subsystem consists of two components:
- CDR Collector -- receives events from the Call Control FSM, VLR location update procedures, and SMS handlers. It correlates events for active calls (setup, alerting, answer, release) into complete CDR records and manages per-record-type sequence numbers.
- CDR Writer -- writes encoded CDR records to files on disk, handling file rotation based on size, record count, and time interval.
Record Types
OmniMSC supports the following CDR record types, each identified by a unique ASN.1 tag per TS 32.298.
| ASN.1 Tag | Record Type | Description |
|---|---|---|
| 0 | MOCallRecord | Mobile Originated voice call. Generated when a subscriber originates a voice call. |
| 1 | MTCallRecord | Mobile Terminated voice call. Generated when a subscriber receives a voice call. |
| 5 | MOSMSRecord | Mobile Originated SMS. Generated when a subscriber sends a short message. |
| 6 | MTSMSRecord | Mobile Terminated SMS. Generated when a subscriber receives a short message. |
| 13 | LocUpdateHLRRecord | Location Update (HLR). Generated for location update procedures at the HLR level, tracking MSC/VLR changes. |
| 14 | LocUpdateVLRRecord | Location Update (VLR). Generated for location update procedures at the VLR level, tracking location area changes, authentication results, and TMSI allocation. |
| 17 | RoamingRecord | Roaming event. Generated for inter-MSC roaming events. |
CDR Fields
Voice Call Records (MOCallRecord and MTCallRecord)
| Field | Description |
|---|---|
| served_imsi | IMSI of the subscriber who originated or received the call |
| served_msisdn | MSISDN (phone number) of the served subscriber |
| served_imei | IMEI of the mobile equipment used |
| calling_number | Calling party number (A-number) |
| called_number | Called party number (B-number), present in MO records |
| connected_number | Number of the party actually connected (may differ from called number due to forwarding) |
| recording_entity | Address of the MSC that generated the CDR |
| msc_address | E.164 address of the MSC |
| msc_incoming_tkgp | Incoming trunk group name |
| msc_outgoing_tkgp | Outgoing trunk group name |
| location | Subscriber location at time of call, including Location Area Code (LAC) and Cell Identity (CI) |
| basic_service | Bearer service or teleservice code identifying the service type |
| seizure_time | UTC timestamp when the call was initiated (setup message received) |
| answer_time | UTC timestamp when the call was answered (may be nil for unanswered calls) |
| release_time | UTC timestamp when the call was released |
| call_duration | Duration of the call in seconds, measured from answer to release. Zero for unanswered calls. |
| radio_chan_used | Radio channel type used (full rate or half rate) |
| cause_for_term | Reason for call termination (see Cause for Termination below) |
| diagnostics | Diagnostic information: GSM 04.08 cause code, MAP error code, or network-specific cause |
| call_reference | Unique call reference number |
| sequence_number | Per-record-type sequence number for gap detection by downstream billing systems |
| ms_classmark | Mobile station classmark information |
| system_type | Access network type: GERAN, UTRAN, or unknown |
| partial_record_type | For partial CDRs: indicates whether this is an intermediate or last partial record |
SMS Records (MOSMSRecord and MTSMSRecord)
| Field | Description |
|---|---|
| served_imsi | IMSI of the subscriber |
| served_msisdn | MSISDN of the subscriber |
| served_imei | IMEI of the mobile equipment |
| service_centre | Address of the SMS Service Centre |
| recording_entity | Address of the recording MSC |
| location | Subscriber location (LAC/CI) |
| message_reference | SMS message reference number (MO only) |
| destination_number | SMS destination number (MO only) |
| originating_number | SMS sender number (MT only) |
| origination_time | Timestamp of SMS origination (MO) or delivery (MT) |
| sms_result | Result of SMS delivery: success, delivery failure, or forwarded |
Location Update Records
| Field | Description |
|---|---|
| served_imsi | IMSI of the subscriber |
| served_msisdn | MSISDN of the subscriber (VLR records only) |
| recording_entity | Address of the recording entity |
| update_time | UTC timestamp of the location update |
| update_type | Type of update: normal location update, periodic location update, IMSI attach, or IMSI detach |
| old_location / new_location | Previous and new location information (VLR records: LAC/CI) |
| old_msc / new_msc | Previous and new MSC addresses (HLR records) |
| old_vlr / new_vlr | Previous and new VLR addresses (HLR records) |
| vlr_result / hlr_result | Outcome of the location update procedure |
| authentication_result | Authentication outcome: success, failure (no vectors), failure (auth mismatch), or not performed (VLR records only) |
| tmsi_allocated | New TMSI value if one was allocated during the procedure (VLR records only) |
Cause for Termination
The cause_for_term field records why a call was terminated. The following values are defined per TS 32.298.
| Cause | Integer Value | Description |
|---|---|---|
| normal_release | 0 | Normal call clearing by either party |
| partial_record | 1 | Partial CDR generated for a long-duration call (intermediate record) |
| partial_record_call_reestablishment | 2 | Partial record due to call re-establishment |
| unsuccessful_call_attempt | 3 | Call setup failed before answer (busy, no answer, routing failure) |
| abnormal_release | 4 | Abnormal release due to radio link failure, protocol error, or system error |
| CAMEL_init_call_release | 5 | Call released by the CAMEL service (SCP initiated release) |
| management_intervention | 52 | Call released by operator intervention |
CDR Collector
The Collector is a GenServer that acts as the central collection point for CDR events. It receives event notifications from the Call Control FSM, VLR, and SMS handlers, and correlates them into complete CDR records.
Event Flow
For voice calls, the Collector receives a sequence of events over the call lifetime:
- Call setup -- records the subscriber identity, called/calling numbers, direction (MO or MT), seizure time, and service type.
- Call alerting -- logged for diagnostics but does not generate a CDR field.
- Call answer -- records the answer timestamp and starts the partial CDR timer for long calls.
- Call release -- calculates the call duration, selects the termination cause, generates the final CDR record, and buffers it for writing.
For SMS and location updates, the Collector generates a CDR record immediately from a single event notification.
Buffering and Flushing
CDR records are accumulated in an in-memory buffer. The buffer is flushed to the Writer under two conditions:
- A periodic flush timer fires (default interval: 5000 ms).
- The buffer reaches its maximum size (default: 1000 records), triggering an immediate flush.
Partial CDR Generation
For long-duration calls, the Collector generates intermediate partial CDR records at a configurable interval (default: 3600 seconds / 1 hour). Each partial CDR captures the call state up to that point. The final CDR record upon call release is marked as the last partial if any intermediate partials were generated. This ensures that downstream billing systems can reconstruct the complete call duration even if the MSC fails before the call ends.
Sequence Numbers
The Collector maintains independent sequence number counters for each record type (MO call, MT call, MO SMS, MT SMS, roaming, HLR location update, VLR location update). Sequence numbers increment monotonically and wrap at 10000. Downstream billing systems use sequence numbers to detect gaps indicating lost CDR records.
CDR File Naming
CDR files follow a naming convention that includes the MSC identity, timestamp, and sequence number:
<NodeID><Date><Time>_<SeqNum>.dat
Where:
- NodeID is the MSC name (from the recording_entity configuration).
- Date is in YYYYMMDD format.
- Time is in HHMMSS format.
- SeqNum is a zero-padded 4-digit sequence number (wraps at 10000).
For example: MSC01_20260329_143022_0001.dat
Files are written in ASN.1 BER format containing a sequence of CDR records as defined in TS 32.298.
File Rotation
CDR files are rotated (closed and a new file opened) when any of the following conditions are met:
- The file exceeds the configured maximum size (default: 10 MB).
- The file contains the configured maximum number of records (default: 100,000).
- The configured time interval has elapsed since the file was opened (default: 3600 seconds).
- An explicit rotation is triggered via the API.
Configuration
The CDR subsystem is configured through the Collector and Writer startup parameters.
Collector Parameters
| Parameter | Default | Description |
|---|---|---|
| recording_entity | (required) | Address or name of the recording MSC, written into every CDR record |
| msc_address | Same as recording_entity | E.164 MSC address included in call records |
| flush_interval | 5000 ms | Interval between periodic buffer flushes to the Writer |
| buffer_size | 1000 | Maximum number of CDR records held in the buffer before a forced flush |
| partial_cdr_interval | 3600 seconds | Interval for generating intermediate partial CDRs on long-duration calls |
Writer Parameters
| Parameter | Default | Description |
|---|---|---|
| output_dir | (required) | Directory where CDR files are written. Created automatically if it does not exist. |
| node_id | (required) | Network element identifier used in CDR file names |
| extension | .dat | File extension for CDR files |
| max_file_size | 10,000,000 bytes (10 MB) | Maximum file size before rotation |
| max_records | 100,000 | Maximum number of records per file before rotation |
| rotation_interval | 3600 seconds | Maximum time a file remains open before rotation. Set to nil to disable time-based rotation. |
CDR Web UI
The CDR Statistics page in the Control Panel displays real-time information about the CDR subsystem.
CDR Statistics page showing writer status, buffer depth, active tracked calls, and per-type sequence numbers.
| Field | Description |
|---|---|
| Records in File | Number of CDR records written to the current output file |
| Pending in Buffer | Number of CDR records buffered in memory awaiting the next flush |
| Active Calls Tracked | Number of calls with open CDR state (between setup and release) |
| Current File | Path of the current CDR output file, or "No file open" if idle |
| Sequence Numbers | Per-record-type sequence counters showing the next sequence number for each CDR type |
The page auto-refreshes every 5 seconds via WebSocket.
3GPP Specification References
| Specification | Title | Relevance |
|---|---|---|
| TS 32.298 | Charging Data Record Encoding Rules | CDR record types, ASN.1 structure, field definitions |
| TS 32.205 | Charging Data Description for CS Domain | CS domain charging principles and CDR content requirements |
| TS 32.015 | Charging and Billing | Overall charging architecture context |