OCUDU Prototyping with O-RAN Compliant nearRT-RIC and xApps

Platform: OCUDU software stack, nearRT-RIC (ORAN SC and FlexRIC), and Universal Software Radio Peripherals (USRPs).

Resources used: USRP NI N320 (Base Station), N320 host computer, Quectel RM5xxQ-GL (UE), Quectel host computer, power amplifiers, CommScope SS-65M-R2 Sector BS Antenna, and Quectel YEMN017AA Antenna.

Description: This experiment demonstrates an over-the-air 5G NR Radio Access Network (RAN) built with the OCUDU 5G software stack and monitored through an O-RAN compliant near-RT-RIC and xApps. Two RIC implementations are supported:

  • FlexRIC — a lightweight near-RT-RIC that runs as a native binary on the Base Station host. xApps are compiled native binaries.

  • ORAN SC RIC — the O-RAN Software Community near-RT-RIC deployed as a containerized stack via Docker Compose on the Base Station host.

OCUDU can also be deployed in two ways:

  • Monolithic gNB — the full gNB (CU + DU) runs as a single process.

  • OCU-ODU split — the gNB is disaggregated into an O-CU and an O-DU that connect over the F1 interface.

In all modes the RAN nodes expose an E2 agent that connects to the near-RT-RIC. A monitoring xApp subscribes to the E2 nodes through the RIC and collects per-UE downlink/uplink throughput Key Performance Metrics (KPMs) using the E2SM-KPM service model. A COTS Quectel UE attaches over the air, and the core network is deployed in the data center and reachable via the long-distance fiber backhaul.

This page covers both RIC choices and both RAN deployment modes. Use the tabs in Step 7 to select your near-RT-RIC, and the tabs in Step 8 to switch between the Monolithic gNB and the OCU-ODU split — every other step is identical for the two RAN modes.

OCUDU experiment architecture

Experiment Architecture: The OCUDU 5G RAN (monolithic gNB or OCU-ODU split) connects over the air to a COTS Quectel UE. Both the gNB/CU and the DU expose an E2 agent to the near-RT-RIC (FlexRIC or ORAN SC RIC), which relays KPM measurements to the monitoring xApp. The core network (Open5GS) is hosted in the ARA data center and reachable via the long-distance fiber backhaul.

Note

For OCUDU 5G experiments, an Open5GS core network is deployed at the data center and runs an iperf3 server in the background. Users do not have direct access to the core network, but they can run iperf3 and ping commands against it from the UE.

