A RAN Intelligent Controller (RIC) is a crucial software-defined component within the Open Radio Access Network (Open RAN) architecture, designed to manage and enhance RAN functions. It promotes multivendor interoperability, intelligence, agility, and programmability, enabling the integration of third-party applications to automate and optimize RAN operations at scale. This results in reduced total cost of ownership (TCO) for mobile operators and improved quality of experience (QoE) for users, making the RIC a key element in the Open RAN strategy to create flexible, efficient, and cost-effective networks.
The near-RT RIC is a logical function that optimizes and controls O-CU and O-DU nodes in near-real-time (10 ms to 1 s), guided by policies and models from the non-RT RIC. It manages RAN infrastructure at the cloud edge, hosting cloud-native, microservice-based applications called xApps.
The E2 interface facilitates the RAN closed-loop control by enabling the RIC to enforce control and policy decisions towards the RAN. It also supports data collection and feedback mechanisms, providing critical information to the near-RT RIC for real-time optimization and management of the network.
E2SIM is a simulation tool used of Open Radio Access Networks (Open RAN) to emulate the E2 interface, which is essential for interactions between the RAN Intelligent Controller (RIC) and the underlying radio access network components, such as O-CU and O-DU nodes. E2sim allows developers and researchers to test, validate, and optimize the behavior of RAN functions and RIC applications (xApps) in a controlled and virtual environment.
The steps below assume a clean installation of Ubuntu 20.04 (no k8s, no docker, no helm)
You can Install Kubernetes cluster is installed, the next step is to install the (Near Realtime) RIC Platform.
To access Root:
sudo -i
Clone the repository :
git clone "https://gerrit.o-ran-sc.org/r/ric-plt/ric-dep" -b i-release
Change mirror repository
cd ric-dep/bin
nano install_k8s_and_helm.sh
### Insert this code
curl https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | apt-key add -
cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main
EOF
cd ric-dep/bin
./install_k8s_and_helm.sh
output:
root@ubuntu:~/ric-dep/bin# ./install_k8s_and_helm.sh
+ KUBEV=1.28.11
+ KUBECNIV=0.7.5
+ HELMV=3.14.4
+ DOCKERV=20.10.21
+ echo running ./install_k8s_and_helm.sh
running ./install_k8s_and_helm.sh
+ getopts :k:d:e:n:c o
+ [[ 3.14.4 == 2.* ]]
+ set -x
+ export DEBIAN_FRONTEND=noninteractive
+ DEBIAN_FRONTEND=noninteractive
++ hostname -I
++ hostname
.
.
.
++ hostname
+ '[' '' == ubuntu ']'
+ echo 'Done with master node setup'
Done with master node setup
+ [[ ! -z '' ]]
+ [[ ! -z '' ]]
+ [[ ! -z '' ]]
+ [[ 1 -gt 100 ]]
+ [[ 1 -gt 100 ]]
./install_common_templates_to_helm.sh
output:
Installing servecm (Chart Manager) and common templates to helm3
Installed plugin: servecm
/root/.cache/helm/repository
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 15.0M 100 15.0M 0 0 11.4M 0 0:00:01 0:00:01 --:--:-- 11.4M
.
.
.
"local" has been added to your repositories
checking that ric-common templates were added
NAME CHART VERSION APP VERSION DESCRIPTION
local/ric-common 3.3.2 Common templates for inclusion in other charts
nano ./RECIPE_EXAMPLE/example_recipe_oran_i_release.yaml
You can specify which docker registry will be used for each component. If the docker registry requires login credential, you can add the credential in the following section. Extsvcplt can fill your server IP.
In this section we use [I release] because latest release have error in installations.
cd ric-dep/bin
./install -f ../RECIPE_EXAMPLE/example_recipe_oran_i_release.yaml
configmap "ricplt-recipe" deleted
configmap/ricplt-recipe created
Add cluster roles
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "local" chart repository
Update Complete. ⎈Happy Helming!⎈
.
.
.
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "local" chart repository
Update Complete. ⎈Happy Helming!⎈
Saving 1 charts
Downloading ric-common from repo http://127.0.0.1:8879/charts
Deleting outdated charts
NAME: r4-jaegeradapter
LAST DEPLOYED: Mon Jul 8 04:11:17 2024
NAMESPACE: ricplt
STATUS: deployed
REVISION: 1
TEST SUITE: None
kubectl get pods -n ricplt
output:
root@ubuntu:~# kubectl get pods -n ricplt
NAME READY STATUS RESTARTS AGE
deployment-ricplt-a1mediator-7d5b85ff7d-5xkmw 1/1 Running 0 13h
deployment-ricplt-alarmmanager-6bd5fccfc8-7hx8m 1/1 Running 0 13h
deployment-ricplt-appmgr-77986c9cbb-n9hh4 1/1 Running 0 13h
deployment-ricplt-e2mgr-78c987559f-xx6l6 1/1 Running 0 13h
deployment-ricplt-e2term-alpha-5dc768bcb7-k9dr4 1/1 Running 0 13h
deployment-ricplt-jaegeradapter-76ddbf9c9-8hkz7 1/1 Running 0 13h
deployment-ricplt-o1mediator-97fb6759b-zcgsw 1/1 Running 0 13h
deployment-ricplt-rtmgr-78f768474-vgkkh 1/1 Running 3 13h
deployment-ricplt-submgr-56bb776b68-88fzw 1/1 Running 0 13h
deployment-ricplt-vespamgr-84f7d87dfb-jdvtr 1/1 Running 0 13h
r4-influxdb-influxdb2-0 1/1 Running 0 13h
r4-infrastructure-kong-7995f4679b-7x2lk 2/2 Running 2 13h
r4-infrastructure-prometheus-alertmanager-5798b78f48-xfcfr 2/2 Running 0 13h
r4-infrastructure-prometheus-server-c8ddcfdf5-szkc6 1/1 Running 0 13h
statefulset-ricplt-dbaas-server-0 1/1 Running 0 13h
nano pv-ricplt.yaml
fill this file with :
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-ricplt-influxdb
labels:
type: local
spec:
storageClassName: "manual"
capacity:
storage: 50Gi
accessModes:
- ReadWriteOnce
hostPath:
path: "/mnt/data"
then create file pvc
nano pvc-ricplt.yaml
fill this file with :
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: r4-influxdb-influxdb2
namespace: ricplt
spec:
storageClassName: "manual" # Empty string must be explicitly set otherwise default StorageClass will be set
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 30Gi
after that build pv and pvc :
kubectl apply -f pv-ricplt.yaml
kubectl apply -f pvc-ricplt.yaml
After this you can see your influxdb running.
kubectl exec -it r4-influxdb-influxdb2-0 -n ricplt -- /bin/sh
root@ubuntu:~# kubectl exec -it r4-influxdb-influxdb2-0 -n ricplt -- /bin/sh
/ # env | grep INFLUXDB
R4_INFLUXDB_INFLUXDB2_PORT_80_TCP_ADDR=10.103.101.32
R4_INFLUXDB_INFLUXDB2_PORT_80_TCP_PORT=80
R4_INFLUXDB_INFLUXDB2_PORT_80_TCP_PROTO=tcp
DOCKER_INFLUXDB_INIT_BUCKET=default
DOCKER_INFLUXDB_INIT_MODE=setup
DOCKER_INFLUXDB_INIT_ADMIN_TOKEN=NFmbiS66DaV9fIoTYTJFqxfveUO4RJzU
R4_INFLUXDB_INFLUXDB2_PORT_80_TCP=tcp://10.103.101.32:80
DOCKER_INFLUXDB_INIT_USERNAME=admin
R4_INFLUXDB_INFLUXDB2_SERVICE_PORT_HTTP=80
DOCKER_INFLUXDB_INIT_RETENTION=0s
R4_INFLUXDB_INFLUXDB2_SERVICE_HOST=10.103.101.32
DOCKER_INFLUXDB_INIT_ORG=influxdata
DOCKER_INFLUXDB_INIT_CLI_CONFIG_NAME=default
DOCKER_INFLUXDB_INIT_PASSWORD=64VrxG940K0Npg1bEFUAVSuaZCMnQWO6
R4_INFLUXDB_INFLUXDB2_SERVICE_PORT=80
R4_INFLUXDB_INFLUXDB2_PORT=tcp://10.103.101.32:80
INFLUXDB_VERSION=2.2.0
influx config create --active \
-n config-name \
-u http://localhost:8086 \
-t <token admin> \
-o influxdata
kubectl get pods -n ricinfra
root@ubuntu:~/ric-dep/bin# kubectl get pods -n ricinfra
NAME READY STATUS RESTARTS AGE
deployment-tiller-ricxapp-676dfd8664-lscnb 1/1 Running 0 43m
tiller-secret-generator-mlml7 0/1 Completed 0 43m
E2 Simulator enables a specific E2SM to be supported by the calling application in the following way:
Registration of an E2SM with the E2 Simulator entails the following:
git clone -b https://github.com/o-ran-sc/sim-e2-interface.git
output:
root@ubuntu:~# git clone -b https://gerrit.o-ran-sc.org/r/sim/e2-interface.git
sc.org/r/sim/e2-interface"Cloning into 'e2-interface'...
remote: Total 4964 (delta 0), reused 4964 (delta 0)
Receiving objects: 100% (4964/4964), 4.49 MiB | 880.00 KiB/s, done.
Resolving deltas: 100% (3911/3911), done.
sudo apt-get install -y build-essential git cmake libsctp-dev lksctp-tools autoconf automake libtool bison flex libboost-all-dev
sudo apt-get clean
Output:
Reading package lists... Done
Building dependency tree
Reading state information... Done
libtool is already the newest version (2.4.6-14).
0 upgraded, 0 newly installed, 0 to remove and 72 not upgraded.
cd ~/e2-interface/e2sim/
mkdir build
cd build
cmake ..
make package
Output:
root@ubuntu:~/e2-interface/e2sim# mkdir build
root@ubuntu:~/e2-interface/e2sim# cd build
root@ubuntu:~/e2-interface/e2sim/build# cmake ..
-- The C compiler identification is GNU 9.4.0
-- The CXX compiler identification is GNU 9.4.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
.
.
.
root@ubuntu:~/e2-interface/e2sim/build# make package
Scanning dependencies of target encoding_objects
[ 0%] Building CXX object src/encoding/CMakeFiles/encoding_objects.dir/encode_e2apv1.cpp.o
/root/e2-interface/e2sim/src/encoding/encode_e2apv1.cpp: In function ‘long int encoding::get_function_id_from_subscription(E2AP_PDU_t*)’:
.
.
.
[100%] Built target asn1_objects
Run CPack packaging tool...
CPack: Create package using DEB
CPack: Install projects
CPack: - Run preinstall target for: e2sim
CPack: - Install project: e2sim []
CPack: Create package
-- CPACK_DEBIAN_PACKAGE_DEPENDS not set, the package will have no dependencies.
CPack: - package: /root/e2-interface/e2sim/build/e2sim_1.0.0_amd64.deb generated.
.
.
.
root@ubuntu:~/e2-interface/e2sim/build# cmake .. -DDEV_PKG=1
+++ pkg name: e2sim-dev_1.0.0_amd64.deb
### make package will generate only deb package; cannot find support to generate rpm packages
+++ profiling is off
-- Configuring done
-- Generating done
-- Build files have been written to: /root/e2-interface/e2sim/build
.
.
.
root@ubuntu:~/e2-interface/e2sim/build# make package
[ 0%] Built target encoding_objects
[ 0%] Built target def_objects
[ 1%] Built target sctp_objects
[ 1%] Built target messagerouting_objects
[ 1%] Built target base_objects
Scanning dependencies of target e2sim_static
[ 2%] Linking CXX static library libe2sim.a
[ 2%] Built target e2sim_static
[ 2%] Built target e2sim_shared
[100%] Built target asn1_objects
Run CPack packaging tool...
CPack: Create package using DEB
CPack: Install projects
CPack: - Run preinstall target for: e2sim
CPack: - Install project: e2sim []
CPack: Create package
-- CPACK_DEBIAN_PACKAGE_DEPENDS not set, the package will have no dependencies.
CPack: - package: /root/e2-interface/e2sim/build/e2sim-dev_1.0.0_amd64.deb generated.
cmake .. && make package
cp *.deb ../e2sm_examples/kpm_e2sm/
output:
root@ubuntu:~/e2-interface/e2sim/build# cmake .. && make package && cmake .. -DDEV_PKG=1 && make package
+++ pkg name: e2sim_1.0.0_amd64.deb
### make package will generate only deb package; cannot find support to generate rpm packages
+++ profiling is off
-- Configuring done
-- Generating done
-- Build files have been written to: /root/e2-interface/e2sim/build
[ 0%] Built target encoding_objects
[ 0%] Built target def_objects
.
.
.
root@ubuntu:~/e2-interface/e2sim/build# cp *.deb ../e2sm_examples/kpm_e2sm/
if you wish to change the e2t address to connect then modify the Dockerfile in e2sm_examples/kpm_e2sm/ path.
kubectl get service -n ricplt
output:
root@ubuntu:~# kubectl get service -n ricplt
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
aux-entry ClusterIP 10.104.205.40 <none> 80/TCP,443/TCP 119m
r4-infrastructure-kong-manager NodePort 10.97.41.103 <none> 8002:31384/TCP,8445:31954/TCP 119m
r4-infrastructure-kong-proxy LoadBalancer 10.104.247.169 <pending> 80:32080/TCP,443:32443/TCP 119m
r4-infrastructure-kong-validation-webhook ClusterIP 10.108.111.106 <none> 443/TCP 119m
r4-infrastructure-prometheus-alertmanager ClusterIP 10.101.42.179 <none> 80/TCP 119m
r4-infrastructure-prometheus-server ClusterIP 10.96.156.175 <none> 80/TCP 119m
service-ricplt-a1mediator-http ClusterIP 10.111.141.65 <none> 10000/TCP 118m
service-ricplt-a1mediator-rmr ClusterIP 10.103.222.251 <none> 4561/TCP,4562/TCP 118m
service-ricplt-alarmmanager-http ClusterIP 10.107.254.187 <none> 8080/TCP 117m
service-ricplt-alarmmanager-rmr ClusterIP 10.103.145.41 <none> 4560/TCP,4561/TCP 117m
service-ricplt-appmgr-http ClusterIP 10.107.105.148 <none> 8080/TCP 119m
service-ricplt-appmgr-rmr ClusterIP 10.109.187.173 <none> 4561/TCP,4560/TCP 119m
service-ricplt-dbaas-tcp ClusterIP None <none> 6379/TCP 119m
service-ricplt-e2mgr-http ClusterIP 10.99.1.23 <none> 3800/TCP 118m
service-ricplt-e2mgr-rmr ClusterIP 10.107.185.182 <none> 4561/TCP,3801/TCP 118m
service-ricplt-e2term-prometheus-alpha ClusterIP 10.106.81.203 <none> 8088/TCP 118m
service-ricplt-e2term-rmr-alpha ClusterIP 10.110.221.177 <none> 4561/TCP,38000/TCP 118m
service-ricplt-e2term-sctp-alpha NodePort 10.110.72.147 <none> 36422:32222/SCTP 118m
service-ricplt-o1mediator-http ClusterIP 10.96.147.72 <none> 9001/TCP,8080/TCP,3000/TCP 117m
service-ricplt-o1mediator-tcp-netconf NodePort 10.107.202.218 <none> 830:30830/TCP 117m
service-ricplt-rtmgr-http ClusterIP 10.96.141.107 <none> 3800/TCP 119m
service-ricplt-rtmgr-rmr ClusterIP 10.100.163.198 <none> 4561/TCP,4560/TCP 119m
service-ricplt-submgr-http ClusterIP None <none> 3800/TCP 118m
service-ricplt-submgr-rmr ClusterIP None <none> 4560/TCP,4561/TCP 118m
service-ricplt-vespamgr-http ClusterIP 10.97.31.72 <none> 8080/TCP,9095/TCP 117m
nano Dockerfile
cd ../e2sm_examples/kpm_e2sm/
docker build -t e2simul:0.0.2 .
output:
root@ubuntu:~/e2-interface/e2sim/e2sm_examples/kpm_e2sm# root@ubuntu:~/e2-interface/e2sim/e2sm_examples/kpm_e2sm#
root@ubuntu:~/e2-interface/e2sim/e2sm_examples/kpm_e2sm# docker build -t e2simul:0.0.2 .
Sending build context to Docker daemon 1.172MB
Step 1/17 : ARG CONTAINER_PULL_REGISTRY=nexus3.o-ran-sc.org:10002
Step 2/17 : FROM ${CONTAINER_PULL_REGISTRY}/o-ran-sc/bldr-ubuntu18-c-go:1.9.0 as buildenv
1.9.0: Pulling from o-ran-sc/bldr-ubuntu18-c-go
f22ccc0b8772: Pull complete
3cf8fb62ba5f: Pull complete
e80c964ece6a: Pull complete
d4194511dbdc: Pull complete
2d489c440bae: Pull complete 33ee3c77506b: Pull complete
7cdf3f1d17d0: Pull complete
cf153de296b0: Pull complete
e1920709a3af: Pull complete
6cdcae3380c6: Pull complete
6dbdb1c3e5fd: Pull complete
1710cd1faa0e: Pull complete
d44308ed4b3e: Extracting [=======
docker run e2simul:0.0.2
output:
root@ubuntu:~/sim-e2-interface/e2sim/e2sm_examples/kpm_e2sm# docker run e2simul:0.0.2
[kpm_callbacks.cpp:65] [INFO] Starting KPM simulator
[encode_kpm.cpp:49] [INFO] short_name: ORAN-E2SM-KPM, func_desc: KPM Monitor, e2sm_odi: OID123
[encode_kpm.cpp:72] [INFO] Initialize event trigger style list structure
[encode_kpm.cpp:91] [INFO] Initialize report style structure
[e2sim.cpp:65] [INFO] About to register E2SM RAN function description with ID 2
[e2sim.cpp:43] [INFO] About to register callback for subscription for RAN function with ID 2
[e2sim.cpp:104] [INFO] Start E2 Agent (E2 Simulator)
[e2sim.cpp:125] [INFO] After reading input options
[e2sim_sctp.cpp:180] [INFO] [SCTP] Binding client socket to source port 36422
[e2sim_sctp.cpp:187] [INFO] [SCTP] Connecting to server at 10.109.135.184:36422 ...
[e2sim_sctp.cpp:194] [INFO] [SCTP] Connection established
[e2sim.cpp:133] [INFO] SCTP client has been started
[e2sim.cpp:143] [INFO] Constructing a list of RAN functions based on registered information
[e2sim.cpp:149] [INFO] Adding RAN function ID 2, description: h0ORAN-E2SM-KPM to the list
[e2sim.cpp:161] [INFO] Generate E2AP v1 setup request for all registered RAN functions
.
.
.
[kpm_callbacks.cpp:651] [INFO] Encode and sending E2AP subscription success response via SCTP
[e2ap_asn1c_codec.c:175] [DEBUG] [E2AP ASN] Encoded succesfully, encoded size = 33
[kpm_callbacks.cpp:654] [INFO] Now generating data for subscription request
[kpm_callbacks.cpp:167] [INFO] Current line: {"ueMeasReport":{"du-id":1002,"measTimeStampRf":"2020-11-05T15:39:58.858734","ueMeasReportList":[{"ue-id":"Pedestrian-11","nrCellIdentity":2,"targetTput":0.3,"servingCellRfReport":{"rsrp":74,"rsrq":65,"rssinr":113},"neighbourCellList":[{"nbCellIdentity":8,"nbCellRfReport":{"rsrp":67,"rsrq":65,"rssinr":112}},{"nbCellIdentity":7,"nbCellRfReport":{"rsrp":65,"rsrq":65,"rssinr":107}},{"nbCellIdentity":9,"nbCellRfReport":{"rsrp":64,"rsrq":65,"rssinr":106}},{"nbCellIdentity":1,"nbCellRfReport":{"rsrp":63,"rsrq":65,"rssinr":104}},{"nbCellIdentity":3,"nbCellRfReport":{"rsrp":62,"rsrq":65,"rssinr":101}},{"nbCellIdentity":10,"nbCellRfReport":{"rsrp":61,"rsrq":65,"rssinr":100}},{"nbCellIdentity":6,"nbCellRfReport":{"rsrp":59,"rsrq":65,"rssinr":95}}],"throughput":0.3,"prb_usage":23}]}}
[kpm_callbacks.cpp:182] [INFO] First key is ueMeasReport
[kpm_callbacks.cpp:189] [INFO] Start sending UE measurement reports with DU id 1002
[kpm_callbacks.cpp:205] [INFO] Preparing report data for UE 0 with id P:��
[kpm_callbacks.cpp:297] [INFO] This is neighbor str [{"CID" : "37343722511136087", "Cell-RF" : {"rsrp": 67, "rsrq": 65, "rssinr": 112}},{"CID" : "37343722511136077", "Cell-RF" : {"rsrp": 65, "rsrq": 65, "rssinr": 107}},{"CID" : "37343722511136097", "Cell-RF" : {"rsrp": 64, "rsrq": 65, "rssinr": 106}},{"CID" : "37343722511136017", "Cell-RF" : {"rsrp": 63, "rsrq": 65, "rssinr": 104}},{"CID" : "37343722511136037", "Cell-RF" : {"rsrp": 62, "rsrq": 65, "rssinr": 101}},{"CID" : "373437225111360107", "Cell-RF" : {"rsrp": 61, "rsrq": 65, "rssinr": 100}},{"CID" : "37343722511136067", "Cell-RF" : {"rsrp": 59, "rsrq": 65, "rssinr": 95}}]
you can build e2sim to ricplt with this command:
helm install e2sim ./helm -n ricplt
and e2sim will show in your pods ricplt