Running the SS Xapp

Table of Contents

Prerequisites

System Requirements

Hardware

For ZMQ scenario:

  • 1 machine

For USRP scenario:

  • 3 - 4 machines (1 for EPC & eNB, 2 - 3 for UEs)

  • 1 B210 for each machine

  • 1 Octoclock for 10MHz reference

Software

  1. Deploy Near-Real Time RIC (EPC & eNB server ONLY)

    Follow instructions on the OAIC documentation: O-RAN Near-Real Time RIC Installation Guide

  2. Next install all the required dependencies, ZMQ, UHD and asn1c Compiler

    Follow instructions on OAIC documentation for installation of dependencies, ZMQ and as1nc compiler: srsRAN with E2 Agent Installation Guide. Do NOT follow the section that says srsRAN with E2 agent Installation.

  3. Clone down the srslte modified with e2

cd ~/oaic
git clone https://github.com/openaicellular/srslte-e2
cd srslte-e2
rm -rf build
mkdir build
export SRS=`realpath .`
cd build
cmake ../ -DCMAKE_BUILD_TYPE=RelWithDebInfo \
    -DRIC_GENERATED_E2AP_BINDING_DIR=${SRS}/e2_bindings/E2AP-v01.01 \
    -DRIC_GENERATED_E2SM_KPM_BINDING_DIR=${SRS}/e2_bindings/E2SM-KPM \
    -DRIC_GENERATED_E2SM_GNB_NRT_BINDING_DIR=${SRS}/e2_bindings/E2SM-GNB-NRT
make -j`nproc`
sudo make install
sudo ldconfig
sudo srslte_install_configs.sh user --force

Warning

The rest of this section is for EPC & eNB server ONLY if you are working with USRPs and ZMQ. If you’re setting up for a UE for USRPs, skip to the Starting the network with USRPs section.

After install srslte modified, open the user_db.csv file with your preferred text editor

sudo -i
cd .config/srslte
vim user_db.csv

Replace these lines of code with the existing configurations at the bottom of the file. This allows the ENB to be able to connect with 3 UEs.

Kept in the following format: “Name, Auth, IMSI, Key, OP_Type, OP/OPc, AMF, SQN, QCI, IP_alloc”.

ue2,xor,001010123456780,00112233445566778899aabbccddeeff,opc,63bfa50ee6523365ff14c1f45f88737d,8000,000000001635,7,dynamic
ue3,xor,001010123456781,00112233445566778899aabbccddeeff,opc,63bfa50ee6523365ff14c1f45f88737d,8002,0000000014eb,7,dynamic
ue1,xor,001010123456789,00112233445566778899aabbccddeeff,opc,63bfa50ee6523365ff14c1f45f88737d,9001,00000000131b,7,dynamic

Exit out of sudo once you are done editing the file

exit

We can now clone the repositories we will need to run build the xapp and onboard it as well as run multiple UEs.

Setup

Install the following dependencies

sudo apt install gnuradio python3-pip iperf3 -y

Under the oaic directory, run the following commands

cd ~/oaic
git clone https://github.com/openaicellular/ss-xapp.git

Note

If you do not have Nginx web server setted up, head over to the xApp Deployment - General Guidelines and follow the Configuring the Nginx Web Server section ONLY and nothing else.

Create a symlink from the xApp’s config file. This can be replaced by another symlink in the future. Reload Nginx once this has been done.

cd ~/oaic/ss-xapp
sudo cp config-file.json /var/www/xApp_config.local/config_files/
sudo systemctl reload nginx

Now we are going to build the xapp from the DockerFile

cd ~/oaic/ss-xapp
sudo docker build . -t xApp-registry.local:5008/ss:0.1.0

Paste the following in the ss-xapp-onboard.url file located in the ss-xapp directory. Substitute the <machine_ip_addr> with the IP address of your machine. You can find this out by pasting the command ifconfig or hostname -I in the terminal.

