1 /*******************************************************************************
2 ################################################################################
3 # Copyright (c) [2020] [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 TcpServer class that listens for Netconf Alarm messages
20 on a TCP socket from ODU. It calls the AlarmManager functions for raising
21 or clearing the alarms based on the actions received
24 #include "TcpServer.hpp"
26 #include "AlarmManager.hpp"
28 #include "GlobalDefs.hpp"
34 #include <sys/types.h>
35 #include <sys/socket.h>
36 #include <netinet/in.h>
38 #include <arpa/inet.h>
39 #include "InitConfig.hpp"
45 TcpServer::~TcpServer()
51 /*******************************************************************
53 * @brief Read the data from the connected client application
57 * Function : readMessage
60 * - Reads the data from the connected client application
62 * @params[in] File descriptor
63 * @return No. of bytes read
65 ******************************************************************/
66 int TcpServer::readMessage(int fd)
68 AlarmRecord *alrmRec = NULL;
71 bzero(&recvBuf,sizeof(recvBuf));
73 int nbytes = read (fd, &recvBuf, sizeof(recvBuf));
77 MsgHeader *msgHdr = (MsgHeader*)recvBuf;
79 O1_LOG("\nO1 TcpServer :\nBuf size %ld", sizeof(recvBuf));
80 O1_LOG("\nO1 TcpServer :\nMsgType %d",msgHdr->msgType);
81 O1_LOG("\nO1 TcpServer :\nAction %d",msgHdr->action);
83 if ( msgHdr->msgType == ALARM ){
85 alrmRec = (AlarmRecord*) recvBuf;
86 O1_LOG("\nO1 TcpServer :\nAction %d\nalarm ID %s\n%d\n%s\n%d\n%s\n%s\nbytes %d",
87 alrmRec->msgHeader.action,
89 alrmRec->perceivedSeverity,
90 alrmRec->additionalText,
92 alrmRec->specificProblem,
93 alrmRec->additionalInfo,
97 /*Fill the alarm structure */
98 sscanf(alrmRec->alarmId,"%hu",&alrmId);
99 alrm.setAlarmId(alrmId);
100 alrm.setPerceivedSeverity(alrmRec->perceivedSeverity);
101 alrm.setAdditionalText(alrmRec->additionalText);
102 alrm.setEventType(alrmRec->eventType);
103 alrm.setSpecificProblem(alrmRec->specificProblem);
104 alrm.setAdditionalInfo(alrmRec->additionalInfo);
107 switch(msgHdr->action)
110 if(AlarmManager::instance().raiseAlarm(alrm))
112 O1_LOG("\nO1 TcpServer : Alarm raised for alarm Id %s", alrmRec->alarmId);
116 O1_LOG("\nO1 TcpServer : Error in raising alarm for alrm Id %s", alrmRec->alarmId);
120 if(AlarmManager::instance().clearAlarm(alrm))
122 O1_LOG("\nO1 TcpServer : Alarm cleared for alarm Id %s", alrmRec->alarmId);
126 O1_LOG("\nO1 TcpServer : Error in clearing alarm for alarm Id %s", alrmRec->alarmId);
129 case GET_STARTUP_CONFIG:
132 InitConfig::instance().getCurrInterfaceConfig(cfg);
133 O1_LOG("\nO1 TcpServer : cfg.DU_IPV4_Addr [%s]", cfg.DU_IPV4_Addr);
134 O1_LOG("\nO1 TcpServer : cfg.DU_Port [%d]", cfg.DU_Port);
135 O1_LOG("\nO1 TcpServer : cfg.CU_IPV4_Addr [%s]", cfg.CU_IPV4_Addr);
136 O1_LOG("\nO1 TcpServer : cfg.CU_Port [%d]", cfg.CU_Port);
137 O1_LOG("\nO1 TcpServer : cfg.RIC_IPV4_Addr [%s]", cfg.RIC_IPV4_Addr);
138 O1_LOG("\nO1 TcpServer : cfg.RIC_Port [%d]", cfg.RIC_Port);
139 if (write (fd, &cfg, sizeof(cfg)) < 0)
141 O1_LOG("\nO1 TcpServer : Error sending startup configuration \n");
146 O1_LOG("\nO1 TcpServer : No action performed");
155 /*******************************************************************
157 * @brief Open a TCP socket and bind on the port
161 * Function : makeSocket
164 * - Opens a TCP socket and bind on the port
167 * @return O1:SUCCESS - success
168 * O1:FAILURE - failure
169 ******************************************************************/
170 int TcpServer::makeSocket()
172 struct sockaddr_in name;
173 /* Create the socket. */
174 mSock = socket (PF_INET, SOCK_STREAM, 0);
177 O1_LOG("\nO1 TcpServer : Socket error");
180 /* Give the socket a name. */
181 bzero(&name, sizeof(name));
182 name.sin_family = AF_INET;
183 name.sin_port = htons (mPort);
184 name.sin_addr.s_addr = htonl (INADDR_ANY);
185 if (bind (mSock, (struct sockaddr *) &name, sizeof (name)) < 0)
188 O1_LOG("\nO1 TcpServer : Bind error");
195 /*******************************************************************
197 * @brief Start TCP server in thread
204 * - Start TCP server in thread
207 * @return true - success
209 ******************************************************************/
210 bool TcpServer::start()
212 return (pthread_create(&mThreadId, NULL, task, this) == 0);
215 /*******************************************************************
217 * @brief A TCP server to handle multiple connection
224 * - A TCP server to handle multiple connection
225 * Uses select multiplexing
228 * @return true - success
230 ******************************************************************/
231 bool TcpServer::run()
234 fd_set active_fd_set, read_fd_set;
236 struct sockaddr_in clientName;
240 /* Create the socket and set it up to accept connections. */
241 if( makeSocket() == O1::SUCCESS )
243 if (listen (mSock, 1) < 0)
245 O1_LOG("\nO1 TcpServer : Listen error");
251 /* Initialize the set of active sockets. */
252 FD_ZERO (&active_fd_set);
253 FD_SET (mSock, &active_fd_set);
257 /* Block until input arrives on one or more active sockets. */
258 read_fd_set = active_fd_set;
259 if (select (FD_SETSIZE, &read_fd_set, NULL, NULL, NULL) < 0)
261 O1_LOG("\nO1 TcpServer : Select error");
267 /* Service all the sockets with input pending. */
268 for (i = 0; i < FD_SETSIZE; ++i)
270 if (FD_ISSET (i, &read_fd_set))
274 /* Connection request on original socket. */
276 bzero(&clientName, sizeof(clientName));
277 size = sizeof (clientName);
278 newFd = accept(mSock,(struct sockaddr *) &clientName,&size);
281 O1_LOG("\nO1 TcpServer : Accept error");
286 O1_LOG("\nO1 TcpServer : Connected from host %s, port %hd.\n",
287 inet_ntoa (clientName.sin_addr),
288 ntohs (clientName.sin_port));
289 FD_SET (newFd, &active_fd_set);
293 /* Data arriving on an already-connected socket. */
294 if (readMessage(i) < 0)
297 FD_CLR (i, &active_fd_set);
302 } /* while(1) ends */
304 } /* outer if ends */
313 /*******************************************************************
315 * @brief Static function for launching a TCP server instance
323 * - Static function for launching a TCP server instance
326 * @params[in] TcpServer instance
328 ******************************************************************/
329 void* TcpServer::task(void *args)
331 TcpServer *tcpServer = (TcpServer*)args;
337 /*******************************************************************
339 * @brief Wait for the thread to complete in the parent process
346 * - Waits for the thread to complete in the parent process
349 * @return true : success
351 ******************************************************************/
352 bool TcpServer::wait()
354 return (pthread_join(mThreadId,NULL) == 0);
359 /**********************************************************************
361 **********************************************************************/