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_ue_mgr.h"
29 /* Global variable declaration */
32 /**************************************************************************
33 * @brief Task Initiation callback function.
37 * Function : egtpActvInit
40 * This function is supplied as one of parameters during EGTP's
41 * task registration. SSI will invoke this function once, after
42 * it creates and attaches this TAPA Task to a system task.
44 * @param[in] Ent entity, the entity ID of this task.
45 * @param[in] Inst inst, the instance ID of this task.
46 * @param[in] Region region, the region ID registered for memory
48 * @param[in] Reason reason.
49 * @return ROK - success
51 ***************************************************************************/
52 S16 egtpActvInit(Ent entity, Inst inst, Region region, Reason reason)
54 DU_LOG("\n\nEGTP : Initializing");
56 cmMemset ((U8 *)&egtpCb, 0, sizeof(EgtpGlobalCb));
57 protType = CM_INET_PROTO_UDP;
63 /**************************************************************************
64 * @brief Task Activation callback function.
68 * Function : egtpActvTsk
71 * This function handles all EGTP messages received
72 * This API is registered with SSI during the
73 * Task Registration of DU APP.
75 * @param[in] Pst *pst, Post structure of the primitive.
76 * @param[in] Buffer *mBuf, Packed primitive parameters in the
78 * @return ROK - success
81 ***************************************************************************/
82 S16 egtpActvTsk(Pst *pst, Buffer *mBuf)
94 ret = unpackEgtpCfgReq(egtpCfgReq, pst, mBuf);
99 ret = unpackEgtpSrvOpenReq(egtpSrvOpenReq, pst, mBuf);
104 ret = unpackEgtpTnlMgmtReq(egtpTnlMgmtReq, pst, mBuf);
109 ret = unpackEgtpSlotInd(egtpSlotInd, pst, mBuf);
115 DU_LOG("\nEGTP : Invalid event %d", pst->event);
133 DU_LOG("\nEGTP : Invalid event %d", pst->event);
141 DU_LOG("\nEGTP : Invalid source entity %d", pst->srcEnt);
149 /**************************************************************************
150 * @brief EGTP server configuration
154 * Function : egtpCfgReq
157 * This function handles EGTP configuration request.
159 * @return ROK - success
162 * ***********************************************************************/
163 S16 egtpCfgReq(Pst *pst, EgtpConfig egtpCfg)
165 U8 ret; /* Return value */
166 Pst rspPst; /* Response Pst structure */
167 CmStatus cfgCfm; /* Configuration Confirm */
169 cmMemcpy((U8 *)&egtpCb.egtpCfg, (U8 *)&egtpCfg, (PTR)sizeof(EgtpConfig));
171 egtpCb.recvTptSrvr.addr.address = CM_INET_NTOH_U32(egtpCb.egtpCfg.localIp.ipV4Addr);
172 egtpCb.recvTptSrvr.addr.port = EGTP_DFLT_PORT;
174 egtpCb.dstCb.dstIp = CM_INET_NTOH_U32(egtpCb.egtpCfg.destIp.ipV4Addr);
175 egtpCb.dstCb.dstPort = egtpCb.egtpCfg.destPort;
176 egtpCb.dstCb.sendTptSrvr.addr.address = CM_INET_NTOH_U32(egtpCb.egtpCfg.localIp.ipV4Addr);
177 egtpCb.dstCb.sendTptSrvr.addr.port = egtpCb.egtpCfg.localPort;
178 egtpCb.dstCb.numTunn = 0;
180 ret = cmHashListInit(&(egtpCb.dstCb.teIdLst), 1024, sizeof(EgtpTeIdCb), FALSE, CM_HASH_KEYTYPE_U32MOD, DU_APP_MEM_REGION, DU_POOL);
184 DU_LOG("\nEGTP : TeId hash list initialization failed");
185 cfgCfm.status = LCM_PRIM_NOK;
186 cfgCfm.reason = LCM_REASON_HASHING_FAILED;
190 DU_LOG("\nEGTP : EGTP configuration successful");
191 cfgCfm.status = LCM_PRIM_OK;
192 cfgCfm.reason = LCM_REASON_NOT_APPL;
195 /* Fill response Pst */
196 egtpFillRspPst(pst, &rspPst);
197 rspPst.event = EVTCFGCFM;
199 packEgtpCfgCfm(&rspPst, cfgCfm);
204 /**************************************************************************
205 * @brief Fills post structure to send response
209 * Function : egtpFillRspPst
212 * Fills post struture to send response
214 * @return ROK - success
218 * ***********************************************************************/
219 S16 egtpFillRspPst(Pst *pst, Pst *rspPst)
222 cmMemset((U8 *)rspPst, 0, sizeof(Pst));
223 rspPst->srcEnt = pst->dstEnt;
224 rspPst->srcInst = pst->dstInst;
225 rspPst->srcProcId = pst->dstProcId;
226 rspPst->dstEnt = pst->srcEnt;
227 rspPst->dstInst = pst->srcInst;
228 rspPst->dstProcId = pst->srcProcId;
229 rspPst->selector = ODU_SELECTOR_LC;
230 rspPst->pool= DU_POOL;
235 /**************************************************************************
236 * @brief EGTP server open request
240 * Function : egtpSrvOpenReq
243 * This function handles EGTP open server request.
244 * It opens udp socket to receive/send msgs.
246 * @param[in] Pst *pst, post structure
247 * @return ROK - success
250 ***************************************************************************/
252 S16 egtpSrvOpenReq(Pst *pst)
255 U8 ret; /* Return value */
256 Pst rspPst; /* Response Pst structure */
257 CmStatus cfm; /* Confirmation status */
258 U8 sockType; /* Socket type */
260 DU_LOG("\nEGTP : Received EGTP open server request");
262 sockType = CM_INET_DGRAM;
263 ret = egtpSrvOpenPrc(sockType, &(egtpCb.recvTptSrvr));
264 /* Opening and Binding receiver socket */
267 DU_LOG("\nEGTP : Failed while opening receiver transport server");
270 /* Opening and Binding sender socket */
271 ret = egtpSrvOpenPrc(sockType, &(egtpCb.dstCb.sendTptSrvr));
274 DU_LOG("\nEGTP : Failed while opening sender transport server");
278 DU_LOG("\nEGTP : Receiver socket[%d] and Sender socket[%d] open", egtpCb.recvTptSrvr.sockFd.fd, egtpCb.dstCb.sendTptSrvr.sockFd.fd);
280 /* Filling and seing response */
281 cfm.status = LCM_PRIM_OK;
282 cfm.reason = LCM_REASON_NOT_APPL;
284 egtpFillRspPst(pst, &rspPst);
285 rspPst.event = EVTSRVOPENCFM;
286 packEgtpSrvOpenCfm(&rspPst, cfm);
291 /*******************************************************************
293 * @brief Processing Sever open request
297 * Function : egtpSrvOpenPrc
303 * @return ROK - success
306 * ****************************************************************/
308 S16 egtpSrvOpenPrc(U8 sockType, EgtpTptSrvr *server)
311 ret = cmInetSocket(sockType, &(server->sockFd), protType);
314 DU_LOG("\nEGTP : Failed to open UDP socket");
317 ret = cmInetBind(&(server->sockFd), &(server->addr));
320 DU_LOG("\nEGTP : Failed to bind socket");
327 /**************************************************************************
328 * @brief EGTP tunnel management request
332 * Function : egtpTnlMgmtReq
335 * This function handles EGTP tunnel managament request
337 * @param[in] Pst *pst, post structure
338 * Tunnel Eveny structure
339 * @return ROK - success
343 * ***************************************************************************/
344 S16 egtpTnlMgmtReq(Pst *pst, EgtpTnlEvt tnlEvt)
349 DU_LOG("\nEGTP : Received tunnel management request");
350 switch(tnlEvt.action)
352 case EGTP_TNL_MGMT_ADD:
354 ret = egtpTnlAdd(tnlEvt);
357 case EGTP_TNL_MGMT_MOD:
359 ret = egtpTnlMod(tnlEvt);
362 case EGTP_TNL_MGMT_DEL:
364 ret = egtpTnlDel(tnlEvt);
369 DU_LOG("\nEGTP : Invalid tunnel management action[%d]", tnlEvt.action);
370 ret = LCM_REASON_INVALID_ACTION;
376 tnlEvt.cfmStatus.status = LCM_PRIM_OK;
377 tnlEvt.cfmStatus.reason = LCM_REASON_NOT_APPL;
381 tnlEvt.cfmStatus.status = LCM_PRIM_NOK;
382 tnlEvt.cfmStatus.reason = ret;
385 DU_LOG("\nEGTP : Sending Tunnel management confirmation");
386 egtpFillRspPst(pst, &rspPst);
387 rspPst.event = EVTTNLMGMTCFM;
388 packEgtpTnlMgmtCfm(&rspPst, tnlEvt);
393 /**************************************************************************
394 * @brief EGTP tunnel addition
398 * Function : egtpTnlAdd
401 * This function handles EGTP tunnel addition
403 * @param[in] Tunnel Event structure
404 * @return ROK - success
407 * ***************************************************************************/
408 S16 egtpTnlAdd(EgtpTnlEvt tnlEvt)
411 EgtpTeIdCb *teidCb; /* Tunnel endpoint control block */
412 EgtpMsgHdr preDefHdr; /* pre-define header for this tunnel */
414 DU_LOG("\nEGTP : Tunnel addition : LocalTeid[%d] Remote Teid[%d]", tnlEvt.lclTeid, tnlEvt.remTeid);
416 ret = SGetSBuf(DU_APP_MEM_REGION, DU_POOL, (Data **)&teidCb, (Size)sizeof(EgtpTeIdCb));
419 DU_LOG("\nEGTP : Memory allocation failed");
420 return LCM_REASON_MEM_NOAVAIL;
423 cmMemset((U8 *)teidCb, 0, sizeof(EgtpTeIdCb));
424 teidCb->teId = tnlEvt.lclTeid;
425 teidCb->remTeId = tnlEvt.remTeid;
427 ret = cmHashListInsert(&(egtpCb.dstCb.teIdLst), (PTR)teidCb, (U8 *)&(teidCb->teId), sizeof(U32));
430 DU_LOG("\nEGTP : Failed to insert in hash list");
431 SPutSBuf(DU_APP_MEM_REGION, DU_POOL, (Data *)teidCb, (Size)sizeof(EgtpTeIdCb));
432 return LCM_REASON_HASHING_FAILED;
434 egtpCb.dstCb.numTunn++;
436 /* Encoding pre-defined header */
437 cmMemset((U8*)&preDefHdr, 0, sizeof(EgtpMsgHdr));
438 preDefHdr.msgType = EGTPU_MSG_GPDU;
439 preDefHdr.teId = teidCb->remTeId;
440 preDefHdr.extHdr.pdcpNmb.pres = FALSE;
441 preDefHdr.extHdr.udpPort.pres = FALSE;
442 preDefHdr.nPdu.pres = FALSE;
444 egtpEncodeHdr((U8 *)teidCb->preEncodedHdr.hdr, &preDefHdr, &(teidCb->preEncodedHdr.cnt));
449 /**************************************************************************
450 * @brief EGTP tunnel modification
454 * Function : egtpTnlMod
457 * This function handles EGTP tunnel modification
459 * @param[in] Tunnel Event structure
460 * @return ROK - success
463 * ***************************************************************************/
464 S16 egtpTnlMod(EgtpTnlEvt tnlEvt)
468 EgtpTeIdCb *teidCb = NULLP;
470 printf("\nTunnel modification : LocalTeid[%d] Remote Teid[%d]", tnlEvt.lclTeid, tnlEvt.remTeid);
472 cmHashListFind(&(egtpCb.dstCb.teIdLst), (U8 *)&(tnlEvt.teId), sizeof(U32), 0, (PTR *)&teidCb);
475 printf("\nTunnel id not found");
479 teidCb->teId = tnlEvt.lclTeid;
480 teidCb->remTeId = tnlEvt.remTeid;
485 /**************************************************************************
486 * @brief EGTP tunnel deletion
490 * Function : egtpTnlDel
493 * This function handles EGTP tunnel deletion
495 * @param[in] Tunnel Event structure
496 * @return ROK - success
499 * ***************************************************************************/
500 S16 egtpTnlDel(EgtpTnlEvt tnlEvt)
502 EgtpTeIdCb *teidCb = NULLP;
504 DU_LOG("\nEGTP : Tunnel deletion : Local Teid[%d] Remote Teid[%d]", tnlEvt.lclTeid, tnlEvt.remTeid);
506 cmHashListFind(&(egtpCb.dstCb.teIdLst), (U8 *)&(tnlEvt.lclTeid), sizeof(U32), 0, (PTR *)&teidCb);
509 DU_LOG("\nEGTP : Tunnel id[%d] not configured", tnlEvt.lclTeid);
510 return LCM_REASON_INVALID_PAR_VAL;
513 cmHashListDelete(&(egtpCb.dstCb.teIdLst), (PTR)teidCb);
514 SPutSBuf(DU_APP_MEM_REGION, DU_POOL, (Data *)teidCb, (Size)sizeof(EgtpTeIdCb));
515 egtpCb.dstCb.numTunn--;
520 /*******************************************************************
522 * @brief Handles data indication
526 * Function : EgtpHdlDatInd
529 * Handles incoming data from peer to be passed
533 * @return ROK - success
536 * ****************************************************************/
537 S16 egtpHdlDatInd(EgtpMsg egtpMsg)
539 EgtpTeIdCb *teidCb = NULLP;
545 DU_LOG("\nEGTP : Received Data Indication");
547 cmHashListFind(&(egtpCb.dstCb.teIdLst), (U8 *)&(egtpMsg.msgHdr.teId), sizeof(U32), 0, (PTR *)&teidCb);
550 DU_LOG("\nEGTP : Tunnel id[%d] not configured", egtpMsg.msgHdr.teId);
551 return LCM_REASON_INVALID_PAR_VAL;
554 msgHdr = &(egtpMsg.msgHdr);
556 hdrLen = teidCb->preEncodedHdr.cnt;
558 if(msgHdr->extHdr.pdcpNmb.pres)
560 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] |= EGTP_MASK_BIT3;
561 teidCb->preEncodedHdr.hdr[hdrLen] = EGTP_EXT_HDR_PDCP_TYPE;
562 teidCb->preEncodedHdr.hdr[--hdrLen] = 1;
563 teidCb->preEncodedHdr.hdr[--hdrLen] = GetHiByte(msgHdr->extHdr.pdcpNmb.val);
564 teidCb->preEncodedHdr.hdr[--hdrLen] = GetLoByte(msgHdr->extHdr.pdcpNmb.val);
565 teidCb->preEncodedHdr.hdr[--hdrLen] = 0;
569 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] &= ~(EGTP_MASK_BIT3);
572 SFndLenMsg(egtpMsg.msg, &tPduSize);
574 /*Adjust the header to fill the correct length*/
575 msgLen = tPduSize + (EGTP_MAX_HDR_LEN - hdrLen) - 0x08;
577 /***********************************************
578 * Fill the length field of the message header *
579 ***********************************************/
580 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 3] = (U8)GetHiByte(msgLen);
581 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 4] = (U8)GetLoByte(msgLen);
583 /*Update the sequence number*/
584 if(egtpMsg.msgHdr.seqNum.pres)
586 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] |= (EGTP_MASK_BIT2);
587 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 9] = (U8)GetHiByte(egtpMsg.msgHdr.seqNum.val);
588 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 10] = (U8)GetLoByte(egtpMsg.msgHdr.seqNum.val);
592 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] &= ~(EGTP_MASK_BIT2);
595 DU_LOG("\nEGTP : UL Data buffer before encoding header");
596 SPrntMsg(egtpMsg.msg, 0, 0);
598 SAddPreMsgMult(&teidCb->preEncodedHdr.hdr[hdrLen], (EGTP_MAX_HDR_LEN - hdrLen), egtpMsg.msg);
601 DU_LOG("\nEGTP : UL Data buffer after encoding header");
602 SPrntMsg(egtpMsg.msg, 0, 0);
605 egtpSendMsg(egtpMsg.msg);
606 SPutMsg(egtpMsg.msg);
611 /*******************************************************************
613 * @brief Encodes outgoing message
617 * Function : egtpEncodeMsg
620 * Encodes EGTP message to be sent
622 * @params[in] EGTP message
624 * @return ROK - success
627 * ****************************************************************/
628 S16 egtpEncodeHdr(U8 *preEncodedHdr, EgtpMsgHdr *preDefHdr, U8 *hdrIdx)
630 U8 tmpByte = 0; /* Stores one byte of data for enc */
631 U8 cnt = EGTP_MAX_HDR_LEN; /* Stores the position */
632 Bool extPres = FALSE; /* Flag for indication of S, E or P presense flag */
635 /* Encoding header */
636 tmpByte |= EGTP_MASK_BIT6; /* Setting 6th LSB of 1st byte as version */
637 tmpByte |= EGTP_MASK_BIT5; /* Setting 5th LSB of 1st byte as protocol type */
639 if(preDefHdr->extHdr.udpPort.pres || preDefHdr->extHdr.pdcpNmb.pres)
641 tmpByte |= EGTP_MASK_BIT3; /* Setting 3rd LSB of 1st byte if Extension heaeder is present */
644 if(preDefHdr->seqNum.pres)
646 tmpByte |= EGTP_MASK_BIT2;
649 if(preDefHdr->nPdu.pres)
651 tmpByte |= EGTP_MASK_BIT1;
654 if((tmpByte & EGTP_MASK_BIT1) || (tmpByte & EGTP_MASK_BIT2)||(tmpByte & EGTP_MASK_BIT3))
659 preEncodedHdr[--cnt] = tmpByte;
660 preEncodedHdr[--cnt] = preDefHdr->msgType;
662 /* Encode Tunnel endpoint */
663 preEncodedHdr[--cnt] = 0;
664 preEncodedHdr[--cnt] = 0;
665 nwWord = (U16)(GetHiWord(preDefHdr->teId));
666 preEncodedHdr[--cnt] = (U8)(GetHiByte(nwWord));
667 preEncodedHdr[--cnt] = (U8)(GetLoByte(nwWord));
668 nwWord = (U16)(GetLoWord(preDefHdr->teId));
669 preEncodedHdr[--cnt] = (U8)(GetHiByte(nwWord));
670 preEncodedHdr[--cnt] = (U8)(GetLoByte(nwWord));
672 /* Encode sequence number */
673 if(preDefHdr->seqNum.pres)
675 preEncodedHdr[--cnt] = GetHiByte(preDefHdr->seqNum.val);
676 preEncodedHdr[--cnt] = GetLoByte(preDefHdr->seqNum.val);
680 preEncodedHdr[--cnt] = 0;
681 preEncodedHdr[--cnt] = 0;
684 /* Encode nPdu number */
685 if(preDefHdr->nPdu.pres)
687 preEncodedHdr[--cnt] = preDefHdr->nPdu.val;
691 preEncodedHdr[--cnt] = 0;
694 if(preDefHdr->extHdr.udpPort.pres)
696 preEncodedHdr[--cnt] = EGTP_EXT_HDR_UDP_TYPE;
697 preEncodedHdr[--cnt] = 1;
698 preEncodedHdr[--cnt] = GetHiByte(preDefHdr->extHdr.udpPort.val);
699 preEncodedHdr[--cnt] = GetLoByte(preDefHdr->extHdr.udpPort.val);
702 if(preDefHdr->extHdr.pdcpNmb.pres)
704 preEncodedHdr[--cnt] = EGTP_EXT_HDR_PDCP_TYPE;
705 preEncodedHdr[--cnt] = 1;
706 preEncodedHdr[--cnt] = GetHiByte(preDefHdr->extHdr.pdcpNmb.val);
707 preEncodedHdr[--cnt] = GetLoByte(preDefHdr->extHdr.pdcpNmb.val);
710 if(tmpByte & EGTP_MASK_BIT3)
712 preEncodedHdr[--cnt] = 0;
716 preEncodedHdr[--cnt] = 0;
721 } /* egtpEncodeHdr */
723 /*******************************************************************
725 * @brief Sends message over UDP
729 * Function : egtpSendMsg
732 * Sends message over UDP
734 * @params[in] Message Buffer
735 * @return ROK - success
738 * ****************************************************************/
739 S16 egtpSendMsg(Buffer *mBuf)
746 info.region = DU_APP_MEM_REGION;
749 dstAddr.port = EGTP_DFLT_PORT;
750 dstAddr.address = egtpCb.dstCb.dstIp;
752 ret = cmInetSendMsg(&(egtpCb.dstCb.sendTptSrvr.sockFd), &dstAddr, &info, mBuf, &txLen, CM_INET_NO_FLAG);
753 if(ret != ROK && ret != RWOULDBLOCK)
755 DU_LOG("\nEGTP : Failed sending the message");
759 DU_LOG("\nEGTP : Message Sent");
764 /*******************************************************************
766 * @brief Handles Slot Indication from PHY
770 * Function : egtpSlotInd
773 * Handles TTI Indication from PHY
776 * @return ROK - success
779 * ****************************************************************/
786 /*******************************************************************
788 * @brief Receives EGTP message from UDP socket
792 * Function : egtpRecvMsg
795 * Receive incoming messages from UDP socket
798 * @return ROK - success
801 * ****************************************************************/
805 U8 ret; /* Return value */
806 U8 nMsg; /* Number of messages to read from UDP socked */
807 MsgLen bufLen; /* Length of received buffer */
808 Buffer *recvBuf; /* Received buffer */
809 CmInetAddr fromAddr; /* Egtp data sender address */
810 CmInetMemInfo memInfo; /* Buffer allocation info */
813 DU_LOG("\nEGTP : Received Slot Indication");
816 memInfo.region = DU_APP_MEM_REGION;
817 memInfo.pool = DU_POOL;
819 fromAddr.port = egtpCb.dstCb.dstPort;
820 fromAddr.address = egtpCb.dstCb.dstIp;
822 while(nMsg < EGTP_MAX_MSG_RECV)
825 ret = cmInetRecvMsg(&(egtpCb.recvTptSrvr.sockFd), &fromAddr, &memInfo, &recvBuf, &bufLen, CM_INET_NO_FLAG);
826 if(ret == ROK && recvBuf != NULLP)
828 DU_LOG("\nEGTP : Received DL Message[%d]\n", nMsg+1);
829 SPrntMsg(recvBuf, 0 ,0);
830 egtpHdlRecvData(recvBuf);
838 S16 egtpHdlRecvData(Buffer *mBuf)
842 /* Decode EGTP header */
843 egtpDecodeHdr(mBuf, &egtpMsg);
845 /* TODO : Send received message to RLC */
846 duHdlEgtpDlData(&egtpMsg);
851 S16 egtpDecodeHdr(Buffer *mBuf, EgtpMsg *egtpMsg)
853 U8 tmpByte[5]; /* Holds 5 byte of data after Decoding */
854 U8 version = 0; /* Holds the version type, decoded */
855 MsgLen msgLen = 0; /* Holds the msgLen from the Hdr */
856 MsgLen bufLen = 0; /* Holds the total buffer length */
857 U8 extHdrType = 0; /* Holds the Extension hdr type */
858 U8 extHdrLen = 0; /* Extension hdr length */
859 Bool extPres = FALSE; /* Flag for indication of S, E or P presense flag */
861 SFndLenMsg(mBuf, &bufLen);
863 /* Decode first byte and storing in temporary variable */
864 SRemPreMsg(&tmpByte[0], mBuf);
866 /* Extracting version fro 1st byte */
867 version = tmpByte[0] >> 5;
869 DU_LOG("\nEGTP : Version %d", version);
871 /* Decode message type */
872 SRemPreMsg((Data*)&(egtpMsg->msgHdr.msgType), mBuf);
873 DU_LOG("\nEGTP : msgType %d", egtpMsg->msgHdr.msgType);
875 /****************************************************************************
876 * Message length param is 2 bytes. So decode next 2 bytes from msg hdr and
877 * performing OR operation on these two bytes to calculate message length
878 ***************************************************************************/
879 SRemPreMsg(&tmpByte[1], mBuf);
880 SRemPreMsg(&tmpByte[2], mBuf);
881 msgLen = (tmpByte[1] << 8) | tmpByte[2];
882 DU_LOG("\nEGTP : msgLen %d", msgLen);
885 /****************************************************************************
886 * Tunnel id param is 4 bytes. So decode next 4 bytes from msg hdr and
887 * perform OR operation on these 4 bytes to calculate tunnel id
888 ***************************************************************************/
889 SRemPreMsg(&tmpByte[1], mBuf);
890 SRemPreMsg(&tmpByte[2], mBuf);
891 SRemPreMsg(&tmpByte[3], mBuf);
892 SRemPreMsg(&tmpByte[4], mBuf);
893 egtpMsg->msgHdr.teId = (tmpByte[1] << 24) | (tmpByte[2] << 16) | (tmpByte[3] << 8) | tmpByte[4];
894 DU_LOG("\nEGTP : teId %d",egtpMsg->msgHdr.teId);
897 /* If any one of S, E or PN flag is set, set extension present as true. */
898 if((tmpByte[0] & EGTP_MASK_BIT1) || (tmpByte[0] & EGTP_MASK_BIT2)||(tmpByte[0] & EGTP_MASK_BIT3))
903 /* Decode sequence number, if S flag is set in first byte */
904 if (tmpByte[0] & EGTP_MASK_BIT2)
906 /************************************************************************
907 * Sequence num is 2 bytes. So decode next 2 bytes from msg hdr and
908 * perform OR operation on them
909 ************************************************************************/
910 egtpMsg->msgHdr.seqNum.pres = TRUE;
911 SRemPreMsg(&tmpByte[1], mBuf);
912 SRemPreMsg(&tmpByte[2], mBuf);
913 egtpMsg->msgHdr.seqNum.val = (tmpByte[1] << 8) | tmpByte[2];
915 /****************************************************************************
916 * If extPres is true, but S bit is not set, implies, either of PN or E bit
917 * was set during Encode so accordingly extract Byte fields for seqNum anyway
918 ***************************************************************************/
921 /*************************************************************************
922 * Sequence num is 2 bytes. So decode next 2 bytes from msg hdr and
923 * perform OR operation on them
924 ************************************************************************/
925 egtpMsg->msgHdr.seqNum.pres = 0;
926 SRemPreMsg(&tmpByte[1], mBuf);
927 SRemPreMsg(&tmpByte[2], mBuf);
928 egtpMsg->msgHdr.seqNum.val = (tmpByte[1] << 8) | tmpByte[2];
931 /* Decode N-PDU number if present flag is set */
932 if (tmpByte[0] & EGTP_MASK_BIT1)
934 egtpMsg->msgHdr.nPdu.pres = TRUE;
935 SRemPreMsg(&(egtpMsg->msgHdr.nPdu.val), mBuf);
937 /****************************************************************************
938 * If extPres is true, but PN bit is not set, implies, either of S or E bit
939 * was set during Encode. Aaccordingly extract Byte fields of N-PDU num anyway
940 ***************************************************************************/
943 egtpMsg->msgHdr.nPdu.pres = TRUE;
944 SRemPreMsg(&(egtpMsg->msgHdr.nPdu.val), mBuf);
947 /* If E flag is set in first byte, decode extension header */
948 if(tmpByte[0] & EGTP_MASK_BIT3)
950 SRemPreMsg(&extHdrType, mBuf);
951 while( 0 != extHdrType)
955 case EGTP_EXT_HDR_UDP_TYPE:
957 SRemPreMsg(&extHdrLen, mBuf);
958 if(extHdrLen == 0x01)
960 /************************************************************
961 * UDP Port is 2 bytes. So decode next 2 bytes from msg hdr
962 * and perform OR operation on them
963 *************************************************************/
964 egtpMsg->msgHdr.extHdr.udpPort.pres = TRUE;
965 SRemPreMsg(&tmpByte[1], mBuf);
966 SRemPreMsg(&tmpByte[2], mBuf);
967 egtpMsg->msgHdr.extHdr.udpPort.val = (tmpByte[1] << 8) | tmpByte[2];
972 case EGTP_EXT_HDR_PDCP_TYPE:
974 SRemPreMsg(&extHdrLen, mBuf);
975 if(extHdrLen == 0x01)
977 /*************************************************************
978 * PDCP num is 2 bytes. So decode next 2 bytes from msg hdr
979 * and perform OR operation on them
980 ************************************************************/
981 egtpMsg->msgHdr.extHdr.pdcpNmb.pres = TRUE;
982 SRemPreMsg(&tmpByte[1], mBuf);
983 SRemPreMsg(&tmpByte[2], mBuf);
984 egtpMsg->msgHdr.extHdr.pdcpNmb.val = (tmpByte[1] << 8) | tmpByte[2];
988 } /* End of switch */
990 SRemPreMsg(&extHdrType, mBuf);
994 /****************************************************************************
995 * If extPres is true, but E bit is not set, implies, either of PN or S bit
996 * was set during Encode so accordingly extract Byte fields for extension
998 ***************************************************************************/
1001 SRemPreMsg(&extHdrType, mBuf);
1004 egtpMsg->msg = mBuf;
1006 DU_LOG("\nEGTP : DL Data Buffer after decoding header ");
1007 SPrntMsg(mBuf, 0, 0);
1009 /* Forward the data to duApp/RLC */