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 */
22 #include "ric_e2ap_msg_hdl.h"
23 #include "ric_stub_sctp.h"
25 CuSctpDestCb ricParams;
27 /**************************************************************************
28 * @brief Task Initiation callback function.
32 * Function : sctpActvInit
35 * This function is supplied as one of parameters during SCTP's
36 * task registration. SSI will invoke this function once, after
37 * it creates and attaches this TAPA Task to a system task.
39 * @param[in] Ent entity, the entity ID of this task.
40 * @param[in] Inst inst, the instance ID of this task.
41 * @param[in] Region region, the region ID registered for memory
43 * @param[in] Reason reason.
44 * @return ROK - success
46 ***************************************************************************/
49 DU_LOG("\n\nSCTP : Initializing");
53 sctpCfg = cuCfgParams.sctpParams;
58 /**************************************************************************
59 * @brief Task Activation callback function.
63 * Function : sctpActvTsk
66 * This function handles all SCTP messages received
67 * This API is registered with SSI during the
68 * Task Registration of DU APP.
70 * @param[in] Pst *pst, Post structure of the primitive.
71 * @param[in] Buffer *mBuf, Packed primitive parameters in the
73 * @return ROK - success
76 ***************************************************************************/
77 S16 sctpActvTsk(Pst *pst, Buffer *mBuf)
83 /**************************************************************************
84 * @brief Function to configure the Sctp Params during config Request
88 * Function : duSctpCfgReq
91 * This function configures SCTP Params during the config Request
93 * @return ROK - success
96 ***************************************************************************/
102 ricParams.destPort = sctpCfg.duPort;
103 ricParams.srcPort = sctpCfg.ricPort;
104 ricParams.bReadFdSet = ROK;
105 cmMemset ((U8 *)&ricParams.sockFd, -1, sizeof(CmInetFd));
106 cmMemset ((U8 *)&ricParams.lstnSockFd, -1, sizeof(CmInetFd));
107 fillDestNetAddr(&ricParams.destIpNetAddr, &sctpCfg.duIpAddr);
112 /*******************************************************************
114 * @brief Fills the address List of the source Ip Address
118 * Function : fillAddrLst
121 * Fills the address List of source Ip Address
123 * @params[in] CmInetNetAddrLst *addrLstPtr, Address List pointer
124 * @params[in] F1IpAddr *srcIpAddr, src Ip Adrress to be filled in the Address List
125 * @return ROK - success
128 ******************************************************************/
130 S16 fillAddrLst(CmInetNetAddrLst *addrLstPtr, SctpIpAddr *ipAddr)
133 addrLstPtr->addrs[(addrLstPtr->count - 1)].type = CM_INET_IPV4ADDR_TYPE;
134 addrLstPtr->addrs[(addrLstPtr->count - 1)].u.ipv4NetAddr = CM_INET_NTOH_U32(ipAddr->ipV4Addr);
139 /******************************************************************************
141 * @brief Fills the address List of the source Ip Address
145 * Function : fillDestNetAddr
148 * Fills the address List of destinatoion Ip Address
150 * @params[in] CmInetNetAddr *destAddrPtr, Address List pointer
151 * @params[in] F1IpAddr *dstIpAddr, destIp Address to be filled in the Address List
152 * @return ROK - success
155 *******************************************************************************/
156 S16 fillDestNetAddr(CmInetNetAddr *destAddrPtr, SctpIpAddr *dstIpPtr)
158 /* Filling destination address */
159 destAddrPtr->type = CM_INET_IPV4ADDR_TYPE;
160 destAddrPtr->u.ipv4NetAddr = CM_INET_NTOH_U32(dstIpPtr->ipV4Addr);
164 /******************************************************************************
166 * @brief Eastablishes the Assoc Req for the received interface type
170 * Function : sctpStartReq
173 * Eastablishes the Assoc Req for the received interface type
175 * @params[in] DuSctpDestCb *paramPtr
176 * @return ROK - success
179 *******************************************************************************/
184 socket_type = CM_INET_STREAM;
185 fillAddrLst(&ricParams.localAddrLst, &sctpCfg.ricIpAddr);
187 if((ret = cmInetSocket(socket_type, &ricParams.lstnSockFd, IPPROTO_SCTP) != ROK))
189 DU_LOG("\nSCTP : Socket[%d] coudnt open for listening", ricParams.lstnSockFd.fd);
191 else if((ret = cmInetSctpBindx(&ricParams.lstnSockFd, &ricParams.localAddrLst, ricParams.srcPort)) != ROK)
193 DU_LOG("\nSCTP: Binding failed at CU");
195 else if((ret = sctpAccept(&ricParams.lstnSockFd, &ricParams.peerAddr, &ricParams.sockFd)) != ROK)
197 DU_LOG("\nSCTP: Unable to accept the connection at CU");
199 else if(sctpSockPoll() != ROK)
201 DU_LOG("\nSCTP: Polling failed to start at RIC");
205 /*******************************************************************
207 * @brief Sets socket options as per requirement
211 * Function : sctpSetSockOpts
214 * Sets socket options as per requirement
217 * @return ROK - success
220 * ****************************************************************/
221 S16 sctpSetSockOpts(CmInetFd *sock_Fd)
224 CmSctpEvent sctpEvent;
226 sctpEvent.dataIoEvent = TRUE;
227 sctpEvent.associationEvent = TRUE;
228 sctpEvent.addressEvent = TRUE;
229 sctpEvent.sendFailureEvent = TRUE;
230 sctpEvent.peerErrorEvent = TRUE;
231 sctpEvent.shutdownEvent = TRUE;
232 sctpEvent.partialDeliveryEvent = TRUE;
233 sctpEvent.adaptationLayerEvent = TRUE;
235 if((ret = cmInetSetOpt(sock_Fd, CM_SOCKOPT_LEVEL_SCTP, CM_SOCKOPT_OPT_SCTP_EVENTS, &sctpEvent)) != ROK)
243 /*******************************************************************
245 * @brief Initiates connection with peer SCTP
249 * Function : sctpAccept
252 * Establishes SCTP connection with peer.
253 * Here, DU-SCTP will initate connection towards RIC-SCTP
256 * @return ROK - success
259 * ****************************************************************/
260 S16 sctpAccept(CmInetFd *lstnSock_Fd, CmInetAddr *peerAddr, CmInetFd *sock_Fd)
264 ret = cmInetListen(lstnSock_Fd, 1);;
267 DU_LOG("\nSCTP : Listening on socket failed");
268 cmInetClose(lstnSock_Fd);
272 DU_LOG("\nSCTP : Connecting");
276 ret = cmInetAccept(lstnSock_Fd, peerAddr, sock_Fd);
283 DU_LOG("\nSCTP : Failed to accept connection");
289 sctpSetSockOpts(sock_Fd);
293 DU_LOG("\nSCTP : Connection established");
298 /*******************************************************************
300 * @brief Handles an SCTP notification message
304 * Function : sctpNtfyHdlr
307 * Handles an SCTP notification message
309 * @params[in] Notify message
311 * @return ROK - success
314 * ****************************************************************/
315 S16 sctpNtfyHdlr(CmInetSctpNotification *ntfy)
317 switch(ntfy->header.nType)
319 case CM_INET_SCTP_ASSOC_CHANGE :
320 DU_LOG("\nSCTP : Assoc change notification received");
321 switch(ntfy->u.assocChange.state)
323 case CM_INET_SCTP_COMM_UP:
324 DU_LOG("Event : COMMUNICATION UP");
327 case CM_INET_SCTP_COMM_LOST:
328 DU_LOG("Event : COMMUNICATION LOST");
331 case CM_INET_SCTP_RESTART:
332 DU_LOG("Event : SCTP RESTART");
335 case CM_INET_SCTP_SHUTDOWN_COMP: /* association gracefully shutdown */
336 DU_LOG("Event : SHUTDOWN COMPLETE");
339 case CM_INET_SCTP_CANT_STR_ASSOC:
340 DU_LOG("Event : CANT START ASSOC");
344 DU_LOG("\nInvalid event");
348 case CM_INET_SCTP_PEER_ADDR_CHANGE :
349 DU_LOG("\nSCTP : Peer Address Change notificarion received");
350 /* Need to add handler */
352 case CM_INET_SCTP_REMOTE_ERROR :
353 DU_LOG("\nSCTP : Remote Error notification received");
355 case CM_INET_SCTP_SEND_FAILED :
356 DU_LOG("\nSCTP : Send Failed notification received\n");
358 case CM_INET_SCTP_SHUTDOWN_EVENT : /* peer socket gracefully closed */
359 DU_LOG("\nSCTP : Shutdown Event notification received\n");
363 case CM_INET_SCTP_ADAPTATION_INDICATION :
364 DU_LOG("\nSCTP : Adaptation Indication received\n");
366 case CM_INET_SCTP_PARTIAL_DELIVERY_EVENT:
367 DU_LOG("\nSCTP : Partial Delivery Event received\n");
370 DU_LOG("\nSCTP : Invalid notification type\n");
376 }/* End of sctpNtfyHdlr */
378 /*******************************************************************
380 * @brief Receives message on the socket
384 * Function : sctpSockPoll
387 * Receives message on the socket
390 * @return ROK - success
393 * ****************************************************************/
399 CmInetMemInfo memInfo;
400 sctpSockPollParams e2PollParams;
402 memset(&e2PollParams, 0, sizeof(sctpSockPollParams));
404 if(ricParams.sockFd.blocking)
413 timeoutPtr = &timeout;
416 memInfo.region = RIC_APP_MEM_REG;
417 memInfo.pool = RIC_POOL;
419 CM_INET_FD_ZERO(&e2PollParams.readFd);
421 DU_LOG("\nSCTP : Polling started at RIC\n");
424 if((ret = processPolling(&e2PollParams, &ricParams.sockFd, timeoutPtr, &memInfo)) != ROK)
426 DU_LOG("\nSCTP : Failed to RecvMsg for E2 at CU \n");
430 }/* End of sctpSockPoll() */
432 /*******************************************************************
434 * @brief checks for valid readFd and process the InetSctpRecvMsg
439 * Function : processPolling
442 * checks for valid readFd and process the InetSctpRecvMsg
445 * @params[in] Params required for polling
446 * @params[in] SockFd for file descriptor
447 * @params[in] timeoutPtr indicates the timeout value
448 * @params[in] MemInfo indicates memory region
450 * @return ROK - success
453 * ****************************************************************/
456 S16 processPolling(sctpSockPollParams *pollParams, CmInetFd *sockFd, U32 *timeoutPtr, CmInetMemInfo *memInfo)
459 CM_INET_FD_SET(sockFd, &pollParams->readFd);
460 ret = cmInetSelect(&pollParams->readFd, NULLP, timeoutPtr, &pollParams->numFds);
461 if(CM_INET_FD_ISSET(sockFd, &pollParams->readFd))
463 CM_INET_FD_CLR(sockFd, &pollParams->readFd);
464 ret = cmInetSctpRecvMsg(sockFd, &pollParams->addr, &pollParams->port, memInfo, &pollParams->mBuf, &pollParams->bufLen, &pollParams->info, &pollParams->flag, &pollParams->ntfy);
465 if(connUp & (ret != ROK))
467 ricParams.bReadFdSet = RFAILED;
471 if(((pollParams->flag & CM_INET_SCTP_MSG_NOTIFICATION) != 0) && (ret == ROK))
473 ret = sctpNtfyHdlr(&pollParams->ntfy);
476 DU_LOG("\nSCTP : Failed to process sctp notify msg\n");
479 else if(connUp & (pollParams->port == ricParams.destPort))
481 E2APMsgHdlr(pollParams->mBuf);
482 SPutMsg(pollParams->mBuf);
486 SPutMsg(pollParams->mBuf);
491 }/* End of sctpSockPoll() */
493 /*******************************************************************
495 * @brief Send message on SCTP socket
499 * Function : sctpSend
502 * Send message on SCTP socket
505 * @return ROK - success
508 * ****************************************************************/
509 S16 sctpSend(Buffer *mBuf)
512 MsgLen len; /* number of actually sent octets */
513 CmInetMemInfo memInfo;
515 memInfo.region = RIC_APP_MEM_REG;
516 memInfo.pool = RIC_POOL;
518 ret = cmInetSctpSendMsg(&ricParams.sockFd, &ricParams.destIpNetAddr, ricParams.destPort, &memInfo, mBuf, &len, 0, FALSE, 0, 0/*SCT_PROTID_NONE*/, RWOULDBLOCK);
520 if(ret != ROK && ret != RWOULDBLOCK)
522 DU_LOG("\nSCTP : Send message failed");
527 } /* End of sctpSend */
528 /**********************************************************************
530 **********************************************************************/