static NwGtpv1uRcT nwGtpv1uInitialReq( NW_IN NwGtpv1uStackT *thiz, NW_IN NwGtpv1uUlpApiT *pUlpReq) { NwGtpv1uRcT rc = NW_GTPV1U_FAILURE; NwGtpv1uTrxnT *pTrxn; #if defined(LOG_GTPU) && LOG_GTPU > 0 NW_ENTER(thiz); #endif /* Create New Transaction */ rc = nwGtpv1uTrxnNew(thiz, &pTrxn); if(pTrxn) { rc = nwGtpv1uTrxnCreateAndSendMsg(thiz, pTrxn, pUlpReq->apiInfo.initialReqInfo.peerIp, pUlpReq->apiInfo.initialReqInfo.peerPort, (NwGtpv1uMsgT *) pUlpReq->hMsg); if(rc == NW_GTPV1U_OK) { /* Insert into search tree */ RB_INSERT(NwGtpv1uOutstandingTxSeqNumTrxnMap, &(thiz->outstandingTxSeqNumMap), pTrxn); } else { rc = nwGtpv1uTrxnDelete(&pTrxn); NW_ASSERT(rc == NW_GTPV1U_OK); } } #if defined(LOG_GTPU) && LOG_GTPU > 0 NW_LEAVE(thiz); #endif return rc; }
NwGtpv1uRcT nwGtpv1uProcessTimeout(void *timeoutInfo) { NwGtpv1uRcT rc = NW_GTPV1U_FAILURE; NwGtpv1uStackT *thiz; NW_ASSERT(timeoutInfo != NULL); thiz = (NwGtpv1uStackT *) (((NwGtpv1uTimeoutInfoT *) timeoutInfo)->hStack); NW_ASSERT(thiz != NULL); #if defined(LOG_GTPU) && LOG_GTPU > 0 NW_ENTER(thiz); #endif GTPU_DEBUG("Received timeout event from ULP with timeoutInfo 0x%p!\n", timeoutInfo); rc = (((NwGtpv1uTimeoutInfoT *) timeoutInfo)->timeoutCallbackFunc) (timeoutInfo); #if defined(LOG_GTPU) && LOG_GTPU > 0 NW_LEAVE(thiz); #endif return rc; }
static NwGtpv1uRcT nwGtpv1uCreateAndSendMsg( NwGtpv1uStackT *thiz, uint32_t peerIp, uint16_t peerPort, NwGtpv1uMsgT *pMsg) { NwGtpv1uRcT rc = NW_GTPV1U_FAILURE; uint8_t *msgHdr; NW_ASSERT(thiz); NW_ASSERT(pMsg); #if defined(LOG_GTPU) && LOG_GTPU > 0 NW_ENTER(thiz); #endif msgHdr = &pMsg->msgBuf[pMsg->msgBufOffset]; NW_ASSERT(msgHdr != NULL); *(msgHdr++) = (pMsg->version << 5) | (pMsg->protocolType << 4) | (pMsg->extHdrFlag << 2) | (pMsg->seqNumFlag << 1) | (pMsg->npduNumFlag); *(msgHdr++) = (pMsg->msgType); *((uint16_t *) msgHdr) = htons(pMsg->msgLen); msgHdr += 2; *((uint32_t *) msgHdr) = htonl(pMsg->teid); msgHdr += 4; #if defined(LOG_GTPU) && LOG_GTPU > 0 GTPU_DEBUG("nwGtpv1uCreateAndSendMsg to teid %u length %d offset %d\n", pMsg->teid, pMsg->msgLen, pMsg->msgBufOffset); #endif if(pMsg->seqNumFlag || pMsg->extHdrFlag || pMsg->npduNumFlag) { *((uint16_t *) msgHdr) = (pMsg->seqNumFlag ? htons(pMsg->seqNum) : 0x0000); msgHdr += 2; *((uint8_t *) msgHdr) = (pMsg->npduNumFlag ? htons(pMsg->npduNum) : 0x00); msgHdr++; *((uint8_t *) msgHdr) = (pMsg->extHdrFlag ? htons(pMsg->nextExtHdrType) : 0x00); msgHdr++; } rc = thiz->udp.udpDataReqCallback(thiz->udp.hUdp, pMsg->msgBuf, pMsg->msgBufLen, pMsg->msgBufOffset, peerIp, peerPort); #if defined(LOG_GTPU) && LOG_GTPU > 0 NW_LEAVE(thiz); #endif return rc; }
static NwSdpRcT nwSdpUpdateFlow( NW_IN NwSdpT* thiz, NW_IN NwSdpUlpApiT *pUlpReq) { NwSdpRcT rc; NW_ENTER(thiz); NW_LEAVE(thiz); return rc; }
NwGtpv1uRcT nwGtpv1uProcessUlpReq( NW_IN NwGtpv1uStackHandleT hGtpuStackHandle, NW_IN NwGtpv1uUlpApiT *pUlpReq) { NwGtpv1uRcT rc = NW_GTPV1U_FAILURE; NwGtpv1uStackT *thiz = (NwGtpv1uStackT *) hGtpuStackHandle; NW_ASSERT(thiz); NW_ASSERT(pUlpReq != NULL); #if defined(LOG_GTPU) && LOG_GTPU > 0 NW_ENTER(thiz); #endif switch(pUlpReq->apiType) { case NW_GTPV1U_ULP_API_CREATE_TUNNEL_ENDPOINT: { GTPU_DEBUG("Received NW_GTPV1U_ULP_API_CREATE_TUNNEL_ENDPOINT from ulp\n"); rc = NwGtpv1uCreateTunnelEndPoint(thiz, pUlpReq->apiInfo.createTunnelEndPointInfo.teid, pUlpReq->apiInfo.createTunnelEndPointInfo.hUlpSession, &(pUlpReq->apiInfo.createTunnelEndPointInfo.hStackSession)); } break; case NW_GTPV1U_ULP_API_DESTROY_TUNNEL_ENDPOINT: { GTPU_DEBUG("Received destroy session req from ulp\n"); rc = nwGtpv1uDestroyTunnelEndPoint(thiz, pUlpReq); } break; case NW_GTPV1U_ULP_API_INITIAL_REQ: { GTPU_DEBUG("Received initial req from ulp\n"); rc = nwGtpv1uInitialReq(thiz, pUlpReq); } break; case NW_GTPV1U_ULP_API_SEND_TPDU: { #if defined(LOG_GTPU) && LOG_GTPU > 0 GTPU_DEBUG("Received send tpdu req from ulp\n"); #endif rc = nwGtpv1uSendto(thiz, pUlpReq); } break; default: GTPU_DEBUG("Unsupported API received from ulp\n"); rc = NW_GTPV1U_FAILURE; break; } #if defined(LOG_GTPU) && LOG_GTPU > 0 NW_LEAVE(thiz); #endif return rc; }
static NwGtpv1uRcT NwGtpv1uCreateTunnelEndPoint( NW_IN NwGtpv1uStackT *thiz, NW_IN uint32_t teid, NW_IN NwGtpv1uUlpSessionHandleT hUlpSession, NW_OUT NwGtpv1uStackSessionHandleT *phStackSession ) { NwGtpv1uRcT rc = NW_GTPV1U_OK; NwGtpv1uTunnelEndPointT *pTunnelEndPoint; NwGtpv1uTunnelEndPointT *pCollision; #if defined(LOG_GTPU) && LOG_GTPU > 0 NW_ENTER(thiz); #endif pTunnelEndPoint = nwGtpTunnelEndPointNew(thiz); if(pTunnelEndPoint) { pTunnelEndPoint->teid = teid; pTunnelEndPoint->pStack = thiz; pTunnelEndPoint->hUlpSession = hUlpSession; pCollision = RB_INSERT(NwGtpv1uTunnelEndPointIdentifierMap, &(thiz->teidMap), pTunnelEndPoint); if(pCollision) { GTPU_ERROR("Tunnel end-point cannot be created for teid 0x%x. " "Tunnel already exists", teid); rc = nwGtpTunnelEndPointDestroy(thiz, pTunnelEndPoint); NW_ASSERT(rc == NW_GTPV1U_OK); *phStackSession = (NwGtpv1uStackSessionHandleT) NULL; NW_ASSERT(0); rc = NW_GTPV1U_FAILURE; } else { *phStackSession = (NwGtpv1uStackSessionHandleT) pTunnelEndPoint; pTunnelEndPoint = RB_FIND(NwGtpv1uTunnelEndPointIdentifierMap, &(thiz->teidMap), pTunnelEndPoint); NW_ASSERT(pTunnelEndPoint); GTPU_DEBUG("Tunnel end-point 0x%p creation successful for teid 0x%x %u(dec)", pTunnelEndPoint, (unsigned int)teid, (unsigned int)teid); } } else { *phStackSession = (NwGtpv1uStackSessionHandleT) NULL; rc = NW_GTPV1U_FAILURE; } #if defined(LOG_GTPU) && LOG_GTPU > 0 NW_LEAVE(thiz); #endif return rc; }
NwSdpRcT nwSdpProcessIpv4DataInd( NW_IN NwSdpHandleT hSdp, NW_IN NwSdpServiceHandleT hIpv4, NW_IN NwU8T* ipv4Buf, NW_IN NwU32T ipv4BufLen) { NwSdpRcT rc = NW_SDP_OK; NwSdpT* thiz; thiz = (NwSdpT*) hSdp; NW_ENTER(thiz); rc = nwIpv4ProcessLlpDataInd(thiz->hIpv4Stack, ipv4Buf, ipv4BufLen); NW_LEAVE(thiz); return rc; }
NwSdpRcT nwSdpProcessGreDataInd( NW_IN NwSdpHandleT hSdp, NW_IN NwSdpServiceHandleT hGre, NW_IN NwCharT* greBuf, NW_IN NwU32T greBufLen, NW_IN NwU16T peerPort, NW_IN NwU32T peerIp) { NwSdpRcT rc; NwSdpT* thiz; thiz = (NwSdpT*) hSdp; NW_ENTER(thiz); rc = nwGreProcessUdpReq(hGre, greBuf, greBufLen, peerPort, peerIp); NW_LEAVE(thiz); return rc; }
NwSdpRcT nwSdpProcessUlpReq( NW_IN NwSdpHandleT hSdp, NW_IN NwSdpUlpApiT *pUlpReq) { NwSdpRcT rc; NwSdpT* thiz = (NwSdpT*) hSdp; NW_ASSERT(thiz); NW_ASSERT(pUlpReq != NULL); NW_ENTER(thiz); switch(pUlpReq->apiType) { case NW_SDP_ULP_API_CREATE_FLOW: { NW_LOG(thiz, NW_LOG_LEVEL_DEBG, "Received create flow request from ulp"); rc = nwSdpCreateFlow(thiz, pUlpReq); } break; case NW_SDP_ULP_API_DESTROY_FLOW: { NW_LOG(thiz, NW_LOG_LEVEL_DEBG, "Received destroy flow request from ulp"); rc = nwSdpDestroyFlow(thiz, pUlpReq); } break; case NW_SDP_ULP_API_UPDATE_FLOW: { NW_LOG(thiz, NW_LOG_LEVEL_DEBG, "Received update flow request from ulp"); rc = nwSdpUpdateFlow(thiz, pUlpReq); } break; default: NW_LOG(thiz, NW_LOG_LEVEL_ERRO, "Unsupported API received from ulp"); rc = NW_SDP_FAILURE; break; } NW_LEAVE(thiz); return rc; }
NwSdpRcT nwSdpProcessUdpDataInd( NW_IN NwSdpHandleT hSdp, NW_IN NwU8T* udpData, NW_IN NwU32T udpDataLen, NW_IN NwU16T peerPort, NW_IN NwU32T peerIp) { NwSdpRcT rc; NwSdpT* thiz; thiz = (NwSdpT*) hSdp; NW_ASSERT(thiz); NW_ENTER(thiz); /* TODO : Process UDP message */ NW_LEAVE(thiz); return rc; }
NwSdpRcT nwSdpProcessGtpuDataInd( NW_IN NwSdpHandleT hSdp, NW_IN NwU8T* udpData, NW_IN NwU32T udpDataLen, NW_IN NwU16T peerPort, NW_IN NwU32T peerIp) { NwSdpRcT rc; NwSdpT* thiz; NwU16T msgType; thiz = (NwSdpT*) hSdp; NW_ASSERT(thiz); NW_ENTER(thiz); rc = nwGtpv1uProcessUdpReq(thiz->hGtpv1uStack, udpData, udpDataLen, peerPort, peerIp); NW_LEAVE(thiz); return rc; }
NwSdpRcT nwSdpProcessTimeout(void* timeoutInfo) { NwSdpRcT rc; NwSdpT* thiz; NW_ASSERT(timeoutInfo != NULL); thiz = (NwSdpT*) (((NwSdpTimeoutInfoT*) timeoutInfo)->hStack); NW_ASSERT(thiz != NULL); NW_ENTER(thiz); NW_LOG(thiz, NW_LOG_LEVEL_DEBG, "Received timeout event from ULP with timeoutInfo 0x%x!", (NwU32T)timeoutInfo); rc = (((NwSdpTimeoutInfoT*) timeoutInfo)->timeoutCallbackFunc) (timeoutInfo); NW_LEAVE(thiz); return rc; }
static NwGtpv1uRcT nwGtpv1uSendUlpMessageIndication( NW_IN NwGtpv1uStackT *thiz, NW_IN uint32_t hUlpTrxn, NW_IN uint32_t apiType, NW_IN uint32_t msgType, NW_IN uint32_t peerIp, NW_IN uint16_t peerPort, NW_IN uint8_t *pMsgBuf, NW_IN uint16_t msgLength) { NwGtpv1uRcT rc = NW_GTPV1U_FAILURE; NwGtpv1uUlpApiT ulpApi; #if defined(LOG_GTPU) && LOG_GTPU > 0 NW_ENTER(thiz); #endif ulpApi.apiType = apiType; ulpApi.apiInfo.recvMsgInfo.msgType = msgType; ulpApi.apiInfo.recvMsgInfo.hUlpTrxn = hUlpTrxn; ulpApi.apiInfo.recvMsgInfo.peerIp = peerIp; ulpApi.apiInfo.recvMsgInfo.peerPort = peerPort; if(pMsgBuf && msgLength) { rc = nwGtpv1uMsgFromBufferNew((NwGtpv1uStackHandleT)thiz, pMsgBuf, msgLength, &(ulpApi.apiInfo.recvMsgInfo.hMsg)); NW_ASSERT(rc == NW_GTPV1U_OK); } rc = thiz->ulp.ulpReqCallback(thiz->ulp.hUlp, &ulpApi); NW_ASSERT(rc == NW_GTPV1U_OK); #if defined(LOG_GTPU) && LOG_GTPU > 0 NW_LEAVE(thiz); #endif return rc; }
static NwGtpv1uRcT nwGtpv1uSendto( NwGtpv1uStackT *thiz, NW_IN NwGtpv1uUlpApiT *pUlpReq) { NwGtpv1uRcT rc = NW_GTPV1U_FAILURE; NW_ASSERT(thiz); #if defined(LOG_GTPU) && LOG_GTPU > 0 NW_ENTER(thiz); #endif (void) nwGtpv1uMsgSetTeid(pUlpReq->apiInfo.sendtoInfo.hMsg, pUlpReq->apiInfo.sendtoInfo.teid); rc = nwGtpv1uCreateAndSendMsg(thiz, pUlpReq->apiInfo.sendtoInfo.ipAddr, 2152, (NwGtpv1uMsgT *) (NwGtpv1uMsgT *) pUlpReq->apiInfo.sendtoInfo.hMsg); #if defined(LOG_GTPU) && LOG_GTPU > 0 NW_LEAVE(thiz); #endif return rc; }
static NwSdpRcT nwSdpCreateFlow( NW_IN NwSdpT* thiz, NW_IN NwSdpUlpApiT *pUlpReq) { NwSdpRcT rc = NW_SDP_OK; NwSdpFlowContextT* pFlowContext; NwSdpCreateFlowInfoT* pCreateFlowInfo; NW_ENTER(thiz); pFlowContext = nwSdpFlowContextNew(thiz); if(pFlowContext) { pCreateFlowInfo = &(pUlpReq->apiInfo.createFlowInfo); pFlowContext->ingressEndPoint = pCreateFlowInfo->ingressEndPoint; pFlowContext->egressEndPoint = pCreateFlowInfo->egressEndPoint; if(pFlowContext->egressEndPoint.flowType == NW_FLOW_TYPE_GTPU) { NW_ASSERT(pFlowContext->egressEndPoint.ipv4Addr != 0); } rc = nwSdpCreateFlowEndPoint(thiz, pFlowContext, &pFlowContext->ingressEndPoint); NW_ASSERT(rc == NW_SDP_OK); pFlowContext->pStack = thiz; } else { NW_ASSERT(pFlowContext); } pUlpReq->apiInfo.createFlowInfo.hSdpSession = (NwSdpSessionHandleT) pFlowContext; NW_LEAVE(thiz); return rc; }
NwGtpv1uRcT nwGtpv1uProcessUdpReq( NW_IN NwGtpv1uStackHandleT hGtpuStackHandle, NW_IN uint8_t *udpData, NW_IN uint32_t udpDataLen, NW_IN uint16_t peerPort, NW_IN uint32_t peerIp) { NwGtpv1uRcT ret = NW_GTPV1U_FAILURE; NwGtpv1uStackT *thiz; uint16_t msgType; #if defined(ENB_MODE) VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GTPV1U_PROCESS_UDP_REQ, VCD_FUNCTION_IN); #endif thiz = (NwGtpv1uStackT *) hGtpuStackHandle; NW_ASSERT(thiz); msgType = *((uint8_t *)(udpData + 1)); switch(msgType) { case NW_GTP_ECHO_REQ: GTPU_DEBUG("NW_GTP_ECHO_REQ\n"); ret = nwGtpv1uHandleEchoReq( thiz, udpData, udpDataLen, peerPort, peerIp); break; case NW_GTP_ERROR_INDICATION: GTPU_DEBUG("NW_GTP_ERROR_INDICATION\n"); ret = nwGtpv1uSendUlpMessageIndication( thiz, 0, NW_GTPV1U_ULP_API_RECV_MSG, msgType, peerIp, peerPort, udpData, udpDataLen); NW_ASSERT(ret == NW_GTPV1U_OK); break; case NW_GTP_ECHO_RSP: GTPU_DEBUG("NW_GTP_ECHO_RSP\n"); ret = NW_GTPV1U_OK; break; case NW_GTP_GPDU: #if defined(LOG_GTPU) && LOG_GTPU > 0 GTPU_DEBUG("NW_GTP_GPDU: DATA COMING FROM UDP\n"); #endif ret = nwGtpv1uProcessGpdu(thiz, udpData, udpDataLen, peerIp); break; default: ret = NW_GTPV1U_FAILURE; NW_ASSERT(0); break; } #if defined(LOG_GTPU) && LOG_GTPU > 0 NW_LEAVE(thiz); #endif #if defined(ENB_MODE) VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GTPV1U_PROCESS_UDP_REQ, VCD_FUNCTION_OUT); #endif return ret; }
static NwGtpv1uRcT nwGtpv1uProcessGpdu( NwGtpv1uStackT *thiz, NW_IN uint8_t *gpdu, NW_IN uint32_t gpduLen, NW_IN uint32_t peerIp) { NwGtpv1uRcT rc = NW_GTPV1U_FAILURE; NwGtpv1uMsgHeaderT *msgHdr = NULL; NwGtpv1uTunnelEndPointT *pTunnelEndPoint = NULL; NwGtpv1uTunnelEndPointT tunnelEndPointKey; // uint16_t hdr_len = 0; #if defined(LOG_GTPU) && LOG_GTPU > 0 NW_ENTER(thiz); #endif // no buffer offset msgHdr = (NwGtpv1uMsgHeaderT *) gpdu; tunnelEndPointKey.teid = ntohl(msgHdr->teid); pTunnelEndPoint = RB_FIND(NwGtpv1uTunnelEndPointIdentifierMap, &(thiz->teidMap), &tunnelEndPointKey); if(pTunnelEndPoint) { NwGtpv1uMsgHandleT hMsg; rc = nwGtpv1uMsgFromBufferNew( (NwGtpv1uStackHandleT)thiz, (uint8_t *)gpdu, gpduLen, &hMsg); /* uint8_t* msgBuf; uint32_t msgBufLen; uint32_t msgBufOffset; */ if(NW_GTPV1U_OK == rc) { NwGtpv1uMsgT *pMsg = (NwGtpv1uMsgT *) hMsg; #if defined(LOG_GTPU) && LOG_GTPU > 0 GTPU_DEBUG("Received T-PDU over tunnel end-point '%x' of size %u (%u) (decapsulated %u)from "NW_IPV4_ADDR"\n", ntohl(msgHdr->teid), gpduLen, pMsg->msgLen, pMsg->msgBufLen, NW_IPV4_ADDR_FORMAT((peerIp))); #endif MSC_LOG_RX_MESSAGE( (thiz->stackType == GTPU_STACK_ENB) ? MSC_GTPU_ENB:MSC_GTPU_SGW, (thiz->stackType == GTPU_STACK_ENB) ? MSC_GTPU_SGW:MSC_GTPU_ENB, NULL, 0, " G-PDU ltid %u size %u", tunnelEndPointKey.teid, gpduLen); rc = nwGtpSessionSendMsgApiToUlpEntity(pTunnelEndPoint, pMsg); } } else { MSC_LOG_RX_DISCARDED_MESSAGE( (thiz->stackType == GTPU_STACK_ENB) ? MSC_GTPU_ENB:MSC_GTPU_SGW, (thiz->stackType == GTPU_STACK_ENB) ? MSC_GTPU_SGW:MSC_GTPU_ENB, NULL, 0, " G-PDU ltid %u size %u", tunnelEndPointKey.teid, gpduLen); GTPU_ERROR("Received T-PDU over non-existent tunnel end-point '%x' from "NW_IPV4_ADDR"\n", ntohl(msgHdr->teid), NW_IPV4_ADDR_FORMAT((peerIp))); } #if defined(LOG_GTPU) && LOG_GTPU > 0 NW_LEAVE(thiz); #endif return rc; }