Detailed Steps for the Experiment

  1. Login to ARA portal with your credentials.

  2. Create two reservations using the Project -> Reservations -> Leases tab from the dashboard. Since each base station serves specific UEs in its footprint, reserve a matching Base Station and User Equipment pair. You may use any of the BS-UE combinations below.

    Resource No.

    Site

    Resource Type

    Device Type

    Device ID

    1

    Gilbert

    AraRAN

    Base Station

    000

    2

    Horticulture

    AraRAN

    User Equipment

    000 or 001

    3

    Curtiss Farm

    AraRAN

    Base Station

    000

    4

    Feedmill or Curtiss Farm

    AraRAN

    User Equipment

    000

  3. Create the containers on the respective nodes as provided in the following table. The Base Station container ships the complete OCUDU stack (gnb, ocu, and odu binaries) together with FlexRIC and the xApps, so the same container image is used for both the monolithic and the OCU-ODU split deployments.

    Component/Reservation

    Container Image

    CPU

    Memory

    Network

    Base Station

    arawirelesshub/ocudu:complete_outdoor_v1

    8

    8192

    ARA_Shared_Net

    User Equipment

    arawirelesshub/ocudu:cots_ue

    8

    8192

    ARA_Shared_Net

  4. Once the containers are launched, take note of the floating IP if you want to access the containers from your PC via the ARA jumpbox. The containers can be accessed via the console tab of the respective containers in the Project -> Containers tab from the dashboard, or using SSH via the jumpbox server. Visit ARA Jumpbox for more information on accessing containers via the jumpbox.

  5. Identifying and selecting the SDR: In the Base Station container, run the following command to list the radios (SDRs) connected to the host. In case the command cannot find an SDR, refer to the instructions in FAQ.

    # uhd_find_devices
    

    The base station hosts multiple USRP N320 SDRs, each serving one sector. The command lists every detected SDR together with its addr (IP address), as shown below.

    ../../_images/ocudu_uhd_find_devices.png

    Select the SDR that serves the sector pointing toward your reserved UE, using the table below.

    User Equipment

    SDR IP Address

    CurtissFarm-UE-000, Portable-UE-000, AgronomyFarm-UE-[001, 010], Gilbert-UE-003

    192.168.20.2

    Horticulture-UE-[000, 001]

    192.168.30.2

    FeedMill-UE-[000, 001]

    192.168.40.2

    For example, if you are using a Horticulture UE, the SDR IP address is 192.168.30.2.

    Note this SDR IP address — you will write it into the RAN node’s YAML configuration file together with the AMF bind address in Step 6c.

  6. Connecting the RAN to the core network: Before starting the gNB (or, in the split mode, the CU/DU), the RAN node must be able to reach the AMF of the data-center core network over the Base Station container’s core-facing interface. For most base stations this interface is eth4. The Agronomy Farm BS is the exception — its core-facing interface is eth3.

    Important

    In the steps below, replace eth4 with eth3 only if your reserved base station is the Agronomy Farm BS. All other base stations use eth4 as shown.

    6a. Note the eth4 IP address. Find the IP address of the eth4 interface of the Base Station container (use eth3 instead if you are on the Agronomy Farm BS):

    # ifconfig eth4
    

    For this experiment we assume the IP address of eth4 is 10.189.3.112.

    6b. Add the route to the core network and verify AMF reachability. The Base Station container ships an add_route.sh helper that adds the static route to the core-network subnet. It takes your own eth4 IP from Step 6a as its only argument, and adds the route. Continuing the Step 6a example where eth4 is 10.189.3.112:

    # ~/add_route.sh 10.189.3.112
    

    Important

    The 10.189.3.112 shown above is only an example — it matches the eth4 IP assumed in Step 6a. Replace it with the actual eth4 IP you obtained from your own container in Step 6a. The script computes the gateway from the IP you pass, so handing it the wrong IP will install a wrong route.

    Once the route is added, ping the AMF to confirm it is reachable:

    # ping -I eth4 10.189.8.8
    

    A successful ping confirms the RAN node can reach the AMF (10.189.8.8). Stop the ping with CTRL+C once a few replies are received.

    Note

    If you ping the AMF before running add_route.sh, the ping will fail because there is no path to the core-network subnet. Run the script with your eth4 IP and ping again — the route must be in place for the N2/AMF connection (and therefore the gNB/CU) to come up successfully.

    6c. Configure the RAN node(s). Open the YAML configuration file for the mode you intend to run and update both settings in a single pass:

    • the SDR address — set ru_sdr -> device_args (the addr= value) to the SDR IP from Step 5 (e.g., 192.168.30.2 for a Horticulture UE).

    • the N2/AMF bind address — set cu_cp -> amf -> bind_addr to the eth4 IP from Step 6a (e.g., 10.189.3.112).

    In the monolithic deployment both settings live in the same file. In the OCU-ODU split they live in two different files — the O-DU drives the radio and the O-CU carries the N2/AMF connection:

    • Monolithic gNB — both settings in ~/ocudu/build/apps/gnb/gnb_n320_tdd_n78_40mhz.yaml

    • OCU-ODU split

      • SDR address in ~/ocudu/build/apps/du/du_n320_tdd_n78_40mhz.yaml

      • Bind address in ~/ocudu/build/apps/cu/cu_n320_tdd_n78_40mhz.yaml

    For example, to edit the monolithic gNB configuration file:

    # nano ~/ocudu/build/apps/gnb/gnb_n320_tdd_n78_40mhz.yaml
    

    The SDR address and the bind address appear in the file as shown below — here the SDR is set to 192.168.30.2 (Horticulture UE) and the bind address is set to the eth4 IP 10.189.3.112.

    ../../_images/ocudu_sdr_IP_setting.png

    ../../_images/ocudu_modify_bind_addr.png

    Note

    The O-DU configuration file has no bind-address setting (the O-DU does not connect to the AMF) and the O-CU configuration file has no SDR setting (the O-CU does not drive the radio). In the OCU-ODU split you therefore touch each file exactly once.

  1. Starting the near-RT-RIC — choose your RIC: The experiment supports two near-RT-RIC implementations. Select the tab below for the RIC you want to use. Keep the RIC running for the entire experiment; all subsequent components must be started in their own terminals of the Base Station container.

    FlexRIC runs as a native binary on the Base Station container. It accepts E2 connections on 127.0.0.1:36421 and serves xApps on 127.0.0.1:36422.

    In a terminal of the Base Station container, start the near-RT-RIC:

    # cd ~
    # ./flexric/build/examples/ric/nearRT-RIC
    

    On startup, the RIC loads its service models and waits for E2 nodes to connect, as shown below.

    ../../_images/ocudu_ric_started.png

  1. Deploying the RAN — choose your mode: OCUDU can be deployed either as a monolithic gNB or as a disaggregated OCU-ODU split. Select the tab below for the mode you want to run. Every step after this one is identical for both modes.

    Note

    When starting the gNB, O-CU, or O-DU, append the e2 section flags on the command line to set the near-RT-RIC address and the local E2 bind address:

    • FlexRIC (RIC runs on localhost): e2 --addr="127.0.0.1" --bind_addr="127.0.0.1"

    • ORAN SC RIC (RIC runs in another Docker): e2 --addr="10.0.2.10" --bind_addr="10.0.2.1"

    Replace the example addresses with the actual RIC IP and the desired local bind address in your deployment.

    In the monolithic deployment, the complete gNB (CU + DU) runs as a single process and exposes one E2 agent to the near-RT-RIC.

    8a. Start the monolithic gNB. In a new terminal of the Base Station container, run (substitute the E2 flags for your chosen RIC). Here we assume the gNB connects to the ORAN SC RIC:

    # cd ~/ocudu/build/apps/gnb
    # ./gnb -c gnb_n320_tdd_n78_40mhz.yaml e2 --addr="10.0.2.10" --bind_addr="10.0.2.1"
    

    The gNB brings up the radio, connects to the AMF over the N2 interface, and connects to the near-RT-RIC over E2AP. When you see ==== gNB started ====, the gNB is ready.

    ../../_images/ocudu_gnb_monolithic_started.png

    8b. Verify the RIC accepts the E2 setup. For FlexRIC, switch to the near-RT-RIC terminal. The RIC receives an E2 SETUP-REQUEST from the gNB and accepts its RAN functions (E2SM-KPM and E2SM-RC).

    ../../_images/ocudu_RIC_accepts_E2_setup_request.png

    For the ORAN SC RIC, the E2 connection is visible in the gNB console log, as shown below.

    ../../_images/ocudu_gnb_cu_du_connects_to_oran_osc_ric.png

    The monolithic gNB registers with the RIC as a single E2 node (RAN type ngran_gNB).

  2. Bringing up the UE: On the UE container, run the UE start script. It automates the full bring-up: rebooting the Quectel radio, checking 5G NR registration, establishing the PDU session with Quectel Connection Manager, and detecting the assigned data interface.

    # ./ue_start.sh
    

    The script performs the following steps automatically:

    • [1/4] Reboot the Quectel radio

    • [2/4] Check UE registration to the 5G network (retries if not yet registered)

    • [3/4] Start the PDU session using Quectel Connection Manager

    • [4/4] Detect the network interface and its IPv4 address

    While the UE registers, the gNB/DU console shows the UE attaching to the cell.

    ../../_images/ocudu_ue_registers_with_network.png

    After a successful run, the UE is assigned an IP address by the Session Management Function of the core network and a data interface (e.g., enxd282e9c1b604) is ready for user-plane testing. The script prints convenient ping and iperf3 commands at the end for your reference.

    ../../_images/ocudu_pdu_session_established.png

    Note

    If the script reports Timed out waiting for enx* interface the PDU session did not come up. Re-run ./ue_start.sh — the radio often needs a second reboot to register.

    ../../_images/ocudu_ue_fails_to_establish_pdu_session.png

