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"
27 #include "du_app_mac_inf.h"
30 #include "du_app_rlc_inf.h"
35 /**************************************************************************
36 * @brief Task Initiation callback function.
40 * Function : egtpActvInit
43 * This function is supplied as one of parameters during EGTP's
44 * task registration. SSI will invoke this function once, after
45 * it creates and attaches this TAPA Task to a system task.
47 * @param[in] Ent entity, the entity ID of this task.
48 * @param[in] Inst inst, the instance ID of this task.
49 * @param[in] Region region, the region ID registered for memory
51 * @param[in] Reason reason.
52 * @return ROK - success
54 ***************************************************************************/
55 uint8_t egtpActvInit(Ent entity, Inst inst, Region region, Reason reason)
57 DU_LOG("\n\nDEBUG --> EGTP : Initializing");
59 memset (&egtpCb, 0, sizeof(EgtpGlobalCb));
60 protType = CM_INET_PROTO_UDP;
66 #ifdef CALL_FLOW_DEBUG_LOG
67 /**************************************************************************
68 * @brief Function prints the src dest and msg reached to egtp.
72 * Function : callFlowEgtpActvTsk
75 * Function prints the src dest and msg reached to egtp.
77 * @param[in] Pst *pst, Post structure of the primitive.
81 ***************************************************************************/
83 void callFlowEgtpActvTsk(Pst *pst)
87 char destTask[50]="ENTEGTP";
94 strcpy(sourceTask,"ENTDUAPP");
99 strcpy(message,"EVTCFGREQ");
104 strcpy(message,"EVTSRVOPENREQ");
109 strcpy(message,"EVTTNLMGMTREQ");
114 strcpy(message,"Invalid Event");
122 strcpy(sourceTask,"ENTEGTP");
127 strcpy(message,"EVTSTARTPOLL");
132 strcpy(message,"Invalid Event");
140 strcpy(sourceTask,"ENTRLC");
145 strcpy(message,"EVTDATIND");
150 strcpy(message,"Invalid Event");
158 strcpy(sourceTask,"Invalid Source Entity Id");
161 DU_LOG("\nCall Flow: %s -> %s : %s\n", sourceTask, destTask, message);
165 /**************************************************************************
166 * @brief Task Activation callback function.
170 * Function : egtpActvTsk
173 * This function handles all EGTP messages received
174 * This API is registered with SSI during the
175 * Task Registration of DU APP.
177 * @param[in] Pst *pst, Post structure of the primitive.
178 * @param[in] Buffer *mBuf, Packed primitive parameters in the
180 * @return ROK - success
183 ***************************************************************************/
184 uint8_t egtpActvTsk(Pst *pst, Buffer *mBuf)
188 #ifdef CALL_FLOW_DEBUG_LOG
189 callFlowEgtpActvTsk(pst);
200 ret = unpackEgtpCfgReq(egtpCfgReq, pst, mBuf);
205 ret = unpackEgtpSrvOpenReq(egtpSrvOpenReq, pst, mBuf);
210 ret = unpackEgtpTnlMgmtReq(egtpTnlMgmtReq, pst, mBuf);
215 DU_LOG("\nERROR --> EGTP : Invalid event %d", pst->event);
216 ODU_PUT_MSG_BUF(mBuf);
228 DU_LOG("\nDEBUG --> EGTP : Starting Socket Polling");
230 ODU_PUT_MSG_BUF(mBuf);
235 DU_LOG("\nERROR --> EGTP : Invalid event %d", pst->event);
236 ODU_PUT_MSG_BUF(mBuf);
253 DU_LOG("\nERROR --> EGTP : Invalid event %d", pst->event);
261 DU_LOG("\nERROR --> EGTP : Invalid source entity %d", pst->srcEnt);
269 /**************************************************************************
270 * @brief EGTP server configuration
274 * Function : egtpCfgReq
277 * This function handles EGTP configuration request.
279 * @return ROK - success
282 * ***********************************************************************/
283 uint8_t egtpCfgReq(Pst *pst, EgtpConfig egtpCfg)
285 uint8_t ret; /* Return value */
286 Pst rspPst; /* Response Pst structure */
287 CmStatus cfgCfm; /* Configuration Confirm */
289 memcpy(&egtpCb.egtpCfg, &egtpCfg, sizeof(EgtpConfig));
291 egtpCb.localAddr.address = CM_INET_NTOH_UINT32(egtpCb.egtpCfg.localIp.ipV4Addr);
292 egtpCb.localAddr.port = egtpCb.egtpCfg.localPort;
294 egtpCb.dstCb.dstAddr.address = CM_INET_NTOH_UINT32(egtpCb.egtpCfg.destIp.ipV4Addr);
295 egtpCb.dstCb.dstAddr.port = egtpCb.egtpCfg.destPort;
296 egtpCb.dstCb.numTunn = 0;
298 ret = cmHashListInit(&(egtpCb.dstCb.teIdLst), 1024, sizeof(EgtpTeIdCb), FALSE, CM_HASH_KEYTYPE_UINT32_MOD, DU_APP_MEM_REGION, DU_POOL);
302 DU_LOG("\nERROR --> EGTP : TeId hash list initialization failed");
303 cfgCfm.status = LCM_PRIM_NOK;
304 cfgCfm.reason = LCM_REASON_HASHING_FAILED;
308 DU_LOG("\nDEBUG --> EGTP : EGTP configuration successful");
309 cfgCfm.status = LCM_PRIM_OK;
310 cfgCfm.reason = LCM_REASON_NOT_APPL;
313 /* Fill response Pst */
314 egtpFillRspPst(pst, &rspPst);
315 rspPst.event = EVTCFGCFM;
317 packEgtpCfgCfm(&rspPst, cfgCfm);
322 /**************************************************************************
323 * @brief Fills post structure to send response
327 * Function : egtpFillRspPst
330 * Fills post struture to send response
332 * @return ROK - success
336 * ***********************************************************************/
337 uint8_t egtpFillRspPst(Pst *pst, Pst *rspPst)
340 memset(rspPst, 0, sizeof(Pst));
341 rspPst->srcEnt = pst->dstEnt;
342 rspPst->srcInst = pst->dstInst;
343 rspPst->srcProcId = pst->dstProcId;
344 rspPst->dstEnt = pst->srcEnt;
345 rspPst->dstInst = pst->srcInst;
346 rspPst->dstProcId = pst->srcProcId;
347 rspPst->selector = ODU_SELECTOR_LC;
348 rspPst->pool= DU_POOL;
353 /**************************************************************************
354 * @brief EGTP server open request
358 * Function : egtpSrvOpenReq
361 * This function handles EGTP open server request.
362 * It opens udp socket to receive/send msgs.
364 * @param[in] Pst *pst, post structure
365 * @return ROK - success
368 ***************************************************************************/
370 uint8_t egtpSrvOpenReq(Pst *pst)
373 uint8_t ret; /* Return value */
374 Pst rspPst; /* Response Pst structure */
375 Pst egtpPst; /* Self post */
376 CmStatus cfm; /* Confirmation status */
377 uint8_t sockType; /* Socket type */
379 DU_LOG("\nDEBUG --> EGTP : Received EGTP open server request");
381 sockType = CM_INET_DGRAM;
382 ret = egtpSrvOpenPrc(sockType);
383 /* Opening and Binding receiver socket */
386 DU_LOG("\nERROR --> EGTP : Failed while opening receiver transport server");
390 DU_LOG("\nDEBUG --> EGTP : Socket [%d] is open", egtpCb.sockFd.fd);
392 /* Start Socket polling */
393 memset(&egtpPst, 0, sizeof(egtpPst));
394 egtpPst.srcEnt = (Ent)ENTEGTP;
395 egtpPst.srcInst = (Inst)EGTP_INST;
396 egtpPst.srcProcId = DU_PROC;
397 egtpPst.dstEnt = (Ent)ENTEGTP;
398 egtpPst.dstInst = (Inst)EGTP_INST;
399 egtpPst.dstProcId = DU_PROC;
400 egtpPst.event = EVTSTARTPOLL;
401 egtpPst.selector = ODU_SELECTOR_LC;
402 egtpPst.pool= DU_POOL;
403 packEgtpStartPollingReq(&egtpPst);
405 /* Filling and sending response */
406 cfm.status = LCM_PRIM_OK;
407 cfm.reason = LCM_REASON_NOT_APPL;
409 egtpFillRspPst(pst, &rspPst);
410 rspPst.event = EVTSRVOPENCFM;
411 packEgtpSrvOpenCfm(&rspPst, cfm);
416 /*******************************************************************
418 * @brief Processing Sever open request
422 * Function : egtpSrvOpenPrc
428 * @return ROK - success
431 * ****************************************************************/
433 uint8_t egtpSrvOpenPrc(uint8_t sockType)
436 ret = cmInetSocket(sockType, &(egtpCb.sockFd), protType);
439 DU_LOG("\nERROR --> EGTP : Failed to open UDP socket");
442 ret = cmInetBind(&(egtpCb.sockFd), &(egtpCb.localAddr));
445 DU_LOG("\nERROR --> EGTP : Failed to bind socket");
452 /**************************************************************************
453 * @brief EGTP tunnel management request
457 * Function : egtpTnlMgmtReq
460 * This function handles EGTP tunnel managament request
462 * @param[in] Tunnel Eveny structure
463 * @return ROK - success
467 * ***************************************************************************/
468 uint8_t egtpTnlMgmtReq(Pst *pst, EgtpTnlEvt tnlEvt)
472 #ifdef CALL_FLOW_DEBUG_LOG
473 DU_LOG("\nCall Flow: ENTDUAPP -> ENTEGTP : TNL_MGMT\n");
476 DU_LOG("\nDEBUG --> EGTP : Received tunnel management request");
477 switch(tnlEvt.action)
479 case EGTP_TNL_MGMT_ADD:
481 ret = egtpTnlAdd(tnlEvt);
484 case EGTP_TNL_MGMT_MOD:
486 ret = egtpTnlMod(tnlEvt);
489 case EGTP_TNL_MGMT_DEL:
491 ret = egtpTnlDel(tnlEvt);
496 DU_LOG("\nERROR --> EGTP : Invalid tunnel management action[%d]", tnlEvt.action);
497 ret = LCM_REASON_INVALID_ACTION;
503 tnlEvt.cfmStatus.status = LCM_PRIM_OK;
504 tnlEvt.cfmStatus.reason = LCM_REASON_NOT_APPL;
508 tnlEvt.cfmStatus.status = LCM_PRIM_NOK;
509 tnlEvt.cfmStatus.reason = ret;
512 DU_LOG("\nDEBUG --> EGTP : Sending Tunnel management confirmation");
513 duHdlEgtpTnlMgmtCfm(tnlEvt);
518 /**************************************************************************
519 * @brief EGTP tunnel addition
523 * Function : egtpTnlAdd
526 * This function handles EGTP tunnel addition
528 * @param[in] Tunnel Event structure
529 * @return ROK - success
532 * ***************************************************************************/
533 uint8_t egtpTnlAdd(EgtpTnlEvt tnlEvt)
536 EgtpTeIdCb *teidCb; /* Tunnel endpoint control block */
537 EgtpMsgHdr preDefHdr; /* pre-define header for this tunnel */
539 DU_LOG("\nINFO --> EGTP : Tunnel addition : LocalTeid[%d] Remote Teid[%d]", tnlEvt.lclTeid, tnlEvt.remTeid);
541 DU_ALLOC(teidCb, sizeof(EgtpTeIdCb));
544 DU_LOG("\nERROR --> EGTP : Memory allocation failed");
545 return LCM_REASON_MEM_NOAVAIL;
548 memset(teidCb, 0, sizeof(EgtpTeIdCb));
549 teidCb->teId = tnlEvt.lclTeid;
550 teidCb->remTeId = tnlEvt.remTeid;
552 ret = cmHashListInsert(&(egtpCb.dstCb.teIdLst), (PTR)teidCb, (uint8_t *)&(teidCb->teId), sizeof(uint32_t));
555 DU_LOG("\nERROR --> EGTP : Failed to insert in hash list");
556 DU_FREE(teidCb, sizeof(EgtpTeIdCb));
557 return LCM_REASON_HASHING_FAILED;
559 egtpCb.dstCb.numTunn++;
561 /* Encoding pre-defined header */
562 memset(&preDefHdr, 0, sizeof(EgtpMsgHdr));
563 preDefHdr.msgType = EGTPU_MSG_GPDU;
564 preDefHdr.teId = teidCb->remTeId;
565 preDefHdr.extHdr.pdcpNmb.pres = FALSE;
566 preDefHdr.extHdr.udpPort.pres = FALSE;
567 preDefHdr.nPdu.pres = FALSE;
569 egtpEncodeHdr((uint8_t *)teidCb->preEncodedHdr.hdr, &preDefHdr, &(teidCb->preEncodedHdr.cnt));
574 /**************************************************************************
575 * @brief EGTP tunnel modification
579 * Function : egtpTnlMod
582 * This function handles EGTP tunnel modification
584 * @param[in] Tunnel Event structure
585 * @return ROK - success
588 * ***************************************************************************/
589 uint8_t egtpTnlMod(EgtpTnlEvt tnlEvt)
591 EgtpTeIdCb *teidCb = NULLP;
593 DU_LOG("\nINFO --> EGTP : Tunnel modification : LocalTeid[%d] Remote Teid[%d]", tnlEvt.lclTeid, tnlEvt.remTeid);
595 cmHashListFind(&(egtpCb.dstCb.teIdLst), (uint8_t *)&(tnlEvt.lclTeid), sizeof(uint32_t), 0, (PTR *)&teidCb);
598 DU_LOG("\nERROR --> EGTP : Tunnel id not found");
601 teidCb->teId = tnlEvt.remTeid;
602 teidCb->remTeId = tnlEvt.remTeid;
606 /**************************************************************************
607 * @brief EGTP tunnel deletion
611 * Function : egtpTnlDel
614 * This function handles EGTP tunnel deletion
616 * @param[in] Tunnel Event structure
617 * @return ROK - success
620 * ***************************************************************************/
621 uint8_t egtpTnlDel(EgtpTnlEvt tnlEvt)
623 EgtpTeIdCb *teidCb = NULLP;
625 DU_LOG("\nINFO --> EGTP : Tunnel deletion : Local Teid[%d] Remote Teid[%d]", tnlEvt.lclTeid, tnlEvt.remTeid);
627 cmHashListFind(&(egtpCb.dstCb.teIdLst), (uint8_t *)&(tnlEvt.lclTeid), sizeof(uint32_t), 0, (PTR *)&teidCb);
630 DU_LOG("\nERROR --> EGTP : Tunnel id[%d] not configured", tnlEvt.lclTeid);
631 return LCM_REASON_INVALID_PAR_VAL;
634 cmHashListDelete(&(egtpCb.dstCb.teIdLst), (PTR)teidCb);
635 DU_FREE(teidCb, sizeof(EgtpTeIdCb));
636 egtpCb.dstCb.numTunn--;
640 /*******************************************************************
642 * @brief Handles data indication
646 * Function : EgtpHdlDatInd
649 * Handles incoming data from peer to be passed
653 * @return ROK - success
656 * ****************************************************************/
657 uint8_t egtpHdlDatInd(EgtpMsg egtpMsg)
659 EgtpTeIdCb *teidCb = NULLP;
665 #ifdef CALL_FLOW_DEBUG_LOG
666 DU_LOG("\nCall Flow: ENTDUAPP -> ENTEGTP : DATA_INDICATION\n");
669 DU_LOG("\nDEBUG --> EGTP : Received Data Indication");
671 cmHashListFind(&(egtpCb.dstCb.teIdLst), (uint8_t *)&(egtpMsg.msgHdr.teId), sizeof(uint32_t), 0, (PTR *)&teidCb);
674 DU_LOG("\nERROR --> EGTP : Tunnel id[%d] not configured", egtpMsg.msgHdr.teId);
675 return LCM_REASON_INVALID_PAR_VAL;
678 msgHdr = &(egtpMsg.msgHdr);
680 hdrLen = teidCb->preEncodedHdr.cnt;
682 if(msgHdr->extHdr.pdcpNmb.pres)
684 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] |= EGTP_MASK_BIT3;
685 teidCb->preEncodedHdr.hdr[hdrLen] = EGTP_EXT_HDR_PDCP_TYPE;
686 teidCb->preEncodedHdr.hdr[--hdrLen] = 1;
687 teidCb->preEncodedHdr.hdr[--hdrLen] = GetHiByte(msgHdr->extHdr.pdcpNmb.val);
688 teidCb->preEncodedHdr.hdr[--hdrLen] = GetLoByte(msgHdr->extHdr.pdcpNmb.val);
689 teidCb->preEncodedHdr.hdr[--hdrLen] = 0;
693 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] &= ~(EGTP_MASK_BIT3);
696 ODU_GET_MSG_LEN(egtpMsg.msg, (int16_t *)&tPduSize);
698 /*Adjust the header to fill the correct length*/
699 msgLen = tPduSize + (EGTP_MAX_HDR_LEN - hdrLen) - 0x08;
701 /***********************************************
702 * Fill the length field of the message header *
703 ***********************************************/
704 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 3] = (uint8_t)GetHiByte(msgLen);
705 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 4] = (uint8_t)GetLoByte(msgLen);
707 /*Update the sequence number*/
708 if(egtpMsg.msgHdr.seqNum.pres)
710 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] |= (EGTP_MASK_BIT2);
711 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 9] = (uint8_t)GetHiByte(egtpMsg.msgHdr.seqNum.val);
712 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 10] = (uint8_t)GetLoByte(egtpMsg.msgHdr.seqNum.val);
716 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] &= ~(EGTP_MASK_BIT2);
719 DU_LOG("\nDEBUG --> EGTP : UL Data buffer before encoding header");
720 ODU_PRINT_MSG(egtpMsg.msg, 0, 0);
722 ODU_ADD_PRE_MSG_MULT(&teidCb->preEncodedHdr.hdr[hdrLen], (EGTP_MAX_HDR_LEN - hdrLen), egtpMsg.msg);
725 DU_LOG("\nDEBUG --> EGTP : UL Data buffer after encoding header");
726 ODU_PRINT_MSG(egtpMsg.msg, 0, 0);
729 egtpSendMsg(egtpMsg.msg);
730 ODU_PUT_MSG_BUF(egtpMsg.msg);
735 /*******************************************************************
737 * @brief Encodes outgoing message
741 * Function : egtpEncodeMsg
744 * Encodes EGTP message to be sent
746 * @params[in] EGTP message
748 * @return ROK - success
751 * ****************************************************************/
752 uint8_t egtpEncodeHdr(uint8_t *preEncodedHdr, EgtpMsgHdr *preDefHdr, uint8_t *hdrIdx)
754 uint8_t tmpByte = 0; /* Stores one byte of data for enc */
755 uint8_t cnt = EGTP_MAX_HDR_LEN; /* Stores the position */
756 bool extPres = FALSE; /* Flag for indication of S, E or P presense flag */
759 /* Encoding header */
760 tmpByte |= EGTP_MASK_BIT6; /* Setting 6th LSB of 1st byte as version */
761 tmpByte |= EGTP_MASK_BIT5; /* Setting 5th LSB of 1st byte as protocol type */
763 if(preDefHdr->extHdr.udpPort.pres || preDefHdr->extHdr.pdcpNmb.pres)
765 tmpByte |= EGTP_MASK_BIT3; /* Setting 3rd LSB of 1st byte if Extension heaeder is present */
768 if(preDefHdr->seqNum.pres)
770 tmpByte |= EGTP_MASK_BIT2;
773 if(preDefHdr->nPdu.pres)
775 tmpByte |= EGTP_MASK_BIT1;
778 if((tmpByte & EGTP_MASK_BIT1) || (tmpByte & EGTP_MASK_BIT2)||(tmpByte & EGTP_MASK_BIT3))
783 preEncodedHdr[--cnt] = tmpByte;
784 preEncodedHdr[--cnt] = preDefHdr->msgType;
786 /* Encode Tunnel endpoint */
787 preEncodedHdr[--cnt] = 0;
788 preEncodedHdr[--cnt] = 0;
789 nwWord = (uint16_t)(GetHiWord(preDefHdr->teId));
790 preEncodedHdr[--cnt] = (uint8_t)(GetHiByte(nwWord));
791 preEncodedHdr[--cnt] = (uint8_t)(GetLoByte(nwWord));
792 nwWord = (uint16_t)(GetLoWord(preDefHdr->teId));
793 preEncodedHdr[--cnt] = (uint8_t)(GetHiByte(nwWord));
794 preEncodedHdr[--cnt] = (uint8_t)(GetLoByte(nwWord));
796 /* Encode sequence number */
797 if(preDefHdr->seqNum.pres)
799 preEncodedHdr[--cnt] = GetHiByte(preDefHdr->seqNum.val);
800 preEncodedHdr[--cnt] = GetLoByte(preDefHdr->seqNum.val);
804 preEncodedHdr[--cnt] = 0;
805 preEncodedHdr[--cnt] = 0;
808 /* Encode nPdu number */
809 if(preDefHdr->nPdu.pres)
811 preEncodedHdr[--cnt] = preDefHdr->nPdu.val;
815 preEncodedHdr[--cnt] = 0;
818 if(preDefHdr->extHdr.udpPort.pres)
820 preEncodedHdr[--cnt] = EGTP_EXT_HDR_UDP_TYPE;
821 preEncodedHdr[--cnt] = 1;
822 preEncodedHdr[--cnt] = GetHiByte(preDefHdr->extHdr.udpPort.val);
823 preEncodedHdr[--cnt] = GetLoByte(preDefHdr->extHdr.udpPort.val);
826 if(preDefHdr->extHdr.pdcpNmb.pres)
828 preEncodedHdr[--cnt] = EGTP_EXT_HDR_PDCP_TYPE;
829 preEncodedHdr[--cnt] = 1;
830 preEncodedHdr[--cnt] = GetHiByte(preDefHdr->extHdr.pdcpNmb.val);
831 preEncodedHdr[--cnt] = GetLoByte(preDefHdr->extHdr.pdcpNmb.val);
834 if(tmpByte & EGTP_MASK_BIT3)
836 preEncodedHdr[--cnt] = 0;
840 preEncodedHdr[--cnt] = 0;
845 } /* egtpEncodeHdr */
847 /*******************************************************************
849 * @brief Sends message over UDP
853 * Function : egtpSendMsg
856 * Sends message over UDP
858 * @params[in] Message Buffer
859 * @return ROK - success
862 * ****************************************************************/
863 uint8_t egtpSendMsg(Buffer *mBuf)
868 static uint64_t numDataSent = 0;
870 info.region = DU_APP_MEM_REGION;
873 ret = cmInetSendMsg(&egtpCb.sockFd, &egtpCb.dstCb.dstAddr, &info, mBuf, (int16_t *)&txLen, CM_INET_NO_FLAG);
874 if(ret != ROK && ret != RWOULDBLOCK)
876 DU_LOG("\nERROR --> EGTP : Failed sending the message");
881 DU_LOG("\nDEBUG --> EGTP : Sent UL Message [%ld]", numDataSent+1);
888 /*******************************************************************
890 * @brief Receives EGTP message from UDP socket
894 * Function : egtpRecvMsg
897 * Receive incoming messages from UDP socket
900 * @return ROK - success
903 * ****************************************************************/
905 uint8_t egtpRecvMsg()
907 uint8_t ret; /* Return value */
908 uint16_t bufLen; /* Length of received buffer */
909 Buffer *recvBuf; /* Received buffer */
910 CmInetMemInfo memInfo; /* Buffer allocation info */
912 memInfo.region = DU_APP_MEM_REGION;
913 memInfo.pool = DU_POOL;
918 ret = cmInetRecvMsg(&egtpCb.sockFd, &egtpCb.dstCb.dstAddr, &memInfo, &recvBuf, (int16_t *)&bufLen, CM_INET_NO_FLAG);
919 if(ret == ROK && recvBuf != NULLP)
921 DU_LOG("\nDEBUG --> EGTP : Received DL Message[%ld]\n", gDlDataRcvdCnt + 1);
922 //ODU_PRINT_MSG(recvBuf, 0 ,0);
923 egtpHdlRecvData(recvBuf);
932 /*******************************************************************
934 * @brief Handles DL User data received from CU
938 * Function : egtpHdlRecvData
940 * Functionality: Handles DL User data received from CU
942 * @params[in] DL Usre data buffer
943 * @return ROK - success
946 * ****************************************************************/
947 uint8_t egtpHdlRecvData(Buffer *mBuf)
951 /* Decode EGTP header */
952 egtpDecodeHdr(mBuf, &egtpMsg);
954 /* TODO : Send received message to RLC */
955 duHdlEgtpDlData(&egtpMsg);
960 /*******************************************************************
962 * @brief Decodes EGTP header from DL User data
966 * Function : egtpDecodeHdr
968 * Functionality: Decodes EGTP header from DL User data
971 * @return ROK - success
974 * ****************************************************************/
975 uint8_t egtpDecodeHdr(Buffer *mBuf, EgtpMsg *egtpMsg)
977 uint8_t tmpByte[5]; /* Holds 5 byte of data after Decoding */
978 uint8_t version = 0; /* Holds the version type, decoded */
979 uint16_t msgLen = 0; /* Holds the msgLen from the Hdr */
980 uint16_t bufLen = 0; /* Holds the total buffer length */
981 uint8_t extHdrType = 0; /* Holds the Extension hdr type */
982 uint8_t extHdrLen = 0; /* Extension hdr length */
983 bool extPres = FALSE; /* Flag for indication of S, E or P presense flag */
985 ODU_GET_MSG_LEN(mBuf, (int16_t *)&bufLen);
987 /* Decode first byte and storing in temporary variable */
988 ODU_REM_PRE_MSG(&tmpByte[0], mBuf);
990 /* Extracting version fro 1st byte */
991 version = tmpByte[0] >> 5;
993 //DU_LOG("\nDEBUG --> EGTP : Version %d", version);
995 /* Decode message type */
996 ODU_REM_PRE_MSG((Data*)&(egtpMsg->msgHdr.msgType), mBuf);
997 //DU_LOG("\nDEBUG --> EGTP : msgType %d", egtpMsg->msgHdr.msgType);
999 /****************************************************************************
1000 * Message length param is 2 bytes. So decode next 2 bytes from msg hdr and
1001 * performing OR operation on these two bytes to calculate message length
1002 ***************************************************************************/
1003 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
1004 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
1005 msgLen = (tmpByte[1] << 8) | tmpByte[2];
1008 //DU_LOG("\nDEBUG --> EGTP : msgLen %d", msgLen);
1011 /****************************************************************************
1012 * Tunnel id param is 4 bytes. So decode next 4 bytes from msg hdr and
1013 * perform OR operation on these 4 bytes to calculate tunnel id
1014 ***************************************************************************/
1015 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
1016 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
1017 ODU_REM_PRE_MSG(&tmpByte[3], mBuf);
1018 ODU_REM_PRE_MSG(&tmpByte[4], mBuf);
1019 egtpMsg->msgHdr.teId = (tmpByte[1] << 24) | (tmpByte[2] << 16) | (tmpByte[3] << 8) | tmpByte[4];
1020 //DU_LOG("\nDEBUG --> EGTP : teId %d",egtpMsg->msgHdr.teId);
1023 /* If any one of S, E or PN flag is set, set extension present as true. */
1024 if((tmpByte[0] & EGTP_MASK_BIT1) || (tmpByte[0] & EGTP_MASK_BIT2)||(tmpByte[0] & EGTP_MASK_BIT3))
1029 /* Decode sequence number, if S flag is set in first byte */
1030 if (tmpByte[0] & EGTP_MASK_BIT2)
1032 /************************************************************************
1033 * Sequence num is 2 bytes. So decode next 2 bytes from msg hdr and
1034 * perform OR operation on them
1035 ************************************************************************/
1036 egtpMsg->msgHdr.seqNum.pres = TRUE;
1037 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
1038 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
1039 egtpMsg->msgHdr.seqNum.val = (tmpByte[1] << 8) | tmpByte[2];
1041 /****************************************************************************
1042 * If extPres is true, but S bit is not set, implies, either of PN or E bit
1043 * was set during Encode so accordingly extract Byte fields for seqNum anyway
1044 ***************************************************************************/
1047 /*************************************************************************
1048 * Sequence num is 2 bytes. So decode next 2 bytes from msg hdr and
1049 * perform OR operation on them
1050 ************************************************************************/
1051 egtpMsg->msgHdr.seqNum.pres = 0;
1052 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
1053 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
1054 egtpMsg->msgHdr.seqNum.val = (tmpByte[1] << 8) | tmpByte[2];
1057 /* Decode N-PDU number if present flag is set */
1058 if (tmpByte[0] & EGTP_MASK_BIT1)
1060 egtpMsg->msgHdr.nPdu.pres = TRUE;
1061 ODU_REM_PRE_MSG(&(egtpMsg->msgHdr.nPdu.val), mBuf);
1063 /****************************************************************************
1064 * If extPres is true, but PN bit is not set, implies, either of S or E bit
1065 * was set during Encode. Aaccordingly extract Byte fields of N-PDU num anyway
1066 ***************************************************************************/
1069 egtpMsg->msgHdr.nPdu.pres = TRUE;
1070 ODU_REM_PRE_MSG(&(egtpMsg->msgHdr.nPdu.val), mBuf);
1073 /* If E flag is set in first byte, decode extension header */
1074 if(tmpByte[0] & EGTP_MASK_BIT3)
1076 ODU_REM_PRE_MSG(&extHdrType, mBuf);
1077 while( 0 != extHdrType)
1081 case EGTP_EXT_HDR_UDP_TYPE:
1083 ODU_REM_PRE_MSG(&extHdrLen, mBuf);
1084 if(extHdrLen == 0x01)
1086 /************************************************************
1087 * UDP Port is 2 bytes. So decode next 2 bytes from msg hdr
1088 * and perform OR operation on them
1089 *************************************************************/
1090 egtpMsg->msgHdr.extHdr.udpPort.pres = TRUE;
1091 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
1092 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
1093 egtpMsg->msgHdr.extHdr.udpPort.val = (tmpByte[1] << 8) | tmpByte[2];
1098 case EGTP_EXT_HDR_PDCP_TYPE:
1100 ODU_REM_PRE_MSG(&extHdrLen, mBuf);
1101 if(extHdrLen == 0x01)
1103 /*************************************************************
1104 * PDCP num is 2 bytes. So decode next 2 bytes from msg hdr
1105 * and perform OR operation on them
1106 ************************************************************/
1107 egtpMsg->msgHdr.extHdr.pdcpNmb.pres = TRUE;
1108 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
1109 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
1110 egtpMsg->msgHdr.extHdr.pdcpNmb.val = (tmpByte[1] << 8) | tmpByte[2];
1114 } /* End of switch */
1116 ODU_REM_PRE_MSG(&extHdrType, mBuf);
1118 } /* End of while */
1120 /****************************************************************************
1121 * If extPres is true, but E bit is not set, implies, either of PN or S bit
1122 * was set during Encode so accordingly extract Byte fields for extension
1124 ***************************************************************************/
1127 ODU_REM_PRE_MSG(&extHdrType, mBuf);
1130 egtpMsg->msg = mBuf;
1132 //DU_LOG("\nDEBUG --> EGTP : DL Data Buffer after decoding header ");
1133 //ODU_PRINT_MSG(mBuf, 0, 0);
1135 /* Forward the data to duApp/RLC */
1140 /**********************************************************************
1142 **********************************************************************/