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
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
"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!"
--- /dev/null
+<netconf-server xmlns="urn:ietf:params:xml:ns:yang:ietf-netconf-server">
+ <listen>
+ <endpoint>
+ <name>default-ssh</name>
+ <ssh>
+ <tcp-server-parameters>
+ <local-address>::</local-address>
+ <keepalives>
+ <idle-time>1</idle-time>
+ <max-probes>10</max-probes>
+ <probe-interval>5</probe-interval>
+ </keepalives>
+ </tcp-server-parameters>
+ <ssh-server-parameters>
+ <server-identity>
+ <host-key>
+ <name>default-key</name>
+ <public-key>
+ <keystore-reference>genkey</keystore-reference>
+ </public-key>
+ </host-key>
+ </server-identity>
+ <client-authentication>
+ <supported-authentication-methods>
+ <publickey/>
+ <passsword/>
+ <other>interactive</other>
+ </supported-authentication-methods>
+ <users/>
+ </client-authentication>
+ </ssh-server-parameters>
+ </ssh>
+ </endpoint>
+ </listen>
+</netconf-server>
$(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)'
endif
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
$(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)'
endif
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/*
$(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:
$(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/*
$(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:
$(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/*
--- /dev/null
+################################################################################
+# 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 #
+################################################################################
--- /dev/null
+################################################################################
+# 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 #
+################################################################################
--- /dev/null
+################################################################################
+# 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 #
+################################################################################
-----------------------------------------------------------------------------------
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:
b. ifconfig <interface name>:CU_STUB "192.168.130.82"
c. ifconfig <interface name>: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:
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
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 <O-DU High Directory>/l2/build/scripts
- | sudo ./install_lib_O1.sh -c
-
-- Start Netopeer2-server:
-
- - Ubuntu :
- | cd <O-DU High Directory>/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 <O-DU High Directory>/l2/build/scripts
+ | sudo ./add_netconf_user.sh
+
+- Install Netconf libraries:
- | cd <O-DU High Directory>/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 <O-DU High Directory>/l2/build/scripts
+ | sudo ./install_lib_O1.sh -c
- | cd <O-DU High Directory>/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 <O-DU High Directory>/l2/build/config
- | cd <O-DU High Directory>/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 <O-DU High Directory>/l2/build/scripts
+ | sudo ./load_yang.sh
- | cd <O-DU High Directory>/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 <O-DU High Directory>/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 <O-DU High Directory>/l2/build/scripts
+ | sudo ./netopeer-server.sh start
Compilation
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.
//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()*/
/**********************************************************************
******************************************************************/
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() )
{
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);
}
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);
std::map<uint16_t, NrCellInfo>::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()));
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;
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();
//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<uint16_t, NrCellInfo>::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()) != \
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;
}
}
}//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;
}
/**********************************************************************
End of file
**********************************************************************/
-
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;
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;
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;
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);
#include "VesUtils.hpp"
#include "VesEventHandler.hpp"
+
+
/*******************************************************************
*
* @brief Constructor
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
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*/
}
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;
UnixSocketServer mUxSocketServer;
protected:
+ O1App();
+ ~O1App();
bool run();
public:
- O1App();
- ~O1App();
bool getStartupStatus()const;
void cleanUp(void);
};
#include "O1Interface.h"
#include "O1App.hpp"
#include "GlobalDefs.hpp"
+#include "PnfRegistrationThread.hpp"
+
#include <signal.h>
#include <unistd.h>
******************************************************************/
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)
{
}
else
{
- sleep(1);
+ sleep(RETRY_DELAY);
}
}
{
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
{
#endif
int start_O1_module(void);
+void sendPnfRegistration(void);
#ifdef __cplusplus
}
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;
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;
}
if((mServerIp.c_str()) && (mServerPort.c_str())) {
oss <<"https://"<<mServerIp<<":"<<mServerPort<<"/eventListener/v7";
string url = oss.str();
- O1_LOG("O1 VES : URL=%s\n", url.c_str());
+ O1_LOG("\nO1 HttpClient : URL=%s", url.c_str());
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
return true;
}
curl_slist_free_all(header);
if(res != CURLE_OK) {
- O1_LOG("O1 VES : could not send data , received error: %s\n", \
+ O1_LOG("\nO1 HttpClient : Could not send data, error: %s", \
curl_easy_strerror(res));
curl_easy_cleanup(curl);
return false;
CURL *curl = curl_easy_init();
if(curl == 0) {
- O1_LOG("O1 VES : could not initialize CURL\n");
+ O1_LOG("\nO1 HttpClient : could not initialize CURL");
return false;
}
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, sendMsg);
if(!prepareHttpHeader(header, curl))
{
- O1_LOG("O1 VES : could not prepare HTTP header\n");
+ O1_LOG("\nO1 HttpClient : could not prepare HTTP header");
curl_easy_cleanup(curl);
return false;
}
else if(!sendHttpRequest(header, curl))
{
- O1_LOG("O1 VES : could not send HTTP request\n");
+ O1_LOG("\nO1 HttpClient : could not send HTTP request");
return false;
}
- curl_easy_cleanup(curl);
- return true;
+ curl_easy_cleanup(curl);
+ return true;
}
/*******************************************************************
******************************************************************/
size_t HttpClient::writeCb(void *data, size_t size, size_t nmemb, void *userp) {
- O1_LOG("O1 VES : write Callback called\n");
+ O1_LOG("\nO1 HttpClient : write Callback called");
size_t realsize = size * nmemb;
struct response *mem = (struct response *)userp;
char *ptr = (char *) realloc(mem->res, mem->size + realsize + 1);
if(ptr == NULL) {
- O1_LOG("O1 VES : realloc failed");
+ O1_LOG("\nO1 HttpClient : realloc failed");
return 0;
}
*
* ****************************************************************/
-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);
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;
}
/**********************************************************************
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);
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 "";
}
}
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 "";
}
}
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;
}
}
return mNetconfUsername;
}
else {
- O1_LOG("O1 VES : could not get Netconf username\n");
+ O1_LOG("\nO1 PnfRegistration : could not get Netconf username");
return "";
}
}
return mNetconfPassword;
}
else {
- O1_LOG("O1 VES : could not get Netconf password\n");
+ O1_LOG("\nO1 PnfRegistration : could not get Netconf password");
return "";
}
}
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 "";
}
}
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) {
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) {
{
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;
}
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;
}
{
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");
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;
}
}
--- /dev/null
+/*******************************************************************************
+################################################################################
+# 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 <unistd.h>
+
+
+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();
+ }
+ }
+}
--- /dev/null
+/*******************************************************************************
+################################################################################
+# 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<PnfRegistrationThread>, public Thread
+{
+ friend Singleton<PnfRegistrationThread>;
+
+ protected:
+ PnfRegistrationThread(){}
+ ~PnfRegistrationThread(){}
+ bool run();
+
+ public:
+ void cleanUp(void){}
+};
+
+
+#endif
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;
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;
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;
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;
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;
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;
bool VesCommonHeader::prepare(cJSON *commonHeader, \
VesEventType type)
{
- O1_LOG("O1 VES : createCommonHeader fuction started\n");
bool ret=true;
string typeStr;
string evntId;
}
else
{
- O1_LOG("O1 VES : VES common Header prepared successfully \n");
+ O1_LOG("\nO1 VesCommonHeader : VES common Header prepared");
}
return ret;
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;
}
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;
}
{
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;
}
//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;
}
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
{
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;
}
}
cJSON* mVesEventFields;
private:
- //Member variable
bool readConfigFile();
- bool getVesCollectorDetails();
char * mSendData;
HttpClient *mHttpClient;
string mVesServerIp;
/*******************************************************************
*
- * @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
*
* ****************************************************************/
-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
**********************************************************************/
public:
/* Default constructor/Destructor*/
- VesEventHandler(){}
- ~VesEventHandler(){}
- bool send(VesEventType evtType);
+ VesEventHandler();
+ ~VesEventHandler();
+ bool prepare(VesEventType evtType);
+ bool send();
+
+ private:
+ VesEvent *mVesEvent;
};