Skip to main content

What CNS OCUDU Adds to OCUDU

CNS OCUDU is Cognitive Network Solutions' downstream distribution of upstream OCUDU — the gNB of the Racora platform. It adds capabilities on top of upstream in service of an AI-native radio access network. This document records what is added relative to stock OCUDU, organized into four parts:

  1. Interfaces and integrations — open interfaces and reference integrations that connect OCUDU to a broader RAN platform.
  2. Primitives — discrete OCUDU improvements: 3GPP / O-RAN / FAPI procedure implementations, framework additions, and small fixes, each a self-contained change.
  3. End-to-end features — operator-facing capabilities built by composing primitives.
  4. Upstreamed — capabilities that began here and are now in upstream OCUDU, and the one related capability CNS OCUDU still carries beyond it.

CNS OCUDU tracks OCUDU dev.


1. Interfaces and Integrations​

RANN-P — Internal gNB Intelligence Interface​

An in-process interface from CU-CP to a downstream intelligence consumer. Measurement reports are hooked at the point of L3 decoding and exported as flat per-UE per-cell per-timestamp records — the same decoded data the control plane uses for its own mobility decisions.

The adapter is non-invasive: when no consumer is configured, the control plane behaves identically to upstream. A file sink is the production transport in this implementation; a Flight (Apache Arrow over gRPC) sink header is included for reference but is not compiled due to a known fmt symbol conflict between Arrow C++ and OCUDU.

The JSONL wire format is a golden-pinned cross-repo contract: the serializer lives in one pure function (lib/rann_p/rann_p_json.h, to_json_line()), byte-compared against a committed fixture (tests/unittests/rann_p/golden/) whose copies also live in the racora and cuip repos, diffed centrally by racora CI. A format change is a deliberate act — regenerate the fixture and fan it out.

Implementation: lib/rann_p/, lib/cu_cp/cell_meas_manager/cell_meas_manager_impl.cpp

OpenTelemetry Observability Integration​

Native OpenTelemetry tracing and log forwarding in OCUDU process binaries. Process-level TracerProvider and LoggerProvider bootstrap via OTLP HTTP, span emission at workflow boundaries, cross-coroutine context propagation, and a srslog-to-OTLP tee that forwards every log line to an OpenTelemetry collector.

Build-gated on ENABLE_CNS_OTEL (default ON). When OFF, all calls compile to no-ops against the header-only opentelemetry-cpp API; the SDK, the OTLP exporter, and their protobuf/curl dependencies are not built.

Implementation: lib/cns_observability/, cmake/modules/cns_otel.cmake


2. Primitives​

F1AP §8.2.4 — gNB-DU Configuration Update Absorption​

Implements CU-CP-side absorption of the DU-initiated F1AP configuration update. Served_Cells_To_Modify_List is parsed and applied: du_processor's served-cells table is updated in place and the change cascades into the measurement manager so PCI-to-NCI resolution, mobility neighbor cache, and measurement-config emission all see the new cell state.

Implementation: lib/f1ap/cu_cp/procedures/du_config_update_procedure.cpp, lib/cu_cp/du_processor/du_processor_impl.cpp, include/ocudu/f1ap/cu_cp/du_setup_notifier.h

FAPI P5 Cell Lifecycle for Monolithic DU​

Closes the FAPI P5 cell lifecycle in monolithic DU mode. Wires MAC to drive FAPI START / STOP per cell, replaces the no-op upper_phy_operation_controller with a real implementation that flips a per-sector slot-indication gate, and adds an init-time bypass to resolve a race between DU-high and DU-low init in a single process. After this, every cell state transition — boot, runtime deactivate, runtime activate — flows through the same FAPI lifecycle contract regardless of whether the DU is monolithic or split-6.

Implementation: lib/mac/mac_dl/mac_cell_processor.cpp, lib/phy/upper/upper_phy_operation_controller_impl.h (+ .cpp), lib/phy/upper/upper_phy_impl.cpp, lib/du/du_high/o_du_high_factory.cpp

DU Cell Runtime Parameter Mutation (PCI)​

Plumbs an optional PCI mutation through the DU parameter config request: du_cell_param_config_request gains a pci_mod field and the request validation accepts it, so the pci_set WebSocket command (below) has a typed path into du_param_config_procedure.

The apply step — swapping the PCI of a deactivated cell via MAC cell destroy-recreate — is interface plumbing: the procedure accepts the request without changing the cell. PCI is baked into the MAC ssb_assembler at construction and has no live setter, so the apply requires a destroy-recreate of the MAC cell, which is only safe on a deactivated cell.

Implementation: include/ocudu/du/du_high/du_manager/du_configurator.h, lib/du/du_high/du_manager/procedures/du_param_config_procedure.cpp

Log File force_flush Configuration​

Exposes the existing fetch_file_sink::force_flush capability through YAML and CLI. Default false — no behavior change. Opt-in true for live debugging where the libstdc++ ~8 KB stdlib buffer otherwise hides events for many minutes on quiet networks.

Implementation: apps/helpers/logger/logger_appconfig.h, apps/helpers/logger/logger_appconfig_cli11_schema.cpp, apps/helpers/logger/logger_appconfig_yaml_writer.cpp

PCAP Real-Time Per-PDU Flush​

Flush after every PDU write in the backend pcap writer. Without this, capture files appear empty during live capture and cannot be consumed by real-time monitoring. Performance cost is negligible: pcap writes are off the critical path and signaling traces are infrequent.

