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 "cu_f1ap_msg_hdl.h"
23 #include "cu_stub_sctp.h"
24 #include "cu_stub_egtp.h"
26 /**************************************************************************
27 * @brief Task Initiation callback function.
31 * Function : sctpActvInit
34 * This function is supplied as one of parameters during SCTP's
35 * task registration. SSI will invoke this function once, after
36 * it creates and attaches this TAPA Task to a system task.
38 * @param[in] Ent entity, the entity ID of this task.
39 * @param[in] Inst inst, the instance ID of this task.
40 * @param[in] Region region, the region ID registered for memory
42 * @param[in] Reason reason.
43 * @return ROK - success
45 ***************************************************************************/
48 DU_LOG("\n\nSCTP : Initializing");
52 sctpCfg = &(cuCfgParams.sctpParams);
57 /**************************************************************************
58 * @brief Task Activation callback function.
62 * Function : sctpActvTsk
65 * This function handles all SCTP messages received
66 * This API is registered with SSI during the
67 * Task Registration of DU APP.
69 * @param[in] Pst *pst, Post structure of the primitive.
70 * @param[in] Buffer *mBuf, Packed primitive parameters in the
72 * @return ROK - success
75 ***************************************************************************/
76 S16 sctpActvTsk(Pst *pst, Buffer *mBuf)
83 /*******************************************************************
85 * @brief Opens a non-blocking socket and binds to local address
89 * Function : openSctpEndp
92 * Opens a non-blocking socket and binds to local address
95 * @return ROK - success
98 * ****************************************************************/
104 /* Opening a non-blocking SCTP socket */
105 socket_type = CM_INET_STREAM;
108 ret = cmInetSocket(socket_type, &lstnSockFd, IPPROTO_SCTP);
112 if(numRetry >= MAX_RETRY)
114 DU_LOG("\nSCTP : All attempts to open socket failed.");
115 /* Send indication to du_app */
120 DU_LOG("\nSCTP : Retrying socket opening");
125 DU_LOG("\nSCTP : Socket[%d] open",lstnSockFd.fd);
128 }while(numRetry < MAX_RETRY);
131 } /* End of openSctpEndp */
134 /*******************************************************************
136 * @brief Bind socket to local Ip address and port
140 * Function : bindSctpEndp
143 * -Bind socket to local Ip address and port
146 * @return ROK - success
149 * ****************************************************************/
156 /* Binding the socket with local address */
157 localAddrLst.count = 1;
158 if(sctpCfg->cuIpAddr.ipV4Pres)
160 localAddrLst.addrs[0].type = CM_INET_IPV4ADDR_TYPE;
161 localAddrLst.addrs[0].u.ipv4NetAddr = CM_INET_NTOH_U32(sctpCfg->cuIpAddr.ipV4Addr);
163 else if(sctpCfg->cuIpAddr.ipV6Pres)
165 localAddrLst.addrs[0].type = CM_INET_IPV6ADDR_TYPE;
166 // CM_INET_COPY_IPV6ADDR(&(localAddrLst.addrs[0].u.ipv6NetAddr),&(sctpCfg->cuIpAddr.ipV6Addr);
170 localAddrLst.addrs[0].type = CM_INET_IPV4ADDR_TYPE;
171 localAddrLst.addrs[0].u.ipv4NetAddr = 0;
175 ret = cmInetSctpBindx(&lstnSockFd, &localAddrLst, sctpCfg->cuPort);
179 if(numRetry >= MAX_RETRY)
181 DU_LOG("\nSCTP : All attempts to bind socket failed.");
182 cmInetClose(&lstnSockFd);
183 /* Send indication to du_app */
188 DU_LOG("\nSCTP : Retrying socket binding");
193 DU_LOG("\nSCTP : Socket bind successful");
196 }while(numRetry < MAX_RETRY);
200 } /* End of bindSctpEndp() */
202 /*******************************************************************
204 * @brief Sets socket options as per requirement
208 * Function : sctpSetSockOpts
211 * Sets socket options as per requirement
214 * @return ROK - success
217 * ****************************************************************/
218 S16 sctpSetSockOpts()
220 CmSctpEvent sctpEvent;
222 sctpEvent.dataIoEvent = TRUE;
223 sctpEvent.associationEvent = TRUE;
224 sctpEvent.addressEvent = TRUE;
225 sctpEvent.sendFailureEvent = TRUE;
226 sctpEvent.peerErrorEvent = TRUE;
227 sctpEvent.shutdownEvent = TRUE;
228 sctpEvent.partialDeliveryEvent = TRUE;
229 sctpEvent.adaptationLayerEvent = TRUE;
231 cmInetSetOpt(&sockFd, CM_SOCKOPT_LEVEL_SCTP, CM_SOCKOPT_OPT_SCTP_EVENTS, &sctpEvent);
235 /*******************************************************************
237 * @brief Initiates connection with peer SCTP
241 * Function : sctpAccept
244 * Establishes SCTP connection with peer.
245 * Here, DU-SCTP will initate connection towards CU-SCTP
248 * @return ROK - success
251 * ****************************************************************/
257 ret = cmInetListen(&lstnSockFd, 1);;
260 DU_LOG("\nSCTP : Listening on socket failed");
261 cmInetClose(&lstnSockFd);
265 DU_LOG("\nSCTP : Connecting");
269 ret = cmInetAccept(&lstnSockFd, &peerAddr, &sockFd);
276 DU_LOG("\nSCTP : Failed to accept connection");
286 DU_LOG("\nSCTP : Connection established");
289 }/* End of sctpAccept() */
291 /*******************************************************************
293 * @brief Handles an SCTP notification message
297 * Function : sctpNtfyHdlr
300 * Handles an SCTP notification message
302 * @params[in] Notify message
304 * @return ROK - success
307 * ****************************************************************/
308 S16 sctpNtfyHdlr(CmInetSctpNotification *ntfy)
310 switch(ntfy->header.nType)
312 case CM_INET_SCTP_ASSOC_CHANGE :
313 DU_LOG("\nSCTP : Assoc change notification received");
314 switch(ntfy->u.assocChange.state)
316 case CM_INET_SCTP_COMM_UP:
317 DU_LOG("Event : COMMUNICATION UP");
320 case CM_INET_SCTP_COMM_LOST:
321 DU_LOG("Event : COMMUNICATION LOST");
324 case CM_INET_SCTP_RESTART:
325 DU_LOG("Event : SCTP RESTART");
328 case CM_INET_SCTP_SHUTDOWN_COMP: /* association gracefully shutdown */
329 DU_LOG("Event : SHUTDOWN COMPLETE");
332 case CM_INET_SCTP_CANT_STR_ASSOC:
333 DU_LOG("Event : CANT START ASSOC");
337 DU_LOG("\nInvalid event");
341 case CM_INET_SCTP_PEER_ADDR_CHANGE :
342 DU_LOG("\nSCTP : Peer Address Change notificarion received");
343 /* Need to add handler */
345 case CM_INET_SCTP_REMOTE_ERROR :
346 DU_LOG("\nSCTP : Remote Error notification received");
348 case CM_INET_SCTP_SEND_FAILED :
349 DU_LOG("\nSCTP : Send Failed notification received\n");
351 case CM_INET_SCTP_SHUTDOWN_EVENT : /* peer socket gracefully closed */
352 DU_LOG("\nSCTP : Shutdown Event notification received\n");
354 exit(1);//Exit process on shutdown indication
356 case CM_INET_SCTP_ADAPTATION_INDICATION :
357 DU_LOG("\nSCTP : Adaptation Indication received\n");
359 case CM_INET_SCTP_PARTIAL_DELIVERY_EVENT:
360 DU_LOG("\nSCTP : Partial Delivery Event received\n");
363 DU_LOG("\nSCTP : Invalid notification type\n");
369 }/* End of sctpNtfyHdlr */
371 /*******************************************************************
373 * @brief Receives message on the socket
377 * Function : sctpSockPoll
380 * Receives message on the socket
383 * @return ROK - success
386 * ****************************************************************/
393 U32 timeout; /* timeout for cmInetSelect() */
394 U32 *timeoutPtr; /* pointer to timeout */
400 CmInetAddr egtpFromAddr; /* Egtp data sender address */
401 CmInetMemInfo memInfo; /* buffer allocation info */
403 CmInetSctpSndRcvInfo info;
404 CmInetSctpNotification ntfy;
415 timeoutPtr = &timeout;
417 memInfo.region = CU_APP_MEM_REG;
418 memInfo.pool = CU_POOL;
420 egtpFromAddr.port = egtpCb.dstCb.dstPort;
421 egtpFromAddr.address = egtpCb.dstCb.dstIp;
423 CM_INET_FD_ZERO(&readFd);
427 /* Receiving SCTP data */
428 CM_INET_FD_SET(&sockFd, &readFd);
429 ret = cmInetSelect(&readFd, NULLP, timeoutPtr, &numFds);
430 if (CM_INET_FD_ISSET(&sockFd, &readFd))
432 CM_INET_FD_CLR(&sockFd, &readFd);
433 ret = cmInetSctpRecvMsg(&sockFd, &addr, &port, &memInfo, &mBuf, &bufLen, &info, &flag, &ntfy);
436 DU_LOG("\nSCTP : Failed to receive sctp msg\n");
440 if ((flag & CM_INET_SCTP_MSG_NOTIFICATION) != 0)
442 ret = sctpNtfyHdlr(&ntfy);
445 DU_LOG("\nSCTP : Failed to process sctp notify msg\n");
448 else if(connUp) /* If data received */
460 /* Receiving EGTP data */
462 ret = cmInetRecvMsg(&(egtpCb.recvTptSrvr.sockFd), &egtpFromAddr, &memInfo, &egtpBuf, &egtpBufLen, CM_INET_NO_FLAG);
463 if(ret == ROK && egtpBuf != NULLP)
465 DU_LOG("\nEGTP : Received message \n");
466 SPrntMsg(egtpBuf, 0 ,0);
467 cuEgtpHdlRecvMsg(egtpBuf);
473 }/* End of sctpSockPoll() */
475 /*******************************************************************
477 * @brief Send message on SCTP socket
481 * Function : sctpSend
484 * Send message on SCTP socket
487 * @return ROK - success
490 * ****************************************************************/
491 S16 sctpSend(Buffer *mBuf)
494 MsgLen len; /* number of actually sent octets */
495 CmInetNetAddr peerAddr; /* destination port address */
496 CmInetNetAddr *dstAddr;
497 CmInetMemInfo memInfo;
499 memInfo.region = CU_APP_MEM_REG;
500 memInfo.pool = CU_POOL;
503 if(sctpCfg->duIpAddr.ipV4Pres)
505 peerAddr.type = CM_INET_IPV4ADDR_TYPE;
506 peerAddr.u.ipv4NetAddr = CM_INET_NTOH_U32(sctpCfg->duIpAddr.ipV4Addr);
509 else if(sctpCfg->duIpAddr.ipV6Pres)
511 peerAddr.type = CM_INET_IPV6ADDR_TYPE;
512 //CM_INET_COPY_IPV6ADDR(&(primDstAddr.u.ipv6NetAddr),&(sctpCfg->duIpAddr.ipV6Addr);
520 ret = cmInetSctpSendMsg(&sockFd, dstAddr, sctpCfg->duPort, &memInfo, mBuf, &len, 0, FALSE, 0, 0/*SCT_PROTID_NONE*/, RWOULDBLOCK);
521 if(ret != ROK && ret != RWOULDBLOCK)
523 DU_LOG("\nSCTP : Send message failed");
528 } /* End of sctpSend */
530 /*******************************************************************
532 * @brief Start SCTP at CU
536 * Function : sctpStartReq
542 * @return ROK - success
545 * ****************************************************************/
548 if(openSctpEndp() != ROK)
550 DU_LOG("\nSCTP : Failed while opening socket");
552 else if(bindSctpEndp() != ROK)
554 DU_LOG("\nSCTP : Failed while binding socket");
556 else if(sctpAccept() != ROK)
558 DU_LOG("\nSCTP : Failed while accepting connection");
560 else if(sctpSockPoll() != ROK)
562 DU_LOG("\nSCTP : Failed while polling");
564 } /* End of sctpAssocReq */
566 /**********************************************************************
568 **********************************************************************/