# 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.