*******************************************************************************/
/* This file contains all SCTP related functionality */
-
-#include <stdio.h>
-#include <fcntl.h>
-#include <netdb.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <errno.h>
-#include <unistd.h>
-
+#include "common_def.h"
+#include "lrg.h"
+#include "legtp.h"
+#include "lrg.x"
+#include "lkw.x"
+#include "cm_inet.h"
+#include "cm_inet.x"
+#include "du_app_mac_inf.h"
+#include "du_cfg.h"
#include "du_sctp.h"
-#include "du_common.h"
-
-/* Global variable declaration */
-S8 sockFd; /* Socket file descriptor */
-U8 socket_type; /* Socket type */
-Bool nonblocking; /* Blocking/Non-blocking socket */
-Bool connUp; /* Is connection up */
-int assocId; /* Assoc Id of connected assoc */
-
-sockaddr_storage_t local_addr; /* Local Address */
-sockaddr_storage_t remote_addr; /* Remote Address */
-U8 la_len; /* Local Address length */
-U8 ra_len; /* Remote Address length */
-F1SctpParams *sctpCfg; /* SCTP configurations at DU */
+#include "lsctp.h"
+#include "du_utils.h"
/**************************************************************************
* @brief Task Initiation callback function.
* @return ROK - success
* RFAILED - failure
***************************************************************************/
-S16 sctpActvInit(Ent entity, Inst inst, Region region, Reason reason)
+uint8_t sctpActvInit(Ent entity, Inst inst, Region region, Reason reason)
{
- sockFd = 0;
+ DU_LOG("\n\nDEBUG --> SCTP : Initializing");
+ ODU_SET_PROC_ID(DU_PROC);
connUp = FALSE;
- assocId = 0;
+ f1Params.assocId = -1;
+ ricParams.assocId = -1;
nonblocking = FALSE;
- sctpCfg = &(ducfgparam.sctpParams);
return ROK;
}
* RFAILED - failure
*
***************************************************************************/
-S16 sctpActvTsk(Pst *pst, Buffer *mBuf)
+uint8_t sctpActvTsk(Pst *pst, Buffer *mBuf)
{
-
-//TODO: TBD
+ switch(pst->srcEnt)
+ {
+ case ENTDUAPP:
+ {
+ switch(pst->event)
+ {
+ case EVTSTARTPOLL:
+ {
+ sctpSockPoll();
+ break;
+ }
+ }
+ break;
+ }
+ }
+ ODU_EXIT_TASK();
return ROK;
}
+/*******************************************************************
+ *
+ * @brief Checks the status of the received information
+ *
+ * @details
+ *
+ * Function : duCheckReqStatus
+ *
+ * Functionality:
+ * Checks the status of the received information
+ *
+ * @params[in] Confirm status
+ * @return ROK - success
+ * RFAILED - failure
+ *
+ ******************************************************************/
+uint8_t duCheckReqStatus(CmStatus *cfm)
+{
+ uint8_t ret = ROK;
+ if(cfm->status != LCM_PRIM_OK)
+ {
+ DU_LOG("\nERROR --> DU_APP : Failed to process the request successfully");
+ ret = RFAILED;
+ }
+ return (ret);
+}
+
+/**************************************************************************
+ * @brief Function to configure the Sctp Params during config Request
+ *
+ * @details
+ *
+ * Function : duSctpCfgReq
+ *
+ * Functionality:
+ * This function configures SCTP Params during the config Request
+ *
+ * @param[in] SctpParams sctpCfg, common structure which has all the configuration
+ * @param[in] CmStatus cfm, Builds the cfm status and reason
+ * buffer.
+ *
+ * @return ROK - success
+ * RFAILED - failure
+ *
+ ***************************************************************************/
+
+uint8_t duSctpCfgReq(SctpParams sctpCfg)
+{
+ uint8_t ret = ROK;
+ CmStatus cfm;
+
+/* Fill F1 Params */
+ f1Params.destIpAddr.ipV4Pres = sctpCfg.cuIpAddr.ipV4Pres;
+ f1Params.destIpAddr.ipV4Addr = sctpCfg.cuIpAddr.ipV4Addr;
+ f1Params.destPort = sctpCfg.cuPort;
+ f1Params.itfState = DU_SCTP_DOWN;
+ f1Params.srcPort = sctpCfg.duPort[F1_INTERFACE];
+ f1Params.recvMsgSet = ROK;
+ memset (&f1Params.sockFd, -1, sizeof(CmInetFd));
+ fillDestNetAddr(&f1Params.destIpNetAddr, &f1Params.destIpAddr);
+ fillAddrLst(&f1Params.destAddrLst, &f1Params.destIpAddr);
+
+/* Fill RIC Params */
+ ricParams.destIpAddr.ipV4Pres = sctpCfg.ricIpAddr.ipV4Pres;
+ ricParams.destIpAddr.ipV4Addr = sctpCfg.ricIpAddr.ipV4Addr;
+ ricParams.destPort = sctpCfg.ricPort;
+ ricParams.itfState = DU_SCTP_DOWN;
+ ricParams.srcPort = sctpCfg.duPort[E2_INTERFACE];
+ ricParams.recvMsgSet = ROK;
+ memset (&ricParams.sockFd, -1, sizeof(CmInetFd));
+ fillDestNetAddr(&ricParams.destIpNetAddr, &ricParams.destIpAddr);
+ fillAddrLst(&ricParams.destAddrLst, &ricParams.destIpAddr);
+
+/* Fill AddressList */
+ fillAddrLst(&localAddrLst, &sctpCfg.duIpAddr);
+
+/* Set polling to FALSE */
+ pollingState = FALSE;
+
+/* Fill Cfm Status */
+ cfm.status = LCM_PRIM_OK;
+ cfm.reason = LCM_REASON_NOT_APPL;
+
+ ret = duCheckReqStatus(&cfm);
+
+ return (ret);
+}
/*******************************************************************
*
- * @brief Converts internet address to sockaddr type
+ * @brief Fills the address List of the source Ip Address
*
* @details
*
- * Function : getSockAddr
+ * Function : fillAddrLst
*
* Functionality:
- * Converts internet address to sockaddr type
+ * Fills the address List of source Ip Address
+ *
+ * @params[in] CmInetNetAddrLst *addrLstPtr, Address List pointer
+ * @params[in] F1IpAddr *srcIpAddr, src Ip Adrress to be filled in the Address List
*
- * @params[in]
* @return ROK - success
* RFAILED - failure
*
- * ****************************************************************/
+ ******************************************************************/
+
+uint8_t fillAddrLst(CmInetNetAddrLst *addrLstPtr, F1IpAddr *ipAddr)
+{
+ addrLstPtr->count++;
+ addrLstPtr->addrs[(addrLstPtr->count - 1)].type = CM_INET_IPV4ADDR_TYPE;
+ addrLstPtr->addrs[(addrLstPtr->count - 1)].u.ipv4NetAddr = CM_INET_NTOH_UINT32(ipAddr->ipV4Addr);
+
+ return ROK;
+}
+
+/******************************************************************************
+ *
+ * @brief Fills the address List of the source Ip Address
+ *
+ * @details
+ *
+ * Function : fillDestNetAddr
+ *
+ * Functionality:
+ * Fills the address List of destinatoion Ip Address
+ *
+ * @params[in] CmInetNetAddr *destAddrPtr, Address List pointer
+ * @params[in] F1IpAddr *dstIpAddr, destIp Address to be filled in the Address List
+ *
+ * @return ROK - success
+ * RFAILED - failure
+ *
+ *******************************************************************************/
+uint8_t fillDestNetAddr(CmInetNetAddr *destAddrPtr, F1IpAddr *dstIpPtr)
+{
+ /* Filling destination address */
+ destAddrPtr->type = CM_INET_IPV4ADDR_TYPE;
+ destAddrPtr->u.ipv4NetAddr = CM_INET_NTOH_UINT32(dstIpPtr->ipV4Addr);
+ return ROK;
+}
-S16 getSockAddr(char *hostIp, U16 portNum, Bool ipv4Pres, Bool local)
+/******************************************************************************
+ *
+ * @brief Establishes the Assoc Req for the received interface type
+ *
+ * @details
+ *
+ * Function : establishAssocReq
+ *
+ * Functionality:
+ * Eastablishes the Assoc Req for the received interface type
+ *
+ * @params[in] DuSctpDestCb *paramPtr
+ *
+ * @return ROK - success
+ * RFAILED - failure
+ *
+ *******************************************************************************/
+
+uint8_t establishReq(DuSctpDestCb *paramPtr)
{
- sockaddr_storage_t address;
- struct hostent *host;
- void *la_raw;
+ Pst pst;
+ uint8_t ret = ROK;
+ socket_type = CM_INET_STREAM;
- /* Getting the transport address for local host name */
- if(ipv4Pres)
+ if((ret = cmInetSocket(socket_type, ¶mPtr->sockFd, IPPROTO_SCTP)) != ROK)
{
- host = gethostbyname(hostIp);
- if (host == NULL || host->h_length < 1)
- {
- printf("\nBad hostname: %s", hostIp);
- RETVALUE(NULLP);
- }
- la_raw = &address.v4.sin_addr;
- address.v4.sin_family = AF_INET;
- address.v4.sin_port = htons(portNum);
+ DU_LOG("\nERROR --> SCTP : Failed while opening a socket in ODU");
+ }
+ else if((ret = cmInetSctpBindx(¶mPtr->sockFd, &localAddrLst, paramPtr->srcPort)) != ROK)
+ {
+ DU_LOG("\nERROR --> SCTP: Failed during Binding in ODU");
}
- else
+ else if((ret = sctpSetSockOpts(¶mPtr->sockFd)) != ROK)
{
- host = gethostbyname2(hostIp, AF_INET6);
- if (host == NULL || host->h_length < 1)
+ DU_LOG("\nERROR --> SCTP : Failed to set Socket Opt in ODU");
+ }
+ else
+ {
+ if(ret != ROK)
{
- printf("\n Bad hostname: %s", hostIp);
- RETVALUE(RFAILED);
+ DU_LOG("\nERROR --> SCTP : Failed while establishing Req at DU");
+ ret = RFAILED;
+ }
+ else
+ {
+ ret = cmInetSctpConnectx(¶mPtr->sockFd, ¶mPtr->destIpNetAddr, ¶mPtr->destAddrLst, paramPtr->destPort);
+ /* 115 error_code indicates that Operation is in progress and hence ignored if SctpConnect failed due to this */
+ if(ret == 18)
+ {
+ ret = ROK;
+ }
}
- la_raw = &address.v6.sin6_addr;
- address.v6.sin6_family = AF_INET6;
- address.v6.sin6_port = htons(portNum);
- address.v6.sin6_scope_id = 0;
+ }
+ if((ret == ROK) & (paramPtr->itfState == DU_SCTP_DOWN))
+ {
+ paramPtr->itfState = DU_SCTP_CONNECTING;
}
- memcpy((U8 *)la_raw, (U8 *)host->h_addr_list[0], host->h_length);
+ /* Post the EVTSTARTPOLL Msg */
+ if(!pollingState)
+ {
+ pollingState = TRUE;
+ duFillSctpPst(&pst, EVTSTARTPOLL);
+ }
- if(local)
+ return (ret);
+}
+
+/******************************************************************************
+ *
+ * @brief Processes the assoc Req for the received interface type
+ *
+ * @details
+ *
+ * Function : duSctpAssocReq
+ *
+ * Functionality:
+ * Processes the Assoc Req for the received interface type
+ *
+ * @params[in] itfType interface Type,
+ * @params[in] cfm , represents the status of request
+ *
+ * @return ROK - success
+ * RFAILED - failure
+ *
+ *******************************************************************************/
+
+uint8_t duSctpAssocReq(uint8_t itfType)
+{
+ uint8_t ret = ROK;
+ CmStatus cfm;
+ DuSctpDestCb *paramPtr = NULLP;
+
+ DU_ALLOC(paramPtr, sizeof(DuSctpDestCb));
+ if(paramPtr == NULLP)
{
- local_addr = address;
+ DU_LOG("\nERROR --> DU_APP : Failed to allocate memory");
+ return RFAILED;
+ }
+ switch(itfType)
+ {
+ case F1_INTERFACE:
+ {
+ paramPtr = &f1Params;
+ ret = establishReq(paramPtr);
+ break;
+ }
+ case E2_INTERFACE:
+ {
+ paramPtr = &ricParams;
+ ret = establishReq(paramPtr);
+ break;
+ }
+ default:
+ {
+ DU_LOG("\nERROR --> SCTP : Invalid Interface Type %d", itfType);
+ break;
+ }
+ }
+ if(ret != ROK)
+ {
+ DU_LOG("\nERROR --> SCTP : ASSOC Req Failed.");
+ cfm.status = LCM_PRIM_NOK;
+ cfm.reason = LCM_REASON_NOT_APPL;
}
else
{
- remote_addr = address;
+ cfm.status = LCM_PRIM_OK;
+ cfm.reason = LCM_REASON_NOT_APPL;
}
+ ret = duCheckReqStatus(&cfm);
- RETVALUE(ROK);
-} /* End of getSockAddr() */
-
+ return (ret);
+}
/*******************************************************************
*
- * @brief Opens a non-blocking socket and binds to local address
+ * @brief Fills Pst struct for ENTSCTP
*
* @details
*
- * Function : openSctpEndp
+ * Function : duFillSctpPst
*
* Functionality:
- * Opens a non-blocking socket and binds to local address
+ * Fills Pst struct for ENTSCTP
*
* @params[in]
* @return ROK - success
* RFAILED - failure
*
* ****************************************************************/
-S16 openSctpEndp()
+uint8_t duFillSctpPst(Pst *pst, Event event)
{
- sa_family_t la_family;
- U8 error;
-
-
- /* Getting the transport address for local host name */
- if(sctpCfg->duIpAddr.ipV4Pres)
- {
- if(getSockAddr(sctpCfg->duIpAddr.ipV4Addr, sctpCfg->duPort, TRUE, TRUE) != ROK )
- {
- printf("\nUnable to get local address");
- RETVALUE(RFAILED);
- }
- la_family = AF_INET;
- }
- else
- {
- if(getSockAddr(sctpCfg->duIpAddr.ipV6Addr, sctpCfg->duPort, FALSE, TRUE) != ROK )
- {
- printf("\nUnable to get local address");
- RETVALUE(RFAILED);
- }
- la_family = AF_INET6;
- }
-
- socket_type = SOCK_STREAM;
-
- /* Creating new end point */
- sockFd = socket(la_family, socket_type, IPPROTO_SCTP);
- if (sockFd < 0)
- {
- printf("\n Failed to create socket %s", strerror(errno));
- RETVALUE(RFAILED);
- }
-
- /* Binding socket to local address and port */
- error = bind(sockFd, &local_addr.sa, la_len);
- if(error != 0)
- {
- printf("\n Failed to bind to socket. Error [%s]", strerror(errno));
- RETVALUE(RFAILED);
- }
+ Buffer *mBuf;
+ if(ODU_GET_MSG_BUF(DFLT_REGION, DU_POOL, &mBuf) != ROK)
+ {
+ DU_LOG("\nERROR --> DU_APP : Failed to allocate memory");
+ return RFAILED;
+ }
+ memset(pst, 0, sizeof(Pst));
+ pst->srcEnt = (Ent)ENTDUAPP;
+ pst->srcInst = (Inst)DU_INST;
+ pst->srcProcId = DU_PROC;
+ pst->dstEnt = (Ent)ENTSCTP;
+ pst->dstInst = (Inst)SCTP_INST;
+ pst->dstProcId = pst->srcProcId;
+ pst->event = event;
+ pst->selector = ODU_SELECTOR_LC;
+ pst->pool= DU_POOL;
+ ODU_POST_TASK(pst, mBuf);
- /* Setting socket as non-blocking*/
- error = fcntl(sockFd, F_SETFL, O_NONBLOCK);
- if (error != 0)
- {
- printf("\n Failed to set socket as non blocking. Error [%s]", strerror(errno));
- RETVALUE(RFAILED);
- }
- else
- {
- nonblocking = TRUE;
- }
+ return ROK;
+}
- RETVALUE(ROK);
+/*******************************************************************
+ *
+ * @brief Sets socket options as per requirement
+ *
+ * @details
+ *
+ * Function : sctpSetSockOpts
+ *
+ * Functionality:
+ * Sets socket options as per requirement
+ *
+ * @params[in] sock_Fd determines the sockFd to be set
+ * @return ROK - success
+ * RFAILED - failure
+ *
+ * ****************************************************************/
+uint8_t sctpSetSockOpts(CmInetFd *sock_Fd)
+{
+ uint8_t ret = ROK;
+ CmSctpEvent sctpEvent;
+
+ sctpEvent.dataIoEvent = TRUE;
+ sctpEvent.associationEvent = TRUE;
+ sctpEvent.addressEvent = TRUE;
+ sctpEvent.sendFailureEvent = TRUE;
+ sctpEvent.peerErrorEvent = TRUE;
+ sctpEvent.shutdownEvent = TRUE;
+ sctpEvent.partialDeliveryEvent = TRUE;
+ sctpEvent.adaptationLayerEvent = TRUE;
+
+ if((ret = cmInetSetOpt(sock_Fd, CM_SOCKOPT_LEVEL_SCTP, CM_SOCKOPT_OPT_SCTP_EVENTS, &sctpEvent) != ROK))
+ {
+ ret = RFAILED;
+ }
-} /* End of openSctpEndp() */
+ return (ret);
+}
/*******************************************************************
*
- * @brief Initiates connection with peer SCTP
+ * @brief Post received data/notification to DU APP
*
* @details
*
- * Function : sctpConnect
+ * Function : sendToDuApp
*
* Functionality:
- * Establishes SCTP connection with peer.
- * Here, DU-SCTP will initate connection towards CU-SCTP
+ * Post received data/notification to DU APP
+ *
+ * @params[in] Message buffer
+ * Message event
*
- * @params[in]
* @return ROK - success
* RFAILED - failure
*
* ****************************************************************/
-S16 sctpConnect()
+void sendToDuApp(Buffer *mBuf, Event event)
{
- U8 error;
- U8 ret;
-
- /* Getting the transport address for remote host name */
- if(sctpCfg->cuIpAddr.ipV4Pres)
+ Pst pst;
+ DU_LOG("\nDEBUG --> SCTP : Forwarding received message to duApp");
+ ODU_PRINT_MSG(mBuf, 0, 0);
+
+
+ memset(&(pst), 0, sizeof(Pst));
+ pst.srcEnt = (Ent)ENTSCTP;
+ pst.srcInst = (Inst)SCTP_INST;
+ pst.srcProcId = DU_PROC;
+ pst.dstEnt = (Ent)ENTDUAPP;
+ pst.dstInst = (Inst)DU_INST;
+ pst.dstProcId = pst.srcProcId;
+ pst.event = event;
+ pst.selector = ODU_SELECTOR_LC;
+ pst.pool= DU_POOL;
+ pst.region = DFLT_REGION;
+
+ if (ODU_POST_TASK(&pst, mBuf) != ROK)
{
- ret = getSockAddr(sctpCfg->cuIpAddr.ipV4Addr, sctpCfg->cuPort, TRUE, FALSE);
+ DU_LOG("\nERROR --> SCTP : ODU_POST_TASK failed in duReadCfg");
}
- else
- {
- ret = getSockAddr(sctpCfg->cuIpAddr.ipV6Addr, sctpCfg->cuPort, FALSE, FALSE);
- }
- if(ret != ROK)
+}
+
+/*******************************************************************
+ *
+ * @brief Handles an SCTP notification message
+ *
+ * @Sending *
+ * Function : sctpNtfyHdlr
+ *
+ * Functionality:
+ * Handles an SCTP notification message
+ *
+ * @params[in] Notify message
+ *
+ * @return ROK - success
+ * RFAILED - failure
+ *
+ * ****************************************************************/
+uint8_t sctpNtfyHdlr(CmInetSctpNotification *ntfy, uint8_t *itfState)
+{
+ Pst pst;
+
+ switch(ntfy->header.nType)
{
- printf("\nUnable to get remote address");
- RETVALUE(RFAILED);
+ case CM_INET_SCTP_ASSOC_CHANGE :
+ DU_LOG("\nDEBUG --> SCTP : Assoc change notification received");
+ switch(ntfy->u.assocChange.state)
+ {
+ case CM_INET_SCTP_COMM_UP:
+ DU_LOG("INFO --> Event : COMMUNICATION UP");
+ *itfState = DU_SCTP_UP;
+ break;
+ case CM_INET_SCTP_COMM_LOST:
+ DU_LOG("INFO --> Event : COMMUNICATION LOST");
+ *itfState = DU_SCTP_DOWN;
+ break;
+ case CM_INET_SCTP_RESTART:
+ DU_LOG("INFO --> Event : SCTP RESTART");
+ *itfState = DU_SCTP_DOWN;
+ break;
+ case CM_INET_SCTP_SHUTDOWN_COMP: /* association gracefully shutdown */
+ DU_LOG("INFO --> Event : SHUTDOWN COMPLETE");
+ *itfState = DU_SCTP_DOWN;
+ break;
+ case CM_INET_SCTP_CANT_STR_ASSOC:
+ DU_LOG("INFO --> Event : CANT START ASSOC");
+ *itfState = DU_SCTP_DOWN;
+ break;
+ default:
+ DU_LOG("\nERROR --> Invalid event %d", ntfy->u.assocChange.state);
+ break;
+ }
+ break;
+ case CM_INET_SCTP_PEER_ADDR_CHANGE :
+ DU_LOG("\nINFO --> SCTP : Peer Address Change notificarion received");
+ /* Need to add handler */
+ break;
+ case CM_INET_SCTP_REMOTE_ERROR :
+ DU_LOG("\nINFO --> SCTP : Remote Error notification received");
+ break;
+ case CM_INET_SCTP_SEND_FAILED :
+ DU_LOG("\nINFO --> SCTP : Send Failed notification received\n");
+ break;
+ case CM_INET_SCTP_SHUTDOWN_EVENT : /* peer socket gracefully closed */
+ DU_LOG("\nINFO --> SCTP : Shutdown Event notification received\n");
+ *itfState = DU_SCTP_DOWN;
+ exit(0);
+ break;
+ case CM_INET_SCTP_ADAPTATION_INDICATION :
+ DU_LOG("\nINFO --> SCTP : Adaptation Indication received\n");
+ break;
+ case CM_INET_SCTP_PARTIAL_DELIVERY_EVENT:
+ DU_LOG("\nINFO --> SCTP : Partial Delivery Event received\n");
+ break;
+ default:
+ DU_LOG("\nERROR --> SCTP : Invalid sctp notification type %d", ntfy->header.nType);
+ break;
}
- /* Initiating connection establishment with remote */
- if(!connUp)
+ /* Pack notification and send to APP */
+ DU_LOG("\nDEBUG --> SCTP : Forwarding received message to duApp");
+
+ memset(&(pst), 0, sizeof(Pst));
+ pst.srcEnt = (Ent)ENTSCTP;
+ pst.srcInst = (Inst)SCTP_INST;
+ pst.srcProcId = DU_PROC;
+ pst.dstEnt = (Ent)ENTDUAPP;
+ pst.dstInst = (Inst)DU_INST;
+ pst.dstProcId = pst.srcProcId;
+ pst.event = EVENT_SCTP_NTFY;
+ pst.selector = ODU_SELECTOR_LC;
+ pst.pool= DU_POOL;
+ pst.region = DU_APP_MEM_REGION;
+
+ if(cmPkSctpNtfy(&pst, ntfy) != ROK)
{
- error = sctp_connectx(sockFd, &remote_addr.sa, 1, &assocId);
- if(error != 0)
- {
- printf("\nError connecting to peer. Error[%s]", strerror(errno));
- RETVALUE(RFAILED);
- }
- else
- {
- /* Mark SCTP connection UP */
- connUp = TRUE;
- }
+ DU_LOG("\nERROR --> SCTP : Failed to pack SCTP notification");
+ return RFAILED;
}
-
- RETVALUE(ROK);
-}/* End of sctpConnect() */
+ return ROK;
+}
/*******************************************************************
*
- * @brief Handles an incoming message
+ * @brief checks for valid readFd and process the InetSctpRecvMsg
+ * during polling
*
* @details
*
- * Function : sctpInmsgHdlr
+ * Function : processPolling
*
* Functionality:
- * Handles an incoming message
+ * checks for valid readFd and process the InetSctpRecvMsg
+ * during polling
*
- * @params[in] Socket file descriptor
- * Incoming message header
- * Message Length
+ * @params[in] Params required for polling
+ * @params[in] SockFd for file descriptor
+ * @params[in] timeoutPtr indicates the timeout value
+ * @params[in] MemInfo, recvMsgSet
*
* @return ROK - success
* RFAILED - failure
*
* ****************************************************************/
-S16 sctpInmsgHdlr(struct msghdr *msg, size_t msgLen)
-{
- sctp_cmsg_data_t *data;
- struct cmsghdr *cmsg;
- union sctp_notification *sn;
- Buffer *mBuf;
- Pst *pst;
-
- for (cmsg = CMSG_FIRSTHDR(msg); cmsg != NULL; cmsg = CMSG_NXTHDR(msg, cmsg))
- {
- data = (sctp_cmsg_data_t *)CMSG_DATA(cmsg);
- }
-
- printf("\nReceived Message");
- /* if incoming message is data */
- if (!(MSG_NOTIFICATION & msg->msg_flags))
+uint8_t processPolling(sctpSockPollParams *pollParams, CmInetFd *sockFd, uint32_t *timeoutPtr, CmInetMemInfo *memInfo, bool recvMsgSet)
+{
+ uint8_t ret = ROK;
+ CM_INET_FD_SET(sockFd, &pollParams->readFd);
+ ret = cmInetSelect(&pollParams->readFd, NULLP, timeoutPtr, (int16_t *)&pollParams->numFd);
+ if(CM_INET_FD_ISSET(sockFd, &pollParams->readFd))
{
- /* Extract message */
- U8 index = 0;
- char *recvBuf;
- char *temp = recvBuf;
- U8 len = msgLen;
- U8 temp_len;
- U8 i;
-
- while( msgLen > 0)
- {
- temp = msg->msg_iov[index].iov_base;
- temp_len = msg->msg_iov[index].iov_len;
+ CM_INET_FD_CLR(sockFd, &pollParams->readFd);
+ ret = cmInetSctpRecvMsg(sockFd, &pollParams->addr, &pollParams->port, memInfo, &(pollParams->mBuf), &pollParams->bufLen, &pollParams->info, &pollParams->flag, &pollParams->ntfy);
- if(temp_len > msgLen)
+ if(ret != ROK)
+ {
+ DU_LOG("\nERROR --> SCTP: Failed to receive sctp msg for sockFd[%d]\n", sockFd->fd);
+ recvMsgSet = RFAILED;
+ }
+ else
+ {
+ if((((pollParams->flag & CM_INET_SCTP_MSG_NOTIFICATION) != 0)) && ret == ROK)
{
- temp[(temp_len = msgLen) - 1] = '\0';
+ if(pollParams->port == f1Params.destPort)
+ {
+ f1Params.assocId = pollParams->ntfy.u.assocChange.assocId;
+ DU_LOG("\nDEBUG --> SCTP : AssocId assigned to F1Params from PollParams [%d]\n", f1Params.assocId);
+ ret = sctpNtfyHdlr(&pollParams->ntfy, &f1Params.itfState);
+ }
+ else if(pollParams->port == ricParams.destPort)
+ {
+ ricParams.assocId = pollParams->ntfy.u.assocChange.assocId;
+ DU_LOG("\nDEBUG --> SCTP : AssocId assigned to ricParams from PollParams [%d]\n", ricParams.assocId);
+ ret = sctpNtfyHdlr(&pollParams->ntfy, &ricParams.itfState);
+ }
+ else
+ {
+ DU_LOG("\nERROR --> SCTP : Failed to fill AssocId\n");
+ return RFAILED;
+ }
+ if(ret != ROK)
+ {
+ DU_LOG("\nERROR --> SCTP : Failed to process sctp notify msg\n");
+ }
}
-
- if((msgLen -= temp_len) > 0)
- {
- index++;
+ else if(f1Params.itfState & (pollParams->port == f1Params.destPort))
+ {
+ sendToDuApp(pollParams->mBuf, EVENT_CU_DATA);
}
- for (i = 0; i < temp_len-1 ; ++i)
- {
- if (!isprint(temp[i]))
- temp[i] = '.';
+ else if(ricParams.itfState & (pollParams->port == ricParams.destPort))
+ {
+ sendToDuApp(pollParams->mBuf, EVENT_RIC_DATA);
}
- printf("\nPrinting temp %s", temp);
- temp = temp + temp_len;
- index++;
- }
- recvBuf[len - 1] = '\0';
- printf("\n Message: %s temp %s", recvBuf, temp);
- /* Post received message to du_App */
- if(SGetMsg(0, 0, &mBuf) == ROK )
- {
- if(SAddPstMsgMult((Data *)recvBuf, len, mBuf) == ROK)
+ else
{
- pst->dstProcId;
- pst->srcProcId;
- pst->dstEnt = ENTDUAPP;
- pst->dstInst = 0;
- pst->srcEnt = ENTSCTP;
- pst->srcInst = 0;
- pst->prior;
- pst->route;
- pst->event = EVTSCTPUP;
- pst->region = 0;
- pst->pool = 0;
- pst->selector = 0;
- pst->intfVer;
-
- SPstTsk(pst, mBuf);
+ ODU_PUT_MSG_BUF(pollParams->mBuf);
}
}
-
-
- }
- else /* If the incoming message is notification */
- {
- /* Extract and perform necessary action
- Change the connUp state accordingly */
- union sctp_notification *notify;
- notify = (union sctp_notification *)msg->msg_iov->iov_base;
-
- if (SCTP_ASSOC_CHANGE != notify->sn_header.sn_type)
- {
- printf("\nReceived unexpected notification: %d", notify->sn_header.sn_type);
- RETVALUE(RFAILED);
- }
-
- switch(notify->sn_assoc_change.sac_state)
- {
- case SCTP_COMM_UP:
- printf("Received SCTP_COMM_UP\n");
- break;
- case SCTP_COMM_LOST:
- printf("Received SCTP_COMM_LOST\n");
- break;
- case SCTP_RESTART:
- printf("Received SCTP_RESTART\n");
- break;
- case SCTP_SHUTDOWN_COMP:
- printf("Received SCTP_SHUTDOWN_COMP\n");
- break;
- case SCTP_CANT_STR_ASSOC:
- printf("Received SCTP_CANT_STR_ASSOC\n");
- break;
- }
- }
- RETVALUE(ROK);
+ }
+ return ROK;
}
-
/*******************************************************************
*
* @brief Receives message on the socket
* RFAILED - failure
*
* ****************************************************************/
-S16 sctpSockPoll()
+uint8_t sctpSockPoll()
{
- U8 error;
- struct msghdr inmessage;
- struct iovec iov;
- char incmsg[CMSG_SPACE(sizeof(_sctp_cmsg_data_t))];
- sockaddr_storage_t msgname;
-
- /* Initialize inmessage with enough space for DATA... */
- memset(&inmessage, 0, sizeof(inmessage));
- if ((iov.iov_base = malloc(REALLY_BIG)) == NULL)
+ uint8_t ret = ROK;
+ uint32_t timeout;
+ uint32_t *timeout_Ptr;
+ CmInetMemInfo memInfo;
+ sctpSockPollParams f1PollParams, e2PollParams;
+
+ memset(&f1PollParams, 0, sizeof(sctpSockPollParams));
+ memset(&e2PollParams, 0, sizeof(sctpSockPollParams));
+
+ if (f1Params.sockFd.blocking & ricParams.sockFd.blocking)
{
- printf("\n malloc not enough memory!!!");
- close(sockFd);
- connUp = FALSE;
- RETVALUE(RFAILED);
+ /* blocking */
+ timeout_Ptr = NULLP;
}
- iov.iov_len = REALLY_BIG;
- inmessage.msg_iov = &iov;
- inmessage.msg_iovlen = 1;
- /* or a control message. */
- inmessage.msg_control = incmsg;
- inmessage.msg_controllen = sizeof(incmsg);
- inmessage.msg_name = &msgname;
- inmessage.msg_namelen = sizeof(msgname);
-
- while (connUp)
+ else
+ {
+ /* non-blocking */
+ timeout = 0;
+ timeout_Ptr = &timeout;
+ }
+ memInfo.region = DU_APP_MEM_REGION;
+ memInfo.pool = DU_POOL;
+
+ CM_INET_FD_ZERO(&f1PollParams.readFd);
+ CM_INET_FD_ZERO(&e2PollParams.readFd);
+
+ DU_LOG("\nINFO --> SCTP : Polling started at DU\n");
+ while(true)
{
- error = recvmsg(sockFd, &inmessage, MSG_WAITALL);
- if (error < 0)
+ if(f1Params.itfState)
{
- if (nonblocking && (EAGAIN == errno))
+ if((ret = processPolling(&f1PollParams, &f1Params.sockFd, timeout_Ptr, &memInfo, f1Params.recvMsgSet)) != ROK)
{
- error = 0;
- continue;
+ DU_LOG("\nERROR --> SCTP : Failed to RecvMsg for F1\n");
}
- if (socket_type == SOCK_STREAM)
+ }
+ if(ricParams.itfState)
+ {
+ if((ret = processPolling(&e2PollParams, &ricParams.sockFd, timeout_Ptr, &memInfo, ricParams.recvMsgSet)) != ROK)
{
- if (ENOTCONN != errno)
- {
- break;
- }
- printf("No association is present now!!\n");
- close(sockFd);
- sockFd = 0;
- connUp = FALSE;
- }
- break;
+ DU_LOG("\nERROR --> SCTP : Failed to RecvMsg for E2\n");
+ }
}
-
- sctpInmsgHdlr(&inmessage, error);
-
- inmessage.msg_control = incmsg;
- inmessage.msg_controllen = sizeof(incmsg);
- inmessage.msg_name = &msgname;
- inmessage.msg_namelen = sizeof(msgname);
- iov.iov_len = REALLY_BIG;
-
- }/* End of while(connUp) */
-
- RETVALUE(ROK);
+ };
+ return (ret);
}/* End of sctpSockPoll() */
/*******************************************************************
*
* @details
*
- * Function : sctpOutMsgSend
+ * Function : sctpSend
*
* Functionality:
* Send message on SCTP socket
* RFAILED - failure
*
* ****************************************************************/
-S16 sctpOutMsgSend(char *message, U8 msglen)
+uint8_t sctpSend(Buffer *mBuf, uint8_t itfType)
{
- struct msghdr outmsg;
- struct iovec iov;
- int error = 0;
-
- do{
- if(connUp && msglen != 0)
- {
- iov.iov_base = message;
- iov.iov_len = msglen;
+ uint8_t ret =0;
+ MsgLen len =0; /* number of actually sent octets */
+ CmInetMemInfo memInfo;
- outmsg.msg_iov = &iov;
- outmsg.msg_iovlen = 1;
- outmsg.msg_control = NULL;
- outmsg.msg_controllen = 0;
- outmsg.msg_name = &remote_addr;
- outmsg.msg_namelen = ra_len;
- outmsg.msg_flags = 0;
-
- error = sendmsg(sockFd, &outmsg, 0);
- }
-
- if(error != msglen)
- {
- if(nonblocking && EAGAIN == errno)
- {
- continue;
- }
- else
- {
- printf("\n Error [%s] while sending message on SCTP assoc", strerror(errno));
- RETVALUE(RFAILED);
- }
- }
- else
- {
- break;
- }
- }while(error != msglen);
-
- RETVALUE(ROK);
-
-} /* End of sctpOutMsgSend */
+ memInfo.region = DU_APP_MEM_REGION;
+ memInfo.pool = DU_POOL;
-/*******************************************************************
- *
- * @brief SCTP Assoc establishment request from DU
- *
- * @details
- *
- * Function : sctpAssocReq
- *
- * Functionality:
- * This function opens a socket at DU and
- * intiates SCTP connection.
- *
- * @params[in]
- * @return ROK - success
- * RFAILED - failure
- *
- * ****************************************************************/
-
-void sctpAssocReq()
-{
- /* Open SCTP socket and bind to local address */
- if(openSctpEndp() != ROK)
+ if(itfType == F1_INTERFACE)
{
- printf("\nFailed while opening SCTP endpoint");
- if(sockFd > 0 )
- {
- close(sockFd);
- sockFd = 0;
- }
- /* TODO : Send Assoc establishment failure to du_app if needed*/
+ DU_LOG("\nDEBUG --> SCTP : sending the message to DuApp");
+ ret = cmInetSctpSendMsg(&f1Params.sockFd, &f1Params.destIpNetAddr, f1Params.destPort, &memInfo, mBuf, &len, 0, FALSE, 0, 0/*SCT_PROTID_NONE*/, RWOULDBLOCK);
}
- else if(sctpConnect() != ROK) /* send connection request */
+
+ if(itfType == E2_INTERFACE)
{
- printf("\nFailed while connecting to peer");
- close(sockFd);
- sockFd = 0;
- assocId = 0;
- nonblocking = FALSE;
- /* TODO : Send Assoc establishment failure to du_app */
+ DU_LOG("\nDEBUG --> SCTP : sending the message to ric");
+ ret = cmInetSctpSendMsg(&ricParams.sockFd, &ricParams.destIpNetAddr, ricParams.destPort, &memInfo, mBuf, &len, 0, FALSE, 0, 0/*SCT_PROTID_NONE*/, RWOULDBLOCK);
}
- else
+
+ if(ret != ROK && ret != RWOULDBLOCK)
{
- /* Send AssocCfm to du_app */
- if(sctpSockPoll() != ROK)
- {
- printf("\nFailed while polling");
- /* Send failure to du_app */
- }
+ DU_LOG("\nERROR --> SCTP : Failed sending the message");
+ return RFAILED;
}
-} /* End of sctpAssocReq */
+
+ return ROK;
+} /* End of sctpSend */
/**********************************************************************
End of file