Skip to content

Monitoring xApps

Read-only xApps that subscribe to E2 nodes and log or stream what they observe. None of them change RAN state (with one clearly-marked exception in ccc-monitor).

kpm-monitor

KPM Style 4 per-UE measurement monitor — and the cross-language binding benchmark. Ships in Python, Go, and C (three functionally-equivalent implementations; the C variant is the binding-overhead baseline the Python and Go costs are measured against).

  • SM: E2SM-KPM REPORT Style 4, with an S-NSSAI SST=1 condition.
  • What it does: on node discovery it decodes the KPM RAN-function definition, logs the advertised report styles and measurements, then subscribes Style 4 to every advertised measurement. Each indication's per-UE values — all Style 4 measurements are per-UE, including RRU.PrbTot* per E2SM-KPM §7.9.0 — are logged and emitted as kpm samples to the timeseries sinks; indication metadata goes to the structured sinks.
  • Config: xapp.instance (operator identity), ping_interval_ms (2000), node_probe_interval_ms (5000 — the EPI probe driver is on here), per-sink queue_size; all sinks enabled by default.

The reference "how to subscribe to KPM" xApp — start here for KPM.

rc-monitor

The E2SM-RC reference xApp — exercises every implemented RC service. Python.

  • SM: E2SM-RC REPORT Style 1 (Message Copy: RRC_Message + UE_ID) and Style 4 (UE Information: RRC_State_Changed_To), default both; INSERT Style 3 / Action 1 per attached UE; QUERY Styles 1 + 2 on a cadence.
  • What it does: subscribes to the selected REPORT styles and logs each indication's blocks / RANParameters, decoding Style 1's octet payloads on arrival — the copied RRC PDU by name via airpuls_ric_sdk.rrc (optional pycrate; hex fallback) and the UEID octets via decode_ue_id_octets. Style 4 doubles as the attach detector: a UE reported CONNECTED gets an INSERT Style 3 subscription filtered to its gNB-CU-UE-F1AP-ID, released when the UE is reported IDLE; every paused handover is answered ACCEPT with its own target, so the monitor observes without changing outcomes. On a timer (ue_query_interval_ms, and once when a node appears) it issues RC QUERYs for each node's connected-UE and served-cell lists without waiting for a REPORT event. A failing QUERY node gets a one-shot WARN + retry.
  • Config: xapp.rc_monitor.ue_query_interval_ms (3000).

cell-tracker

Cell discovery and tracking via RC REPORT Style 3. Python.

  • SM: E2SM-RC REPORT Style 3 (E2 Node Information).
  • What it does: subscribes on each RC-capable node and maintains a live table of NR and E-UTRA cells, reprinting it on each indication. Fully read-only — no sinks, no control. On shutdown it reports the indication count and NR/E-UTRA cell counts.
  • Config: no app-specific knobs; reconnect.max_attempts: 3.

llc-monitor

Per-UE / per-DRB DL RLC buffer-status monitor. Python.

  • SM: E2SM-LLC REPORT Style 2 (Periodic), measurement type DL_RLC_BUFFER_STATUS. LLC advertises a fixed measurement set, so there is no RAN-function-definition decode step.
  • What it does: subscribes on every LLC-capable node. Each indication decodes per-UE blocks — DlRlcBufferOccupancy.LCID<n>, DlRlcHolTimeToLive.LCID<n>, SlotTimeStamp.* — logs them, and packs per-UE samples into the sinks. A high occupancy with a small HOL-TTL is a congested bearer about to miss its delay budget.
  • Config: ping_interval_ms (2000); all sinks enabled by default.

ccc-monitor

Cell / node configuration monitor with a one-shot energy-saving control demo. Python.

  • SM: E2SM-CCC REPORT Style 1 (node-level, O-GnbDuFunction) and Style 2 (cell-level: O-CESManagementFunction, O-NrCellDu, O-Bwp, O-RUInfo), both periodic. Also demonstrates one CCC CONTROL Style 2.
  • What it does: discovers CCC-capable nodes, subscribes to node- and cell-level periodic REPORTs, parses each JSON config snapshot, and logs every reported structure and its attributes. Streams ccc_config_report events plus a numeric ccc sample. As a demonstration, when a cell first reports isNotEnergySaving it issues a CCC CONTROL writing energySavingControl → toBeEnergySaving and logs the outcome — the one place a "monitor" here writes RAN state.
  • Config: ping_interval_ms (2000); structured file sink (ccc-xapp-events.jsonl) on, queue_size tuned for the per-cell multi-structure burst.

ccc-monitor is not strictly read-only

Its energy-saving CONTROL is a deliberate demonstration of the CCC read → decide → write loop. If you need a purely observational CCC xApp, remove that one-shot control path.