X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;f=src%2Fo1%2FTcpServer.cpp;fp=src%2Fo1%2FTcpServer.cpp;h=47ce09475cdd310213c091e2e963d7c837778de9;hb=b85b99f4675173c33e39787be1ceec428cefd51c;hp=0000000000000000000000000000000000000000;hpb=66916eaaf8212d36b38e4dba88bdf159d7637779;p=o-du%2Fl2.git diff --git a/src/o1/TcpServer.cpp b/src/o1/TcpServer.cpp new file mode 100644 index 000000000..47ce09475 --- /dev/null +++ b/src/o1/TcpServer.cpp @@ -0,0 +1,275 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2020] [HCL Technologies Ltd.] # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); # +# you may not use this file except in compliance with the License. # +# You may obtain a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +################################################################################ +*******************************************************************************/ + +/* This file contains TcpServer class that listens for Netconf Alarm messages + on a TCP socket from ODU. It calls the AlarmManager functions for raising + or clearing the alarms based on the actions received +*/ + +#include "TcpServer.hpp" +#include "Alarm.hpp" +#include "AlarmManager.hpp" +#include "GlobalDefs.hpp" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using std::map; +using std::pair; + +/* Destructor */ +TcpServer::~TcpServer() +{ + +} + + +/********************************************************************** + Description : Read the data from the connected client application + Params[In] : fd - File descriptor + Return : int - No of bytes read +**********************************************************************/ +int TcpServer::readMessage(int fd) +{ + AlarmRecord alrmRec; + bzero(&alrmRec,sizeof(alrmRec)); + int nbytes = read (fd, &alrmRec, sizeof(alrmRec)); + if (nbytes > 0) + { + Alarm alrm; + uint16_t alrmId; + O1_LOG("\nO1 TcpServer :\nAction %d\nalarm ID %s\n%d\n%s\n%d\n%s\n%s\nbytes %d", + alrmRec.msgHeader.action, + alrmRec.alarmId, + alrmRec.perceivedSeverity, + alrmRec.additionalText, + alrmRec.eventType, + alrmRec.specificProblem, + alrmRec.additionalInfo, + nbytes + ); + + /*Fill the alarm structure */ + sscanf(alrmRec.alarmId,"%hu",&alrmId); + alrm.setAlarmId(alrmId); + alrm.setPerceivedSeverity(alrmRec.perceivedSeverity); + alrm.setAdditionalText(alrmRec.additionalText); + alrm.setEventType(alrmRec.eventType); + alrm.setSpecificProblem(alrmRec.specificProblem); + alrm.setAdditionalInfo(alrmRec.additionalInfo); + + switch(alrmRec.msgHeader.action) + { + case RAISE: + if(AlarmManager::instance().raiseAlarm(alrm)) + { + O1_LOG("\nO1 TcpServer : Alarm raised for alarm Id %s", alrmRec.alarmId); + } + else + { + O1_LOG("\nO1 TcpServer : Error in raising alarm for alrm Id %s", alrmRec.alarmId); + } + break; + case CLEAR: + if(AlarmManager::instance().clearAlarm(alrm)) + { + O1_LOG("\nO1 TcpServer : Alarm cleared for alarm Id %s", alrmRec.alarmId); + } + else + { + O1_LOG("\nO1 TcpServer : Error in clearing alarm for alarm Id %s", alrmRec.alarmId); + } + break; + default: + O1_LOG("\nO1 TcpServer : No action performed"); + break; + } + + } + return nbytes; +} + + +/********************************************************************** + Description : Open a TCP socket and bind on the port + Params[In] : None + Return : O1::SUCCESS - socket open and bind successful + O1::FAILURE - socket open and bind failed +**********************************************************************/ +int TcpServer::makeSocket() +{ + struct sockaddr_in name; + /* Create the socket. */ + mSock = socket (PF_INET, SOCK_STREAM, 0); + if (mSock < 0) + { + O1_LOG("\nO1 TcpServer : Socket error"); + return O1::FAILURE; + } + /* Give the socket a name. */ + bzero(&name, sizeof(name)); + name.sin_family = AF_INET; + name.sin_port = htons (mPort); + name.sin_addr.s_addr = htonl (INADDR_ANY); + if (bind (mSock, (struct sockaddr *) &name, sizeof (name)) < 0) + { + close(mSock); + O1_LOG("\nO1 TcpServer : Bind error"); + return O1::FAILURE; + } + return O1::SUCCESS; +} + + +/********************************************************************** + Description : Start TCP server in thread + Params[In] : None + Return : true - task launched in pthread successfully + false - task failed to launch +**********************************************************************/ +bool TcpServer::start() +{ + return (pthread_create(&mThreadId, NULL, task, this) == 0); +} + +/********************************************************************** + Description : A TCP server to handle multiple connection using + select multiplexing + Params[In] : None + Return : true - task launched in pthread successfully + false - task failed to launch +**********************************************************************/ +bool TcpServer::run() +{ + + fd_set active_fd_set, read_fd_set; + int i; + struct sockaddr_in clientName; + socklen_t size; + bool ret = true;; + + /* Create the socket and set it up to accept connections. */ + if( makeSocket() == O1::SUCCESS ) + { + if (listen (mSock, 1) < 0) + { + O1_LOG("\nO1 TcpServer : Listen error"); + close(mSock); + ret = false; + } + else + { + /* Initialize the set of active sockets. */ + FD_ZERO (&active_fd_set); + FD_SET (mSock, &active_fd_set); + + while (1) + { + /* Block until input arrives on one or more active sockets. */ + read_fd_set = active_fd_set; + if (select (FD_SETSIZE, &read_fd_set, NULL, NULL, NULL) < 0) + { + O1_LOG("\nO1 TcpServer : Select error"); + close(mSock); + ret = false; + break; + } + + /* Service all the sockets with input pending. */ + for (i = 0; i < FD_SETSIZE; ++i) + { + if (FD_ISSET (i, &read_fd_set)) + { + if (i == mSock) + { + /* Connection request on original socket. */ + int newFd; + bzero(&clientName, sizeof(clientName)); + size = sizeof (clientName); + newFd = accept(mSock,(struct sockaddr *) &clientName,&size); + if (newFd < 0) + { + O1_LOG("\nO1 TcpServer : Accept error"); + close(mSock); + ret = false; + break; + } + O1_LOG("\nO1 TcpServer : Connected from host %s, port %hd.\n", + inet_ntoa (clientName.sin_addr), + ntohs (clientName.sin_port)); + FD_SET (newFd, &active_fd_set); + } + else + { + /* Data arriving on an already-connected socket. */ + if (readMessage(i) < 0) + { + close (i); + FD_CLR (i, &active_fd_set); + } + } + } + }/* for loop ends */ + } /* while(1) ends */ + } /* else ends */ + } /* outer if ends */ + else + { + ret = false; + } + return ret; +} + + +/********************************************************************** + Description : Static function for launching a TCP server instance + in a thread + Params[In] : TcpServer instance + Return : NULL +**********************************************************************/ +void* TcpServer::task(void *args) +{ + TcpServer *tcpServer = (TcpServer*)args; + tcpServer->run(); + return NULL; +} + + +/********************************************************************** + Description : Wait for the thread to complete in the parent process + Params[In] : None + Return : true - pthread join success + false - pthread join failed +**********************************************************************/ +bool TcpServer::wait() +{ + return (pthread_join(mThreadId,NULL) == 0); +} + + + +/********************************************************************** + End of file +**********************************************************************/