From: Vidhu Date: Wed, 7 Apr 2021 03:36:29 +0000 (+0530) Subject: Restructure O1 module to run as a thread in O-DU High binary [Issue-Id: ODUHIGH-297] X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=commitdiff_plain;h=refs%2Fchanges%2F62%2F5862%2F7;p=o-du%2Fl2.git Restructure O1 module to run as a thread in O-DU High binary [Issue-Id: ODUHIGH-297] Signed-off-by: Vidhu Change-Id: I269b9663313e9b0e8de688028dd1ef094443aeb0 --- diff --git a/Dockerfile b/Dockerfile index dbd558df4..cfeffb2f7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -25,9 +25,9 @@ RUN cd build/odu && make clean_odu odu MACHINE=BIT64 MODE=TDD #CMD /opt/o-du-l2/bin/odu/odu #cleanup netconf folder and install libraries -RUN cd build/o1 && rm -rf netconf && /bin/bash install_lib.sh -c - -RUN cd build/o1 && make o1 MACHINE=BIT64 +RUN cd build/scripts && /bin/bash install_lib.sh -c # Install the data models based on the ODU yang model -RUN /usr/local/bin/sysrepoctl -i build/o1/yang/o-ran-sc-odu-alarm-v1.yang +RUN /usr/local/bin/sysrepoctl -i build/yang/o-ran-sc-odu-alarm-v1.yang + +RUN cd build/odu && make clean_odu odu MACHINE=BIT64 MODE=FDD O1_ENABLE=YES diff --git a/build/common/cu_stub.mak b/build/common/cu_stub.mak index 1e9add2ee..cbee68a0b 100755 --- a/build/common/cu_stub.mak +++ b/build/common/cu_stub.mak @@ -40,7 +40,7 @@ I_OPTS+=-I$(ROOT_DIR)/src/codec_utils/F1AP I_OPTS+=-I$(ROOT_DIR)/src/codec_utils/RRC ifeq ($(O1_ENABLE),YES) -I_OPTS+=-I$(ROOT_DIR)/src/o1/o1_client +I_OPTS+=-I$(ROOT_DIR)/src/o1 endif #-------------------------------------------------------------# diff --git a/build/common/du_app.mak b/build/common/du_app.mak index f7175d1b1..b80422309 100644 --- a/build/common/du_app.mak +++ b/build/common/du_app.mak @@ -42,7 +42,7 @@ I_OPTS+=-I$(ROOT_DIR)/src/codec_utils/RRC I_OPTS+=-I$(ROOT_DIR)/src/codec_utils/E2AP ifeq ($(O1_ENABLE),YES) -I_OPTS+=-I$(ROOT_DIR)/src/o1/o1_client +I_OPTS+=-I$(ROOT_DIR)/src/o1 endif #-------------------------------------------------------------# diff --git a/build/common/o1.mak b/build/common/o1.mak index e3acf5462..5815798b2 100755 --- a/build/common/o1.mak +++ b/build/common/o1.mak @@ -20,12 +20,11 @@ include ../common/rsys_fancy.mak include ../common/env.mak COLOR=$(COLOR_RED) -ROOT_DIR=$(patsubst %/build/o1,%,$(BUILD_DIR)) - SRC_DIR=$(ROOT_DIR)/src/o1/ CPP_SRCS=$(wildcard $(SRC_DIR)/*.cpp) CPP_OBJS=$(patsubst $(SRC_DIR)/%.cpp,$(OBJ_DIR)/%.o,$(CPP_SRCS)) +PLTFRM_FLAGS= lib: $(LIB_DIR)/libo1.a include $(COM_BUILD_DIR)/compile.mak @@ -33,7 +32,6 @@ L_OPTS=-lsysrepo -lyang L_OPTS+= -lsysrepo-cpp -lyang-cpp L_OPTS+= -lm -lpthread I_OPTS=-I$(ROOT_DIR)/src/o1/ -I_OPTS+=-I$(ROOT_DIR)/src/o1/o1_client #-------------------------------------------------------------# #Linker macros diff --git a/build/common/o1_client.mak b/build/common/o1_client.mak deleted file mode 100644 index f3b553561..000000000 --- a/build/common/o1_client.mak +++ /dev/null @@ -1,53 +0,0 @@ -################################################################################ -# Copyright (c) [2017-2019] [Radisys] # -# # -# 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. # -################################################################################ - -# This is makefile for O1 client - -include ../common/rsys_fancy.mak -include ../common/env.mak -COLOR=$(COLOR_RED) - -SRC_DIR=$(ROOT_DIR)/src/o1/o1_client -C_SRCS=$(wildcard $(SRC_DIR)/*.c) -C_OBJS=$(patsubst $(SRC_DIR)/%.c,$(OBJ_DIR)/%.o,$(C_SRCS)) - -lib: $(LIB_DIR)/libo1client.a -include $(COM_BUILD_DIR)/compile.mak - -L_OPTS=-lsysrepo -lyang -L_OPTS+= -lsysrepo-cpp -lyang-cpp -L_OPTS+= -lm -lpthread -I_OPTS+=-I$(ROOT_DIR)/src/o1/o1_client -I_OPTS+=-I$(ROOT_DIR)/src/cm -I_OPTS+=-I$(ROOT_DIR)/src/mt - -#-------------------------------------------------------------# -#Linker macros -#-------------------------------------------------------------# -$(LIB_DIR)/libo1client.a:$(C_OBJS) $(C_WO_PED_OBJS) - @echo -e "Creating Archive $(COLOR) $@ $(REVERT_COLOR)" - $(Q)ar -cr $(LIB_DIR)/libo1client.a $(C_OBJS) $(C_WO_PED_OBJS) - -#-------------------------------------------------------------# -#Clean macros -#-------------------------------------------------------------# -clean: - @echo -e "$(COLOR_RED)Cleaning O1 Client$(REVERT_COLOR)" - $(Q)\rm -f $(LIB_DIR)/libo1client.a $(C_OBJS) $(C_WO_PED_OBJS) $(LOG_FILES) $(BAK_FILES) - -#********************************************************************** -# End of file -#********************************************************************** diff --git a/build/common/ric_stub.mak b/build/common/ric_stub.mak index f7c5175c6..43a8a3f60 100644 --- a/build/common/ric_stub.mak +++ b/build/common/ric_stub.mak @@ -39,7 +39,7 @@ I_OPTS+=-I$(ROOT_DIR)/src/codec_utils/common I_OPTS+=-I$(ROOT_DIR)/src/codec_utils/E2AP ifeq ($(O1_ENABLE),YES) -I_OPTS+=-I$(ROOT_DIR)/src/o1/o1_client +I_OPTS+=-I$(ROOT_DIR)/src/o1 endif #-------------------------------------------------------------# #Linker macros diff --git a/build/config/startup_config.xml b/build/config/startup_config.xml new file mode 100644 index 000000000..045c1c2b4 --- /dev/null +++ b/build/config/startup_config.xml @@ -0,0 +1,19 @@ + + + +odu +192.168.130.81 +38472 + + +ocu +192.168.130.82 +38472 + + +ric +192.168.130.80 +36422 + + + diff --git a/build/o1/makefile b/build/o1/makefile deleted file mode 100644 index ff985aff5..000000000 --- a/build/o1/makefile +++ /dev/null @@ -1,126 +0,0 @@ -################################################################################ -# Copyright (c) [2017-2019] [Radisys] # -# # -# 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. # -################################################################################ - -# Master makefile for O1 module - -# Identify the location our software which is used by rest -# of the build scripts - -include ../common/rsys_fancy.mak -include ../common/env.mak - -ROOT_DIR=$(patsubst %/build/o1,%,$(BUILD_DIR)) -RULE=$(COLOR_RED) -OPTS=$(COLOR_GREEN) -NORM=$(REVERT_COLOR) - -# For improved speed -CPUINFO=`cat /proc/cpuinfo | grep processor| wc -l` -ifeq ($(CPUINFO), 1) - NUM_PARALLEL=1 -else - NUM_PARALLEL=$(shell echo $(CPUINFO) - 1 |bc) -endif - -ifeq ($(FAST), 1) - NUM_PARALLEL=$(shell echo $(CPUINFO) + 2 |bc) -endif - -PARALLEL_COMP=-j $(NUM_PARALLEL) - -# Different options to O1 build -# # Other apsects of tool chain set here -# # These should be made available appropriately to the builds -ifeq ($(MACHINE),BIT64) -CC =gcc -m64 -CCPP =g++ -m64 -else -CC =gcc -m32 -CCPP =g++ -m32 -endif - -CC1= $(CC) -CCPP1= $(CCPP) - - -# The include options get merged with the options needed by -# # the called makefiles and hence we export these to make them -# # available to them. -BUILD=i686-linux - -# The called makefiles depend on these macros and these need to be exported -export PLTFRM -export PLTFRM_FLAGS -export BUILD -export I_OPTS - -# Add to the linker options the platform specific components -#L_OPTS+=-lnsl -lrt -lm -lpthread -lsctp -L_OPTS=-lsysrepo -lyang -L_OPTS+= -lsysrepo-cpp -lyang-cpp -L_OPTS+= -lm -lpthread - -# Export some of the flags expected from the command line. -# # These macros are made available for the makefiles called from this makefile -export MACHINE - -help: - @echo -e "******************************************************************" - @echo -e "BUILD COMMAND DESCRIPTION " - @echo -e "------------------------------------------------------------------" - @echo -e "$(RULE)o1 - Builds all components of O1$(NORM)" - @echo -e "$(RULE)clean_o1 - clean up O1$(NORM)" - @echo -e "$(RULE)clean_all - cleanup O1 and all directories$(NORM)" - @echo -e "$(OPTS) options: $(NORM)" - @echo -e "$(OPTS) MACHINE=BIT64/BIT32 - Default is BIT32$(NORM)" - @echo -e "******************************************************************" - -prepare_dirs: - $(Q)echo -e "Preparing directories for build..." - $(Q)mkdir -p $(BUILD_DIR)/obj/o1 - $(Q)mkdir -p $(LIB_ROOT)/o1 - $(Q)mkdir -p $(BIN_DIR)/o1 - $(Q)echo -e "Directories are successfully prepared" - -o1_mod: - $(Q)$(MAKE) -f $(COM_BUILD_DIR)/o1.mak OBJ_DIR=$(OBJ_ROOT)/o1 LIB_DIR=$(LIB_ROOT)/o1 LOG_DIR=$(LOG_ROOT)/o1 CC='$(CCPP1)' - -link_o1: o1_mod - $(Q)$(CCPP1) -g -o $(OBJ_ROOT)/o1/o1 -Wl,-R../lib/:. $(OBJ_ROOT)/o1/*.o\ - $(L_OPTS) -L$(LIB_ROOT)/o1 - -clean_o1: - $(Q)$(MAKE) -f $(COM_BUILD_DIR)/o1.mak clean OBJ_DIR=$(OBJ_ROOT)/o1 LIB_DIR=$(LIB_ROOT)/o1 LOG_DIR=$(LOG_ROOT)/o1 CC='$(CC1)' - $(Q)rm -rf $(OBJ_ROOT)/o1/* - $(Q)rm -rf $(LIB_ROOT)/o1/* - $(Q)rm -rf $(BIN_DIR)/o1/* - $(Q)echo -e "***** O1 CLEAN COMPLETE *****" - -clean_all: clean_o1 - $(Q)rm -rf $(OBJ_ROOT) - $(Q)rm -rf $(LIB_ROOT) - $(Q)rm -rf $(LOG_ROOT) - $(Q)rm -rf $(BIN_DIR) - -copy_build: link_o1 - $(Q)cp -f ./obj/o1/o1 ./bin/o1 - $(Q)echo -e "***** O1 BUILD COMPLETE *****" - -o1: prepare_dirs copy_build - -#********************************************************************** -# End of file -#********************************************************************** diff --git a/build/odu/makefile b/build/odu/makefile index c165fbcdd..d1084210c 100644 --- a/build/odu/makefile +++ b/build/odu/makefile @@ -138,6 +138,12 @@ ifeq ($(PHY), INTEL_L1) -lrte_gro -lrte_pmd_ark -lrte_pmd_i40e -lrte_pmd_sw_event endif +ifeq ($(O1_ENABLE),YES) + L_OPTS+=-lsysrepo -lyang + L_OPTS+=-lsysrepo-cpp -lyang-cpp + L_OPTS+=-lstdc++ +endif + # Export some of the flags expected from the command line. # # These macros are made available for the makefiles called from this makefile export BOARD @@ -205,7 +211,7 @@ du: $(Q)$(MAKE) -f $(COM_BUILD_DIR)/rl.mak OBJ_DIR=$(OBJ_ROOT)/odu LIB_DIR=$(LIB_ROOT)/odu LOG_DIR=$(LOG_ROOT)/odu CC='$(CC1)' $(Q)$(MAKE) -f $(COM_BUILD_DIR)/phy_stub.mak OBJ_DIR=$(OBJ_ROOT)/odu LIB_DIR=$(LIB_ROOT)/odu LOG_DIR=$(LOG_ROOT)/odu CC='$(CC1)' ifeq ($(O1_ENABLE),YES) - $(Q)$(MAKE) -f $(COM_BUILD_DIR)/o1_client.mak OBJ_DIR=$(OBJ_ROOT)/odu LIB_DIR=$(LIB_ROOT)/odu LOG_DIR=$(LOG_ROOT)/odu CC='$(CC1)' + $(Q)$(MAKE) -f $(COM_BUILD_DIR)/o1.mak OBJ_DIR=$(OBJ_ROOT)/odu LIB_DIR=$(LIB_ROOT)/odu LOG_DIR=$(LOG_ROOT)/odu CC='$(CCPP1)' endif link_du: du @@ -226,7 +232,7 @@ clean_odu: $(Q)$(MAKE) -f $(COM_BUILD_DIR)/rl.mak clean OBJ_DIR=$(OBJ_ROOT)/odu LIB_DIR=$(LIB_ROOT)/odu LOG_DIR=$(LOG_ROOT)/odu CC='$(CC1)' $(Q)$(MAKE) -f $(COM_BUILD_DIR)/phy_stub.mak clean OBJ_DIR=$(OBJ_ROOT)/odu LIB_DIR=$(LIB_ROOT)/odu LOG_DIR=$(LOG_ROOT)/odu CC='$(CC1)' ifeq ($(O1_ENABLE),YES) - $(Q)$(MAKE) -f $(COM_BUILD_DIR)/o1_client.mak clean OBJ_DIR=$(OBJ_ROOT)/odu LIB_DIR=$(LIB_ROOT)/odu LOG_DIR=$(LOG_ROOT)/odu CC='$(CC1)' + $(Q)$(MAKE) -f $(COM_BUILD_DIR)/o1.mak clean OBJ_DIR=$(OBJ_ROOT)/odu LIB_DIR=$(LIB_ROOT)/odu LOG_DIR=$(LOG_ROOT)/odu CC='$(CCPP1)' endif $(Q)rm -rf $(OBJ_ROOT)/odu/* $(Q)rm -rf $(LIB_ROOT)/odu/* @@ -250,7 +256,7 @@ cu: $(Q)$(MAKE) -f $(COM_BUILD_DIR)/cm.mak OBJ_DIR=$(OBJ_ROOT)/cu_stub LIB_DIR=$(LIB_ROOT)/cu_stub LOG_DIR=$(LOG_ROOT)/cu_stub CC='$(CC1)' $(Q)$(MAKE) -f $(COM_BUILD_DIR)/mt.mak OBJ_DIR=$(OBJ_ROOT)/cu_stub LIB_DIR=$(LIB_ROOT)/cu_stub LOG_DIR=$(LOG_ROOT)/cu_stub CC='$(CC1)' ifeq ($(O1_ENABLE),YES) - $(Q)$(MAKE) -f $(COM_BUILD_DIR)/o1_client.mak OBJ_DIR=$(OBJ_ROOT)/cu_stub LIB_DIR=$(LIB_ROOT)/cu_stub LOG_DIR=$(LOG_ROOT)/cu_stub CC='$(CC1)' + $(Q)$(MAKE) -f $(COM_BUILD_DIR)/o1.mak OBJ_DIR=$(OBJ_ROOT)/cu_stub LIB_DIR=$(LIB_ROOT)/cu_stub LOG_DIR=$(LOG_ROOT)/cu_stub CC='$(CCPP1)' endif clean_cu: @@ -261,7 +267,7 @@ clean_cu: $(Q)$(MAKE) -f $(COM_BUILD_DIR)/cm.mak clean OBJ_DIR=$(OBJ_ROOT)/cu_stub LIB_DIR=$(LIB_ROOT)/cu_stub LOG_DIR=$(LOG_ROOT)/cu_stub CC='$(CC1)' $(Q)$(MAKE) -f $(COM_BUILD_DIR)/mt.mak clean OBJ_DIR=$(OBJ_ROOT)/cu_stub LIB_DIR=$(LIB_ROOT)/cu_stub LOG_DIR=$(LOG_ROOT)/cu_stub CC='$(CC1)' ifeq ($(O1_ENABLE),YES) - $(Q)$(MAKE) -f $(COM_BUILD_DIR)/o1_client.mak clean OBJ_DIR=$(OBJ_ROOT)/cu_stub LIB_DIR=$(LIB_ROOT)/cu_stub LOG_DIR=$(LOG_ROOT)/cu_stub CC='$(CC1)' + $(Q)$(MAKE) -f $(COM_BUILD_DIR)/o1.mak clean OBJ_DIR=$(OBJ_ROOT)/cu_stub LIB_DIR=$(LIB_ROOT)/cu_stub LOG_DIR=$(LOG_ROOT)/cu_stub CC='$(CCPP1)' endif $(Q)rm -rf $(OBJ_ROOT)/cu_stub/* $(Q)rm -rf $(LIB_ROOT)/cu_stub/* @@ -284,7 +290,7 @@ ric: $(Q)$(MAKE) -f $(COM_BUILD_DIR)/cm.mak OBJ_DIR=$(OBJ_ROOT)/ric_stub LIB_DIR=$(LIB_ROOT)/ric_stub LOG_DIR=$(LOG_ROOT)/ric_stub CC='$(CC1)' $(Q)$(MAKE) -f $(COM_BUILD_DIR)/mt.mak OBJ_DIR=$(OBJ_ROOT)/ric_stub LIB_DIR=$(LIB_ROOT)/ric_stub LOG_DIR=$(LOG_ROOT)/ric_stub CC='$(CC1)' ifeq ($(O1_ENABLE),YES) - $(Q)$(MAKE) -f $(COM_BUILD_DIR)/o1_client.mak OBJ_DIR=$(OBJ_ROOT)/ric_stub LIB_DIR=$(LIB_ROOT)/ric_stub LOG_DIR=$(LOG_ROOT)/ric_stub CC='$(CC1)' + $(Q)$(MAKE) -f $(COM_BUILD_DIR)/o1.mak OBJ_DIR=$(OBJ_ROOT)/ric_stub LIB_DIR=$(LIB_ROOT)/ric_stub LOG_DIR=$(LOG_ROOT)/ric_stub CC='$(CCPP1)' endif clean_ric: @@ -295,7 +301,7 @@ clean_ric: $(Q)$(MAKE) -f $(COM_BUILD_DIR)/cm.mak clean OBJ_DIR=$(OBJ_ROOT)/ric_stub LIB_DIR=$(LIB_ROOT)/ric_stub LOG_DIR=$(LOG_ROOT)/ric_stub CC='$(CC1)' $(Q)$(MAKE) -f $(COM_BUILD_DIR)/mt.mak clean OBJ_DIR=$(OBJ_ROOT)/ric_stub LIB_DIR=$(LIB_ROOT)/ric_stub LOG_DIR=$(LOG_ROOT)/ric_stub CC='$(CC1)' ifeq ($(O1_ENABLE),YES) - $(Q)$(MAKE) -f $(COM_BUILD_DIR)/o1_client.mak clean OBJ_DIR=$(OBJ_ROOT)/ric_stub LIB_DIR=$(LIB_ROOT)/ric_stub LOG_DIR=$(LOG_ROOT)/ric_stub CC='$(CC1)' + $(Q)$(MAKE) -f $(COM_BUILD_DIR)/o1.mak clean OBJ_DIR=$(OBJ_ROOT)/ric_stub LIB_DIR=$(LIB_ROOT)/ric_stub LOG_DIR=$(LOG_ROOT)/ric_stub CC='$(CCPP1)' endif $(Q)rm -rf $(OBJ_ROOT)/ric_stub/* $(Q)rm -rf $(LIB_ROOT)/ric_stub/* diff --git a/build/o1/install_lib.sh b/build/scripts/install_lib.sh similarity index 88% rename from build/o1/install_lib.sh rename to build/scripts/install_lib.sh index da44611fe..2aec9746f 100755 --- a/build/o1/install_lib.sh +++ b/build/scripts/install_lib.sh @@ -22,10 +22,10 @@ #variable declaration CURRENT_PATH=`pwd` HOME="$CURRENT_PATH/../.." -MAKE_PATH="$HOME/build/o1" -NETCONF_PATH="$HOME/build/o1/netconf" -SYSREPOCTL_PATH="$NETCONF_PATH/sysrepo/build/sysrepoctl" -YANG_PATH="$HOME/build/o1/yang" +NETCONF_PATH="$HOME/build/netconf" +YANG_PATH="$HOME/build/yang" +CONFIG_PATH="$HOME/build/config" +STARTUP_CONFIG="startup_config.xml" INSTALL="netconf" CLEANUP="no" @@ -51,11 +51,6 @@ log() { echo -e "$1 " } - - -#functions definitions -#TBD: install only mandatory packages - #install pre-requisite packages prerequisite_netconf() { @@ -93,17 +88,6 @@ check_ret() { #install netconf libraries install_netconf_lib() { - #with sudo we can not create new user so we need to create it manually using - #root credentials. - - #$SUDO adduser --system netconf && \ - # echo "netconf:netconf" | chpasswd - - #$SUDO mkdir -p /home/netconf/.ssh && \ - # ssh-keygen -A && \ - # ssh-keygen -t dsa -P '' -f /home/netconf/.ssh/id_dsa && \ - # cat /home/netconf/.ssh/id_dsa.pub > /home/netconf/.ssh/authorized_keys - if [[ "$CLEANUP" == "cleanup" ]]; then rm -rf $NETCONF_PATH log_warning "DELETED $NETCONF_PATH" @@ -173,7 +157,9 @@ install_netconf_lib() { #install yang module install_yang_module() { - $SYSREPOCTL_PATH -i "$YANG_PATH/o-ran-sc-du-alarm-v1.yang" + sysrepoctl -i "$YANG_PATH/o-ran-sc-odu-alarm-v1.yang" + sysrepoctl -i "$YANG_PATH/o-ran-sc-odu-interface-v1.yang" + sysrepocfg --import="$CONFIG_PATH/$STARTUP_CONFIG" --datastore startup --module o-ran-sc-odu-interface-v1 } @@ -216,7 +202,7 @@ main() { } #start execution / function calls -if [[ "$#" -ge 2 ]] ; then +if [[ "$#" -ge 3 ]] ; then log_error " NUMBER OF PARAMETER : $# " show_help fi diff --git a/build/scripts/netopeer-server.sh b/build/scripts/netopeer-server.sh new file mode 100755 index 000000000..f4b1f80df --- /dev/null +++ b/build/scripts/netopeer-server.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +if [ "$1" == "" ] +then + echo Usage : netopeer.sh [start] [stop] +fi + +if [ "$1" == "start" ] +then + netopeer2-server -d -v2 > /var/log/netopeer2-server.log 2>&1 & +fi + +if [ "$1" == "stop" ] +then + kill -9 `pidof netopeer2-server` +fi diff --git a/build/o1/yang/o-ran-sc-odu-alarm-v1.yang b/build/yang/o-ran-sc-odu-alarm-v1.yang similarity index 100% rename from build/o1/yang/o-ran-sc-odu-alarm-v1.yang rename to build/yang/o-ran-sc-odu-alarm-v1.yang diff --git a/build/o1/yang/o-ran-sc-odu-interface-v1.yang b/build/yang/o-ran-sc-odu-interface-v1.yang similarity index 100% rename from build/o1/yang/o-ran-sc-odu-interface-v1.yang rename to build/yang/o-ran-sc-odu-interface-v1.yang diff --git a/docs/ODU-O1-Arch.jpg b/docs/ODU-O1-Arch.jpg index 06c19846d..7c5c75776 100644 Binary files a/docs/ODU-O1-Arch.jpg and b/docs/ODU-O1-Arch.jpg differ diff --git a/docs/ODU-O1-GetAlarmListFlow.jpg b/docs/ODU-O1-GetAlarmListFlow.jpg index cd205078f..2998993d5 100644 Binary files a/docs/ODU-O1-GetAlarmListFlow.jpg and b/docs/ODU-O1-GetAlarmListFlow.jpg differ diff --git a/docs/ODUArch.jpg b/docs/ODUArch.jpg index 1b9b7723e..39a06a11f 100644 Binary files a/docs/ODUArch.jpg and b/docs/ODUArch.jpg differ diff --git a/docs/README b/docs/README index d527a5e37..cc9d63803 100644 --- a/docs/README +++ b/docs/README @@ -3,8 +3,9 @@ A. Directory Structure : 1. l2/build/ : contains files required to compile the code a. common : contains individual module's makefile b. odu : contains main makefile to generate an executable binary - c. scripts: contains scripts for logging - d. o1 : contains main makefile to generate an executable binary + c. scripts: contains scripts for logging, installing netconf libraries and starting netopeer server + d. config : contains the configuration files + e. yang : contains the YANG modules 2. l2/docs/ : contains README and other configuration files for building docs @@ -32,12 +33,11 @@ B. Pre-requisite for Compilation : b. On CentOS : sudo yum install -y libpcap-devel -C. Pre-requisite for running O1 module: ---------------------------------------- -Install netconf server ----------------------- +C. Pre-requisite for O1 Interface (Required only if run with O1 interface enabled) +----------------------------------------------------------------------------------- +1. Setup netconf server -1. Create new netconf user (login with root user and run following command) + Create new netconf user (login with root user and run following commands) $adduser --system netconf && \ echo "netconf:netconf" | chpasswd @@ -45,16 +45,28 @@ Install netconf server ssh-keygen -A && \ ssh-keygen -t dsa -P '' -f /home/netconf/.ssh/id_dsa && \ cat /home/netconf/.ssh/id_dsa.pub > /home/netconf/.ssh/authorized_keys -2. Install netconf packages. - $cd l2/build/o1/ + Install netconf packages. + $cd l2/build/scripts $chmod +x install_lib.sh - $ ./install_lib.sh + $ ./install_lib.sh -c -Install the yang module ------------------------ -1. cd l2/build/o1/yang - sysrepoctl -i o-ran-sc-odu-alarm-v1.yang - sysrepoctl -i o-ran-sc-odu-interface-v1.yang +2. Start Netopeer2-server: + $cd l2/build/scripts + $./netopeer-server.sh start + +3. Install the yang modules + $cd l2/build/yang + $sysrepoctl -i o-ran-sc-odu-alarm-v1.yang + $sysrepoctl -i o-ran-sc-odu-interface-v1.yang + +4. Configure the startup IP and Port configurations for DU, CU and RIC + + $cd l2/build/config + + Open the startup_config.xml and edit the desired IP and Port for CU, DU and RIC. + Then load the configuration in the sysrepo running datastore using the command below + + $sysrepocfg --import=startup_config.xml --datastore running --module o-ran-sc-odu-interface-v1 D. How to Clean and Build: @@ -86,57 +98,69 @@ D. How to Clean and Build: 4. Cleaning ODU, CU Stub and RIC Stub: make clean_all -5. Building ODU binary with O1 interface enabled: + +E. How to Clean and Build with O1 interface enabled (Requires pre-requisite steps in section C) +------------------------------------------------------------------------------------------------ + +1. Building ODU binary: a. Build folder cd l2/build/odu - b. Building ODU with O1 module enabled: + b. Building ODU binary make odu MACHINE=BIT64 MODE=FDD O1_ENABLE=YES c. Cleaning ODU binary - make clean_odu MACHINE=BIT64 MODE=FDD + make clean_odu MACHINE=BIT64 MODE=FDD O1_ENABLE=YES - d. Build folder - cd l2/build/o1 - e. Building O1 binary - make o1 MACHINE=BIT64 - f. Cleaning O1 binary - make clean_o1 +2. Building CU Stub binary: + a. Build folder + cd l2/build/odu + b. Building CU Stub binary + make cu_stub NODE=TEST_STUB MACHINE=BIT64 MODE=FDD O1_ENABLE=YES + c. Cleaning CU Stub binary + make clean_cu NODE=TEST_STUB MACHINE=BIT64 MODE=FDD O1_ENABLE=YES + +3. Building RIC Stub binary: + a. Build folder + cd l2/build/odu + b. Building RIC Stub binary + make ric_stub NODE=TEST_STUB MACHINE=BIT64 MODE=FDD O1_ENABLE=YES + c. Cleaning RIC Stub binary + make clean_ric NODE=TEST_STUB MACHINE=BIT64 MODE=FDD O1_ENABLE=YES + +4. Cleaning ODU, CU Stub and RIC Stub: + make clean_all -E. How to execute: +F. How to execute: ------------------ 1. Assign virtual IP addresses as follows: a. ifconfig :ODU "192.168.130.81" b. ifconfig :CU_STUB "192.168.130.82" c. ifconfig :RIC_STUB "192.168.130.80" -2. Execute O1 (only if O-DU is built with O1 interface enabled): - a. O1 execution folder: - cd l2/build/o1/bin/o1 - b. Run O1 binary: - ./o1 +PS: If O1 interface is enabled, IP should match those configured in step C.4. -3. Execute CU Stub: +2. Execute CU Stub: a. CU execution folder: cd l2/bin/cu_stub b. Run CU Stub binary: ./cu_stub -4. Execute RIC Stub: +3. Execute RIC Stub: a. RIC execution folder: cd l2/bin/ric_stub b. Run RIC Stub binary: ./ric_stub -5. Execute DU: +4. Execute DU: a. DU execution folder: cd l2/bin/odu b. Run ODU binary: ./odu PS: CU stub and RIC stub must be run (in no particular sequence) before ODU - If O1 module is enabled it must be run before ODU -F. How to test with Intel L1: + +G. How to test with Intel L1: ----------------------------- I. Compilation @@ -201,7 +225,7 @@ II. Execution ./odu -G. How to execute the Health Check : get alarm-list +H. How to execute the Health Check : get alarm-list ---------------------------------------------------- Steps: @@ -217,7 +241,7 @@ G. How to execute the Health Check : get alarm-list Here are the steps as executed in the terminal - netopeer2-cli + $netopeer2-cli > connect --login netconf Interactive SSH Authentication Type your password: diff --git a/docs/developer-guide.rst b/docs/developer-guide.rst index 6ef573812..18e68a08b 100644 --- a/docs/developer-guide.rst +++ b/docs/developer-guide.rst @@ -763,7 +763,9 @@ O1 uses GNU C++ language. ODU - O1 Communication ^^^^^^^^^^^^^^^^^^^^^^ -O-DU High and O1 module communicate on a TCP socket. +O1 module runs as a thread in O-DU High. + +Alarm communication between the threads happen on a Unix socket. O-DU High sends alarm messages in the following structure using Alarm Interface APIs. diff --git a/docs/installation-guide.rst b/docs/installation-guide.rst index ab169b029..7de60d3c2 100644 --- a/docs/installation-guide.rst +++ b/docs/installation-guide.rst @@ -97,27 +97,72 @@ Following libraries are required to compile and execute O-DU High: - Ubuntu : sudo apt-get install -y libpcap-dev - CentOS : sudo yum install -y libpcap-devel -Following libraries are required to compile and execute O1 module: + + +Cloning code +-------------- + +- Create a folder to clone the O-DU High code into. The folder is hereafter referred to as . + +- Clone code into + + git clone "https://gerrit.o-ran-sc.org/r/o-du/l2" + + +Setting up Netconf server +------------------------- -- Netconf: + Following steps are required to compile ODU with O1 interface enabled: + +- Install Netconf libraries: + libssh, libyang, libnetconf2, sysrepo, netopeer2 Script is provided in the following folder to install these libraries - Ubuntu : - | cd /l2/build/o1 - | sudo ./install_lib.sh + | cd /l2/build/scripts + | sudo ./install_lib.sh -c +- Start Netopeer2-server: + + - Ubuntu : + | cd /l2/build/scripts + | sudo ./netopeer-server.sh start -Cloning code --------------- +- Create a new netconf user + + Switch to root user and run following commands + + - Ubuntu : + + | adduser --system netconf && \\ + | echo "netconf:netconf" | chpasswd -- Create a folder to clone the O-DU High code into. The folder is hereafter referred to as . + | mkdir -p /home/netconf/.ssh && \\ + | ssh-keygen -A && \\ + | ssh-keygen -t dsa -P '' -f /home/netconf/.ssh/id_dsa && \\ + | cat /home/netconf/.ssh/id_dsa.pub > /home/netconf/.ssh/authorized_keys -- Clone code into +- Install the YANG modules - git clone "https://gerrit.o-ran-sc.org/r/o-du/l2" + - Ubuntu : + + | cd /l2/build/yang + | sysrepoctl -i ./yang/o-ran-sc-odu-alarm-v1.yang + | sysrepoctl -i ./yang/o-ran-sc-odu-interface-v1.yang + +- Configure the startup IP and Port configurations for DU, CU and RIC + + - Ubuntu : + + | cd /l2/build/config + | + | Open the startup_config.xml and edit the desired IP and Port for CU, DU and RIC. + | Then load the configuration in the sysrepo running datastore using the command below + | + | sysrepocfg --import=startup_config.xml --datastore running --module o-ran-sc-odu-interface-v1 Compilation ------------ @@ -133,13 +178,10 @@ Compilation make clean_odu MACHINE=BIT64 MODE=FDD - - Build O-DU High binary + - Compile O-DU High binary make odu MACHINE=BIT64 MODE=FDD - To build with O1 interface enabled: - - make odu MACHINE=BIT64 MODE=FDD O1_ENABLE=YES - Build CU Stub : @@ -151,7 +193,7 @@ Compilation make clean_cu NODE=TEST_STUB MACHINE=BIT64 MODE=FDD - - Build CU Stub binary + - Compile CU Stub binary make cu_stub NODE=TEST_STUB MACHINE=BIT64 MODE=FDD @@ -165,35 +207,57 @@ Compilation make clean_ric NODE=TEST_STUB MACHINE=BIT64 MODE=FDD - - Build RIC Stub binary + - Compile RIC Stub binary make ric_stub NODE=TEST_STUB MACHINE=BIT64 MODE=FDD -- Build O-DU High with O1 interface enabled: - - Navigate to o1 Build folder +Compilation with O1 interface enabled +-------------------------------------- + +- Build O-DU High: + + - Navigate to Build folder + + cd /l2/build/odu + + - Clean O-DU High binary + + make clean_odu MACHINE=BIT64 MODE=FDD O1_ENABLE=YES + + + - Compile O-DU High binary + + make odu MACHINE=BIT64 MODE=FDD O1_ENABLE=YES + + +- Build CU Stub : + + - Navigate to Build folder - cd /l2/build/o1 + cd /l2/build/odu - - Clean O1 binary + - Clean CU Stub binary - make clean_o1 MACHINE=BIT64 + make clean_cu NODE=TEST_STUB MACHINE=BIT64 MODE=FDD O1_ENABLE=YES - - Build O1 binary + - Compile CU Stub binary - make o1 MACHINE=BIT64 + make cu_stub NODE=TEST_STUB MACHINE=BIT64 MODE=FDD O1_ENABLE=YES - - Navigate to odu Build folder +- Build RIC Stub : + - Navigate to Build folder + cd /l2/build/odu - - Clean O-DU High binary + - Clean RIC Stub binary + + make clean_ric NODE=TEST_STUB MACHINE=BIT64 MODE=FDD O1_ENABLE=YES - make clean_odu MACHINE=BIT64 MODE=FDD - - - Build O-DU High binary + - Compile RIC Stub binary - make odu MACHINE=BIT64 MODE=FDD O1_ENABLE=YES + make ric_stub NODE=TEST_STUB MACHINE=BIT64 MODE=FDD O1_ENABLE=YES @@ -205,4 +269,3 @@ The above generated images can be found at: - RIC Stub - /l2/bin/ric_stub -- O1 - /l2/build/o1/bin/o1 diff --git a/docs/overview.rst b/docs/overview.rst index 61f8ff8c3..371aab8a1 100644 --- a/docs/overview.rst +++ b/docs/overview.rst @@ -102,22 +102,22 @@ O1 Module ^^^^^^^^^^ .. figure:: ODU-O1-Arch.jpg - :width: 600 + :width: 554 :alt: Figure 2 O1 Architecture Figure 2 - O1 Architecture -As shown in figure 2 the O1 module in O-DU High runs a separate process and communicates with ODU-High process over a TCP interface. O1 module uses API calls for interacting with the Netconf server(Netopeer) and datastore(sysrepo) for providing the Netconf interface. +As shown in figure 2 the O1 module runs as a thread in O-DU High. Alarm communication happens over a Unix socket between the O1 and O-DU threads. O1 module uses API calls for interacting with the Netconf server(Netopeer) and datastore(sysrepo) for providing the Netconf interface. O1 architecture has following components: -- Netconf Manager: Subscribe to Netconf YANG modules and events. Register callback handler methods. +- Session Handler: Subscribe to Netconf YANG modules and events. Register callback handler methods. - Alarm Manager: Stores and manages(add/updated/delete) alarms. -- TCP server: Receives the alarm messages sent from O-DU High over TCP socket. +- Unix socket server: Receives the alarm messages sent from O-DU High thread over Unix socket. -- TCP Client Alarm Interface : Integrates with O-DU High module and provides an interface for sending the alarm messages to O1 module over TCP socket. +- Alarm Interface : Provides an interface to O-DU High threads for sending the alarm messages to O1 module over Unix socket. - Netopeer server: Serves the northbound SMO/OAM Netconf requests. @@ -319,11 +319,11 @@ Figure 5 below depicts the above call flow, inclusive of all interfaces: O1 Netconf get-alarm list procedure ----------------------------------- -This section describes the *Health Status Retrieval* scenario of O-DU High health-check. It enables a northbound client(SMO) to retrieve the health of the ODU-High based on the last self-check performed. The alarm-list is provided as the response to the request via O1 Netconf interface. +This section describes the *Health Status Retrieval* scenario of O-DU High health-check. It enables a northbound client(SMO) to retrieve the health of the O-DU High based on the last self-check performed. The alarm-list is provided as the response to the request via O1 Netconf interface. .. figure:: ODU-O1-GetAlarmListFlow.jpg - :width: 720 + :width: 869 :alt: Figure 6 O1 get alarm-list flow Figure 6 - O1 get alarm-list flow @@ -331,13 +331,13 @@ This section describes the *Health Status Retrieval* scenario of O-DU High healt As seen in the Figure 6, -- On the cell state change from de-active to activate, ODU High process raises a cell up alarm message and sends it over the TCP socket using the TCP client Alarm Interface API. +- On the cell state change from de-active to activate, DU APP module raises a cell up alarm message and sends it over the Unix socket using the Alarm Interface API. -- On other side a TCP server, running as a thread, in O1 module receives the cell up alarm message and it passes the alarm information to the Alarm Manager. +- On other side a Unix socket server, running as a thread, in O1 module receives the cell up alarm message and it passes on the alarm information to the Alarm Manager. - Alarm Manager stores the alarm data in a list. -- Whenever SMO/OAM requires the current alarm list, it sends a Netconf get request. The request is received by the Netopeer Server and a callback method, registered with the Netconf Manager, is invoked. +- Whenever SMO/OAM requires the current alarm list, it sends a Netconf get request. The request is received by the Netopeer Server and a callback method, registered with the Session Handler, is invoked. - The callback function fetches the alarm list from Alarm Manager and sends it back to the client (SMO/OAM) via Netconf interface. diff --git a/docs/user-guide.rst b/docs/user-guide.rst index 04f463d57..d8ca936d1 100644 --- a/docs/user-guide.rst +++ b/docs/user-guide.rst @@ -24,36 +24,10 @@ I. Execution - On locally compiling O-DU High Source Code b. ifconfig :CU_STUB "192.168.130.82" c. ifconfig :RIC_STUB "192.168.130.80" -2. Execute O1 (only if O-DU is built with O1 interface enabled): +PS: If O1 interface is enabled, IPs should match those configured in "startup_config.xml" + ( Refer Installation Guide - "Setting up Netconf server" ) - a. Navigate to O1 build folder - - - cd /l2/build/o1 - - b. Create a new netconf user and install the YANG module - - Switch to root user and run following commands - - | adduser --system netconf && \\ - | echo "netconf:netconf" | chpasswd - - | mkdir -p /home/netconf/.ssh && \\ - | ssh-keygen -A && \\ - | ssh-keygen -t dsa -P '' -f /home/netconf/.ssh/id_dsa && \\ - | cat /home/netconf/.ssh/id_dsa.pub > /home/netconf/.ssh/authorized_keys - - sysrepoctl -i ./yang/o-ran-sc-odu-alarm-v1.yang - sysrepoctl -i ./yang/o-ran-sc-odu-interface-v1.yang - - c. Navigate to O1 execution folder - - - cd /l2/build/o1/bin/o1 - - d. Run O1 binary - - - ./o1 - -3. Execute CU Stub: +2. Execute CU Stub: a. Navigate to CU execution folder @@ -63,7 +37,7 @@ I. Execution - On locally compiling O-DU High Source Code - ./cu_stub -4. Execute RIC Stub: +3. Execute RIC Stub: a. Navigate to RIC execution folder @@ -73,7 +47,7 @@ I. Execution - On locally compiling O-DU High Source Code - ./ric_stub -5. Execute O-DU High: +4. Execute O-DU High: a. Navigate to ODU execution folder @@ -83,7 +57,7 @@ I. Execution - On locally compiling O-DU High Source Code - ./odu -PS: CU stub and RIC stub must be run (in no particular sequence) before ODU. If O-DU High is built with O1 interface enabled, the O1 binary must be run before all other binaries. +PS: CU stub and RIC stub must be run (in no particular sequence) before ODU. II. Execution - Using Docker Images ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/cu_stub/cu_stub.c b/src/cu_stub/cu_stub.c index ebaade2fa..6c5980047 100644 --- a/src/cu_stub/cu_stub.c +++ b/src/cu_stub/cu_stub.c @@ -24,9 +24,7 @@ #include "du_log.h" #ifdef O1_ENABLE - -#include "Config.h" - +#include "ConfigInterface.h" #endif #define CU_ID 1 @@ -167,13 +165,13 @@ void readCuCfg() DU_LOG("\nDEBUG --> CU_STUB : Reading CU configurations"); #ifdef O1_ENABLE - if( getStartupConfig(&g_cfg) != ROK ) + if( getStartupConfigForStub(&g_cfg) != ROK ) { - RETVALUE(RFAILED); + DU_LOG("\nError --> CU_STUB : Could not fetch startup "\ + "configurations from Netconf interface\n"); + exit(1); } - DU_LOG("\nReading CU configurations---"); - DU_LOG("\nReading CU configurations g_cfg.DU_IPV4_Addr=%s", g_cfg.DU_IPV4_Addr); - DU_LOG("\nReading CU configurations g_cfg.CU_IPV4_Addr=%s", g_cfg.CU_IPV4_Addr); + cmInetAddr((S8*)g_cfg.DU_IPV4_Addr, &ipv4_du); cmInetAddr((S8*)g_cfg.CU_IPV4_Addr, &ipv4_cu); diff --git a/src/du_app/du_cell_mgr.c b/src/du_app/du_cell_mgr.c index 02a47f042..a06b642a5 100644 --- a/src/du_app/du_cell_mgr.c +++ b/src/du_app/du_cell_mgr.c @@ -30,9 +30,9 @@ #include "du_mgr.h" #include "du_utils.h" #include "du_cell_mgr.h" + #ifdef O1_ENABLE -#include "GlobalDefs.h" #include "AlarmInterface.h" #endif diff --git a/src/du_app/du_cfg.c b/src/du_app/du_cfg.c index e94e1f0e0..f59d77919 100644 --- a/src/du_app/du_cfg.c +++ b/src/du_app/du_cfg.c @@ -53,10 +53,8 @@ #include "BWP-UplinkCommon.h" #ifdef O1_ENABLE - -#include "Config.h" +#include "ConfigInterface.h" extern StartupConfig g_cfg; - #endif DuCfgParams duCfgParam; diff --git a/src/du_app/du_f1ap_msg_hdl.c b/src/du_app/du_f1ap_msg_hdl.c index a6205a53b..00b1dae59 100644 --- a/src/du_app/du_f1ap_msg_hdl.c +++ b/src/du_app/du_f1ap_msg_hdl.c @@ -103,10 +103,8 @@ #include "GTPTunnel.h" #ifdef O1_ENABLE - -#include "Config.h" +#include "ConfigInterface.h" extern StartupConfig g_cfg; - #endif DuCfgParams duCfgParam; diff --git a/src/du_app/du_mgr_main.c b/src/du_app/du_mgr_main.c index 13ef27237..712465d7b 100644 --- a/src/du_app/du_mgr_main.c +++ b/src/du_app/du_mgr_main.c @@ -30,6 +30,12 @@ #include "du_sctp.h" #include "du_egtp.h" +#ifdef O1_ENABLE + +#include "O1Interface.h" + +#endif + uint8_t rlcUlActvTsk (Pst *, Buffer *); uint8_t rlcUlActvInit (Ent, Inst, Region, Reason); uint8_t rlcDlActvTsk (Pst *, Buffer *); @@ -433,6 +439,11 @@ uint8_t tst(void) { init_log(); +#ifdef O1_ENABLE + if(start_O1_module() != ROK) + return RFAILED; +#endif + //Initialize TAPA layers if(duInit() != ROK) { diff --git a/src/du_app/du_msg_hdl.c b/src/du_app/du_msg_hdl.c index af63f7cf0..5a09fe3fa 100644 --- a/src/du_app/du_msg_hdl.c +++ b/src/du_app/du_msg_hdl.c @@ -42,7 +42,6 @@ #ifdef O1_ENABLE -#include "GlobalDefs.h" #include "AlarmInterface.h" #endif diff --git a/src/o1/Alarm.hpp b/src/o1/Alarm.hpp index ced49d0b1..c4d84132c 100644 --- a/src/o1/Alarm.hpp +++ b/src/o1/Alarm.hpp @@ -23,7 +23,7 @@ #include #include -#include "Alarm.h" +#include "AlarmMessages.h" using std::string; diff --git a/src/o1/o1_client/AlarmInterface.c b/src/o1/AlarmInterface.cpp similarity index 79% rename from src/o1/o1_client/AlarmInterface.c rename to src/o1/AlarmInterface.cpp index dcb9447d2..4f265d56e 100644 --- a/src/o1/o1_client/AlarmInterface.c +++ b/src/o1/AlarmInterface.cpp @@ -1,6 +1,6 @@ /******************************************************************************* ################################################################################ -# Copyright (c) [2020] [HCL Technologies Ltd.] # +# Copyright (c) [2020-2021] [HCL Technologies Ltd.] # # # # Licensed under the Apache License, Version 2.0 (the "License"); # # you may not use this file except in compliance with the License. # @@ -16,11 +16,13 @@ ################################################################################ *******************************************************************************/ -/* This file contains interfaces to raise and clear alarms */ +/* This file contains C interfaces for ODU to raise and clear alarms */ +#include +#include +#include "GlobalDefs.hpp" #include "AlarmInterface.h" -#include "TcpClient.h" - +#include "UnixSocketClient.hpp" /******************************************************************* * @@ -32,27 +34,29 @@ * * Functionality: * - Raise an alarm by sending alarm info to O1 module over - * TCP socket with action set to RAISE + * Unix socket with action set to RAISE * * @params[in] alarm information - * @return ROK - success - * RFAILED - failure + * @return O1::SUCCESS - success + * O1::FAILURE - failure ******************************************************************/ uint8_t raiseAlarm(AlarmRecord* alrm) { - if (openSocket(TCP_SERVER_IP,TCP_PORT) == RFAILED) + + UnixSocketClient uxClient(O1::ALARM_SOCK_PATH); + if (uxClient.openSocket() == O1::FAILURE) { - return RFAILED; + return O1::FAILURE; } alrm->msgHeader.msgType = ALARM; alrm->msgHeader.action = RAISE_ALARM; - if (sendData(alrm,sizeof(AlarmRecord)) < 0 ) + if (uxClient.sendData(alrm,sizeof(AlarmRecord)) < 0 ) { - closeSocket(); - return RFAILED; + uxClient.closeSocket(); + return O1::FAILURE; } - closeSocket(); - return ROK; + uxClient.closeSocket(); + return O1::SUCCESS; } /******************************************************************* @@ -65,28 +69,29 @@ uint8_t raiseAlarm(AlarmRecord* alrm) * * Functionality: * - Clears an alarm raised earlier by sending the alrm - * information to O1 module over TCP socket with action + * information to O1 module over Unix socket with action * set to CLEAR * * @params[in] alarm information - * @return ROK - success - * RFAILED - failure + * @return O1::SUCCESS - success + * O1::FAILURE - failure ******************************************************************/ uint8_t clearAlarm(AlarmRecord* alrm) { - if (openSocket(TCP_SERVER_IP,TCP_PORT) == RFAILED) + UnixSocketClient uxClient(O1::ALARM_SOCK_PATH); + if (uxClient.openSocket() == O1::FAILURE) { - return RFAILED; + return O1::FAILURE; } alrm->msgHeader.msgType = ALARM; alrm->msgHeader.action = CLEAR_ALARM; - if (sendData(alrm,sizeof(AlarmRecord)) < 0) + if (uxClient.sendData(alrm,sizeof(AlarmRecord)) < 0) { - closeSocket(); - return RFAILED; + uxClient.closeSocket(); + return O1::FAILURE; } - closeSocket(); - return ROK; + uxClient.closeSocket(); + return O1::SUCCESS; } @@ -103,8 +108,8 @@ uint8_t clearAlarm(AlarmRecord* alrm) * the alarm * * @params[in] alarm Id, cell Id - * @return ROK - success - * RFAILED - failure + * @return O1::SUCCESS - success + * O1::FAILURE - failure ******************************************************************/ uint8_t raiseCellAlrm(uint16_t alrmId, uint16_t cellId) { @@ -153,8 +158,8 @@ uint8_t raiseCellAlrm(uint16_t alrmId, uint16_t cellId) * - Clears the cell specific alarm using alarm id * * @params[in] alarm Id - * @return ROK - success - * RFAILED - failure + * @return O1::SUCCESS - success + * O1::FAILURE - failure ******************************************************************/ uint8_t clearCellAlrm(uint16_t alrmId) { diff --git a/src/o1/o1_client/AlarmInterface.h b/src/o1/AlarmInterface.h similarity index 85% rename from src/o1/o1_client/AlarmInterface.h rename to src/o1/AlarmInterface.h index 4dabd43ee..53839ddfb 100644 --- a/src/o1/o1_client/AlarmInterface.h +++ b/src/o1/AlarmInterface.h @@ -1,6 +1,6 @@ /******************************************************************************* ################################################################################ -# Copyright (c) [2020] [HCL Technologies Ltd.] # +# Copyright (c) [2020-2021] [HCL Technologies Ltd.] # # # # Licensed under the Apache License, Version 2.0 (the "License"); # # you may not use this file except in compliance with the License. # @@ -16,23 +16,32 @@ ################################################################################ *******************************************************************************/ -/* This file contains interfaces to raise and clear alarms */ +/* This file contains C interfaces for ODU to raise and clear alarms */ #ifndef __ALARM_INTERFACE_H__ #define __ALARM_INTERFACE_H__ #include -#include "Alarm.h" -#include "ssi.h" -#include "GlobalDefs.h" +#include "AlarmMessages.h" +#define CELL_UP_ALARM_ID 1009 +#define CELL_DOWN_ALARM_ID 1010 #define BUFF_SIZE 20 +#ifdef __cplusplus +extern "C" +{ +#endif + uint8_t raiseAlarm(AlarmRecord* alrm); uint8_t clearAlarm(AlarmRecord* alrm); uint8_t raiseCellAlrm(uint16_t alrmId, uint16_t cellId); uint8_t clearCellAlrm(uint16_t alrmId); +#ifdef __cplusplus +} +#endif + #endif /********************************************************************** diff --git a/src/o1/o1_client/Alarm.h b/src/o1/AlarmMessages.h similarity index 95% rename from src/o1/o1_client/Alarm.h rename to src/o1/AlarmMessages.h index f88ed2eb2..5a7ab732b 100644 --- a/src/o1/o1_client/Alarm.h +++ b/src/o1/AlarmMessages.h @@ -1,6 +1,6 @@ /******************************************************************************* ################################################################################ -# Copyright (c) [2020] [HCL Technologies Ltd.] # +# Copyright (c) [2020-2021] [HCL Technologies Ltd.] # # # # Licensed under the Apache License, Version 2.0 (the "License"); # # you may not use this file except in compliance with the License. # @@ -18,8 +18,8 @@ /* This file contains definitions of Alarm structure */ -#ifndef __ALARM_H__ -#define __ALARM_H__ +#ifndef __ALARM_MESSAGES_H__ +#define __ALARM_MESSAGES_H__ #include #include "CommonMessages.h" diff --git a/src/o1/o1_client/CommonMessages.h b/src/o1/CommonMessages.h similarity index 96% rename from src/o1/o1_client/CommonMessages.h rename to src/o1/CommonMessages.h index 35ab96539..c51b44759 100644 --- a/src/o1/o1_client/CommonMessages.h +++ b/src/o1/CommonMessages.h @@ -1,6 +1,6 @@ /******************************************************************************* ################################################################################ -# Copyright (c) [2020] [HCL Technologies Ltd.] # +# Copyright (c) [2020-2021] [HCL Technologies Ltd.] # # # # Licensed under the Apache License, Version 2.0 (the "License"); # # you may not use this file except in compliance with the License. # diff --git a/src/o1/ConfigInterface.cpp b/src/o1/ConfigInterface.cpp new file mode 100644 index 000000000..0a283ae51 --- /dev/null +++ b/src/o1/ConfigInterface.cpp @@ -0,0 +1,151 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2020-2021] [HCL Technologies Ltd.] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/* This file contains C interface for ODU and stubs to get startup + configuration +*/ + +#include "ConfigInterface.h" +#include "GlobalDefs.hpp" +#include "UnixSocketClient.hpp" +#include "SessionHandler.hpp" +#include "InitConfig.hpp" + +StartupConfig g_cfg; + +/******************************************************************* + * + * @brief Get the startup config from Netconf + * + * @details + * + * Function : getStartupConfig + * + * Functionality: + * - Get the start up IP and port for DU + * + * @params[in] pointer to StartupConfig + * @return O1::SUCCESS - success + * O1::FAILURE - failure + ******************************************************************/ +uint8_t getStartupConfig(StartupConfig *cfg) +{ + if ( InitConfig::instance().getCurrInterfaceConfig(*cfg) ) + { + O1_LOG("\nO1 StartupConfig : " + "cfg.DU_IPV4_Addr [%s]", + cfg->DU_IPV4_Addr); + O1_LOG("\nO1 StartupConfig : " + "cfg.DU_Port [%d]", + cfg->DU_Port); + O1_LOG("\nO1 StartupConfig : " + "cfg.CU_IPV4_Addr [%s]", + cfg->CU_IPV4_Addr); + O1_LOG("\nO1 StartupConfig : " + "cfg.CU_Port [%d]", + cfg->CU_Port); + O1_LOG("\nO1 StartupConfig : " + "cfg.RIC_IPV4_Addr [%s]", + cfg->RIC_IPV4_Addr); + O1_LOG("\nO1 StartupConfig : " + "cfg.RIC_Port [%d]", + cfg->RIC_Port); + return O1::SUCCESS; + } + return O1::FAILURE; +} + +/******************************************************************* + * + * @brief Get the startup config from Netconf + * + * @details + * + * Function : getStartupConfig + * + * Functionality: + * - Get the start up IP and port for CU and RIC + * + * @params[in] pointer to StartupConfig + * @return O1::SUCCESS - success + * O1::FAILURE - failure + ******************************************************************/ +uint8_t getStartupConfigForStub(StartupConfig *cfg) +{ +#if 0 + UnixSocketClient uxClient(O1::ALARM_SOCK_PATH); + O1_LOG("\nO1 CONFIG : getStartupConfig ------ \n"); + MsgHeader msg; + msg.msgType = CONFIGURATION; + msg.action = GET_STARTUP_CONFIG; + if (uxClient.openSocket() == O1::FAILURE) + { + return O1::FAILURE; + } + if (uxClient.sendData(&msg,sizeof(msg)) < 0 ) + { + uxClient.closeSocket(); + return O1::FAILURE; + } + if (uxClient.receiveData(cfg, sizeof(StartupConfig)) < 0) + { + uxClient.closeSocket(); + return O1::FAILURE; + } + O1_LOG("\nO1 CONFIG : ip du %s\n",cfg->DU_IPV4_Addr ); + O1_LOG("\nO1 CONFIG : ip cu %s\n",cfg->CU_IPV4_Addr ); + O1_LOG("\nO1 CONFIG : ip ric %s\n",cfg->RIC_IPV4_Addr ); + O1_LOG("\nO1 CONFIG : port cu %hu\n",cfg->CU_Port); + O1_LOG("\nO1 CONFIG : port du %hu\n",cfg->DU_Port); + O1_LOG("\nO1 CONFIG : port ric %hu\n",cfg->RIC_Port); + + uxClient.closeSocket(); +#endif + SessionHandler sessHdlr; + if ( sessHdlr.init() ) + { + if ( InitConfig::instance().getCurrInterfaceConfig(*cfg) ) + { + O1_LOG("\nO1 StartupConfig : " + "cfg.DU_IPV4_Addr [%s]", + cfg->DU_IPV4_Addr); + O1_LOG("\nO1 StartupConfig : " + "cfg.DU_Port [%d]", + cfg->DU_Port); + O1_LOG("\nO1 StartupConfig : " + "cfg.CU_IPV4_Addr [%s]", + cfg->CU_IPV4_Addr); + O1_LOG("\nO1 StartupConfig : " + "cfg.CU_Port [%d]", + cfg->CU_Port); + O1_LOG("\nO1 StartupConfig : " + "cfg.RIC_IPV4_Addr [%s]", + cfg->RIC_IPV4_Addr); + O1_LOG("\nO1 StartupConfig : " + "cfg.RIC_Port [%d]", + cfg->RIC_Port); + return O1::SUCCESS; + } + } + return O1::FAILURE; +} + + +/********************************************************************** + End of file +**********************************************************************/ diff --git a/src/o1/o1_client/Config.h b/src/o1/ConfigInterface.h similarity index 85% rename from src/o1/o1_client/Config.h rename to src/o1/ConfigInterface.h index fb7250ca4..0f4929e5c 100644 --- a/src/o1/o1_client/Config.h +++ b/src/o1/ConfigInterface.h @@ -16,10 +16,12 @@ ################################################################################ *******************************************************************************/ -/* This file contains definitions of startup configuration structure */ +/* This file contains C interface for ODU and stubs to get startup + configuration +*/ -#ifndef __CONFIG_H__ -#define __CONFIG_H__ +#ifndef __CONFIG_INTERFACE_H__ +#define __CONFIG_INTERFACE_H__ #include #include @@ -27,6 +29,11 @@ #define IPV4_LEN 16 #define PORT_LEN 10 +#ifdef __cplusplus +extern "C" +{ +#endif + typedef struct { char DU_IPV4_Addr[IPV4_LEN]; @@ -37,7 +44,13 @@ typedef struct uint16_t RIC_Port; }StartupConfig; -uint8_t getStartupConfig(); + +uint8_t getStartupConfig(StartupConfig *cfg); +uint8_t getStartupConfigForStub(StartupConfig *cfg); + +#ifdef __cplusplus +} +#endif #endif diff --git a/src/o1/GlobalDefs.cpp b/src/o1/GlobalDefs.cpp index 77ea38062..e3dc38dbe 100644 --- a/src/o1/GlobalDefs.cpp +++ b/src/o1/GlobalDefs.cpp @@ -20,9 +20,11 @@ #include "GlobalDefs.hpp" -const short O1::TCP_PORT = 8282; const int O1::SUCCESS = 0; const int O1::FAILURE = 1; +const std::string O1::ALARM_SOCK_PATH("/tmp/alarmsock"); +const int O1::CPU_CORE = 22; + /********************************************************************** End of file diff --git a/src/o1/GlobalDefs.hpp b/src/o1/GlobalDefs.hpp index 0f8d42a41..759e72554 100644 --- a/src/o1/GlobalDefs.hpp +++ b/src/o1/GlobalDefs.hpp @@ -22,6 +22,9 @@ #define __GLOBAL_DEFS_HPP__ #include +#include + +using std::string; #define O1_LOG(...) ( {\ printf(__VA_ARGS__);\ @@ -38,9 +41,10 @@ class O1 { public: - static const short TCP_PORT; static const int SUCCESS; static const int FAILURE; + static const string ALARM_SOCK_PATH; + static const int CPU_CORE; }; #endif diff --git a/src/o1/InitConfig.cpp b/src/o1/InitConfig.cpp index 4edc8c2a6..b21e1b734 100644 --- a/src/o1/InitConfig.cpp +++ b/src/o1/InitConfig.cpp @@ -20,9 +20,6 @@ YANG modules */ #include "InitConfig.hpp" -#include -#include -using namespace std; /* Default constructor */ @@ -54,9 +51,13 @@ InitConfig::~InitConfig() bool InitConfig::init(sysrepo::S_Session sess) { - O1_LOG("\nInitConfig::init started "); mSess = sess; - getInterfaceConfig(sess); + InitConfig::InterfaceMap map; + if(!getInterfaceConfig(sess, map)) + { + O1_LOG("\nInitConfig::getInterfaceConfig InitConfig data error "); + return false; + } return true; } @@ -86,57 +87,45 @@ bool InitConfig::getCurrInterfaceConfig(StartupConfig & cfg) switch (it->first) { case Interface::ODU : - if(it->second.first != "0") + if(it->second.first != "") strcpy(cfg.DU_IPV4_Addr, it->second.first.c_str()); else - strcpy(cfg.DU_IPV4_Addr, DEFAULT_DU_IPV4_ADDR); - //O1_LOG("\n InitConfig::getCurrInterfaceConfig cfg.DU_IPV4_Addr = \ - %s", cfg.DU_IPV4_Addr); + return false; if(it->second.second != 0) cfg.DU_Port = (uint16_t)it->second.second; else - cfg.DU_Port = (uint16_t) DEFAULT_DU_PORT; - //O1_LOG("\n InitConfig::getCurrInterfaceConfig cfg.DU_Port = %d", \ - cfg.DU_Port); + return false; break; case Interface::OCU : - if(it->second.first != "0") + if(it->second.first != "") strcpy(cfg.CU_IPV4_Addr, it->second.first.c_str()); else - strcpy(cfg.CU_IPV4_Addr, DEFAULT_CU_IPV4_ADDR); + return false; - //O1_LOG("\n InitConfig::getCurrInterfaceConfig cfg.CU_IPV4_Addr = \ - %s", cfg.CU_IPV4_Addr); if(it->second.second != 0) cfg.CU_Port = (uint16_t) it->second.second; else - cfg.CU_Port = (uint16_t) DEFAULT_CU_PORT; + return false; - //O1_LOG("\n InitConfig::getCurrInterfaceConfig cfg.CU_Port = %d", \ - cfg.CU_Port); break; case Interface::RIC : - if(it->second.first != "0") + if(it->second.first != "") strcpy(cfg.RIC_IPV4_Addr, it->second.first.c_str()); else - strcpy(cfg.RIC_IPV4_Addr, DEFAULT_RIC_IPV4_ADDR); + return false; - //O1_LOG("\n InitConfig::getCurrInterfaceConfig cfg.RIC_IPV4_Addr = \ - %s", cfg.RIC_IPV4_Addr); if(it->second.second != 0) cfg.RIC_Port = (uint16_t) it->second.second; else - cfg.RIC_Port = (uint16_t) DEFAULT_RIC_PORT; + return false; - //O1_LOG("\n InitConfig::getCurrInterfaceConfig cfg.RIC_Port = %d", \ - cfg.RIC_Port); break; default : @@ -162,16 +151,25 @@ bool InitConfig::getCurrInterfaceConfig(StartupConfig & cfg) * @return reference of InterfaceMap * ******************************************************************/ -InitConfig::InterfaceMap InitConfig::getInterfaceConfig(sysrepo::S_Session sess) +bool InitConfig::getInterfaceConfig(sysrepo::S_Session sess , InitConfig::InterfaceMap &map) { - O1_LOG("\nInitConfig::getInterfaceConfig started"); - mInterfaceList.insert(std::make_pair(Interface::ODU, \ - getInterfaceData(sess,Interface::ODU))); - mInterfaceList.insert(std::make_pair(Interface::OCU, \ - getInterfaceData(sess,Interface::OCU))); - mInterfaceList.insert(std::make_pair(Interface::RIC, \ - getInterfaceData(sess,Interface::RIC))); - return mInterfaceList; + InitConfig::Address oduAddr; + InitConfig::Address ocuAddr; + InitConfig::Address ricAddr; + if(getInterfaceData(sess,Interface::ODU, oduAddr) && \ + getInterfaceData(sess,Interface::OCU, ocuAddr) && \ + getInterfaceData(sess,Interface::RIC, ricAddr)) + { + mInterfaceList.insert(std::make_pair(Interface::ODU, oduAddr)); + mInterfaceList.insert(std::make_pair(Interface::OCU, ocuAddr)); + mInterfaceList.insert(std::make_pair(Interface::RIC, ricAddr)); + map = mInterfaceList; + return true; + } + else + { + return false; + } } /******************************************************************* @@ -189,13 +187,26 @@ InitConfig::InterfaceMap InitConfig::getInterfaceConfig(sysrepo::S_Session sess) * @return reference of Address * ******************************************************************/ -InitConfig::Address InitConfig::getInterfaceData(sysrepo::S_Session sess, \ - Interface inf) +bool InitConfig::getInterfaceData(sysrepo::S_Session sess, \ + Interface inf, InitConfig::Address & addr) { - O1_LOG("\nInitConfig::getInterfaceData started"); + //O1_LOG("\nInitConfig::getInterfaceData started"); string sInf = interfaceToString(inf); - return std::make_pair(getData(sess, getInterfaceXpath(sInf, IP_ADDRESS)), \ - atoi(getData(sess, getInterfaceXpath(sInf, PORT)).c_str())); + string ip; + string port; + + if(getData(sess, getInterfaceXpath(sInf, IP_ADDRESS), ip)) + { + if(getData(sess, getInterfaceXpath(sInf, PORT), port)) + { + addr = std::make_pair(ip, atoi(port.c_str())); + return true; + } + else + return false; + } + else + return false; } /******************************************************************* @@ -236,7 +247,7 @@ char * InitConfig::getInterfaceXpath( string sInf, string param) * ******************************************************************/ -string InitConfig::getData(sysrepo::S_Session sess,char* xpath) +bool InitConfig::getData(sysrepo::S_Session sess,char* xpath, string &val) { //O1_LOG("\nInitConfig::getData of xpath = %s", \ xpath); //enable for debugging only @@ -245,19 +256,21 @@ string InitConfig::getData(sysrepo::S_Session sess,char* xpath) auto value = sess->get_item(xpath); if (value == nullptr) { + O1_LOG("\nInitConfig::getData no data available at xpath= %s", \ + xpath); //O1_LOG("\nget_item value are null for xpath = %s", \ xpath); //enable for debugging only - return "0"; + return false; } - string mVal = value->val_to_string(); - return mVal; + val = value->val_to_string(); + return true; } catch (...) { - //O1_LOG("\nInitConfig::getData exception occured for block xpath= %s", \ - xpath); //enable for debugging only - return "0"; + O1_LOG("\nInitConfig::getData exception occured for xpath= %s", \ + xpath); + return false; } } diff --git a/src/o1/InitConfig.hpp b/src/o1/InitConfig.hpp index 99d61f348..1b58f0861 100644 --- a/src/o1/InitConfig.hpp +++ b/src/o1/InitConfig.hpp @@ -24,27 +24,20 @@ #include #include #include -#include "sysrepo-cpp/Session.hpp" +#include #include +#include "sysrepo-cpp/Session.hpp" #include "Singleton.hpp" -#include "Config.h" - +#include "ConfigInterface.h" #include "GlobalDefs.hpp" + #define IP_ADDRESS "interface-address" #define PORT "port" #define INTERFACE_MODULE_NAME_ORAN "/o-ran-sc-odu-interface-v1:odu" #define MAX_XPATH 100 #define NETCONF_STARTUP_CFG "/etc/netconf_startup.cfg" -#define DEFAULT_DU_IPV4_ADDR "192.168.130.81" -#define DEFAULT_DU_PORT 38472 - -#define DEFAULT_CU_IPV4_ADDR "192.168.130.82" -#define DEFAULT_CU_PORT 38472 - -#define DEFAULT_RIC_IPV4_ADDR "192.168.130.80" -#define DEFAULT_RIC_PORT 36421 - +using namespace std; enum class Interface { ODU, OCU, @@ -75,10 +68,11 @@ class InitConfig : public Singleton sysrepo::S_Session mSess; //string mVal; /* function to get the data of Interfaces param*/ - InterfaceMap getInterfaceConfig(sysrepo::S_Session sess); - Address getInterfaceData(sysrepo::S_Session sess, Interface inf); + bool getInterfaceData(sysrepo::S_Session sess, \ + Interface inf, InitConfig::Address & addr); + bool getInterfaceConfig(sysrepo::S_Session sess , InitConfig::InterfaceMap &map); char * getInterfaceXpath( std::string sInf, std::string param); - std::string getData(sysrepo::S_Session sess,char* xpath); + bool getData(sysrepo::S_Session sess,char* xpath, string &val); std::string interfaceToString(Interface inf); bool printInterfaceConfig(); bool writeInterfaceConfig(); diff --git a/src/o1/NetconfManager.cpp b/src/o1/NetconfManager.cpp index 077cdfefb..4fa027629 100644 --- a/src/o1/NetconfManager.cpp +++ b/src/o1/NetconfManager.cpp @@ -119,11 +119,11 @@ void NetconfManager::sigintHandler(int signum) **********************************************************************/ bool NetconfManager::init(void) { - if(startNetopeerServer()) + /* if(startNetopeerServer()) { O1_LOG("\nO1 NetconfManager : netopeer server started"); } - + */ try { mSessHndl = new SessionHandler; @@ -132,9 +132,10 @@ bool NetconfManager::init(void) if( !mSessHndl->init()) { - O1_LOG("\nO1 NetconfManager : SessionHandler init failed "); + O1_LOG("\nO1 NetconfManager : SessionHandler init failed \n"); return false; } + return true; } catch( const std::exception& e ) { diff --git a/src/o1/O1App.cpp b/src/o1/O1App.cpp new file mode 100644 index 000000000..b4cfbde2c --- /dev/null +++ b/src/o1/O1App.cpp @@ -0,0 +1,182 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2020-2021] [HCL Technologies Ltd.] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/* This file contains the O1App class which is responsible for running/starting + all the O1 modules in a thread. It inherits the Thread class and Singleton + class. +*/ + +#include "O1App.hpp" +#include "GlobalDefs.hpp" +#include "SessionHandler.hpp" +#include "ConfigInterface.h" +#include + +/******************************************************************* + * + * @brief Constructor + * + * @details + * + * Function : O1App + * + * Functionality: + * - Constructor intialization + * + * @params[in] None + * @return None + ******************************************************************/ + +O1App::O1App() : mUxSocketServer(O1::ALARM_SOCK_PATH) +{ + +} + +/******************************************************************* + * + * @brief Destructor + * + * @details + * + * Function : ~O1App + * + * Functionality: + * - Destructor + * + * @params[in] None + * @return None + ******************************************************************/ + +O1App::~O1App() +{ + +} + +/******************************************************************* + * + * @brief Runs the O1 modules as a thread + * + * @details + * + * Function : run + * + * Functionality: + * - Implements the "run" function of Thread class. + * Starts all the O1 modules. + * + * + * @params[in] void + * @return true : success + * false : failure + ******************************************************************/ + +bool O1App::run() +{ + + SessionHandler sessHdlr; + /* Start Netconf session and subscribe to yang modules */ + try + { + if( !sessHdlr.init() ) + { + O1_LOG("\nO1 O1App : SessionHandler initialization failed "); + return false; + } + } + catch( const std::exception& e ) + { + O1_LOG("\nO1 O1App : Exception : %s", e.what()); + return false; + } + + /* Start the Unix Socket Server to listen for alarm messages */ + if( mUxSocketServer.start() ) + { + + if(mUxSocketServer.setAffinity(O1::CPU_CORE)) + { + O1_LOG("\nO1 O1App : CPU affinity set " ); + mUxSocketServer.printAffinity(); + } + + sleep(2); + if( mUxSocketServer.isRunning() ) + { + mStartupStatus = true; + O1_LOG("\nO1 O1App : Unix Socket server started\n"); + } + else + { + O1_LOG("\nO1 O1App : Unix Socket server failed to start\n"); + return false; + } + /* Wait for the Unix Socket Server thread to end*/ + mUxSocketServer.join(); + } + else + { + O1_LOG("\nO1 O1App : Unix Socket server failed to start\n"); + return false; + } + return true; +} + +/******************************************************************* + * + * @brief Check if the O1 Module is fully up and running + * + * @details + * + * Function : getStartupStatus + * + * Functionality: + * - Returns the status of O1App whether it is fully up + * + * + * @params[in] void + * @return true : started + * false : not started + ******************************************************************/ + +bool O1App::getStartupStatus() const +{ + return mStartupStatus; +} + +/******************************************************************* + * + * @brief Cleanup O1App + * + * @details + * + * Function : cleanUp + * + * Functionality: + * - Implements the "cleanUp" function of Thread class to + * take care of any clean up required for O1 components + * before stopping the thread. + * + * @params[in] void + * @return void + ******************************************************************/ + +void O1App::cleanUp(void) +{ + /* Stop the socket server thread */ + mUxSocketServer.stop(); +} diff --git a/src/o1/o1_client/GlobalDefs.h b/src/o1/O1App.hpp similarity index 67% rename from src/o1/o1_client/GlobalDefs.h rename to src/o1/O1App.hpp index 6323819e2..b1653d3f3 100644 --- a/src/o1/o1_client/GlobalDefs.h +++ b/src/o1/O1App.hpp @@ -1,6 +1,6 @@ /******************************************************************************* ################################################################################ -# Copyright (c) [2020] [HCL Technologies Ltd.] # +# Copyright (c) [2020-2021] [HCL Technologies Ltd.] # # # # Licensed under the Apache License, Version 2.0 (the "License"); # # you may not use this file except in compliance with the License. # @@ -16,25 +16,36 @@ ################################################################################ *******************************************************************************/ -/* Class for global defines and constants for O1 interface */ +/* This file contains the O1App class which is responsible for running/starting + all the O1 modules in a thread. It inherits the Thread class and Singleton + class. +*/ -#ifndef __GLOBAL_DEFS_H__ -#define __GLOBAL_DEFS_H__ +#ifndef __O1_APP_HPP__ +#define __O1_APP_HPP__ -#include +#include "Singleton.hpp" +#include "Thread.hpp" +#include "UnixSocketServer.hpp" -#define O1_LOG(...) ({\ - printf(__VA_ARGS__);\ - syslog(LOG_DEBUG,__VA_ARGS__);\ - }) -#define TCP_PORT 8282 -#define TCP_SERVER_IP "127.0.0.1" -#define CELL_UP_ALARM_ID 1009 -#define CELL_DOWN_ALARM_ID 1010 +class O1App : public Singleton, public Thread +{ + friend Singleton; + + private: + bool mStartupStatus; + UnixSocketServer mUxSocketServer; -#endif + protected: + bool run(); + + public: + O1App(); + ~O1App(); + bool getStartupStatus()const; + void cleanUp(void); +}; -/********************************************************************** - End of file -**********************************************************************/ + +#endif diff --git a/src/o1/o1_client/Config.c b/src/o1/O1Interface.cpp similarity index 53% rename from src/o1/o1_client/Config.c rename to src/o1/O1Interface.cpp index 0f766cab4..c3135b53a 100644 --- a/src/o1/o1_client/Config.c +++ b/src/o1/O1Interface.cpp @@ -1,6 +1,6 @@ /******************************************************************************* ################################################################################ -# Copyright (c) [2020] [HCL Technologies Ltd.] # +# Copyright (c) [2020-2021] [HCL Technologies Ltd.] # # # # Licensed under the Apache License, Version 2.0 (the "License"); # # you may not use this file except in compliance with the License. # @@ -16,59 +16,80 @@ ################################################################################ *******************************************************************************/ -/* This file contains definitions of startup configuration structure */ +/* This file contains the C interface for ODU to start the O1 module */ -#include "Config.h" -#include "ssi.h" -#include "GlobalDefs.h" -#include "TcpClient.h" +#include "O1Interface.h" +#include "O1App.hpp" +#include "GlobalDefs.hpp" +#include +#include -StartupConfig g_cfg; /******************************************************************* * - * @brief Get the startup config from Netconf + * @brief Wait for the O1 Module to start * * @details * - * Function : getStartupConfig + * Function : check_O1_module_status * * Functionality: - * - Get the start up IP and port for DU,CU and RIC + * - Checks if the O1App has started * - * @params[in] pointer to StartupConfig - * @return ROK - success - * RFAILED - failure + * + * @params[in] void + * @return O1::SUCCESS - success + * O1::FAILURE - failure ******************************************************************/ -uint8_t getStartupConfig(StartupConfig *cfg) -{ - O1_LOG("\nCONFIG : getStartupConfig ------ \n"); - MsgHeader msg; - msg.msgType = CONFIGURATION; - msg.action = GET_STARTUP_CONFIG; - if (openSocket(TCP_SERVER_IP,TCP_PORT) == RFAILED) + +int static check_O1_module_status(void){ + for( int i = 0; i < 5 ; i++) { - return RFAILED; + if( O1App::instance().getStartupStatus() == true) + { + return O1::SUCCESS; + } + else + { + sleep(1); + } } - if (sendData(&msg,sizeof(msg)) < 0 ) - { - closeSocket(); - return RFAILED; + + return O1::FAILURE; +} + +/******************************************************************* + * + * @brief Starts the O1 Module + * + * @details + * + * Function : start_O1_module + * + * Functionality: + * - Starts the O1 module by instantiating the O1App instance + * Invoked from the ODU-High main function + * + * + * @params[in] void + * @return O1::SUCCESS - success + * O1::FAILURE - failure + ******************************************************************/ + +int start_O1_module(void) +{ + + if(O1App::instance().start() == false){ + O1_LOG("\nO1 O1Interface : Failed to start"); + return O1::FAILURE; } - if (receiveData(cfg, sizeof(StartupConfig)) < 0) + + if(O1App::instance().setAffinity(O1::CPU_CORE)) { - closeSocket(); - return RFAILED; + O1_LOG("\nO1 O1Interface : CPU affinity set " ); + O1App::instance().printAffinity(); } - O1_LOG("\nCONFIG : ip du %s\n",cfg->DU_IPV4_Addr ); - O1_LOG("\nCONFIG : ip cu %s\n",cfg->CU_IPV4_Addr ); - O1_LOG("\nCONFIG : ip ric %s\n",cfg->RIC_IPV4_Addr ); - O1_LOG("\nCONFIG : port cu %hu\n",cfg->CU_Port); - O1_LOG("\nCONFIG : port du %hu\n",cfg->DU_Port); - O1_LOG("\nCONFIG : port ric %hu\n",cfg->RIC_Port); - - closeSocket(); - return ROK; + return check_O1_module_status(); } diff --git a/src/o1/o1_client/TcpClient.h b/src/o1/O1Interface.h similarity index 70% rename from src/o1/o1_client/TcpClient.h rename to src/o1/O1Interface.h index 8349e580f..cff161da6 100644 --- a/src/o1/o1_client/TcpClient.h +++ b/src/o1/O1Interface.h @@ -1,6 +1,6 @@ /******************************************************************************* ################################################################################ -# Copyright (c) [2020] [HCL Technologies Ltd.] # +# Copyright (c) [2020-2021] [HCL Technologies Ltd.] # # # # Licensed under the Apache License, Version 2.0 (the "License"); # # you may not use this file except in compliance with the License. # @@ -16,20 +16,20 @@ ################################################################################ *******************************************************************************/ -/* This file contains functions to connect to a TCP server and send massages */ +/* This file contains the C interface for ODU to start the O1 module */ -#ifndef __TCP_CLIENT_H__ -#define __TCP_CLIENT_H__ -#include -#include "ssi.h" +#ifndef __O1_INTERFACE_H__ +#define __O1_INTERFACE_H__ -uint8_t openSocket(const char*, const uint16_t); -int sendData(void*, const int); -int receiveData(void* data, const int size); -uint8_t closeSocket(); +#ifdef __cplusplus +extern "C" +{ +#endif +int start_O1_module(void); +#ifdef __cplusplus +} #endif -/********************************************************************** - End of file -**********************************************************************/ + +#endif diff --git a/src/o1/O1_main.cpp b/src/o1/O1_main.cpp deleted file mode 100644 index c0ecce74f..000000000 --- a/src/o1/O1_main.cpp +++ /dev/null @@ -1,68 +0,0 @@ -/******************************************************************************* -################################################################################ -# Copyright (c) [2020] [HCL Technologies Ltd.] # -# # -# 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. # -################################################################################ -*******************************************************************************/ - -/* This file contains O1 main. - Starts the Netopeer and TCP server -*/ - -#include "NetconfManager.hpp" -#include "TcpServer.hpp" -#include - -/********************************************************************** - Description : Main function. Start of O1 module. - Params[In] : None - Return : EXIT_SUCCESS - : EXIT_FAILURE -**********************************************************************/ - -int main(int argc, char **argv) -{ - TcpServer tcpServer(O1::TCP_PORT); - /*SIGINT handling*/ - //signal(SIGINT, NetconfManager::sigintHandler); - /* Start Netconf server and subscribe to yang modules */ - try - { - NetconfManager::instancePtr()->init(); - O1_LOG("\nO1 O1_main : NetconfManager init successful"); - - } - catch( const std::exception& e ) - { - O1_LOG("\nO1 O1_main : Exception : %s", e.what()); - return EXIT_FAILURE; - } - /* Start the TCP Server to listen for alarm messages */ - if( tcpServer.start() ) - { - O1_LOG("\nO1 O1_main : TCP server started\n"); - /* Wait for the TcpServer thread to end*/ - tcpServer.wait(); - } - else - { - O1_LOG("\nO1 O1_main : Failed to start TCP server"); - return EXIT_FAILURE; - } - return EXIT_SUCCESS; -} - -/********************************************************************** - End of file -**********************************************************************/ diff --git a/src/o1/SessionHandler.cpp b/src/o1/SessionHandler.cpp index bc6ec9f98..1f9c0cf06 100644 --- a/src/o1/SessionHandler.cpp +++ b/src/o1/SessionHandler.cpp @@ -50,15 +50,46 @@ bool SessionHandler::init() { try { - O1_LOG("\nO1 SessionHandler : Initialization done"); mConn = createConnection(); - O1_LOG("\nO1 SessionHandler : Initialization done"); - mSess = createSession(mConn); - mSub = createSubscribe(mSess); - O1_LOG("\nO1 SessionHandler : Initialization done"); - //InitConfig initConf; - InitConfig::instance().init(mSess); - return true; + if(mConn != NULL) + { + O1_LOG("\nO1 SessionHandler : Connection created"); + //removing nacm module temperary for auth issue resolve + //mConn.remove_module("ietf-netconf-acm"); + mSess = createSession(mConn); + if(mSess != NULL) + { + O1_LOG("\nO1 SessionHandler : Session created"); + mSub = createSubscribe(mSess); + if(mSub != NULL) + { + O1_LOG("\nO1 SessionHandler : Subscription created"); + if(InitConfig::instance().init(mSess)) + { + return true; + } + else + { + return false; + } + } + else + { + O1_LOG("\nO1 SessionHandler : Subscription failed"); + return false; + } + } + else + { + O1_LOG("\nO1 SessionHandler : Session failed"); + return false; + } + } + else + { + O1_LOG("\nO1 SessionHandler : connection failed"); + return false; + } } catch( const std::exception& e ) { diff --git a/src/o1/Thread.cpp b/src/o1/Thread.cpp new file mode 100644 index 000000000..266c21b5f --- /dev/null +++ b/src/o1/Thread.cpp @@ -0,0 +1,222 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2020-2021] [HCL Technologies Ltd.] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/* This file contains class for launching and managing POSIX threads */ + +#include "Thread.hpp" +#include "GlobalDefs.hpp" +#include +#include + +/******************************************************************* + * + * @brief Constructor + * + * @details + * + * Function : Thread + * + * Functionality: + * - Constructor intialization + * + * @params[in] None + * @return None + ******************************************************************/ + +Thread::Thread(): mThreadId(0) +{ + +} + +/******************************************************************* + * + * @brief Destructor + * + * @details + * + * Function : ~Thread + * + * Functionality: + * - Destructor + * + * @params[in] None + * @return None + ******************************************************************/ + +Thread::~Thread() +{ + +} + +/******************************************************************* + * + * @brief Static function registered to run as pthread + + * + * @details + * + * Function : task + * + * Functionality: + * - Static function registered to run as pthread. It calls + * the run function that is implemented by the derived + * class instance. + * + * @params[in] void pointer to the base class instance that + implements this Thread class + * @return void + ******************************************************************/ + +void* Thread::task(void* args) +{ + Thread* thisPtr = static_cast(args); + thisPtr->run(); +} + + +/******************************************************************* + * + * @brief Creates a thread + * + * @details + * + * Function : start + * + * Functionality: + * - Starts a pthread registering the "task" function for + * performing the thread task. + * + * @params[in] void + * @return true : success + * false : failure + ******************************************************************/ + +bool Thread::start() +{ + return (pthread_create(&mThreadId, NULL, task, this) == 0); +} + + +/******************************************************************* + * + * @brief Stops the thread + * + * @details + * + * Function : stop + * + * Functionality: + * - Stops the thread. Performs an clean ups prior to + * stopping the thread + * + * + * @params[in] void + * @return true : success + * false : failure + ******************************************************************/ +bool Thread::stop() +{ + cleanUp(); + return (pthread_cancel(mThreadId) == 0); +} + +/******************************************************************* + * + * @brief Wait for the thread to complete + * + * @details + * + * Function : join + * + * Functionality: + * - Waits for the thread to complete in the calling process/ + * thread + * + * @params[in] void + * @return true : success + * false : failure + ******************************************************************/ +bool Thread::join() +{ + return (pthread_join(mThreadId,NULL) == 0); +} + + +/******************************************************************* + * + * @brief Set the affinity of the thread + * + * @details + * + * Function : setAffinity + * + * Functionality: + * - Pins the thread to cpu core(s) + * + * @params[in] CPU cores + * @return true : success + * false : failure + ******************************************************************/ +bool Thread::setAffinity(int coreNum) +{ + int ret; + cpu_set_t cpuset; + long nCores = sysconf(_SC_NPROCESSORS_ONLN); + + CPU_ZERO(&cpuset); + CPU_SET(coreNum%nCores, &cpuset); + ret = pthread_setaffinity_np(mThreadId, sizeof(cpu_set_t), &cpuset); + if (ret != 0) + { + return false; + } + return true; +} + +/******************************************************************* + * + * @brief Print the affinity of the thread + * + * @details + * + * Function : printAffinity + * + * Functionality: + * - Prints the cpu core(s) the thread is pinned to + * + * @params[in] void + * @return true : success + * false : failure + ******************************************************************/ +bool Thread::printAffinity() +{ + int ret; + long nCores = sysconf(_SC_NPROCESSORS_ONLN); + + cpu_set_t cpuset; + CPU_ZERO(&cpuset); + + ret = pthread_getaffinity_np(mThreadId, sizeof(cpu_set_t), &cpuset); + if (ret != 0) + return false; + + for (int i = 0; i < nCores; i++) + if (CPU_ISSET(i, &cpuset)) + O1_LOG("CPU %d ", i); + return true; +} diff --git a/src/o1/o1_client/Message.h b/src/o1/Thread.hpp similarity index 70% rename from src/o1/o1_client/Message.h rename to src/o1/Thread.hpp index 80fdc5804..9f9ee514e 100644 --- a/src/o1/o1_client/Message.h +++ b/src/o1/Thread.hpp @@ -1,6 +1,6 @@ /******************************************************************************* ################################################################################ -# Copyright (c) [2020] [HCL Technologies Ltd.] # +# Copyright (c) [2020-2021] [HCL Technologies Ltd.] # # # # Licensed under the Apache License, Version 2.0 (the "License"); # # you may not use this file except in compliance with the License. # @@ -16,34 +16,33 @@ ################################################################################ *******************************************************************************/ -/* This file contains definitions of common message structures */ +/* This file contains class for launching and managing POSIX threads */ -#ifndef __MESSAGE_H__ -#define __MESSAGE_H__ +#ifndef __THREAD_HPP__ +#define __THREAD_HPP__ -#include +#include -typedef enum +class Thread { - RAISE_ALARM, - CLEAR_ALARM, - GET_STARTUP_CONFIG -}MsgAction; + private: + pthread_t mThreadId; + static void* task(void*); -typedef enum -{ - ALARM, - CONFIGURATION -}MsgType; + protected: + virtual bool run() = 0; -typedef struct -{ - MsgType msgType; - MsgAction action; -}MsgHeader; + public: + Thread(); + virtual ~Thread(); + bool start(); + bool stop(); + virtual void cleanUp()=0; + bool setAffinity(int); + bool printAffinity(); + bool join(); +}; -#endif -/********************************************************************** - End of file -**********************************************************************/ + +#endif diff --git a/src/o1/o1_client/TcpClient.c b/src/o1/UnixSocketClient.cpp similarity index 56% rename from src/o1/o1_client/TcpClient.c rename to src/o1/UnixSocketClient.cpp index 0049962b5..bd27dde07 100644 --- a/src/o1/o1_client/TcpClient.c +++ b/src/o1/UnixSocketClient.cpp @@ -1,6 +1,6 @@ /******************************************************************************* ################################################################################ -# Copyright (c) [2020] [HCL Technologies Ltd.] # +# Copyright (c) [2020-2021] [HCL Technologies Ltd.] # # # # Licensed under the Apache License, Version 2.0 (the "License"); # # you may not use this file except in compliance with the License. # @@ -16,7 +16,9 @@ ################################################################################ *******************************************************************************/ -/* This file contains functions to connect to TCP server and send massages */ +/* This file contains functions to connect to unix socket server and send/recv + messages +*/ #include @@ -27,166 +29,162 @@ #include #include #include +#include -#include "TcpClient.h" -#include "GlobalDefs.h" -#include "ssi.h" - -static int s_sock; -static struct sockaddr_in s_serverName; -static uint16_t s_port; -static const char* s_hostName = NULL; +#include "UnixSocketClient.hpp" +#include "GlobalDefs.hpp" /******************************************************************* * - * @brief Initilize the sockadd_in structure + * @brief Constructor * * @details * - * Function : initSockaddr + * Function : UnixSocketClient * * Functionality: - * - Initilizes the sockadd_in structure + * - Constructor intialization * - * @params[in] void - * @return ROK - success - * RFAILED - failure + * @params[in] socket path + * @return None ******************************************************************/ -static uint8_t initSockaddr() +UnixSocketClient::UnixSocketClient(const string& path) + : mSockPath(path) { - struct hostent *hostInfo; - struct sockaddr_in *name = &s_serverName; - bzero(&s_serverName, sizeof(s_serverName)); - name->sin_family = AF_INET; - name->sin_port = htons (s_port); - hostInfo = gethostbyname (s_hostName); - if (hostInfo == NULL) - { - O1_LOG("\nO1 TcpClient : Unknown host %s", s_hostName); - return RFAILED; - } - name->sin_addr = *(struct in_addr *) hostInfo->h_addr; - return ROK; } +/******************************************************************* + * + * @brief Destructor + * + * @details + * + * Function : ~UnixSocketClient + * + * Functionality: + * - Destructor + * + * @params[in] None + * @return None + ******************************************************************/ + UnixSocketClient::~UnixSocketClient() + { + + } /******************************************************************* * - * @brief Open a TCP socket + * @brief Open a Unix socket * * @details * * Function : openSocket * * Functionality: - * - Opens a TCP socket + * - Opens a Unix socket * - * @params[in] hostname, port - * @return ROK - success - * RFAILED - failure + * @params[in] void + * @return O1::SUCCESS - success + * O1::FAILURE - failure ******************************************************************/ -uint8_t openSocket(const char* hostName, const uint16_t port) +uint8_t UnixSocketClient::openSocket() { /* Create the socket. */ - s_port = port; - s_hostName = hostName; - s_sock = socket (PF_INET, SOCK_STREAM, 0); - if (s_sock < 0) + mSock = socket (AF_UNIX, SOCK_STREAM, 0); + if (mSock < 0) { - O1_LOG("\nO1 TcpClient : Error opening socket"); - return RFAILED; + O1_LOG("\nO1 UnixSocketClient : Error opening socket"); + return O1::FAILURE; } - /* Init the sockaddr_in structure */ - if (initSockaddr() == RFAILED) - { - return RFAILED; - } + /* Init the sockaddr_un structure */ + mSockName.sun_family = AF_UNIX; + strcpy(mSockName.sun_path, mSockPath.c_str()); + /* Connect to the server */ - if (0 > connect (s_sock, - (struct sockaddr_in *)&s_serverName , - sizeof (s_serverName))) + if (0 > connect (mSock, + (struct sockaddr *)&mSockName, + sizeof (mSockName))) { - O1_LOG("\nO1 TcpClient : Error connecting"); - return RFAILED; + O1_LOG("\nO1 UnixSocketClient : Error connecting"); + return O1::FAILURE; } - return ROK; + return O1::SUCCESS; } - /******************************************************************* * - * @brief Send message over TCP socket + * @brief Send message over Unix socket * * @details * * Function : sendData * * Functionality: - * - Sends message over TCP socket + * - Sends message over Unix socket * * @params[in] message, size of the message * @return Number of bytes sent * ******************************************************************/ -int sendData(void* data, const int size) +int UnixSocketClient::sendData(void* data, const int size) { - int nbytes = write (s_sock, data, size); + int nbytes = write (mSock, data, size); if (nbytes < 0) { - O1_LOG("\nO1 TcpClient : Error writing. %d bytes sent", nbytes); + O1_LOG("\nO1 UnixSocketClient : Error writing. %d bytes sent", nbytes); } return nbytes; } /******************************************************************* * - * @brief Recieve message over TCP socket + * @brief Recieve message over Unix socket * * @details * * Function : receiveData * * Functionality: - * - Recieves message over TCP socket + * - Recieves message over Unix socket * * @params[in] message, size of the message * @return Number of bytes received * ******************************************************************/ -int receiveData(void* data, const int size) +int UnixSocketClient::receiveData(void* data, const int size) { - int nbytes = read (s_sock, data, size); + int nbytes = read (mSock, data, size); if (nbytes < 0) { - O1_LOG("\nO1 TcpClient : Error reading. %d bytes sent", nbytes); + O1_LOG("\nO1 UnixSocketClient : Error reading. %d bytes sent", nbytes); } return nbytes; } /******************************************************************* * - * @brief Close the TCP socket + * @brief Close the Unix socket * * @details * * Function : closeSocket * * Functionality: - * - Closes the TCP socket + * - Closes the Unix socket * - * @params[in] message, size of the message - * @return ROK - success - * RFAILED - failure + * @params[in] void + * @return O1::SUCCESS - success + * O1::FAILURE - failure ******************************************************************/ -uint8_t closeSocket() +uint8_t UnixSocketClient::closeSocket() { - if( close(s_sock) != 0 ) - return RFAILED; - return ROK; + if( close(mSock) != 0 ) + return O1::FAILURE; + return O1::SUCCESS; } /********************************************************************** diff --git a/src/o1/UnixSocketClient.hpp b/src/o1/UnixSocketClient.hpp new file mode 100644 index 000000000..6256d3830 --- /dev/null +++ b/src/o1/UnixSocketClient.hpp @@ -0,0 +1,54 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2020-2021] [HCL Technologies Ltd.] # +# # +# Licensed under th`e 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. # +################################################################################ +*******************************************************************************/ + +/* This file contains functions to connect to a unix socket server and send/recv + messages +*/ + +#ifndef __UNIX_SOCKET_CLIENT_HPP__ +#define __UNIX_SOCKET_CLIENT_HPP__ + +#include +#include +#include + +using std::string; + +class UnixSocketClient +{ + private: + + int mSock; + string mSockPath; + struct sockaddr_un mSockName; + + public: + UnixSocketClient(const string& path); + ~UnixSocketClient(); + uint8_t openSocket(); + int sendData(void*, const int); + int receiveData(void* data, const int size); + uint8_t closeSocket(); + +}; + +#endif + +/********************************************************************** + End of file +**********************************************************************/ diff --git a/src/o1/TcpServer.cpp b/src/o1/UnixSocketServer.cpp similarity index 57% rename from src/o1/TcpServer.cpp rename to src/o1/UnixSocketServer.cpp index 337387d09..528e0398a 100644 --- a/src/o1/TcpServer.cpp +++ b/src/o1/UnixSocketServer.cpp @@ -1,6 +1,6 @@ /******************************************************************************* ################################################################################ -# Copyright (c) [2020] [HCL Technologies Ltd.] # +# Copyright (c) [2020-2021] [HCL Technologies Ltd.] # # # # Licensed under the Apache License, Version 2.0 (the "License"); # # you may not use this file except in compliance with the License. # @@ -16,15 +16,15 @@ ################################################################################ *******************************************************************************/ -/* This file contains TcpServer class that listens for Netconf Alarm messages - on a TCP socket from ODU. It calls the AlarmManager functions for raising - or clearing the alarms based on the actions received +/* This file contains UnixSocketServer class that listens for Netconf Alarm + messages on a Unix socket from ODU. It calls the AlarmManager functions + for raising or clearing the alarms based on the actions received */ -#include "TcpServer.hpp" +#include "UnixSocketServer.hpp" #include "Alarm.hpp" #include "AlarmManager.hpp" -#include "Config.h" +#include "ConfigInterface.h" #include "GlobalDefs.hpp" #include #include @@ -36,13 +36,49 @@ #include #include #include +#include #include "InitConfig.hpp" + using std::map; using std::pair; -/* Destructor */ -TcpServer::~TcpServer() +/******************************************************************* + * + * @brief Constructor + * + * @details + * + * Function : UnixSocketServer + * + * Functionality: + * - Constructor intialization + * + * @params[in] socket path + * @return None + ******************************************************************/ +UnixSocketServer::UnixSocketServer(const string& sockPath) + : mSockPath(sockPath), + mIsRunning(false) +{ + +} + +/******************************************************************* + * + * @brief Destructor + * + * @details + * + * Function : ~UnixSocketServer + * + * Functionality: + * - Destructor + * + * @params[in] None + * @return None + ******************************************************************/ +UnixSocketServer::~UnixSocketServer() { } @@ -63,7 +99,7 @@ TcpServer::~TcpServer() * @return No. of bytes read * ******************************************************************/ -int TcpServer::readMessage(int fd) +int UnixSocketServer::readMessage(int fd) { AlarmRecord *alrmRec = NULL; char recvBuf[BUFLEN]; @@ -76,23 +112,27 @@ int TcpServer::readMessage(int fd) { MsgHeader *msgHdr = (MsgHeader*)recvBuf; - O1_LOG("\nO1 TcpServer :\nBuf size %ld", sizeof(recvBuf)); - O1_LOG("\nO1 TcpServer :\nMsgType %d",msgHdr->msgType); - O1_LOG("\nO1 TcpServer :\nAction %d",msgHdr->action); + O1_LOG("\nO1 UnixSocketServer :\nMsgType %d",msgHdr->msgType); if ( msgHdr->msgType == ALARM ){ uint16_t alrmId; alrmRec = (AlarmRecord*) recvBuf; - O1_LOG("\nO1 TcpServer :\nAction %d\nalarm ID %s\n%d\n%s\n%d\n%s\n%s\nbytes %d", - alrmRec->msgHeader.action, - alrmRec->alarmId, - alrmRec->perceivedSeverity, - alrmRec->additionalText, - alrmRec->eventType, - alrmRec->specificProblem, - alrmRec->additionalInfo, - nbytes - ); + O1_LOG("\nO1 UnixSocketServer :\n" + "Action %d\n" + "Alarm ID %s\n" + "Severity %d\n" + "Additional Text %s\n" + "Specific Problem %s\n" + "Additional Info %s\n" + "Alarm Raise Time %s\n", + alrmRec->msgHeader.action, + alrmRec->alarmId, + alrmRec->perceivedSeverity, + alrmRec->additionalText, + alrmRec->specificProblem, + alrmRec->additionalInfo, + alrmRec->alarmRaiseTime + ); /*Fill the alarm structure */ sscanf(alrmRec->alarmId,"%hu",&alrmId); @@ -109,41 +149,64 @@ int TcpServer::readMessage(int fd) case RAISE_ALARM: if(AlarmManager::instance().raiseAlarm(alrm)) { - O1_LOG("\nO1 TcpServer : Alarm raised for alarm Id %s", alrmRec->alarmId); + O1_LOG("\nO1 UnixSocketServer : " + "Alarm raised for alarm Id %s", + alrmRec->alarmId); } else { - O1_LOG("\nO1 TcpServer : Error in raising alarm for alrm Id %s", alrmRec->alarmId); + O1_LOG("\nO1 UnixSocketServer : " + "Error in raising alarm for alrm Id %s", + alrmRec->alarmId); } break; case CLEAR_ALARM: if(AlarmManager::instance().clearAlarm(alrm)) { - O1_LOG("\nO1 TcpServer : Alarm cleared for alarm Id %s", alrmRec->alarmId); + O1_LOG("\nO1 UnixSocketServer : " + "Alarm cleared for alarm Id %s", + alrmRec->alarmId); } else { - O1_LOG("\nO1 TcpServer : Error in clearing alarm for alarm Id %s", alrmRec->alarmId); + O1_LOG("\nO1 UnixSocketServer : " + "Error in clearing alarm for alarm Id %s", + alrmRec->alarmId); } break; +#if 0 case GET_STARTUP_CONFIG: { StartupConfig cfg; InitConfig::instance().getCurrInterfaceConfig(cfg); - O1_LOG("\nO1 TcpServer : cfg.DU_IPV4_Addr [%s]", cfg.DU_IPV4_Addr); - O1_LOG("\nO1 TcpServer : cfg.DU_Port [%d]", cfg.DU_Port); - O1_LOG("\nO1 TcpServer : cfg.CU_IPV4_Addr [%s]", cfg.CU_IPV4_Addr); - O1_LOG("\nO1 TcpServer : cfg.CU_Port [%d]", cfg.CU_Port); - O1_LOG("\nO1 TcpServer : cfg.RIC_IPV4_Addr [%s]", cfg.RIC_IPV4_Addr); - O1_LOG("\nO1 TcpServer : cfg.RIC_Port [%d]", cfg.RIC_Port); + O1_LOG("\nO1 UnixSocketServer : " + "cfg.DU_IPV4_Addr [%s]", + cfg.DU_IPV4_Addr); + O1_LOG("\nO1 UnixSocketServer : " + "cfg.DU_Port [%d]", + cfg.DU_Port); + O1_LOG("\nO1 UnixSocketServer : " + "cfg.CU_IPV4_Addr [%s]", + cfg.CU_IPV4_Addr); + O1_LOG("\nO1 UnixSocketServer : " + "cfg.CU_Port [%d]", + cfg.CU_Port); + O1_LOG("\nO1 UnixSocketServer : " + "cfg.RIC_IPV4_Addr [%s]", + cfg.RIC_IPV4_Addr); + O1_LOG("\nO1 UnixSocketServer : " + "cfg.RIC_Port [%d]", + cfg.RIC_Port); if (write (fd, &cfg, sizeof(cfg)) < 0) { - O1_LOG("\nO1 TcpServer : Error sending startup configuration \n"); + O1_LOG("\nO1 UnixSocketServer : " + "Error sending startup configuration \n"); } break; } +#endif default: - O1_LOG("\nO1 TcpServer : No action performed"); + O1_LOG("\nO1 UnixSocketServer : No action performed"); break; } @@ -154,38 +217,46 @@ int TcpServer::readMessage(int fd) /******************************************************************* * - * @brief Open a TCP socket and bind on the port + * @brief Open a Unix socket and bind on the port * * @details * * Function : makeSocket * * Functionality: - * - Opens a TCP socket and bind on the port + * - Opens a Unix socket and bind on the port * * @params[in] void * @return O1:SUCCESS - success * O1:FAILURE - failure ******************************************************************/ -int TcpServer::makeSocket() + +int UnixSocketServer::makeSocket() { - struct sockaddr_in name; + struct sockaddr_un name; /* Create the socket. */ - mSock = socket (PF_INET, SOCK_STREAM, 0); + mSock = socket (AF_UNIX, SOCK_STREAM, 0); if (mSock < 0) { - O1_LOG("\nO1 TcpServer : Socket error"); + O1_LOG("\nO1 UnixSocketServer : Socket error"); return O1::FAILURE; } /* Give the socket a name. */ bzero(&name, sizeof(name)); - name.sin_family = AF_INET; - name.sin_port = htons (mPort); - name.sin_addr.s_addr = htonl (INADDR_ANY); + name.sun_family = AF_UNIX; + + /* Remove the socket file if it already exists */ + if ( unlink(mSockPath.c_str()) == 0) + { + O1_LOG("\nO1 UnixSocketServer : " + "Removing the existing socket path %s", + mSockPath.c_str()); + } + strcpy(name.sun_path, mSockPath.c_str()); if (bind (mSock, (struct sockaddr *) &name, sizeof (name)) < 0) { close(mSock); - O1_LOG("\nO1 TcpServer : Bind error"); + O1_LOG("\nO1 UnixSocketServer : Bind error"); return O1::FAILURE; } return O1::SUCCESS; @@ -194,57 +265,37 @@ int TcpServer::makeSocket() /******************************************************************* * - * @brief Start TCP server in thread - * - * @details - * - * Function : start - * - * Functionality: - * - Start TCP server in thread - * - * @params[in] void - * @return true - success - * false - failure - ******************************************************************/ -bool TcpServer::start() -{ - return (pthread_create(&mThreadId, NULL, task, this) == 0); -} - -/******************************************************************* - * - * @brief A TCP server to handle multiple connection + * @brief A Unix server to handle multiple connection * * @details * * Function : run * * Functionality: - * - A TCP server to handle multiple connection + * - A Unix server to handle multiple connection * Uses select multiplexing * * @params[in] void * @return true - success * false - failure ******************************************************************/ -bool TcpServer::run() +bool UnixSocketServer::run() { fd_set active_fd_set, read_fd_set; int i; - struct sockaddr_in clientName; + struct sockaddr_un clientName; socklen_t size; - bool ret = true;; + mIsRunning = true; /* Create the socket and set it up to accept connections. */ if( makeSocket() == O1::SUCCESS ) { if (listen (mSock, 1) < 0) { - O1_LOG("\nO1 TcpServer : Listen error"); + O1_LOG("\nO1 UnixSocketServer : Listen error"); close(mSock); - ret = false; + mIsRunning = false; } else { @@ -258,9 +309,9 @@ bool TcpServer::run() read_fd_set = active_fd_set; if (select (FD_SETSIZE, &read_fd_set, NULL, NULL, NULL) < 0) { - O1_LOG("\nO1 TcpServer : Select error"); + O1_LOG("\nO1 UnixSocketServer : Select error"); close(mSock); - ret = false; + mIsRunning = false; break; } @@ -278,14 +329,12 @@ bool TcpServer::run() newFd = accept(mSock,(struct sockaddr *) &clientName,&size); if (newFd < 0) { - O1_LOG("\nO1 TcpServer : Accept error"); + O1_LOG("\nO1 UnixSocketServer : Accept error"); close(mSock); - ret = false; + mIsRunning = false; break; } - O1_LOG("\nO1 TcpServer : Connected from host %s, port %hd.\n", - inet_ntoa (clientName.sin_addr), - ntohs (clientName.sin_port)); + O1_LOG("\nO1 UnixSocketServer : Connected from client\n"); FD_SET (newFd, &active_fd_set); } else @@ -304,58 +353,52 @@ bool TcpServer::run() } /* outer if ends */ else { - ret = false; + mIsRunning = false; } - return ret; + return mIsRunning; } /******************************************************************* * - * @brief Static function for launching a TCP server instance - * in a thread + * @brief Clean up open socket * * @details * - * Function : task + * Function : cleanUp * * Functionality: - * - Static function for launching a TCP server instance - * in a thread + * - Performs any clean ups before stopping the thread * - * @params[in] TcpServer instance + * @params[in] void * @return void ******************************************************************/ -void* TcpServer::task(void *args) +void UnixSocketServer::cleanUp(void) { - TcpServer *tcpServer = (TcpServer*)args; - tcpServer->run(); - return NULL; + close(mSock); + O1_LOG("\nO1 UnixSocketServer : Cleaning up Closing socket \n"); } - /******************************************************************* * - * @brief Wait for the thread to complete in the parent process + * @brief Check if the server is running * * @details * - * Function : wait + * Function : isRunning * * Functionality: - * - Waits for the thread to complete in the parent process + * - Returns the running status of the server * * @params[in] void - * @return true : success - * false : failure + * @return true : running + * false: not running ******************************************************************/ -bool TcpServer::wait() +bool UnixSocketServer::isRunning() const { - return (pthread_join(mThreadId,NULL) == 0); + return mIsRunning; } - - /********************************************************************** End of file **********************************************************************/ diff --git a/src/o1/TcpServer.hpp b/src/o1/UnixSocketServer.hpp similarity index 75% rename from src/o1/TcpServer.hpp rename to src/o1/UnixSocketServer.hpp index 862b57eab..cf3c18d27 100644 --- a/src/o1/TcpServer.hpp +++ b/src/o1/UnixSocketServer.hpp @@ -1,6 +1,6 @@ /******************************************************************************* ################################################################################ -# Copyright (c) [2020] [HCL Technologies Ltd.] # +# Copyright (c) [2020-2021] [HCL Technologies Ltd.] # # # # Licensed under the Apache License, Version 2.0 (the "License"); # # you may not use this file except in compliance with the License. # @@ -16,36 +16,38 @@ ################################################################################ *******************************************************************************/ -/* This file contains TcpServer class that listens for Netconf Alarm messages - on a TCP socket from ODU. It calls the AlarmManager functions for raising +/* This file contains UnixSocketServer class that listens for Netconf Alarm messages + on a Unix socket from ODU. It calls the AlarmManager functions for raising or clearing the alarms based on the actions received */ -#ifndef __TCP_SERVER_HPP__ -#define __TCP_SERVER_HPP__ +#ifndef __UNIX_SOCKET_SERVER_HPP__ +#define __UNIX_SOCKET_SERVER_HPP__ #include #include +#include "Thread.hpp" using std::string; #define BUFLEN 512 -class TcpServer +class UnixSocketServer : public Thread { private: - pthread_t mThreadId; int mSock; - const int16_t mPort; + string mSockPath; int readMessage(int); int makeSocket(); + + protected: bool run(); - static void* task(void*); + bool mIsRunning; public: - bool start(); - bool wait(); - TcpServer(const uint16_t port) : mPort(port){}; - ~TcpServer(); + UnixSocketServer(const string& sockPath); + ~UnixSocketServer(); + bool isRunning() const; + virtual void cleanUp(void); }; diff --git a/src/ric_stub/ric_stub.c b/src/ric_stub/ric_stub.c index 90f481c13..bbb4dde76 100644 --- a/src/ric_stub/ric_stub.c +++ b/src/ric_stub/ric_stub.c @@ -23,7 +23,7 @@ #include "du_log.h" #ifdef O1_ENABLE -#include "Config.h" +#include "ConfigInterface.h" #endif #define RIC_ID 1 @@ -51,9 +51,7 @@ #define PLMN_MNC2 0 #ifdef O1_ENABLE - extern StartupConfig g_cfg; - #endif /******************************************************************* @@ -137,10 +135,13 @@ void readRicCfg() DU_LOG("\nINFO --> RIC : Reading RIC configurations"); #ifdef O1_ENABLE - if( getStartupConfig(&g_cfg) != ROK ) + if( getStartupConfigForStub(&g_cfg) != ROK ) { - RETVALUE(RFAILED); + DU_LOG("\nError --> RIC : Could not fetch startup "\ + "configurations from Netconf interface\n"); + exit(1); } + cmInetAddr((S8*)g_cfg.DU_IPV4_Addr, &ipv4_du); cmInetAddr((S8*)g_cfg.RIC_IPV4_Addr, &ipv4_ric);