From: HariomGupta Date: Wed, 30 Jun 2021 06:22:42 +0000 (+0530) Subject: PNF Registration to be sent after odu stack is up X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=commitdiff_plain;h=8752ca5273e2f50ea631f80ee71b18b562e8a0ec;p=o-du%2Fl2.git PNF Registration to be sent after odu stack is up Issue-Id: ODUHIGH-349 Signed-off-by: HariomGupta Change-Id: Icca5b097b02e144339914e49027ca4881856e88f --- diff --git a/Dockerfile b/Dockerfile index 02e0e275a..84b83831c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,18 +1,6 @@ FROM nexus3.o-ran-sc.org:10002/o-ran-sc/bldr-ubuntu18-c-go:1.9.0 # ====================================================================== -# add netconf user -RUN \ - adduser --system netconf && \ - echo "netconf:netconf!" | chpasswd - -# generate ssh keys for netconf user -RUN \ - 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 - ADD . /opt/o-du-l2 WORKDIR /opt/o-du-l2 @@ -24,10 +12,13 @@ RUN cd build/odu && make clean_odu odu MACHINE=BIT64 MODE=FDD RUN cd build/odu && make clean_odu odu MACHINE=BIT64 MODE=TDD #CMD /opt/o-du-l2/bin/odu/odu +# add netconf user +RUN cd build/scripts && /bin/bash add_netconf_user.sh + #cleanup netconf folder and install libraries RUN cd build/scripts && /bin/bash install_lib_O1.sh -c -# Install the data models based on the ODU yang model -RUN /usr/local/bin/sysrepoctl -i build/yang/o-ran-sc-odu-alarm-v1.yang +# Install yang models and load initial configuration +RUN cd build/scripts && /bin/bash load_yang.sh RUN cd build/odu && make clean_odu odu MACHINE=BIT64 MODE=FDD O1_ENABLE=YES diff --git a/build/config/netconfConfig.json b/build/config/netconfConfig.json index 272f6869e..238d962ed 100644 --- a/build/config/netconfConfig.json +++ b/build/config/netconfConfig.json @@ -2,7 +2,7 @@ "NetconfServer": { "MacAddress": "02:42:f7:d4:62:ce", "NetconfServerIpv4": "10.0.2.132", - "NetconfServerIpv6": "0:0:0:0:0:ffff:a0a:013", + "NetconfServerIpv6": "2002:c0a8:3865::", "NetconfPort": "830", "NetconfUsername": "netconf", "NetconfPassword": "netconf!" diff --git a/build/config/netconf_server_ipv6.xml b/build/config/netconf_server_ipv6.xml new file mode 100644 index 000000000..d0b6c5704 --- /dev/null +++ b/build/config/netconf_server_ipv6.xml @@ -0,0 +1,35 @@ + + + + default-ssh + + + :: + + 1 + 10 + 5 + + + + + + default-key + + genkey + + + + + + + + interactive + + + + + + + + diff --git a/build/odu/makefile b/build/odu/makefile index 3ca892a59..868696e67 100644 --- a/build/odu/makefile +++ b/build/odu/makefile @@ -211,8 +211,8 @@ du: $(Q)$(MAKE) -j -f $(COM_BUILD_DIR)/mt.mak OBJ_DIR=$(OBJ_ROOT)/odu LIB_DIR=$(LIB_ROOT)/odu LOG_DIR=$(LOG_ROOT)/odu CC='$(CC1)' $(Q)$(MAKE) -j -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.mak OBJ_DIR=$(OBJ_ROOT)/odu LIB_DIR=$(LIB_ROOT)/odu LOG_DIR=$(LOG_ROOT)/odu CC='$(CCPP1)' - $(Q)$(MAKE) -f $(COM_BUILD_DIR)/ves.mak OBJ_DIR=$(OBJ_ROOT)/odu LIB_DIR=$(LIB_ROOT)/odu LOG_DIR=$(LOG_ROOT)/odu CC='$(CCPP1)' + $(Q)$(MAKE) -j -f $(COM_BUILD_DIR)/o1.mak OBJ_DIR=$(OBJ_ROOT)/odu LIB_DIR=$(LIB_ROOT)/odu LOG_DIR=$(LOG_ROOT)/odu CC='$(CCPP1)' + $(Q)$(MAKE) -j -f $(COM_BUILD_DIR)/ves.mak OBJ_DIR=$(OBJ_ROOT)/odu LIB_DIR=$(LIB_ROOT)/odu LOG_DIR=$(LOG_ROOT)/odu CC='$(CCPP1)' endif link_du: du @@ -232,8 +232,8 @@ clean_odu: $(Q)$(MAKE) -j -f $(COM_BUILD_DIR)/mt.mak clean OBJ_DIR=$(OBJ_ROOT)/odu LIB_DIR=$(LIB_ROOT)/odu LOG_DIR=$(LOG_ROOT)/odu CC='$(CC1)' $(Q)$(MAKE) -j -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.mak clean OBJ_DIR=$(OBJ_ROOT)/odu LIB_DIR=$(LIB_ROOT)/odu LOG_DIR=$(LOG_ROOT)/odu CC='$(CCPP1)' - $(Q)$(MAKE) -f $(COM_BUILD_DIR)/ves.mak clean OBJ_DIR=$(OBJ_ROOT)/odu LIB_DIR=$(LIB_ROOT)/odu LOG_DIR=$(LOG_ROOT)/odu CC='$(CCPP1)' + $(Q)$(MAKE) -j -f $(COM_BUILD_DIR)/o1.mak clean OBJ_DIR=$(OBJ_ROOT)/odu LIB_DIR=$(LIB_ROOT)/odu LOG_DIR=$(LOG_ROOT)/odu CC='$(CCPP1)' + $(Q)$(MAKE) -j -f $(COM_BUILD_DIR)/ves.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/* @@ -257,8 +257,8 @@ cu: $(Q)$(MAKE) -j -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) -j -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.mak OBJ_DIR=$(OBJ_ROOT)/cu_stub LIB_DIR=$(LIB_ROOT)/cu_stub LOG_DIR=$(LOG_ROOT)/cu_stub CC='$(CCPP1)' - $(Q)$(MAKE) -f $(COM_BUILD_DIR)/ves.mak OBJ_DIR=$(OBJ_ROOT)/cu_stub LIB_DIR=$(LIB_ROOT)/cu_stub LOG_DIR=$(LOG_ROOT)/cu_stub CC='$(CCPP1)' + $(Q)$(MAKE) -j -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)' + $(Q)$(MAKE) -j -f $(COM_BUILD_DIR)/ves.mak OBJ_DIR=$(OBJ_ROOT)/cu_stub LIB_DIR=$(LIB_ROOT)/cu_stub LOG_DIR=$(LOG_ROOT)/cu_stub CC='$(CCPP1)' endif clean_cu: @@ -269,8 +269,8 @@ clean_cu: $(Q)$(MAKE) -j -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) -j -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.mak clean OBJ_DIR=$(OBJ_ROOT)/cu_stub LIB_DIR=$(LIB_ROOT)/cu_stub LOG_DIR=$(LOG_ROOT)/cu_stub CC='$(CCPP1)' - $(Q)$(MAKE) -f $(COM_BUILD_DIR)/ves.mak clean OBJ_DIR=$(OBJ_ROOT)/cu_stub LIB_DIR=$(LIB_ROOT)/cu_stub LOG_DIR=$(LOG_ROOT)/cu_stub CC='$(CCPP1)' + $(Q)$(MAKE) -j -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)' + $(Q)$(MAKE) -j -f $(COM_BUILD_DIR)/ves.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/* @@ -293,8 +293,8 @@ ric: $(Q)$(MAKE) -j -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) -j -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.mak OBJ_DIR=$(OBJ_ROOT)/ric_stub LIB_DIR=$(LIB_ROOT)/ric_stub LOG_DIR=$(LOG_ROOT)/ric_stub CC='$(CCPP1)' - $(Q)$(MAKE) -f $(COM_BUILD_DIR)/ves.mak OBJ_DIR=$(OBJ_ROOT)/ric_stub LIB_DIR=$(LIB_ROOT)/ric_stub LOG_DIR=$(LOG_ROOT)/ric_stub CC='$(CCPP1)' + $(Q)$(MAKE) -j -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)' + $(Q)$(MAKE) -j -f $(COM_BUILD_DIR)/ves.mak OBJ_DIR=$(OBJ_ROOT)/ric_stub LIB_DIR=$(LIB_ROOT)/ric_stub LOG_DIR=$(LOG_ROOT)/ric_stub CC='$(CCPP1)' endif clean_ric: @@ -305,8 +305,8 @@ clean_ric: $(Q)$(MAKE) -j -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) -j -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.mak clean OBJ_DIR=$(OBJ_ROOT)/ric_stub LIB_DIR=$(LIB_ROOT)/ric_stub LOG_DIR=$(LOG_ROOT)/ric_stub CC='$(CCPP1)' - $(Q)$(MAKE) -f $(COM_BUILD_DIR)/ves.mak clean OBJ_DIR=$(OBJ_ROOT)/ric_stub LIB_DIR=$(LIB_ROOT)/ric_stub LOG_DIR=$(LOG_ROOT)/ric_stub CC='$(CCPP1)' + $(Q)$(MAKE) -j -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)' + $(Q)$(MAKE) -j -f $(COM_BUILD_DIR)/ves.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/scripts/add_netconf_user.sh b/build/scripts/add_netconf_user.sh new file mode 100755 index 000000000..d0ea1fb75 --- /dev/null +++ b/build/scripts/add_netconf_user.sh @@ -0,0 +1,29 @@ +################################################################################ +# 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 script will add new netconf user +#!/bin/bash + +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 + +################################################################################ +# End of file # +################################################################################ diff --git a/build/scripts/load_yang.sh b/build/scripts/load_yang.sh new file mode 100755 index 000000000..d837210c6 --- /dev/null +++ b/build/scripts/load_yang.sh @@ -0,0 +1,39 @@ +################################################################################ +# 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 script is used to install yang module and load initial configuration +#!/bin/bash + + +CURRENT_DIR=$PWD +ROOT_DIR=$CURRENT_DIR/../../ + +#load yand models +echo "### loading yang model ###" +sysrepoctl -i $ROOT_DIR/build/yang/o-ran-sc-odu-alarm-v1.yang +sysrepoctl -i $ROOT_DIR/build/yang/o-ran-sc-du-hello-world.yang +sysrepoctl -i $ROOT_DIR/build/yang/o-ran-sc-odu-interface-v1.yang +echo "### loading yang model Done###" + +#load initial configuration +echo "### loading initial configuration ###" +sysrepocfg --import=$ROOT_DIR/bin/odu/config/startup_config.xml -v 3 --datastore running --module o-ran-sc-odu-interface-v1 +sysrepocfg --import=$ROOT_DIR/bin/odu/config/nacm_config.xml -v 3 --datastore running --module ietf-netconf-acm +sysrepocfg --import=$ROOT_DIR/bin/odu/config/netconf_server_ipv6.xml -v 3 --datastore running --module ietf-netconf-server +echo "### loading initial configuration done ###" + +################################################################################ +# End of file # +################################################################################ diff --git a/build/scripts/troubleshoot_netconf.sh b/build/scripts/troubleshoot_netconf.sh new file mode 100755 index 000000000..08e6805cb --- /dev/null +++ b/build/scripts/troubleshoot_netconf.sh @@ -0,0 +1,33 @@ +################################################################################ +# 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 script is used to clean-up sysrepo databas +#!/bin/bash + +CURRENT_DIR=$PWD +ROOT_DIR=$CURRENT_DIR/../.. + +if [ "$1" = "cleanup" ]; then + kill -9 `pidof netopeer2-server` + cd $ROOT_DIR/build/netconf/sysrepo/build/ + make sr_clean + cd $ROOT_DIR/build/netconf/Netopeer2/build/ + make install + cd $CURRENT_DIR +fi + +################################################################################ +# End of file # +################################################################################ diff --git a/docs/ODU-O1-Arch.jpg b/docs/ODU-O1-Arch.jpg index 7c5c75776..234cdd1ea 100644 Binary files a/docs/ODU-O1-Arch.jpg and b/docs/ODU-O1-Arch.jpg differ diff --git a/docs/README b/docs/README index 9eb9fe7b4..741ec5e3b 100644 --- a/docs/README +++ b/docs/README @@ -37,58 +37,31 @@ C. Pre-requisite for O1 Interface (Required only if run with O1 interface enable ----------------------------------------------------------------------------------- 1. Setup netconf server - Create new netconf user (login with 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 - Install netconf packages. - $cd l2/build/scripts - $chmod +x install_lib_O1.sh - $ ./install_lib_O1.sh -c - -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 - $sysrepoctl -i o-ran-sc-du-hello-world.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 - -5. Configure the netconf server details for VES PNF Event - - $cd l2/build/config + a. Add new netconf user (login with root user or use sudo and run following script) + $cd l2/build/scripts + $sudo ./add_netconf_user.sh - Open the netconfConfig.json and edit the desired MAC address, IP, Port, Username and Password for VES PNF Registration. + b. Install netconf packages. + $chmod +x install_lib_O1.sh + $sudo ./install_lib_O1.sh -c -6. Configure the VES server details to send VES Events +2. Update the configuration according to your setup. $cd l2/build/config - Open the vesConfig.json and edit the desired IP, Port, Username and Password to send VES Event. + a. Open the startup_config.xml and edit the desired IP and Port for CU, DU and RIC. + b. Open the nacm_config.xml and edit the desired user name to provide the access to that user. + c. Open the netconf_server_ipv6.xml and edit the desired netconf server configuration. + d. Open the vesConfig.json and edit the details of VES collector. + e. Open the netconfConfig.json and edit the details of Netopeer server. + f. Install the yang modules and load initial configuration -7. Configure the nacm module to provide access to new user - - $cd l2/build/config - - Open the nacm_config.xml and edit the desired user-name to provide the access to that user. - - $sysrepocfg --import=nacm_config.xml --datastore running --module ietf-netconf-acm + $cd l2/build/scripts + $sudo ./load_yang.sh +3. Start Netopeer2-server: + $cd l2/build/scripts + $sudo ./netopeer-server.sh start D. How to Clean and Build: @@ -175,7 +148,7 @@ F. How to execute: b. ifconfig :CU_STUB "192.168.130.82" c. ifconfig :RIC_STUB "192.168.130.80" -PS: If O1 interface is enabled, IP should match those configured in step C.4. +PS: If O1 interface is enabled, IP should match those configured in step C.2.a. 2. Execute CU Stub: a. CU execution folder: @@ -305,3 +278,11 @@ H. How to execute the Health Check : get alarm-list The XML output is a list of active alarms in the O-DU High system. + +G. Troubleshooting Netconf server issues +---------------------------------------- + In case the Netconf server and sysrepo breaks down, run the following steps: + + $cd l2/build/scripts + $sudo ./troubleshoot_netconf.sh cleanup + execute section C.2.f, C.3 again diff --git a/docs/installation-guide.rst b/docs/installation-guide.rst index e8c005b0a..1c998e9a7 100644 --- a/docs/installation-guide.rst +++ b/docs/installation-guide.rst @@ -112,84 +112,50 @@ Cloning code Setting up Netconf server ------------------------- - 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/scripts - | sudo ./install_lib_O1.sh -c - -- Start Netopeer2-server: - - - Ubuntu : - | cd /l2/build/scripts - | sudo ./netopeer-server.sh start + Following steps are required to compile and run ODU with O1 interface enabled. + This requires SMO components (OAM and VES collector) to be running. - Create a new netconf user - - Switch to root user and run following commands - - - Ubuntu : - - | 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 - -- Install the YANG modules + Switch to root user or use sudo and run following commands - Ubuntu : + | cd /l2/build/scripts + | sudo ./add_netconf_user.sh + +- Install Netconf libraries: - | cd /l2/build/yang - | sysrepoctl -i ./yang/o-ran-sc-odu-alarm-v1.yang - | sysrepoctl -i ./yang/o-ran-sc-odu-interface-v1.yang - | sysrepoctl -i ./yang/o-ran-sc-du-hello-world.yang + libssh, libyang, libnetconf2, sysrepo, netopeer2 -- Configure the startup IP and Port configurations for DU, CU and RIC + Script is provided in the following folder to install these libraries - Ubuntu : + | cd /l2/build/scripts + | sudo ./install_lib_O1.sh -c - | 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 +- Install the YANG modules and load initial configuration -- Configure the netconf server details for VES PNF Event + - Navigate to config folder and update the desired initial configuration - Ubuntu : + | cd /l2/build/config - | cd /l2/build/config - | - | Open the netconfConfig.json and edit the desired MAC address, IP, Port, Username and Password for VES PNF Registration. - -- Configure the VES server details to send VES Events + | Open the startup_config.xml and edit the desired IP and Port for CU, DU and RIC. + | Open the nacm_config.xml and edit the desired user name to provide the access to that user. + | Open the netconf_server_ipv6.xml and edit the desired netconf server configuration. + | Open the vesConfig.json and edit the details of VES collector. + | Open the netconfConfig.json and edit the details of Netopeer server. + | Install the yang modules and load initial configuration. - Ubuntu : + | cd /l2/build/scripts + | sudo ./load_yang.sh - | cd /l2/build/config - | - | Open the vesConfig.json and edit the desired IP, Port, Username and Password to send VES Event. - -- Configure the nacm module to provide access to new user +- Start Netopeer2-server: - Ubuntu : - - | cd /l2/build/config - | - | Open the nacm_config.xml and edit the desired user-name to provide the access to that user. - | - | $sysrepocfg --import=nacm_config.xml --datastore running --module ietf-netconf-acm + | cd /l2/build/scripts + | sudo ./netopeer-server.sh start Compilation diff --git a/docs/overview.rst b/docs/overview.rst index 371aab8a1..bed3972c0 100644 --- a/docs/overview.rst +++ b/docs/overview.rst @@ -111,14 +111,16 @@ As shown in figure 2 the O1 module runs as a thread in O-DU High. Alarm communic O1 architecture has following components: -- Session Handler: Subscribe to Netconf YANG modules and events. Register callback handler methods. +- Netconf Session Handler: Subscribe to Netconf YANG modules and events. Register callback handler methods. -- Alarm Manager: Stores and manages(add/updated/delete) alarms. +- VES Agent : Sends the VES events to SMO -- Unix socket server: Receives the alarm messages sent from O-DU High thread over Unix socket. +- Alarm Manager: Stores and manages(add/updated/delete) alarms. - Alarm Interface : Provides an interface to O-DU High threads for sending the alarm messages to O1 module over Unix socket. +- Config Interface : Interface to handle the configurations sent from SMO to the stack + - Netopeer server: Serves the northbound SMO/OAM Netconf requests. diff --git a/src/du_app/du_mgr_main.c b/src/du_app/du_mgr_main.c index d4988301c..14c810f0b 100644 --- a/src/du_app/du_mgr_main.c +++ b/src/du_app/du_mgr_main.c @@ -563,7 +563,13 @@ uint8_t tst(void) //Read all the configs from du_utils.c into duCfgParams duReadCfg(); +#ifdef O1_ENABLE + //Send VES PNF registration message to SMO + sendPnfRegistration(); +#endif + return ROK; + }/* end of main()*/ /********************************************************************** diff --git a/src/o1/ConfigInterface.cpp b/src/o1/ConfigInterface.cpp index 76c584de3..161d6caab 100644 --- a/src/o1/ConfigInterface.cpp +++ b/src/o1/ConfigInterface.cpp @@ -88,35 +88,6 @@ uint8_t getStartupConfig(StartupConfig *cfg) ******************************************************************/ 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() ) { @@ -166,7 +137,7 @@ uint8_t getStartupConfigForStub(StartupConfig *cfg) bool setCellOpState(uint16_t cellId, OpState opState, CellState cellState) { O1_LOG("\nO1 ConfigInterface: Setting cellId = %d, opState=%d, \ -cellState=%d\n", cellId, opState, cellState); +cellState=%d", cellId, opState, cellState); return NrCellList::instance().setCellOpState(cellId, opState, \ cellState); } diff --git a/src/o1/NrCellCb.cpp b/src/o1/NrCellCb.cpp index e97358b49..4d7365d74 100644 --- a/src/o1/NrCellCb.cpp +++ b/src/o1/NrCellCb.cpp @@ -54,7 +54,7 @@ int NrCellCb::oper_get_items(sysrepo::S_Session session, \ libyang::S_Data_Node &parent, \ void *private_data) { - O1_LOG("O1 NrCellCb : Callback called for path=%s on get request", path); + O1_LOG("\nO1 NrCellCb : Callback called for path=%s on get request", path); libyang::S_Context ctx = session->get_context(); libyang::S_Module mod = ctx->get_module(module_name); @@ -76,7 +76,7 @@ int NrCellCb::oper_get_items(sysrepo::S_Session session, \ std::map::const_iterator it; for(it = cellOpStateMap.begin(); it !=cellOpStateMap.end(); it++) { - O1_LOG("\nO1 NrCellCb : cellId = %d, opState=%d, cellState=%d\n", \ + O1_LOG("\nO1 NrCellCb : cellId = %d, opState=%d, cellState=%d", \ it->first, (int) it->second.getOpState(), (int) it->second.getCellState()); name.reset(new libyang::Data_Node(connection, mod, "name", \ to_string(it->first).c_str())); @@ -109,31 +109,31 @@ void NrCellCb::printChange(sysrepo::S_Change change) { switch(change->oper()) { case SR_OP_CREATED: if (nullptr != change->new_val()) { - O1_LOG("O1 NrCellCb : CREATED: %s", \ + O1_LOG("\nO1 NrCellCb : CREATED: %s", \ change->new_val()->to_string().c_str()); } break; case SR_OP_DELETED: if (nullptr != change->old_val()) { - O1_LOG("O1 NrCellCb : DELETED: %s", \ + O1_LOG("\nO1 NrCellCb : DELETED: %s", \ change->old_val()->to_string().c_str()); } break; case SR_OP_MODIFIED: if (nullptr != change->old_val() && nullptr != change->new_val()) { - O1_LOG("O1 NrCellCb : MODIFIED: old value %s :new value %s", \ + O1_LOG("\nO1 NrCellCb : MODIFIED: old value %s :new value %s", \ change->old_val()->to_string().c_str(), \ change->new_val()->to_string().c_str()); } break; case SR_OP_MOVED: if (nullptr != change->old_val() && nullptr != change->new_val()) { - O1_LOG("O1 NrCellCb : MOVED: %s :after %s ", \ + O1_LOG("\nO1 NrCellCb : MOVED: %s :after %s ", \ change->new_val()->xpath(), \ change->old_val()->xpath()); } else if (nullptr != change->new_val()) { - O1_LOG("O1 NrCellCb : MOVED: %s : first\n", \ + O1_LOG("\nO1 NrCellCb : MOVED: %s : first", \ change->new_val()->xpath()); } break; @@ -199,7 +199,7 @@ int NrCellCb::module_change(sysrepo::S_Session sess, \ char change_path[MAX_LEN]; try { - O1_LOG("O1 NrCellCb : Notification %s\n", evToStr(event)); + O1_LOG("\nO1 NrCellCb : Notification %s", evToStr(event)); if (SR_EV_CHANGE == event) { NrCellList & cellList = NrCellList::instance(); @@ -212,15 +212,15 @@ int NrCellCb::module_change(sysrepo::S_Session sess, \ //printChange(change); //enable only for debugging if(nullptr != change->new_val()) { - O1_LOG("O1 NrCellCb : Parameter value has been \ -changed val=%s\n", change->new_val()->val_to_string().c_str()); + O1_LOG("\nO1 NrCellCb : Parameter value has been \ +changed val=%s", change->new_val()->val_to_string().c_str()); std::map::const_iterator it; for(it = cellOpStateMap.begin(); it !=cellOpStateMap.end(); it++) { stringstream xpath; xpath << CELL_STATE_MODULE_PATH << "/du-to-ru-connection[name='" \ << it->first << "']/administrative-state"; - O1_LOG("O1 NrCellCb : created xpath = %s", \ + O1_LOG("\nO1 NrCellCb : created xpath = %s", \ xpath.str().c_str()); if((change->new_val()->to_string().find(xpath.str().c_str()) != \ @@ -229,11 +229,11 @@ changed val=%s\n", change->new_val()->val_to_string().c_str()); printChange(change); string val = change->new_val()->val_to_string(); AdminState newVal = cellInfo.adminStateToEnum(val); - O1_LOG("O1 NrCellCb : Update admin state \ -cellId =%d with admin-state value=%s\n", it->first, val.c_str()); + O1_LOG("\nO1 NrCellCb : Update admin state \ +cellId =%d with admin-state value=%s", it->first, val.c_str()); if(!setAdminState(it->first, newVal)) { - O1_LOG("O1 NrCellCb : Could not change \ -parameter value =%s\n", change->new_val()->val_to_string().c_str()); + O1_LOG("\nO1 NrCellCb : Could not change \ +parameter value =%s", change->new_val()->val_to_string().c_str()); return SR_ERR_INTERNAL; } } @@ -243,7 +243,7 @@ parameter value =%s\n", change->new_val()->val_to_string().c_str()); }//if evToStr(event) check } catch( const std::exception& e ) { - O1_LOG("exception : %s\n", e.what()); + O1_LOG("\nO1 NrCellCb exception : %s\n", e.what()); } return SR_ERR_OK; } @@ -287,4 +287,3 @@ bool NrCellCb::setAdminState(uint16_t cellId, AdminState newAdminState) /********************************************************************** End of file **********************************************************************/ - diff --git a/src/o1/NrCellInfo.cpp b/src/o1/NrCellInfo.cpp index 6fc55161b..4c9aef85b 100644 --- a/src/o1/NrCellInfo.cpp +++ b/src/o1/NrCellInfo.cpp @@ -48,7 +48,7 @@ AdminState NrCellInfo::adminStateToEnum(string val) else if(val == "SHUTTING_DOWN") ret = SHUTTING_DOWN; else - O1_LOG("O1 NrCellInfo : %s admin state not handled\n", \ + O1_LOG("\nO1 NrCellInfo : %s admin state not handled", \ val.c_str()); return ret; @@ -86,7 +86,7 @@ string NrCellInfo::enumToCellStateString(CellState val) ret = "IDLE"; break; default : - O1_LOG("O1 NrCellInfo : %d cell state not handled\n", val); + O1_LOG("\nO1 NrCellInfo : %d cell state not handled", val); } return ret; @@ -120,7 +120,7 @@ string NrCellInfo::enumToOperationalStateString(OpState val) ret = "ENABLED"; break; default : - O1_LOG("O1 NrCellInfo : %d operational state not handled\n", val); + O1_LOG("\nO1 NrCellInfo : %d operational state not handled", val); } return ret; diff --git a/src/o1/NrCellList.cpp b/src/o1/NrCellList.cpp index 9ea92e08f..eec8b0b30 100644 --- a/src/o1/NrCellList.cpp +++ b/src/o1/NrCellList.cpp @@ -49,7 +49,7 @@ bool NrCellList::setCellOpState(uint16_t cellId, \ CellState cellState) { O1_LOG("\nO1 NrCellList : Setting cellId = %d, opState=%d, \ -cellState=%d\n", cellId, opState, cellState); +cellState=%d", cellId, opState, cellState); NrCellInfo cellInfo ; cellInfo.setCellId( cellId); cellInfo.setOpState(opState); diff --git a/src/o1/O1App.cpp b/src/o1/O1App.cpp index 05bdf7ed9..5b1382160 100644 --- a/src/o1/O1App.cpp +++ b/src/o1/O1App.cpp @@ -29,6 +29,8 @@ #include "VesUtils.hpp" #include "VesEventHandler.hpp" + + /******************************************************************* * * @brief Constructor @@ -89,16 +91,12 @@ O1App::~O1App() bool O1App::run() { - + const int SLEEP_INTERVAL = 2; + const int DEFAUL_CELL_ID = 1; SessionHandler sessHdlr; - /*send ves PNF registration request*/ - VesEventHandler vesEvtHdr; - O1_LOG("\nO1 O1App : Sending VES Event"); - if(!vesEvtHdr.send(VesEventType::PNF_REGISTRATION)) - { - O1_LOG("\nO1 O1App : Could not send VES Request"); - return false; - } + + /*setting default cell state disabled*/ + setCellOpState(DEFAUL_CELL_ID, DISABLED, INACTIVE); /* Start Netconf session and subscribe to yang modules */ try @@ -121,19 +119,19 @@ bool O1App::run() if(mUxSocketServer.setAffinity(O1::CPU_CORE)) { - O1_LOG("\nO1 O1App : CPU affinity set " ); + O1_LOG("\nO1 O1App : CPU affinity set for UnixSocketServer thread to " ); mUxSocketServer.printAffinity(); } - sleep(2); + sleep(SLEEP_INTERVAL); if( mUxSocketServer.isRunning() ) { mStartupStatus = true; - O1_LOG("\nO1 O1App : Unix Socket server started\n"); + O1_LOG("\nO1 O1App : Unix Socket server started"); } else { - O1_LOG("\nO1 O1App : Unix Socket server failed to start\n"); + O1_LOG("\nO1 O1App : Unix Socket server failed to start"); return false; } /* Wait for the Unix Socket Server thread to end*/ @@ -141,7 +139,7 @@ bool O1App::run() } else { - O1_LOG("\nO1 O1App : Unix Socket server failed to start\n"); + O1_LOG("\nO1 O1App : Unix Socket server failed to start"); return false; } return true; diff --git a/src/o1/O1App.hpp b/src/o1/O1App.hpp index b1653d3f3..56eb02a0a 100644 --- a/src/o1/O1App.hpp +++ b/src/o1/O1App.hpp @@ -38,11 +38,11 @@ class O1App : public Singleton, public Thread UnixSocketServer mUxSocketServer; protected: + O1App(); + ~O1App(); bool run(); public: - O1App(); - ~O1App(); bool getStartupStatus()const; void cleanUp(void); }; diff --git a/src/o1/O1Interface.cpp b/src/o1/O1Interface.cpp index c3135b53a..c0c552a38 100644 --- a/src/o1/O1Interface.cpp +++ b/src/o1/O1Interface.cpp @@ -21,6 +21,8 @@ #include "O1Interface.h" #include "O1App.hpp" #include "GlobalDefs.hpp" +#include "PnfRegistrationThread.hpp" + #include #include @@ -43,7 +45,11 @@ ******************************************************************/ int static check_O1_module_status(void){ - for( int i = 0; i < 5 ; i++) + + const int N_RETRY = 5; + const int RETRY_DELAY = 1; + + for( int i = 0; i < N_RETRY; i++) { if( O1App::instance().getStartupStatus() == true) { @@ -51,7 +57,7 @@ int static check_O1_module_status(void){ } else { - sleep(1); + sleep(RETRY_DELAY); } } @@ -80,18 +86,44 @@ int start_O1_module(void) { if(O1App::instance().start() == false){ - O1_LOG("\nO1 O1Interface : Failed to start"); + O1_LOG("\nO1 O1Interface : Failed to start"); return O1::FAILURE; } if(O1App::instance().setAffinity(O1::CPU_CORE)) { - O1_LOG("\nO1 O1Interface : CPU affinity set " ); + O1_LOG("\nO1 O1Interface : CPU affinity set for O1App thread to" ); O1App::instance().printAffinity(); } return check_O1_module_status(); } +/******************************************************************* + * + * @brief Send VES PNF Registration Request + * + * @details + * + * Function : sendPnfRegistration + * + * Functionality: + * - Create a thread and send VES PNF Registration Request + * + * + * @params[in] void + * @return void + ******************************************************************/ + +void sendPnfRegistration(void) +{ + PnfRegistrationThread::instance().start(); + if(PnfRegistrationThread::instance().setAffinity(O1::CPU_CORE)) + { + O1_LOG("\nO1 O1Interface : CPU affinity set for PnfRegistration thread to " ); + PnfRegistrationThread::instance().printAffinity(); + } +} + /********************************************************************** End of file diff --git a/src/o1/O1Interface.h b/src/o1/O1Interface.h index cff161da6..e4e04d8ef 100644 --- a/src/o1/O1Interface.h +++ b/src/o1/O1Interface.h @@ -26,6 +26,7 @@ extern "C" { #endif int start_O1_module(void); +void sendPnfRegistration(void); #ifdef __cplusplus } diff --git a/src/o1/ves/HttpClient.cpp b/src/o1/ves/HttpClient.cpp index 4fc675cb7..261f5aed8 100644 --- a/src/o1/ves/HttpClient.cpp +++ b/src/o1/ves/HttpClient.cpp @@ -89,28 +89,28 @@ bool HttpClient::prepareHttpHeader(struct curl_slist *header, CURL *curl) if(!setUserPassword(curl)) { - O1_LOG("O1 VES : unable to set user:password \n"); + O1_LOG("\nO1 HttpClient : unable to set user:password"); curl_slist_free_all(header); } setCurlOptions(curl); header = curl_slist_append(header, "Content-Type: application/json"); if(!header) { - O1_LOG("O1 VES : curl_slist_append failed\n"); + O1_LOG("\nO1 HttpClient : curl_slist_append failed"); curl_easy_cleanup(curl); return false; } header = curl_slist_append(header, "Accept: application/json"); if(!header) { - O1_LOG("O1 VES : curl_slist_append failed\n"); + O1_LOG("\nO1 HttpClient : curl_slist_append failed"); curl_easy_cleanup(curl); return false; } curl_easy_setopt(curl, CURLOPT_HTTPHEADER, header); if(!createUrl(curl)) { - O1_LOG("O1 VES : could not create URL\n"); + O1_LOG("\nO1 HttpClient : could not create URL"); return false; } return true; @@ -142,7 +142,7 @@ bool HttpClient::setUserPassword(CURL *curl) if((mServerUsername.c_str()) && (mServerPassword.c_str())) { asprintf(&credentials, "%s:%s", mServerUsername.c_str(), mServerPassword.c_str()); if(credentials == 0) { - O1_LOG("O1 VES : credentials is blank\n"); + O1_LOG("\nO1 HttpClient : Credential is blank"); curl_easy_cleanup(curl); return false; } @@ -181,7 +181,7 @@ bool HttpClient::createUrl(CURL *curl) if((mServerIp.c_str()) && (mServerPort.c_str())) { oss <<"https://"<res, mem->size + realsize + 1); if(ptr == NULL) { - O1_LOG("O1 VES : realloc failed"); + O1_LOG("\nO1 HttpClient : realloc failed"); return 0; } diff --git a/src/o1/ves/JsonHelper.cpp b/src/o1/ves/JsonHelper.cpp index 5eeb39f26..db8627511 100644 --- a/src/o1/ves/JsonHelper.cpp +++ b/src/o1/ves/JsonHelper.cpp @@ -223,15 +223,15 @@ const char *JsonHelper::getError() * * ****************************************************************/ -char* JsonHelper::getValue(cJSON *json, const char *node) +string JsonHelper::getValue(cJSON *json, const char *node) { cJSON *object; - char * value = NULL; + string value = ""; object = cJSON_GetObjectItem(json, node); if(object) { value = object->valuestring; - O1_LOG("O1 VES : [ %s] : [%s]\n",node, value ); + O1_LOG("O1 VES : [ %s] : [%s]\n",node, value.c_str() ); } else O1_LOG("O1 VES : node [ %s] not found\n",node); @@ -283,16 +283,16 @@ cJSON* JsonHelper::read(const char * fileName) std::fstream fs(fileName, std::ios::in | std::ios::binary); if (!fs) { - O1_LOG("O1 VES : json can NOT open file %s\n", fileName); - return NULL; + O1_LOG("\nO1 JsonHelper : Cannot open file %s", fileName); + return NULL; } std::stringstream iss; iss << fs.rdbuf(); - cJSON *json = cJSON_Parse(iss.str().c_str()); - return json; + cJSON *json = cJSON_Parse(iss.str().c_str()); + return json; } /********************************************************************** diff --git a/src/o1/ves/JsonHelper.hpp b/src/o1/ves/JsonHelper.hpp index 154677619..6509ddaf5 100644 --- a/src/o1/ves/JsonHelper.hpp +++ b/src/o1/ves/JsonHelper.hpp @@ -44,7 +44,7 @@ class JsonHelper static cJSON_bool addJsonNodeToObject(cJSON * parent, \ const char * nodeName, cJSON * node); static cJSON* read(const char * fileName); - static char* getValue(cJSON *json, const char *node); + static std::string getValue(cJSON *json, const char *node); static cJSON * getNode(cJSON *json, const char *node); static char *printUnformatted(cJSON * node); static char *print(cJSON * node); diff --git a/src/o1/ves/PnfRegistration.cpp b/src/o1/ves/PnfRegistration.cpp index 37eae20ca..27f692a7a 100644 --- a/src/o1/ves/PnfRegistration.cpp +++ b/src/o1/ves/PnfRegistration.cpp @@ -88,7 +88,7 @@ string PnfRegistration::getNetconfMacAddr() return mNetconfMacAddr; } else { - O1_LOG("O1 VES : could not get Netconf Mac Address\n"); + O1_LOG("\nO1 PnfRegistration : could not get Netconf Mac Address"); return ""; } } @@ -116,7 +116,7 @@ string PnfRegistration::getNetconfV4ServerIP() return mNetconfIpv4; } else { - O1_LOG("O1 VES : could not get Netconf IPv4 ip\n"); + O1_LOG("\nO1 PnfRegistration : could not get Netconf IPv4 ip"); return ""; } } @@ -144,7 +144,7 @@ string PnfRegistration::getNetconfPort() return mNetconfPort; } else { - O1_LOG("O1 VES : Could not get Netconf Port number\n"); + O1_LOG("\nO1 PnfRegistration : Could not get Netconf Port number"); return NETCONF_DEFAULT_PORT; } } @@ -173,7 +173,7 @@ string PnfRegistration::getUsername() return mNetconfUsername; } else { - O1_LOG("O1 VES : could not get Netconf username\n"); + O1_LOG("\nO1 PnfRegistration : could not get Netconf username"); return ""; } } @@ -201,7 +201,7 @@ string PnfRegistration::getPassword() return mNetconfPassword; } else { - O1_LOG("O1 VES : could not get Netconf password\n"); + O1_LOG("\nO1 PnfRegistration : could not get Netconf password"); return ""; } } @@ -228,7 +228,7 @@ string PnfRegistration::getNetconfV6ServerIP() return mNetconfIpv6; } else { - O1_LOG("O1 VES : could not get Netconf IPv6 ip\n"); + O1_LOG("\nO1 PnfRegistration : could not get Netconf IPv6 ip"); return ""; } } @@ -309,8 +309,8 @@ bool PnfRegistration::prepareEventFields() cJSON* pnfFields = this->mVesEventFields; if(!readConfigFile()) { - O1_LOG("O1 VES : config file reading failed\n"); - //return false; + O1_LOG("\nO1 PnfRegistration : Failed to read config file"); + return false; } if(JsonHelper::addNodeToObject(pnfFields, "pnfRegistrationFieldsVersion", \ PNF_REGISTRATION_VERSION_2_1) == 0) { @@ -336,9 +336,10 @@ bool PnfRegistration::prepareEventFields() getNetconfV4ServerIP().c_str()) == 0) { ret = false; } - else if(JsonHelper::addNodeToObject(pnfFields, "oamV6IpAddress", \ - getNetconfV6ServerIP().c_str()) == 0) { - ret = false; + else if(getNetconfV6ServerIP() != "" && (JsonHelper::addNodeToObject( \ + pnfFields, "oamV6IpAddress", \ + getNetconfV6ServerIP().c_str()) == 0)) { + ret = false; } else if(JsonHelper::addNodeToObject(pnfFields, "serialNumber", \ getSerialNumber().c_str()) == 0) { @@ -364,29 +365,26 @@ bool PnfRegistration::prepareEventFields() { cJSON *addFields = JsonHelper::createNode(); if(addFields == 0) { - O1_LOG("O1 VES : could not create additional fields JSON object\n"); + O1_LOG("\nO1 PnfRegistration : could not create additional fields JSON object"); return false; } if(prepareAdditionalFields(addFields)) { - O1_LOG("O1 VES : PNF parameter prepration done adding additional parameters \ -if required \n"); - if(addFields == 0) { - O1_LOG("O1 VES : could not prepare additional fields cJSON object\n"); - JsonHelper::deleteNode(pnfFields); - return false; + if(addFields == 0) { + O1_LOG("\nO1 PnfRegistration : could not prepare additional fields cJSON object"); + JsonHelper::deleteNode(pnfFields); + return false; } - if(JsonHelper::addJsonNodeToObject(pnfFields, "additionalFields", \ + if(JsonHelper::addJsonNodeToObject(pnfFields, "additionalFields", \ addFields) == 0) { - O1_LOG("O1 VES : could not add additional fileds\n"); - JsonHelper::deleteNode(pnfFields); - return false; + O1_LOG("\nO1 PnfRegistration : could not add additional fields"); + JsonHelper::deleteNode(pnfFields); + return false; } - } - O1_LOG("O1 VES : Preparation on PNF registration additional fields done \ -successfully \n"); + } + O1_LOG("\nO1 PnfRegistration : Event fields prepared for PNF registration"); } return ret; } @@ -455,7 +453,7 @@ bool PnfRegistration::prepareAdditionalFields(cJSON *addFields) KEEPALIVE_DELAY_120) == 0) { ret = false; } - O1_LOG("O1 VES : additonal field preparation of PNF done successfully \n"); + O1_LOG("\nO1 PnfRegistration : Additional fields prepared for PNF registration"); return ret; } @@ -480,14 +478,14 @@ bool PnfRegistration::readConfigFile() { cJSON *json = JsonHelper::read(NETCONF_CONFIG); if(json == NULL) { - O1_LOG("O1 VES : Config file reading error is :%s\n", JsonHelper::getError()); + O1_LOG("\nO1 PnfRegistration : Config file reading error is :%s", JsonHelper::getError()); return false; } else { cJSON *rootNode = NULL; rootNode = JsonHelper::getNode(json, "NetconfServer"); if(rootNode) { - O1_LOG("O1 VES : Reading NetconfServer config file\n"); + O1_LOG("\nO1 PnfRegistration : Reading NetconfServer config file"); mNetconfMacAddr = JsonHelper::getValue(rootNode, "MacAddress"); mNetconfIpv4 = JsonHelper::getValue(rootNode, "NetconfServerIpv4"); mNetconfIpv6 = JsonHelper::getValue(rootNode, "NetconfServerIpv6"); @@ -496,7 +494,7 @@ bool PnfRegistration::readConfigFile() mNetconfPassword = JsonHelper::getValue(rootNode, "NetconfPassword"); } else { - O1_LOG("O1 VES : smoConfig Object is not availbale in config file\n"); + O1_LOG("\nO1 PnfRegistration : smoConfig Object is not available in config file"); return false; } } diff --git a/src/o1/ves/PnfRegistrationThread.cpp b/src/o1/ves/PnfRegistrationThread.cpp new file mode 100644 index 000000000..61583273f --- /dev/null +++ b/src/o1/ves/PnfRegistrationThread.cpp @@ -0,0 +1,48 @@ +/******************************************************************************* +################################################################################ +# 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 class which runs as a thread to send the PNF + registration message. +*/ + + +#include "PnfRegistrationThread.hpp" +#include "VesUtils.hpp" +#include "VesEventHandler.hpp" + +#include + + +bool PnfRegistrationThread::run() +{ + + const int N_RETRY = 2; + const int RETRY_DELAY = 10; + /* Prepare VES PNF registration request */ + VesEventHandler vesEvtHdr; + if(vesEvtHdr.prepare(VesEventType::PNF_REGISTRATION)) + { + /* Send VES PNF registration request */ + for( int i = 0; i < N_RETRY; i++) + { + sleep(RETRY_DELAY); + O1_LOG("\nO1 PnfRegistrationThread : Sending PNF registration. Attempt %d\n", i ); + vesEvtHdr.send(); + } + } +} diff --git a/src/o1/ves/PnfRegistrationThread.hpp b/src/o1/ves/PnfRegistrationThread.hpp new file mode 100644 index 000000000..607bd5f11 --- /dev/null +++ b/src/o1/ves/PnfRegistrationThread.hpp @@ -0,0 +1,44 @@ +/******************************************************************************* +################################################################################ +# 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 class which runs as a thread to send the PNF + registration message. +*/ + +#ifndef __PNF_REGISTRATION_THREAD_HPP__ +#define __PNF_REGISTRATION_THREAD_HPP__ + +#include "Thread.hpp" +#include "Singleton.hpp" + + +class PnfRegistrationThread : public Singleton, public Thread +{ + friend Singleton; + + protected: + PnfRegistrationThread(){} + ~PnfRegistrationThread(){} + bool run(); + + public: + void cleanUp(void){} +}; + + +#endif diff --git a/src/o1/ves/VesCommonHeader.cpp b/src/o1/ves/VesCommonHeader.cpp index 3c4b1f95b..864ea84ca 100644 --- a/src/o1/ves/VesCommonHeader.cpp +++ b/src/o1/ves/VesCommonHeader.cpp @@ -107,7 +107,7 @@ string VesCommonHeader::getEventTypeToStr() str = "heartbeat"; break; default: - O1_LOG("O1 VES : VES msg Type is not avilable\n"); + O1_LOG("\nO1 VesCommonHeader : VES msg Type not supported"); break; } return str; @@ -144,8 +144,8 @@ string VesCommonHeader::getEventId() evntId = getEventTypeToStr() + "_" + getCurrentTime(); break; default: - O1_LOG("O1 VES : this VES msg Type support in getEventId is \ -not available\n"); + O1_LOG("\nO1 VesCommonHeader : this VES msg Type support in getEventId is \ +not available"); break; } return evntId; @@ -184,8 +184,8 @@ string VesCommonHeader::getEventType() evntType = EVENT_TYPE_ORAN_COMPONENET; break; default: - O1_LOG("O1 VES : this VES msg Type support in getEvenType is \ -not available\n"); + O1_LOG("\nO1 VesCommonHeader : this VES msg Type support in getEvenType is \ +not available"); break; } return evntType; @@ -223,8 +223,8 @@ string VesCommonHeader::getPriority() evntId = PRIORITY_LOW; break; default: - O1_LOG("O1 VES : This VES msg Type support in getPriority is \ -not available\n"); + O1_LOG("\nO1 VesCommonHeader : This VES msg Type support in getPriority is \ +not available"); break; } return evntId; @@ -263,8 +263,8 @@ string VesCommonHeader::getEventName() evntName = getEventTypeToStr() + "_" + EVENT_TYPE_ORAN_COMPONENET; break; default: - O1_LOG("O1 VES : This VES msg Type support in getEventName is \ -not available\n"); + O1_LOG("\nO1 VesCommonHeader : This VES msg Type support in getEventName is \ +not available"); break; } return evntName; @@ -298,8 +298,8 @@ string VesCommonHeader::getReportingEntityName() evntName = getSourceName(); break; default: - O1_LOG("O1 VES : This VES msg Type support in \ -getReportingEntityName is not available\n"); + O1_LOG("\nO1 VesCommonHeader : This VES msg Type support in \ +getReportingEntityName is not available"); break; } return evntName; @@ -424,7 +424,6 @@ string VesCommonHeader::getCurrentTime() bool VesCommonHeader::prepare(cJSON *commonHeader, \ VesEventType type) { - O1_LOG("O1 VES : createCommonHeader fuction started\n"); bool ret=true; string typeStr; string evntId; @@ -518,7 +517,7 @@ bool VesCommonHeader::prepare(cJSON *commonHeader, \ } else { - O1_LOG("O1 VES : VES common Header prepared successfully \n"); + O1_LOG("\nO1 VesCommonHeader : VES common Header prepared"); } return ret; diff --git a/src/o1/ves/VesEvent.cpp b/src/o1/ves/VesEvent.cpp index 6565fdfb7..23a4d88ea 100644 --- a/src/o1/ves/VesEvent.cpp +++ b/src/o1/ves/VesEvent.cpp @@ -60,9 +60,8 @@ VesEvent::~VesEvent() bool VesEvent::prepare() { - O1_LOG("O1 VES : prepare PNF Registration start\n"); - if(!getVesCollectorDetails()) { - O1_LOG("O1 VES : Could not get successfully details of Ves Collector\n"); + if(!readConfigFile()) { + O1_LOG("\nO1 VesEvent : Could not get SMO details"); return false; } @@ -71,26 +70,26 @@ bool VesEvent::prepare() cJSON *rootNode = JsonHelper::createNode(); if(rootNode == 0) { - O1_LOG("O1 VES : could not create cJSON root Node object\n"); + O1_LOG("\nO1 VesEvent : could not create cJSON root Node object"); return false; } cJSON *event = JsonHelper::createNode(); if(event == 0) { - O1_LOG("O1 VES : could not create event cJSON object\n"); + O1_LOG("\nO1 VesEvent : could not create event cJSON object"); JsonHelper::deleteNode(rootNode); return false; } if(JsonHelper::addJsonNodeToObject(rootNode, "event", event) == 0) { - O1_LOG("O1 VES : could not add event Object\n"); + O1_LOG("\nO1 VesEvent : could not add event Object"); JsonHelper::deleteNode(rootNode); return false; } cJSON *commHdrNode = JsonHelper::createNode(); if(commHdrNode == 0) { - O1_LOG("O1 VES : could not create common header Node JSON object"); + O1_LOG("\nO1 VesEvent : could not create common header Node JSON object"); return false; } @@ -100,7 +99,7 @@ bool VesEvent::prepare() { if(JsonHelper::addJsonNodeToObject(event, "commonEventHeader", \ commHdrNode) == 0) { - O1_LOG("O1 VES : could not add commonEventHeader object\n"); + O1_LOG("\nO1 VesEvent : could not add commonEventHeader object"); JsonHelper::deleteNode(rootNode); return false; } @@ -109,29 +108,29 @@ bool VesEvent::prepare() //add header into the message and create pnfFields mVesEventFields = JsonHelper::createNode(); if(mVesEventFields == 0) { - O1_LOG("O1 VES : could not create Ves Event Fields JSON object\n"); + O1_LOG("\nO1 VesEvent : could not create Ves Event Fields JSON object"); return false; } if(!prepareEventFields()) { - O1_LOG("O1 VES : could not prepare Ves Event Fields Node \n"); + O1_LOG("\nO1 VesEvent : could not prepare Ves Event Fields Node"); JsonHelper::deleteNode(rootNode); return false; } if(JsonHelper::addJsonNodeToObject(event, "pnfRegistrationFields", mVesEventFields) == 0) { - O1_LOG("O1 VES : could not add mVesEventFields object\n"); + O1_LOG("\nO1 VesEvent : could not add mVesEventFields object"); JsonHelper::deleteNode(rootNode); return false; } mSendData = JsonHelper::printUnformatted(rootNode); - O1_LOG("O1 VES : final ves request : -- \n%s\n", JsonHelper::print(rootNode)); + O1_LOG("\nO1 VesEvent : VES request : -- \n%s\n", JsonHelper::print(rootNode)); } } else { - O1_LOG("O1 VES : preparePnfRegistration common header preparation failed\n"); + O1_LOG("\nO1 VesEvent : Failed to prepare preparePnfRegistration common header"); JsonHelper::deleteNode(rootNode); return false; } @@ -143,29 +142,6 @@ bool VesEvent::send() return mHttpClient->send(mSendData); } -/******************************************************************* - * - * @brief Gets the Ves Collector Server details - * - * @details - * - * Function : getVesCollectorDetails - * - * Functionality: - * - Gets the Ves Collector Server details by reading config file - * - * @params[in] IN - pointer to pnfFields - * @return true - success - * false - failure - * - * ****************************************************************/ - - -bool VesEvent::getVesCollectorDetails() -{ - return readConfigFile(); -} - /******************************************************************* * * @brief Read Ves Collector config json file @@ -187,21 +163,21 @@ bool VesEvent::readConfigFile() { cJSON *json = JsonHelper::read(VES_CONFIG); if(json == NULL) { - O1_LOG("O1 VES : Config file reading error is :%s\n", JsonHelper::getError()); - return false; + O1_LOG("\nO1 VesEvent : Error reading config file :%s", JsonHelper::getError()); + return false; } else { cJSON *rootNode = NULL; rootNode = JsonHelper::getNode(json, "vesConfig"); if(rootNode) { - O1_LOG("O1 VES : Reading smoConfig.json file\n"); + O1_LOG("\nO1 VesEvent : Reading smoConfig.json file\n"); mVesServerIp = JsonHelper::getValue(rootNode, "vesV4IpAddress"); mVesServerPort = JsonHelper::getValue(rootNode, "vesPort"); mVesServerUsername = JsonHelper::getValue(rootNode, "username"); mVesServerPassword = JsonHelper::getValue(rootNode, "password"); } else { - O1_LOG("O1 VES : smoConfig Object is not availbale in config file\n"); + O1_LOG("\nO1 VesEvent : smoConfig Object is not available in config file"); return false; } } diff --git a/src/o1/ves/VesEvent.hpp b/src/o1/ves/VesEvent.hpp index f6e746d80..c1254da9e 100644 --- a/src/o1/ves/VesEvent.hpp +++ b/src/o1/ves/VesEvent.hpp @@ -47,9 +47,7 @@ class VesEvent{ cJSON* mVesEventFields; private: - //Member variable bool readConfigFile(); - bool getVesCollectorDetails(); char * mSendData; HttpClient *mHttpClient; string mVesServerIp; diff --git a/src/o1/ves/VesEventHandler.cpp b/src/o1/ves/VesEventHandler.cpp index 18258e143..48e0ff62d 100644 --- a/src/o1/ves/VesEventHandler.cpp +++ b/src/o1/ves/VesEventHandler.cpp @@ -25,14 +25,53 @@ /******************************************************************* * - * @brief prepare and send Ves Message + * @brief Constructor * * @details * - * Function : sendVesEvent + * Function : VesEventHandler * * Functionality: - * - prepare VES event and send to oam + * - Constructor intialization + * + * @params[in] NULL + * @return None + ******************************************************************/ +VesEventHandler::VesEventHandler() : mVesEvent(NULL) +{ + +} + +/******************************************************************* + * + * @brief Destructor + * + * @details + * + * Function : ~VesEventHandler + * + * Functionality: + * - Destructor + * + * @params[in] None + * @return None + ******************************************************************/ +VesEventHandler::~VesEventHandler() +{ + if( mVesEvent != NULL ) + delete mVesEvent; +} + +/******************************************************************* + * + * @brief Prepare VES Message + * + * @details + * + * Function : prepare + * + * Functionality: + * - prepare VES event * * @params[in] void * @return true - success @@ -40,47 +79,64 @@ * * ****************************************************************/ -bool VesEventHandler::send(VesEventType evtType) +bool VesEventHandler::prepare(VesEventType evtType) { //check event type and call funtions accordingly bool ret = true; - //char *sendData; - O1_LOG("O1 VES : sendVesEvent started\n"); - VesEvent *vesEvent; - //common header switch(evtType) { case VesEventType::PNF_REGISTRATION: { - O1_LOG("O1 VES : send PNP registration\n"); - vesEvent = new PnfRegistration; + O1_LOG("\nO1 VesEventHandler : Preparing PNF registration"); + mVesEvent = new PnfRegistration; break; } case VesEventType::FAULT_NOTIFICATION: - O1_LOG("O1 VES : send VES fault notification\n"); + O1_LOG("\nO1 VesEventHandler : Preparing VES fault notification"); break; case VesEventType::PM_NOTIFICATION: - O1_LOG("O1 VES : send VES pm notification\n"); + O1_LOG("\nO1 VesEventHandler : Preparing VES pm notification"); break; case VesEventType::HEARTBEAT: - O1_LOG("O1 VES : send VES heartbeat \n"); + O1_LOG("\nO1 VesEventHandler : Preparing VES heartbeat"); break; default: - O1_LOG("O1 VES : send VES msg Type is not avilable\n"); + O1_LOG("\nO1 VesEventHandler : VES msg Type is not available"); ret = false; break; } - if(!vesEvent->prepare()) { - O1_LOG("O1 VES : could not send VES Event\n"); - ret = false; - } - else if (!vesEvent->send()) { - O1_LOG("O1 VES : could not send VES Event\n"); + if(!mVesEvent->prepare()) { + O1_LOG("\nO1 VesEventHandler : Failed to prepare VES message"); ret = false; } - delete vesEvent; return ret; } + +/******************************************************************* + * + * @brief Send Ves Message + * + * @details + * + * Function : send + * + * Functionality: + * - Send VES event to SMO + * + * @params[in] void + * @return true - success + * false - failure + * + * ****************************************************************/ + +bool VesEventHandler::send() +{ + if (!mVesEvent->send()) { + O1_LOG("\nO1 VesEventHandler : Failed to send VES event"); + return false; + } + return true; +} /********************************************************************** End of file **********************************************************************/ diff --git a/src/o1/ves/VesEventHandler.hpp b/src/o1/ves/VesEventHandler.hpp index 614967ac3..c3041909d 100644 --- a/src/o1/ves/VesEventHandler.hpp +++ b/src/o1/ves/VesEventHandler.hpp @@ -32,9 +32,13 @@ class VesEventHandler public: /* Default constructor/Destructor*/ - VesEventHandler(){} - ~VesEventHandler(){} - bool send(VesEventType evtType); + VesEventHandler(); + ~VesEventHandler(); + bool prepare(VesEventType evtType); + bool send(); + + private: + VesEvent *mVesEvent; };