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 EGTP related functionality */
20 #include "common_def.h"
28 #include "du_app_mac_inf.h"
29 #include "du_e2ap_mgr.h"
32 #include "du_app_rlc_inf.h"
37 /**************************************************************************
38 * @brief Task Initiation callback function.
42 * Function : egtpActvInit
45 * This function is supplied as one of parameters during EGTP's
46 * task registration. SSI will invoke this function once, after
47 * it creates and attaches this TAPA Task to a system task.
49 * @param[in] Ent entity, the entity ID of this task.
50 * @param[in] Inst inst, the instance ID of this task.
51 * @param[in] Region region, the region ID registered for memory
53 * @param[in] Reason reason.
54 * @return ROK - success
56 ***************************************************************************/
57 uint8_t egtpActvInit(Ent entity, Inst inst, Region region, Reason reason)
59 DU_LOG("\n\nDEBUG --> EGTP : Initializing");
61 memset (&egtpCb, 0, sizeof(EgtpGlobalCb));
62 protType = CM_INET_PROTO_UDP;
68 #ifdef CALL_FLOW_DEBUG_LOG
69 /**************************************************************************
70 * @brief Function prints the src dest and msg reached to egtp.
74 * Function : callFlowEgtpActvTsk
77 * Function prints the src dest and msg reached to egtp.
79 * @param[in] Pst *pst, Post structure of the primitive.
83 ***************************************************************************/
85 void callFlowEgtpActvTsk(Pst *pst)
89 char destTask[50]="ENTEGTP";
96 strcpy(sourceTask,"ENTDUAPP");
101 strcpy(message,"EVTCFGREQ");
106 strcpy(message,"EVTSRVOPENREQ");
111 strcpy(message,"EVTTNLMGMTREQ");
116 strcpy(message,"Invalid Event");
124 strcpy(sourceTask,"ENTEGTP");
129 strcpy(message,"EVTSTARTPOLL");
134 strcpy(message,"Invalid Event");
142 strcpy(sourceTask,"ENTRLC");
147 strcpy(message,"EVTDATIND");
152 strcpy(message,"Invalid Event");
160 strcpy(sourceTask,"Invalid Source Entity Id");
163 DU_LOG("\nCall Flow: %s -> %s : %s\n", sourceTask, destTask, message);
167 /**************************************************************************
168 * @brief Task Activation callback function.
172 * Function : egtpActvTsk
175 * This function handles all EGTP messages received
176 * This API is registered with SSI during the
177 * Task Registration of DU APP.
179 * @param[in] Pst *pst, Post structure of the primitive.
180 * @param[in] Buffer *mBuf, Packed primitive parameters in the
182 * @return ROK - success
185 ***************************************************************************/
186 uint8_t egtpActvTsk(Pst *pst, Buffer *mBuf)
190 #ifdef CALL_FLOW_DEBUG_LOG
191 callFlowEgtpActvTsk(pst);
202 ret = unpackEgtpCfgReq(egtpCfgReq, pst, mBuf);
207 ret = unpackEgtpSrvOpenReq(egtpSrvOpenReq, pst, mBuf);
212 ret = unpackEgtpTnlMgmtReq(egtpTnlMgmtReq, pst, mBuf);
217 DU_LOG("\nERROR --> EGTP : Invalid event %d", pst->event);
218 ODU_PUT_MSG_BUF(mBuf);
230 DU_LOG("\nDEBUG --> EGTP : Starting Socket Polling");
232 ODU_PUT_MSG_BUF(mBuf);
237 DU_LOG("\nERROR --> EGTP : Invalid event %d", pst->event);
238 ODU_PUT_MSG_BUF(mBuf);
255 DU_LOG("\nERROR --> EGTP : Invalid event %d", pst->event);
263 DU_LOG("\nERROR --> EGTP : Invalid source entity %d", pst->srcEnt);
271 /**************************************************************************
272 * @brief EGTP server configuration
276 * Function : egtpCfgReq
279 * This function handles EGTP configuration request.
281 * @return ROK - success
284 * ***********************************************************************/
285 uint8_t egtpCfgReq(Pst *pst, EgtpConfig egtpCfg)
287 uint8_t ret; /* Return value */
288 Pst rspPst; /* Response Pst structure */
289 CmStatus cfgCfm; /* Configuration Confirm */
291 memcpy(&egtpCb.egtpCfg, &egtpCfg, sizeof(EgtpConfig));
293 egtpCb.localAddr.address = CM_INET_NTOH_UINT32(egtpCb.egtpCfg.localIp.ipV4Addr);
294 egtpCb.localAddr.port = egtpCb.egtpCfg.localPort;
296 egtpCb.dstCb.dstAddr.address = CM_INET_NTOH_UINT32(egtpCb.egtpCfg.destIp.ipV4Addr);
297 egtpCb.dstCb.dstAddr.port = egtpCb.egtpCfg.destPort;
298 egtpCb.dstCb.numTunn = 0;
300 ret = cmHashListInit(&(egtpCb.dstCb.teIdLst), 1024, sizeof(EgtpTeIdCb), FALSE, CM_HASH_KEYTYPE_UINT32_MOD, DU_APP_MEM_REGION, DU_POOL);
304 DU_LOG("\nERROR --> EGTP : TeId hash list initialization failed");
305 cfgCfm.status = LCM_PRIM_NOK;
306 cfgCfm.reason = LCM_REASON_HASHING_FAILED;
310 DU_LOG("\nDEBUG --> EGTP : EGTP configuration successful");
311 cfgCfm.status = LCM_PRIM_OK;
312 cfgCfm.reason = LCM_REASON_NOT_APPL;
315 /* Fill response Pst */
316 egtpFillRspPst(pst, &rspPst);
317 rspPst.event = EVTCFGCFM;
319 packEgtpCfgCfm(&rspPst, cfgCfm);
324 /**************************************************************************
325 * @brief Fills post structure to send response
329 * Function : egtpFillRspPst
332 * Fills post struture to send response
334 * @return ROK - success
338 * ***********************************************************************/
339 uint8_t egtpFillRspPst(Pst *pst, Pst *rspPst)
342 memset(rspPst, 0, sizeof(Pst));
343 rspPst->srcEnt = pst->dstEnt;
344 rspPst->srcInst = pst->dstInst;
345 rspPst->srcProcId = pst->dstProcId;
346 rspPst->dstEnt = pst->srcEnt;
347 rspPst->dstInst = pst->srcInst;
348 rspPst->dstProcId = pst->srcProcId;
349 rspPst->selector = ODU_SELECTOR_LC;
350 rspPst->pool= DU_POOL;
355 /**************************************************************************
356 * @brief EGTP server open request
360 * Function : egtpSrvOpenReq
363 * This function handles EGTP open server request.
364 * It opens udp socket to receive/send msgs.
366 * @param[in] Pst *pst, post structure
367 * @return ROK - success
370 ***************************************************************************/
372 uint8_t egtpSrvOpenReq(Pst *pst)
375 uint8_t ret; /* Return value */
376 Pst rspPst; /* Response Pst structure */
377 Pst egtpPst; /* Self post */
378 CmStatus cfm; /* Confirmation status */
379 uint8_t sockType; /* Socket type */
381 DU_LOG("\nDEBUG --> EGTP : Received EGTP open server request");
383 sockType = CM_INET_DGRAM;
384 ret = egtpSrvOpenPrc(sockType);
385 /* Opening and Binding receiver socket */
388 DU_LOG("\nERROR --> EGTP : Failed while opening receiver transport server");
392 DU_LOG("\nDEBUG --> EGTP : Socket [%d] is open", egtpCb.sockFd.fd);
394 /* Start Socket polling */
395 memset(&egtpPst, 0, sizeof(egtpPst));
396 egtpPst.srcEnt = (Ent)ENTEGTP;
397 egtpPst.srcInst = (Inst)EGTP_INST;
398 egtpPst.srcProcId = DU_PROC;
399 egtpPst.dstEnt = (Ent)ENTEGTP;
400 egtpPst.dstInst = (Inst)EGTP_INST;
401 egtpPst.dstProcId = DU_PROC;
402 egtpPst.event = EVTSTARTPOLL;
403 egtpPst.selector = ODU_SELECTOR_LC;
404 egtpPst.pool= DU_POOL;
405 packEgtpStartPollingReq(&egtpPst);
407 /* Filling and sending response */
408 cfm.status = LCM_PRIM_OK;
409 cfm.reason = LCM_REASON_NOT_APPL;
411 egtpFillRspPst(pst, &rspPst);
412 rspPst.event = EVTSRVOPENCFM;
413 packEgtpSrvOpenCfm(&rspPst, cfm);
418 /*******************************************************************
420 * @brief Processing Sever open request
424 * Function : egtpSrvOpenPrc
430 * @return ROK - success
433 * ****************************************************************/
435 uint8_t egtpSrvOpenPrc(uint8_t sockType)
438 ret = cmInetSocket(sockType, &(egtpCb.sockFd), protType);
441 DU_LOG("\nERROR --> EGTP : Failed to open UDP socket");
444 ret = cmInetBind(&(egtpCb.sockFd), &(egtpCb.localAddr));
447 DU_LOG("\nERROR --> EGTP : Failed to bind socket");
454 /**************************************************************************
455 * @brief EGTP tunnel management request
459 * Function : egtpTnlMgmtReq
462 * This function handles EGTP tunnel managament request
464 * @param[in] Tunnel Eveny structure
465 * @return ROK - success
469 * ***************************************************************************/
470 uint8_t egtpTnlMgmtReq(Pst *pst, EgtpTnlEvt tnlEvt)
474 #ifdef CALL_FLOW_DEBUG_LOG
475 DU_LOG("\nCall Flow: ENTDUAPP -> ENTEGTP : TNL_MGMT\n");
478 DU_LOG("\nDEBUG --> EGTP : Received tunnel management request");
479 switch(tnlEvt.action)
481 case EGTP_TNL_MGMT_ADD:
483 ret = egtpTnlAdd(tnlEvt);
486 case EGTP_TNL_MGMT_MOD:
488 ret = egtpTnlMod(tnlEvt);
491 case EGTP_TNL_MGMT_DEL:
493 ret = egtpTnlDel(tnlEvt);
498 DU_LOG("\nERROR --> EGTP : Invalid tunnel management action[%d]", tnlEvt.action);
499 ret = LCM_REASON_INVALID_ACTION;
505 tnlEvt.cfmStatus.status = LCM_PRIM_OK;
506 tnlEvt.cfmStatus.reason = LCM_REASON_NOT_APPL;
510 tnlEvt.cfmStatus.status = LCM_PRIM_NOK;
511 tnlEvt.cfmStatus.reason = ret;
514 DU_LOG("\nDEBUG --> EGTP : Sending Tunnel management confirmation");
515 duHdlEgtpTnlMgmtCfm(tnlEvt);
520 /**************************************************************************
521 * @brief EGTP tunnel addition
525 * Function : egtpTnlAdd
528 * This function handles EGTP tunnel addition
530 * @param[in] Tunnel Event structure
531 * @return ROK - success
534 * ***************************************************************************/
535 uint8_t egtpTnlAdd(EgtpTnlEvt tnlEvt)
538 EgtpTeIdCb *teidCb; /* Tunnel endpoint control block */
539 EgtpMsgHdr preDefHdr; /* pre-define header for this tunnel */
541 DU_LOG("\nINFO --> EGTP : Tunnel addition : LocalTeid[%d] Remote Teid[%d]", tnlEvt.lclTeid, tnlEvt.remTeid);
543 DU_ALLOC(teidCb, sizeof(EgtpTeIdCb));
546 DU_LOG("\nERROR --> EGTP : Memory allocation failed");
547 return LCM_REASON_MEM_NOAVAIL;
550 memset(teidCb, 0, sizeof(EgtpTeIdCb));
551 teidCb->teId = tnlEvt.lclTeid;
552 teidCb->remTeId = tnlEvt.remTeid;
554 ret = cmHashListInsert(&(egtpCb.dstCb.teIdLst), (PTR)teidCb, (uint8_t *)&(teidCb->teId), sizeof(uint32_t));
557 DU_LOG("\nERROR --> EGTP : Failed to insert in hash list");
558 DU_FREE(teidCb, sizeof(EgtpTeIdCb));
559 return LCM_REASON_HASHING_FAILED;
561 egtpCb.dstCb.numTunn++;
563 /* Encoding pre-defined header */
564 memset(&preDefHdr, 0, sizeof(EgtpMsgHdr));
565 preDefHdr.msgType = EGTPU_MSG_GPDU;
566 preDefHdr.teId = teidCb->remTeId;
567 preDefHdr.extHdr.pdcpNmb.pres = FALSE;
568 preDefHdr.extHdr.udpPort.pres = FALSE;
569 preDefHdr.nPdu.pres = FALSE;
571 egtpEncodeHdr((uint8_t *)teidCb->preEncodedHdr.hdr, &preDefHdr, &(teidCb->preEncodedHdr.cnt));
576 /**************************************************************************
577 * @brief EGTP tunnel modification
581 * Function : egtpTnlMod
584 * This function handles EGTP tunnel modification
586 * @param[in] Tunnel Event structure
587 * @return ROK - success
590 * ***************************************************************************/
591 uint8_t egtpTnlMod(EgtpTnlEvt tnlEvt)
593 EgtpTeIdCb *teidCb = NULLP;
595 DU_LOG("\nINFO --> EGTP : Tunnel modification : LocalTeid[%d] Remote Teid[%d]", tnlEvt.lclTeid, tnlEvt.remTeid);
597 cmHashListFind(&(egtpCb.dstCb.teIdLst), (uint8_t *)&(tnlEvt.lclTeid), sizeof(uint32_t), 0, (PTR *)&teidCb);
600 DU_LOG("\nERROR --> EGTP : Tunnel id not found");
603 teidCb->teId = tnlEvt.remTeid;
604 teidCb->remTeId = tnlEvt.remTeid;
608 /**************************************************************************
609 * @brief EGTP tunnel deletion
613 * Function : egtpTnlDel
616 * This function handles EGTP tunnel deletion
618 * @param[in] Tunnel Event structure
619 * @return ROK - success
622 * ***************************************************************************/
623 uint8_t egtpTnlDel(EgtpTnlEvt tnlEvt)
625 EgtpTeIdCb *teidCb = NULLP;
627 DU_LOG("\nINFO --> EGTP : Tunnel deletion : Local Teid[%d] Remote Teid[%d]", tnlEvt.lclTeid, tnlEvt.remTeid);
629 cmHashListFind(&(egtpCb.dstCb.teIdLst), (uint8_t *)&(tnlEvt.lclTeid), sizeof(uint32_t), 0, (PTR *)&teidCb);
632 DU_LOG("\nERROR --> EGTP : Tunnel id[%d] not configured", tnlEvt.lclTeid);
633 return LCM_REASON_INVALID_PAR_VAL;
636 cmHashListDelete(&(egtpCb.dstCb.teIdLst), (PTR)teidCb);
637 DU_FREE(teidCb, sizeof(EgtpTeIdCb));
638 egtpCb.dstCb.numTunn--;
642 /*******************************************************************
644 * @brief Handles data indication
648 * Function : EgtpHdlDatInd
651 * Handles incoming data from peer to be passed
655 * @return ROK - success
658 * ****************************************************************/
659 uint8_t egtpHdlDatInd(EgtpMsg egtpMsg)
661 EgtpTeIdCb *teidCb = NULLP;
667 #ifdef CALL_FLOW_DEBUG_LOG
668 DU_LOG("\nCall Flow: ENTDUAPP -> ENTEGTP : DATA_INDICATION\n");
671 DU_LOG("\nDEBUG --> EGTP : Received Data Indication");
673 cmHashListFind(&(egtpCb.dstCb.teIdLst), (uint8_t *)&(egtpMsg.msgHdr.teId), sizeof(uint32_t), 0, (PTR *)&teidCb);
676 DU_LOG("\nERROR --> EGTP : Tunnel id[%d] not configured", egtpMsg.msgHdr.teId);
677 return LCM_REASON_INVALID_PAR_VAL;
680 msgHdr = &(egtpMsg.msgHdr);
682 hdrLen = teidCb->preEncodedHdr.cnt;
684 if(msgHdr->extHdr.pdcpNmb.pres)
686 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] |= EGTP_MASK_BIT3;
687 teidCb->preEncodedHdr.hdr[hdrLen] = EGTP_EXT_HDR_PDCP_TYPE;
688 teidCb->preEncodedHdr.hdr[--hdrLen] = 1;
689 teidCb->preEncodedHdr.hdr[--hdrLen] = GetHiByte(msgHdr->extHdr.pdcpNmb.val);
690 teidCb->preEncodedHdr.hdr[--hdrLen] = GetLoByte(msgHdr->extHdr.pdcpNmb.val);
691 teidCb->preEncodedHdr.hdr[--hdrLen] = 0;
695 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] &= ~(EGTP_MASK_BIT3);
698 ODU_GET_MSG_LEN(egtpMsg.msg, (int16_t *)&tPduSize);
700 /*Adjust the header to fill the correct length*/
701 msgLen = tPduSize + (EGTP_MAX_HDR_LEN - hdrLen) - 0x08;
703 /***********************************************
704 * Fill the length field of the message header *
705 ***********************************************/
706 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 3] = (uint8_t)GetHiByte(msgLen);
707 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 4] = (uint8_t)GetLoByte(msgLen);
709 /*Update the sequence number*/
710 if(egtpMsg.msgHdr.seqNum.pres)
712 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] |= (EGTP_MASK_BIT2);
713 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 9] = (uint8_t)GetHiByte(egtpMsg.msgHdr.seqNum.val);
714 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 10] = (uint8_t)GetLoByte(egtpMsg.msgHdr.seqNum.val);
718 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] &= ~(EGTP_MASK_BIT2);
721 DU_LOG("\nDEBUG --> EGTP : UL Data buffer before encoding header");
722 ODU_PRINT_MSG(egtpMsg.msg, 0, 0);
724 ODU_ADD_PRE_MSG_MULT(&teidCb->preEncodedHdr.hdr[hdrLen], (EGTP_MAX_HDR_LEN - hdrLen), egtpMsg.msg);
727 DU_LOG("\nDEBUG --> EGTP : UL Data buffer after encoding header");
728 ODU_PRINT_MSG(egtpMsg.msg, 0, 0);
731 egtpSendMsg(egtpMsg.msg);
732 ODU_PUT_MSG_BUF(egtpMsg.msg);
737 /*******************************************************************
739 * @brief Encodes outgoing message
743 * Function : egtpEncodeMsg
746 * Encodes EGTP message to be sent
748 * @params[in] EGTP message
750 * @return ROK - success
753 * ****************************************************************/
754 uint8_t egtpEncodeHdr(uint8_t *preEncodedHdr, EgtpMsgHdr *preDefHdr, uint8_t *hdrIdx)
756 uint8_t tmpByte = 0; /* Stores one byte of data for enc */
757 uint8_t cnt = EGTP_MAX_HDR_LEN; /* Stores the position */
758 bool extPres = FALSE; /* Flag for indication of S, E or P presense flag */
761 /* Encoding header */
762 tmpByte |= EGTP_MASK_BIT6; /* Setting 6th LSB of 1st byte as version */
763 tmpByte |= EGTP_MASK_BIT5; /* Setting 5th LSB of 1st byte as protocol type */
765 if(preDefHdr->extHdr.udpPort.pres || preDefHdr->extHdr.pdcpNmb.pres)
767 tmpByte |= EGTP_MASK_BIT3; /* Setting 3rd LSB of 1st byte if Extension heaeder is present */
770 if(preDefHdr->seqNum.pres)
772 tmpByte |= EGTP_MASK_BIT2;
775 if(preDefHdr->nPdu.pres)
777 tmpByte |= EGTP_MASK_BIT1;
780 if((tmpByte & EGTP_MASK_BIT1) || (tmpByte & EGTP_MASK_BIT2)||(tmpByte & EGTP_MASK_BIT3))
785 preEncodedHdr[--cnt] = tmpByte;
786 preEncodedHdr[--cnt] = preDefHdr->msgType;
788 /* Encode Tunnel endpoint */
789 preEncodedHdr[--cnt] = 0;
790 preEncodedHdr[--cnt] = 0;
791 nwWord = (uint16_t)(GetHiWord(preDefHdr->teId));
792 preEncodedHdr[--cnt] = (uint8_t)(GetHiByte(nwWord));
793 preEncodedHdr[--cnt] = (uint8_t)(GetLoByte(nwWord));
794 nwWord = (uint16_t)(GetLoWord(preDefHdr->teId));
795 preEncodedHdr[--cnt] = (uint8_t)(GetHiByte(nwWord));
796 preEncodedHdr[--cnt] = (uint8_t)(GetLoByte(nwWord));
798 /* Encode sequence number */
799 if(preDefHdr->seqNum.pres)
801 preEncodedHdr[--cnt] = GetHiByte(preDefHdr->seqNum.val);
802 preEncodedHdr[--cnt] = GetLoByte(preDefHdr->seqNum.val);
806 preEncodedHdr[--cnt] = 0;
807 preEncodedHdr[--cnt] = 0;
810 /* Encode nPdu number */
811 if(preDefHdr->nPdu.pres)
813 preEncodedHdr[--cnt] = preDefHdr->nPdu.val;
817 preEncodedHdr[--cnt] = 0;
820 if(preDefHdr->extHdr.udpPort.pres)
822 preEncodedHdr[--cnt] = EGTP_EXT_HDR_UDP_TYPE;
823 preEncodedHdr[--cnt] = 1;
824 preEncodedHdr[--cnt] = GetHiByte(preDefHdr->extHdr.udpPort.val);
825 preEncodedHdr[--cnt] = GetLoByte(preDefHdr->extHdr.udpPort.val);
828 if(preDefHdr->extHdr.pdcpNmb.pres)
830 preEncodedHdr[--cnt] = EGTP_EXT_HDR_PDCP_TYPE;
831 preEncodedHdr[--cnt] = 1;
832 preEncodedHdr[--cnt] = GetHiByte(preDefHdr->extHdr.pdcpNmb.val);
833 preEncodedHdr[--cnt] = GetLoByte(preDefHdr->extHdr.pdcpNmb.val);
836 if(tmpByte & EGTP_MASK_BIT3)
838 preEncodedHdr[--cnt] = 0;
842 preEncodedHdr[--cnt] = 0;
847 } /* egtpEncodeHdr */
849 /*******************************************************************
851 * @brief Sends message over UDP
855 * Function : egtpSendMsg
858 * Sends message over UDP
860 * @params[in] Message Buffer
861 * @return ROK - success
864 * ****************************************************************/
865 uint8_t egtpSendMsg(Buffer *mBuf)
870 static uint64_t numDataSent = 0;
872 info.region = DU_APP_MEM_REGION;
875 ret = cmInetSendMsg(&egtpCb.sockFd, &egtpCb.dstCb.dstAddr, &info, mBuf, (int16_t *)&txLen, CM_INET_NO_FLAG);
876 if(ret != ROK && ret != RWOULDBLOCK)
878 DU_LOG("\nERROR --> EGTP : Failed sending the message");
883 DU_LOG("\nDEBUG --> EGTP : Sent UL Message [%ld]", numDataSent+1);
890 /*******************************************************************
892 * @brief Receives EGTP message from UDP socket
896 * Function : egtpRecvMsg
899 * Receive incoming messages from UDP socket
902 * @return ROK - success
905 * ****************************************************************/
907 uint8_t egtpRecvMsg()
909 uint8_t ret; /* Return value */
910 uint16_t bufLen; /* Length of received buffer */
911 Buffer *recvBuf; /* Received buffer */
912 CmInetMemInfo memInfo; /* Buffer allocation info */
914 memInfo.region = DU_APP_MEM_REGION;
915 memInfo.pool = DU_POOL;
920 ret = cmInetRecvMsg(&egtpCb.sockFd, &egtpCb.dstCb.dstAddr, &memInfo, &recvBuf, (int16_t *)&bufLen, CM_INET_NO_FLAG);
921 if(ret == ROK && recvBuf != NULLP)
923 DU_LOG("\nDEBUG --> EGTP : Received DL Message[%ld]\n", gDlDataRcvdCnt + 1);
924 //ODU_PRINT_MSG(recvBuf, 0 ,0);
925 egtpHdlRecvData(recvBuf);
934 /*******************************************************************
936 * @brief Handles DL User data received from CU
940 * Function : egtpHdlRecvData
942 * Functionality: Handles DL User data received from CU
944 * @params[in] DL Usre data buffer
945 * @return ROK - success
948 * ****************************************************************/
949 uint8_t egtpHdlRecvData(Buffer *mBuf)
953 /* Decode EGTP header */
954 egtpDecodeHdr(mBuf, &egtpMsg);
956 /* TODO : Send received message to RLC */
957 duHdlEgtpDlData(&egtpMsg);
962 /*******************************************************************
964 * @brief Decodes EGTP header from DL User data
968 * Function : egtpDecodeHdr
970 * Functionality: Decodes EGTP header from DL User data
973 * @return ROK - success
976 * ****************************************************************/
977 uint8_t egtpDecodeHdr(Buffer *mBuf, EgtpMsg *egtpMsg)
979 uint8_t tmpByte[5]; /* Holds 5 byte of data after Decoding */
980 uint8_t version = 0; /* Holds the version type, decoded */
981 uint16_t msgLen = 0; /* Holds the msgLen from the Hdr */
982 uint16_t bufLen = 0; /* Holds the total buffer length */
983 uint8_t extHdrType = 0; /* Holds the Extension hdr type */
984 uint8_t extHdrLen = 0; /* Extension hdr length */
985 bool extPres = FALSE; /* Flag for indication of S, E or P presense flag */
987 ODU_GET_MSG_LEN(mBuf, (int16_t *)&bufLen);
989 /* Decode first byte and storing in temporary variable */
990 ODU_REM_PRE_MSG(&tmpByte[0], mBuf);
992 /* Extracting version fro 1st byte */
993 version = tmpByte[0] >> 5;
995 //DU_LOG("\nDEBUG --> EGTP : Version %d", version);
997 /* Decode message type */
998 ODU_REM_PRE_MSG((Data*)&(egtpMsg->msgHdr.msgType), mBuf);
999 //DU_LOG("\nDEBUG --> EGTP : msgType %d", egtpMsg->msgHdr.msgType);
1001 /****************************************************************************
1002 * Message length param is 2 bytes. So decode next 2 bytes from msg hdr and
1003 * performing OR operation on these two bytes to calculate message length
1004 ***************************************************************************/
1005 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
1006 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
1007 msgLen = (tmpByte[1] << 8) | tmpByte[2];
1010 //DU_LOG("\nDEBUG --> EGTP : msgLen %d", msgLen);
1013 /****************************************************************************
1014 * Tunnel id param is 4 bytes. So decode next 4 bytes from msg hdr and
1015 * perform OR operation on these 4 bytes to calculate tunnel id
1016 ***************************************************************************/
1017 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
1018 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
1019 ODU_REM_PRE_MSG(&tmpByte[3], mBuf);
1020 ODU_REM_PRE_MSG(&tmpByte[4], mBuf);
1021 egtpMsg->msgHdr.teId = (tmpByte[1] << 24) | (tmpByte[2] << 16) | (tmpByte[3] << 8) | tmpByte[4];
1022 //DU_LOG("\nDEBUG --> EGTP : teId %d",egtpMsg->msgHdr.teId);
1025 /* If any one of S, E or PN flag is set, set extension present as true. */
1026 if((tmpByte[0] & EGTP_MASK_BIT1) || (tmpByte[0] & EGTP_MASK_BIT2)||(tmpByte[0] & EGTP_MASK_BIT3))
1031 /* Decode sequence number, if S flag is set in first byte */
1032 if (tmpByte[0] & EGTP_MASK_BIT2)
1034 /************************************************************************
1035 * Sequence num is 2 bytes. So decode next 2 bytes from msg hdr and
1036 * perform OR operation on them
1037 ************************************************************************/
1038 egtpMsg->msgHdr.seqNum.pres = TRUE;
1039 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
1040 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
1041 egtpMsg->msgHdr.seqNum.val = (tmpByte[1] << 8) | tmpByte[2];
1043 /****************************************************************************
1044 * If extPres is true, but S bit is not set, implies, either of PN or E bit
1045 * was set during Encode so accordingly extract Byte fields for seqNum anyway
1046 ***************************************************************************/
1049 /*************************************************************************
1050 * Sequence num is 2 bytes. So decode next 2 bytes from msg hdr and
1051 * perform OR operation on them
1052 ************************************************************************/
1053 egtpMsg->msgHdr.seqNum.pres = 0;
1054 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
1055 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
1056 egtpMsg->msgHdr.seqNum.val = (tmpByte[1] << 8) | tmpByte[2];
1059 /* Decode N-PDU number if present flag is set */
1060 if (tmpByte[0] & EGTP_MASK_BIT1)
1062 egtpMsg->msgHdr.nPdu.pres = TRUE;
1063 ODU_REM_PRE_MSG(&(egtpMsg->msgHdr.nPdu.val), mBuf);
1065 /****************************************************************************
1066 * If extPres is true, but PN bit is not set, implies, either of S or E bit
1067 * was set during Encode. Aaccordingly extract Byte fields of N-PDU num anyway
1068 ***************************************************************************/
1071 egtpMsg->msgHdr.nPdu.pres = TRUE;
1072 ODU_REM_PRE_MSG(&(egtpMsg->msgHdr.nPdu.val), mBuf);
1075 /* If E flag is set in first byte, decode extension header */
1076 if(tmpByte[0] & EGTP_MASK_BIT3)
1078 ODU_REM_PRE_MSG(&extHdrType, mBuf);
1079 while( 0 != extHdrType)
1083 case EGTP_EXT_HDR_UDP_TYPE:
1085 ODU_REM_PRE_MSG(&extHdrLen, mBuf);
1086 if(extHdrLen == 0x01)
1088 /************************************************************
1089 * UDP Port is 2 bytes. So decode next 2 bytes from msg hdr
1090 * and perform OR operation on them
1091 *************************************************************/
1092 egtpMsg->msgHdr.extHdr.udpPort.pres = TRUE;
1093 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
1094 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
1095 egtpMsg->msgHdr.extHdr.udpPort.val = (tmpByte[1] << 8) | tmpByte[2];
1100 case EGTP_EXT_HDR_PDCP_TYPE:
1102 ODU_REM_PRE_MSG(&extHdrLen, mBuf);
1103 if(extHdrLen == 0x01)
1105 /*************************************************************
1106 * PDCP num is 2 bytes. So decode next 2 bytes from msg hdr
1107 * and perform OR operation on them
1108 ************************************************************/
1109 egtpMsg->msgHdr.extHdr.pdcpNmb.pres = TRUE;
1110 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
1111 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
1112 egtpMsg->msgHdr.extHdr.pdcpNmb.val = (tmpByte[1] << 8) | tmpByte[2];
1116 } /* End of switch */
1118 ODU_REM_PRE_MSG(&extHdrType, mBuf);
1120 } /* End of while */
1122 /****************************************************************************
1123 * If extPres is true, but E bit is not set, implies, either of PN or S bit
1124 * was set during Encode so accordingly extract Byte fields for extension
1126 ***************************************************************************/
1129 ODU_REM_PRE_MSG(&extHdrType, mBuf);
1132 egtpMsg->msg = mBuf;
1134 //DU_LOG("\nDEBUG --> EGTP : DL Data Buffer after decoding header ");
1135 //ODU_PRINT_MSG(mBuf, 0, 0);
1137 /* Forward the data to duApp/RLC */
1142 /**********************************************************************
1144 **********************************************************************/