1 /*******************************************************************************
2 ################################################################################
3 # Copyright (c) [2020-2021] [HCL Technologies Ltd.] #
5 # Licensed under the Apache License, Version 2.0 (the "License"); #
6 # you may not use this file except in compliance with the License. #
7 # You may obtain a copy of the License at #
9 # http://www.apache.org/licenses/LICENSE-2.0 #
11 # Unless required by applicable law or agreed to in writing, software #
12 # distributed under the License is distributed on an "AS IS" BASIS, #
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
14 # See the License for the specific language governing permissions and #
15 # limitations under the License. #
16 ################################################################################
17 *******************************************************************************/
19 /* This file contains UnixSocketServer class that listens for Netconf Alarm
20 messages on a Unix socket from ODU. It calls the AlarmManager functions
21 for raising or clearing the alarms based on the actions received
24 #include "UnixSocketServer.hpp"
26 #include "AlarmManager.hpp"
27 #include "ConfigInterface.h"
28 #include "GlobalDefs.hpp"
34 #include <sys/types.h>
35 #include <sys/socket.h>
36 #include <netinet/in.h>
38 #include <arpa/inet.h>
40 #include "InitConfig.hpp"
46 /*******************************************************************
52 * Function : UnixSocketServer
55 * - Constructor intialization
57 * @params[in] socket path
59 ******************************************************************/
60 UnixSocketServer::UnixSocketServer(const string& sockPath)
61 : mSockPath(sockPath),
67 /*******************************************************************
73 * Function : ~UnixSocketServer
80 ******************************************************************/
81 UnixSocketServer::~UnixSocketServer()
87 /*******************************************************************
89 * @brief Read the data from the connected client application
93 * Function : readMessage
96 * - Reads the data from the connected client application
98 * @params[in] File descriptor
99 * @return No. of bytes read
101 ******************************************************************/
102 int UnixSocketServer::readMessage(int fd)
104 AlarmRecord *alrmRec = NULL;
105 char recvBuf[BUFLEN];
107 bzero(&recvBuf,sizeof(recvBuf));
109 int nbytes = read (fd, &recvBuf, sizeof(recvBuf));
113 MsgHeader *msgHdr = (MsgHeader*)recvBuf;
115 O1_LOG("\nO1 UnixSocketServer :\nMsgType %d",msgHdr->msgType);
117 if ( msgHdr->msgType == ALARM ){
119 alrmRec = (AlarmRecord*) recvBuf;
120 O1_LOG("\nO1 UnixSocketServer :\n"
124 "Additional Text %s\n"
125 "Specific Problem %s\n"
126 "Additional Info %s\n"
127 "Alarm Raise Time %s\n",
128 alrmRec->msgHeader.action,
130 alrmRec->perceivedSeverity,
131 alrmRec->additionalText,
132 alrmRec->specificProblem,
133 alrmRec->additionalInfo,
134 alrmRec->alarmRaiseTime
137 /*Fill the alarm structure */
138 sscanf(alrmRec->alarmId,"%hu",&alrmId);
139 alrm.setAlarmId(alrmId);
140 alrm.setPerceivedSeverity(alrmRec->perceivedSeverity);
141 alrm.setAdditionalText(alrmRec->additionalText);
142 alrm.setEventType(alrmRec->eventType);
143 alrm.setSpecificProblem(alrmRec->specificProblem);
144 alrm.setAdditionalInfo(alrmRec->additionalInfo);
147 switch(msgHdr->action)
151 if(AlarmManager::instance().raiseAlarm(alrm))
153 O1_LOG("\nO1 UnixSocketServer : "
154 "Alarm raised for alarm Id %s",
157 // triggering VES notification for the risen Alarm
159 VesEventHandler vesEvtHdr;
160 if(vesEvtHdr.prepare(VesEventType::FAULT_NOTIFICATION, &alrm)) {
168 O1_LOG("\nO1 UnixSocketServer : "
169 "Error in raising alarm for alrm Id %s",
175 if(AlarmManager::instance().clearAlarm(alrm))
177 O1_LOG("\nO1 UnixSocketServer : "
178 "Alarm cleared for alarm Id %s",
181 // triggering VES notification for the cleared Alarm
182 VesEventHandler vesEvtHdr;
183 if(vesEvtHdr.prepare(VesEventType::FAULT_NOTIFICATION, &alrm)) {
189 O1_LOG("\nO1 UnixSocketServer : "
190 "Error in clearing alarm for alarm Id %s",
195 case GET_STARTUP_CONFIG:
198 InitConfig::instance().getCurrInterfaceConfig(cfg);
199 O1_LOG("\nO1 UnixSocketServer : "
200 "cfg.DU_IPV4_Addr [%s]",
202 O1_LOG("\nO1 UnixSocketServer : "
205 O1_LOG("\nO1 UnixSocketServer : "
206 "cfg.CU_IPV4_Addr [%s]",
208 O1_LOG("\nO1 UnixSocketServer : "
211 O1_LOG("\nO1 UnixSocketServer : "
212 "cfg.RIC_IPV4_Addr [%s]",
214 O1_LOG("\nO1 UnixSocketServer : "
217 if (write (fd, &cfg, sizeof(cfg)) < 0)
219 O1_LOG("\nO1 UnixSocketServer : "
220 "Error sending startup configuration \n");
226 O1_LOG("\nO1 UnixSocketServer : No action performed");
235 /*******************************************************************
237 * @brief Open a Unix socket and bind on the port
241 * Function : makeSocket
244 * - Opens a Unix socket and bind on the port
247 * @return O1:SUCCESS - success
248 * O1:FAILURE - failure
249 ******************************************************************/
251 int UnixSocketServer::makeSocket()
253 struct sockaddr_un name;
254 /* Create the socket. */
255 mSock = socket (AF_UNIX, SOCK_STREAM, 0);
258 O1_LOG("\nO1 UnixSocketServer : Socket error");
261 /* Give the socket a name. */
262 bzero(&name, sizeof(name));
263 name.sun_family = AF_UNIX;
265 /* Remove the socket file if it already exists */
266 if ( unlink(mSockPath.c_str()) == 0)
268 O1_LOG("\nO1 UnixSocketServer : "
269 "Removing the existing socket path %s",
272 strcpy(name.sun_path, mSockPath.c_str());
273 if (bind (mSock, (struct sockaddr *) &name, sizeof (name)) < 0)
276 O1_LOG("\nO1 UnixSocketServer : Bind error");
283 /*******************************************************************
285 * @brief A Unix server to handle multiple connection
292 * - A Unix server to handle multiple connection
293 * Uses select multiplexing
296 * @return true - success
298 ******************************************************************/
299 bool UnixSocketServer::run()
302 fd_set active_fd_set, read_fd_set;
304 struct sockaddr_un clientName;
308 /* Create the socket and set it up to accept connections. */
309 if( makeSocket() == O1::SUCCESS )
311 if (listen (mSock, 1) < 0)
313 O1_LOG("\nO1 UnixSocketServer : Listen error");
319 /* Initialize the set of active sockets. */
320 FD_ZERO (&active_fd_set);
321 FD_SET (mSock, &active_fd_set);
325 /* Block until input arrives on one or more active sockets. */
326 read_fd_set = active_fd_set;
327 if (select (FD_SETSIZE, &read_fd_set, NULL, NULL, NULL) < 0)
329 O1_LOG("\nO1 UnixSocketServer : Select error");
335 /* Service all the sockets with input pending. */
336 for (i = 0; i < FD_SETSIZE; ++i)
338 if (FD_ISSET (i, &read_fd_set))
342 /* Connection request on original socket. */
344 bzero(&clientName, sizeof(clientName));
345 size = sizeof (clientName);
346 newFd = accept(mSock,(struct sockaddr *) &clientName,&size);
349 O1_LOG("\nO1 UnixSocketServer : Accept error");
354 O1_LOG("\nO1 UnixSocketServer : Connected from client\n");
355 FD_SET (newFd, &active_fd_set);
359 /* Data arriving on an already-connected socket. */
360 if (readMessage(i) < 0)
363 FD_CLR (i, &active_fd_set);
368 } /* while(1) ends */
370 } /* outer if ends */
379 /*******************************************************************
381 * @brief Clean up open socket
388 * - Performs any clean ups before stopping the thread
392 ******************************************************************/
393 void UnixSocketServer::cleanUp(void)
396 O1_LOG("\nO1 UnixSocketServer : Cleaning up Closing socket \n");
399 /*******************************************************************
401 * @brief Check if the server is running
405 * Function : isRunning
408 * - Returns the running status of the server
411 * @return true : running
413 ******************************************************************/
414 bool UnixSocketServer::isRunning() const
419 /**********************************************************************
421 **********************************************************************/