Asterisk - The Open Source Telephony Project GIT-master-3dee037
Call Detail Record Engine
Intro

The Call Detail Record (CDR) engine uses the Stasis Message Bus API Stasis Message Bus to build records for the channels in Asterisk. As the state of a channel and the bridges it participates in changes, notifications are sent over the Stasis Message Bus. The CDR engine consumes these notifications and builds records that reflect that state. Over the lifetime of a channel, many CDRs may be generated for that channel or that involve that channel.

CDRs have a lifecycle that is a subset of the channel that they reflect. A single CDR for a channel represents a path of communication between the endpoint behind a channel and Asterisk, or between two endpoints. When a channel establishes a new path of communication, a new CDR is created for the channel. Likewise, when a path of communication is terminated, a CDR is finalized. Finally, when a channel is no longer present in Asterisk, all CDRs for that channel are dispatched for recording.

Dispatching of CDRs occurs to registered CDR backends. CDR backends register through ast_cdr_register and are responsible for taking the produced CDRs and storing them in permanent storage.

CDR attributes

While a CDR can have many attributes, all CDRs have two parties: a Party A and a Party B. The Party A is always the channel that owns the CDR. A CDR may or may not have a Party B, depending on its state.

For the most part, attributes on a CDR are reflective of those same attributes on the channel at the time when the CDR was finalized. Specific CDR attributes include:

  • start The time when the CDR was created
  • answer The time when the Party A was answered, or when the path of communication between Party A and Party B was established
  • end The time when the CDR was finalized
  • duration end - start. If end is not known, the current time is used
  • billsec end - answer. If end is not known, the current time is used
  • userfield User set data on some party in the CDR

Note that accountcode and amaflags are actually properties of a channel, not the CDR.

CDR States

CDRs go through various states during their lifetime. State transitions occur due to messages received over the Stasis Message Bus API Stasis Message Bus. The following describes the possible states a CDR can be in, and how it transitions through the states.

Single

When a CDR is created, it is put into the Single state. The Single state represents a CDR for a channel that has no Party B. CDRs can be unanswered or answered while in the Single state.

The following transitions can occur while in the Single state:

  • If a ast_channel_dial_type indicating a Dial Begin is received, the state transitions to Dial
  • If a ast_channel_snapshot is received indicating that the channel has hung up, the state transitions to Finalized
  • If a ast_bridge_blob is received indicating a Bridge Enter, the state transitions to Bridge
  • If a ast_bridge_blob message indicating an entrance to a holding bridge with a subclass type of "parking" is received, the CDR is transitioned to the Parked state.
Dial

This state represents a dial that is occurring within Asterisk. The Party A can either be the caller for a two party dial, or it can be the dialed party if the calling party is Asterisk (that is, an Originated channel). In the first case, the Party B is always the dialed channel; in the second case, the channel is not considered to be a "dialed" channel as it is alone in the dialed operation.

While in the Dial state, multiple CDRs can be created for the Party A if a parallel dial occurs. Each dialed party receives its own CDR with Party A.

The following transitions can occur while in the Dial state:

  • If a ast_channel_dial_type indicating a Dial End is received where the dial_status is not ANSWER, the state transitions to Finalized
  • If a ast_channel_snapshot is received indicating that the channel has hung up, the state transitions to Finalized
  • If a ast_channel_dial_type indicating a Dial End is received where the dial_status is ANSWER, the state transitions to DialedPending
  • If a ast_bridge_blob is received indicating a Bridge Enter, the state transitions to Bridge
DialedPending

Technically, after being dialed, a CDR does not have to transition to the Bridge state. If the channel being dialed was originated, the channel may being executing dialplan. Strangely enough, it is also valid to have both Party A and Party B - after a dial - to not be bridged and instead execute dialplan. DialedPending handles the state where we figure out if the CDR showing the dial needs to move to the Bridge state; if the CDR should show that we started executing dialplan; of if we need a new CDR.

The following transition can occur while in the DialedPending state:

  • If a ast_channel_snapshot is received that indicates that the channel has begun executing dialplan, we transition to the Finalized state if we have a Party B. Otherwise, we transition to the Single state.
  • If a ast_bridge_blob is received indicating a Bridge Enter, the state transitions to Bridge (through the Dial state)
  • If a ast_bridge_blob message indicating an entrance to a holding bridge with a subclass type of "parking" is received, the CDR is transitioned to the Parked state.
Bridge

The Bridge state represents a path of communication between Party A and one or more other parties. When a CDR enters into the Bridge state, the following occurs:

  • The CDR attempts to find a Party B. If the CDR has a Party B, it looks for that channel in the bridge and updates itself accordingly. If the CDR does not yet have a Party B, it attempts to find a channel that can be its Party B. If it finds one, it updates itself; otherwise, the CDR is temporarily finalized.
  • Once the CDR has a Party B or it is determined that it cannot have a Party B, new CDRs are created for each pairing of channels with the CDR's Party A.

As an example, consider the following:

  • A Dials B - both answer
  • B joins a bridge. Since no one is in the bridge and it was a dialed channel, it cannot have a Party B.
  • A joins the bridge. Since A's Party B is B, A updates itself with B.
  • Now say an Originated channel, C, joins the bridge. The bridge becomes a multi-party bridge.
  • C attempts to get a Party B. A cannot be C's Party B, as it was created before it. B is a dialed channel and can thus be C's Party B, so C's CDR updates its Party B to B.
  • New CDRs are now generated. A gets a new CDR for A -> C. B is dialed, and hence cannot get any CDR.
  • Now say another Originated channel, D, joins the bridge. Say D has the AST_CDR_FLAG_PARTY_A flag set on it, such that it is always the preferred Party A. As such, it takes A as its Party B.
  • New CDRs are generated. D gets new CDRs for D -> B and D -> C.

The following transitions can occur while in the Bridge state:

  • If a ast_bridge_blob message indicating a leave is received, the state transitions to the Finalized state.
Parked

Parking is technically just another bridge in the Asterisk bridging framework. Unlike other bridges, however there are several key distinctions:

  • With normal bridges, you want to show paths of communication between the participants. In parking, however, each participant is independent. From the perspective of a CDR, a call in parking should look like a dialplan application just executed.
  • Holding bridges are typically items using in more complex applications, and so we usually don't want to show them. However, with Park, there is no application execution - often, a channel will be put directly into the holding bridge, bypassing the dialplan. This occurs when a call is blind transferred to a parking extension.

As such, if a channel enters a bridge and that happens to be a holding bridge with a subclass type of "parking", we transition the CDR into the Parked state. The parking Stasis message updates the application name and data to reflect that the channel is in parking. When this occurs, a special flag is set on the CDR that prevents the application name from being updates by subsequent channel snapshot updates.

The following transitions can occur while in the Parked state:

  • If a ast_bridge_blob message indicating a leave is received, the state transitions to the Finalized state
Finalized

Once a CDR enters the finalized state, it is finished. No further updates can be made to the party information, and the CDR cannot be changed.

One exception to this occurs during linkedid propagation, in which the CDRs linkedids are updated based on who the channel is bridged with. In general, however, a finalized CDR is waiting for dispatch to the CDR backends.