---
# System prepended metadata

title: 'xApp Development: OSC-RIC Near RT RIC and ns-o-ran'

---

# xApp Development: OSC-RIC Near RT RIC and ns-o-ran

[TOC]

---

## Setup OSC-RIC

For installing the OSC-RIC Near RT RIC, you can follow this tutorial: [OSC-RIC Near RT RIC Installation](https://hackmd.io/@nomaden/Skh65KFOex).

## Setup ns-o-ran

For simulation o-ran, we'll be using ns3-mmwave-o-ran which supports mmwave frequencies capable of simulating gnbs.

### Clone the Repository

**Without root user**

```bash!
cd ~

git clone https://github.com/wineslab/ns-o-ran-ns3-mmwave ns3-mmwave-oran

cd ns3-mmwave-oran/contrib
git clone -b master https://github.com/o-ran-sc/sim-ns3-o-ran-e2 oran-interface
```

### Create Dockerfile

```bash!
cd ~/ns3-mmwave-oran

sudo nano Dockerfile
```

**Write this code:**

:::spoiler Dockerfile
```dockerfile!
#==================================================================================
#       Copyright (c) 2022 Northeastern University
#         Extended by Den of NTUST TEEP Programs
#
#   Licensed under the Apache License, Version 2.0 (the "License");
#   you may not use this file except in compliance with the License.
#   You may obtain a copy of the License at
#
#          http://www.apache.org/licenses/LICENSE-2.0
#
#   Unless required by applicable law or agreed to in writing, software
#   distributed under the License is distributed on an "AS IS" BASIS,
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#   See the License for the specific language governing permissions and
#   limitations under the License.
#==================================================================================

FROM ubuntu:20.04 as buildenv
ARG log_level_e2sim=3

# Install E2sim
RUN mkdir -p /workspace

# To configure tzdata without having to do it interactively
ARG DEBIAN_FRONTEND=noninteractive
ENV TZ=Etc/UTC
#RUN DEBIAN_FRONTEND=noninteractive apt-get -y install tzdata

RUN apt-get update && apt-get install -y build-essential git cmake libsctp-dev autoconf automake libtool bison flex libboost-all-dev

WORKDIR /workspace

RUN git clone -b develop https://github.com/wineslab/ns-o-ran-e2-sim /workspace/e2sim

RUN mkdir /workspace/e2sim/e2sim/build
WORKDIR /workspace/e2sim/e2sim/build
RUN cmake .. -DDEV_PKG=1 -DLOG_LEVEL=${log_level_e2sim}

RUN make package
RUN echo "Going to install e2sim-dev"
RUN dpkg --install ./e2sim-dev_1.0.0_amd64.deb
RUN ldconfig

WORKDIR /workspace

# Install ns-3
RUN apt-get install -y g++ python3 cmake ninja-build git ccache clang-format clang-tidy gdb valgrind tcpdump sqlite sqlite3 libsqlite3-dev qtbase5-dev qtchooser qt5-qmake qtbase5-dev-tools openmpi-bin openmpi-common openmpi-doc libopenmpi-dev doxygen graphviz imagemagick python3-sphinx dia imagemagick texlive dvipng latexmk texlive-extra-utils texlive-latex-extra texlive-font-utils libeigen3-dev gsl-bin libgsl-dev libgslcblas0 libxml2 libxml2-dev libgtk-3-dev lxc-utils lxc-templates iproute2 iptables libxml2 libxml2-dev libboost-all-dev

RUN git clone https://github.com/wineslab/ns-o-ran-ns3-mmwave /workspace/ns3-mmwave-oran
RUN git clone -b master https://github.com/o-ran-sc/sim-ns3-o-ran-e2 /workspace/ns3-mmwave-oran/contrib/oran-interface

WORKDIR /workspace/ns3-mmwave-oran

RUN ./ns3 configure --enable-tests --enable-examples
RUN cd cmake-cache; /usr/bin/cmake -DCMAKE_BUILD_TYPE=default -DNS3_ASSERT=ON -DNS3_LOG=ON -DNS3_WARNINGS_AS_ERRORS=OFF -DNS3_NATIVE_OPTIMIZATIONS=OFF -DNS3_EXAMPLES=ON -DNS3_PYTHON_BINDINGS=ON -DNS3_TESTS=ON -G Ninja .. ; cd ..
RUN ./ns3 build
RUN cd cmake-cache; /usr/bin/cmake --build . -j 7 ; cd ..

WORKDIR /workspace

CMD [ "/bin/sh" ]
```
:::

Then save and close the editor.

### Build ns3 Docker Image

>[!Caution] Long Process
> The building process will took a very long time, maybe up to 1 hour because there are a lot of dependencies and lots of modules to be built.
> 
> While building the image, make sure the connection to the machine or the machine itself is not turning off. If it happens, then the building process will take from the beginning.

```bash!
docker build -t ns3 -f Dockerfile . --no-cache
```

:::success
:::spoiler Output
![image](https://hackmd.io/_uploads/rJB57BBwlg.png =320x)
::::::

**Check:**

```bash!
docker image ls
```

![image](https://hackmd.io/_uploads/rJFAQSHPxe.png =400x)

### Deploy ns3 to k8s

Create Definition

```bash!
cd ~/ns-3-mmwave-oran
sudo nano ns-o-ran-pod.yaml
```

Write this code:

```yaml!
apiVersion: v1
kind: Pod
metadata:
  name: ns-3-pod
  namespace: ricplt
spec:
  containers:
  - name: ns-3-pod
    image: localhost:5000/ns3:latest
    imagePullPolicy: Always
    command: ["sleep", "infinity"]
```

Install **chart museum** and **Docker local registry**:

```bash!
docker run --rm -u 0 -it -d -p 8090:8080 -e DEBUG=1 -e STORAGE=local -e STORAGE_LOCAL_ROOTDIR=/charts -v $(pwd)/charts:/charts chartmuseum/chartmuseum:latest

docker run -d -p 5000:5000 --name registry registry:2
```

:::success
:::spoiler Output
![image](https://hackmd.io/_uploads/S1Oz_HBvel.png =500x)
::::::

Push ns3 image to local registry:
```bash!
docker tag ns3:latest localhost:5000/ns3:latest
docker push localhost:5000/ns3:latest
```

:::success
:::spoiler Output
![image](https://hackmd.io/_uploads/rk1AoBHwlg.png =500x)
::::::

**Deploy ns3**

```bash!
sudo kubectl apply -f ns-o-ran-pod.yaml
```

![image](https://hackmd.io/_uploads/SJrr2SSvgg.png =500x)

```bash!
sudo kubectl get pod ns-3-pod -n ricplt
```

:::success
:::spoiler Output
![image](https://hackmd.io/_uploads/SJEpCSSvle.png =400x)
::::::

## Deploy xApp

### Setup Chart Repo URL

```bash!
sudo nano ~/.bashrc
```

At the end of the file, insert this:

```bashrc!
#Set CHART_REPO_URL env variable
export CHART_REPO_URL=http://0.0.0.0:8090
```

Save and close and execute:

```bash!
source ~/.bashrc
```

### Setup dms_cli

```bash!
sudo su
cd ~

#Git clone appmgr
git clone "https://gerrit.o-ran-sc.org/r/ric-plt/appmgr"

#Change dir to xapp_onboarder
cd appmgr/xapp_orchestrater/dev/xapp_onboarder

#If pip3 is not installed, install using the following command
apt install python3-pip -y

#In case dms_cli binary is already installed, it can be uninstalled using following command
pip3 uninstall xapp_onboarder

#Install xapp_onboarder using following command
pip3 install ./
```

**Check:**

```bash!
dms_cli health
```

![image](https://hackmd.io/_uploads/rkHybLBwee.png =400x)

### RIC-APP-HW-Python

Link: https://github.com/o-ran-sc/ric-app-hw-python

**Clone the Repository:**

```bash!
git clone "https://gerrit.o-ran-sc.org/r/ric-app/hw-python"

cd hw-python
```

**Build the Image:**

```bash!
docker build . -f Dockerfile -t 127.0.0.1:5000/hw-python:1.0.0
```

:::success
:::spoiler Output
![image](https://hackmd.io/_uploads/HkBJ4Irwlx.png =400x)
::::::

```bash!
docker push 127.0.0.1:5000/hw-python:1.0.0
```

:::success
:::spoiler Output
![image](https://hackmd.io/_uploads/Bywl4LHwgl.png =500x)
::::::


**Change xApp Descriptor:**

```bash!
sudo nano init/config-file.json
```

**Change from this:**

:::spoiler Before
```json!
{
    "name": "hw-python",
    "version": "1.0.0",
    "containers": [
        {
            "name": "hw-python",
            "image": {
                "registry": "nexus3.o-ran-sc.org:10004",
                "name": "o-ran-sc/ric-app-hw-python",
                "tag": "1.1.0"
            }
        }
// ...
```
:::

to:

:::spoiler After
```json!
{
    "name": "hw-python",
    "version": "1.0.0",
    "containers": [
        {
            "name": "hw-python",
            "image": {
                "registry": "127.0.0.1:5000",
                "name": "hw-python",
                "tag": "1.0.0"
            }
        }
// ...
```
:::

**Onboard the xApp:**

```bash!
dms_cli onboard init/config-file.json init/schema.json
```

![image](https://hackmd.io/_uploads/HkudLUSDll.png =500x)

**Install the xApp:**

```bash!
sudo dms_cli install hw-python 1.0.0 ricxapp
```

![image](https://hackmd.io/_uploads/SkRiLLSDgx.png =500x)

**Check if xApp running:**

```bash!
sudo kubectl get pods -n ricxapp
```

:::success
:::spoiler Output
![image](https://hackmd.io/_uploads/HkYzvLSvee.png =500x)
::::::


### RIC App Kpimon

Link: https://github.com/wineslab/ns-o-ran-scp-ric-app-kpimon.git

**Clone the Repository:**

```bash!
cd ~/

git clone -b ns-o-ran https://github.com/wineslab/ns-o-ran-scp-ric-app-kpimon.git ric-app-kpimon

cd ric-app-kpimon
```

**Edit Launch Script:**

```bash!
sudo nano launch_app.sh
```

Change the script to match this:

:::spoiler launch_app.sh
```shell!
#!/bin/bash
#set -x

#export CHART_REPO_URL=http://0.0.0.0:8090

dms_cli uninstall xappkpimon ricxapp

docker build . -f Dockerfile -t 127.0.0.1:5000/kpimon_master:1.0.0 # --no-cache

docker push 127.0.0.1:5000/kpimon_master:1.0.0

dms_cli onboard xapp-descriptor/config.json xapp-descriptor/schema.json

dms_cli install xappkpimon 1.0.0 ricxapp

echo "Wait for 10 seconds"
sleep 10

unset $pod_name

pod_name=$(kubectl get pods -n ricxapp --no-headers -o custom-columns=":metadata.name")

echo kubectl exec -ti -n ricxapp $pod_name bash

# To run the kpimon
# ./kpimon -f /opt/ric/config/config-file.json
```
:::

**Launch the Script:**

```bash!
sudo ./launch_app.sh
```

:::success
:::spoiler Output
![image](https://hackmd.io/_uploads/BJIEasrwxe.png =500x)
::::::

### RIC App RC Control

Link: https://github.com/wineslab/ns-o-ran-xapp-rc.git

**Clone the Repository:**

```bash!
cd ~/

git clone -b ns-o-ran https://github.com/wineslab/ns-o-ran-xapp-rc.git ric-app-rc

cd ric-app-rc
```

**Change Launch Script:**

```bash!
sudo nano launch_app.sh
```

Change with this script:

:::spoiler launch_app.sh
```shell!
#!/bin/bash
#set -x

#export CHART_REPO_URL=http://0.0.0.0:8090

dms_cli uninstall rc ricxapp

docker build . -f Dockerfile -t 127.0.0.1:5000/rc:1.0.0 # --no-cache

docker push 127.0.0.1:5000/rc:1.0.0

dms_cli onboard xapp-descriptor/config.json xapp-descriptor/schema.json

dms_cli install rc 1.0.0 ricxapp

echo "Wait for 10 seconds"
sleep 10

unset $pod_name

#pod_name=$(kubectl get pods -n ricxapp --no-headers -o custom-columns=":metadata.name")

#echo kubectl exec -ti -n ricxapp $pod_name bash
```
:::

**Change xApp Descriptor:**

```bash!
sudo nano xapp-descriptor/config.json
```

Match to this code:

```json!
{
  "name": "rc",
  "version": "1.0.0",
  "containers": [
    {
      "name": "rc",
      "image": {
        "registry": "127.0.0.1:5000",
        "name": "rc",
        "tag": "1.0.0"
      }
    }
// ...
```

**Run Launch Script:**

```bash!
sudo ./launch_app.sh
```

:::success
:::spoiler Output
![image](https://hackmd.io/_uploads/SkmgXnrvgg.png =500x)
::::::


## Testing

At this point, we should see 3 different xApp being deployed in the kubernetes:

```bash!
sudo kubectl get pods -n ricxapp
```

![image](https://hackmd.io/_uploads/HJtP73rwxe.png =500x)

### Run ns3

**Get E2Term IP:**

```bash!
sudo kubectl get pods -n ricplt -o wide | grep e2term
```

![image](https://hackmd.io/_uploads/BJCCS6rvll.png)

**Exec into the pod:**

```bash!
sudo kubectl exec -it ns-3-pod -n ricplt -- /bin/bash
```

**Run the scenario:**

```bash!
cd ns3-mmwave-oran/

NS_LOG="RicControlMessage" ./ns3 run "scratch/scenario-zero.cc -- simTime=15 -- e2TermIp=10.244.0.19"
```

:::spoiler Output
![image](https://hackmd.io/_uploads/H1rMIprDxg.png =500x)
![image](https://hackmd.io/_uploads/HyevIpBPgx.png =300x)
:::

### Run xApp Kpimon

**Exec into the pod:**

```bash!
sudo kubectl exec -it ricxapp-xappkpimon-b88bf879d-vf7qn -n ricxapp -- /bin/bash
```

**Run the xApp:**

```bash!
./kpimon -f /opt/ric/config/config-file.json
```

:::spoiler Output
![image](https://hackmd.io/_uploads/HJWSvTSvxg.png)
:::

### Send grpc Command via rc xApp

**Get the xApp IP:**

```bash!
sudo kubectl get pods -n ricxapp -o wide | grep rc
```

![image](https://hackmd.io/_uploads/B1DovprDxg.png)

**Adjust IP in the grpc command**

```bash!
cd ric-app-rc
sudo nano grpc.sh
```

**Make the RC_XAPP_IP as above:**

![image](https://hackmd.io/_uploads/SkERP6Hvle.png)

**Send the command:**

```bash!
./grpc.sh
```

![image](https://hackmd.io/_uploads/BkyZ_arDgx.png)

## Problem

ns3 ASN.1 encoding message does not capable with the OSC RIC E2Term decoding.

![image](https://hackmd.io/_uploads/B1HO_6BDgg.png)

This problem makes the simulation cannot be integrated with the Near RT RIC.