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"
28 #include "du_e2ap_mgr.h"
31 #include "du_app_rlc_inf.h"
36 /**************************************************************************
37 * @brief Task Initiation callback function.
41 * Function : egtpActvInit
44 * This function is supplied as one of parameters during EGTP's
45 * task registration. SSI will invoke this function once, after
46 * it creates and attaches this TAPA Task to a system task.
48 * @param[in] Ent entity, the entity ID of this task.
49 * @param[in] Inst inst, the instance ID of this task.
50 * @param[in] Region region, the region ID registered for memory
52 * @param[in] Reason reason.
53 * @return ROK - success
55 ***************************************************************************/
56 uint8_t egtpActvInit(Ent entity, Inst inst, Region region, Reason reason)
58 DU_LOG("\n\nDEBUG --> EGTP : Initializing");
60 memset (&egtpCb, 0, sizeof(EgtpGlobalCb));
61 protType = CM_INET_PROTO_UDP;
67 #ifdef CALL_FLOW_DEBUG_LOG
68 /**************************************************************************
69 * @brief Function prints the src dest and msg reached to egtp.
73 * Function : callFlowEgtpActvTsk
76 * Function prints the src dest and msg reached to egtp.
78 * @param[in] Pst *pst, Post structure of the primitive.
82 ***************************************************************************/
84 void callFlowEgtpActvTsk(Pst *pst)
88 char destTask[50]="ENTEGTP";
95 strcpy(sourceTask,"ENTDUAPP");
100 strcpy(message,"EVTCFGREQ");
105 strcpy(message,"EVTSRVOPENREQ");
110 strcpy(message,"EVTTNLMGMTREQ");
115 strcpy(message,"Invalid Event");
123 strcpy(sourceTask,"ENTEGTP");
128 strcpy(message,"EVTSTARTPOLL");
133 strcpy(message,"Invalid Event");
141 strcpy(sourceTask,"ENTRLC");
146 strcpy(message,"EVTDATIND");
151 strcpy(message,"Invalid Event");
159 strcpy(sourceTask,"Invalid Source Entity Id");
162 DU_LOG("\nCall Flow: %s -> %s : %s\n", sourceTask, destTask, message);
166 /**************************************************************************
167 * @brief Task Activation callback function.
171 * Function : egtpActvTsk
174 * This function handles all EGTP messages received
175 * This API is registered with SSI during the
176 * Task Registration of DU APP.
178 * @param[in] Pst *pst, Post structure of the primitive.
179 * @param[in] Buffer *mBuf, Packed primitive parameters in the
181 * @return ROK - success
184 ***************************************************************************/
185 uint8_t egtpActvTsk(Pst *pst, Buffer *mBuf)
189 #ifdef CALL_FLOW_DEBUG_LOG
190 callFlowEgtpActvTsk(pst);
201 ret = unpackEgtpCfgReq(egtpCfgReq, pst, mBuf);
206 ret = unpackEgtpSrvOpenReq(egtpSrvOpenReq, pst, mBuf);
211 ret = unpackEgtpTnlMgmtReq(egtpTnlMgmtReq, pst, mBuf);
216 DU_LOG("\nERROR --> EGTP : Invalid event %d", pst->event);
217 ODU_PUT_MSG_BUF(mBuf);
229 DU_LOG("\nDEBUG --> EGTP : Starting Socket Polling");
231 ODU_PUT_MSG_BUF(mBuf);
236 DU_LOG("\nERROR --> EGTP : Invalid event %d", pst->event);
237 ODU_PUT_MSG_BUF(mBuf);
254 DU_LOG("\nERROR --> EGTP : Invalid event %d", pst->event);
262 DU_LOG("\nERROR --> EGTP : Invalid source entity %d", pst->srcEnt);
270 /**************************************************************************
271 * @brief EGTP server configuration
275 * Function : egtpCfgReq
278 * This function handles EGTP configuration request.
280 * @return ROK - success
283 * ***********************************************************************/
284 uint8_t egtpCfgReq(Pst *pst, EgtpConfig egtpCfg)
286 uint8_t ret; /* Return value */
287 Pst rspPst; /* Response Pst structure */
288 CmStatus cfgCfm; /* Configuration Confirm */
290 memcpy(&egtpCb.egtpCfg, &egtpCfg, sizeof(EgtpConfig));
292 egtpCb.localAddr.address = CM_INET_NTOH_UINT32(egtpCb.egtpCfg.localIp.ipV4Addr);
293 egtpCb.localAddr.port = egtpCb.egtpCfg.localPort;
295 egtpCb.dstCb.dstAddr.address = CM_INET_NTOH_UINT32(egtpCb.egtpCfg.destIp.ipV4Addr);
296 egtpCb.dstCb.dstAddr.port = egtpCb.egtpCfg.destPort;
297 egtpCb.dstCb.numTunn = 0;
299 ret = cmHashListInit(&(egtpCb.dstCb.teIdLst), 1024, sizeof(EgtpTeIdCb), FALSE, CM_HASH_KEYTYPE_UINT32_MOD, DU_APP_MEM_REGION, DU_POOL);
303 DU_LOG("\nERROR --> EGTP : TeId hash list initialization failed");
304 cfgCfm.status = LCM_PRIM_NOK;
305 cfgCfm.reason = LCM_REASON_HASHING_FAILED;
309 DU_LOG("\nDEBUG --> EGTP : EGTP configuration successful");
310 cfgCfm.status = LCM_PRIM_OK;
311 cfgCfm.reason = LCM_REASON_NOT_APPL;
314 /* Fill response Pst */
315 egtpFillRspPst(pst, &rspPst);
316 rspPst.event = EVTCFGCFM;
318 packEgtpCfgCfm(&rspPst, cfgCfm);
323 /**************************************************************************
324 * @brief Fills post structure to send response
328 * Function : egtpFillRspPst
331 * Fills post struture to send response
333 * @return ROK - success
337 * ***********************************************************************/
338 uint8_t egtpFillRspPst(Pst *pst, Pst *rspPst)
341 memset(rspPst, 0, sizeof(Pst));
342 rspPst->srcEnt = pst->dstEnt;
343 rspPst->srcInst = pst->dstInst;
344 rspPst->srcProcId = pst->dstProcId;
345 rspPst->dstEnt = pst->srcEnt;
346 rspPst->dstInst = pst->srcInst;
347 rspPst->dstProcId = pst->srcProcId;
348 rspPst->selector = ODU_SELECTOR_LC;
349 rspPst->pool= DU_POOL;
354 /**************************************************************************
355 * @brief EGTP server open request
359 * Function : egtpSrvOpenReq
362 * This function handles EGTP open server request.
363 * It opens udp socket to receive/send msgs.
365 * @param[in] Pst *pst, post structure
366 * @return ROK - success
369 ***************************************************************************/
371 uint8_t egtpSrvOpenReq(Pst *pst)
374 uint8_t ret; /* Return value */
375 Pst rspPst; /* Response Pst structure */
376 Pst egtpPst; /* Self post */
377 CmStatus cfm; /* Confirmation status */
378 uint8_t sockType; /* Socket type */
380 DU_LOG("\nDEBUG --> EGTP : Received EGTP open server request");
382 sockType = CM_INET_DGRAM;
383 ret = egtpSrvOpenPrc(sockType);
384 /* Opening and Binding receiver socket */
387 DU_LOG("\nERROR --> EGTP : Failed while opening receiver transport server");
391 DU_LOG("\nDEBUG --> EGTP : Socket [%d] is open", egtpCb.sockFd.fd);
393 /* Start Socket polling */
394 memset(&egtpPst, 0, sizeof(egtpPst));
395 egtpPst.srcEnt = (Ent)ENTEGTP;
396 egtpPst.srcInst = (Inst)EGTP_INST;
397 egtpPst.srcProcId = DU_PROC;
398 egtpPst.dstEnt = (Ent)ENTEGTP;
399 egtpPst.dstInst = (Inst)EGTP_INST;
400 egtpPst.dstProcId = DU_PROC;
401 egtpPst.event = EVTSTARTPOLL;
402 egtpPst.selector = ODU_SELECTOR_LC;
403 egtpPst.pool= DU_POOL;
404 packEgtpStartPollingReq(&egtpPst);
406 /* Filling and sending response */
407 cfm.status = LCM_PRIM_OK;
408 cfm.reason = LCM_REASON_NOT_APPL;
410 egtpFillRspPst(pst, &rspPst);
411 rspPst.event = EVTSRVOPENCFM;
412 packEgtpSrvOpenCfm(&rspPst, cfm);
417 /*******************************************************************
419 * @brief Processing Sever open request
423 * Function : egtpSrvOpenPrc
429 * @return ROK - success
432 * ****************************************************************/
434 uint8_t egtpSrvOpenPrc(uint8_t sockType)
437 ret = cmInetSocket(sockType, &(egtpCb.sockFd), protType);
440 DU_LOG("\nERROR --> EGTP : Failed to open UDP socket");
443 ret = cmInetBind(&(egtpCb.sockFd), &(egtpCb.localAddr));
446 DU_LOG("\nERROR --> EGTP : Failed to bind socket");
453 /**************************************************************************
454 * @brief EGTP tunnel management request
458 * Function : egtpTnlMgmtReq
461 * This function handles EGTP tunnel managament request
463 * @param[in] Tunnel Eveny structure
464 * @return ROK - success
468 * ***************************************************************************/
469 uint8_t egtpTnlMgmtReq(Pst *pst, EgtpTnlEvt tnlEvt)
473 #ifdef CALL_FLOW_DEBUG_LOG
474 DU_LOG("\nCall Flow: ENTDUAPP -> ENTEGTP : TNL_MGMT\n");
477 DU_LOG("\nDEBUG --> EGTP : Received tunnel management request");
478 switch(tnlEvt.action)
480 case EGTP_TNL_MGMT_ADD:
482 ret = egtpTnlAdd(tnlEvt);
485 case EGTP_TNL_MGMT_MOD:
487 ret = egtpTnlMod(tnlEvt);
490 case EGTP_TNL_MGMT_DEL:
492 ret = egtpTnlDel(tnlEvt);
497 DU_LOG("\nERROR --> EGTP : Invalid tunnel management action[%d]", tnlEvt.action);
498 ret = LCM_REASON_INVALID_ACTION;
504 tnlEvt.cfmStatus.status = LCM_PRIM_OK;
505 tnlEvt.cfmStatus.reason = LCM_REASON_NOT_APPL;
509 tnlEvt.cfmStatus.status = LCM_PRIM_NOK;
510 tnlEvt.cfmStatus.reason = ret;
513 DU_LOG("\nDEBUG --> EGTP : Sending Tunnel management confirmation");
514 duHdlEgtpTnlMgmtCfm(tnlEvt);
519 /**************************************************************************
520 * @brief EGTP tunnel addition
524 * Function : egtpTnlAdd
527 * This function handles EGTP tunnel addition
529 * @param[in] Tunnel Event structure
530 * @return ROK - success
533 * ***************************************************************************/
534 uint8_t egtpTnlAdd(EgtpTnlEvt tnlEvt)
537 EgtpTeIdCb *teidCb; /* Tunnel endpoint control block */
538 EgtpMsgHdr preDefHdr; /* pre-define header for this tunnel */
540 DU_LOG("\nINFO --> EGTP : Tunnel addition : LocalTeid[%d] Remote Teid[%d]", tnlEvt.lclTeid, tnlEvt.remTeid);
542 DU_ALLOC(teidCb, sizeof(EgtpTeIdCb));
545 DU_LOG("\nERROR --> EGTP : Memory allocation failed");
546 return LCM_REASON_MEM_NOAVAIL;
549 memset(teidCb, 0, sizeof(EgtpTeIdCb));
550 teidCb->teId = tnlEvt.lclTeid;
551 teidCb->remTeId = tnlEvt.remTeid;
553 ret = cmHashListInsert(&(egtpCb.dstCb.teIdLst), (PTR)teidCb, (uint8_t *)&(teidCb->teId), sizeof(uint32_t));
556 DU_LOG("\nERROR --> EGTP : Failed to insert in hash list");
557 DU_FREE(teidCb, sizeof(EgtpTeIdCb));
558 return LCM_REASON_HASHING_FAILED;
560 egtpCb.dstCb.numTunn++;
562 /* Encoding pre-defined header */
563 memset(&preDefHdr, 0, sizeof(EgtpMsgHdr));
564 preDefHdr.msgType = EGTPU_MSG_GPDU;
565 preDefHdr.teId = teidCb->remTeId;
566 preDefHdr.extHdr.pdcpNmb.pres = FALSE;
567 preDefHdr.extHdr.udpPort.pres = FALSE;
568 preDefHdr.nPdu.pres = FALSE;
570 egtpEncodeHdr((uint8_t *)teidCb->preEncodedHdr.hdr, &preDefHdr, &(teidCb->preEncodedHdr.cnt));
575 /**************************************************************************
576 * @brief EGTP tunnel modification
580 * Function : egtpTnlMod
583 * This function handles EGTP tunnel modification
585 * @param[in] Tunnel Event structure
586 * @return ROK - success
589 * ***************************************************************************/
590 uint8_t egtpTnlMod(EgtpTnlEvt tnlEvt)
592 EgtpTeIdCb *teidCb = NULLP;
594 DU_LOG("\nINFO --> EGTP : Tunnel modification : LocalTeid[%d] Remote Teid[%d]", tnlEvt.lclTeid, tnlEvt.remTeid);
596 cmHashListFind(&(egtpCb.dstCb.teIdLst), (uint8_t *)&(tnlEvt.lclTeid), sizeof(uint32_t), 0, (PTR *)&teidCb);
599 DU_LOG("\nERROR --> EGTP : Tunnel id not found");
602 teidCb->teId = tnlEvt.remTeid;
603 teidCb->remTeId = tnlEvt.remTeid;
607 /**************************************************************************
608 * @brief EGTP tunnel deletion
612 * Function : egtpTnlDel
615 * This function handles EGTP tunnel deletion
617 * @param[in] Tunnel Event structure
618 * @return ROK - success
621 * ***************************************************************************/
622 uint8_t egtpTnlDel(EgtpTnlEvt tnlEvt)
624 EgtpTeIdCb *teidCb = NULLP;
626 DU_LOG("\nINFO --> EGTP : Tunnel deletion : Local Teid[%d] Remote Teid[%d]", tnlEvt.lclTeid, tnlEvt.remTeid);
628 cmHashListFind(&(egtpCb.dstCb.teIdLst), (uint8_t *)&(tnlEvt.lclTeid), sizeof(uint32_t), 0, (PTR *)&teidCb);
631 DU_LOG("\nERROR --> EGTP : Tunnel id[%d] not configured", tnlEvt.lclTeid);
632 return LCM_REASON_INVALID_PAR_VAL;
635 cmHashListDelete(&(egtpCb.dstCb.teIdLst), (PTR)teidCb);
636 DU_FREE(teidCb, sizeof(EgtpTeIdCb));
637 egtpCb.dstCb.numTunn--;
641 /*******************************************************************
643 * @brief Handles data indication
647 * Function : EgtpHdlDatInd
650 * Handles incoming data from peer to be passed
654 * @return ROK - success
657 * ****************************************************************/
658 uint8_t egtpHdlDatInd(EgtpMsg egtpMsg)
660 EgtpTeIdCb *teidCb = NULLP;
666 #ifdef CALL_FLOW_DEBUG_LOG
667 DU_LOG("\nCall Flow: ENTDUAPP -> ENTEGTP : DATA_INDICATION\n");
670 DU_LOG("\nDEBUG --> EGTP : Received Data Indication");
672 cmHashListFind(&(egtpCb.dstCb.teIdLst), (uint8_t *)&(egtpMsg.msgHdr.teId), sizeof(uint32_t), 0, (PTR *)&teidCb);
675 DU_LOG("\nERROR --> EGTP : Tunnel id[%d] not configured", egtpMsg.msgHdr.teId);
676 return LCM_REASON_INVALID_PAR_VAL;
679 msgHdr = &(egtpMsg.msgHdr);
681 hdrLen = teidCb->preEncodedHdr.cnt;
683 if(msgHdr->extHdr.pdcpNmb.pres)
685 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] |= EGTP_MASK_BIT3;
686 teidCb->preEncodedHdr.hdr[hdrLen] = EGTP_EXT_HDR_PDCP_TYPE;
687 teidCb->preEncodedHdr.hdr[--hdrLen] = 1;
688 teidCb->preEncodedHdr.hdr[--hdrLen] = GetHiByte(msgHdr->extHdr.pdcpNmb.val);
689 teidCb->preEncodedHdr.hdr[--hdrLen] = GetLoByte(msgHdr->extHdr.pdcpNmb.val);
690 teidCb->preEncodedHdr.hdr[--hdrLen] = 0;
694 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] &= ~(EGTP_MASK_BIT3);
697 ODU_GET_MSG_LEN(egtpMsg.msg, (int16_t *)&tPduSize);
699 /*Adjust the header to fill the correct length*/
700 msgLen = tPduSize + (EGTP_MAX_HDR_LEN - hdrLen) - 0x08;
702 /***********************************************
703 * Fill the length field of the message header *
704 ***********************************************/
705 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 3] = (uint8_t)GetHiByte(msgLen);
706 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 4] = (uint8_t)GetLoByte(msgLen);
708 /*Update the sequence number*/
709 if(egtpMsg.msgHdr.seqNum.pres)
711 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] |= (EGTP_MASK_BIT2);
712 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 9] = (uint8_t)GetHiByte(egtpMsg.msgHdr.seqNum.val);
713 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 10] = (uint8_t)GetLoByte(egtpMsg.msgHdr.seqNum.val);
717 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] &= ~(EGTP_MASK_BIT2);
720 DU_LOG("\nDEBUG --> EGTP : UL Data buffer before encoding header");
721 ODU_PRINT_MSG(egtpMsg.msg, 0, 0);
723 ODU_ADD_PRE_MSG_MULT(&teidCb->preEncodedHdr.hdr[hdrLen], (EGTP_MAX_HDR_LEN - hdrLen), egtpMsg.msg);
726 DU_LOG("\nDEBUG --> EGTP : UL Data buffer after encoding header");
727 ODU_PRINT_MSG(egtpMsg.msg, 0, 0);
730 egtpSendMsg(egtpMsg.msg);
731 ODU_PUT_MSG_BUF(egtpMsg.msg);
736 /*******************************************************************
738 * @brief Encodes outgoing message
742 * Function : egtpEncodeMsg
745 * Encodes EGTP message to be sent
747 * @params[in] EGTP message
749 * @return ROK - success
752 * ****************************************************************/
753 uint8_t egtpEncodeHdr(uint8_t *preEncodedHdr, EgtpMsgHdr *preDefHdr, uint8_t *hdrIdx)
755 uint8_t tmpByte = 0; /* Stores one byte of data for enc */
756 uint8_t cnt = EGTP_MAX_HDR_LEN; /* Stores the position */
757 bool extPres = FALSE; /* Flag for indication of S, E or P presense flag */
760 /* Encoding header */
761 tmpByte |= EGTP_MASK_BIT6; /* Setting 6th LSB of 1st byte as version */
762 tmpByte |= EGTP_MASK_BIT5; /* Setting 5th LSB of 1st byte as protocol type */
764 if(preDefHdr->extHdr.udpPort.pres || preDefHdr->extHdr.pdcpNmb.pres)
766 tmpByte |= EGTP_MASK_BIT3; /* Setting 3rd LSB of 1st byte if Extension heaeder is present */
769 if(preDefHdr->seqNum.pres)
771 tmpByte |= EGTP_MASK_BIT2;
774 if(preDefHdr->nPdu.pres)
776 tmpByte |= EGTP_MASK_BIT1;
779 if((tmpByte & EGTP_MASK_BIT1) || (tmpByte & EGTP_MASK_BIT2)||(tmpByte & EGTP_MASK_BIT3))
784 preEncodedHdr[--cnt] = tmpByte;
785 preEncodedHdr[--cnt] = preDefHdr->msgType;
787 /* Encode Tunnel endpoint */
788 preEncodedHdr[--cnt] = 0;
789 preEncodedHdr[--cnt] = 0;
790 nwWord = (uint16_t)(GetHiWord(preDefHdr->teId));
791 preEncodedHdr[--cnt] = (uint8_t)(GetHiByte(nwWord));
792 preEncodedHdr[--cnt] = (uint8_t)(GetLoByte(nwWord));
793 nwWord = (uint16_t)(GetLoWord(preDefHdr->teId));
794 preEncodedHdr[--cnt] = (uint8_t)(GetHiByte(nwWord));
795 preEncodedHdr[--cnt] = (uint8_t)(GetLoByte(nwWord));
797 /* Encode sequence number */
798 if(preDefHdr->seqNum.pres)
800 preEncodedHdr[--cnt] = GetHiByte(preDefHdr->seqNum.val);
801 preEncodedHdr[--cnt] = GetLoByte(preDefHdr->seqNum.val);
805 preEncodedHdr[--cnt] = 0;
806 preEncodedHdr[--cnt] = 0;
809 /* Encode nPdu number */
810 if(preDefHdr->nPdu.pres)
812 preEncodedHdr[--cnt] = preDefHdr->nPdu.val;
816 preEncodedHdr[--cnt] = 0;
819 if(preDefHdr->extHdr.udpPort.pres)
821 preEncodedHdr[--cnt] = EGTP_EXT_HDR_UDP_TYPE;
822 preEncodedHdr[--cnt] = 1;
823 preEncodedHdr[--cnt] = GetHiByte(preDefHdr->extHdr.udpPort.val);
824 preEncodedHdr[--cnt] = GetLoByte(preDefHdr->extHdr.udpPort.val);
827 if(preDefHdr->extHdr.pdcpNmb.pres)
829 preEncodedHdr[--cnt] = EGTP_EXT_HDR_PDCP_TYPE;
830 preEncodedHdr[--cnt] = 1;
831 preEncodedHdr[--cnt] = GetHiByte(preDefHdr->extHdr.pdcpNmb.val);
832 preEncodedHdr[--cnt] = GetLoByte(preDefHdr->extHdr.pdcpNmb.val);
835 if(tmpByte & EGTP_MASK_BIT3)
837 preEncodedHdr[--cnt] = 0;
841 preEncodedHdr[--cnt] = 0;
846 } /* egtpEncodeHdr */
848 /*******************************************************************
850 * @brief Sends message over UDP
854 * Function : egtpSendMsg
857 * Sends message over UDP
859 * @params[in] Message Buffer
860 * @return ROK - success
863 * ****************************************************************/
864 uint8_t egtpSendMsg(Buffer *mBuf)
869 static uint64_t numDataSent = 0;
871 info.region = DU_APP_MEM_REGION;
874 ret = cmInetSendMsg(&egtpCb.sockFd, &egtpCb.dstCb.dstAddr, &info, mBuf, (int16_t *)&txLen, CM_INET_NO_FLAG);
875 if(ret != ROK && ret != RWOULDBLOCK)
877 DU_LOG("\nERROR --> EGTP : Failed sending the message");
882 DU_LOG("\nDEBUG --> EGTP : Sent UL Message [%ld]", numDataSent+1);
889 /*******************************************************************
891 * @brief Receives EGTP message from UDP socket
895 * Function : egtpRecvMsg
898 * Receive incoming messages from UDP socket
901 * @return ROK - success
904 * ****************************************************************/
906 uint8_t egtpRecvMsg()
908 uint8_t ret; /* Return value */
909 uint16_t bufLen; /* Length of received buffer */
910 Buffer *recvBuf; /* Received buffer */
911 CmInetMemInfo memInfo; /* Buffer allocation info */
913 memInfo.region = DU_APP_MEM_REGION;
914 memInfo.pool = DU_POOL;
919 ret = cmInetRecvMsg(&egtpCb.sockFd, &egtpCb.dstCb.dstAddr, &memInfo, &recvBuf, (int16_t *)&bufLen, CM_INET_NO_FLAG);
920 if(ret == ROK && recvBuf != NULLP)
922 DU_LOG("\nDEBUG --> EGTP : Received DL Message[%ld]\n", gDlDataRcvdCnt + 1);
923 //ODU_PRINT_MSG(recvBuf, 0 ,0);
924 egtpHdlRecvData(recvBuf);
933 /*******************************************************************
935 * @brief Handles DL User data received from CU
939 * Function : egtpHdlRecvData
941 * Functionality: Handles DL User data received from CU
943 * @params[in] DL Usre data buffer
944 * @return ROK - success
947 * ****************************************************************/
948 uint8_t egtpHdlRecvData(Buffer *mBuf)
952 /* Decode EGTP header */
953 egtpDecodeHdr(mBuf, &egtpMsg);
955 /* TODO : Send received message to RLC */
956 duHdlEgtpDlData(&egtpMsg);
961 /*******************************************************************
963 * @brief Decodes EGTP header from DL User data
967 * Function : egtpDecodeHdr
969 * Functionality: Decodes EGTP header from DL User data
972 * @return ROK - success
975 * ****************************************************************/
976 uint8_t egtpDecodeHdr(Buffer *mBuf, EgtpMsg *egtpMsg)
978 uint8_t tmpByte[5]; /* Holds 5 byte of data after Decoding */
979 uint8_t version = 0; /* Holds the version type, decoded */
980 uint16_t msgLen = 0; /* Holds the msgLen from the Hdr */
981 uint16_t bufLen = 0; /* Holds the total buffer length */
982 uint8_t extHdrType = 0; /* Holds the Extension hdr type */
983 uint8_t extHdrLen = 0; /* Extension hdr length */
984 bool extPres = FALSE; /* Flag for indication of S, E or P presense flag */
986 ODU_GET_MSG_LEN(mBuf, (int16_t *)&bufLen);
988 /* Decode first byte and storing in temporary variable */
989 ODU_REM_PRE_MSG(&tmpByte[0], mBuf);
991 /* Extracting version fro 1st byte */
992 version = tmpByte[0] >> 5;
994 //DU_LOG("\nDEBUG --> EGTP : Version %d", version);
996 /* Decode message type */
997 ODU_REM_PRE_MSG((Data*)&(egtpMsg->msgHdr.msgType), mBuf);
998 //DU_LOG("\nDEBUG --> EGTP : msgType %d", egtpMsg->msgHdr.msgType);
1000 /****************************************************************************
1001 * Message length param is 2 bytes. So decode next 2 bytes from msg hdr and
1002 * performing OR operation on these two bytes to calculate message length
1003 ***************************************************************************/
1004 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
1005 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
1006 msgLen = (tmpByte[1] << 8) | tmpByte[2];
1009 //DU_LOG("\nDEBUG --> EGTP : msgLen %d", msgLen);
1012 /****************************************************************************
1013 * Tunnel id param is 4 bytes. So decode next 4 bytes from msg hdr and
1014 * perform OR operation on these 4 bytes to calculate tunnel id
1015 ***************************************************************************/
1016 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
1017 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
1018 ODU_REM_PRE_MSG(&tmpByte[3], mBuf);
1019 ODU_REM_PRE_MSG(&tmpByte[4], mBuf);
1020 egtpMsg->msgHdr.teId = (tmpByte[1] << 24) | (tmpByte[2] << 16) | (tmpByte[3] << 8) | tmpByte[4];
1021 //DU_LOG("\nDEBUG --> EGTP : teId %d",egtpMsg->msgHdr.teId);
1024 /* If any one of S, E or PN flag is set, set extension present as true. */
1025 if((tmpByte[0] & EGTP_MASK_BIT1) || (tmpByte[0] & EGTP_MASK_BIT2)||(tmpByte[0] & EGTP_MASK_BIT3))
1030 /* Decode sequence number, if S flag is set in first byte */
1031 if (tmpByte[0] & EGTP_MASK_BIT2)
1033 /************************************************************************
1034 * Sequence num is 2 bytes. So decode next 2 bytes from msg hdr and
1035 * perform OR operation on them
1036 ************************************************************************/
1037 egtpMsg->msgHdr.seqNum.pres = TRUE;
1038 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
1039 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
1040 egtpMsg->msgHdr.seqNum.val = (tmpByte[1] << 8) | tmpByte[2];
1042 /****************************************************************************
1043 * If extPres is true, but S bit is not set, implies, either of PN or E bit
1044 * was set during Encode so accordingly extract Byte fields for seqNum anyway
1045 ***************************************************************************/
1048 /*************************************************************************
1049 * Sequence num is 2 bytes. So decode next 2 bytes from msg hdr and
1050 * perform OR operation on them
1051 ************************************************************************/
1052 egtpMsg->msgHdr.seqNum.pres = 0;
1053 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
1054 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
1055 egtpMsg->msgHdr.seqNum.val = (tmpByte[1] << 8) | tmpByte[2];
1058 /* Decode N-PDU number if present flag is set */
1059 if (tmpByte[0] & EGTP_MASK_BIT1)
1061 egtpMsg->msgHdr.nPdu.pres = TRUE;
1062 ODU_REM_PRE_MSG(&(egtpMsg->msgHdr.nPdu.val), mBuf);
1064 /****************************************************************************
1065 * If extPres is true, but PN bit is not set, implies, either of S or E bit
1066 * was set during Encode. Aaccordingly extract Byte fields of N-PDU num anyway
1067 ***************************************************************************/
1070 egtpMsg->msgHdr.nPdu.pres = TRUE;
1071 ODU_REM_PRE_MSG(&(egtpMsg->msgHdr.nPdu.val), mBuf);
1074 /* If E flag is set in first byte, decode extension header */
1075 if(tmpByte[0] & EGTP_MASK_BIT3)
1077 ODU_REM_PRE_MSG(&extHdrType, mBuf);
1078 while( 0 != extHdrType)
1082 case EGTP_EXT_HDR_UDP_TYPE:
1084 ODU_REM_PRE_MSG(&extHdrLen, mBuf);
1085 if(extHdrLen == 0x01)
1087 /************************************************************
1088 * UDP Port is 2 bytes. So decode next 2 bytes from msg hdr
1089 * and perform OR operation on them
1090 *************************************************************/
1091 egtpMsg->msgHdr.extHdr.udpPort.pres = TRUE;
1092 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
1093 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
1094 egtpMsg->msgHdr.extHdr.udpPort.val = (tmpByte[1] << 8) | tmpByte[2];
1099 case EGTP_EXT_HDR_PDCP_TYPE:
1101 ODU_REM_PRE_MSG(&extHdrLen, mBuf);
1102 if(extHdrLen == 0x01)
1104 /*************************************************************
1105 * PDCP num is 2 bytes. So decode next 2 bytes from msg hdr
1106 * and perform OR operation on them
1107 ************************************************************/
1108 egtpMsg->msgHdr.extHdr.pdcpNmb.pres = TRUE;
1109 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
1110 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
1111 egtpMsg->msgHdr.extHdr.pdcpNmb.val = (tmpByte[1] << 8) | tmpByte[2];
1115 } /* End of switch */
1117 ODU_REM_PRE_MSG(&extHdrType, mBuf);
1119 } /* End of while */
1121 /****************************************************************************
1122 * If extPres is true, but E bit is not set, implies, either of PN or S bit
1123 * was set during Encode so accordingly extract Byte fields for extension
1125 ***************************************************************************/
1128 ODU_REM_PRE_MSG(&extHdrType, mBuf);
1131 egtpMsg->msg = mBuf;
1133 //DU_LOG("\nDEBUG --> EGTP : DL Data Buffer after decoding header ");
1134 //ODU_PRINT_MSG(mBuf, 0, 0);
1136 /* Forward the data to duApp/RLC */
1141 /**********************************************************************
1143 **********************************************************************/