/******************************************************************************* ################################################################################ # 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 UnixSocketServer class that listens for Netconf Alarm messages on a Unix socket from ODU. It calls the AlarmManager functions for raising or clearing the alarms based on the actions received */ #include "UnixSocketServer.hpp" #include "Alarm.hpp" #include "CmInterface.h" #include "GlobalDefs.hpp" #include #include #include #include #include #include #include #include #include #include #include #include "InitConfig.hpp" using std::map; using std::pair; /******************************************************************* * * @brief Constructor * * @details * * Function : UnixSocketServer * * Functionality: * - Constructor intialization * * @params[in] socket path * @return None ******************************************************************/ UnixSocketServer::UnixSocketServer(const string& sockPath) : mSockPath(sockPath), mIsRunning(false) { } /******************************************************************* * * @brief Destructor * * @details * * Function : ~UnixSocketServer * * Functionality: * - Destructor * * @params[in] None * @return None ******************************************************************/ UnixSocketServer::~UnixSocketServer() { } /******************************************************************* * * @brief Read the data from the connected client application * * @details * * Function : readMessage * * Functionality: * - Reads the data from the connected client application * * @params[in] File descriptor * @return No. of bytes read * ******************************************************************/ int UnixSocketServer::readMessage(int fd) { char recvBuf[BUFLEN]; bzero(&recvBuf,sizeof(recvBuf)); int nbytes = read (fd, &recvBuf, sizeof(recvBuf)); if (nbytes > 0) { /* sending message to all Unix Socket Server subscribers */ createMessage(recvBuf); } return nbytes; } /******************************************************************* * * @brief Open a Unix socket and bind on the port * * @details * * Function : makeSocket * * Functionality: * - Opens a Unix socket and bind on the port * * @params[in] void * @return O1:SUCCESS - success * O1:FAILURE - failure ******************************************************************/ int UnixSocketServer::makeSocket() { struct sockaddr_un name; /* Create the socket. */ mSock = socket (AF_UNIX, SOCK_STREAM, 0); if (mSock < 0) { O1_LOG("\nO1 UnixSocketServer : Socket error"); return O1::FAILURE; } /* Give the socket a name. */ bzero(&name, sizeof(name)); name.sun_family = AF_UNIX; /* Remove the socket file if it already exists */ if ( unlink(mSockPath.c_str()) == 0) { O1_LOG("\nO1 UnixSocketServer : " "Removing the existing socket path %s", mSockPath.c_str()); } strcpy(name.sun_path, mSockPath.c_str()); if (bind (mSock, (struct sockaddr *) &name, sizeof (name)) < 0) { close(mSock); O1_LOG("\nO1 UnixSocketServer : Bind error"); return O1::FAILURE; } return O1::SUCCESS; } /******************************************************************* * * @brief A Unix server to handle multiple connection * * @details * * Function : run * * Functionality: * - A Unix server to handle multiple connection * Uses select multiplexing * * @params[in] void * @return true - success * false - failure ******************************************************************/ bool UnixSocketServer::run() { fd_set active_fd_set, read_fd_set; int i; struct sockaddr_un clientName; socklen_t size; mIsRunning = true; /* Create the socket and set it up to accept connections. */ if( makeSocket() == O1::SUCCESS ) { if (listen (mSock, 1) < 0) { O1_LOG("\nO1 UnixSocketServer : Listen error"); close(mSock); mIsRunning = 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 UnixSocketServer : Select error"); close(mSock); mIsRunning = 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 UnixSocketServer : Accept error"); close(mSock); mIsRunning = false; break; } O1_LOG("\nO1 UnixSocketServer : Connected from client\n"); 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 { mIsRunning = false; } return mIsRunning; } /******************************************************************* * * @brief Clean up open socket * * @details * * Function : cleanUp * * Functionality: * - Performs any clean ups before stopping the thread * * @params[in] void * @return void ******************************************************************/ void UnixSocketServer::cleanUp(void) { close(mSock); O1_LOG("\nO1 UnixSocketServer : Cleaning up Closing socket \n"); } /******************************************************************* * * @brief Check if the server is running * * @details * * Function : isRunning * * Functionality: * - Returns the running status of the server * * @params[in] void * @return true : running * false: not running ******************************************************************/ bool UnixSocketServer::isRunning() const { return mIsRunning; } /********************************************************************** End of file **********************************************************************/