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 "odu_common_codec.h"
23 #include "ric_e2ap_msg_hdl.h"
24 #include "ric_stub_sctp.h"
29 CuSctpDestCb ricParams;
30 RicSctpParams sctpCfg;
31 S16 fillAddrLst(CmInetNetAddrLst *addrLstPtr, SctpIpAddr *ipAddr);
32 S16 fillDestNetAddr(CmInetNetAddr *destAddrPtr, SctpIpAddr *dstIpPtr);
33 /**************************************************************************
34 * @brief Function to configure the Sctp Params during config Request
38 * Function : sctpCfgReq
41 * This function configures SCTP Params during the config Request
43 * @return ROK - success
46 ***************************************************************************/
51 sctpCfg = ricCfgParams.sctpParams;
54 ricParams.destPort = sctpCfg.duPort;
55 ricParams.srcPort = sctpCfg.ricPort;
56 ricParams.bReadFdSet = ROK;
57 memset(&ricParams.sockFd, -1, sizeof(CmInetFd));
58 memset(&ricParams.lstnSockFd, -1, sizeof(CmInetFd));
59 fillDestNetAddr(&ricParams.destIpNetAddr, &sctpCfg.duIpAddr);
64 /*******************************************************************
66 * @brief Fills the address List of the source Ip Address
70 * Function : fillAddrLst
73 * Fills the address List of source Ip Address
75 * @params[in] CmInetNetAddrLst *addrLstPtr, Address List pointer
76 * @params[in] F1IpAddr *srcIpAddr, src Ip Adrress to be filled in the Address List
77 * @return ROK - success
80 ******************************************************************/
82 S16 fillAddrLst(CmInetNetAddrLst *addrLstPtr, SctpIpAddr *ipAddr)
85 addrLstPtr->addrs[(addrLstPtr->count - 1)].type = CM_INET_IPV4ADDR_TYPE;
86 addrLstPtr->addrs[(addrLstPtr->count - 1)].u.ipv4NetAddr = CM_INET_NTOH_U32(ipAddr->ipV4Addr);
91 /******************************************************************************
93 * @brief Fills the address List of the source Ip Address
97 * Function : fillDestNetAddr
100 * Fills the address List of destinatoion Ip Address
102 * @params[in] CmInetNetAddr *destAddrPtr, Address List pointer
103 * @params[in] F1IpAddr *dstIpAddr, destIp Address to be filled in the Address List
104 * @return ROK - success
107 *******************************************************************************/
108 S16 fillDestNetAddr(CmInetNetAddr *destAddrPtr, SctpIpAddr *dstIpPtr)
110 /* Filling destination address */
111 destAddrPtr->type = CM_INET_IPV4ADDR_TYPE;
112 destAddrPtr->u.ipv4NetAddr = CM_INET_NTOH_U32(dstIpPtr->ipV4Addr);
116 /******************************************************************************
118 * @brief Eastablishes the Assoc Req for the received interface type
122 * Function : sctpStartReq
125 * Eastablishes the Assoc Req for the received interface type
127 * @params[in] DuSctpDestCb *paramPtr
128 * @return ROK - success
131 *******************************************************************************/
136 socket_type = CM_INET_STREAM;
137 fillAddrLst(&ricParams.localAddrLst, &sctpCfg.ricIpAddr);
139 if((ret = cmInetSocket(socket_type, &ricParams.lstnSockFd, IPPROTO_SCTP) != ROK))
141 DU_LOG("\nSCTP : Socket[%d] coudnt open for listening", ricParams.lstnSockFd.fd);
143 else if((ret = cmInetSctpBindx(&ricParams.lstnSockFd, &ricParams.localAddrLst, ricParams.srcPort)) != ROK)
145 DU_LOG("\nSCTP: Binding failed at RIC");
147 else if((ret = sctpAccept(&ricParams.lstnSockFd, &ricParams.peerAddr, &ricParams.sockFd)) != ROK)
149 DU_LOG("\nSCTP: Unable to accept the connection at RIC");
151 else if(sctpSockPoll() != ROK)
153 DU_LOG("\nSCTP: Polling failed to start at RIC");
157 /*******************************************************************
159 * @brief Sets socket options as per requirement
163 * Function : sctpSetSockOpts
166 * Sets socket options as per requirement
169 * @return ROK - success
172 * ****************************************************************/
173 S16 sctpSetSockOpts(CmInetFd *sock_Fd)
176 CmSctpEvent sctpEvent;
178 sctpEvent.dataIoEvent = TRUE;
179 sctpEvent.associationEvent = TRUE;
180 sctpEvent.addressEvent = TRUE;
181 sctpEvent.sendFailureEvent = TRUE;
182 sctpEvent.peerErrorEvent = TRUE;
183 sctpEvent.shutdownEvent = TRUE;
184 sctpEvent.partialDeliveryEvent = TRUE;
185 sctpEvent.adaptationLayerEvent = TRUE;
187 if((ret = cmInetSetOpt(sock_Fd, CM_SOCKOPT_LEVEL_SCTP, CM_SOCKOPT_OPT_SCTP_EVENTS, &sctpEvent)) != ROK)
195 /*******************************************************************
197 * @brief Initiates connection with peer SCTP
201 * Function : sctpAccept
204 * Establishes SCTP connection with peer.
205 * Here, DU-SCTP will initate connection towards RIC-SCTP
208 * @return ROK - success
211 * ****************************************************************/
212 S16 sctpAccept(CmInetFd *lstnSock_Fd, CmInetAddr *peerAddr, CmInetFd *sock_Fd)
216 ret = cmInetListen(lstnSock_Fd, 1);
219 DU_LOG("\nSCTP : Listening on socket failed");
220 cmInetClose(lstnSock_Fd);
224 DU_LOG("\nSCTP : Connecting");
228 ret = cmInetAccept(lstnSock_Fd, peerAddr, sock_Fd);
235 DU_LOG("\nSCTP : Failed to accept connection");
241 sctpSetSockOpts(sock_Fd);
245 DU_LOG("\nSCTP : Connection established");
250 /*******************************************************************
252 * @brief Handles an SCTP notification message
256 * Function : sctpNtfyHdlr
259 * Handles an SCTP notification message
261 * @params[in] Notify message
263 * @return ROK - success
266 * ****************************************************************/
267 S16 sctpNtfyHdlr(CmInetSctpNotification *ntfy)
269 switch(ntfy->header.nType)
271 case CM_INET_SCTP_ASSOC_CHANGE :
272 DU_LOG("\nSCTP : Assoc change notification received");
273 switch(ntfy->u.assocChange.state)
275 case CM_INET_SCTP_COMM_UP:
276 DU_LOG("Event : COMMUNICATION UP");
279 case CM_INET_SCTP_COMM_LOST:
280 DU_LOG("Event : COMMUNICATION LOST");
283 case CM_INET_SCTP_RESTART:
284 DU_LOG("Event : SCTP RESTART");
287 case CM_INET_SCTP_SHUTDOWN_COMP: /* association gracefully shutdown */
288 DU_LOG("Event : SHUTDOWN COMPLETE");
291 case CM_INET_SCTP_CANT_STR_ASSOC:
292 DU_LOG("Event : CANT START ASSOC");
296 DU_LOG("\nInvalid event");
300 case CM_INET_SCTP_PEER_ADDR_CHANGE :
301 DU_LOG("\nSCTP : Peer Address Change notificarion received");
302 /* Need to add handler */
304 case CM_INET_SCTP_REMOTE_ERROR :
305 DU_LOG("\nSCTP : Remote Error notification received");
307 case CM_INET_SCTP_SEND_FAILED :
308 DU_LOG("\nSCTP : Send Failed notification received\n");
310 case CM_INET_SCTP_SHUTDOWN_EVENT : /* peer socket gracefully closed */
311 DU_LOG("\nSCTP : Shutdown Event notification received\n");
315 case CM_INET_SCTP_ADAPTATION_INDICATION :
316 DU_LOG("\nSCTP : Adaptation Indication received\n");
318 case CM_INET_SCTP_PARTIAL_DELIVERY_EVENT:
319 DU_LOG("\nSCTP : Partial Delivery Event received\n");
322 DU_LOG("\nSCTP : Invalid notification type\n");
328 }/* End of sctpNtfyHdlr */
330 /*******************************************************************
332 * @brief Receives message on the socket
336 * Function : sctpSockPoll
339 * Receives message on the socket
342 * @return ROK - success
345 * ****************************************************************/
351 CmInetMemInfo memInfo;
352 sctpSockPollParams e2PollParams;
354 memset(&e2PollParams, 0, sizeof(sctpSockPollParams));
356 if(ricParams.sockFd.blocking)
365 timeoutPtr = &timeout;
368 memInfo.region = RIC_APP_MEM_REG;
369 memInfo.pool = RIC_POOL;
371 CM_INET_FD_ZERO(&e2PollParams.readFd);
373 DU_LOG("\nSCTP : Polling started at RIC\n");
376 if((ret = processPolling(&e2PollParams, &ricParams.sockFd, timeoutPtr, &memInfo)) != ROK)
378 DU_LOG("\nSCTP : Failed to RecvMsg for E2 at RIC \n");
382 }/* End of sctpSockPoll() */
384 /*******************************************************************
386 * @brief checks for valid readFd and process the InetSctpRecvMsg
391 * Function : processPolling
394 * checks for valid readFd and process the InetSctpRecvMsg
397 * @params[in] Params required for polling
398 * @params[in] SockFd for file descriptor
399 * @params[in] timeoutPtr indicates the timeout value
400 * @params[in] MemInfo indicates memory region
402 * @return ROK - success
405 * ****************************************************************/
408 S16 processPolling(sctpSockPollParams *pollParams, CmInetFd *sockFd, U32 *timeoutPtr, CmInetMemInfo *memInfo)
411 CM_INET_FD_SET(sockFd, &pollParams->readFd);
412 ret = cmInetSelect(&pollParams->readFd, NULLP, timeoutPtr, &pollParams->numFd);
413 if(CM_INET_FD_ISSET(sockFd, &pollParams->readFd))
415 CM_INET_FD_CLR(sockFd, &pollParams->readFd);
416 ret = cmInetSctpRecvMsg(sockFd, &pollParams->addr, &pollParams->port, memInfo, &pollParams->mBuf, &pollParams->bufLen, &pollParams->info, &pollParams->flag, &pollParams->ntfy);
417 if(connUp & (ret != ROK))
419 ricParams.bReadFdSet = RFAILED;
423 if(((pollParams->flag & CM_INET_SCTP_MSG_NOTIFICATION) != 0) && (ret == ROK))
425 ret = sctpNtfyHdlr(&pollParams->ntfy);
428 DU_LOG("\nSCTP : Failed to process sctp notify msg\n");
431 else if(connUp & (pollParams->port == ricParams.destPort))
433 E2APMsgHdlr(pollParams->mBuf);
434 SPutMsg(pollParams->mBuf);
438 SPutMsg(pollParams->mBuf);
443 }/* End of sctpSockPoll() */
445 /*******************************************************************
447 * @brief Send message on SCTP socket
451 * Function : sctpSend
454 * Send message on SCTP socket
457 * @return ROK - success
460 * ****************************************************************/
461 S16 sctpSend(Buffer *mBuf)
464 MsgLen len; /* number of actually sent octets */
465 CmInetMemInfo memInfo;
467 memInfo.region = RIC_APP_MEM_REG;
468 memInfo.pool = RIC_POOL;
470 ret = cmInetSctpSendMsg(&ricParams.sockFd, &ricParams.destIpNetAddr, ricParams.destPort, &memInfo, mBuf, &len, 0, FALSE, 0, 0/*SCT_PROTID_NONE*/, RWOULDBLOCK);
472 if(ret != ROK && ret != RWOULDBLOCK)
474 DU_LOG("\nSCTP : Send message failed");
479 } /* End of sctpSend */
480 /**********************************************************************
482 **********************************************************************/