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 "cu_f1ap_msg_hdl.h"
23 #include "cu_stub_sctp.h"
24 #include "cu_stub_egtp.h"
27 CuSctpDestCb f1Params;
28 /**************************************************************************
29 * @brief Task Initiation callback function.
33 * Function : sctpActvInit
36 * This function is supplied as one of parameters during SCTP's
37 * task registration. SSI will invoke this function once, after
38 * it creates and attaches this TAPA Task to a system task.
40 * @param[in] Ent entity, the entity ID of this task.
41 * @param[in] Inst inst, the instance ID of this task.
42 * @param[in] Region region, the region ID registered for memory
44 * @param[in] Reason reason.
45 * @return ROK - success
47 ***************************************************************************/
50 DU_LOG("\n\nSCTP : Initializing");
54 sctpCfg = cuCfgParams.sctpParams;
59 /**************************************************************************
60 * @brief Task Activation callback function.
64 * Function : sctpActvTsk
67 * This function handles all SCTP messages received
68 * This API is registered with SSI during the
69 * Task Registration of DU APP.
71 * @param[in] Pst *pst, Post structure of the primitive.
72 * @param[in] Buffer *mBuf, Packed primitive parameters in the
74 * @return ROK - success
77 ***************************************************************************/
78 S16 sctpActvTsk(Pst *pst, Buffer *mBuf)
85 /**************************************************************************
86 * @brief Function to configure the Sctp Params during config Request
90 * Function : duSctpCfgReq
93 * This function configures SCTP Params during the config Request
95 * @return ROK - success
98 ***************************************************************************/
104 f1Params.destPort = sctpCfg.duPort;
105 f1Params.srcPort = sctpCfg.cuPort;
106 f1Params.bReadFdSet = ROK;
107 memset(&f1Params.sockFd, -1, sizeof(CmInetFd));
108 memset(&f1Params.lstnSockFd, -1, sizeof(CmInetFd));
109 fillDestNetAddr(&f1Params.destIpNetAddr, &sctpCfg.duIpAddr);
115 /*******************************************************************
117 * @brief Fills the address List of the source Ip Address
121 * Function : fillAddrLst
124 * Fills the address List of source Ip Address
126 * @params[in] CmInetNetAddrLst *addrLstPtr, Address List pointer
127 * @params[in] F1IpAddr *srcIpAddr, src Ip Adrress to be filled in the Address List
128 * @return ROK - success
131 ******************************************************************/
133 S16 fillAddrLst(CmInetNetAddrLst *addrLstPtr, SctpIpAddr *ipAddr)
136 addrLstPtr->addrs[(addrLstPtr->count - 1)].type = CM_INET_IPV4ADDR_TYPE;
137 addrLstPtr->addrs[(addrLstPtr->count - 1)].u.ipv4NetAddr = CM_INET_NTOH_UINT32(ipAddr->ipV4Addr);
142 /******************************************************************************
144 * @brief Fills the address List of the source Ip Address
148 * Function : fillDestNetAddr
151 * Fills the address List of destinatoion Ip Address
153 * @params[in] CmInetNetAddr *destAddrPtr, Address List pointer
154 * @params[in] F1IpAddr *dstIpAddr, destIp Address to be filled in the Address List
155 * @return ROK - success
158 *******************************************************************************/
159 S16 fillDestNetAddr(CmInetNetAddr *destAddrPtr, SctpIpAddr *dstIpPtr)
161 /* Filling destination address */
162 destAddrPtr->type = CM_INET_IPV4ADDR_TYPE;
163 destAddrPtr->u.ipv4NetAddr = CM_INET_NTOH_UINT32(dstIpPtr->ipV4Addr);
167 /******************************************************************************
169 * @brief Eastablishes the Assoc Req for the received interface type
173 * Function : sctpStartReq
176 * Eastablishes the Assoc Req for the received interface type
178 * @params[in] DuSctpDestCb *paramPtr
179 * @return ROK - success
182 *******************************************************************************/
187 socket_type = CM_INET_STREAM;
188 fillAddrLst(&f1Params.localAddrLst, &sctpCfg.cuIpAddr);
190 if((ret = cmInetSocket(socket_type, &f1Params.lstnSockFd, IPPROTO_SCTP) != ROK))
192 DU_LOG("\nSCTP : Socket[%d] coudnt open for listening", f1Params.lstnSockFd.fd);
194 else if((ret = cmInetSctpBindx(&f1Params.lstnSockFd, &f1Params.localAddrLst, f1Params.srcPort)) != ROK)
196 DU_LOG("\nSCTP: Binding failed at CU");
198 else if((ret = sctpAccept(&f1Params.lstnSockFd, &f1Params.peerAddr, &f1Params.sockFd)) != ROK)
200 DU_LOG("\nSCTP: Unable to accept the connection at CU");
202 else if(sctpSockPoll() != ROK)
204 DU_LOG("\nSCTP: Polling failed to start at CU");
208 /*******************************************************************
210 * @brief Sets socket options as per requirement
214 * Function : sctpSetSockOpts
217 * Sets socket options as per requirement
220 * @return ROK - success
223 * ****************************************************************/
224 S16 sctpSetSockOpts(CmInetFd *sock_Fd)
227 CmSctpEvent sctpEvent;
229 sctpEvent.dataIoEvent = TRUE;
230 sctpEvent.associationEvent = TRUE;
231 sctpEvent.addressEvent = TRUE;
232 sctpEvent.sendFailureEvent = TRUE;
233 sctpEvent.peerErrorEvent = TRUE;
234 sctpEvent.shutdownEvent = TRUE;
235 sctpEvent.partialDeliveryEvent = TRUE;
236 sctpEvent.adaptationLayerEvent = TRUE;
238 if((ret = cmInetSetOpt(sock_Fd, CM_SOCKOPT_LEVEL_SCTP, CM_SOCKOPT_OPT_SCTP_EVENTS, &sctpEvent)) != ROK)
246 /*******************************************************************
248 * @brief Initiates connection with peer SCTP
252 * Function : sctpAccept
255 * Establishes SCTP connection with peer.
256 * Here, DU-SCTP will initate connection towards CU-SCTP
259 * @return ROK - success
262 * ****************************************************************/
263 S16 sctpAccept(CmInetFd *lstnSock_Fd, CmInetAddr *peerAddr, CmInetFd *sock_Fd)
267 ret = cmInetListen(lstnSock_Fd, 1);
270 DU_LOG("\nSCTP : Listening on socket failed");
271 cmInetClose(lstnSock_Fd);
275 DU_LOG("\nSCTP : Connecting");
279 ret = cmInetAccept(lstnSock_Fd, peerAddr, sock_Fd);
286 DU_LOG("\nSCTP : Failed to accept connection");
292 sctpSetSockOpts(sock_Fd);
296 DU_LOG("\nSCTP : Connection established");
301 /*******************************************************************
303 * @brief Handles an SCTP notification message
307 * Function : sctpNtfyHdlr
310 * Handles an SCTP notification message
312 * @params[in] Notify message
314 * @return ROK - success
317 * ****************************************************************/
318 S16 sctpNtfyHdlr(CmInetSctpNotification *ntfy)
320 switch(ntfy->header.nType)
322 case CM_INET_SCTP_ASSOC_CHANGE :
323 DU_LOG("\nSCTP : Assoc change notification received");
324 switch(ntfy->u.assocChange.state)
326 case CM_INET_SCTP_COMM_UP:
327 DU_LOG("Event : COMMUNICATION UP");
330 case CM_INET_SCTP_COMM_LOST:
331 DU_LOG("Event : COMMUNICATION LOST");
334 case CM_INET_SCTP_RESTART:
335 DU_LOG("Event : SCTP RESTART");
338 case CM_INET_SCTP_SHUTDOWN_COMP: /* association gracefully shutdown */
339 DU_LOG("Event : SHUTDOWN COMPLETE");
342 case CM_INET_SCTP_CANT_STR_ASSOC:
343 DU_LOG("Event : CANT START ASSOC");
347 DU_LOG("\nInvalid event");
351 case CM_INET_SCTP_PEER_ADDR_CHANGE :
352 DU_LOG("\nSCTP : Peer Address Change notificarion received");
353 /* Need to add handler */
355 case CM_INET_SCTP_REMOTE_ERROR :
356 DU_LOG("\nSCTP : Remote Error notification received");
358 case CM_INET_SCTP_SEND_FAILED :
359 DU_LOG("\nSCTP : Send Failed notification received\n");
361 case CM_INET_SCTP_SHUTDOWN_EVENT : /* peer socket gracefully closed */
362 DU_LOG("\nSCTP : Shutdown Event notification received\n");
366 case CM_INET_SCTP_ADAPTATION_INDICATION :
367 DU_LOG("\nSCTP : Adaptation Indication received\n");
369 case CM_INET_SCTP_PARTIAL_DELIVERY_EVENT:
370 DU_LOG("\nSCTP : Partial Delivery Event received\n");
373 DU_LOG("\nSCTP : Invalid notification type\n");
379 }/* End of sctpNtfyHdlr */
381 /*******************************************************************
383 * @brief Receives message on the socket
387 * Function : sctpSockPoll
390 * Receives message on the socket
393 * @return ROK - success
396 * ****************************************************************/
401 uint32_t *timeoutPtr;
404 CmInetAddr egtpFromAddr;
405 CmInetMemInfo memInfo;
406 sctpSockPollParams f1PollParams;
408 memset(&f1PollParams, 0, sizeof(sctpSockPollParams));
410 egtpFromAddr.port = egtpCb.dstCb.dstPort;
411 egtpFromAddr.address = egtpCb.dstCb.dstIp;
413 if(f1Params.sockFd.blocking)
422 timeoutPtr = &timeout;
424 memInfo.region = CU_APP_MEM_REG;
425 memInfo.pool = CU_POOL;
427 CM_INET_FD_ZERO(&f1PollParams.readFd);
431 if((ret = processPolling(&f1PollParams, &f1Params.sockFd, timeoutPtr, &memInfo)) != ROK)
433 DU_LOG("\nSCTP : Failed to RecvMsg for F1 at CU\n");
436 /* Receiving EGTP data */
438 ret = cmInetRecvMsg(&(egtpCb.recvTptSrvr.sockFd), &egtpFromAddr, &memInfo, &egtpBuf, &egtpBufLen, CM_INET_NO_FLAG);
439 if(ret == ROK && egtpBuf != NULLP)
441 DU_LOG("\nEGTP : Received message \n");
442 ODU_PRINT_MSG(egtpBuf, 0 ,0);
443 cuEgtpHdlRecvMsg(egtpBuf);
448 }/* End of sctpSockPoll() */
450 /*******************************************************************
452 * @brief checks for valid readFd and process the InetSctpRecvMsg
457 * Function : processPolling
460 * checks for valid readFd and process the InetSctpRecvMsg
463 * @params[in] Params required for polling
464 * @params[in] SockFd for file descriptor
465 * @params[in] timeoutPtr indicates the timeout value
466 * @params[in] MemInfo indicates memory region
468 * @return ROK - success
471 * ****************************************************************/
473 S16 processPolling(sctpSockPollParams *pollParams, CmInetFd *sockFd, uint32_t *timeoutPtr, CmInetMemInfo *memInfo)
476 CM_INET_FD_SET(sockFd, &pollParams->readFd);
477 ret = cmInetSelect(&pollParams->readFd, NULLP, timeoutPtr, &pollParams->numFd);
478 if(CM_INET_FD_ISSET(sockFd, &pollParams->readFd))
480 CM_INET_FD_CLR(sockFd, &pollParams->readFd);
481 ret = cmInetSctpRecvMsg(sockFd, &pollParams->addr, &pollParams->port, memInfo, &pollParams->mBuf, &pollParams->bufLen, &pollParams->info, &pollParams->flag, &pollParams->ntfy);
482 if(connUp & (ret != ROK))
484 f1Params.bReadFdSet = RFAILED;
488 if(((pollParams->flag & CM_INET_SCTP_MSG_NOTIFICATION) != 0) && (ret == ROK))
490 ret = sctpNtfyHdlr(&pollParams->ntfy);
493 DU_LOG("\nSCTP : Failed to process sctp notify msg\n");
496 else if(connUp & (pollParams->port == f1Params.destPort))
498 F1APMsgHdlr(pollParams->mBuf);
499 ODU_PUT_MSG_BUF(pollParams->mBuf);
503 ODU_PUT_MSG_BUF(pollParams->mBuf);
508 }/* End of sctpSockPoll() */
510 /*******************************************************************
512 * @brief Send message on SCTP socket
516 * Function : sctpSend
519 * Send message on SCTP socket
522 * @return ROK - success
525 * ****************************************************************/
526 S16 sctpSend(Buffer *mBuf)
529 MsgLen len; /* number of actually sent octets */
530 CmInetMemInfo memInfo;
532 memInfo.region = CU_APP_MEM_REG;
533 memInfo.pool = CU_POOL;
535 ret = cmInetSctpSendMsg(&f1Params.sockFd, &f1Params.destIpNetAddr, f1Params.destPort, &memInfo, mBuf, &len, 0, FALSE, 0, 0/*SCT_PROTID_NONE*/, RWOULDBLOCK);
537 if(ret != ROK && ret != RWOULDBLOCK)
539 DU_LOG("\nSCTP : Send message failed");
544 } /* End of sctpSend */
546 /**********************************************************************
548 **********************************************************************/