cd ~/oaic/ss-xapp
vim ss-xapp-onboard.url
{"config-file.json_url":"http://<machine_ip_addr>:5010/config_files/config-file.json"}

Starting the network with ZMQ

Note

If you are using USRPs, head to Starting the network with USRPs.

Terminal 1: Start the Core Network/Add Ues to Network Namespace

sudo ip netns add ue1
sudo ip netns add ue2
sudo ip netns add ue3
sudo ip netns list
sudo srsepc

Terminal 2: Set up Environment Variables and Base Station

export E2NODE_IP=`hostname  -I | cut -f1 -d' '`
export E2NODE_PORT=5006
export E2TERM_IP=`sudo kubectl get svc -n ricplt --field-selector metadata.name=service-ricplt-e2term-sctp-alpha -o jsonpath='{.items[0].spec.clusterIP}'`
sudo srsenb --enb.n_prb=100 --enb.name=enb1 --enb.enb_id=0x19B \
--rf.device_name=zmq --rf.device_args="fail_on_disconnect=true,tx_port=tcp://*:2000,rx_port=tcp://localhost:2009,id=enb,base_srate=23.04e6" --ric.agent.remote_ipv4_addr=${E2TERM_IP} --log.all_level=warn --ric.agent.log_level=debug --log.filename=stdout --ric.agent.local_ipv4_addr=${E2NODE_IP} --ric.agent.local_port=${E2NODE_PORT} --slicer.enable=1 --slicer.workshare=0

Warning

Make sure you can see the eNB have a RIC State Establish message as shown in the image below before proceeding.

eNB having a RIC State Established message

Note

If you are not getting a RIC State Established message, you need to restart the e2term-alpha pod by using the command: sudo kubectl delete pod -n ricplt -l app=ricplt-e2term-alpha. If that still doesn’t work, undeploy and redeploy the near-realtime RIC.

Terminal 3: Set up the first UE

sudo srsue \
--rf.device_name=zmq --rf.device_args="tx_port=tcp://*:2010,rx_port=tcp://localhost:2300,id=ue,base_srate=23.04e6" --usim.algo=xor --usim.imsi=001010123456789 --usim.k=00112233445566778899aabbccddeeff --usim.imei=353490069873310 --log.all_level=warn --log.filename=stdout --gw.netns=ue1

Terminal 4: Set up the second UE

sudo srsue \
--rf.device_name=zmq --rf.device_args="tx_port=tcp://*:2007,rx_port=tcp://localhost:2400,id=ue,base_srate=23.04e6" --usim.algo=xor --usim.imsi=001010123456780 --usim.k=00112233445566778899aabbccddeeff --usim.imei=353490069873310 --log.all_level=warn --log.filename=stdout --gw.netns=ue2

Terminal 5: Set up the third UE

sudo srsue \
--rf.device_name=zmq --rf.device_args="tx_port=tcp://*:2008,rx_port=tcp://localhost:2500,id=ue,base_srate=23.04e6" --usim.algo=xor --usim.imsi=001010123456781 --usim.k=00112233445566778899aabbccddeeff --usim.imei=353490069873310 --log.all_level=warn --log.filename=stdout --gw.netns=ue3

GUI

Open the GNU Radio Companion App. It should be installed when installing the gnuradio package. Open the multi_ue.grc file located in the ~/oaic/ss-xapp directory.

Press play as marked in the image below. This allows the UEs to attach to the eNodeB base station.

GNU Flowchart

No GUI

Note

If you have already ran the GNU Radio Companion Application, skip this step.

If you running without a GUI, open a new terminal and run the following commands:

cd ~/oaic/ss-xapp
python3 multi_ue.py

Iperf3

Note

Execute the next commands each in a separate terminal

Terminal 6/7/8: Set up iperf3 test on the server side

iperf3 -s -B 172.16.0.1 -p 5006 -i 1
iperf3 -s -B 172.16.0.1 -p 5020 -i 1
iperf3 -s -B 172.16.0.1 -p 5021 -i 1

Note

Execute the next commands each in a separate terminal

