Skip to main content

Lab 1: “My hello world” monitoring xApp

In this experiment we will deploy a 5G Standalone (SA) network using OpenAirInterface (OAI) RF Simulator gNB and OAI minimal 5GC. We also deploy FlexRIC as the Near-RT RIC. Finally a simple hello world xApp will be deployed on bare-metal connecting to the deployed RIC.

open-ran.yaml
apiVersion: athena.trirematics.io/v1
kind: Network
metadata:
name: bubbleran
namespace: trirematics
spec:
slices:
- plmn: "00101"
dnn: "internet"
network-mode: "IPv4"
service-type: eMBB
differentiator: 0x000000
ipv4-range: "12.1.1.0/24"
ipv6-range: "2001:db8:1::/64"
access:
- name: oai-gnb
stack: 5g-sa
model: oai-ran/monolithic-gnb
identity:
an-id: 50
radio:
device: rf-sim
cells:
- band: n78
arfcn: 641280
bandwidth: 40MHz
subcarrier-spacing: 30kHz
tdd-config:
period: 5ms
dl-slots: 7
dl-symbols: 6
ul-slots: 2
ul-symbols: 4
controller: flexric.bubbleran
core-networks:
- minimal.bubbleran
core:
- name: minimal
stack: 5g-sa
model: oai-cn/minimal
identity:
region: 0
cn-group: 4
cn-id: 5
dns:
ipv4:
default: 8.8.8.8
secondary: 8.8.4.4
edge:
- name: flexric
stack: 5g-sa
model: mosaic5g/flexric
---
apiVersion: athena.trirematics.io/v1
kind: Terminal
metadata:
name: ue1
namespace: trirematics
spec:
vendor: oai
stack: 5g-sa
model: terminal/nr-rfsim
preferred-access: oai-gnb.bubbleran
target-cores:
- minimal.bubbleran
identity:
imsi: "001010000000001"
pin: "1234"
opc: "0xc42449363bbad02b66d16bc975d77cc1"
key: "0xfec86ba6eb707ed08905757b1bb44b8f"
sqn: "0xff9bb4000001"
slice:
dnn: "internet"
network-mode: "IPv4"
service-type: eMBB
differentiator: 0x000000
radio:
bands:
- n78
readiness-check:
method: ping
target: google-ip
interface-name: oaitun_ue0

---
apiVersion: athena.trirematics.io/v1
kind: Terminal
metadata:
name: ue2
namespace: trirematics
spec:
vendor: oai
stack: 5g-sa
model: terminal/nr-rfsim
preferred-access: oai-gnb.bubbleran
target-cores:
- minimal.bubbleran
identity:
imsi: "001010000000002"
pin: "1234"
opc: "0xc42449363bbad02b66d16bc975d77cc1"
key: "0xfec86ba6eb707ed08905757b1bb44b8f"
sqn: "0xff9bb4000001"
slice:
dnn: "internet"
network-mode: "IPv4"
service-type: eMBB
differentiator: 0x000000
radio:
bands:
- n78
readiness-check:
method: ping
target: google-ip
interface-name: oaitun_ue0

Deployment

Use the command brc install network open-ran.yaml to deploy the network. It should finish without errors and printout the three Kubernetes resource names that were created. Check for the status of the deployment using the command brc observe. Wait until all the Elements other than the UE are in the STATUS set to 1/1 Y state.

After deploying the network, before running the xApp, you should update the xApp configuration file with the IP of the deployed Near-RT RIC, the local source IP in the cluster subnet. To do so you may execute the update_conf.sh script which automatically extract the IPs from the cluster and updates the specified configuration file:

cd /path/to/xapp_sdk/conf
./update_conf.sh -c default.conf

The script will prompt the user for selecting which Near-RT RIC the xApp should connect to (in case of multiple RICs and/or networks currently deployed). After selecting a RIC to connect an output as the following is obtained:

Select the RIC to configure (enter number):
1) flexric.flexric.bubbleran (10.244.0.251)
Choice [1-1]: 1
Selected RIC: flexric.flexric.bubbleran with IP 10.244.0.251
Local IP for xApp: 10.244.0.218
Config file 'default.conf' updated successfully.

Once the configuration file has been updated accordingly, the coding challenge of lab 1 can be addressed.

lab1.c
/*
Copyright (C) 2021-2025 BubbleRAN SAS

External application
Last Changed: 2025-05-02
Project: MX-XAPP
Full License: https://bubbleran.com/resources/files/BubbleRAN_Licence-Agreement-1.3.pdf)
*/

#include "xapp_sdk_api.h"
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>

