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 "f1ap_msg_hdl.h"
23 #include "cu_stub_sctp.h"
25 /* Global variable declaration */
26 CmInetFd lstnSockFd; /* Listening Socket file descriptor */
27 CmInetFd sockFd; /* Socket File descriptor */
28 U8 socket_type; /* Socket type */
29 Bool nonblocking; /* Blocking/Non-blocking socket */
30 Bool connUp; /* Is connection up */
31 int assocId; /* Assoc Id of connected assoc */
33 CmInetNetAddrLst localAddrLst;
34 CmInetNetAddrLst remoteAddrLst;
36 SctpParams *sctpCfg; /* SCTP configurations at DU */
38 /**************************************************************************
39 * @brief Task Initiation callback function.
43 * Function : sctpActvInit
46 * This function is supplied as one of parameters during SCTP's
47 * task registration. SSI will invoke this function once, after
48 * it creates and attaches this TAPA Task to a system task.
50 * @param[in] Ent entity, the entity ID of this task.
51 * @param[in] Inst inst, the instance ID of this task.
52 * @param[in] Region region, the region ID registered for memory
54 * @param[in] Reason reason.
55 * @return ROK - success
57 ***************************************************************************/
58 S16 sctpActvInit(Ent entity, Inst inst, Region region, Reason reason)
63 sctpCfg = &(cuCfgParams.sctpParams);
68 /**************************************************************************
69 * @brief Task Activation callback function.
73 * Function : sctpActvTsk
76 * This function handles all SCTP messages received
77 * This API is registered with SSI during the
78 * Task Registration of DU APP.
80 * @param[in] Pst *pst, Post structure of the primitive.
81 * @param[in] Buffer *mBuf, Packed primitive parameters in the
83 * @return ROK - success
86 ***************************************************************************/
87 S16 sctpActvTsk(Pst *pst, Buffer *mBuf)
94 /*******************************************************************
96 * @brief Opens a non-blocking socket and binds to local address
100 * Function : openSctpEndp
103 * Opens a non-blocking socket and binds to local address
106 * @return ROK - success
109 * ****************************************************************/
115 /* Opening a non-blocking SCTP socket */
116 socket_type = CM_INET_STREAM;
119 ret = cmInetSocket(socket_type, &lstnSockFd, IPPROTO_SCTP,(sctpCfg->cuIpAddr.ipV4Pres ? AF_INET : AF_INET6));
123 if(numRetry >= MAX_RETRY)
125 printf("\nAll attempts to open socket failed.");
126 /* Send indication to du_app */
131 printf("\nRetrying socket opening");
136 printf("\nSocket[%d] opened successfully",lstnSockFd.fd);
139 }while(numRetry < MAX_RETRY);
142 } /* End of openSctpEndp */
145 /*******************************************************************
147 * @brief Bind socket to local Ip address and port
151 * Function : bindSctpEndp
154 * -Bind socket to local Ip address and port
157 * @return ROK - success
160 * ****************************************************************/
167 /* Binding the socket with local address */
168 localAddrLst.count = 1;
169 if(sctpCfg->cuIpAddr.ipV4Pres)
171 localAddrLst.addrs[0].type = CM_INET_IPV4ADDR_TYPE;
172 localAddrLst.addrs[0].u.ipv4NetAddr = CM_INET_NTOH_U32(sctpCfg->cuIpAddr.ipV4Addr);
174 else if(sctpCfg->cuIpAddr.ipV6Pres)
176 localAddrLst.addrs[0].type = CM_INET_IPV6ADDR_TYPE;
177 // CM_INET_COPY_IPV6ADDR(&(localAddrLst.addrs[0].u.ipv6NetAddr),&(sctpCfg->cuIpAddr.ipV6Addr);
181 localAddrLst.addrs[0].type = CM_INET_IPV4ADDR_TYPE;
182 localAddrLst.addrs[0].u.ipv4NetAddr = 0;
186 ret = cmInetSctpBindx(&lstnSockFd, &localAddrLst, sctpCfg->cuPort);
190 if(numRetry >= MAX_RETRY)
192 printf("\nAll attempts to bind socket failed.");
193 cmInetClose(&lstnSockFd);
194 /* Send indication to du_app */
199 printf("\nRetrying socket binding");
204 printf("\nSocket bind successful");
207 }while(numRetry < MAX_RETRY);
211 } /* End of bindSctpEndp() */
213 /*******************************************************************
215 * @brief Sets socket options as per requirement
219 * Function : sctpSetSockOpts
222 * Sets socket options as per requirement
225 * @return ROK - success
228 * ****************************************************************/
229 S16 sctpSetSockOpts()
231 CmSctpEvent sctpEvent;
233 sctpEvent.dataIoEvent = TRUE;
234 sctpEvent.associationEvent = TRUE;
235 sctpEvent.addressEvent = TRUE;
236 sctpEvent.sendFailureEvent = TRUE;
237 sctpEvent.peerErrorEvent = TRUE;
238 sctpEvent.shutdownEvent = TRUE;
239 sctpEvent.partialDeliveryEvent = TRUE;
240 sctpEvent.adaptationLayerEvent = TRUE;
242 cmInetSetOpt(&sockFd, CM_SOCKOPT_LEVEL_SCTP, CM_SOCKOPT_OPT_SCTP_EVENTS, &sctpEvent);
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 * ****************************************************************/
268 ret = cmInetListen(&lstnSockFd, 1);;
271 printf("\nListening on socket failed");
272 cmInetClose(&lstnSockFd);
278 ret = cmInetAccept(&lstnSockFd, &peerAddr, &sockFd);
285 printf("\nFailed to accept connection");
292 printf("\nAccepted incoming connection");
298 }/* End of sctpAccept() */
300 /*******************************************************************
302 * @brief Handles an SCTP notification message
306 * Function : sctpNtfyHdlr
309 * Handles an SCTP notification message
311 * @params[in] Notify message
313 * @return ROK - success
316 * ****************************************************************/
317 S16 sctpNtfyHdlr(CmInetSctpNotification *ntfy)
319 switch(ntfy->header.nType)
321 case CM_INET_SCTP_ASSOC_CHANGE :
322 switch(ntfy->u.assocChange.state)
324 case CM_INET_SCTP_COMM_UP:
325 printf("\nSCTP notify assocchange(comm up) received");
328 case CM_INET_SCTP_COMM_LOST:
329 printf("\nSCTP notify assocchange(comm lost) received");
332 case CM_INET_SCTP_RESTART:
333 printf("\nSCTP notify assocchange(sctp restart) received");
336 case CM_INET_SCTP_SHUTDOWN_COMP: /* association gracefully shutdown */
337 printf("\nSCTP notify assocchange(shutdown complete) received\n");
340 case CM_INET_SCTP_CANT_STR_ASSOC:
341 printf("\nSCTP notify assocchange(cant str assoc) received\n");
345 printf("\nInvalid event");
349 case CM_INET_SCTP_PEER_ADDR_CHANGE :
350 printf("\nSCTP notify peer addr change received");
351 /* Need to add handler */
353 case CM_INET_SCTP_REMOTE_ERROR :
354 printf("\nSCTP notify remote error received");
356 case CM_INET_SCTP_SEND_FAILED :
357 printf("\nSCTP notify send failed received\n");
359 case CM_INET_SCTP_SHUTDOWN_EVENT : /* peer socket gracefully closed */
360 printf("\nSCTP notify shutdown event received\n");
363 case CM_INET_SCTP_ADAPTATION_INDICATION :
364 printf("\nSCTP notify adaptation indication received\n");
366 case CM_INET_SCTP_PARTIAL_DELIVERY_EVENT:
367 printf("\nSCTP notify partial delivery received\n");
370 printf("\nInvalid sctp 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 * ****************************************************************/
400 U32 timeout; /* timeout for cmInetSelect() */
401 U32 *timeoutPtr; /* pointer to timeout */
405 CmInetMemInfo memInfo; /* buffer allocation info */
407 CmInetSctpSndRcvInfo info;
408 CmInetSctpNotification ntfy;
419 timeoutPtr = &timeout;
421 memInfo.region = CU_APP_MEM_REG;
422 memInfo.pool = CU_POOL;
423 CM_INET_FD_ZERO(&readFd);
427 CM_INET_FD_SET(&sockFd, &readFd);
428 ret = cmInetSelect(&readFd, NULLP, timeoutPtr, &numFds);
429 if (CM_INET_FD_ISSET(&sockFd, &readFd))
431 CM_INET_FD_CLR(&sockFd, &readFd);
432 ret = cmInetSctpRecvMsg(&sockFd, &addr, &port, &memInfo, &mBuf, &bufLen, &info, &flag, &ntfy);
435 printf("\nFailed to receive sctp msg\n");
439 if ((flag & CM_INET_SCTP_MSG_NOTIFICATION) != 0)
441 ret = sctpNtfyHdlr(&ntfy);
444 printf("\nFailed to process sctp notify msg\n");
447 else if(connUp) /* If data received */
461 }/* End of sctpSockPoll() */
463 /*******************************************************************
465 * @brief Send message on SCTP socket
469 * Function : sctpOutMsgSend
472 * Send message on SCTP socket
475 * @return ROK - success
478 * ****************************************************************/
479 S16 sctpOutMsgSend(Buffer *mBuf)
482 MsgLen len; /* number of actually sent octets */
483 CmInetNetAddr peerAddr; /* destination port address */
484 CmInetNetAddr *dstAddr;
485 CmInetMemInfo memInfo;
487 memInfo.region = CU_APP_MEM_REG;
488 memInfo.pool = CU_POOL;
491 if(sctpCfg->duIpAddr.ipV4Pres)
493 peerAddr.type = CM_INET_IPV4ADDR_TYPE;
494 peerAddr.u.ipv4NetAddr = CM_INET_NTOH_U32(sctpCfg->duIpAddr.ipV4Addr);
497 else if(sctpCfg->duIpAddr.ipV6Pres)
499 peerAddr.type = CM_INET_IPV6ADDR_TYPE;
500 //CM_INET_COPY_IPV6ADDR(&(primDstAddr.u.ipv6NetAddr),&(sctpCfg->duIpAddr.ipV6Addr);
508 ret = cmInetSctpSendMsg(&sockFd, dstAddr, sctpCfg->duPort, &memInfo, mBuf, &len, 0, FALSE, 0, 0/*SCT_PROTID_NONE*/, RWOULDBLOCK);
509 if(ret != ROK && ret != RWOULDBLOCK)
511 printf("\nFailed sending the message");
516 } /* End of sctpOutMsgSend */
518 /*******************************************************************
520 * @brief Start SCTP at CU
524 * Function : sctpStartReq
530 * @return ROK - success
533 * ****************************************************************/
536 if(openSctpEndp() != ROK)
538 printf("\nFailed while opening socket");
540 else if(bindSctpEndp() != ROK)
542 printf("\nFailed while binding socket");
544 else if(sctpAccept() != ROK)
546 printf("\nFailed while accepting connection");
548 else if(sctpSockPoll() != ROK)
550 printf("\nFailed while polling");
552 } /* End of sctpAssocReq */
554 /**********************************************************************
556 **********************************************************************/