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\nDEBUG --> EGTP : Initializing");
59 memset (&egtpCb, 0, sizeof(EgtpGlobalCb));
60 protType = CM_INET_PROTO_UDP;
67 /**************************************************************************
68 * @brief Task Activation callback function.
72 * Function : egtpActvTsk
75 * This function handles all EGTP messages received
76 * This API is registered with SSI during the
77 * Task Registration of DU APP.
79 * @param[in] Pst *pst, Post structure of the primitive.
80 * @param[in] Buffer *mBuf, Packed primitive parameters in the
82 * @return ROK - success
85 ***************************************************************************/
86 uint8_t egtpActvTsk(Pst *pst, Buffer *mBuf)
98 ret = unpackEgtpCfgReq(egtpCfgReq, pst, mBuf);
103 ret = unpackEgtpSrvOpenReq(egtpSrvOpenReq, pst, mBuf);
108 ret = unpackEgtpTnlMgmtReq(egtpTnlMgmtReq, pst, mBuf);
113 DU_LOG("\nERROR --> EGTP : Invalid event %d", pst->event);
114 ODU_PUT_MSG_BUF(mBuf);
126 DU_LOG("\nDEBUG --> EGTP : Starting Socket Polling");
128 ODU_PUT_MSG_BUF(mBuf);
133 DU_LOG("\nERROR --> EGTP : Invalid event %d", pst->event);
134 ODU_PUT_MSG_BUF(mBuf);
151 DU_LOG("\nERROR --> EGTP : Invalid event %d", pst->event);
159 DU_LOG("\nERROR --> EGTP : Invalid source entity %d", pst->srcEnt);
167 /**************************************************************************
168 * @brief EGTP server configuration
172 * Function : egtpCfgReq
175 * This function handles EGTP configuration request.
177 * @return ROK - success
180 * ***********************************************************************/
181 uint8_t egtpCfgReq(Pst *pst, EgtpConfig egtpCfg)
183 uint8_t ret; /* Return value */
184 Pst rspPst; /* Response Pst structure */
185 CmStatus cfgCfm; /* Configuration Confirm */
187 memcpy(&egtpCb.egtpCfg, &egtpCfg, sizeof(EgtpConfig));
189 egtpCb.recvTptSrvr.addr.address = CM_INET_NTOH_UINT32(egtpCb.egtpCfg.localIp.ipV4Addr);
190 egtpCb.recvTptSrvr.addr.port = EGTP_DFLT_PORT;
192 egtpCb.dstCb.dstIp = CM_INET_NTOH_UINT32(egtpCb.egtpCfg.destIp.ipV4Addr);
193 egtpCb.dstCb.dstPort = egtpCb.egtpCfg.destPort;
194 egtpCb.dstCb.sendTptSrvr.addr.address = CM_INET_NTOH_UINT32(egtpCb.egtpCfg.localIp.ipV4Addr);
195 egtpCb.dstCb.sendTptSrvr.addr.port = egtpCb.egtpCfg.localPort;
196 egtpCb.dstCb.numTunn = 0;
198 ret = cmHashListInit(&(egtpCb.dstCb.teIdLst), 1024, sizeof(EgtpTeIdCb), FALSE, CM_HASH_KEYTYPE_UINT32_MOD, DU_APP_MEM_REGION, DU_POOL);
202 DU_LOG("\nERROR --> EGTP : TeId hash list initialization failed");
203 cfgCfm.status = LCM_PRIM_NOK;
204 cfgCfm.reason = LCM_REASON_HASHING_FAILED;
208 DU_LOG("\nDEBUG --> EGTP : EGTP configuration successful");
209 cfgCfm.status = LCM_PRIM_OK;
210 cfgCfm.reason = LCM_REASON_NOT_APPL;
213 /* Fill response Pst */
214 egtpFillRspPst(pst, &rspPst);
215 rspPst.event = EVTCFGCFM;
217 packEgtpCfgCfm(&rspPst, cfgCfm);
222 /**************************************************************************
223 * @brief Fills post structure to send response
227 * Function : egtpFillRspPst
230 * Fills post struture to send response
232 * @return ROK - success
236 * ***********************************************************************/
237 uint8_t egtpFillRspPst(Pst *pst, Pst *rspPst)
240 memset(rspPst, 0, sizeof(Pst));
241 rspPst->srcEnt = pst->dstEnt;
242 rspPst->srcInst = pst->dstInst;
243 rspPst->srcProcId = pst->dstProcId;
244 rspPst->dstEnt = pst->srcEnt;
245 rspPst->dstInst = pst->srcInst;
246 rspPst->dstProcId = pst->srcProcId;
247 rspPst->selector = ODU_SELECTOR_LC;
248 rspPst->pool= DU_POOL;
253 /**************************************************************************
254 * @brief EGTP server open request
258 * Function : egtpSrvOpenReq
261 * This function handles EGTP open server request.
262 * It opens udp socket to receive/send msgs.
264 * @param[in] Pst *pst, post structure
265 * @return ROK - success
268 ***************************************************************************/
270 uint8_t egtpSrvOpenReq(Pst *pst)
273 uint8_t ret; /* Return value */
274 Pst rspPst; /* Response Pst structure */
275 Pst egtpPst; /* Self post */
276 CmStatus cfm; /* Confirmation status */
277 uint8_t sockType; /* Socket type */
279 DU_LOG("\nDEBUG --> EGTP : Received EGTP open server request");
281 sockType = CM_INET_DGRAM;
282 ret = egtpSrvOpenPrc(sockType, &(egtpCb.recvTptSrvr));
283 /* Opening and Binding receiver socket */
286 DU_LOG("\nERROR --> EGTP : Failed while opening receiver transport server");
289 /* Opening and Binding sender socket */
290 ret = egtpSrvOpenPrc(sockType, &(egtpCb.dstCb.sendTptSrvr));
293 DU_LOG("\nERROR --> EGTP : Failed while opening sender transport server");
297 DU_LOG("\nDEBUG --> EGTP : Receiver socket[%d] and Sender socket[%d] open", egtpCb.recvTptSrvr.sockFd.fd,\
298 egtpCb.dstCb.sendTptSrvr.sockFd.fd);
300 /* Start Socket polling */
301 memset(&egtpPst, 0, sizeof(egtpPst));
302 egtpPst.srcEnt = (Ent)ENTEGTP;
303 egtpPst.srcInst = (Inst)EGTP_INST;
304 egtpPst.srcProcId = DU_PROC;
305 egtpPst.dstEnt = (Ent)ENTEGTP;
306 egtpPst.dstInst = (Inst)EGTP_INST;
307 egtpPst.dstProcId = DU_PROC;
308 egtpPst.event = EVTSTARTPOLL;
309 egtpPst.selector = ODU_SELECTOR_LC;
310 egtpPst.pool= DU_POOL;
311 packEgtpStartPollingReq(&egtpPst);
313 /* Filling and sending response */
314 cfm.status = LCM_PRIM_OK;
315 cfm.reason = LCM_REASON_NOT_APPL;
317 egtpFillRspPst(pst, &rspPst);
318 rspPst.event = EVTSRVOPENCFM;
319 packEgtpSrvOpenCfm(&rspPst, cfm);
324 /*******************************************************************
326 * @brief Processing Sever open request
330 * Function : egtpSrvOpenPrc
336 * @return ROK - success
339 * ****************************************************************/
341 uint8_t egtpSrvOpenPrc(uint8_t sockType, EgtpTptSrvr *server)
344 ret = cmInetSocket(sockType, &(server->sockFd), protType);
347 DU_LOG("\nERROR --> EGTP : Failed to open UDP socket");
350 ret = cmInetBind(&(server->sockFd), &(server->addr));
353 DU_LOG("\nERROR --> EGTP : Failed to bind socket");
360 /**************************************************************************
361 * @brief EGTP tunnel management request
365 * Function : egtpTnlMgmtReq
368 * This function handles EGTP tunnel managament request
370 * @param[in] Tunnel Eveny structure
371 * @return ROK - success
375 * ***************************************************************************/
376 uint8_t egtpTnlMgmtReq(Pst *pst, EgtpTnlEvt tnlEvt)
380 DU_LOG("\nDEBUG --> EGTP : Received tunnel management request");
381 switch(tnlEvt.action)
383 case EGTP_TNL_MGMT_ADD:
385 ret = egtpTnlAdd(tnlEvt);
388 case EGTP_TNL_MGMT_MOD:
390 ret = egtpTnlMod(tnlEvt);
393 case EGTP_TNL_MGMT_DEL:
395 ret = egtpTnlDel(tnlEvt);
400 DU_LOG("\nERROR --> EGTP : Invalid tunnel management action[%d]", tnlEvt.action);
401 ret = LCM_REASON_INVALID_ACTION;
407 tnlEvt.cfmStatus.status = LCM_PRIM_OK;
408 tnlEvt.cfmStatus.reason = LCM_REASON_NOT_APPL;
412 tnlEvt.cfmStatus.status = LCM_PRIM_NOK;
413 tnlEvt.cfmStatus.reason = ret;
416 DU_LOG("\nDEBUG --> EGTP : Sending Tunnel management confirmation");
417 duHdlEgtpTnlMgmtCfm(tnlEvt);
422 /**************************************************************************
423 * @brief EGTP tunnel addition
427 * Function : egtpTnlAdd
430 * This function handles EGTP tunnel addition
432 * @param[in] Tunnel Event structure
433 * @return ROK - success
436 * ***************************************************************************/
437 uint8_t egtpTnlAdd(EgtpTnlEvt tnlEvt)
440 EgtpTeIdCb *teidCb; /* Tunnel endpoint control block */
441 EgtpMsgHdr preDefHdr; /* pre-define header for this tunnel */
443 DU_LOG("\nINFO --> EGTP : Tunnel addition : LocalTeid[%d] Remote Teid[%d]", tnlEvt.lclTeid, tnlEvt.remTeid);
445 DU_ALLOC(teidCb, sizeof(EgtpTeIdCb));
448 DU_LOG("\nERROR --> EGTP : Memory allocation failed");
449 return LCM_REASON_MEM_NOAVAIL;
452 memset(teidCb, 0, sizeof(EgtpTeIdCb));
453 teidCb->teId = tnlEvt.lclTeid;
454 teidCb->remTeId = tnlEvt.remTeid;
456 ret = cmHashListInsert(&(egtpCb.dstCb.teIdLst), (PTR)teidCb, (uint8_t *)&(teidCb->teId), sizeof(uint32_t));
459 DU_LOG("\nERROR --> EGTP : Failed to insert in hash list");
460 DU_FREE(teidCb, sizeof(EgtpTeIdCb));
461 return LCM_REASON_HASHING_FAILED;
463 egtpCb.dstCb.numTunn++;
465 /* Encoding pre-defined header */
466 memset(&preDefHdr, 0, sizeof(EgtpMsgHdr));
467 preDefHdr.msgType = EGTPU_MSG_GPDU;
468 preDefHdr.teId = teidCb->remTeId;
469 preDefHdr.extHdr.pdcpNmb.pres = FALSE;
470 preDefHdr.extHdr.udpPort.pres = FALSE;
471 preDefHdr.nPdu.pres = FALSE;
473 egtpEncodeHdr((uint8_t *)teidCb->preEncodedHdr.hdr, &preDefHdr, &(teidCb->preEncodedHdr.cnt));
478 /**************************************************************************
479 * @brief EGTP tunnel modification
483 * Function : egtpTnlMod
486 * This function handles EGTP tunnel modification
488 * @param[in] Tunnel Event structure
489 * @return ROK - success
492 * ***************************************************************************/
493 uint8_t egtpTnlMod(EgtpTnlEvt tnlEvt)
495 EgtpTeIdCb *teidCb = NULLP;
497 DU_LOG("\nINFO --> EGTP : Tunnel modification : LocalTeid[%d] Remote Teid[%d]", tnlEvt.lclTeid, tnlEvt.remTeid);
499 cmHashListFind(&(egtpCb.dstCb.teIdLst), (uint8_t *)&(tnlEvt.lclTeid), sizeof(uint32_t), 0, (PTR *)&teidCb);
502 DU_LOG("\nERROR --> EGTP : Tunnel id not found");
505 teidCb->teId = tnlEvt.remTeid;
506 teidCb->remTeId = tnlEvt.remTeid;
510 /**************************************************************************
511 * @brief EGTP tunnel deletion
515 * Function : egtpTnlDel
518 * This function handles EGTP tunnel deletion
520 * @param[in] Tunnel Event structure
521 * @return ROK - success
524 * ***************************************************************************/
525 uint8_t egtpTnlDel(EgtpTnlEvt tnlEvt)
527 EgtpTeIdCb *teidCb = NULLP;
529 DU_LOG("\nINFO --> EGTP : Tunnel deletion : Local Teid[%d] Remote Teid[%d]", tnlEvt.lclTeid, tnlEvt.remTeid);
531 cmHashListFind(&(egtpCb.dstCb.teIdLst), (uint8_t *)&(tnlEvt.lclTeid), sizeof(uint32_t), 0, (PTR *)&teidCb);
534 DU_LOG("\nERROR --> EGTP : Tunnel id[%d] not configured", tnlEvt.lclTeid);
535 return LCM_REASON_INVALID_PAR_VAL;
538 cmHashListDelete(&(egtpCb.dstCb.teIdLst), (PTR)teidCb);
539 DU_FREE(teidCb, sizeof(EgtpTeIdCb));
540 egtpCb.dstCb.numTunn--;
544 /*******************************************************************
546 * @brief Handles data indication
550 * Function : EgtpHdlDatInd
553 * Handles incoming data from peer to be passed
557 * @return ROK - success
560 * ****************************************************************/
561 uint8_t egtpHdlDatInd(EgtpMsg egtpMsg)
563 EgtpTeIdCb *teidCb = NULLP;
569 DU_LOG("\nDEBUG --> EGTP : Received Data Indication");
571 cmHashListFind(&(egtpCb.dstCb.teIdLst), (uint8_t *)&(egtpMsg.msgHdr.teId), sizeof(uint32_t), 0, (PTR *)&teidCb);
574 DU_LOG("\nERROR --> EGTP : Tunnel id[%d] not configured", egtpMsg.msgHdr.teId);
575 return LCM_REASON_INVALID_PAR_VAL;
578 msgHdr = &(egtpMsg.msgHdr);
580 hdrLen = teidCb->preEncodedHdr.cnt;
582 if(msgHdr->extHdr.pdcpNmb.pres)
584 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] |= EGTP_MASK_BIT3;
585 teidCb->preEncodedHdr.hdr[hdrLen] = EGTP_EXT_HDR_PDCP_TYPE;
586 teidCb->preEncodedHdr.hdr[--hdrLen] = 1;
587 teidCb->preEncodedHdr.hdr[--hdrLen] = GetHiByte(msgHdr->extHdr.pdcpNmb.val);
588 teidCb->preEncodedHdr.hdr[--hdrLen] = GetLoByte(msgHdr->extHdr.pdcpNmb.val);
589 teidCb->preEncodedHdr.hdr[--hdrLen] = 0;
593 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] &= ~(EGTP_MASK_BIT3);
596 ODU_GET_MSG_LEN(egtpMsg.msg, (int16_t *)&tPduSize);
598 /*Adjust the header to fill the correct length*/
599 msgLen = tPduSize + (EGTP_MAX_HDR_LEN - hdrLen) - 0x08;
601 /***********************************************
602 * Fill the length field of the message header *
603 ***********************************************/
604 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 3] = (uint8_t)GetHiByte(msgLen);
605 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 4] = (uint8_t)GetLoByte(msgLen);
607 /*Update the sequence number*/
608 if(egtpMsg.msgHdr.seqNum.pres)
610 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] |= (EGTP_MASK_BIT2);
611 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 9] = (uint8_t)GetHiByte(egtpMsg.msgHdr.seqNum.val);
612 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 10] = (uint8_t)GetLoByte(egtpMsg.msgHdr.seqNum.val);
616 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] &= ~(EGTP_MASK_BIT2);
619 DU_LOG("\nDEBUG --> EGTP : UL Data buffer before encoding header");
620 ODU_PRINT_MSG(egtpMsg.msg, 0, 0);
622 ODU_ADD_PRE_MSG_MULT(&teidCb->preEncodedHdr.hdr[hdrLen], (EGTP_MAX_HDR_LEN - hdrLen), egtpMsg.msg);
625 DU_LOG("\nDEBUG --> EGTP : UL Data buffer after encoding header");
626 ODU_PRINT_MSG(egtpMsg.msg, 0, 0);
629 egtpSendMsg(egtpMsg.msg);
630 ODU_PUT_MSG_BUF(egtpMsg.msg);
635 /*******************************************************************
637 * @brief Encodes outgoing message
641 * Function : egtpEncodeMsg
644 * Encodes EGTP message to be sent
646 * @params[in] EGTP message
648 * @return ROK - success
651 * ****************************************************************/
652 uint8_t egtpEncodeHdr(uint8_t *preEncodedHdr, EgtpMsgHdr *preDefHdr, uint8_t *hdrIdx)
654 uint8_t tmpByte = 0; /* Stores one byte of data for enc */
655 uint8_t cnt = EGTP_MAX_HDR_LEN; /* Stores the position */
656 bool extPres = FALSE; /* Flag for indication of S, E or P presense flag */
659 /* Encoding header */
660 tmpByte |= EGTP_MASK_BIT6; /* Setting 6th LSB of 1st byte as version */
661 tmpByte |= EGTP_MASK_BIT5; /* Setting 5th LSB of 1st byte as protocol type */
663 if(preDefHdr->extHdr.udpPort.pres || preDefHdr->extHdr.pdcpNmb.pres)
665 tmpByte |= EGTP_MASK_BIT3; /* Setting 3rd LSB of 1st byte if Extension heaeder is present */
668 if(preDefHdr->seqNum.pres)
670 tmpByte |= EGTP_MASK_BIT2;
673 if(preDefHdr->nPdu.pres)
675 tmpByte |= EGTP_MASK_BIT1;
678 if((tmpByte & EGTP_MASK_BIT1) || (tmpByte & EGTP_MASK_BIT2)||(tmpByte & EGTP_MASK_BIT3))
683 preEncodedHdr[--cnt] = tmpByte;
684 preEncodedHdr[--cnt] = preDefHdr->msgType;
686 /* Encode Tunnel endpoint */
687 preEncodedHdr[--cnt] = 0;
688 preEncodedHdr[--cnt] = 0;
689 nwWord = (uint16_t)(GetHiWord(preDefHdr->teId));
690 preEncodedHdr[--cnt] = (uint8_t)(GetHiByte(nwWord));
691 preEncodedHdr[--cnt] = (uint8_t)(GetLoByte(nwWord));
692 nwWord = (uint16_t)(GetLoWord(preDefHdr->teId));
693 preEncodedHdr[--cnt] = (uint8_t)(GetHiByte(nwWord));
694 preEncodedHdr[--cnt] = (uint8_t)(GetLoByte(nwWord));
696 /* Encode sequence number */
697 if(preDefHdr->seqNum.pres)
699 preEncodedHdr[--cnt] = GetHiByte(preDefHdr->seqNum.val);
700 preEncodedHdr[--cnt] = GetLoByte(preDefHdr->seqNum.val);
704 preEncodedHdr[--cnt] = 0;
705 preEncodedHdr[--cnt] = 0;
708 /* Encode nPdu number */
709 if(preDefHdr->nPdu.pres)
711 preEncodedHdr[--cnt] = preDefHdr->nPdu.val;
715 preEncodedHdr[--cnt] = 0;
718 if(preDefHdr->extHdr.udpPort.pres)
720 preEncodedHdr[--cnt] = EGTP_EXT_HDR_UDP_TYPE;
721 preEncodedHdr[--cnt] = 1;
722 preEncodedHdr[--cnt] = GetHiByte(preDefHdr->extHdr.udpPort.val);
723 preEncodedHdr[--cnt] = GetLoByte(preDefHdr->extHdr.udpPort.val);
726 if(preDefHdr->extHdr.pdcpNmb.pres)
728 preEncodedHdr[--cnt] = EGTP_EXT_HDR_PDCP_TYPE;
729 preEncodedHdr[--cnt] = 1;
730 preEncodedHdr[--cnt] = GetHiByte(preDefHdr->extHdr.pdcpNmb.val);
731 preEncodedHdr[--cnt] = GetLoByte(preDefHdr->extHdr.pdcpNmb.val);
734 if(tmpByte & EGTP_MASK_BIT3)
736 preEncodedHdr[--cnt] = 0;
740 preEncodedHdr[--cnt] = 0;
745 } /* egtpEncodeHdr */
747 /*******************************************************************
749 * @brief Sends message over UDP
753 * Function : egtpSendMsg
756 * Sends message over UDP
758 * @params[in] Message Buffer
759 * @return ROK - success
762 * ****************************************************************/
763 uint8_t egtpSendMsg(Buffer *mBuf)
770 info.region = DU_APP_MEM_REGION;
773 dstAddr.port = EGTP_DFLT_PORT;
774 dstAddr.address = egtpCb.dstCb.dstIp;
776 ret = cmInetSendMsg(&(egtpCb.dstCb.sendTptSrvr.sockFd), &dstAddr, &info, \
777 mBuf, (int16_t *)&txLen, CM_INET_NO_FLAG);
778 if(ret != ROK && ret != RWOULDBLOCK)
780 DU_LOG("\nERROR --> EGTP : Failed sending the message");
784 DU_LOG("\nDEBUG --> EGTP : Message Sent");
789 /*******************************************************************
791 * @brief Receives EGTP message from UDP socket
795 * Function : egtpRecvMsg
798 * Receive incoming messages from UDP socket
801 * @return ROK - success
804 * ****************************************************************/
806 uint8_t egtpRecvMsg()
808 uint8_t ret; /* Return value */
809 uint16_t bufLen; /* Length of received buffer */
810 Buffer *recvBuf; /* Received buffer */
811 CmInetAddr fromAddr; /* Egtp data sender address */
812 CmInetMemInfo memInfo; /* Buffer allocation info */
814 memInfo.region = DU_APP_MEM_REGION;
815 memInfo.pool = DU_POOL;
817 fromAddr.port = egtpCb.dstCb.dstPort;
818 fromAddr.address = egtpCb.dstCb.dstIp;
823 ret = cmInetRecvMsg(&(egtpCb.recvTptSrvr.sockFd), &fromAddr, &memInfo, \
824 &recvBuf, (int16_t *)&bufLen, CM_INET_NO_FLAG);
825 if(ret == ROK && recvBuf != NULLP)
827 //DU_LOG("\nDEBUG --> EGTP : Received DL Message[%ld]\n", gDlDataRcvdCnt + 1);
828 //ODU_PRINT_MSG(recvBuf, 0 ,0);
829 egtpHdlRecvData(recvBuf);
837 /*******************************************************************
839 * @brief Handles DL User data received from CU
843 * Function : egtpHdlRecvData
845 * Functionality: Handles DL User data received from CU
847 * @params[in] DL Usre data buffer
848 * @return ROK - success
851 * ****************************************************************/
852 uint8_t egtpHdlRecvData(Buffer *mBuf)
856 /* Decode EGTP header */
857 egtpDecodeHdr(mBuf, &egtpMsg);
859 /* TODO : Send received message to RLC */
860 duHdlEgtpDlData(&egtpMsg);
865 /*******************************************************************
867 * @brief Decodes EGTP header from DL User data
871 * Function : egtpDecodeHdr
873 * Functionality: Decodes EGTP header from DL User data
876 * @return ROK - success
879 * ****************************************************************/
880 uint8_t egtpDecodeHdr(Buffer *mBuf, EgtpMsg *egtpMsg)
882 uint8_t tmpByte[5]; /* Holds 5 byte of data after Decoding */
883 uint8_t version = 0; /* Holds the version type, decoded */
884 uint16_t msgLen = 0; /* Holds the msgLen from the Hdr */
885 uint16_t bufLen = 0; /* Holds the total buffer length */
886 uint8_t extHdrType = 0; /* Holds the Extension hdr type */
887 uint8_t extHdrLen = 0; /* Extension hdr length */
888 bool extPres = FALSE; /* Flag for indication of S, E or P presense flag */
890 ODU_GET_MSG_LEN(mBuf, (int16_t *)&bufLen);
892 /* Decode first byte and storing in temporary variable */
893 ODU_REM_PRE_MSG(&tmpByte[0], mBuf);
895 /* Extracting version fro 1st byte */
896 version = tmpByte[0] >> 5;
898 //DU_LOG("\nDEBUG --> EGTP : Version %d", version);
900 /* Decode message type */
901 ODU_REM_PRE_MSG((Data*)&(egtpMsg->msgHdr.msgType), mBuf);
902 //DU_LOG("\nDEBUG --> EGTP : msgType %d", egtpMsg->msgHdr.msgType);
904 /****************************************************************************
905 * Message length param is 2 bytes. So decode next 2 bytes from msg hdr and
906 * performing OR operation on these two bytes to calculate message length
907 ***************************************************************************/
908 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
909 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
910 msgLen = (tmpByte[1] << 8) | tmpByte[2];
913 //DU_LOG("\nDEBUG --> EGTP : msgLen %d", msgLen);
916 /****************************************************************************
917 * Tunnel id param is 4 bytes. So decode next 4 bytes from msg hdr and
918 * perform OR operation on these 4 bytes to calculate tunnel id
919 ***************************************************************************/
920 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
921 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
922 ODU_REM_PRE_MSG(&tmpByte[3], mBuf);
923 ODU_REM_PRE_MSG(&tmpByte[4], mBuf);
924 egtpMsg->msgHdr.teId = (tmpByte[1] << 24) | (tmpByte[2] << 16) | (tmpByte[3] << 8) | tmpByte[4];
925 //DU_LOG("\nDEBUG --> EGTP : teId %d",egtpMsg->msgHdr.teId);
928 /* If any one of S, E or PN flag is set, set extension present as true. */
929 if((tmpByte[0] & EGTP_MASK_BIT1) || (tmpByte[0] & EGTP_MASK_BIT2)||(tmpByte[0] & EGTP_MASK_BIT3))
934 /* Decode sequence number, if S flag is set in first byte */
935 if (tmpByte[0] & EGTP_MASK_BIT2)
937 /************************************************************************
938 * Sequence num is 2 bytes. So decode next 2 bytes from msg hdr and
939 * perform OR operation on them
940 ************************************************************************/
941 egtpMsg->msgHdr.seqNum.pres = TRUE;
942 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
943 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
944 egtpMsg->msgHdr.seqNum.val = (tmpByte[1] << 8) | tmpByte[2];
946 /****************************************************************************
947 * If extPres is true, but S bit is not set, implies, either of PN or E bit
948 * was set during Encode so accordingly extract Byte fields for seqNum anyway
949 ***************************************************************************/
952 /*************************************************************************
953 * Sequence num is 2 bytes. So decode next 2 bytes from msg hdr and
954 * perform OR operation on them
955 ************************************************************************/
956 egtpMsg->msgHdr.seqNum.pres = 0;
957 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
958 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
959 egtpMsg->msgHdr.seqNum.val = (tmpByte[1] << 8) | tmpByte[2];
962 /* Decode N-PDU number if present flag is set */
963 if (tmpByte[0] & EGTP_MASK_BIT1)
965 egtpMsg->msgHdr.nPdu.pres = TRUE;
966 ODU_REM_PRE_MSG(&(egtpMsg->msgHdr.nPdu.val), mBuf);
968 /****************************************************************************
969 * If extPres is true, but PN bit is not set, implies, either of S or E bit
970 * was set during Encode. Aaccordingly extract Byte fields of N-PDU num anyway
971 ***************************************************************************/
974 egtpMsg->msgHdr.nPdu.pres = TRUE;
975 ODU_REM_PRE_MSG(&(egtpMsg->msgHdr.nPdu.val), mBuf);
978 /* If E flag is set in first byte, decode extension header */
979 if(tmpByte[0] & EGTP_MASK_BIT3)
981 ODU_REM_PRE_MSG(&extHdrType, mBuf);
982 while( 0 != extHdrType)
986 case EGTP_EXT_HDR_UDP_TYPE:
988 ODU_REM_PRE_MSG(&extHdrLen, mBuf);
989 if(extHdrLen == 0x01)
991 /************************************************************
992 * UDP Port is 2 bytes. So decode next 2 bytes from msg hdr
993 * and perform OR operation on them
994 *************************************************************/
995 egtpMsg->msgHdr.extHdr.udpPort.pres = TRUE;
996 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
997 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
998 egtpMsg->msgHdr.extHdr.udpPort.val = (tmpByte[1] << 8) | tmpByte[2];
1003 case EGTP_EXT_HDR_PDCP_TYPE:
1005 ODU_REM_PRE_MSG(&extHdrLen, mBuf);
1006 if(extHdrLen == 0x01)
1008 /*************************************************************
1009 * PDCP num is 2 bytes. So decode next 2 bytes from msg hdr
1010 * and perform OR operation on them
1011 ************************************************************/
1012 egtpMsg->msgHdr.extHdr.pdcpNmb.pres = TRUE;
1013 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
1014 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
1015 egtpMsg->msgHdr.extHdr.pdcpNmb.val = (tmpByte[1] << 8) | tmpByte[2];
1019 } /* End of switch */
1021 ODU_REM_PRE_MSG(&extHdrType, mBuf);
1023 } /* End of while */
1025 /****************************************************************************
1026 * If extPres is true, but E bit is not set, implies, either of PN or S bit
1027 * was set during Encode so accordingly extract Byte fields for extension
1029 ***************************************************************************/
1032 ODU_REM_PRE_MSG(&extHdrType, mBuf);
1035 egtpMsg->msg = mBuf;
1037 //DU_LOG("\nDEBUG --> EGTP : DL Data Buffer after decoding header ");
1038 //ODU_PRINT_MSG(mBuf, 0, 0);
1040 /* Forward the data to duApp/RLC */
1045 /**********************************************************************
1047 **********************************************************************/