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"
32 /* Global variable declaration */
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\nEGTP : Initializing");
59 memset ((uint8_t *)&egtpCb, 0, sizeof(EgtpGlobalCb));
60 protType = CM_INET_PROTO_UDP;
66 /**************************************************************************
67 * @brief Task Activation callback function.
71 * Function : egtpActvTsk
74 * This function handles all EGTP messages received
75 * This API is registered with SSI during the
76 * Task Registration of DU APP.
78 * @param[in] Pst *pst, Post structure of the primitive.
79 * @param[in] Buffer *mBuf, Packed primitive parameters in the
81 * @return ROK - success
84 ***************************************************************************/
85 uint8_t egtpActvTsk(Pst *pst, Buffer *mBuf)
97 ret = unpackEgtpCfgReq(egtpCfgReq, pst, mBuf);
102 ret = unpackEgtpSrvOpenReq(egtpSrvOpenReq, pst, mBuf);
107 ret = unpackEgtpTnlMgmtReq(egtpTnlMgmtReq, pst, mBuf);
112 ret = unpackEgtpSlotInd(egtpSlotInd, pst, mBuf);
118 DU_LOG("\nEGTP : Invalid event %d", pst->event);
136 DU_LOG("\nEGTP : Invalid event %d", pst->event);
144 DU_LOG("\nEGTP : Invalid source entity %d", pst->srcEnt);
152 /**************************************************************************
153 * @brief EGTP server configuration
157 * Function : egtpCfgReq
160 * This function handles EGTP configuration request.
162 * @return ROK - success
165 * ***********************************************************************/
166 uint8_t egtpCfgReq(Pst *pst, EgtpConfig egtpCfg)
168 uint8_t ret; /* Return value */
169 Pst rspPst; /* Response Pst structure */
170 CmStatus cfgCfm; /* Configuration Confirm */
172 memcpy((uint8_t *)&egtpCb.egtpCfg, (uint8_t *)&egtpCfg, (PTR)sizeof(EgtpConfig));
174 egtpCb.recvTptSrvr.addr.address = CM_INET_NTOH_U32(egtpCb.egtpCfg.localIp.ipV4Addr);
175 egtpCb.recvTptSrvr.addr.port = EGTP_DFLT_PORT;
177 egtpCb.dstCb.dstIp = CM_INET_NTOH_U32(egtpCb.egtpCfg.destIp.ipV4Addr);
178 egtpCb.dstCb.dstPort = egtpCb.egtpCfg.destPort;
179 egtpCb.dstCb.sendTptSrvr.addr.address = CM_INET_NTOH_U32(egtpCb.egtpCfg.localIp.ipV4Addr);
180 egtpCb.dstCb.sendTptSrvr.addr.port = egtpCb.egtpCfg.localPort;
181 egtpCb.dstCb.numTunn = 0;
183 ret = cmHashListInit(&(egtpCb.dstCb.teIdLst), 1024, sizeof(EgtpTeIdCb), FALSE, CM_HASH_KEYTYPE_U32MOD, DU_APP_MEM_REGION, DU_POOL);
187 DU_LOG("\nEGTP : TeId hash list initialization failed");
188 cfgCfm.status = LCM_PRIM_NOK;
189 cfgCfm.reason = LCM_REASON_HASHING_FAILED;
193 DU_LOG("\nEGTP : EGTP configuration successful");
194 cfgCfm.status = LCM_PRIM_OK;
195 cfgCfm.reason = LCM_REASON_NOT_APPL;
198 /* Fill response Pst */
199 egtpFillRspPst(pst, &rspPst);
200 rspPst.event = EVTCFGCFM;
202 packEgtpCfgCfm(&rspPst, cfgCfm);
207 /**************************************************************************
208 * @brief Fills post structure to send response
212 * Function : egtpFillRspPst
215 * Fills post struture to send response
217 * @return ROK - success
221 * ***********************************************************************/
222 uint8_t egtpFillRspPst(Pst *pst, Pst *rspPst)
225 memset((uint8_t *)rspPst, 0, sizeof(Pst));
226 rspPst->srcEnt = pst->dstEnt;
227 rspPst->srcInst = pst->dstInst;
228 rspPst->srcProcId = pst->dstProcId;
229 rspPst->dstEnt = pst->srcEnt;
230 rspPst->dstInst = pst->srcInst;
231 rspPst->dstProcId = pst->srcProcId;
232 rspPst->selector = ODU_SELECTOR_LC;
233 rspPst->pool= DU_POOL;
238 /**************************************************************************
239 * @brief EGTP server open request
243 * Function : egtpSrvOpenReq
246 * This function handles EGTP open server request.
247 * It opens udp socket to receive/send msgs.
249 * @param[in] Pst *pst, post structure
250 * @return ROK - success
253 ***************************************************************************/
255 uint8_t egtpSrvOpenReq(Pst *pst)
258 uint8_t ret; /* Return value */
259 Pst rspPst; /* Response Pst structure */
260 CmStatus cfm; /* Confirmation status */
261 uint8_t sockType; /* Socket type */
263 DU_LOG("\nEGTP : Received EGTP open server request");
265 sockType = CM_INET_DGRAM;
266 ret = egtpSrvOpenPrc(sockType, &(egtpCb.recvTptSrvr));
267 /* Opening and Binding receiver socket */
270 DU_LOG("\nEGTP : Failed while opening receiver transport server");
273 /* Opening and Binding sender socket */
274 ret = egtpSrvOpenPrc(sockType, &(egtpCb.dstCb.sendTptSrvr));
277 DU_LOG("\nEGTP : Failed while opening sender transport server");
281 DU_LOG("\nEGTP : Receiver socket[%d] and Sender socket[%d] open", egtpCb.recvTptSrvr.sockFd.fd, egtpCb.dstCb.sendTptSrvr.sockFd.fd);
283 /* Filling and seing response */
284 cfm.status = LCM_PRIM_OK;
285 cfm.reason = LCM_REASON_NOT_APPL;
287 egtpFillRspPst(pst, &rspPst);
288 rspPst.event = EVTSRVOPENCFM;
289 packEgtpSrvOpenCfm(&rspPst, cfm);
294 /*******************************************************************
296 * @brief Processing Sever open request
300 * Function : egtpSrvOpenPrc
306 * @return ROK - success
309 * ****************************************************************/
311 uint8_t egtpSrvOpenPrc(uint8_t sockType, EgtpTptSrvr *server)
314 ret = cmInetSocket(sockType, &(server->sockFd), protType);
317 DU_LOG("\nEGTP : Failed to open UDP socket");
320 ret = cmInetBind(&(server->sockFd), &(server->addr));
323 DU_LOG("\nEGTP : Failed to bind socket");
330 /**************************************************************************
331 * @brief EGTP tunnel management request
335 * Function : egtpTnlMgmtReq
338 * This function handles EGTP tunnel managament request
340 * @param[in] Pst *pst, post structure
341 * Tunnel Eveny structure
342 * @return ROK - success
346 * ***************************************************************************/
347 uint8_t egtpTnlMgmtReq(Pst *pst, EgtpTnlEvt tnlEvt)
352 DU_LOG("\nEGTP : Received tunnel management request");
353 switch(tnlEvt.action)
355 case EGTP_TNL_MGMT_ADD:
357 ret = egtpTnlAdd(tnlEvt);
360 case EGTP_TNL_MGMT_MOD:
362 ret = egtpTnlMod(tnlEvt);
365 case EGTP_TNL_MGMT_DEL:
367 ret = egtpTnlDel(tnlEvt);
372 DU_LOG("\nEGTP : Invalid tunnel management action[%d]", tnlEvt.action);
373 ret = LCM_REASON_INVALID_ACTION;
379 tnlEvt.cfmStatus.status = LCM_PRIM_OK;
380 tnlEvt.cfmStatus.reason = LCM_REASON_NOT_APPL;
384 tnlEvt.cfmStatus.status = LCM_PRIM_NOK;
385 tnlEvt.cfmStatus.reason = ret;
388 DU_LOG("\nEGTP : Sending Tunnel management confirmation");
389 egtpFillRspPst(pst, &rspPst);
390 rspPst.event = EVTTNLMGMTCFM;
391 packEgtpTnlMgmtCfm(&rspPst, tnlEvt);
396 /**************************************************************************
397 * @brief EGTP tunnel addition
401 * Function : egtpTnlAdd
404 * This function handles EGTP tunnel addition
406 * @param[in] Tunnel Event structure
407 * @return ROK - success
410 * ***************************************************************************/
411 uint8_t egtpTnlAdd(EgtpTnlEvt tnlEvt)
414 EgtpTeIdCb *teidCb; /* Tunnel endpoint control block */
415 EgtpMsgHdr preDefHdr; /* pre-define header for this tunnel */
417 DU_LOG("\nEGTP : Tunnel addition : LocalTeid[%d] Remote Teid[%d]", tnlEvt.lclTeid, tnlEvt.remTeid);
419 DU_ALLOC(teidCb, sizeof(EgtpTeIdCb));
422 DU_LOG("\nEGTP : Memory allocation failed");
423 return LCM_REASON_MEM_NOAVAIL;
426 memset((uint8_t *)teidCb, 0, sizeof(EgtpTeIdCb));
427 teidCb->teId = tnlEvt.lclTeid;
428 teidCb->remTeId = tnlEvt.remTeid;
430 ret = cmHashListInsert(&(egtpCb.dstCb.teIdLst), (PTR)teidCb, (uint8_t *)&(teidCb->teId), sizeof(uint32_t));
433 DU_LOG("\nEGTP : Failed to insert in hash list");
434 DU_FREE(teidCb, sizeof(EgtpTeIdCb));
435 return LCM_REASON_HASHING_FAILED;
437 egtpCb.dstCb.numTunn++;
439 /* Encoding pre-defined header */
440 memset((uint8_t*)&preDefHdr, 0, sizeof(EgtpMsgHdr));
441 preDefHdr.msgType = EGTPU_MSG_GPDU;
442 preDefHdr.teId = teidCb->remTeId;
443 preDefHdr.extHdr.pdcpNmb.pres = FALSE;
444 preDefHdr.extHdr.udpPort.pres = FALSE;
445 preDefHdr.nPdu.pres = FALSE;
447 egtpEncodeHdr((uint8_t *)teidCb->preEncodedHdr.hdr, &preDefHdr, &(teidCb->preEncodedHdr.cnt));
452 /**************************************************************************
453 * @brief EGTP tunnel modification
457 * Function : egtpTnlMod
460 * This function handles EGTP tunnel modification
462 * @param[in] Tunnel Event structure
463 * @return ROK - success
466 * ***************************************************************************/
467 uint8_t egtpTnlMod(EgtpTnlEvt tnlEvt)
471 EgtpTeIdCb *teidCb = NULLP;
473 printf("\nTunnel modification : LocalTeid[%d] Remote Teid[%d]", tnlEvt.lclTeid, tnlEvt.remTeid);
475 cmHashListFind(&(egtpCb.dstCb.teIdLst), (uint8_t *)&(tnlEvt.teId), sizeof(uint32_t), 0, (PTR *)&teidCb);
478 printf("\nTunnel id not found");
482 teidCb->teId = tnlEvt.lclTeid;
483 teidCb->remTeId = tnlEvt.remTeid;
488 /**************************************************************************
489 * @brief EGTP tunnel deletion
493 * Function : egtpTnlDel
496 * This function handles EGTP tunnel deletion
498 * @param[in] Tunnel Event structure
499 * @return ROK - success
502 * ***************************************************************************/
503 uint8_t egtpTnlDel(EgtpTnlEvt tnlEvt)
505 EgtpTeIdCb *teidCb = NULLP;
507 DU_LOG("\nEGTP : Tunnel deletion : Local Teid[%d] Remote Teid[%d]", tnlEvt.lclTeid, tnlEvt.remTeid);
509 cmHashListFind(&(egtpCb.dstCb.teIdLst), (uint8_t *)&(tnlEvt.lclTeid), sizeof(uint32_t), 0, (PTR *)&teidCb);
512 DU_LOG("\nEGTP : Tunnel id[%d] not configured", tnlEvt.lclTeid);
513 return LCM_REASON_INVALID_PAR_VAL;
516 cmHashListDelete(&(egtpCb.dstCb.teIdLst), (PTR)teidCb);
517 DU_FREE(teidCb, sizeof(EgtpTeIdCb));
518 egtpCb.dstCb.numTunn--;
523 /*******************************************************************
525 * @brief Handles data indication
529 * Function : EgtpHdlDatInd
532 * Handles incoming data from peer to be passed
536 * @return ROK - success
539 * ****************************************************************/
540 uint8_t egtpHdlDatInd(EgtpMsg egtpMsg)
542 EgtpTeIdCb *teidCb = NULLP;
548 DU_LOG("\nEGTP : Received Data Indication");
550 cmHashListFind(&(egtpCb.dstCb.teIdLst), (uint8_t *)&(egtpMsg.msgHdr.teId), sizeof(uint32_t), 0, (PTR *)&teidCb);
553 DU_LOG("\nEGTP : Tunnel id[%d] not configured", egtpMsg.msgHdr.teId);
554 return LCM_REASON_INVALID_PAR_VAL;
557 msgHdr = &(egtpMsg.msgHdr);
559 hdrLen = teidCb->preEncodedHdr.cnt;
561 if(msgHdr->extHdr.pdcpNmb.pres)
563 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] |= EGTP_MASK_BIT3;
564 teidCb->preEncodedHdr.hdr[hdrLen] = EGTP_EXT_HDR_PDCP_TYPE;
565 teidCb->preEncodedHdr.hdr[--hdrLen] = 1;
566 teidCb->preEncodedHdr.hdr[--hdrLen] = GetHiByte(msgHdr->extHdr.pdcpNmb.val);
567 teidCb->preEncodedHdr.hdr[--hdrLen] = GetLoByte(msgHdr->extHdr.pdcpNmb.val);
568 teidCb->preEncodedHdr.hdr[--hdrLen] = 0;
572 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] &= ~(EGTP_MASK_BIT3);
575 ODU_FIND_MSG_LEN(egtpMsg.msg, &tPduSize);
577 /*Adjust the header to fill the correct length*/
578 msgLen = tPduSize + (EGTP_MAX_HDR_LEN - hdrLen) - 0x08;
580 /***********************************************
581 * Fill the length field of the message header *
582 ***********************************************/
583 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 3] = (uint8_t)GetHiByte(msgLen);
584 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 4] = (uint8_t)GetLoByte(msgLen);
586 /*Update the sequence number*/
587 if(egtpMsg.msgHdr.seqNum.pres)
589 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] |= (EGTP_MASK_BIT2);
590 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 9] = (uint8_t)GetHiByte(egtpMsg.msgHdr.seqNum.val);
591 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 10] = (uint8_t)GetLoByte(egtpMsg.msgHdr.seqNum.val);
595 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] &= ~(EGTP_MASK_BIT2);
598 DU_LOG("\nEGTP : UL Data buffer before encoding header");
599 ODU_PRINT_MSG(egtpMsg.msg, 0, 0);
601 ODU_ADD_PRE_MSG_MULT(&teidCb->preEncodedHdr.hdr[hdrLen], (EGTP_MAX_HDR_LEN - hdrLen), egtpMsg.msg);
604 DU_LOG("\nEGTP : UL Data buffer after encoding header");
605 ODU_PRINT_MSG(egtpMsg.msg, 0, 0);
608 egtpSendMsg(egtpMsg.msg);
609 ODU_PUT_MSG(egtpMsg.msg);
614 /*******************************************************************
616 * @brief Encodes outgoing message
620 * Function : egtpEncodeMsg
623 * Encodes EGTP message to be sent
625 * @params[in] EGTP message
627 * @return ROK - success
630 * ****************************************************************/
631 uint8_t egtpEncodeHdr(uint8_t *preEncodedHdr, EgtpMsgHdr *preDefHdr, uint8_t *hdrIdx)
633 uint8_t tmpByte = 0; /* Stores one byte of data for enc */
634 uint8_t cnt = EGTP_MAX_HDR_LEN; /* Stores the position */
635 bool extPres = FALSE; /* Flag for indication of S, E or P presense flag */
638 /* Encoding header */
639 tmpByte |= EGTP_MASK_BIT6; /* Setting 6th LSB of 1st byte as version */
640 tmpByte |= EGTP_MASK_BIT5; /* Setting 5th LSB of 1st byte as protocol type */
642 if(preDefHdr->extHdr.udpPort.pres || preDefHdr->extHdr.pdcpNmb.pres)
644 tmpByte |= EGTP_MASK_BIT3; /* Setting 3rd LSB of 1st byte if Extension heaeder is present */
647 if(preDefHdr->seqNum.pres)
649 tmpByte |= EGTP_MASK_BIT2;
652 if(preDefHdr->nPdu.pres)
654 tmpByte |= EGTP_MASK_BIT1;
657 if((tmpByte & EGTP_MASK_BIT1) || (tmpByte & EGTP_MASK_BIT2)||(tmpByte & EGTP_MASK_BIT3))
662 preEncodedHdr[--cnt] = tmpByte;
663 preEncodedHdr[--cnt] = preDefHdr->msgType;
665 /* Encode Tunnel endpoint */
666 preEncodedHdr[--cnt] = 0;
667 preEncodedHdr[--cnt] = 0;
668 nwWord = (uint16_t)(GetHiWord(preDefHdr->teId));
669 preEncodedHdr[--cnt] = (uint8_t)(GetHiByte(nwWord));
670 preEncodedHdr[--cnt] = (uint8_t)(GetLoByte(nwWord));
671 nwWord = (uint16_t)(GetLoWord(preDefHdr->teId));
672 preEncodedHdr[--cnt] = (uint8_t)(GetHiByte(nwWord));
673 preEncodedHdr[--cnt] = (uint8_t)(GetLoByte(nwWord));
675 /* Encode sequence number */
676 if(preDefHdr->seqNum.pres)
678 preEncodedHdr[--cnt] = GetHiByte(preDefHdr->seqNum.val);
679 preEncodedHdr[--cnt] = GetLoByte(preDefHdr->seqNum.val);
683 preEncodedHdr[--cnt] = 0;
684 preEncodedHdr[--cnt] = 0;
687 /* Encode nPdu number */
688 if(preDefHdr->nPdu.pres)
690 preEncodedHdr[--cnt] = preDefHdr->nPdu.val;
694 preEncodedHdr[--cnt] = 0;
697 if(preDefHdr->extHdr.udpPort.pres)
699 preEncodedHdr[--cnt] = EGTP_EXT_HDR_UDP_TYPE;
700 preEncodedHdr[--cnt] = 1;
701 preEncodedHdr[--cnt] = GetHiByte(preDefHdr->extHdr.udpPort.val);
702 preEncodedHdr[--cnt] = GetLoByte(preDefHdr->extHdr.udpPort.val);
705 if(preDefHdr->extHdr.pdcpNmb.pres)
707 preEncodedHdr[--cnt] = EGTP_EXT_HDR_PDCP_TYPE;
708 preEncodedHdr[--cnt] = 1;
709 preEncodedHdr[--cnt] = GetHiByte(preDefHdr->extHdr.pdcpNmb.val);
710 preEncodedHdr[--cnt] = GetLoByte(preDefHdr->extHdr.pdcpNmb.val);
713 if(tmpByte & EGTP_MASK_BIT3)
715 preEncodedHdr[--cnt] = 0;
719 preEncodedHdr[--cnt] = 0;
724 } /* egtpEncodeHdr */
726 /*******************************************************************
728 * @brief Sends message over UDP
732 * Function : egtpSendMsg
735 * Sends message over UDP
737 * @params[in] Message Buffer
738 * @return ROK - success
741 * ****************************************************************/
742 uint8_t egtpSendMsg(Buffer *mBuf)
749 info.region = DU_APP_MEM_REGION;
752 dstAddr.port = EGTP_DFLT_PORT;
753 dstAddr.address = egtpCb.dstCb.dstIp;
755 ret = cmInetSendMsg(&(egtpCb.dstCb.sendTptSrvr.sockFd), &dstAddr, &info, mBuf, &txLen, CM_INET_NO_FLAG);
756 if(ret != ROK && ret != RWOULDBLOCK)
758 DU_LOG("\nEGTP : Failed sending the message");
762 DU_LOG("\nEGTP : Message Sent");
767 /*******************************************************************
769 * @brief Handles Slot Indication from PHY
773 * Function : egtpSlotInd
776 * Handles TTI Indication from PHY
779 * @return ROK - success
782 * ****************************************************************/
783 uint8_t egtpSlotInd()
789 /*******************************************************************
791 * @brief Receives EGTP message from UDP socket
795 * Function : egtpRecvMsg
798 * Receive incoming messages from UDP socket
801 * @return ROK - success
804 * ****************************************************************/
806 uint8_t egtpRecvMsg()
808 uint8_t ret; /* Return value */
809 uint8_t nMsg; /* Number of messages to read from UDP socked */
810 uint16_t bufLen; /* Length of received buffer */
811 Buffer *recvBuf; /* Received buffer */
812 CmInetAddr fromAddr; /* Egtp data sender address */
813 CmInetMemInfo memInfo; /* Buffer allocation info */
816 DU_LOG("\nEGTP : Received Slot Indication");
819 memInfo.region = DU_APP_MEM_REGION;
820 memInfo.pool = DU_POOL;
822 fromAddr.port = egtpCb.dstCb.dstPort;
823 fromAddr.address = egtpCb.dstCb.dstIp;
825 while(nMsg < EGTP_MAX_MSG_RECV)
828 ret = cmInetRecvMsg(&(egtpCb.recvTptSrvr.sockFd), &fromAddr, &memInfo, &recvBuf, &bufLen, CM_INET_NO_FLAG);
829 if(ret == ROK && recvBuf != NULLP)
831 DU_LOG("\nEGTP : Received DL Message[%d]\n", nMsg+1);
832 ODU_PRINT_MSG(recvBuf, 0 ,0);
833 egtpHdlRecvData(recvBuf);
841 uint8_t egtpHdlRecvData(Buffer *mBuf)
845 /* Decode EGTP header */
846 egtpDecodeHdr(mBuf, &egtpMsg);
848 /* TODO : Send received message to RLC */
849 duHdlEgtpDlData(&egtpMsg);
854 uint8_t egtpDecodeHdr(Buffer *mBuf, EgtpMsg *egtpMsg)
856 uint8_t tmpByte[5]; /* Holds 5 byte of data after Decoding */
857 uint8_t version = 0; /* Holds the version type, decoded */
858 uint16_t msgLen = 0; /* Holds the msgLen from the Hdr */
859 uint16_t bufLen = 0; /* Holds the total buffer length */
860 uint8_t extHdrType = 0; /* Holds the Extension hdr type */
861 uint8_t extHdrLen = 0; /* Extension hdr length */
862 bool extPres = FALSE; /* Flag for indication of S, E or P presense flag */
864 ODU_FIND_MSG_LEN(mBuf, &bufLen);
866 /* Decode first byte and storing in temporary variable */
867 ODU_REM_PRE_MSG(&tmpByte[0], mBuf);
869 /* Extracting version fro 1st byte */
870 version = tmpByte[0] >> 5;
872 DU_LOG("\nEGTP : Version %d", version);
874 /* Decode message type */
875 ODU_REM_PRE_MSG((Data*)&(egtpMsg->msgHdr.msgType), mBuf);
876 DU_LOG("\nEGTP : msgType %d", egtpMsg->msgHdr.msgType);
878 /****************************************************************************
879 * Message length param is 2 bytes. So decode next 2 bytes from msg hdr and
880 * performing OR operation on these two bytes to calculate message length
881 ***************************************************************************/
882 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
883 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
884 msgLen = (tmpByte[1] << 8) | tmpByte[2];
885 DU_LOG("\nEGTP : msgLen %d", msgLen);
888 /****************************************************************************
889 * Tunnel id param is 4 bytes. So decode next 4 bytes from msg hdr and
890 * perform OR operation on these 4 bytes to calculate tunnel id
891 ***************************************************************************/
892 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
893 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
894 ODU_REM_PRE_MSG(&tmpByte[3], mBuf);
895 ODU_REM_PRE_MSG(&tmpByte[4], mBuf);
896 egtpMsg->msgHdr.teId = (tmpByte[1] << 24) | (tmpByte[2] << 16) | (tmpByte[3] << 8) | tmpByte[4];
897 DU_LOG("\nEGTP : teId %d",egtpMsg->msgHdr.teId);
900 /* If any one of S, E or PN flag is set, set extension present as true. */
901 if((tmpByte[0] & EGTP_MASK_BIT1) || (tmpByte[0] & EGTP_MASK_BIT2)||(tmpByte[0] & EGTP_MASK_BIT3))
906 /* Decode sequence number, if S flag is set in first byte */
907 if (tmpByte[0] & EGTP_MASK_BIT2)
909 /************************************************************************
910 * Sequence num is 2 bytes. So decode next 2 bytes from msg hdr and
911 * perform OR operation on them
912 ************************************************************************/
913 egtpMsg->msgHdr.seqNum.pres = TRUE;
914 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
915 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
916 egtpMsg->msgHdr.seqNum.val = (tmpByte[1] << 8) | tmpByte[2];
918 /****************************************************************************
919 * If extPres is true, but S bit is not set, implies, either of PN or E bit
920 * was set during Encode so accordingly extract Byte fields for seqNum anyway
921 ***************************************************************************/
924 /*************************************************************************
925 * Sequence num is 2 bytes. So decode next 2 bytes from msg hdr and
926 * perform OR operation on them
927 ************************************************************************/
928 egtpMsg->msgHdr.seqNum.pres = 0;
929 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
930 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
931 egtpMsg->msgHdr.seqNum.val = (tmpByte[1] << 8) | tmpByte[2];
934 /* Decode N-PDU number if present flag is set */
935 if (tmpByte[0] & EGTP_MASK_BIT1)
937 egtpMsg->msgHdr.nPdu.pres = TRUE;
938 ODU_REM_PRE_MSG(&(egtpMsg->msgHdr.nPdu.val), mBuf);
940 /****************************************************************************
941 * If extPres is true, but PN bit is not set, implies, either of S or E bit
942 * was set during Encode. Aaccordingly extract Byte fields of N-PDU num anyway
943 ***************************************************************************/
946 egtpMsg->msgHdr.nPdu.pres = TRUE;
947 ODU_REM_PRE_MSG(&(egtpMsg->msgHdr.nPdu.val), mBuf);
950 /* If E flag is set in first byte, decode extension header */
951 if(tmpByte[0] & EGTP_MASK_BIT3)
953 ODU_REM_PRE_MSG(&extHdrType, mBuf);
954 while( 0 != extHdrType)
958 case EGTP_EXT_HDR_UDP_TYPE:
960 ODU_REM_PRE_MSG(&extHdrLen, mBuf);
961 if(extHdrLen == 0x01)
963 /************************************************************
964 * UDP Port is 2 bytes. So decode next 2 bytes from msg hdr
965 * and perform OR operation on them
966 *************************************************************/
967 egtpMsg->msgHdr.extHdr.udpPort.pres = TRUE;
968 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
969 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
970 egtpMsg->msgHdr.extHdr.udpPort.val = (tmpByte[1] << 8) | tmpByte[2];
975 case EGTP_EXT_HDR_PDCP_TYPE:
977 ODU_REM_PRE_MSG(&extHdrLen, mBuf);
978 if(extHdrLen == 0x01)
980 /*************************************************************
981 * PDCP num is 2 bytes. So decode next 2 bytes from msg hdr
982 * and perform OR operation on them
983 ************************************************************/
984 egtpMsg->msgHdr.extHdr.pdcpNmb.pres = TRUE;
985 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
986 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
987 egtpMsg->msgHdr.extHdr.pdcpNmb.val = (tmpByte[1] << 8) | tmpByte[2];
991 } /* End of switch */
993 ODU_REM_PRE_MSG(&extHdrType, mBuf);
997 /****************************************************************************
998 * If extPres is true, but E bit is not set, implies, either of PN or S bit
999 * was set during Encode so accordingly extract Byte fields for extension
1001 ***************************************************************************/
1004 ODU_REM_PRE_MSG(&extHdrType, mBuf);
1007 egtpMsg->msg = mBuf;
1009 DU_LOG("\nEGTP : DL Data Buffer after decoding header ");
1010 ODU_PRINT_MSG(mBuf, 0, 0);
1012 /* Forward the data to duApp/RLC */