5G OpenAirInterface with O-RAN near-RT RIC

How to setup and use OpenAirInterface with a near-RT RIC


OpenAirInterface (OAI) is a 3GPP-compliant software implementation of the full 5G NR stack. In this tutorial, we show how OpenRAN Gym users can get started with deploying an OAI gNB on Colosseum equipped with a standard compliant E2 agent for the E2AP component and custom Service Models based on protocol buffers, together with a Near-RT RIC and a sample xApp.

The basic repository for this project can be found here. It contains submodules that point to the different projects that are relevant to this tutorial.

xApp Components

Base xApp

This is a basic xapp (base-xapp in xapp-oai submodule) that subscribes to selected RAN parameters, receives periodic indications messages and sends control requests to update these parameters. The base xApp can communicate with the gNB by means of a RIC, or via direct socket communication.

xApp SM Connector

This component (xapp-sm-connector in xapp-oai submodule) connects the xApp with the RIC. In downstream (from the xApp to the gNB), the connector receives our custom sm buffers to be encapsulated in E2AP messages and sent to the RIC. In upstream (from the gNB to the xApp), the connector retrieves custom Service Model (SM) buffers from E2AP to be sent to the xApp.

RIC Components

See ColO-RAN for a detailed description of the RIC components.

Base Station Components


Similar to what the xApp SM Connector does, the E2SIM component (e2sim submodule) encapsulates/decapsulates custom SM buffers that are to be sent or that are received from the gNB. It communicates with the gNB via UDP sockets.

gNB Emulator

This component (in the e2protobuf submodule) is a simple gNB emulator to test custom SMs without running a real gNB.

Protobuf Definitions

This repository contains our custom protobuf definitions (in the oai-oran-protolib submodule).

OpenAirInterface with xApp Agent

This component (openairinterface5g submodule) is a fork of OpenAirInterface with the addition of a custom xApp agent.

Running the Base xApp with OAI gNB

This tutorial showcases an end-to-end 5G SA deployment with a near-RT RIC and an xApp reading L2 info from the gNB.

This requires a Colosseum reservation with the following SRNs (credentials are root/pass for all):

  • oai-core for the core network functions
  • oai-gnb-e2agent for the E2-compliant gNB
  • 1 or more oai-gnb-e2agent acting as UEs
  • oai-ric for the near-RT RIC and the sample xApp

Once the reservation is ready, start the core network in the oai-core SRN:

cd oai-cn5g-fed/docker-compose
./core-network.sh start nrf spgwu

Then start the near-RT RIC in the oai-ric SRN:


and take note of the IP address of the SRN:

ifconfig col0 | grep 'inet addr:' | cut -d: -f2 | awk '{ print $1}'

You can check if all the ric components are running by using the command docker ps, whose result should be this:


Start the gNB in the oai-gnb-e2agent SRN:

./run_gnb.sh -t donor

In the same SRN, start the e2term:

cd ocp-e2sim
./run_e2sim.sh RIC_IP

where RIC_IP is the col0 IP address you have previously found. The E2 Agent of the gNB is successfully connected with the RIC if the following line is shown:


Now start the xApp container in the oai-ric SRN:


The xApp is separated into two components: an xapp-connector which establishes a connection with the RIC, and a base-xapp which implements the xApp logic.

Start the xapp-connector in a dedicated terminal:

docker exec -it base-xapp-24 bash
cd ../xapp-oai/xapp-sm-connector/

Wait for the following lines to appear:

about to call xapp startup
Still waiting for indreq buf...
Opened control socket server on port 7000

The xapp-connector is now ready to communicate with the base xApp, which should be started in a separate terminal:

docker exec -it base-xapp-24 bash
cd ../xapp-oai/base-xapp/
python3 run_xapp.py

The base xApp will now receive periodic update messages from the gNB:

Recevied RIC indication response:
param_map {
  key: GNB_ID
  string_value: "0"
param_map {
  key: UE_LIST
  ue_list {
    connected_ues: 0

Since no UEs are connected, the collection of UE L2 statistics is empty. Run the following command in a oai-gnb-e2agent SRN different from the one where the gNB is running to activate an UE:

colosseumcli rf start -c 10011

to activate a 0dB attenuation rf scenario, and:


to finally start the UE. The xApp is now reporting the statistics:

param_map {
  key: GNB_ID
  string_value: "0"
param_map {
  key: UE_LIST
  ue_list {
    connected_ues: 1
    ue_info {
      rnti: 21000
      dlsch_errors: 0
      dlsch_total_bytes: 24477
      dlsch_current_bytes: 0
      ulsch_errors: 0
      ulsch_total_bytes_rx: 21344
      num_rsrp_meas: 0
      sched_ul_bytes: 0
      estimated_ul_buffer: 0
      num_total_bytes: 0
      raw_rssi: 1022
      pusch_snrx10: 240
      pucch_snrx10: 350
      ul_rssi: 0

You can add more UEs. To test the end-to-end connection add the route to the UE subnet in the core network SRN:

ip route add via

In the UE SRN, add the route to the core network host:

ip route add via

and take note of the UE GTP endpoint IP:

ifconfig oaitun_ue1 | grep 'inet addr:' | cut -d: -f2 | awk '{ print $1}'

Run an iperf3 server in the UE SRN:

iperf3 -s

and test the connection in downlink by running this in the oai-core SRN:

iperf3 -c UE_IP -u -b 1M 

where UE_IP is the UE GTP endpoint IP. Add -R to the previous command to the the uplink connection.