diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..e354b07 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,58 @@ +#================================================================================== +# Copyright (c) 2022 Northeastern University +# +# 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 wineslab/o-ran-sc-bldr-ubuntu18-c-go:9-u18.04 as buildenv +ARG log_level_e2sim=2 +# log_level_e2sim = 0 -> LOG_LEVEL_UNCOND 0 +# log_level_e2sim = 1 -> LOG_LEVEL_ERROR 1 +# log_level_e2sim = 2 -> LOG_LEVEL_INFO 2 +# log_level_e2sim = 3 -> LOG_LEVEL_DEBUG 3 + +# Install E2sim +RUN mkdir -p /workspace/e2sim +RUN apt-get update && apt-get install -y build-essential git cmake libsctp-dev autoconf automake libtool bison flex libboost-all-dev + +WORKDIR /workspace/e2sim + +COPY ./e2sim/e2sim /workspace/e2sim + +RUN mkdir /workspace/e2sim/build +WORKDIR /workspace/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 qtbase5-dev qtchooser qt5-qmake qtbase5-dev-tools + +COPY ./ns3-mmwave-oran /workspace/ns3-mmwave-oran +COPY ./ns-o-ran /workspace/ns3-mmwave-oran/contrib/oran-interface + +WORKDIR /workspace/ns3-mmwave-oran + +RUN ./waf configure --enable-tests --enable-examples +# RUN ./waf build + +WORKDIR /workspace + +CMD [ "/bin/sh" ] + + diff --git a/build-ns-o-ran.sh b/build-ns-o-ran.sh new file mode 100755 index 0000000..6c7af1b --- /dev/null +++ b/build-ns-o-ran.sh @@ -0,0 +1,22 @@ +#!/bin/sh +# Script to import the base images to create the RIC containers from Wineslab Docker Hub + + +# This shall execute first wineslab images and ns-o-ran after +# import-wines-images.sh +# setup-ric-bronze.sh + +# Build image for ns-o-ran + +$SUDO docker build -t ns-o-ran -f Dockerfile . + +remove_container() { + $SUDO docker inspect $1 >/dev/null 2>&1 + if [ $? -eq 0 ]; then + $SUDO docker kill $1 + $SUDO docker rm $1 + fi +} + +remove_container ns-o-ran +$SUDO docker run -d -it --network=ric --name ns-o-ran ns-o-ran \ No newline at end of file diff --git a/setup-scripts/import-wines-images.sh b/setup-scripts/import-wines-images.sh new file mode 100755 index 0000000..231c763 --- /dev/null +++ b/setup-scripts/import-wines-images.sh @@ -0,0 +1,18 @@ +#!/bin/sh +# Script to import the base images to create the RIC containers from Wineslab Docker Hub + +# Pull Wines base images +docker pull wineslab/o-ran-sc-bldr-ubuntu18-c-go:9-u18.04 +docker pull wineslab/o-ran-sc-bldr-alpine3-go:6-a3.11-rmr3 + +# Pull Wines RIC images +docker pull wineslab/colo-ran-e2term:bronze +docker pull wineslab/colo-ran-e2mgr:bronze +docker pull wineslab/colo-ran-e2rtmansim:bronze +docker pull wineslab/colo-ran-dbaas:bronze + +# Tag images to be used with the setup-ric script +docker tag wineslab/colo-ran-e2term:bronze e2term:bronze +docker tag wineslab/colo-ran-e2mgr:bronze e2mgr:bronze +docker tag wineslab/colo-ran-e2rtmansim:bronze e2rtmansim:bronze +docker tag wineslab/colo-ran-dbaas:bronze dbaas:bronze diff --git a/setup-scripts/setup-ric-bronze.sh b/setup-scripts/setup-ric-bronze.sh new file mode 100755 index 0000000..0da2572 --- /dev/null +++ b/setup-scripts/setup-ric-bronze.sh @@ -0,0 +1,194 @@ +#!/bin/sh +# Script to setup the RIC containers. Call as ./setup-ric.sh [network interface] + +set -x + +# get flags +for ARGUMENT in "$@" +do + KEY=$(echo $ARGUMENT | cut -f1 -d=) + case "$KEY" in + arena) arena=true;; + import) import=true;; + *) + esac +done + +# get RIC interface from cli arguments +if [ $# -eq 0 ] || [ "$import" = false ] ; then + RIC_INTERFACE="col0" +else + if [ "$arena" = true ]; then + RIC_INTERFACE="brric" + else + RIC_INTERFACE=$1 + fi +fi + +export SRC=`dirname $0` +. $SRC/setup-lib.sh + +OURDIR=../setup + +# import base RIC images +if [ "$import" = true ] || [ $(docker image ls -q | wc -l) -eq "0" ]; then + echo "Importing base Docker images" + cd $SRC + ./import-wines-images.sh +fi + +cd $OURDIR +tagvers=`git log --pretty=format:"%h" -n 1` + +# build e2term +$SUDO docker image inspect e2term:bronze >/dev/null 2>&1 +if [ ! $? -eq 0 ]; then + cd e2/RIC-E2-TERMINATION + $SUDO docker image inspect e2term:$tagvers >/dev/null 2>&1 + if [ ! $? -eq 0 ]; then + $SUDO docker build -f Dockerfile -t e2term:$tagvers . + fi + $SUDO docker tag e2term:$tagvers e2term:bronze + $SUDO docker rmi e2term:$tagvers + cd ../.. +fi + +# build e2mgr +$SUDO docker image inspect e2mgr:bronze >/dev/null 2>&1 +if [ ! $? -eq 0 ]; then + cd e2mgr/E2Manager + $SUDO docker image inspect e2mgr:$tagvers >/dev/null 2>&1 + if [ ! $? -eq 0 ]; then + $SUDO docker build -f Dockerfile -t e2mgr:$tagvers . + fi + $SUDO docker tag e2mgr:$tagvers e2mgr:bronze + $SUDO docker rmi e2mgr:$tagvers + cd ../.. +fi + +# build e2rtmansim +$SUDO docker image inspect e2rtmansim:bronze >/dev/null 2>&1 +if [ ! $? -eq 0 ]; then + cd e2mgr/tools/RoutingManagerSimulator + $SUDO docker image inspect e2rtmansim:$tagvers >/dev/null 2>&1 + if [ ! $? -eq 0 ]; then + $SUDO docker build -f Dockerfile -t e2rtmansim:$tagvers . + fi + $SUDO docker tag e2rtmansim:$tagvers e2rtmansim:bronze + $SUDO docker rmi e2rtmansim:$tagvers + cd ../../.. +fi + +# build dbaas +$SUDO docker image inspect dbaas:bronze >/dev/null 2>&1 +if [ ! $? -eq 0 ]; then + cd dbaas + $SUDO docker build -f docker/Dockerfile.redis -t dbaas:bronze . + cd .. +fi + +# remove dangling images +docker rmi $(docker images --filter "dangling=true" -q --no-trunc) 2> /dev/null + +# create a private network for near-real-time RIC +$SUDO docker network inspect ric >/dev/null 2>&1 +if [ ! $? -eq 0 ]; then + $SUDO brctl addbr brric + $SUDO docker network create --subnet=$RIC_SUBNET -d bridge --attachable -o com.docker.network.bridge.name=brric ric +fi + +# Create a route info file to tell the containers where to send various +# messages. This will be mounted on the containers +ROUTERFILE=`pwd`/router.txt +cat << EOF > $ROUTERFILE +newrt|start +rte|10020|$E2MGR_IP:3801 +rte|10060|$E2TERM_IP:38000 +rte|10061|$E2MGR_IP:3801 +rte|10062|$E2MGR_IP:3801 +rte|10070|$E2MGR_IP:3801 +rte|10071|$E2MGR_IP:3801 +rte|10080|$E2MGR_IP:3801 +rte|10081|$E2TERM_IP:38000 +rte|10082|$E2TERM_IP:38000 +rte|10360|$E2TERM_IP:38000 +rte|10361|$E2MGR_IP:3801 +rte|10362|$E2MGR_IP:3801 +rte|10370|$E2MGR_IP:3801 +rte|10371|$E2TERM_IP:38000 +rte|10372|$E2TERM_IP:38000 +rte|1080|$E2MGR_IP:3801 +rte|1090|$E2TERM_IP:38000 +rte|1100|$E2MGR_IP:3801 +rte|12010|$E2MGR_IP:38010 +rte|1101|$E2TERM_IP:38000 +rte|12002|$E2TERM_IP:38000 +rte|12003|$E2TERM_IP:38000 +rte|10091|$E2MGR_IP:4801 +rte|10092|$E2MGR_IP:4801 +rte|1101|$E2TERM_IP:38000 +rte|1102|$E2MGR_IP:3801 +rte|12001|$E2MGR_IP:3801 +mse|12050|$(echo $XAPP_IP | cut -d "." -f 4)|$XAPP_IP:4560 +newrt|end +EOF + +remove_container() { + $SUDO docker inspect $1 >/dev/null 2>&1 + if [ $? -eq 0 ]; then + $SUDO docker kill $1 + $SUDO docker rm $1 + fi +} + +# create RIC various containers. Kill and remove them if they exist. +remove_container db +$SUDO docker run -d --network ric --ip $DBAAS_IP --name db dbaas:bronze + +remove_container e2rtmansim +$SUDO docker run -d -it --network ric --ip $E2RTMANSIM_IP --name e2rtmansim e2rtmansim:bronze + +remove_container e2mgr +$SUDO docker run -d -it --network ric --ip $E2MGR_IP -e RIC_ID=7b0000-000000/18 \ + -e DBAAS_PORT_6379_TCP_ADDR=$DBAAS_IP -e DBAAS_PORT_6379_TCP_PORT="6379" \ + -e DBAAS_SERVICE_HOST=$DBAAS_IP -e DBAAS_SERCE_PORT="6379" \ + --mount type=bind,source=$ROUTERFILE,destination=/opt/E2Manager/router.txt,ro \ + --name e2mgr e2mgr:bronze + +remove_container e2term +E2TERMCONFFILE=`pwd`/e2term_config.conf +if [ ! -e $E2TERMCONFFILE ]; then +cat <$E2TERMCONFFILE +nano=38000 +loglevel=debug +volume=log +#the key name of the environment holds the local ip address +#ip address of the E2T in the RMR +local-ip=$E2TERM_IP +#trace is start, stop +trace=start +external-fqdn=e2t.com +#put pointer to the key that point to pod name +pod_name=E2TERM_POD_NAME +sctp-port=$E2TERM_SCTP_PORT +EOF +fi + E2TERM_CONFIG_BIND="--mount type=bind,source=$E2TERMCONFFILE,destination=/opt/e2/config/config.conf,ro" + +export RIC_IP=`ifconfig ${RIC_INTERFACE} | grep -Eo 'inet (addr:)?([0-9]*\.){3}[0-9]*' | grep -Eo '([0-9]*\.){3}[0-9]*'` + + +if [ "$arena" = true ]; then + echo 'Starting local setup' + # if both RIC and DU are executed on the same machine, do not set Docker NAT rules + $SUDO docker run -d -it --network=ric --ip $E2TERM_IP --name e2term \ + --mount type=bind,source=$ROUTERFILE,destination=/opt/e2/dockerRouter.txt,ro \ + $E2TERM_CONFIG_BIND \ + e2term:bronze +else + $SUDO docker run -d -it --network=ric --ip $E2TERM_IP --name e2term -p ${RIC_IP}:${E2TERM_SCTP_PORT}:${E2TERM_SCTP_PORT}/sctp\ + --mount type=bind,source=$ROUTERFILE,destination=/opt/e2/dockerRouter.txt,ro \ + $E2TERM_CONFIG_BIND e2term:bronze +fi + +exit 0 diff --git a/setup-scripts/start-xapp-ns-o-ran.sh b/setup-scripts/start-xapp-ns-o-ran.sh new file mode 100755 index 0000000..f56be2a --- /dev/null +++ b/setup-scripts/start-xapp-ns-o-ran.sh @@ -0,0 +1,2 @@ +#!/bin/bash +./setup-sample-xapp.sh ns-o-ran \ No newline at end of file diff --git a/setup-scripts/start-xapp.sh b/setup-scripts/start-xapp.sh index cce22aa..df632f8 100755 --- a/setup-scripts/start-xapp.sh +++ b/setup-scripts/start-xapp.sh @@ -1,2 +1,2 @@ #!/bin/bash -./setup-sample-xapp.sh gnb:311-048-01000501 +./setup-sample-xapp.sh gnb:131-133-31000000 \ No newline at end of file diff --git a/setup/xapp-sm-connector/src/xapp.cc b/setup/xapp-sm-connector/src/xapp.cc index bbbbed2..77eb8bb 100644 --- a/setup/xapp-sm-connector/src/xapp.cc +++ b/setup/xapp-sm-connector/src/xapp.cc @@ -93,8 +93,27 @@ void Xapp::startup(SubscriptionHandler &sub_ref) { // get list of gnbs from ric std::cout << "Getting gNB list from RIC" << std::endl; set_rnib_gnblist(); - } - else { + } else if (strcmp(GNB_ID, "file") == 0) { + // Get gNB list from file + std::cout << "Getting gNB list from file" << std::endl; + std::ifstream id_file("gnb_list.txt", ios_base::in); + if(!id_file) { + std::cerr << "Error in opening file, gonna crash!" << std::endl; + exit(-1); + } + std::string id_gnb; + while(getline(id_file,id_gnb)){ + std::cout << "gNB read: " << id_gnb << std::endl; + rnib_gnblist.push_back(id_gnb); + } + } else if (strcmp(GNB_ID, "ns-o-ran") == 0) { + std::vector gnb_ids{"gnb:131-133-31000000", "gnb:131-133-32000000", "gnb:131-133-33000000", + "gnb:131-133-34000000", "gnb:131-133-35000000"}; + for (vector::iterator it = gnb_ids.begin(); it != gnb_ids.end(); it++) { + std::cout << "gNB read: " << *it << std::endl; + rnib_gnblist.push_back(*it); + } + } else { // only insert target gnb std::cout << "Querying target gNB" << std::endl; rnib_gnblist.push_back(GNB_ID); @@ -270,7 +289,7 @@ void Xapp::handle_external_control_message(int port) { while (true) { auto addrlen = sizeof(sockaddr); int connection = accept(sockfd, (struct sockaddr*)&sockaddr, (socklen_t*)&addrlen); - + if (connection < 0) { continue; } @@ -279,7 +298,7 @@ void Xapp::handle_external_control_message(int port) { const size_t max_size = 256; char buffer[max_size] = {0}; auto bytes_read = read(connection, buffer, 100); - + if (bytes_read > 0) { std::cout << "External control socket. Message received: " << buffer << std::endl; @@ -326,7 +345,7 @@ void Xapp::terminate_du_reporting(void) { } void Xapp::send_ric_control_request(char* payload, std::string gnb_id) { - + std::cout << "Sending RIC Control Request" << std::endl; bool res; @@ -436,7 +455,7 @@ void Xapp::startup_subscribe_requests(void ){ //Random Data for request int request_id = XAPP_REQ_ID; - int function_id = 0; + int function_id = 200; // DU report timer in ms std::string event_def = "250"; @@ -533,7 +552,7 @@ void Xapp::set_rnib_gnblist(void) { std::string name = gnbobj["inventory_name"].GetString(); rnib_gnblist.push_back(name); } - + closeSdl(); return; } diff --git a/setup/xapp-sm-connector/src/xapp.hpp b/setup/xapp-sm-connector/src/xapp.hpp index 9241990..22323f4 100644 --- a/setup/xapp-sm-connector/src/xapp.hpp +++ b/setup/xapp-sm-connector/src/xapp.hpp @@ -28,6 +28,7 @@ #define SRC_XAPP_HPP_ #include +#include #include #include #include