KPM xApp with the OSC Near-RT RIC and NVIDIA ARC on X5G

How to run a KPM xApp leveraging the X5G testbed comprising OAI, NVIDIA ARC-OTA, and the OSC Near-RT RIC


X5G is an open, programmable, and multi-vendor private 5G O-RAN testbed that leverages the NVIDIA Aerial SDK for the High-PHY layer and OpenAirInterface for the higher layers.

More details can be found in the following paper:

D. Villa, I. Khan, F. Kaltenberger, N. Hedberg, R. Soares da Silva, S. Maxenti, L. Bonati, A. Kelkar, C. Dick, E. Baena, J. M. Jornet, T. Melodia, M. Polese, and D. Koutsonikolas, "X5G: An Open, Programmable, Multi-vendor, End-to-end, Private 5G O-RAN Testbed with NVIDIA ARC and OpenAirInterface," arXiv:2406.15935 [cs.NI], pp. 1-15, June 2024. [pdf] [bibtex]

This tutorial servers as a reference on how to operate a Key Performance Measurement (KPM) xApp in an end-to-end platform with similar capabilities to those provided by X5G. A possible final outcome of this tutorial can be found on this X5G Overview Video.


The following prerequisites are recommended to be met in order to properly run the tutorial.


The NVIDIA Aerial information and installation guide are available on its official website.


The O-RAN Software Community (OSC) Near-RT RIC Release E can be installed following this guide. Note that for this tutorial, the OSC Near-RT RIC runs on an OpenShift cluster, whereas a plain Kubernetes deployment might require specific networking configurations.

OpenAirInterface with Custom E2 Agent

The OpenAirInterface (OAI) gNB code requires the addition of a custom E2 Agent to manage E2SM (E2 Service Model) functionalities that has been developed and tested as part of the following publication:

E. Moro, M. Polese, A. Capone, T. Melodia, "An Open RAN Framework for the Dynamic Control of 5G Service Level Agreements," in Proceedings of IEEE NFV-SDN, Dresden, Germany, November 2023. [pdf] [bibtex]

The E2 agent is based on the OSC e2sim project. An OAI version with the custom E2 Agent already integrated in the 2024.w18 release of OAI can be found at this GitHub repository.


A basic and easily extensible xApp developed in Python can be found at the GitHub repository. This repository contains some Python examples that can subscribe to selected RAN parameters, receive periodic indication messages, and send control requests to update these parameters.

xApp SM Connector

The xApp SM connector component connects the xApp with the OSC Near-RT RIC. On one side, it receives the custom SM buffers to be encapsulated in E2AP (E2 Application Protocol) messages and sent to the RIC. On the other side, it retrieves the custom SM buffers from E2AP to be sent to the xApp. The connector is part of the base xApp code and can be found at this GitHub repository.


The e2sim is a component that can run on the same server as the OAI L2/L3 and ARC PHY and has the duty to encapsulate/decapsulate the custom Service Model (SM) buffers to be sent to or received from the gNB. It communicates with the gNB via UDP sockets. The e2sim codebase can be found at this GitHub repository.

Run the System

We assume that all components listed in the prerequisites, such as the gNB with NVIDIA ARC-OTA and OAI, OSC Near-RT RIC, e2sim, and xApp, have been compiled and are functioning properly. Please note that the commands and terminals used in this tutorial may vary depending on your setup.

To run the system in this tutorial, we open 5 terminals as follows:

  • Terminal 1 (T1): NVIDIA L1 cuBB (Server 1 with A100 GPU)
  • Terminal 2 (T2): OAI L2 (Server 1 same as cuBB)
  • Terminal 3 (T3): e2sim (Server 1 same as cuBB)
  • Terminal 4 (T4): xApp connector (xApp Container in OSC RIC)
  • Terminal 5 (T5): xApp Python (xApp Container in OSC RIC)
  • (Optional) Terminal 6 (T6): UEs

In T1, we first run the NVIDIA L1 cuBB, for example, by using the following command (it may vary based on your ARC release and configurations, please refer to Running cuBB End-to End):

sudo -E /opt/nvidia/cuBB/build/cuPHY-CP/cuphycontroller/examples/cuphycontroller_scf P5G FXN

In T2, once the L1 is ready, we can run the custom version of OAI with the usual OAI start command (note that this command can also vary based on your OAI configuration):

./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/

From this point onwards, we can connect the UEs as desired, for example, from within T6.

In T3, we run the e2sim on the same machine where OAI is running, specifying the IP and port of the OSC Near-RT RIC, for example:

./ 32222

The E2 Agent of the gNB and the RIC are successfully connected if the following prompt is shown:


In T4, we can start connecting our xApp by running the xapp-sm-connector with:

cd xapp-sm-connector

We wait for the connector to finish its initialization, which is indicated by, for example, the following line:

Opened control socket server on port 7000

In T5, we start the xApp Python code by running, for example:

cd base-xapp

If everything is running correctly, we should periodically see the UEs’ metrics displayed on the screen:

report index 3
rnti: 15026
tbs_avg_dl: 0.0
tbs_avg_ul: 0.0
is_GBR: false
dl_mac_buffer_occupation: 1953239.0
avg_prbs_dl: 0.0
mcs: 23
avg_tbs_per_prb_dl: 0.0
avg_rsrp: -79.0
ph: 52.0
pcmax: 21.0
dl_total_bytes: 6613826048.0
dl_errors: 0.0
dl_bler: 0.07657613605260849
dl_mcs: 23.0
ul_total_bytes: 7838225.0
ul_errors: 0.0
ul_bler: 2.0877508055683336e-10
ul_mcs: 18.0

The script can be easily modified to save these metrics in an external dB, such as InfluxDB, and then display them on a dashboard, such as Grafana.