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 (&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 DU_LOG("\nEGTP : Invalid event %d", pst->event);
113 ODU_PUT_MSG_BUF(mBuf);
125 DU_LOG("\nEGTP : Starting Socket Polling");
127 ODU_PUT_MSG_BUF(mBuf);
132 DU_LOG("\nEGTP : Invalid event %d", pst->event);
133 ODU_PUT_MSG_BUF(mBuf);
150 DU_LOG("\nEGTP : Invalid event %d", pst->event);
158 DU_LOG("\nEGTP : Invalid source entity %d", pst->srcEnt);
166 /**************************************************************************
167 * @brief EGTP server configuration
171 * Function : egtpCfgReq
174 * This function handles EGTP configuration request.
176 * @return ROK - success
179 * ***********************************************************************/
180 uint8_t egtpCfgReq(Pst *pst, EgtpConfig egtpCfg)
182 uint8_t ret; /* Return value */
183 Pst rspPst; /* Response Pst structure */
184 CmStatus cfgCfm; /* Configuration Confirm */
186 memcpy(&egtpCb.egtpCfg, &egtpCfg, sizeof(EgtpConfig));
188 egtpCb.recvTptSrvr.addr.address = CM_INET_NTOH_UINT32(egtpCb.egtpCfg.localIp.ipV4Addr);
189 egtpCb.recvTptSrvr.addr.port = EGTP_DFLT_PORT;
191 egtpCb.dstCb.dstIp = CM_INET_NTOH_UINT32(egtpCb.egtpCfg.destIp.ipV4Addr);
192 egtpCb.dstCb.dstPort = egtpCb.egtpCfg.destPort;
193 egtpCb.dstCb.sendTptSrvr.addr.address = CM_INET_NTOH_UINT32(egtpCb.egtpCfg.localIp.ipV4Addr);
194 egtpCb.dstCb.sendTptSrvr.addr.port = egtpCb.egtpCfg.localPort;
195 egtpCb.dstCb.numTunn = 0;
197 ret = cmHashListInit(&(egtpCb.dstCb.teIdLst), 1024, sizeof(EgtpTeIdCb), FALSE, CM_HASH_KEYTYPE_UINT32_MOD, DU_APP_MEM_REGION, DU_POOL);
201 DU_LOG("\nEGTP : TeId hash list initialization failed");
202 cfgCfm.status = LCM_PRIM_NOK;
203 cfgCfm.reason = LCM_REASON_HASHING_FAILED;
207 DU_LOG("\nEGTP : EGTP configuration successful");
208 cfgCfm.status = LCM_PRIM_OK;
209 cfgCfm.reason = LCM_REASON_NOT_APPL;
212 /* Fill response Pst */
213 egtpFillRspPst(pst, &rspPst);
214 rspPst.event = EVTCFGCFM;
216 packEgtpCfgCfm(&rspPst, cfgCfm);
221 /**************************************************************************
222 * @brief Fills post structure to send response
226 * Function : egtpFillRspPst
229 * Fills post struture to send response
231 * @return ROK - success
235 * ***********************************************************************/
236 uint8_t egtpFillRspPst(Pst *pst, Pst *rspPst)
239 memset(rspPst, 0, sizeof(Pst));
240 rspPst->srcEnt = pst->dstEnt;
241 rspPst->srcInst = pst->dstInst;
242 rspPst->srcProcId = pst->dstProcId;
243 rspPst->dstEnt = pst->srcEnt;
244 rspPst->dstInst = pst->srcInst;
245 rspPst->dstProcId = pst->srcProcId;
246 rspPst->selector = ODU_SELECTOR_LC;
247 rspPst->pool= DU_POOL;
252 /**************************************************************************
253 * @brief EGTP server open request
257 * Function : egtpSrvOpenReq
260 * This function handles EGTP open server request.
261 * It opens udp socket to receive/send msgs.
263 * @param[in] Pst *pst, post structure
264 * @return ROK - success
267 ***************************************************************************/
269 uint8_t egtpSrvOpenReq(Pst *pst)
272 uint8_t ret; /* Return value */
273 Pst rspPst; /* Response Pst structure */
274 Pst egtpPst; /* Self post */
275 CmStatus cfm; /* Confirmation status */
276 uint8_t sockType; /* Socket type */
278 DU_LOG("\nEGTP : Received EGTP open server request");
280 sockType = CM_INET_DGRAM;
281 ret = egtpSrvOpenPrc(sockType, &(egtpCb.recvTptSrvr));
282 /* Opening and Binding receiver socket */
285 DU_LOG("\nEGTP : Failed while opening receiver transport server");
288 /* Opening and Binding sender socket */
289 ret = egtpSrvOpenPrc(sockType, &(egtpCb.dstCb.sendTptSrvr));
292 DU_LOG("\nEGTP : Failed while opening sender transport server");
296 DU_LOG("\nEGTP : Receiver socket[%d] and Sender socket[%d] open", egtpCb.recvTptSrvr.sockFd.fd, egtpCb.dstCb.sendTptSrvr.sockFd.fd);
298 /* Start Socket polling */
299 memset(&egtpPst, 0, sizeof(egtpPst));
300 egtpPst.srcEnt = (Ent)ENTEGTP;
301 egtpPst.srcInst = (Inst)EGTP_INST;
302 egtpPst.srcProcId = DU_PROC;
303 egtpPst.dstEnt = (Ent)ENTEGTP;
304 egtpPst.dstInst = (Inst)EGTP_INST;
305 egtpPst.dstProcId = DU_PROC;
306 egtpPst.event = EVTSTARTPOLL;
307 egtpPst.selector = ODU_SELECTOR_LC;
308 egtpPst.pool= DU_POOL;
309 packEgtpStartPollingReq(&egtpPst);
311 /* Filling and sending response */
312 cfm.status = LCM_PRIM_OK;
313 cfm.reason = LCM_REASON_NOT_APPL;
315 egtpFillRspPst(pst, &rspPst);
316 rspPst.event = EVTSRVOPENCFM;
317 packEgtpSrvOpenCfm(&rspPst, cfm);
322 /*******************************************************************
324 * @brief Processing Sever open request
328 * Function : egtpSrvOpenPrc
334 * @return ROK - success
337 * ****************************************************************/
339 uint8_t egtpSrvOpenPrc(uint8_t sockType, EgtpTptSrvr *server)
342 ret = cmInetSocket(sockType, &(server->sockFd), protType);
345 DU_LOG("\nEGTP : Failed to open UDP socket");
348 ret = cmInetBind(&(server->sockFd), &(server->addr));
351 DU_LOG("\nEGTP : Failed to bind socket");
358 /**************************************************************************
359 * @brief EGTP tunnel management request
363 * Function : egtpTnlMgmtReq
366 * This function handles EGTP tunnel managament request
368 * @param[in] Tunnel Eveny structure
369 * @return ROK - success
373 * ***************************************************************************/
374 uint8_t egtpTnlMgmtReq(Pst *pst, EgtpTnlEvt tnlEvt)
378 DU_LOG("\nEGTP : Received tunnel management request");
379 switch(tnlEvt.action)
381 case EGTP_TNL_MGMT_ADD:
383 ret = egtpTnlAdd(tnlEvt);
386 case EGTP_TNL_MGMT_MOD:
388 ret = egtpTnlMod(tnlEvt);
391 case EGTP_TNL_MGMT_DEL:
393 ret = egtpTnlDel(tnlEvt);
398 DU_LOG("\nEGTP : Invalid tunnel management action[%d]", tnlEvt.action);
399 ret = LCM_REASON_INVALID_ACTION;
405 tnlEvt.cfmStatus.status = LCM_PRIM_OK;
406 tnlEvt.cfmStatus.reason = LCM_REASON_NOT_APPL;
410 tnlEvt.cfmStatus.status = LCM_PRIM_NOK;
411 tnlEvt.cfmStatus.reason = ret;
414 DU_LOG("\nEGTP : Sending Tunnel management confirmation");
415 duHdlEgtpTnlMgmtCfm(tnlEvt);
420 /**************************************************************************
421 * @brief EGTP tunnel addition
425 * Function : egtpTnlAdd
428 * This function handles EGTP tunnel addition
430 * @param[in] Tunnel Event structure
431 * @return ROK - success
434 * ***************************************************************************/
435 uint8_t egtpTnlAdd(EgtpTnlEvt tnlEvt)
438 EgtpTeIdCb *teidCb; /* Tunnel endpoint control block */
439 EgtpMsgHdr preDefHdr; /* pre-define header for this tunnel */
441 DU_LOG("\nEGTP : Tunnel addition : LocalTeid[%d] Remote Teid[%d]", tnlEvt.lclTeid, tnlEvt.remTeid);
443 DU_ALLOC(teidCb, sizeof(EgtpTeIdCb));
446 DU_LOG("\nEGTP : Memory allocation failed");
447 return LCM_REASON_MEM_NOAVAIL;
450 memset(teidCb, 0, sizeof(EgtpTeIdCb));
451 teidCb->teId = tnlEvt.lclTeid;
452 teidCb->remTeId = tnlEvt.remTeid;
454 ret = cmHashListInsert(&(egtpCb.dstCb.teIdLst), (PTR)teidCb, (uint8_t *)&(teidCb->teId), sizeof(uint32_t));
457 DU_LOG("\nEGTP : Failed to insert in hash list");
458 DU_FREE(teidCb, sizeof(EgtpTeIdCb));
459 return LCM_REASON_HASHING_FAILED;
461 egtpCb.dstCb.numTunn++;
463 /* Encoding pre-defined header */
464 memset(&preDefHdr, 0, sizeof(EgtpMsgHdr));
465 preDefHdr.msgType = EGTPU_MSG_GPDU;
466 preDefHdr.teId = teidCb->remTeId;
467 preDefHdr.extHdr.pdcpNmb.pres = FALSE;
468 preDefHdr.extHdr.udpPort.pres = FALSE;
469 preDefHdr.nPdu.pres = FALSE;
471 egtpEncodeHdr((uint8_t *)teidCb->preEncodedHdr.hdr, &preDefHdr, &(teidCb->preEncodedHdr.cnt));
476 /**************************************************************************
477 * @brief EGTP tunnel modification
481 * Function : egtpTnlMod
484 * This function handles EGTP tunnel modification
486 * @param[in] Tunnel Event structure
487 * @return ROK - success
490 * ***************************************************************************/
491 uint8_t egtpTnlMod(EgtpTnlEvt tnlEvt)
495 EgtpTeIdCb *teidCb = NULLP;
497 printf("\nTunnel modification : LocalTeid[%d] Remote Teid[%d]", tnlEvt.lclTeid, tnlEvt.remTeid);
499 cmHashListFind(&(egtpCb.dstCb.teIdLst), (uint8_t *)&(tnlEvt.teId), sizeof(uint32_t), 0, (PTR *)&teidCb);
502 printf("\nTunnel id not found");
506 teidCb->teId = tnlEvt.lclTeid;
507 teidCb->remTeId = tnlEvt.remTeid;
512 /**************************************************************************
513 * @brief EGTP tunnel deletion
517 * Function : egtpTnlDel
520 * This function handles EGTP tunnel deletion
522 * @param[in] Tunnel Event structure
523 * @return ROK - success
526 * ***************************************************************************/
527 uint8_t egtpTnlDel(EgtpTnlEvt tnlEvt)
529 EgtpTeIdCb *teidCb = NULLP;
531 DU_LOG("\nEGTP : Tunnel deletion : Local Teid[%d] Remote Teid[%d]", tnlEvt.lclTeid, tnlEvt.remTeid);
533 cmHashListFind(&(egtpCb.dstCb.teIdLst), (uint8_t *)&(tnlEvt.lclTeid), sizeof(uint32_t), 0, (PTR *)&teidCb);
536 DU_LOG("\nEGTP : Tunnel id[%d] not configured", tnlEvt.lclTeid);
537 return LCM_REASON_INVALID_PAR_VAL;
540 cmHashListDelete(&(egtpCb.dstCb.teIdLst), (PTR)teidCb);
541 DU_FREE(teidCb, sizeof(EgtpTeIdCb));
542 egtpCb.dstCb.numTunn--;
547 /*******************************************************************
549 * @brief Handles data indication
553 * Function : EgtpHdlDatInd
556 * Handles incoming data from peer to be passed
560 * @return ROK - success
563 * ****************************************************************/
564 uint8_t egtpHdlDatInd(EgtpMsg egtpMsg)
566 EgtpTeIdCb *teidCb = NULLP;
572 DU_LOG("\nEGTP : Received Data Indication");
574 cmHashListFind(&(egtpCb.dstCb.teIdLst), (uint8_t *)&(egtpMsg.msgHdr.teId), sizeof(uint32_t), 0, (PTR *)&teidCb);
577 DU_LOG("\nEGTP : Tunnel id[%d] not configured", egtpMsg.msgHdr.teId);
578 return LCM_REASON_INVALID_PAR_VAL;
581 msgHdr = &(egtpMsg.msgHdr);
583 hdrLen = teidCb->preEncodedHdr.cnt;
585 if(msgHdr->extHdr.pdcpNmb.pres)
587 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] |= EGTP_MASK_BIT3;
588 teidCb->preEncodedHdr.hdr[hdrLen] = EGTP_EXT_HDR_PDCP_TYPE;
589 teidCb->preEncodedHdr.hdr[--hdrLen] = 1;
590 teidCb->preEncodedHdr.hdr[--hdrLen] = GetHiByte(msgHdr->extHdr.pdcpNmb.val);
591 teidCb->preEncodedHdr.hdr[--hdrLen] = GetLoByte(msgHdr->extHdr.pdcpNmb.val);
592 teidCb->preEncodedHdr.hdr[--hdrLen] = 0;
596 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] &= ~(EGTP_MASK_BIT3);
599 ODU_GET_MSG_LEN(egtpMsg.msg, (int16_t *)&tPduSize);
601 /*Adjust the header to fill the correct length*/
602 msgLen = tPduSize + (EGTP_MAX_HDR_LEN - hdrLen) - 0x08;
604 /***********************************************
605 * Fill the length field of the message header *
606 ***********************************************/
607 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 3] = (uint8_t)GetHiByte(msgLen);
608 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 4] = (uint8_t)GetLoByte(msgLen);
610 /*Update the sequence number*/
611 if(egtpMsg.msgHdr.seqNum.pres)
613 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] |= (EGTP_MASK_BIT2);
614 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 9] = (uint8_t)GetHiByte(egtpMsg.msgHdr.seqNum.val);
615 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 10] = (uint8_t)GetLoByte(egtpMsg.msgHdr.seqNum.val);
619 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] &= ~(EGTP_MASK_BIT2);
622 DU_LOG("\nEGTP : UL Data buffer before encoding header");
623 ODU_PRINT_MSG(egtpMsg.msg, 0, 0);
625 ODU_ADD_PRE_MSG_MULT(&teidCb->preEncodedHdr.hdr[hdrLen], (EGTP_MAX_HDR_LEN - hdrLen), egtpMsg.msg);
628 DU_LOG("\nEGTP : UL Data buffer after encoding header");
629 ODU_PRINT_MSG(egtpMsg.msg, 0, 0);
632 egtpSendMsg(egtpMsg.msg);
633 ODU_PUT_MSG_BUF(egtpMsg.msg);
638 /*******************************************************************
640 * @brief Encodes outgoing message
644 * Function : egtpEncodeMsg
647 * Encodes EGTP message to be sent
649 * @params[in] EGTP message
651 * @return ROK - success
654 * ****************************************************************/
655 uint8_t egtpEncodeHdr(uint8_t *preEncodedHdr, EgtpMsgHdr *preDefHdr, uint8_t *hdrIdx)
657 uint8_t tmpByte = 0; /* Stores one byte of data for enc */
658 uint8_t cnt = EGTP_MAX_HDR_LEN; /* Stores the position */
659 bool extPres = FALSE; /* Flag for indication of S, E or P presense flag */
662 /* Encoding header */
663 tmpByte |= EGTP_MASK_BIT6; /* Setting 6th LSB of 1st byte as version */
664 tmpByte |= EGTP_MASK_BIT5; /* Setting 5th LSB of 1st byte as protocol type */
666 if(preDefHdr->extHdr.udpPort.pres || preDefHdr->extHdr.pdcpNmb.pres)
668 tmpByte |= EGTP_MASK_BIT3; /* Setting 3rd LSB of 1st byte if Extension heaeder is present */
671 if(preDefHdr->seqNum.pres)
673 tmpByte |= EGTP_MASK_BIT2;
676 if(preDefHdr->nPdu.pres)
678 tmpByte |= EGTP_MASK_BIT1;
681 if((tmpByte & EGTP_MASK_BIT1) || (tmpByte & EGTP_MASK_BIT2)||(tmpByte & EGTP_MASK_BIT3))
686 preEncodedHdr[--cnt] = tmpByte;
687 preEncodedHdr[--cnt] = preDefHdr->msgType;
689 /* Encode Tunnel endpoint */
690 preEncodedHdr[--cnt] = 0;
691 preEncodedHdr[--cnt] = 0;
692 nwWord = (uint16_t)(GetHiWord(preDefHdr->teId));
693 preEncodedHdr[--cnt] = (uint8_t)(GetHiByte(nwWord));
694 preEncodedHdr[--cnt] = (uint8_t)(GetLoByte(nwWord));
695 nwWord = (uint16_t)(GetLoWord(preDefHdr->teId));
696 preEncodedHdr[--cnt] = (uint8_t)(GetHiByte(nwWord));
697 preEncodedHdr[--cnt] = (uint8_t)(GetLoByte(nwWord));
699 /* Encode sequence number */
700 if(preDefHdr->seqNum.pres)
702 preEncodedHdr[--cnt] = GetHiByte(preDefHdr->seqNum.val);
703 preEncodedHdr[--cnt] = GetLoByte(preDefHdr->seqNum.val);
707 preEncodedHdr[--cnt] = 0;
708 preEncodedHdr[--cnt] = 0;
711 /* Encode nPdu number */
712 if(preDefHdr->nPdu.pres)
714 preEncodedHdr[--cnt] = preDefHdr->nPdu.val;
718 preEncodedHdr[--cnt] = 0;
721 if(preDefHdr->extHdr.udpPort.pres)
723 preEncodedHdr[--cnt] = EGTP_EXT_HDR_UDP_TYPE;
724 preEncodedHdr[--cnt] = 1;
725 preEncodedHdr[--cnt] = GetHiByte(preDefHdr->extHdr.udpPort.val);
726 preEncodedHdr[--cnt] = GetLoByte(preDefHdr->extHdr.udpPort.val);
729 if(preDefHdr->extHdr.pdcpNmb.pres)
731 preEncodedHdr[--cnt] = EGTP_EXT_HDR_PDCP_TYPE;
732 preEncodedHdr[--cnt] = 1;
733 preEncodedHdr[--cnt] = GetHiByte(preDefHdr->extHdr.pdcpNmb.val);
734 preEncodedHdr[--cnt] = GetLoByte(preDefHdr->extHdr.pdcpNmb.val);
737 if(tmpByte & EGTP_MASK_BIT3)
739 preEncodedHdr[--cnt] = 0;
743 preEncodedHdr[--cnt] = 0;
748 } /* egtpEncodeHdr */
750 /*******************************************************************
752 * @brief Sends message over UDP
756 * Function : egtpSendMsg
759 * Sends message over UDP
761 * @params[in] Message Buffer
762 * @return ROK - success
765 * ****************************************************************/
766 uint8_t egtpSendMsg(Buffer *mBuf)
773 info.region = DU_APP_MEM_REGION;
776 dstAddr.port = EGTP_DFLT_PORT;
777 dstAddr.address = egtpCb.dstCb.dstIp;
779 ret = cmInetSendMsg(&(egtpCb.dstCb.sendTptSrvr.sockFd), &dstAddr, &info, \
780 mBuf, (int16_t *)&txLen, CM_INET_NO_FLAG);
781 if(ret != ROK && ret != RWOULDBLOCK)
783 DU_LOG("\nEGTP : Failed sending the message");
787 DU_LOG("\nEGTP : Message Sent");
792 /*******************************************************************
794 * @brief Receives EGTP message from UDP socket
798 * Function : egtpRecvMsg
801 * Receive incoming messages from UDP socket
804 * @return ROK - success
807 * ****************************************************************/
809 uint8_t egtpRecvMsg()
811 uint8_t ret; /* Return value */
812 uint8_t nMsg; /* Number of messages to read from UDP socked */
813 uint16_t bufLen; /* Length of received buffer */
814 Buffer *recvBuf; /* Received buffer */
815 CmInetAddr fromAddr; /* Egtp data sender address */
816 CmInetMemInfo memInfo; /* Buffer allocation info */
819 memInfo.region = DU_APP_MEM_REGION;
820 memInfo.pool = DU_POOL;
822 fromAddr.port = egtpCb.dstCb.dstPort;
823 fromAddr.address = egtpCb.dstCb.dstIp;
828 ret = cmInetRecvMsg(&(egtpCb.recvTptSrvr.sockFd), &fromAddr, &memInfo, \
829 &recvBuf, (int16_t *)&bufLen, CM_INET_NO_FLAG);
830 if(ret == ROK && recvBuf != NULLP)
832 DU_LOG("\nEGTP : Received DL Message[%d]\n", nMsg+1);
833 ODU_PRINT_MSG(recvBuf, 0 ,0);
834 egtpHdlRecvData(recvBuf);
842 /*******************************************************************
844 * @brief Handles DL User data received from CU
848 * Function : egtpHdlRecvData
850 * Functionality: Handles DL User data received from CU
852 * @params[in] DL Usre data buffer
853 * @return ROK - success
856 * ****************************************************************/
857 uint8_t egtpHdlRecvData(Buffer *mBuf)
861 /* Decode EGTP header */
862 egtpDecodeHdr(mBuf, &egtpMsg);
864 /* TODO : Send received message to RLC */
865 duHdlEgtpDlData(&egtpMsg);
870 /*******************************************************************
872 * @brief Decodes EGTP header from DL User data
876 * Function : egtpDecodeHdr
878 * Functionality: Decodes EGTP header from DL User data
881 * @return ROK - success
884 * ****************************************************************/
885 uint8_t egtpDecodeHdr(Buffer *mBuf, EgtpMsg *egtpMsg)
887 uint8_t tmpByte[5]; /* Holds 5 byte of data after Decoding */
888 uint8_t version = 0; /* Holds the version type, decoded */
889 uint16_t msgLen = 0; /* Holds the msgLen from the Hdr */
890 uint16_t bufLen = 0; /* Holds the total buffer length */
891 uint8_t extHdrType = 0; /* Holds the Extension hdr type */
892 uint8_t extHdrLen = 0; /* Extension hdr length */
893 bool extPres = FALSE; /* Flag for indication of S, E or P presense flag */
895 ODU_GET_MSG_LEN(mBuf, (int16_t *)&bufLen);
897 /* Decode first byte and storing in temporary variable */
898 ODU_REM_PRE_MSG(&tmpByte[0], mBuf);
900 /* Extracting version fro 1st byte */
901 version = tmpByte[0] >> 5;
903 DU_LOG("\nEGTP : Version %d", version);
905 /* Decode message type */
906 ODU_REM_PRE_MSG((Data*)&(egtpMsg->msgHdr.msgType), mBuf);
907 DU_LOG("\nEGTP : msgType %d", egtpMsg->msgHdr.msgType);
909 /****************************************************************************
910 * Message length param is 2 bytes. So decode next 2 bytes from msg hdr and
911 * performing OR operation on these two bytes to calculate message length
912 ***************************************************************************/
913 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
914 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
915 msgLen = (tmpByte[1] << 8) | tmpByte[2];
916 DU_LOG("\nEGTP : msgLen %d", msgLen);
919 /****************************************************************************
920 * Tunnel id param is 4 bytes. So decode next 4 bytes from msg hdr and
921 * perform OR operation on these 4 bytes to calculate tunnel id
922 ***************************************************************************/
923 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
924 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
925 ODU_REM_PRE_MSG(&tmpByte[3], mBuf);
926 ODU_REM_PRE_MSG(&tmpByte[4], mBuf);
927 egtpMsg->msgHdr.teId = (tmpByte[1] << 24) | (tmpByte[2] << 16) | (tmpByte[3] << 8) | tmpByte[4];
928 DU_LOG("\nEGTP : teId %d",egtpMsg->msgHdr.teId);
931 /* If any one of S, E or PN flag is set, set extension present as true. */
932 if((tmpByte[0] & EGTP_MASK_BIT1) || (tmpByte[0] & EGTP_MASK_BIT2)||(tmpByte[0] & EGTP_MASK_BIT3))
937 /* Decode sequence number, if S flag is set in first byte */
938 if (tmpByte[0] & EGTP_MASK_BIT2)
940 /************************************************************************
941 * Sequence num is 2 bytes. So decode next 2 bytes from msg hdr and
942 * perform OR operation on them
943 ************************************************************************/
944 egtpMsg->msgHdr.seqNum.pres = TRUE;
945 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
946 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
947 egtpMsg->msgHdr.seqNum.val = (tmpByte[1] << 8) | tmpByte[2];
949 /****************************************************************************
950 * If extPres is true, but S bit is not set, implies, either of PN or E bit
951 * was set during Encode so accordingly extract Byte fields for seqNum anyway
952 ***************************************************************************/
955 /*************************************************************************
956 * Sequence num is 2 bytes. So decode next 2 bytes from msg hdr and
957 * perform OR operation on them
958 ************************************************************************/
959 egtpMsg->msgHdr.seqNum.pres = 0;
960 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
961 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
962 egtpMsg->msgHdr.seqNum.val = (tmpByte[1] << 8) | tmpByte[2];
965 /* Decode N-PDU number if present flag is set */
966 if (tmpByte[0] & EGTP_MASK_BIT1)
968 egtpMsg->msgHdr.nPdu.pres = TRUE;
969 ODU_REM_PRE_MSG(&(egtpMsg->msgHdr.nPdu.val), mBuf);
971 /****************************************************************************
972 * If extPres is true, but PN bit is not set, implies, either of S or E bit
973 * was set during Encode. Aaccordingly extract Byte fields of N-PDU num anyway
974 ***************************************************************************/
977 egtpMsg->msgHdr.nPdu.pres = TRUE;
978 ODU_REM_PRE_MSG(&(egtpMsg->msgHdr.nPdu.val), mBuf);
981 /* If E flag is set in first byte, decode extension header */
982 if(tmpByte[0] & EGTP_MASK_BIT3)
984 ODU_REM_PRE_MSG(&extHdrType, mBuf);
985 while( 0 != extHdrType)
989 case EGTP_EXT_HDR_UDP_TYPE:
991 ODU_REM_PRE_MSG(&extHdrLen, mBuf);
992 if(extHdrLen == 0x01)
994 /************************************************************
995 * UDP Port is 2 bytes. So decode next 2 bytes from msg hdr
996 * and perform OR operation on them
997 *************************************************************/
998 egtpMsg->msgHdr.extHdr.udpPort.pres = TRUE;
999 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
1000 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
1001 egtpMsg->msgHdr.extHdr.udpPort.val = (tmpByte[1] << 8) | tmpByte[2];
1006 case EGTP_EXT_HDR_PDCP_TYPE:
1008 ODU_REM_PRE_MSG(&extHdrLen, mBuf);
1009 if(extHdrLen == 0x01)
1011 /*************************************************************
1012 * PDCP num is 2 bytes. So decode next 2 bytes from msg hdr
1013 * and perform OR operation on them
1014 ************************************************************/
1015 egtpMsg->msgHdr.extHdr.pdcpNmb.pres = TRUE;
1016 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
1017 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
1018 egtpMsg->msgHdr.extHdr.pdcpNmb.val = (tmpByte[1] << 8) | tmpByte[2];
1022 } /* End of switch */
1024 ODU_REM_PRE_MSG(&extHdrType, mBuf);
1026 } /* End of while */
1028 /****************************************************************************
1029 * If extPres is true, but E bit is not set, implies, either of PN or S bit
1030 * was set during Encode so accordingly extract Byte fields for extension
1032 ***************************************************************************/
1035 ODU_REM_PRE_MSG(&extHdrType, mBuf);
1038 egtpMsg->msg = mBuf;
1040 DU_LOG("\nEGTP : DL Data Buffer after decoding header ");
1041 ODU_PRINT_MSG(mBuf, 0, 0);
1043 /* Forward the data to duApp/RLC */
1048 /**********************************************************************
1050 **********************************************************************/