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:
- Interfaces and integrations — open interfaces and reference integrations that connect OCUDU to a broader RAN platform.
- Primitives — discrete OCUDU improvements: 3GPP / O-RAN / FAPI procedure implementations, framework additions, and small fixes, each a self-contained change.
- End-to-end features — operator-facing capabilities built by composing primitives.
- 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/intraFreqReselectionmutation. Merged upstream (ocudu/ocudu !862 and !864). - Runtime SIB content update — the
sib_updateWebSocket 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 thecell_lock/cell_unlock/cell_bar/cell_unbar/cell_statusWebSocket 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_handoverWebSocket commands.