int main(int argc, char** argv)
{
init_xapp_sdk(argc, argv);

// Step 1
// Retrieve information from the nearRT-RIC
// Don't forget to free it afterwards!!!

// Possible naming convention! Feel free to use it or discard it!
// global_e2_node_id_sdk_t const* node = &arr.n[0].node ;
// ue_id_e2sm_sdk_t const* ue = &arr.n[0].ue_ho[0].ue;

// Step 2
// Select monitoring variable
// e.g., mntr_var_e var = UE_THP_DL;
mntr_var_e var = END_MNTR_VAR_E;

// Step 3
// Call the function ue_mntr_xapp_sdk with
// the appropiate variables and measure the response latency
int64_t const t0 = time_now_us_sdk();
// Code Here!!!
int64_t const t1 = time_now_us_sdk();
printf(" elapsed time %ld\n", t1 - t0);

// Step 4
// Free the resources

return EXIT_SUCCESS;
}
./build/labs/lab1 -c conf/default.conf

After successfully performing the coding challenge, uou should get the following output:

22:55:49.395020 [INFO]:  conf_file.c:443 Config file path ../conf/default.conf. To change the path add -c path_to_file e.g., python3 mntr.py -c default.conf
22:55:49.395114 [INFO]: e42_xapp_api.c:81 Git SHA1 e7a9fa37e4f056ffd8ca49533e30acf2d4371ce0
22:55:49.395124 [INFO]: e42_xapp.c:191 NearRT-RIC Server IP Address = 10.244.0.46, PORT = 36422
22:55:49.395188 [INFO]: emb_sm_ag.c:93 Loaded SM(s) 10, custom SMs true
22:55:49.395200 [INFO]: emb_sm_ric.c:93 Loaded SM(s) 10, custom SMs true
22:55:49.395238 [INFO]: e42_xapp.c:227 DB_ENABLE = FALSE
22:55:49.395240 [INFO]: e42_xapp.c:232 do not initial database
22:55:49.395658 [INFO]: msg_handler_xapp.c:533 E42 SETUP-REQUEST tx
22:55:49.396094 [INFO]: msg_handler_xapp.c:374 E42 SETUP-RESPONSE rx xApp ID 11
22:55:49.396116 [INFO]: msg_handler_xapp.c:390 Connected E2 Node(s) 1
22:55:49.396559 [INFO]: msg_handler_xapp.c:568 RIC_SUBSCRIPTION_REQUEST tx RAN_FUNC_ID 2 RIC_REQ_ID 1
22:55:49.396927 [INFO]: msg_handler_xapp.c:155 RIC_SUBSCRIPTION_RESPONSE rx RAN_FUNC_ID 2 RIC_REQ_ID 1
22:55:49.398374 [INFO]: msg_handler_xapp.c:581 RIC_SUBSCRIPTION_DELETE_REQUEST tx RAN_FUNC_ID 2 RIC_REQ_ID 1
22:55:49.398615 [INFO]: msg_handler_xapp.c:195 RIC_SUBSCRIPTION_DELETE_RESPONSE RAN_FUNC_ID 2 rx RIC_REQ_ID 1
22:55:49.398724 [INFO]: msg_handler_xapp.c:568 RIC_SUBSCRIPTION_REQUEST tx RAN_FUNC_ID 2 RIC_REQ_ID 2
22:55:49.399254 [INFO]: msg_handler_xapp.c:155 RIC_SUBSCRIPTION_RESPONSE rx RAN_FUNC_ID 2 RIC_REQ_ID 2
22:55:49.400355 [INFO]: msg_handler_xapp.c:581 RIC_SUBSCRIPTION_DELETE_REQUEST tx RAN_FUNC_ID 2 RIC_REQ_ID 2
22:55:49.400640 [INFO]: msg_handler_xapp.c:195 RIC_SUBSCRIPTION_DELETE_RESPONSE RAN_FUNC_ID 2 rx RIC_REQ_ID 2
UE throughput in downlink 389752.000000

Uninstall

To uninstall the network, use the following command:

brc remove network open-ran.yaml

Checking via the brc observe command, you should see that all the elements are removed.

💬 Lab Questions 💬

  1. What is the IP address and port of the Near-RT RIC?
  2. What is the IP address and port of gNB?
  3. Measure how much time it takes between subscription to a service model (e.g. KPM) and the reception of the indication.
  4. What is the meaning of RAN_FUNC_ID and and RIC_REQ_ID.
  5. Describe the xApp lifecycle.
  6. What are the different types of xApps ?
tip

You can obtain the wireshark captures from a given element, i.e. the ones listed in the dashboard with brc observe. For example in this lab for flexric.flexric.bubbleran:

brc extract pcap flexric.flexric.bubbleran | sudo wireshark -k -i -

For more information on this tool you can check the brc reference

Advance

  1. Open wireshark and filter E2AP and draw the message sequence chart of the transaction between the E2 node and the Near-RT RIC. You can leverage this tool.
  2. Identify the interface the xApp and the Near-RT RIC.