Monitoring Throughput with the xApp

  1. Generate user-plane traffic: On the UE container, copy the iperf3 command printed by ue_start.sh and run it to measure downlink throughput from the core network to the UE. The -R flag selects reverse (downlink) mode. Use a long duration so the xApp has time to collect KPM measurements while traffic is flowing. For example:

    # iperf3 -c 10.45.0.1 -p 5203 -B 10.45.0.10 -R -t 120
    

    Note

    Use your UE’s assigned IP address (from Step 9) in the -B flag.

    The iperf3 output shows the achieved throughput.

    ../../_images/iperf3_ocudu.png

  2. Starting the KPM monitor xApp: With iperf3 traffic flowing, start the KPM monitoring xApp in a new terminal of the Base Station container. The xApp subscribes to E2 nodes through the near-RT-RIC and collects per-UE downlink/uplink throughput metrics. Select the tab below for your chosen RIC.

    Start the O-RAN KPM monitoring xApp. The xApp reads xapp_moni_e2sm_kpm.conf, which requests the DRB.UEThpDl and DRB.UEThpUl (downlink/uplink per-UE throughput) measurements at a 1000 ms reporting period.

    # cd ~/flexric/build/examples/xApp/c/monitor
    # ./xapp_oran_moni -c ./xapp_moni_e2sm_kpm.conf
    

    The xApp connects to the near-RT-RIC, exchanges an E42 SETUP with the RIC, and discovers the registered E2 node(s).

    ../../_images/ocudu_xApp_starts_and_connects_to_ric.png

    On the near-RT-RIC terminal you can see the xApp connecting and issuing the KPM subscription request toward the RAN function.

    ../../_images/ocudu_xApps_connects_to_ric.png

    Note

    The xApp discovers one E2 node in the monolithic deployment and two E2 nodes (CU and DU) in the OCU-ODU split deployment. The subscription and monitoring steps are otherwise identical.

  3. Observe the KPMs at the xApp: The xApp receives periodic KPM indication messages from the E2 node(s) and prints the per-UE downlink and uplink throughput (DRB.UEThpDl / DRB.UEThpUl) collected through the near-RT-RIC. Select the tab for your chosen RIC to see the expected output.

    ../../_images/ocudu_xApps_collects_ULandDL_throughput_from_E2nodes.png

    Tip

    In the OCU-ODU split deployment the xApp collects KPMs from both the CU and the DU E2 nodes, letting you observe the disaggregated RAN through a single near-RT-RIC.

  4. View the RAN node metrics: On the gNB (monolithic) or the DU (split) terminal, press t followed by ENTER to display the live per-UE radio metrics — PCI, RNTI, CQI, MCS, DL/UL bit-rate, PUSCH SNR, and packet success/drop counts — while the iperf3 test runs.

    ../../_images/ocudu_gNB_or_DU_logs_with_userdata.png

Troubleshooting

  • DU cannot connect to the CU (split mode): Ensure the O-CU was started before the O-DU and that it reports F1-C: Listening for new connections. Restart the O-DU once the CU is ready.

  • E2 node not visible to the xApp: Confirm the near-RT-RIC is still running and that the gNB/CU/DU console reported E2AP: Connection to Near-RT-RIC completed. Verify the --addr flag matches the RIC’s actual IP address. Start the xApp only after the RAN node(s) have registered with the RIC.

  • UE fails to establish a PDU session: If ue_start.sh times out waiting for the enx* interface, re-run the script.

Tip

If you want to perform weather measurements along with the RAN experiment, refer to ARA Weather APIs.