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 */
24 /* Global variable declaration */
27 /**************************************************************************
28 * @brief Task Initiation callback function.
32 * Function : egtpActvInit
35 * This function is supplied as one of parameters during EGTP's
36 * task registration. SSI will invoke this function once, after
37 * it creates and attaches this TAPA Task to a system task.
39 * @param[in] Ent entity, the entity ID of this task.
40 * @param[in] Inst inst, the instance ID of this task.
41 * @param[in] Region region, the region ID registered for memory
43 * @param[in] Reason reason.
44 * @return ROK - success
46 ***************************************************************************/
47 S16 egtpActvInit(Ent entity, Inst inst, Region region, Reason reason)
49 DU_LOG("\n\nEGTP : Initializing");
51 cmMemset ((U8 *)&egtpCb, 0, sizeof(EgtpGlobalCb));
52 protType = CM_INET_PROTO_UDP;
58 /**************************************************************************
59 * @brief Task Activation callback function.
63 * Function : egtpActvTsk
66 * This function handles all EGTP messages received
67 * This API is registered with SSI during the
68 * Task Registration of DU APP.
70 * @param[in] Pst *pst, Post structure of the primitive.
71 * @param[in] Buffer *mBuf, Packed primitive parameters in the
73 * @return ROK - success
76 ***************************************************************************/
77 S16 egtpActvTsk(Pst *pst, Buffer *mBuf)
89 ret = cmUnpkEgtpCfgReq(egtpCfgReq, pst, mBuf);
94 ret = cmUnpkEgtpSrvOpenReq(egtpSrvOpenReq, pst, mBuf);
99 ret = cmUnpkEgtpTnlMgmtReq(egtpTnlMgmtReq, pst, mBuf);
104 ret = cmUnpkEgtpTTIInd(egtpTTIInd, pst, mBuf);
110 DU_LOG("\nEGTP : Invalid event %d", pst->event);
128 DU_LOG("\nEGTP : Invalid event %d", pst->event);
136 DU_LOG("\nEGTP : Invalid source entity %d", pst->srcEnt);
144 /**************************************************************************
145 * @brief EGTP server configuration
149 * Function : egtpCfgReq
152 * This function handles EGTP configuration request.
154 * @return ROK - success
157 * ***********************************************************************/
158 S16 egtpCfgReq(Pst *pst, EgtpConfig egtpCfg)
160 U8 ret; /* Return value */
161 Pst rspPst; /* Response Pst structure */
162 CmStatus cfgCfm; /* Configuration Confirm */
164 cmMemcpy((U8 *)&egtpCb.egtpCfg, (U8 *)&egtpCfg, (PTR)sizeof(EgtpConfig));
166 egtpCb.recvTptSrvr.addr.address = CM_INET_NTOH_U32(egtpCb.egtpCfg.localIp.ipV4Addr);
167 egtpCb.recvTptSrvr.addr.port = EGTP_DFLT_PORT;
169 egtpCb.dstCb.dstIp = CM_INET_NTOH_U32(egtpCb.egtpCfg.destIp.ipV4Addr);
170 egtpCb.dstCb.dstPort = egtpCb.egtpCfg.destPort;
171 egtpCb.dstCb.sendTptSrvr.addr.address = CM_INET_NTOH_U32(egtpCb.egtpCfg.localIp.ipV4Addr);
172 egtpCb.dstCb.sendTptSrvr.addr.port = egtpCb.egtpCfg.localPort;
173 egtpCb.dstCb.numTunn = 0;
175 ret = cmHashListInit(&(egtpCb.dstCb.teIdLst), 1024, sizeof(EgtpTeIdCb), FALSE, CM_HASH_KEYTYPE_U32MOD, DU_APP_MEM_REGION, DU_POOL);
179 DU_LOG("\nEGTP : TeId hash list initialization failed");
180 cfgCfm.status = LCM_PRIM_NOK;
181 cfgCfm.reason = LCM_REASON_HASHING_FAILED;
185 DU_LOG("\nEGTP : EGTP configuration successful");
186 cfgCfm.status = LCM_PRIM_OK;
187 cfgCfm.reason = LCM_REASON_NOT_APPL;
190 /* Fill response Pst */
191 egtpFillRspPst(pst, &rspPst);
192 rspPst.event = EVTCFGCFM;
194 cmPkEgtpCfgCfm(&rspPst, cfgCfm);
199 /**************************************************************************
200 * @brief Fills post structure to send response
204 * Function : egtpFillRspPst
207 * Fills post struture to send response
209 * @return ROK - success
213 * ***********************************************************************/
214 S16 egtpFillRspPst(Pst *pst, Pst *rspPst)
217 cmMemset((U8 *)rspPst, 0, sizeof(Pst));
218 rspPst->srcEnt = pst->dstEnt;
219 rspPst->srcInst = pst->dstInst;
220 rspPst->srcProcId = pst->dstProcId;
221 rspPst->dstEnt = pst->srcEnt;
222 rspPst->dstInst = pst->srcInst;
223 rspPst->dstProcId = pst->srcProcId;
224 rspPst->selector = DU_SELECTOR_LC;
225 rspPst->pool= DU_POOL;
230 /**************************************************************************
231 * @brief EGTP server open request
235 * Function : egtpSrvOpenReq
238 * This function handles EGTP open server request.
239 * It opens udp socket to receive/send msgs.
241 * @param[in] Pst *pst, post structure
242 * @return ROK - success
245 ***************************************************************************/
247 S16 egtpSrvOpenReq(Pst *pst)
250 U8 ret; /* Return value */
251 Pst rspPst; /* Response Pst structure */
252 CmStatus cfm; /* Confirmation status */
253 U8 sockType; /* Socket type */
255 DU_LOG("\nEGTP : Received EGTP open server request");
257 sockType = CM_INET_DGRAM;
259 /* Opening and Binding receiver socket */
260 if(ret = egtpSrvOpenPrc(sockType, &(egtpCb.recvTptSrvr)) != ROK)
262 DU_LOG("\nEGTP : Failed while opening receiver transport server");
266 /* Opening and Binding sender socket */
267 if(ret = egtpSrvOpenPrc(sockType, &(egtpCb.dstCb.sendTptSrvr)) != ROK)
269 DU_LOG("\nEGTP : Failed while opening sender transport server");
273 DU_LOG("\nEGTP : Receiver socket[%d] and Sender socket[%d] open", egtpCb.recvTptSrvr.sockFd.fd, egtpCb.dstCb.sendTptSrvr.sockFd.fd);
275 /* Filling and seing response */
276 cfm.status = LCM_PRIM_OK;
277 cfm.reason = LCM_REASON_NOT_APPL;
279 egtpFillRspPst(pst, &rspPst);
280 rspPst.event = EVTSRVOPENCFM;
281 cmPkEgtpSrvOpenCfm(&rspPst, cfm);
286 /*******************************************************************
288 * @brief Processing Sever open request
292 * Function : egtpSrvOpenPrc
298 * @return ROK - success
301 * ****************************************************************/
303 S16 egtpSrvOpenPrc(U8 sockType, EgtpTptSrvr *server)
307 if(ret = (cmInetSocket(sockType, &(server->sockFd), protType)) != ROK)
309 DU_LOG("\nEGTP : Failed to open UDP socket");
313 if(ret = cmInetBind(&(server->sockFd), &(server->addr)) != ROK)
315 DU_LOG("\nEGTP : Failed to bind socket");
322 /**************************************************************************
323 * @brief EGTP tunnel management request
327 * Function : egtpTnlMgmtReq
330 * This function handles EGTP tunnel managament request
332 * @param[in] Pst *pst, post structure
333 * Tunnel Eveny structure
334 * @return ROK - success
338 * ***************************************************************************/
339 S16 egtpTnlMgmtReq(Pst *pst, EgtpTnlEvt tnlEvt)
344 DU_LOG("\nEGTP : Received tunnel management request");
345 switch(tnlEvt.action)
347 case EGTP_TNL_MGMT_ADD:
349 ret = egtpTnlAdd(tnlEvt);
352 case EGTP_TNL_MGMT_MOD:
354 ret = egtpTnlMod(tnlEvt);
357 case EGTP_TNL_MGMT_DEL:
359 ret = egtpTnlDel(tnlEvt);
364 DU_LOG("\nEGTP : Invalid tunnel management action[%d]", tnlEvt.action);
365 ret = LCM_REASON_INVALID_ACTION;
371 tnlEvt.cfmStatus.status = LCM_PRIM_OK;
372 tnlEvt.cfmStatus.reason = LCM_REASON_NOT_APPL;
376 tnlEvt.cfmStatus.status = LCM_PRIM_NOK;
377 tnlEvt.cfmStatus.reason = ret;
380 DU_LOG("\nEGTP : Sending Tunnel management confirmation");
381 egtpFillRspPst(pst, &rspPst);
382 rspPst.event = EVTTNLMGMTCFM;
383 cmPkEgtpTnlMgmtCfm(&rspPst, tnlEvt);
388 /**************************************************************************
389 * @brief EGTP tunnel addition
393 * Function : egtpTnlAdd
396 * This function handles EGTP tunnel addition
398 * @param[in] Tunnel Event structure
399 * @return ROK - success
402 * ***************************************************************************/
403 S16 egtpTnlAdd(EgtpTnlEvt tnlEvt)
406 EgtpTeIdCb *teidCb; /* Tunnel endpoint control block */
407 EgtpMsgHdr preDefHdr; /* pre-define header for this tunnel */
409 DU_LOG("\nEGTP : Tunnel addition : LocalTeid[%d] Remote Teid[%d]", tnlEvt.lclTeid, tnlEvt.remTeid);
411 ret = SGetSBuf(DU_APP_MEM_REGION, DU_POOL, (Data **)&teidCb, (Size)sizeof(EgtpTeIdCb));
414 DU_LOG("\nEGTP : Memory allocation failed");
415 RETVALUE(LCM_REASON_MEM_NOAVAIL);
418 cmMemset((U8 *)teidCb, 0, sizeof(EgtpTeIdCb));
419 teidCb->teId = tnlEvt.lclTeid;
420 teidCb->remTeId = tnlEvt.remTeid;
422 ret = cmHashListInsert(&(egtpCb.dstCb.teIdLst), (PTR)teidCb, (U8 *)&(teidCb->teId), sizeof(U32));
425 DU_LOG("\nEGTP : Failed to insert in hash list");
426 SPutSBuf(DU_APP_MEM_REGION, DU_POOL, (Data *)teidCb, (Size)sizeof(EgtpTeIdCb));
427 RETVALUE(LCM_REASON_HASHING_FAILED);
429 egtpCb.dstCb.numTunn++;
431 /* Encoding pre-defined header */
432 cmMemset((U8*)&preDefHdr, 0, sizeof(EgtpMsgHdr));
433 preDefHdr.msgType = EGTPU_MSG_GPDU;
434 preDefHdr.teId = teidCb->remTeId;
435 preDefHdr.extHdr.pdcpNmb.pres = FALSE;
436 preDefHdr.extHdr.udpPort.pres = FALSE;
437 preDefHdr.nPdu.pres = FALSE;
439 egtpEncodeHdr((U8 *)teidCb->preEncodedHdr.hdr, &preDefHdr, &(teidCb->preEncodedHdr.cnt));
444 /**************************************************************************
445 * @brief EGTP tunnel modification
449 * Function : egtpTnlMod
452 * This function handles EGTP tunnel modification
454 * @param[in] Tunnel Event structure
455 * @return ROK - success
458 * ***************************************************************************/
459 S16 egtpTnlMod(EgtpTnlEvt tnlEvt)
463 EgtpTeIdCb *teidCb = NULLP;
465 printf("\nTunnel modification : LocalTeid[%d] Remote Teid[%d]", tnlEvt.lclTeid, tnlEvt.remTeid);
467 cmHashListFind(&(egtpCb.dstCb.teIdLst), (U8 *)&(tnlEvt.teId), sizeof(U32), 0, (PTR *)&teidCb);
470 printf("\nTunnel id not found");
474 teidCb->teId = tnlEvt.lclTeid;
475 teidCb->remTeId = tnlEvt.remTeid;
480 /**************************************************************************
481 * @brief EGTP tunnel deletion
485 * Function : egtpTnlDel
488 * This function handles EGTP tunnel deletion
490 * @param[in] Tunnel Event structure
491 * @return ROK - success
494 * ***************************************************************************/
495 S16 egtpTnlDel(EgtpTnlEvt tnlEvt)
497 EgtpTeIdCb *teidCb = NULLP;
499 DU_LOG("\nEGTP : Tunnel deletion : Local Teid[%d] Remote Teid[%d]", tnlEvt.lclTeid, tnlEvt.remTeid);
501 cmHashListFind(&(egtpCb.dstCb.teIdLst), (U8 *)&(tnlEvt.lclTeid), sizeof(U32), 0, (PTR *)&teidCb);
504 DU_LOG("\nEGTP : Tunnel id[%d] not configured", tnlEvt.lclTeid);
505 RETVALUE(LCM_REASON_INVALID_PAR_VAL);
508 cmHashListDelete(&(egtpCb.dstCb.teIdLst), (PTR)teidCb);
509 SPutSBuf(DU_APP_MEM_REGION, DU_POOL, (Data *)teidCb, (Size)sizeof(EgtpTeIdCb));
510 egtpCb.dstCb.numTunn--;
515 /*******************************************************************
517 * @brief Handles data indication
521 * Function : EgtpHdlDatInd
524 * Handles incoming data from peer to be passed
528 * @return ROK - success
531 * ****************************************************************/
532 S16 egtpHdlDatInd(EgtpMsg egtpMsg)
534 EgtpTeIdCb *teidCb = NULLP;
540 DU_LOG("\nEGTP : Received Data Indication");
542 cmHashListFind(&(egtpCb.dstCb.teIdLst), (U8 *)&(egtpMsg.msgHdr.teId), sizeof(U32), 0, (PTR *)&teidCb);
545 DU_LOG("\nEGTP : Tunnel id[%d] not configured", egtpMsg.msgHdr.teId);
546 RETVALUE(LCM_REASON_INVALID_PAR_VAL);
549 msgHdr = &(egtpMsg.msgHdr);
551 hdrLen = teidCb->preEncodedHdr.cnt;
553 if(msgHdr->extHdr.pdcpNmb.pres)
555 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] |= EGTP_MASK_BIT3;
556 teidCb->preEncodedHdr.hdr[hdrLen] = EGTP_EXT_HDR_PDCP_TYPE;
557 teidCb->preEncodedHdr.hdr[--hdrLen] = 1;
558 teidCb->preEncodedHdr.hdr[--hdrLen] = GetHiByte(msgHdr->extHdr.pdcpNmb.val);
559 teidCb->preEncodedHdr.hdr[--hdrLen] = GetLoByte(msgHdr->extHdr.pdcpNmb.val);
560 teidCb->preEncodedHdr.hdr[--hdrLen] = 0;
564 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] &= ~(EGTP_MASK_BIT3);
567 SFndLenMsg(egtpMsg.msg, &tPduSize);
569 /*Adjust the header to fill the correct length*/
570 msgLen = tPduSize + (EGTP_MAX_HDR_LEN - hdrLen) - 0x08;
572 /***********************************************
573 * Fill the length field of the message header *
574 ***********************************************/
575 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 3] = (U8)GetHiByte(msgLen);
576 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 4] = (U8)GetLoByte(msgLen);
578 /*Update the sequence number*/
579 if(egtpMsg.msgHdr.seqNum.pres)
581 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] |= (EGTP_MASK_BIT2);
582 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 9] = (U8)GetHiByte(egtpMsg.msgHdr.seqNum.val);
583 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 10] = (U8)GetLoByte(egtpMsg.msgHdr.seqNum.val);
587 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] &= ~(EGTP_MASK_BIT2);
590 DU_LOG("\nEGTP : Data buffer before encoding header");
591 SPrntMsg(egtpMsg.msg, 0, 0);
593 SAddPreMsgMult(&teidCb->preEncodedHdr.hdr[hdrLen], (EGTP_MAX_HDR_LEN - hdrLen), egtpMsg.msg);
596 DU_LOG("\nEGTP : Data buffer after encoding header");
597 SPrntMsg(egtpMsg.msg, 0, 0);
600 egtpSendMsg(egtpMsg.msg);
601 SPutMsg(egtpMsg.msg);
606 /*******************************************************************
608 * @brief Encodes outgoing message
612 * Function : egtpEncodeMsg
615 * Encodes EGTP message to be sent
617 * @params[in] EGTP message
619 * @return ROK - success
622 * ****************************************************************/
623 S16 egtpEncodeHdr(U8 *preEncodedHdr, EgtpMsgHdr *preDefHdr, U8 *hdrIdx)
625 U8 tmpByte = 0; /* Stores one byte of data for enc */
626 U8 cnt = EGTP_MAX_HDR_LEN; /* Stores the position */
627 Bool extPres = FALSE; /* Flag for indication of S, E or P presense flag */
630 /* Encoding header */
631 tmpByte |= EGTP_MASK_BIT6; /* Setting 6th LSB of 1st byte as version */
632 tmpByte |= EGTP_MASK_BIT5; /* Setting 5th LSB of 1st byte as protocol type */
634 if(preDefHdr->extHdr.udpPort.pres || preDefHdr->extHdr.pdcpNmb.pres)
636 tmpByte |= EGTP_MASK_BIT3; /* Setting 3rd LSB of 1st byte if Extension heaeder is present */
639 if(preDefHdr->seqNum.pres)
641 tmpByte |= EGTP_MASK_BIT2;
644 if(preDefHdr->nPdu.pres)
646 tmpByte |= EGTP_MASK_BIT1;
649 if((tmpByte & EGTP_MASK_BIT1) || (tmpByte & EGTP_MASK_BIT2)||(tmpByte & EGTP_MASK_BIT3))
654 preEncodedHdr[--cnt] = tmpByte;
655 preEncodedHdr[--cnt] = preDefHdr->msgType;
657 /* Encode Tunnel endpoint */
658 preEncodedHdr[--cnt] = 0;
659 preEncodedHdr[--cnt] = 0;
660 nwWord = (U16)(GetHiWord(preDefHdr->teId));
661 preEncodedHdr[--cnt] = (U8)(GetHiByte(nwWord));
662 preEncodedHdr[--cnt] = (U8)(GetLoByte(nwWord));
663 nwWord = (U16)(GetLoWord(preDefHdr->teId));
664 preEncodedHdr[--cnt] = (U8)(GetHiByte(nwWord));
665 preEncodedHdr[--cnt] = (U8)(GetLoByte(nwWord));
667 /* Encode sequence number */
668 if(preDefHdr->seqNum.pres)
670 preEncodedHdr[--cnt] = GetHiByte(preDefHdr->seqNum.val);
671 preEncodedHdr[--cnt] = GetLoByte(preDefHdr->seqNum.val);
675 preEncodedHdr[--cnt] = 0;
676 preEncodedHdr[--cnt] = 0;
679 /* Encode nPdu number */
680 if(preDefHdr->nPdu.pres)
682 preEncodedHdr[--cnt] = preDefHdr->nPdu.val;
686 preEncodedHdr[--cnt] = 0;
689 if(preDefHdr->extHdr.udpPort.pres)
691 preEncodedHdr[--cnt] = EGTP_EXT_HDR_UDP_TYPE;
692 preEncodedHdr[--cnt] = 1;
693 preEncodedHdr[--cnt] = GetHiByte(preDefHdr->extHdr.udpPort.val);
694 preEncodedHdr[--cnt] = GetLoByte(preDefHdr->extHdr.udpPort.val);
697 if(preDefHdr->extHdr.pdcpNmb.pres)
699 preEncodedHdr[--cnt] = EGTP_EXT_HDR_PDCP_TYPE;
700 preEncodedHdr[--cnt] = 1;
701 preEncodedHdr[--cnt] = GetHiByte(preDefHdr->extHdr.pdcpNmb.val);
702 preEncodedHdr[--cnt] = GetLoByte(preDefHdr->extHdr.pdcpNmb.val);
705 if(tmpByte & EGTP_MASK_BIT3)
707 preEncodedHdr[--cnt] = 0;
711 preEncodedHdr[--cnt] = 0;
716 } /* egtpEncodeHdr */
718 /*******************************************************************
720 * @brief Sends message over UDP
724 * Function : egtpSendMsg
727 * Sends message over UDP
729 * @params[in] Message Buffer
730 * @return ROK - success
733 * ****************************************************************/
734 S16 egtpSendMsg(Buffer *mBuf)
741 info.region = DU_APP_MEM_REGION;
744 dstAddr.port = EGTP_DFLT_PORT;
745 dstAddr.address = egtpCb.dstCb.dstIp;
747 ret = cmInetSendMsg(&(egtpCb.dstCb.sendTptSrvr.sockFd), &dstAddr, &info, mBuf, &txLen, CM_INET_NO_FLAG);
748 if(ret != ROK && ret != RWOULDBLOCK)
750 DU_LOG("\nEGTP : Failed sending the message");
754 DU_LOG("\nEGTP : Message Sent");
759 /*******************************************************************
761 * @brief Handles TTI Indication from PHY
765 * Function : egtpTTIInd
768 * Handles TTI Indication from PHY
771 * @return ROK - success
774 * ****************************************************************/
781 /*******************************************************************
783 * @brief Receives EGTP message from UDP socket
787 * Function : egtpRecvMsg
790 * Receive incoming messages from UDP socket
793 * @return ROK - success
796 * ****************************************************************/
800 U8 ret; /* Return value */
801 U8 nMsg; /* Number of messages to read from UDP socked */
802 MsgLen bufLen; /* Length of received buffer */
803 Buffer *recvBuf; /* Received buffer */
804 CmInetAddr fromAddr; /* Egtp data sender address */
805 CmInetMemInfo memInfo; /* Buffer allocation info */
808 DU_LOG("\nEGTP : Received TTI Indication");
811 memInfo.region = DU_APP_MEM_REGION;
812 memInfo.pool = DU_POOL;
814 fromAddr.port = egtpCb.dstCb.dstPort;
815 fromAddr.address = egtpCb.dstCb.dstIp;
817 while(nMsg < EGTP_MAX_MSG_RECV)
820 ret = cmInetRecvMsg(&(egtpCb.recvTptSrvr.sockFd), &fromAddr, &memInfo, &recvBuf, &bufLen, CM_INET_NO_FLAG);
821 if(ret == ROK && recvBuf != NULLP)
823 DU_LOG("\nEGTP : Received Message[%d]\n", nMsg+1);
824 SPrntMsg(recvBuf, 0 ,0);
825 egtpHdlRecvData(recvBuf);
833 S16 egtpHdlRecvData(Buffer *mBuf)
837 /* Decode EGTP header */
838 egtpDecodeHdr(mBuf, &egtpMsg);
840 /* TODO : Send received message to RLC */
845 S16 egtpDecodeHdr(Buffer *mBuf, EgtpMsg *egtpMsg)
847 U8 tmpByte[5]; /* Holds 5 byte of data after Decoding */
848 U8 version = 0; /* Holds the version type, decoded */
849 MsgLen msgLen = 0; /* Holds the msgLen from the Hdr */
850 MsgLen bufLen = 0; /* Holds the total buffer length */
851 U8 extHdrType = 0; /* Holds the Extension hdr type */
852 U8 extHdrLen = 0; /* Extension hdr length */
853 Bool extPres = FALSE; /* Flag for indication of S, E or P presense flag */
855 SFndLenMsg(mBuf, &bufLen);
857 /* Decode first byte and storing in temporary variable */
858 SRemPreMsg(&tmpByte[0], mBuf);
860 /* Extracting version fro 1st byte */
861 version = tmpByte[0] >> 5;
863 DU_LOG("\nEGTP : Version %d", version);
865 /* Decode message type */
866 SRemPreMsg((Data*)&(egtpMsg->msgHdr.msgType), mBuf);
867 DU_LOG("\nEGTP : msgType %d", egtpMsg->msgHdr.msgType);
869 /****************************************************************************
870 * Message length param is 2 bytes. So decode next 2 bytes from msg hdr and
871 * performing OR operation on these two bytes to calculate message length
872 ***************************************************************************/
873 SRemPreMsg(&tmpByte[1], mBuf);
874 SRemPreMsg(&tmpByte[2], mBuf);
875 msgLen = (tmpByte[1] << 8) | tmpByte[2];
876 DU_LOG("\nEGTP : msgLen %d", msgLen);
879 /****************************************************************************
880 * Tunnel id param is 4 bytes. So decode next 4 bytes from msg hdr and
881 * perform OR operation on these 4 bytes to calculate tunnel id
882 ***************************************************************************/
883 SRemPreMsg(&tmpByte[1], mBuf);
884 SRemPreMsg(&tmpByte[2], mBuf);
885 SRemPreMsg(&tmpByte[3], mBuf);
886 SRemPreMsg(&tmpByte[4], mBuf);
887 egtpMsg->msgHdr.teId = (tmpByte[1] << 24) | (tmpByte[2] << 16) | (tmpByte[3] << 8) | tmpByte[4];
888 DU_LOG("\nEGTP : teId %d",egtpMsg->msgHdr.teId);
891 /* If any one of S, E or PN flag is set, set extension present as true. */
892 if((tmpByte[0] & EGTP_MASK_BIT1) || (tmpByte[0] & EGTP_MASK_BIT2)||(tmpByte[0] & EGTP_MASK_BIT3))
897 /* Decode sequence number, if S flag is set in first byte */
898 if (tmpByte[0] & EGTP_MASK_BIT2)
900 /************************************************************************
901 * Sequence num is 2 bytes. So decode next 2 bytes from msg hdr and
902 * perform OR operation on them
903 ************************************************************************/
904 egtpMsg->msgHdr.seqNum.pres = TRUE;
905 SRemPreMsg(&tmpByte[1], mBuf);
906 SRemPreMsg(&tmpByte[2], mBuf);
907 egtpMsg->msgHdr.seqNum.val = (tmpByte[1] << 8) | tmpByte[2];
909 /****************************************************************************
910 * If extPres is true, but S bit is not set, implies, either of PN or E bit
911 * was set during Encode so accordingly extract Byte fields for seqNum anyway
912 ***************************************************************************/
915 /*************************************************************************
916 * Sequence num is 2 bytes. So decode next 2 bytes from msg hdr and
917 * perform OR operation on them
918 ************************************************************************/
919 egtpMsg->msgHdr.seqNum.pres = 0;
920 SRemPreMsg(&tmpByte[1], mBuf);
921 SRemPreMsg(&tmpByte[2], mBuf);
922 egtpMsg->msgHdr.seqNum.val = (tmpByte[1] << 8) | tmpByte[2];
925 /* Decode N-PDU number if present flag is set */
926 if (tmpByte[0] & EGTP_MASK_BIT1)
928 egtpMsg->msgHdr.nPdu.pres = TRUE;
929 SRemPreMsg(&(egtpMsg->msgHdr.nPdu.val), mBuf);
931 /****************************************************************************
932 * If extPres is true, but PN bit is not set, implies, either of S or E bit
933 * was set during Encode. Aaccordingly extract Byte fields of N-PDU num anyway
934 ***************************************************************************/
937 egtpMsg->msgHdr.nPdu.pres = TRUE;
938 SRemPreMsg(&(egtpMsg->msgHdr.nPdu.val), mBuf);
941 /* If E flag is set in first byte, decode extension header */
942 if(tmpByte[0] & EGTP_MASK_BIT3)
944 SRemPreMsg(&extHdrType, mBuf);
945 while( 0 != extHdrType)
949 case EGTP_EXT_HDR_UDP_TYPE:
951 SRemPreMsg(&extHdrLen, mBuf);
952 if(extHdrLen == 0x01)
954 /************************************************************
955 * UDP Port is 2 bytes. So decode next 2 bytes from msg hdr
956 * and perform OR operation on them
957 *************************************************************/
958 egtpMsg->msgHdr.extHdr.udpPort.pres = TRUE;
959 SRemPreMsg(&tmpByte[1], mBuf);
960 SRemPreMsg(&tmpByte[2], mBuf);
961 egtpMsg->msgHdr.extHdr.udpPort.val = (tmpByte[1] << 8) | tmpByte[2];
966 case EGTP_EXT_HDR_PDCP_TYPE:
968 SRemPreMsg(&extHdrLen, mBuf);
969 if(extHdrLen == 0x01)
971 /*************************************************************
972 * PDCP num is 2 bytes. So decode next 2 bytes from msg hdr
973 * and perform OR operation on them
974 ************************************************************/
975 egtpMsg->msgHdr.extHdr.pdcpNmb.pres = TRUE;
976 SRemPreMsg(&tmpByte[1], mBuf);
977 SRemPreMsg(&tmpByte[2], mBuf);
978 egtpMsg->msgHdr.extHdr.pdcpNmb.val = (tmpByte[1] << 8) | tmpByte[2];
982 } /* End of switch */
984 SRemPreMsg(&extHdrType, mBuf);
988 /****************************************************************************
989 * If extPres is true, but E bit is not set, implies, either of PN or S bit
990 * was set during Encode so accordingly extract Byte fields for extension
992 ***************************************************************************/
995 SRemPreMsg(&extHdrType, mBuf);
998 DU_LOG("\nEGTP : Data Buffer after decoding header ");
999 SPrntMsg(mBuf, 0, 0);
1001 /* Forward the data to duApp/RLC */