Terminal 9/10/11: Set up iperf3 test on the client side

We add an additional bandwidth argument “-b xxM” on each iperf3 test on client side to create a scenario of UEs trying to access more or less of resources on the network. If a UE surpasses the pre-determined threshold for amount of data packets transmitted, it is considered as malicious by the SS xApp.

sudo ip netns exec ue1 iperf3 -c 172.16.0.1 -p 5006 -i 1 -t 36000 -R -b 40M
sudo ip netns exec ue2 iperf3 -c 172.16.0.1 -p 5020 -i 1 -t 36000 -R -b 10M
sudo ip netns exec ue3 iperf3 -c 172.16.0.1 -p 5021 -i 1 -t 36000 -R -b 15M

You should notice traffic flow on both the server and client side for both UEs.

Move on to the Deploying the SS xApp section for deploying the xApp

Starting the network with USRPs

Note

If you already started the network using ZMQ, you can head to the Deploying the SS xApp section

For better performance of USRPs, we use the CDA-2990 Octoclock as an external clock reference source for the B210s. To ensure that the B210s recognize the source, we have to add an extra argument “clock=external” on the eNodeB and UE commands.

B210 with Octoclock Setup

Connect the SMA cables from each of the 10 MHz out of the Octoclock to the REF IN port for the B210 as shown in the picture.

Connect the two Antennas in the RF A section for both the TX/RX and RX2 ports.

Connect the USB port from the B210 to your machines.

Before starting the network, check to see if each machine recognizes the USRPs by using the following command.

sudo uhd_images_downloader
sudo uhd_find_devices

Install iperf3 for all machines if not already done so.

sudo apt install iperf3 -y

Machine 1 - Terminal 1: Start the Core Network on server side (eNodeB server)

sudo srsepc

Machine 1 - Terminal 2: Set up Environment Variables and Base Station

export E2NODE_IP=`hostname  -I | cut -f1 -d' '`
export E2NODE_PORT=5006
export E2TERM_IP=`sudo kubectl get svc -n ricplt --field-selector metadata.name=service-ricplt-e2term-sctp-alpha -o jsonpath='{.items[0].spec.clusterIP}'`
sudo srsenb --enb.n_prb=100 --enb.name=enb1 --enb.enb_id=0x19B --rf.device_name=uhd --rf.device_args="clock=external" --ric.agent.remote_ipv4_addr=${E2TERM_IP} --log.all_level=warn --ric.agent.log_level=debug --log.filename=stdout --ric.agent.local_ipv4_addr=${E2NODE_IP} --ric.agent.local_port=${E2NODE_PORT} --slicer.enable=1 --slicer.workshare=0

Warning

Make sure you can see the eNB have a RIC State Establish message as shown in the image below before proceeding.

eNB having a RIC State Established message

Note

If you are not getting a RIC State Established message, you need to restart the e2term-alpha pod by using the command: sudo kubectl delete pod -n ricplt -l app=ricplt-e2term-alpha. If that still doesn’t work, undeploy and redeploy the near-realtime RIC.

Machine 2 - Terminal 1: Set up the first UE

sudo srsue \
--rf.device_name=uhd --rf.device_args="clock=external" --usim.algo=xor --usim.imsi=001010123456789 --usim.k=00112233445566778899aabbccddeeff --usim.imei=353490069873310  --log.all_level=warn --log.filename=stdout

Machine 3 - Terminal 1: Set up the second UE

sudo srsue \
--rf.device_name=uhd --rf.device_args="clock=external" --usim.algo=xor --usim.imsi=001010123456780 --usim.k=00112233445566778899aabbccddeeff --usim.imei=353490069873310  --log.all_level=warn --log.filename=stdout

Machine 4 - Terminal 1: Set up the third UE (If you have one)

sudo srsue \
--rf.device_name=uhd --rf.device_args="clock=external" --usim.algo=xor --usim.imsi=001010123456781 --usim.k=00112233445566778899aabbccddeeff --usim.imei=353490069873310  --log.all_level=warn --log.filename=stdout