Implementation: lib/pcap/backend_pcap_writer.cpp, lib/pcap/pcap_file_writer.cpp

Docker ZMQ Build/Runtime Dependencies​

Adds libzmq3-dev (build) and libzmq5 (runtime) to the Debian/Ubuntu install function. Without these, ZMQ radio — the standard testing transport for OCUDU-based stacks — is not available in prebuilt Docker images even though CMake defaults ENABLE_ZEROMQ=ON.

Implementation: docker/scripts/install_docker_dependencies.sh

CU-CP Standalone JSON Metrics Plumbing​

Two fixes in the standalone ocucp initialization path so JSON metrics can be published: wires metrics.enable_json to the remote_control server's metrics-subscription flag, and assigns the remote_metrics_gateway field of the unit-dependencies struct that was previously left unassigned. Standalone mode only.

Implementation: apps/cu_cp/cu_cp.cpp

WebSocket Remote Command Extension (DU pci_set, Command Results)​

Extends the existing WebSocket remote-command framework in two ways. A DU pci_set command dispatches to the cell runtime parameter mutation plumbing above. And the command ABI changes: execute() returns expected<nlohmann::json, std::string> instead of error_type<std::string>, so a command can answer with a payload (cell_status returns the cell's admin / barred / operational state through it). Every existing DU command (ssb_set, rrm_policy_ratio_set, sib_update, ntn_config_update) and the remote server were adapted to the new signature — the largest CNS addition to upstream code. The DU sib_update command that previously appeared here is upstream OCUDU now; the CU-CP cell management commands are upstream too — see "Upstreamed" below.

Implementation: apps/services/remote_control/remote_command.h, apps/services/remote_control/remote_server.cpp, apps/units/flexible_o_du/o_du_high/du_high/commands/du_high_remote_commands.cpp

Container Images for the Racora Platform​

.gitlab/ci/racora.yml builds and publishes the two images the Racora platform bundles: gnb (CNS OCUDU's CU-CP / CU-UP / DU / gNB binaries, built with MARCH=x86-64-v3) and open5gs (the reference 5G core, built from upstream Open5GS source by docker/open5gs/Dockerfile). A push to cns/main republishes the rolling :cns-main tags; a git tag vX.Y.Z publishes immutable tags. Both pushes are gated by a boot smoke test, and the gnb build additionally needs the RANN-P golden-fixture check. The stage is additive to and independent of the upstream pipeline.

Implementation: .gitlab/ci/racora.yml, docker/open5gs/


3. End-to-End Features​

Runtime Cell Reactivation with a Full FAPI Handshake​

Upstream's cell_unlock command reactivates a locked cell via the F1AP gNB-CU Configuration Update. In monolithic DU builds it is the FAPI P5 cell lifecycle primitive (above) that makes the reactivation real: the full FAPI START handshake runs at runtime activation (unlike the boot-time bypass), exercising the spec-compliant lifecycle contract.

AI-Native Measurement Export​

Composes the RANN-P platform integration with the cell_meas_manager notifier hook. Every CU-CP measurement report is forwarded as a flat per-UE per-cell per-timestamp record to a downstream intelligence consumer, providing the raw observation stream needed for graph-based learning over the radio access network.

Distributed Tracing across the gNB​

Composes the OpenTelemetry platform integration with span hooks placed at workflow boundaries: all fourteen CU-CP WS remote commands (the five cell state commands, the seven mobility configuration commands, and the two handover triggers — each emitting cucp.<cmd>.execute with its identity attributes and an outcome/error classification), the DU cell-stop procedure, and the F1AP gNB-CU Configuration Update TX procedure (CU-CP F1AP layer). The synchronous section of the mobility manager annotates the active trigger span with mobility.trigger_outcome, making the otherwise silent trigger failures (unknown UE, unknown target cell) visible; the bounded executor dispatch distinguishes queue-full/timeout from genuine rejections via dispatch.failure. Cross-coroutine context propagation chains the spans so a single operator action (e.g., cell_lock) renders as one continuous trace across all gNB process boundaries, and a W3C traceparent carried in the WS payload parents the command span under the caller's trace. Span naming and attribute conventions: the Racora span schema.


4. Upstreamed​

Capabilities that began life in this catalog and are now upstream OCUDU. They are no longer CNS additions; CNS OCUDU simply tracks them.

  • CU-driven graceful cell stop and runtime MIB mutation — the bar → release UEs → deactivate stop sequence over the F1AP gNB-CU Configuration Update and runtime MIB cellBarred / intraFreqReselection mutation. Merged upstream (ocudu/ocudu !862 and !864).
  • Runtime SIB content update — the sib_update WebSocket command (PLMN, TAC, SIB1, SIB3 parameter changes at runtime). Merged upstream.
  • CU-CP logical cells and cell state commands — the logical cell registry with per-cell administrative state, the shared cells: configuration section, and the cell_lock / cell_unlock / cell_bar / cell_unbar / cell_status WebSocket commands. Merged upstream 2026-09-03 (ocudu/ocudu !863).

CNS OCUDU carries this beyond upstream:

  • Runtime mobility configuration — a runtime mobility configuration API on the cell measurement manager (cell, neighbor, and report-config add/update/remove with measurement-object maintenance and UE meas-config updates at the next RRC reconfiguration) plus the mobility_cell_set / mobility_cell_remove / neighbor_add / neighbor_remove / report_config_set / report_config_remove / periodic_report_set / trigger_handover / trigger_conditional_handover WebSocket commands.