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 */
23 #include "du_ue_mgr.h"
25 /* Global variable declaration */
28 /**************************************************************************
29 * @brief Task Initiation callback function.
33 * Function : egtpActvInit
36 * This function is supplied as one of parameters during EGTP's
37 * task registration. SSI will invoke this function once, after
38 * it creates and attaches this TAPA Task to a system task.
40 * @param[in] Ent entity, the entity ID of this task.
41 * @param[in] Inst inst, the instance ID of this task.
42 * @param[in] Region region, the region ID registered for memory
44 * @param[in] Reason reason.
45 * @return ROK - success
47 ***************************************************************************/
48 S16 egtpActvInit(Ent entity, Inst inst, Region region, Reason reason)
50 DU_LOG("\n\nEGTP : Initializing");
52 cmMemset ((U8 *)&egtpCb, 0, sizeof(EgtpGlobalCb));
53 protType = CM_INET_PROTO_UDP;
59 /**************************************************************************
60 * @brief Task Activation callback function.
64 * Function : egtpActvTsk
67 * This function handles all EGTP messages received
68 * This API is registered with SSI during the
69 * Task Registration of DU APP.
71 * @param[in] Pst *pst, Post structure of the primitive.
72 * @param[in] Buffer *mBuf, Packed primitive parameters in the
74 * @return ROK - success
77 ***************************************************************************/
78 S16 egtpActvTsk(Pst *pst, Buffer *mBuf)
90 ret = cmUnpkEgtpCfgReq(egtpCfgReq, pst, mBuf);
95 ret = cmUnpkEgtpSrvOpenReq(egtpSrvOpenReq, pst, mBuf);
100 ret = cmUnpkEgtpTnlMgmtReq(egtpTnlMgmtReq, pst, mBuf);
105 ret = cmUnpkEgtpTTIInd(egtpTTIInd, pst, mBuf);
111 DU_LOG("\nEGTP : Invalid event %d", pst->event);
129 DU_LOG("\nEGTP : Invalid event %d", pst->event);
137 DU_LOG("\nEGTP : Invalid source entity %d", pst->srcEnt);
145 /**************************************************************************
146 * @brief EGTP server configuration
150 * Function : egtpCfgReq
153 * This function handles EGTP configuration request.
155 * @return ROK - success
158 * ***********************************************************************/
159 S16 egtpCfgReq(Pst *pst, EgtpConfig egtpCfg)
161 U8 ret; /* Return value */
162 Pst rspPst; /* Response Pst structure */
163 CmStatus cfgCfm; /* Configuration Confirm */
165 cmMemcpy((U8 *)&egtpCb.egtpCfg, (U8 *)&egtpCfg, (PTR)sizeof(EgtpConfig));
167 egtpCb.recvTptSrvr.addr.address = CM_INET_NTOH_U32(egtpCb.egtpCfg.localIp.ipV4Addr);
168 egtpCb.recvTptSrvr.addr.port = EGTP_DFLT_PORT;
170 egtpCb.dstCb.dstIp = CM_INET_NTOH_U32(egtpCb.egtpCfg.destIp.ipV4Addr);
171 egtpCb.dstCb.dstPort = egtpCb.egtpCfg.destPort;
172 egtpCb.dstCb.sendTptSrvr.addr.address = CM_INET_NTOH_U32(egtpCb.egtpCfg.localIp.ipV4Addr);
173 egtpCb.dstCb.sendTptSrvr.addr.port = egtpCb.egtpCfg.localPort;
174 egtpCb.dstCb.numTunn = 0;
176 ret = cmHashListInit(&(egtpCb.dstCb.teIdLst), 1024, sizeof(EgtpTeIdCb), FALSE, CM_HASH_KEYTYPE_U32MOD, DU_APP_MEM_REGION, DU_POOL);
180 DU_LOG("\nEGTP : TeId hash list initialization failed");
181 cfgCfm.status = LCM_PRIM_NOK;
182 cfgCfm.reason = LCM_REASON_HASHING_FAILED;
186 DU_LOG("\nEGTP : EGTP configuration successful");
187 cfgCfm.status = LCM_PRIM_OK;
188 cfgCfm.reason = LCM_REASON_NOT_APPL;
191 /* Fill response Pst */
192 egtpFillRspPst(pst, &rspPst);
193 rspPst.event = EVTCFGCFM;
195 cmPkEgtpCfgCfm(&rspPst, cfgCfm);
200 /**************************************************************************
201 * @brief Fills post structure to send response
205 * Function : egtpFillRspPst
208 * Fills post struture to send response
210 * @return ROK - success
214 * ***********************************************************************/
215 S16 egtpFillRspPst(Pst *pst, Pst *rspPst)
218 cmMemset((U8 *)rspPst, 0, sizeof(Pst));
219 rspPst->srcEnt = pst->dstEnt;
220 rspPst->srcInst = pst->dstInst;
221 rspPst->srcProcId = pst->dstProcId;
222 rspPst->dstEnt = pst->srcEnt;
223 rspPst->dstInst = pst->srcInst;
224 rspPst->dstProcId = pst->srcProcId;
225 rspPst->selector = DU_SELECTOR_LC;
226 rspPst->pool= DU_POOL;
231 /**************************************************************************
232 * @brief EGTP server open request
236 * Function : egtpSrvOpenReq
239 * This function handles EGTP open server request.
240 * It opens udp socket to receive/send msgs.
242 * @param[in] Pst *pst, post structure
243 * @return ROK - success
246 ***************************************************************************/
248 S16 egtpSrvOpenReq(Pst *pst)
251 U8 ret; /* Return value */
252 Pst rspPst; /* Response Pst structure */
253 CmStatus cfm; /* Confirmation status */
254 U8 sockType; /* Socket type */
256 DU_LOG("\nEGTP : Received EGTP open server request");
258 sockType = CM_INET_DGRAM;
260 /* Opening and Binding receiver socket */
261 if(ret = egtpSrvOpenPrc(sockType, &(egtpCb.recvTptSrvr)) != ROK)
263 DU_LOG("\nEGTP : Failed while opening receiver transport server");
267 /* Opening and Binding sender socket */
268 if(ret = egtpSrvOpenPrc(sockType, &(egtpCb.dstCb.sendTptSrvr)) != ROK)
270 DU_LOG("\nEGTP : Failed while opening sender transport server");
274 DU_LOG("\nEGTP : Receiver socket[%d] and Sender socket[%d] open", egtpCb.recvTptSrvr.sockFd.fd, egtpCb.dstCb.sendTptSrvr.sockFd.fd);
276 /* Filling and seing response */
277 cfm.status = LCM_PRIM_OK;
278 cfm.reason = LCM_REASON_NOT_APPL;
280 egtpFillRspPst(pst, &rspPst);
281 rspPst.event = EVTSRVOPENCFM;
282 cmPkEgtpSrvOpenCfm(&rspPst, cfm);
287 /*******************************************************************
289 * @brief Processing Sever open request
293 * Function : egtpSrvOpenPrc
299 * @return ROK - success
302 * ****************************************************************/
304 S16 egtpSrvOpenPrc(U8 sockType, EgtpTptSrvr *server)
308 if(ret = (cmInetSocket(sockType, &(server->sockFd), protType)) != ROK)
310 DU_LOG("\nEGTP : Failed to open UDP socket");
314 if(ret = cmInetBind(&(server->sockFd), &(server->addr)) != ROK)
316 DU_LOG("\nEGTP : Failed to bind socket");
323 /**************************************************************************
324 * @brief EGTP tunnel management request
328 * Function : egtpTnlMgmtReq
331 * This function handles EGTP tunnel managament request
333 * @param[in] Pst *pst, post structure
334 * Tunnel Eveny structure
335 * @return ROK - success
339 * ***************************************************************************/
340 S16 egtpTnlMgmtReq(Pst *pst, EgtpTnlEvt tnlEvt)
345 DU_LOG("\nEGTP : Received tunnel management request");
346 switch(tnlEvt.action)
348 case EGTP_TNL_MGMT_ADD:
350 ret = egtpTnlAdd(tnlEvt);
353 case EGTP_TNL_MGMT_MOD:
355 ret = egtpTnlMod(tnlEvt);
358 case EGTP_TNL_MGMT_DEL:
360 ret = egtpTnlDel(tnlEvt);
365 DU_LOG("\nEGTP : Invalid tunnel management action[%d]", tnlEvt.action);
366 ret = LCM_REASON_INVALID_ACTION;
372 tnlEvt.cfmStatus.status = LCM_PRIM_OK;
373 tnlEvt.cfmStatus.reason = LCM_REASON_NOT_APPL;
377 tnlEvt.cfmStatus.status = LCM_PRIM_NOK;
378 tnlEvt.cfmStatus.reason = ret;
381 DU_LOG("\nEGTP : Sending Tunnel management confirmation");
382 egtpFillRspPst(pst, &rspPst);
383 rspPst.event = EVTTNLMGMTCFM;
384 cmPkEgtpTnlMgmtCfm(&rspPst, tnlEvt);
389 /**************************************************************************
390 * @brief EGTP tunnel addition
394 * Function : egtpTnlAdd
397 * This function handles EGTP tunnel addition
399 * @param[in] Tunnel Event structure
400 * @return ROK - success
403 * ***************************************************************************/
404 S16 egtpTnlAdd(EgtpTnlEvt tnlEvt)
407 EgtpTeIdCb *teidCb; /* Tunnel endpoint control block */
408 EgtpMsgHdr preDefHdr; /* pre-define header for this tunnel */
410 DU_LOG("\nEGTP : Tunnel addition : LocalTeid[%d] Remote Teid[%d]", tnlEvt.lclTeid, tnlEvt.remTeid);
412 ret = SGetSBuf(DU_APP_MEM_REGION, DU_POOL, (Data **)&teidCb, (Size)sizeof(EgtpTeIdCb));
415 DU_LOG("\nEGTP : Memory allocation failed");
416 RETVALUE(LCM_REASON_MEM_NOAVAIL);
419 cmMemset((U8 *)teidCb, 0, sizeof(EgtpTeIdCb));
420 teidCb->teId = tnlEvt.lclTeid;
421 teidCb->remTeId = tnlEvt.remTeid;
423 ret = cmHashListInsert(&(egtpCb.dstCb.teIdLst), (PTR)teidCb, (U8 *)&(teidCb->teId), sizeof(U32));
426 DU_LOG("\nEGTP : Failed to insert in hash list");
427 SPutSBuf(DU_APP_MEM_REGION, DU_POOL, (Data *)teidCb, (Size)sizeof(EgtpTeIdCb));
428 RETVALUE(LCM_REASON_HASHING_FAILED);
430 egtpCb.dstCb.numTunn++;
432 /* Encoding pre-defined header */
433 cmMemset((U8*)&preDefHdr, 0, sizeof(EgtpMsgHdr));
434 preDefHdr.msgType = EGTPU_MSG_GPDU;
435 preDefHdr.teId = teidCb->remTeId;
436 preDefHdr.extHdr.pdcpNmb.pres = FALSE;
437 preDefHdr.extHdr.udpPort.pres = FALSE;
438 preDefHdr.nPdu.pres = FALSE;
440 egtpEncodeHdr((U8 *)teidCb->preEncodedHdr.hdr, &preDefHdr, &(teidCb->preEncodedHdr.cnt));
445 /**************************************************************************
446 * @brief EGTP tunnel modification
450 * Function : egtpTnlMod
453 * This function handles EGTP tunnel modification
455 * @param[in] Tunnel Event structure
456 * @return ROK - success
459 * ***************************************************************************/
460 S16 egtpTnlMod(EgtpTnlEvt tnlEvt)
464 EgtpTeIdCb *teidCb = NULLP;
466 printf("\nTunnel modification : LocalTeid[%d] Remote Teid[%d]", tnlEvt.lclTeid, tnlEvt.remTeid);
468 cmHashListFind(&(egtpCb.dstCb.teIdLst), (U8 *)&(tnlEvt.teId), sizeof(U32), 0, (PTR *)&teidCb);
471 printf("\nTunnel id not found");
475 teidCb->teId = tnlEvt.lclTeid;
476 teidCb->remTeId = tnlEvt.remTeid;
481 /**************************************************************************
482 * @brief EGTP tunnel deletion
486 * Function : egtpTnlDel
489 * This function handles EGTP tunnel deletion
491 * @param[in] Tunnel Event structure
492 * @return ROK - success
495 * ***************************************************************************/
496 S16 egtpTnlDel(EgtpTnlEvt tnlEvt)
498 EgtpTeIdCb *teidCb = NULLP;
500 DU_LOG("\nEGTP : Tunnel deletion : Local Teid[%d] Remote Teid[%d]", tnlEvt.lclTeid, tnlEvt.remTeid);
502 cmHashListFind(&(egtpCb.dstCb.teIdLst), (U8 *)&(tnlEvt.lclTeid), sizeof(U32), 0, (PTR *)&teidCb);
505 DU_LOG("\nEGTP : Tunnel id[%d] not configured", tnlEvt.lclTeid);
506 RETVALUE(LCM_REASON_INVALID_PAR_VAL);
509 cmHashListDelete(&(egtpCb.dstCb.teIdLst), (PTR)teidCb);
510 SPutSBuf(DU_APP_MEM_REGION, DU_POOL, (Data *)teidCb, (Size)sizeof(EgtpTeIdCb));
511 egtpCb.dstCb.numTunn--;
516 /*******************************************************************
518 * @brief Handles data indication
522 * Function : EgtpHdlDatInd
525 * Handles incoming data from peer to be passed
529 * @return ROK - success
532 * ****************************************************************/
533 S16 egtpHdlDatInd(EgtpMsg egtpMsg)
535 EgtpTeIdCb *teidCb = NULLP;
541 DU_LOG("\nEGTP : Received Data Indication");
543 cmHashListFind(&(egtpCb.dstCb.teIdLst), (U8 *)&(egtpMsg.msgHdr.teId), sizeof(U32), 0, (PTR *)&teidCb);
546 DU_LOG("\nEGTP : Tunnel id[%d] not configured", egtpMsg.msgHdr.teId);
547 RETVALUE(LCM_REASON_INVALID_PAR_VAL);
550 msgHdr = &(egtpMsg.msgHdr);
552 hdrLen = teidCb->preEncodedHdr.cnt;
554 if(msgHdr->extHdr.pdcpNmb.pres)
556 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] |= EGTP_MASK_BIT3;
557 teidCb->preEncodedHdr.hdr[hdrLen] = EGTP_EXT_HDR_PDCP_TYPE;
558 teidCb->preEncodedHdr.hdr[--hdrLen] = 1;
559 teidCb->preEncodedHdr.hdr[--hdrLen] = GetHiByte(msgHdr->extHdr.pdcpNmb.val);
560 teidCb->preEncodedHdr.hdr[--hdrLen] = GetLoByte(msgHdr->extHdr.pdcpNmb.val);
561 teidCb->preEncodedHdr.hdr[--hdrLen] = 0;
565 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] &= ~(EGTP_MASK_BIT3);
568 SFndLenMsg(egtpMsg.msg, &tPduSize);
570 /*Adjust the header to fill the correct length*/
571 msgLen = tPduSize + (EGTP_MAX_HDR_LEN - hdrLen) - 0x08;
573 /***********************************************
574 * Fill the length field of the message header *
575 ***********************************************/
576 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 3] = (U8)GetHiByte(msgLen);
577 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 4] = (U8)GetLoByte(msgLen);
579 /*Update the sequence number*/
580 if(egtpMsg.msgHdr.seqNum.pres)
582 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] |= (EGTP_MASK_BIT2);
583 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 9] = (U8)GetHiByte(egtpMsg.msgHdr.seqNum.val);
584 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 10] = (U8)GetLoByte(egtpMsg.msgHdr.seqNum.val);
588 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] &= ~(EGTP_MASK_BIT2);
591 DU_LOG("\nEGTP : UL Data buffer before encoding header");
592 SPrntMsg(egtpMsg.msg, 0, 0);
594 SAddPreMsgMult(&teidCb->preEncodedHdr.hdr[hdrLen], (EGTP_MAX_HDR_LEN - hdrLen), egtpMsg.msg);
597 DU_LOG("\nEGTP : UL Data buffer after encoding header");
598 SPrntMsg(egtpMsg.msg, 0, 0);
601 egtpSendMsg(egtpMsg.msg);
602 SPutMsg(egtpMsg.msg);
607 /*******************************************************************
609 * @brief Encodes outgoing message
613 * Function : egtpEncodeMsg
616 * Encodes EGTP message to be sent
618 * @params[in] EGTP message
620 * @return ROK - success
623 * ****************************************************************/
624 S16 egtpEncodeHdr(U8 *preEncodedHdr, EgtpMsgHdr *preDefHdr, U8 *hdrIdx)
626 U8 tmpByte = 0; /* Stores one byte of data for enc */
627 U8 cnt = EGTP_MAX_HDR_LEN; /* Stores the position */
628 Bool extPres = FALSE; /* Flag for indication of S, E or P presense flag */
631 /* Encoding header */
632 tmpByte |= EGTP_MASK_BIT6; /* Setting 6th LSB of 1st byte as version */
633 tmpByte |= EGTP_MASK_BIT5; /* Setting 5th LSB of 1st byte as protocol type */
635 if(preDefHdr->extHdr.udpPort.pres || preDefHdr->extHdr.pdcpNmb.pres)
637 tmpByte |= EGTP_MASK_BIT3; /* Setting 3rd LSB of 1st byte if Extension heaeder is present */
640 if(preDefHdr->seqNum.pres)
642 tmpByte |= EGTP_MASK_BIT2;
645 if(preDefHdr->nPdu.pres)
647 tmpByte |= EGTP_MASK_BIT1;
650 if((tmpByte & EGTP_MASK_BIT1) || (tmpByte & EGTP_MASK_BIT2)||(tmpByte & EGTP_MASK_BIT3))
655 preEncodedHdr[--cnt] = tmpByte;
656 preEncodedHdr[--cnt] = preDefHdr->msgType;
658 /* Encode Tunnel endpoint */
659 preEncodedHdr[--cnt] = 0;
660 preEncodedHdr[--cnt] = 0;
661 nwWord = (U16)(GetHiWord(preDefHdr->teId));
662 preEncodedHdr[--cnt] = (U8)(GetHiByte(nwWord));
663 preEncodedHdr[--cnt] = (U8)(GetLoByte(nwWord));
664 nwWord = (U16)(GetLoWord(preDefHdr->teId));
665 preEncodedHdr[--cnt] = (U8)(GetHiByte(nwWord));
666 preEncodedHdr[--cnt] = (U8)(GetLoByte(nwWord));
668 /* Encode sequence number */
669 if(preDefHdr->seqNum.pres)
671 preEncodedHdr[--cnt] = GetHiByte(preDefHdr->seqNum.val);
672 preEncodedHdr[--cnt] = GetLoByte(preDefHdr->seqNum.val);
676 preEncodedHdr[--cnt] = 0;
677 preEncodedHdr[--cnt] = 0;
680 /* Encode nPdu number */
681 if(preDefHdr->nPdu.pres)
683 preEncodedHdr[--cnt] = preDefHdr->nPdu.val;
687 preEncodedHdr[--cnt] = 0;
690 if(preDefHdr->extHdr.udpPort.pres)
692 preEncodedHdr[--cnt] = EGTP_EXT_HDR_UDP_TYPE;
693 preEncodedHdr[--cnt] = 1;
694 preEncodedHdr[--cnt] = GetHiByte(preDefHdr->extHdr.udpPort.val);
695 preEncodedHdr[--cnt] = GetLoByte(preDefHdr->extHdr.udpPort.val);
698 if(preDefHdr->extHdr.pdcpNmb.pres)
700 preEncodedHdr[--cnt] = EGTP_EXT_HDR_PDCP_TYPE;
701 preEncodedHdr[--cnt] = 1;
702 preEncodedHdr[--cnt] = GetHiByte(preDefHdr->extHdr.pdcpNmb.val);
703 preEncodedHdr[--cnt] = GetLoByte(preDefHdr->extHdr.pdcpNmb.val);
706 if(tmpByte & EGTP_MASK_BIT3)
708 preEncodedHdr[--cnt] = 0;
712 preEncodedHdr[--cnt] = 0;
717 } /* egtpEncodeHdr */
719 /*******************************************************************
721 * @brief Sends message over UDP
725 * Function : egtpSendMsg
728 * Sends message over UDP
730 * @params[in] Message Buffer
731 * @return ROK - success
734 * ****************************************************************/
735 S16 egtpSendMsg(Buffer *mBuf)
742 info.region = DU_APP_MEM_REGION;
745 dstAddr.port = EGTP_DFLT_PORT;
746 dstAddr.address = egtpCb.dstCb.dstIp;
748 ret = cmInetSendMsg(&(egtpCb.dstCb.sendTptSrvr.sockFd), &dstAddr, &info, mBuf, &txLen, CM_INET_NO_FLAG);
749 if(ret != ROK && ret != RWOULDBLOCK)
751 DU_LOG("\nEGTP : Failed sending the message");
755 DU_LOG("\nEGTP : Message Sent");
760 /*******************************************************************
762 * @brief Handles TTI Indication from PHY
766 * Function : egtpTTIInd
769 * Handles TTI Indication from PHY
772 * @return ROK - success
775 * ****************************************************************/
782 /*******************************************************************
784 * @brief Receives EGTP message from UDP socket
788 * Function : egtpRecvMsg
791 * Receive incoming messages from UDP socket
794 * @return ROK - success
797 * ****************************************************************/
801 U8 ret; /* Return value */
802 U8 nMsg; /* Number of messages to read from UDP socked */
803 MsgLen bufLen; /* Length of received buffer */
804 Buffer *recvBuf; /* Received buffer */
805 CmInetAddr fromAddr; /* Egtp data sender address */
806 CmInetMemInfo memInfo; /* Buffer allocation info */
809 DU_LOG("\nEGTP : Received TTI Indication");
812 memInfo.region = DU_APP_MEM_REGION;
813 memInfo.pool = DU_POOL;
815 fromAddr.port = egtpCb.dstCb.dstPort;
816 fromAddr.address = egtpCb.dstCb.dstIp;
818 while(nMsg < EGTP_MAX_MSG_RECV)
821 ret = cmInetRecvMsg(&(egtpCb.recvTptSrvr.sockFd), &fromAddr, &memInfo, &recvBuf, &bufLen, CM_INET_NO_FLAG);
822 if(ret == ROK && recvBuf != NULLP)
824 DU_LOG("\nEGTP : Received DL Message[%d]\n", nMsg+1);
825 SPrntMsg(recvBuf, 0 ,0);
826 egtpHdlRecvData(recvBuf);
834 S16 egtpHdlRecvData(Buffer *mBuf)
838 /* Decode EGTP header */
839 egtpDecodeHdr(mBuf, &egtpMsg);
841 /* TODO : Send received message to RLC */
842 duHdlEgtpDlData(&egtpMsg);
847 S16 egtpDecodeHdr(Buffer *mBuf, EgtpMsg *egtpMsg)
849 U8 tmpByte[5]; /* Holds 5 byte of data after Decoding */
850 U8 version = 0; /* Holds the version type, decoded */
851 MsgLen msgLen = 0; /* Holds the msgLen from the Hdr */
852 MsgLen bufLen = 0; /* Holds the total buffer length */
853 U8 extHdrType = 0; /* Holds the Extension hdr type */
854 U8 extHdrLen = 0; /* Extension hdr length */
855 Bool extPres = FALSE; /* Flag for indication of S, E or P presense flag */
857 SFndLenMsg(mBuf, &bufLen);
859 /* Decode first byte and storing in temporary variable */
860 SRemPreMsg(&tmpByte[0], mBuf);
862 /* Extracting version fro 1st byte */
863 version = tmpByte[0] >> 5;
865 DU_LOG("\nEGTP : Version %d", version);
867 /* Decode message type */
868 SRemPreMsg((Data*)&(egtpMsg->msgHdr.msgType), mBuf);
869 DU_LOG("\nEGTP : msgType %d", egtpMsg->msgHdr.msgType);
871 /****************************************************************************
872 * Message length param is 2 bytes. So decode next 2 bytes from msg hdr and
873 * performing OR operation on these two bytes to calculate message length
874 ***************************************************************************/
875 SRemPreMsg(&tmpByte[1], mBuf);
876 SRemPreMsg(&tmpByte[2], mBuf);
877 msgLen = (tmpByte[1] << 8) | tmpByte[2];
878 DU_LOG("\nEGTP : msgLen %d", msgLen);
881 /****************************************************************************
882 * Tunnel id param is 4 bytes. So decode next 4 bytes from msg hdr and
883 * perform OR operation on these 4 bytes to calculate tunnel id
884 ***************************************************************************/
885 SRemPreMsg(&tmpByte[1], mBuf);
886 SRemPreMsg(&tmpByte[2], mBuf);
887 SRemPreMsg(&tmpByte[3], mBuf);
888 SRemPreMsg(&tmpByte[4], mBuf);
889 egtpMsg->msgHdr.teId = (tmpByte[1] << 24) | (tmpByte[2] << 16) | (tmpByte[3] << 8) | tmpByte[4];
890 DU_LOG("\nEGTP : teId %d",egtpMsg->msgHdr.teId);
893 /* If any one of S, E or PN flag is set, set extension present as true. */
894 if((tmpByte[0] & EGTP_MASK_BIT1) || (tmpByte[0] & EGTP_MASK_BIT2)||(tmpByte[0] & EGTP_MASK_BIT3))
899 /* Decode sequence number, if S flag is set in first byte */
900 if (tmpByte[0] & EGTP_MASK_BIT2)
902 /************************************************************************
903 * Sequence num is 2 bytes. So decode next 2 bytes from msg hdr and
904 * perform OR operation on them
905 ************************************************************************/
906 egtpMsg->msgHdr.seqNum.pres = TRUE;
907 SRemPreMsg(&tmpByte[1], mBuf);
908 SRemPreMsg(&tmpByte[2], mBuf);
909 egtpMsg->msgHdr.seqNum.val = (tmpByte[1] << 8) | tmpByte[2];
911 /****************************************************************************
912 * If extPres is true, but S bit is not set, implies, either of PN or E bit
913 * was set during Encode so accordingly extract Byte fields for seqNum anyway
914 ***************************************************************************/
917 /*************************************************************************
918 * Sequence num is 2 bytes. So decode next 2 bytes from msg hdr and
919 * perform OR operation on them
920 ************************************************************************/
921 egtpMsg->msgHdr.seqNum.pres = 0;
922 SRemPreMsg(&tmpByte[1], mBuf);
923 SRemPreMsg(&tmpByte[2], mBuf);
924 egtpMsg->msgHdr.seqNum.val = (tmpByte[1] << 8) | tmpByte[2];
927 /* Decode N-PDU number if present flag is set */
928 if (tmpByte[0] & EGTP_MASK_BIT1)
930 egtpMsg->msgHdr.nPdu.pres = TRUE;
931 SRemPreMsg(&(egtpMsg->msgHdr.nPdu.val), mBuf);
933 /****************************************************************************
934 * If extPres is true, but PN bit is not set, implies, either of S or E bit
935 * was set during Encode. Aaccordingly extract Byte fields of N-PDU num anyway
936 ***************************************************************************/
939 egtpMsg->msgHdr.nPdu.pres = TRUE;
940 SRemPreMsg(&(egtpMsg->msgHdr.nPdu.val), mBuf);
943 /* If E flag is set in first byte, decode extension header */
944 if(tmpByte[0] & EGTP_MASK_BIT3)
946 SRemPreMsg(&extHdrType, mBuf);
947 while( 0 != extHdrType)
951 case EGTP_EXT_HDR_UDP_TYPE:
953 SRemPreMsg(&extHdrLen, mBuf);
954 if(extHdrLen == 0x01)
956 /************************************************************
957 * UDP Port is 2 bytes. So decode next 2 bytes from msg hdr
958 * and perform OR operation on them
959 *************************************************************/
960 egtpMsg->msgHdr.extHdr.udpPort.pres = TRUE;
961 SRemPreMsg(&tmpByte[1], mBuf);
962 SRemPreMsg(&tmpByte[2], mBuf);
963 egtpMsg->msgHdr.extHdr.udpPort.val = (tmpByte[1] << 8) | tmpByte[2];
968 case EGTP_EXT_HDR_PDCP_TYPE:
970 SRemPreMsg(&extHdrLen, mBuf);
971 if(extHdrLen == 0x01)
973 /*************************************************************
974 * PDCP num is 2 bytes. So decode next 2 bytes from msg hdr
975 * and perform OR operation on them
976 ************************************************************/
977 egtpMsg->msgHdr.extHdr.pdcpNmb.pres = TRUE;
978 SRemPreMsg(&tmpByte[1], mBuf);
979 SRemPreMsg(&tmpByte[2], mBuf);
980 egtpMsg->msgHdr.extHdr.pdcpNmb.val = (tmpByte[1] << 8) | tmpByte[2];
984 } /* End of switch */
986 SRemPreMsg(&extHdrType, mBuf);
990 /****************************************************************************
991 * If extPres is true, but E bit is not set, implies, either of PN or S bit
992 * was set during Encode so accordingly extract Byte fields for extension
994 ***************************************************************************/
997 SRemPreMsg(&extHdrType, mBuf);
1000 egtpMsg->msg = mBuf;
1002 DU_LOG("\nEGTP : DL Data Buffer after decoding header ");
1003 SPrntMsg(mBuf, 0, 0);
1005 /* Forward the data to duApp/RLC */