1 /*******************************************************************************
2 ################################################################################
3 # Copyright (c) [2017-2019] [Radisys] #
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 all SCTP related functionality */
21 #include "common_def.h"
22 #include "ric_e2ap_msg_hdl.h"
23 #include "ric_stub_sctp.h"
28 CuSctpDestCb ricParams;
29 RicSctpParams sctpCfg;
30 S16 fillAddrLst(CmInetNetAddrLst *addrLstPtr, SctpIpAddr *ipAddr);
31 S16 fillDestNetAddr(CmInetNetAddr *destAddrPtr, SctpIpAddr *dstIpPtr);
32 /**************************************************************************
33 * @brief Function to configure the Sctp Params during config Request
37 * Function : sctpCfgReq
40 * This function configures SCTP Params during the config Request
42 * @return ROK - success
45 ***************************************************************************/
50 sctpCfg = ricCfgParams.sctpParams;
53 ricParams.destPort = sctpCfg.duPort;
54 ricParams.srcPort = sctpCfg.ricPort;
55 ricParams.bReadFdSet = ROK;
56 memset(&ricParams.sockFd, -1, sizeof(CmInetFd));
57 memset(&ricParams.lstnSockFd, -1, sizeof(CmInetFd));
58 fillDestNetAddr(&ricParams.destIpNetAddr, &sctpCfg.duIpAddr);
63 /*******************************************************************
65 * @brief Fills the address List of the source Ip Address
69 * Function : fillAddrLst
72 * Fills the address List of source Ip Address
74 * @params[in] CmInetNetAddrLst *addrLstPtr, Address List pointer
75 * @params[in] F1IpAddr *srcIpAddr, src Ip Adrress to be filled in the Address List
76 * @return ROK - success
79 ******************************************************************/
81 S16 fillAddrLst(CmInetNetAddrLst *addrLstPtr, SctpIpAddr *ipAddr)
84 addrLstPtr->addrs[(addrLstPtr->count - 1)].type = CM_INET_IPV4ADDR_TYPE;
85 addrLstPtr->addrs[(addrLstPtr->count - 1)].u.ipv4NetAddr = CM_INET_NTOH_U32(ipAddr->ipV4Addr);
90 /******************************************************************************
92 * @brief Fills the address List of the source Ip Address
96 * Function : fillDestNetAddr
99 * Fills the address List of destinatoion Ip Address
101 * @params[in] CmInetNetAddr *destAddrPtr, Address List pointer
102 * @params[in] F1IpAddr *dstIpAddr, destIp Address to be filled in the Address List
103 * @return ROK - success
106 *******************************************************************************/
107 S16 fillDestNetAddr(CmInetNetAddr *destAddrPtr, SctpIpAddr *dstIpPtr)
109 /* Filling destination address */
110 destAddrPtr->type = CM_INET_IPV4ADDR_TYPE;
111 destAddrPtr->u.ipv4NetAddr = CM_INET_NTOH_U32(dstIpPtr->ipV4Addr);
115 /******************************************************************************
117 * @brief Eastablishes the Assoc Req for the received interface type
121 * Function : sctpStartReq
124 * Eastablishes the Assoc Req for the received interface type
126 * @params[in] DuSctpDestCb *paramPtr
127 * @return ROK - success
130 *******************************************************************************/
135 socket_type = CM_INET_STREAM;
136 fillAddrLst(&ricParams.localAddrLst, &sctpCfg.ricIpAddr);
138 if((ret = cmInetSocket(socket_type, &ricParams.lstnSockFd, IPPROTO_SCTP) != ROK))
140 DU_LOG("\nSCTP : Socket[%d] coudnt open for listening", ricParams.lstnSockFd.fd);
142 else if((ret = cmInetSctpBindx(&ricParams.lstnSockFd, &ricParams.localAddrLst, ricParams.srcPort)) != ROK)
144 DU_LOG("\nSCTP: Binding failed at RIC");
146 else if((ret = sctpAccept(&ricParams.lstnSockFd, &ricParams.peerAddr, &ricParams.sockFd)) != ROK)
148 DU_LOG("\nSCTP: Unable to accept the connection at RIC");
150 else if(sctpSockPoll() != ROK)
152 DU_LOG("\nSCTP: Polling failed to start at RIC");
156 /*******************************************************************
158 * @brief Sets socket options as per requirement
162 * Function : sctpSetSockOpts
165 * Sets socket options as per requirement
168 * @return ROK - success
171 * ****************************************************************/
172 S16 sctpSetSockOpts(CmInetFd *sock_Fd)
175 CmSctpEvent sctpEvent;
177 sctpEvent.dataIoEvent = TRUE;
178 sctpEvent.associationEvent = TRUE;
179 sctpEvent.addressEvent = TRUE;
180 sctpEvent.sendFailureEvent = TRUE;
181 sctpEvent.peerErrorEvent = TRUE;
182 sctpEvent.shutdownEvent = TRUE;
183 sctpEvent.partialDeliveryEvent = TRUE;
184 sctpEvent.adaptationLayerEvent = TRUE;
186 if((ret = cmInetSetOpt(sock_Fd, CM_SOCKOPT_LEVEL_SCTP, CM_SOCKOPT_OPT_SCTP_EVENTS, &sctpEvent)) != ROK)
194 /*******************************************************************
196 * @brief Initiates connection with peer SCTP
200 * Function : sctpAccept
203 * Establishes SCTP connection with peer.
204 * Here, DU-SCTP will initate connection towards RIC-SCTP
207 * @return ROK - success
210 * ****************************************************************/
211 S16 sctpAccept(CmInetFd *lstnSock_Fd, CmInetAddr *peerAddr, CmInetFd *sock_Fd)
215 ret = cmInetListen(lstnSock_Fd, 1);
218 DU_LOG("\nSCTP : Listening on socket failed");
219 cmInetClose(lstnSock_Fd);
223 DU_LOG("\nSCTP : Connecting");
227 ret = cmInetAccept(lstnSock_Fd, peerAddr, sock_Fd);
234 DU_LOG("\nSCTP : Failed to accept connection");
240 sctpSetSockOpts(sock_Fd);
244 DU_LOG("\nSCTP : Connection established");
249 /*******************************************************************
251 * @brief Handles an SCTP notification message
255 * Function : sctpNtfyHdlr
258 * Handles an SCTP notification message
260 * @params[in] Notify message
262 * @return ROK - success
265 * ****************************************************************/
266 S16 sctpNtfyHdlr(CmInetSctpNotification *ntfy)
268 switch(ntfy->header.nType)
270 case CM_INET_SCTP_ASSOC_CHANGE :
271 DU_LOG("\nSCTP : Assoc change notification received");
272 switch(ntfy->u.assocChange.state)
274 case CM_INET_SCTP_COMM_UP:
275 DU_LOG("Event : COMMUNICATION UP");
278 case CM_INET_SCTP_COMM_LOST:
279 DU_LOG("Event : COMMUNICATION LOST");
282 case CM_INET_SCTP_RESTART:
283 DU_LOG("Event : SCTP RESTART");
286 case CM_INET_SCTP_SHUTDOWN_COMP: /* association gracefully shutdown */
287 DU_LOG("Event : SHUTDOWN COMPLETE");
290 case CM_INET_SCTP_CANT_STR_ASSOC:
291 DU_LOG("Event : CANT START ASSOC");
295 DU_LOG("\nInvalid event");
299 case CM_INET_SCTP_PEER_ADDR_CHANGE :
300 DU_LOG("\nSCTP : Peer Address Change notificarion received");
301 /* Need to add handler */
303 case CM_INET_SCTP_REMOTE_ERROR :
304 DU_LOG("\nSCTP : Remote Error notification received");
306 case CM_INET_SCTP_SEND_FAILED :
307 DU_LOG("\nSCTP : Send Failed notification received\n");
309 case CM_INET_SCTP_SHUTDOWN_EVENT : /* peer socket gracefully closed */
310 DU_LOG("\nSCTP : Shutdown Event notification received\n");
314 case CM_INET_SCTP_ADAPTATION_INDICATION :
315 DU_LOG("\nSCTP : Adaptation Indication received\n");
317 case CM_INET_SCTP_PARTIAL_DELIVERY_EVENT:
318 DU_LOG("\nSCTP : Partial Delivery Event received\n");
321 DU_LOG("\nSCTP : Invalid notification type\n");
327 }/* End of sctpNtfyHdlr */
329 /*******************************************************************
331 * @brief Receives message on the socket
335 * Function : sctpSockPoll
338 * Receives message on the socket
341 * @return ROK - success
344 * ****************************************************************/
350 CmInetMemInfo memInfo;
351 sctpSockPollParams e2PollParams;
353 memset(&e2PollParams, 0, sizeof(sctpSockPollParams));
355 if(ricParams.sockFd.blocking)
364 timeoutPtr = &timeout;
367 memInfo.region = RIC_APP_MEM_REG;
368 memInfo.pool = RIC_POOL;
370 CM_INET_FD_ZERO(&e2PollParams.readFd);
372 DU_LOG("\nSCTP : Polling started at RIC\n");
375 if((ret = processPolling(&e2PollParams, &ricParams.sockFd, timeoutPtr, &memInfo)) != ROK)
377 DU_LOG("\nSCTP : Failed to RecvMsg for E2 at RIC \n");
381 }/* End of sctpSockPoll() */
383 /*******************************************************************
385 * @brief checks for valid readFd and process the InetSctpRecvMsg
390 * Function : processPolling
393 * checks for valid readFd and process the InetSctpRecvMsg
396 * @params[in] Params required for polling
397 * @params[in] SockFd for file descriptor
398 * @params[in] timeoutPtr indicates the timeout value
399 * @params[in] MemInfo indicates memory region
401 * @return ROK - success
404 * ****************************************************************/
407 S16 processPolling(sctpSockPollParams *pollParams, CmInetFd *sockFd, U32 *timeoutPtr, CmInetMemInfo *memInfo)
410 CM_INET_FD_SET(sockFd, &pollParams->readFd);
411 ret = cmInetSelect(&pollParams->readFd, NULLP, timeoutPtr, &pollParams->numFd);
412 if(CM_INET_FD_ISSET(sockFd, &pollParams->readFd))
414 CM_INET_FD_CLR(sockFd, &pollParams->readFd);
415 ret = cmInetSctpRecvMsg(sockFd, &pollParams->addr, &pollParams->port, memInfo, &pollParams->mBuf, &pollParams->bufLen, &pollParams->info, &pollParams->flag, &pollParams->ntfy);
416 if(connUp & (ret != ROK))
418 ricParams.bReadFdSet = RFAILED;
422 if(((pollParams->flag & CM_INET_SCTP_MSG_NOTIFICATION) != 0) && (ret == ROK))
424 ret = sctpNtfyHdlr(&pollParams->ntfy);
427 DU_LOG("\nSCTP : Failed to process sctp notify msg\n");
430 else if(connUp & (pollParams->port == ricParams.destPort))
432 E2APMsgHdlr(pollParams->mBuf);
433 ODU_PUT_MSG(pollParams->mBuf);
437 ODU_PUT_MSG(pollParams->mBuf);
442 }/* End of sctpSockPoll() */
444 /*******************************************************************
446 * @brief Send message on SCTP socket
450 * Function : sctpSend
453 * Send message on SCTP socket
456 * @return ROK - success
459 * ****************************************************************/
460 S16 sctpSend(Buffer *mBuf)
463 MsgLen len; /* number of actually sent octets */
464 CmInetMemInfo memInfo;
466 memInfo.region = RIC_APP_MEM_REG;
467 memInfo.pool = RIC_POOL;
469 ret = cmInetSctpSendMsg(&ricParams.sockFd, &ricParams.destIpNetAddr, ricParams.destPort, &memInfo, mBuf, &len, 0, FALSE, 0, 0/*SCT_PROTID_NONE*/, RWOULDBLOCK);
471 if(ret != ROK && ret != RWOULDBLOCK)
473 DU_LOG("\nSCTP : Send message failed");
478 } /* End of sctpSend */
479 /**********************************************************************
481 **********************************************************************/