Machine 1 - Terminal 3/4/5: Set up iperf3 test on the server side (eNodeB server)

iperf3 -s -B 172.16.0.1 -p 5006 -i 1
iperf3 -s -B 172.16.0.1 -p 5020 -i 1
iperf3 -s -B 172.16.0.1 -p 5021 -i 1 # If you have a third UE

Machine 2/3/4 - Terminal 2: Set up iperf3 test on the client side (UE servers)

We add an additional bandwidth argument “-b xxM” on each iperf3 test on client side to create a scenario of UEs trying to access more or less of resources on the network. If a UE surpasses the pre-determined threshold for amount of data packets transmitted, it is considered as malicious by the SS xApp.

sudo iperf3 -c 172.16.0.1 -p 5006 -i 1 -t 36000 -R -b 40M
sudo iperf3 -c 172.16.0.1 -p 5020 -i 1 -t 36000 -R -b 10M
sudo iperf3 -c 172.16.0.1 -p 5021 -i 1 -t 36000 -R -b 15M # If you have a third UE

You should notice traffic flow on both the server and client side for all three UEs. Move on to the next step.

Deploying the SS xApp

cd ~/oaic/ss-xapp
export KONG_PROXY=`sudo kubectl get svc -n ricplt -l app.kubernetes.io/name=kong -o jsonpath='{.items[0].spec.clusterIP}'`
export E2MGR_HTTP=`sudo kubectl get svc -n ricplt --field-selector metadata.name=service-ricplt-e2mgr-http -o jsonpath='{.items[0].spec.clusterIP}'`
export APPMGR_HTTP=`sudo kubectl get svc -n ricplt --field-selector metadata.name=service-ricplt-appmgr-http -o jsonpath='{.items[0].spec.clusterIP}'`
export E2TERM_SCTP=`sudo kubectl get svc -n ricplt --field-selector metadata.name=service-ricplt-e2term-sctp-alpha -o jsonpath='{.items[0].spec.clusterIP}'`
export ONBOARDER_HTTP=`sudo kubectl get svc -n ricplt --field-selector metadata.name=service-ricplt-xapp-onboarder-http -o jsonpath='{.items[0].spec.clusterIP}'`
export RTMGR_HTTP=`sudo kubectl get svc -n ricplt --field-selector metadata.name=service-ricplt-rtmgr-http -o jsonpath='{.items[0].spec.clusterIP}'`
curl -L -X POST "http://$KONG_PROXY:32080/onboard/api/v1/onboard/download" --header 'Content-Type: application/json' --data-binary "@ss-xapp-onboard.url"
curl -L -X GET "http://$KONG_PROXY:32080/onboard/api/v1/charts"
curl -L -X POST "http://$KONG_PROXY:32080/appmgr/ric/v1/xapps" --header 'Content-Type: application/json' --data-raw '{"xappName": "ss"}'

Warning

If you are repeating an experiement, you may want to restart the pod using the command below. By doing so, you do not have to undeploy and redeploy the xApp again.

sudo kubectl -n ricxapp rollout restart deployment ricxapp-ss

Running the xApp

In your EPC & eNB server’s terminal, print the logs for the SS xApp

Note

The SS xApp has to be deployed in order for this to work.

sudo kubectl logs -f -n ricxapp -l app=ricxapp-ss

Now run the test script with the following commands on a separate terminal, depending on the number of UEs you have.

Two UEs

cd ~/oaic/ss-xapp
sudo chmod +x zmqtwoue.sh
sudo ./zmqtwoue.sh

Three UEs

cd ~/oaic/ss-xapp
sudo chmod +x zmqthreeue.sh
sudo ./zmqthreeue.sh

After a short time you can observe through the logs that UE1 will be considered malicious and moved to a different slice. You also observe the traffic exchange for UE1 will significantly decrease.

Note

To run the script again, you have to restart the SS xApp and redeploy the network again.

sudo kubectl -n ricxapp rollout restart deployment ricxapp-ss