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 */
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 ***************************************************************************/
46 S16 sctpActvInit(Ent entity, Inst inst, Region region, Reason reason)
48 DU_LOG("\n\nSCTP : Initializing");
51 f1Params.assocId = -1;
52 ricParams.assocId = -1;
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)
98 /**************************************************************************
99 * @brief Function to configure the Sctp Params during config Request
103 * Function : duSctpCfgReq
106 * This function configures SCTP Params during the config Request
108 * @param[in] SctpParams sctpCfg, common structure which has all the configuration
109 * @param[in] CmStatus cfm, Builds the cfm status and reason
112 * @return ROK - success
115 ***************************************************************************/
117 S16 duSctpCfgReq(SctpParams sctpCfg, CmStatus *cfm)
120 f1Params.destIpAddr.ipV4Pres = sctpCfg.cuIpAddr.ipV4Pres;
121 f1Params.destIpAddr.ipV4Addr = sctpCfg.cuIpAddr.ipV4Addr;
122 f1Params.destPort = sctpCfg.cuPort;
123 f1Params.itfState = DU_SCTP_DOWN;
124 f1Params.srcPort = sctpCfg.duPort[0];
125 f1Params.recvMsgSet = ROK;
126 cmMemset ((U8 *)&f1Params.sockFd, -1, sizeof(CmInetFd));
127 fillDestNetAddr(&f1Params.destIpNetAddr, &f1Params.destIpAddr);
128 fillAddrLst(&f1Params.destAddrLst, &f1Params.destIpAddr);
130 /* Fill RIC Params */
131 ricParams.destIpAddr.ipV4Pres = sctpCfg.ricIpAddr.ipV4Pres;
132 ricParams.destIpAddr.ipV4Addr = sctpCfg.ricIpAddr.ipV4Addr;
133 ricParams.destPort = sctpCfg.ricPort;
134 ricParams.itfState = DU_SCTP_DOWN;
135 ricParams.srcPort = sctpCfg.duPort[1];
136 ricParams.recvMsgSet = ROK;
137 cmMemset ((U8 *)&ricParams.sockFd, -1, sizeof(CmInetFd));
138 fillDestNetAddr(&ricParams.destIpNetAddr, &ricParams.destIpAddr);
139 fillAddrLst(&ricParams.destAddrLst, &ricParams.destIpAddr);
141 /* Fill AddressList */
142 fillAddrLst(&localAddrLst, &sctpCfg.duIpAddr);
144 /* Set polling to FALSE */
145 pollingState = FALSE;
147 /* Fill Cfm Status */
148 cfm->status = LCM_PRIM_OK;
149 cfm->reason = LCM_REASON_NOT_APPL;
154 /*******************************************************************
156 * @brief Fills the address List of the source Ip Address
160 * Function : fillAddrLst
163 * Fills the address List of source Ip Address
165 * @params[in] CmInetNetAddrLst *addrLstPtr, Address List pointer
166 * @params[in] F1IpAddr *srcIpAddr, src Ip Adrress to be filled in the Address List
168 * @return ROK - success
171 ******************************************************************/
173 S16 fillAddrLst(CmInetNetAddrLst *addrLstPtr, F1IpAddr *ipAddr)
176 addrLstPtr->addrs[(addrLstPtr->count - 1)].type = CM_INET_IPV4ADDR_TYPE;
177 addrLstPtr->addrs[(addrLstPtr->count - 1)].u.ipv4NetAddr = CM_INET_NTOH_U32(ipAddr->ipV4Addr);
182 /******************************************************************************
184 * @brief Fills the address List of the source Ip Address
188 * Function : fillDestNetAddr
191 * Fills the address List of destinatoion Ip Address
193 * @params[in] CmInetNetAddr *destAddrPtr, Address List pointer
194 * @params[in] F1IpAddr *dstIpAddr, destIp Address to be filled in the Address List
196 * @return ROK - success
199 *******************************************************************************/
200 S16 fillDestNetAddr(CmInetNetAddr *destAddrPtr, F1IpAddr *dstIpPtr)
202 /* Filling destination address */
203 destAddrPtr->type = CM_INET_IPV4ADDR_TYPE;
204 destAddrPtr->u.ipv4NetAddr = CM_INET_NTOH_U32(dstIpPtr->ipV4Addr);
208 /******************************************************************************
210 * @brief Establishes the Assoc Req for the received interface type
214 * Function : establishAssocReq
217 * Eastablishes the Assoc Req for the received interface type
219 * @params[in] DuSctpDestCb *paramPtr
221 * @return ROK - success
224 *******************************************************************************/
226 S16 establishReq(DuSctpDestCb *paramPtr)
230 socket_type = CM_INET_STREAM;
232 if((ret = cmInetSocket(socket_type, ¶mPtr->sockFd, IPPROTO_SCTP)) != ROK)
234 DU_LOG("\nSCTP : Failed while opening a socket in ODU");
236 else if((ret = cmInetSctpBindx(¶mPtr->sockFd, &localAddrLst, paramPtr->srcPort)) != ROK)
238 DU_LOG("\nSCTP: Failed during Binding in ODU");
240 else if((ret = sctpSetSockOpts(¶mPtr->sockFd)) != ROK)
242 DU_LOG("\nSCTP : Failed to set Socket Opt in ODU");
248 DU_LOG("\nSCTP : Failed while establishing Req at DU");
253 ret = cmInetSctpConnectx(¶mPtr->sockFd, ¶mPtr->destIpNetAddr, ¶mPtr->destAddrLst, paramPtr->destPort);
254 /* 115 error_code indicates that Operation is in progress and hence ignored if SctpConnect failed due to this */
261 if((ret == ROK) & (paramPtr->itfState == DU_SCTP_DOWN))
263 paramPtr->itfState = DU_SCTP_UP;
266 /* Post the EVTSTRTPOLL Msg */
270 duFillSctpPst(&pst, EVTSTRTPOLL);
276 /******************************************************************************
278 * @brief Processes the assoc Req for the received interface type
282 * Function : duSctpAssocReq
285 * Processes the Assoc Req for the received interface type
287 * @params[in] itfType interface Type,
288 * @params[in] cfm , represents the status of request
290 * @return ROK - success
293 *******************************************************************************/
295 S16 duSctpAssocReq(U8 itfType, CmStatus *cfm)
298 DuSctpDestCb *paramPtr = NULLP;
299 if(SGetSBuf(DU_APP_MEM_REGION, DU_POOL, (Data **)¶mPtr, (Size)sizeof(DuSctpDestCb)) != ROK)
301 printf("\nDU_APP : Failed to allocate memory");
308 paramPtr = &f1Params;
309 ret = establishReq(paramPtr);
314 paramPtr = &ricParams;
315 ret = establishReq(paramPtr);
320 DU_LOG("\nSCTP : Invalid Interface Type");
326 DU_LOG("\nSCTP : ASSOC Req Failed.");
327 cfm->status = LCM_PRIM_NOK;
328 cfm->reason = LCM_REASON_NOT_APPL;
332 cfm->status = LCM_PRIM_OK;
333 cfm->reason = LCM_REASON_NOT_APPL;
338 /*******************************************************************
340 * @brief Fills Pst struct for ENTSCTP
344 * Function : duFillSctpPst
347 * Fills Pst struct for ENTSCTP
350 * @return ROK - success
353 * ****************************************************************/
354 S16 duFillSctpPst(Pst *pst, Event event)
357 if(SGetMsg(DFLT_REGION, DU_POOL, &mBuf) != ROK)
359 printf("\nDU_APP : Failed to allocate memory");
362 cmMemset((U8 *)pst, 0, sizeof(Pst));
363 pst->srcEnt = (Ent)ENTDUAPP;
364 pst->srcInst = (Inst)DU_INST;
365 pst->srcProcId = DU_PROC;
366 pst->dstEnt = (Ent)ENTSCTP;
367 pst->dstInst = (Inst)SCTP_INST;
368 pst->dstProcId = pst->srcProcId;
370 pst->selector = DU_SELECTOR_LC;
377 /*******************************************************************
379 * @brief Sets socket options as per requirement
383 * Function : sctpSetSockOpts
386 * Sets socket options as per requirement
388 * @params[in] sock_Fd determines the sockFd to be set
389 * @return ROK - success
392 * ****************************************************************/
393 S16 sctpSetSockOpts(CmInetFd *sock_Fd)
396 CmSctpEvent sctpEvent;
398 sctpEvent.dataIoEvent = TRUE;
399 sctpEvent.associationEvent = TRUE;
400 sctpEvent.addressEvent = TRUE;
401 sctpEvent.sendFailureEvent = TRUE;
402 sctpEvent.peerErrorEvent = TRUE;
403 sctpEvent.shutdownEvent = TRUE;
404 sctpEvent.partialDeliveryEvent = TRUE;
405 sctpEvent.adaptationLayerEvent = TRUE;
407 if((ret = cmInetSetOpt(sock_Fd, CM_SOCKOPT_LEVEL_SCTP, CM_SOCKOPT_OPT_SCTP_EVENTS, &sctpEvent) != ROK))
415 /*******************************************************************
417 * @brief Post received data/notification to DU APP
421 * Function : sendToDuApp
424 * Post received data/notification to DU APP
426 * @params[in] Message buffer
429 * @return ROK - success
432 * ****************************************************************/
433 void sendToDuApp(Buffer *mBuf, Event event)
436 DU_LOG("\nSCTP : Forwarding received message to duApp");
437 SPrntMsg(mBuf, 0, 0);
440 cmMemset((U8 *)&(pst), 0, sizeof(Pst));
441 pst.srcEnt = (Ent)ENTSCTP;
442 pst.srcInst = (Inst)SCTP_INST;
443 pst.srcProcId = DU_PROC;
444 pst.dstEnt = (Ent)ENTDUAPP;
445 pst.dstInst = (Inst)DU_INST;
446 pst.dstProcId = pst.srcProcId;
448 pst.selector = DU_SELECTOR_LC;
450 pst.region = DFLT_REGION;
452 if (SPstTsk(&pst, mBuf) != ROK)
454 DU_LOG("\nSCTP : SPstTsk failed in duReadCfg");
458 /*******************************************************************
460 * @brief Handles an SCTP notification message
463 * Function : sctpNtfyHdlr
466 * Handles an SCTP notification message
468 * @params[in] Notify message
470 * @return ROK - success
473 * ****************************************************************/
474 S16 sctpNtfyHdlr(CmInetSctpNotification *ntfy)
478 switch(ntfy->header.nType)
480 case CM_INET_SCTP_ASSOC_CHANGE :
481 DU_LOG("\nSCTP : Assoc change notification received");
482 switch(ntfy->u.assocChange.state)
484 case CM_INET_SCTP_COMM_UP:
485 DU_LOG("Event : COMMUNICATION UP");
488 case CM_INET_SCTP_COMM_LOST:
489 DU_LOG("Event : COMMUNICATION LOST");
492 case CM_INET_SCTP_RESTART:
493 DU_LOG("Event : SCTP RESTART");
496 case CM_INET_SCTP_SHUTDOWN_COMP: /* association gracefully shutdown */
497 DU_LOG("Event : SHUTDOWN COMPLETE");
500 case CM_INET_SCTP_CANT_STR_ASSOC:
501 DU_LOG("Event : CANT START ASSOC");
505 DU_LOG("\nInvalid event");
509 case CM_INET_SCTP_PEER_ADDR_CHANGE :
510 DU_LOG("\nSCTP : Peer Address Change notificarion received");
511 /* Need to add handler */
513 case CM_INET_SCTP_REMOTE_ERROR :
514 DU_LOG("\nSCTP : Remote Error notification received");
516 case CM_INET_SCTP_SEND_FAILED :
517 DU_LOG("\nSCTP : Send Failed notification received\n");
519 case CM_INET_SCTP_SHUTDOWN_EVENT : /* peer socket gracefully closed */
520 DU_LOG("\nSCTP : Shutdown Event notification received\n");
524 case CM_INET_SCTP_ADAPTATION_INDICATION :
525 DU_LOG("\nSCTP : Adaptation Indication received\n");
527 case CM_INET_SCTP_PARTIAL_DELIVERY_EVENT:
528 DU_LOG("\nSCTP : Partial Delivery Event received\n");
531 DU_LOG("\nSCTP : Invalid sctp notification type\n");
535 /* Pack notification and send to APP */
536 DU_LOG("\nSCTP : Forwarding received message to duApp");
538 cmMemset((U8 *)&(pst), 0, sizeof(Pst));
539 pst.srcEnt = (Ent)ENTSCTP;
540 pst.srcInst = (Inst)SCTP_INST;
541 pst.srcProcId = DU_PROC;
542 pst.dstEnt = (Ent)ENTDUAPP;
543 pst.dstInst = (Inst)DU_INST;
544 pst.dstProcId = pst.srcProcId;
545 pst.event = EVTSCTPNTFY;
546 pst.selector = DU_SELECTOR_LC;
548 pst.region = DFLT_REGION;
550 if(cmPkSctpNtfy(&pst, ntfy) != ROK)
552 DU_LOG("\nSCTP : Failed to pack SCTP notification");
558 /*******************************************************************
560 * @brief checks for valid readFd and process the InetSctpRecvMsg
565 * Function : processPolling
568 * checks for valid readFd and process the InetSctpRecvMsg
571 * @params[in] Params required for polling
572 * @params[in] SockFd for file descriptor
573 * @params[in] timeoutPtr indicates the timeout value
574 * @params[in] MemInfo, recvMsgSet
576 * @return ROK - success
579 * ****************************************************************/
581 S16 processPolling(sctpSockPollParams *pollParams, CmInetFd *sockFd, U32 *timeoutPtr, CmInetMemInfo *memInfo, Bool recvMsgSet)
584 CM_INET_FD_SET(sockFd, &pollParams->readFd);
585 ret = cmInetSelect(&pollParams->readFd, NULLP, timeoutPtr, &pollParams->numFds);
586 if(CM_INET_FD_ISSET(sockFd, &pollParams->readFd))
588 CM_INET_FD_CLR(sockFd, &pollParams->readFd);
589 ret = cmInetSctpRecvMsg(sockFd, &pollParams->addr, &pollParams->port, memInfo, &(pollParams->mBuf), &pollParams->bufLen, &pollParams->info, &pollParams->flag, &pollParams->ntfy);
591 if(connUp && ret != ROK)
593 DU_LOG("\n SCTP: Failed to receive sctp msg for sockFd[%d]\n", sockFd->fd);
594 recvMsgSet = RFAILED;
598 if((((pollParams->flag & CM_INET_SCTP_MSG_NOTIFICATION) != 0)) && ret == ROK)
600 if(pollParams->port == f1Params.destPort)
602 f1Params.assocId = pollParams->ntfy.u.assocChange.assocId;
603 DU_LOG("\nSCTP : AssocId assigned to F1Params from PollParams [%d]\n", f1Params.assocId);
605 else if(pollParams->port == ricParams.destPort)
607 ricParams.assocId = pollParams->ntfy.u.assocChange.assocId;
608 DU_LOG("\nSCTP : AssocId assigned to ricParams from PollParams [%d]\n", ricParams.assocId);
612 DU_LOG("\nSCTP : Failed to fill AssocId\n");
614 ret = sctpNtfyHdlr(&pollParams->ntfy);
617 DU_LOG("\nSCTP : Failed to process sctp notify msg\n");
620 else if(connUp & (pollParams->port == f1Params.destPort))
622 sendToDuApp(pollParams->mBuf, EVTSCTPDATA);
624 else if(connUp & (pollParams->port == ricParams.destPort))
626 sendToDuApp(pollParams->mBuf, EVTRICDATA);
631 SPutMsg(pollParams->mBuf);
637 /*******************************************************************
639 * @brief Receives message on the socket
643 * Function : sctpSockPoll
646 * Receives message on the socket
649 * @return ROK - success
652 * ****************************************************************/
658 CmInetMemInfo memInfo;
659 sctpSockPollParams f1PollParams, e2PollParams;
661 memset(&f1PollParams, 0, sizeof(sctpSockPollParams));
662 memset(&e2PollParams, 0, sizeof(sctpSockPollParams));
664 if (f1Params.sockFd.blocking & ricParams.sockFd.blocking)
673 timeout_Ptr = &timeout;
675 memInfo.region = DU_APP_MEM_REGION;
676 memInfo.pool = DU_POOL;
678 CM_INET_FD_ZERO(&f1PollParams.readFd);
679 CM_INET_FD_ZERO(&e2PollParams.readFd);
681 DU_LOG("\nSCTP : Polling started at DU\n");
684 if(f1Params.itfState)
686 if((ret = processPolling(&f1PollParams, &f1Params.sockFd, timeout_Ptr, &memInfo, f1Params.recvMsgSet)) != ROK)
688 DU_LOG("\nSCTP : Failed to RecvMsg for F1\n");
691 if(ricParams.itfState)
693 if((ret = processPolling(&e2PollParams, &ricParams.sockFd, timeout_Ptr, &memInfo, ricParams.recvMsgSet)) != ROK)
695 DU_LOG("\nSCTP : Failed to RecvMsg for E2\n");
700 }/* End of sctpSockPoll() */
702 /*******************************************************************
704 * @brief Send message on SCTP socket
708 * Function : sctpSend
711 * Send message on SCTP socket
714 * @return ROK - success
717 * ****************************************************************/
718 S16 sctpSend(Buffer *mBuf, U8 itfType)
721 MsgLen len; /* number of actually sent octets */
722 CmInetMemInfo memInfo;
724 memInfo.region = DU_APP_MEM_REGION;
725 memInfo.pool = DU_POOL;
727 if(itfType == F1_INTERFACE)
729 DU_LOG("\nSCTP : sending the message to DuApp");
730 ret = cmInetSctpSendMsg(&f1Params.sockFd, &f1Params.destIpNetAddr, f1Params.destPort, &memInfo, mBuf, &len, 0, FALSE, 0, 0/*SCT_PROTID_NONE*/, RWOULDBLOCK);
733 if(itfType == E2_INTERFACE)
735 DU_LOG("\nSCTP : sending the message to ric");
736 ret = cmInetSctpSendMsg(&ricParams.sockFd, &ricParams.destIpNetAddr, ricParams.destPort, &memInfo, mBuf, &len, 0, FALSE, 0, 0/*SCT_PROTID_NONE*/, RWOULDBLOCK);
739 if(ret != ROK && ret != RWOULDBLOCK)
741 DU_LOG("\nSCTP : Failed sending the message");
746 } /* End of sctpSend */
748 /**********************************************************************
750 **********************************************************************/