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"
28 #include "du_app_mac_inf.h"
29 #include "du_e2ap_mgr.h"
32 #include "du_app_rlc_inf.h"
37 uint8_t unpackEgtpSrvOpenReq(EgtpSrvOpenReq func, Pst *pst, Buffer *mBuf);
39 EgtpGlobalCb egtpCb; /* EGTP global control block */
40 /**************************************************************************
41 * @brief Task Initiation callback function.
45 * Function : egtpActvInit
48 * This function is supplied as one of parameters during EGTP's
49 * task registration. SSI will invoke this function once, after
50 * it creates and attaches this TAPA Task to a system task.
52 * @param[in] Ent entity, the entity ID of this task.
53 * @param[in] Inst inst, the instance ID of this task.
54 * @param[in] Region region, the region ID registered for memory
56 * @param[in] Reason reason.
57 * @return ROK - success
59 ***************************************************************************/
60 uint8_t egtpActvInit(Ent entity, Inst inst, Region region, Reason reason)
62 DU_LOG("\n\nDEBUG --> EGTP : Initializing");
64 memset (&egtpCb, 0, sizeof(EgtpGlobalCb));
65 protType = CM_INET_PROTO_UDP;
66 gConfigInfo.gDlDataRcvdCnt = 0;
71 #ifdef CALL_FLOW_DEBUG_LOG
72 /**************************************************************************
73 * @brief Function prints the src dest and msg reached to egtp.
77 * Function : callFlowEgtpActvTsk
80 * Function prints the src dest and msg reached to egtp.
82 * @param[in] Pst *pst, Post structure of the primitive.
86 ***************************************************************************/
88 void callFlowEgtpActvTsk(Pst *pst)
92 char destTask[50]="ENTEGTP";
99 strcpy(sourceTask,"ENTDUAPP");
104 strcpy(message,"EVTCFGREQ");
109 strcpy(message,"EVTSRVOPENREQ");
114 strcpy(message,"EVTTNLMGMTREQ");
119 strcpy(message,"Invalid Event");
127 strcpy(sourceTask,"ENTEGTP");
132 strcpy(message,"EVTSTARTPOLL");
137 strcpy(message,"Invalid Event");
145 strcpy(sourceTask,"ENTRLC");
150 strcpy(message,"EVTDATIND");
155 strcpy(message,"Invalid Event");
163 strcpy(sourceTask,"Invalid Source Entity Id");
166 DU_LOG("\nCall Flow: %s -> %s : %s\n", sourceTask, destTask, message);
170 /**************************************************************************
171 * @brief Task Activation callback function.
175 * Function : egtpActvTsk
178 * This function handles all EGTP messages received
179 * This API is registered with SSI during the
180 * Task Registration of DU APP.
182 * @param[in] Pst *pst, Post structure of the primitive.
183 * @param[in] Buffer *mBuf, Packed primitive parameters in the
185 * @return ROK - success
188 ***************************************************************************/
189 uint8_t egtpActvTsk(Pst *pst, Buffer *mBuf)
193 #ifdef CALL_FLOW_DEBUG_LOG
194 callFlowEgtpActvTsk(pst);
205 ret = unpackEgtpCfgReq(egtpCfgReq, pst, mBuf);
210 ret = unpackEgtpSrvOpenReq(egtpSrvOpenReq, pst, mBuf);
215 ret = unpackEgtpTnlMgmtReq(egtpTnlMgmtReq, pst, mBuf);
220 DU_LOG("\nERROR --> EGTP : Invalid event %d", pst->event);
221 ODU_PUT_MSG_BUF(mBuf);
233 DU_LOG("\nDEBUG --> EGTP : Starting Socket Polling");
235 ODU_PUT_MSG_BUF(mBuf);
240 DU_LOG("\nERROR --> EGTP : Invalid event %d", pst->event);
241 ODU_PUT_MSG_BUF(mBuf);
258 DU_LOG("\nERROR --> EGTP : Invalid event %d", pst->event);
266 DU_LOG("\nERROR --> EGTP : Invalid source entity %d", pst->srcEnt);
274 /**************************************************************************
275 * @brief EGTP server configuration
279 * Function : egtpCfgReq
282 * This function handles EGTP configuration request.
284 * @return ROK - success
287 * ***********************************************************************/
288 uint8_t egtpCfgReq(Pst *pst, EgtpConfig egtpCfg)
290 uint8_t ret; /* Return value */
291 Pst rspPst; /* Response Pst structure */
292 CmStatus cfgCfm; /* Configuration Confirm */
294 memcpy(&egtpCb.egtpCfg, &egtpCfg, sizeof(EgtpConfig));
296 egtpCb.localAddr.address = CM_INET_NTOH_UINT32(egtpCb.egtpCfg.localIp.ipV4Addr);
297 egtpCb.localAddr.port = egtpCb.egtpCfg.localPort;
299 egtpCb.dstCb.dstAddr.address = CM_INET_NTOH_UINT32(egtpCb.egtpCfg.destIp.ipV4Addr);
300 egtpCb.dstCb.dstAddr.port = egtpCb.egtpCfg.destPort;
301 egtpCb.dstCb.numTunn = 0;
303 ret = cmHashListInit(&(egtpCb.dstCb.teIdLst), 1024, sizeof(EgtpTeIdCb), FALSE, CM_HASH_KEYTYPE_UINT32_MOD, DU_APP_MEM_REGION, DU_POOL);
307 DU_LOG("\nERROR --> EGTP : TeId hash list initialization failed");
308 cfgCfm.status = LCM_PRIM_NOK;
309 cfgCfm.reason = LCM_REASON_HASHING_FAILED;
313 DU_LOG("\nDEBUG --> EGTP : EGTP configuration successful");
314 cfgCfm.status = LCM_PRIM_OK;
315 cfgCfm.reason = LCM_REASON_NOT_APPL;
318 /* Fill response Pst */
319 egtpFillRspPst(pst, &rspPst);
320 rspPst.event = EVTCFGCFM;
322 packEgtpCfgCfm(&rspPst, cfgCfm);
327 /**************************************************************************
328 * @brief Fills post structure to send response
332 * Function : egtpFillRspPst
335 * Fills post struture to send response
337 * @return ROK - success
341 * ***********************************************************************/
342 uint8_t egtpFillRspPst(Pst *pst, Pst *rspPst)
345 memset(rspPst, 0, sizeof(Pst));
346 rspPst->srcEnt = pst->dstEnt;
347 rspPst->srcInst = pst->dstInst;
348 rspPst->srcProcId = pst->dstProcId;
349 rspPst->dstEnt = pst->srcEnt;
350 rspPst->dstInst = pst->srcInst;
351 rspPst->dstProcId = pst->srcProcId;
352 rspPst->selector = ODU_SELECTOR_LC;
353 rspPst->pool= DU_POOL;
358 /**************************************************************************
359 * @brief EGTP server open request
363 * Function : egtpSrvOpenReq
366 * This function handles EGTP open server request.
367 * It opens udp socket to receive/send msgs.
369 * @param[in] Pst *pst, post structure
370 * @return ROK - success
373 ***************************************************************************/
375 uint8_t egtpSrvOpenReq(Pst *pst)
378 uint8_t ret; /* Return value */
379 Pst rspPst; /* Response Pst structure */
380 Pst egtpPst; /* Self post */
381 CmStatus cfm; /* Confirmation status */
382 uint8_t sockType; /* Socket type */
384 DU_LOG("\nDEBUG --> EGTP : Received EGTP open server request");
386 sockType = CM_INET_DGRAM;
387 ret = egtpSrvOpenPrc(sockType);
388 /* Opening and Binding receiver socket */
391 DU_LOG("\nERROR --> EGTP : Failed while opening receiver transport server");
395 DU_LOG("\nDEBUG --> EGTP : Socket [%d] is open", egtpCb.sockFd.fd);
397 /* Start Socket polling */
398 memset(&egtpPst, 0, sizeof(egtpPst));
399 egtpPst.srcEnt = (Ent)ENTEGTP;
400 egtpPst.srcInst = (Inst)EGTP_INST;
401 egtpPst.srcProcId = DU_PROC;
402 egtpPst.dstEnt = (Ent)ENTEGTP;
403 egtpPst.dstInst = (Inst)EGTP_INST;
404 egtpPst.dstProcId = DU_PROC;
405 egtpPst.event = EVTSTARTPOLL;
406 egtpPst.selector = ODU_SELECTOR_LC;
407 egtpPst.pool= DU_POOL;
408 packEgtpStartPollingReq(&egtpPst);
410 /* Filling and sending response */
411 cfm.status = LCM_PRIM_OK;
412 cfm.reason = LCM_REASON_NOT_APPL;
414 egtpFillRspPst(pst, &rspPst);
415 rspPst.event = EVTSRVOPENCFM;
416 packEgtpSrvOpenCfm(&rspPst, cfm);
421 /*******************************************************************
423 * @brief Processing Sever open request
427 * Function : egtpSrvOpenPrc
433 * @return ROK - success
436 * ****************************************************************/
438 uint8_t egtpSrvOpenPrc(uint8_t sockType)
441 ret = cmInetSocket(sockType, &(egtpCb.sockFd), protType);
444 DU_LOG("\nERROR --> EGTP : Failed to open UDP socket");
447 ret = cmInetBind(&(egtpCb.sockFd), &(egtpCb.localAddr));
450 DU_LOG("\nERROR --> EGTP : Failed to bind socket");
457 /**************************************************************************
458 * @brief EGTP tunnel management request
462 * Function : egtpTnlMgmtReq
465 * This function handles EGTP tunnel managament request
467 * @param[in] Tunnel Eveny structure
468 * @return ROK - success
472 * ***************************************************************************/
473 uint8_t egtpTnlMgmtReq(Pst *pst, EgtpTnlEvt tnlEvt)
477 #ifdef CALL_FLOW_DEBUG_LOG
478 DU_LOG("\nCall Flow: ENTDUAPP -> ENTEGTP : TNL_MGMT\n");
481 DU_LOG("\nDEBUG --> EGTP : Received tunnel management request");
482 switch(tnlEvt.action)
484 case EGTP_TNL_MGMT_ADD:
486 ret = egtpTnlAdd(tnlEvt);
489 case EGTP_TNL_MGMT_MOD:
491 ret = egtpTnlMod(tnlEvt);
494 case EGTP_TNL_MGMT_DEL:
496 ret = egtpTnlDel(tnlEvt);
501 DU_LOG("\nERROR --> EGTP : Invalid tunnel management action[%d]", tnlEvt.action);
502 ret = LCM_REASON_INVALID_ACTION;
508 tnlEvt.cfmStatus.status = LCM_PRIM_OK;
509 tnlEvt.cfmStatus.reason = LCM_REASON_NOT_APPL;
513 tnlEvt.cfmStatus.status = LCM_PRIM_NOK;
514 tnlEvt.cfmStatus.reason = ret;
517 DU_LOG("\nDEBUG --> EGTP : Sending Tunnel management confirmation");
518 duHdlEgtpTnlMgmtCfm(tnlEvt);
523 /**************************************************************************
524 * @brief EGTP tunnel addition
528 * Function : egtpTnlAdd
531 * This function handles EGTP tunnel addition
533 * @param[in] Tunnel Event structure
534 * @return ROK - success
537 * ***************************************************************************/
538 uint8_t egtpTnlAdd(EgtpTnlEvt tnlEvt)
541 EgtpTeIdCb *teidCb; /* Tunnel endpoint control block */
542 EgtpMsgHdr preDefHdr; /* pre-define header for this tunnel */
544 DU_LOG("\nINFO --> EGTP : Tunnel addition : LocalTeid[%d] Remote Teid[%d]", tnlEvt.lclTeid, tnlEvt.remTeid);
546 DU_ALLOC(teidCb, sizeof(EgtpTeIdCb));
549 DU_LOG("\nERROR --> EGTP : Memory allocation failed");
550 return LCM_REASON_MEM_NOAVAIL;
553 memset(teidCb, 0, sizeof(EgtpTeIdCb));
554 teidCb->teId = tnlEvt.lclTeid;
555 teidCb->remTeId = tnlEvt.remTeid;
557 ret = cmHashListInsert(&(egtpCb.dstCb.teIdLst), (PTR)teidCb, (uint8_t *)&(teidCb->teId), sizeof(uint32_t));
560 DU_LOG("\nERROR --> EGTP : Failed to insert in hash list");
561 DU_FREE(teidCb, sizeof(EgtpTeIdCb));
562 return LCM_REASON_HASHING_FAILED;
564 egtpCb.dstCb.numTunn++;
566 /* Encoding pre-defined header */
567 memset(&preDefHdr, 0, sizeof(EgtpMsgHdr));
568 preDefHdr.msgType = EGTPU_MSG_GPDU;
569 preDefHdr.teId = teidCb->remTeId;
570 preDefHdr.extHdr.pdcpNmb.pres = FALSE;
571 preDefHdr.extHdr.udpPort.pres = FALSE;
572 preDefHdr.nPdu.pres = FALSE;
574 egtpEncodeHdr((uint8_t *)teidCb->preEncodedHdr.hdr, &preDefHdr, &(teidCb->preEncodedHdr.cnt));
579 /**************************************************************************
580 * @brief EGTP tunnel modification
584 * Function : egtpTnlMod
587 * This function handles EGTP tunnel modification
589 * @param[in] Tunnel Event structure
590 * @return ROK - success
593 * ***************************************************************************/
594 uint8_t egtpTnlMod(EgtpTnlEvt tnlEvt)
596 EgtpTeIdCb *teidCb = NULLP;
598 DU_LOG("\nINFO --> EGTP : Tunnel modification : LocalTeid[%d] Remote Teid[%d]", tnlEvt.lclTeid, tnlEvt.remTeid);
600 cmHashListFind(&(egtpCb.dstCb.teIdLst), (uint8_t *)&(tnlEvt.lclTeid), sizeof(uint32_t), 0, (PTR *)&teidCb);
603 DU_LOG("\nERROR --> EGTP : Tunnel id not found");
606 teidCb->teId = tnlEvt.remTeid;
607 teidCb->remTeId = tnlEvt.remTeid;
611 /**************************************************************************
612 * @brief EGTP tunnel deletion
616 * Function : egtpTnlDel
619 * This function handles EGTP tunnel deletion
621 * @param[in] Tunnel Event structure
622 * @return ROK - success
625 * ***************************************************************************/
626 uint8_t egtpTnlDel(EgtpTnlEvt tnlEvt)
628 EgtpTeIdCb *teidCb = NULLP;
630 DU_LOG("\nINFO --> EGTP : Tunnel deletion : Local Teid[%d] Remote Teid[%d]", tnlEvt.lclTeid, tnlEvt.remTeid);
632 cmHashListFind(&(egtpCb.dstCb.teIdLst), (uint8_t *)&(tnlEvt.lclTeid), sizeof(uint32_t), 0, (PTR *)&teidCb);
635 DU_LOG("\nERROR --> EGTP : Tunnel id[%d] not configured", tnlEvt.lclTeid);
636 return LCM_REASON_INVALID_PAR_VAL;
639 cmHashListDelete(&(egtpCb.dstCb.teIdLst), (PTR)teidCb);
640 DU_FREE(teidCb, sizeof(EgtpTeIdCb));
641 egtpCb.dstCb.numTunn--;
645 /*******************************************************************
647 * @brief Handles data indication
651 * Function : EgtpHdlDatInd
654 * Handles incoming data from peer to be passed
658 * @return ROK - success
661 * ****************************************************************/
662 uint8_t egtpHdlDatInd(EgtpMsg egtpMsg)
664 EgtpTeIdCb *teidCb = NULLP;
670 #ifdef CALL_FLOW_DEBUG_LOG
671 DU_LOG("\nCall Flow: ENTDUAPP -> ENTEGTP : DATA_INDICATION\n");
674 DU_LOG("\nDEBUG --> EGTP : Received Data Indication");
676 cmHashListFind(&(egtpCb.dstCb.teIdLst), (uint8_t *)&(egtpMsg.msgHdr.teId), sizeof(uint32_t), 0, (PTR *)&teidCb);
679 DU_LOG("\nERROR --> EGTP : Tunnel id[%d] not configured", egtpMsg.msgHdr.teId);
680 return LCM_REASON_INVALID_PAR_VAL;
683 msgHdr = &(egtpMsg.msgHdr);
685 hdrLen = teidCb->preEncodedHdr.cnt;
687 if(msgHdr->extHdr.pdcpNmb.pres)
689 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] |= EGTP_MASK_BIT3;
690 teidCb->preEncodedHdr.hdr[hdrLen] = EGTP_EXT_HDR_PDCP_TYPE;
691 teidCb->preEncodedHdr.hdr[--hdrLen] = 1;
692 teidCb->preEncodedHdr.hdr[--hdrLen] = GetHiByte(msgHdr->extHdr.pdcpNmb.val);
693 teidCb->preEncodedHdr.hdr[--hdrLen] = GetLoByte(msgHdr->extHdr.pdcpNmb.val);
694 teidCb->preEncodedHdr.hdr[--hdrLen] = 0;
698 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] &= ~(EGTP_MASK_BIT3);
701 ODU_GET_MSG_LEN(egtpMsg.msg, (int16_t *)&tPduSize);
703 /*Adjust the header to fill the correct length*/
704 msgLen = tPduSize + (EGTP_MAX_HDR_LEN - hdrLen) - 0x08;
706 /***********************************************
707 * Fill the length field of the message header *
708 ***********************************************/
709 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 3] = (uint8_t)GetHiByte(msgLen);
710 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 4] = (uint8_t)GetLoByte(msgLen);
712 /*Update the sequence number*/
713 if(egtpMsg.msgHdr.seqNum.pres)
715 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] |= (EGTP_MASK_BIT2);
716 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 9] = (uint8_t)GetHiByte(egtpMsg.msgHdr.seqNum.val);
717 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 10] = (uint8_t)GetLoByte(egtpMsg.msgHdr.seqNum.val);
721 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] &= ~(EGTP_MASK_BIT2);
724 DU_LOG("\nDEBUG --> EGTP : UL Data buffer before encoding header");
725 ODU_PRINT_MSG(egtpMsg.msg, 0, 0);
727 ODU_ADD_PRE_MSG_MULT(&teidCb->preEncodedHdr.hdr[hdrLen], (EGTP_MAX_HDR_LEN - hdrLen), egtpMsg.msg);
730 DU_LOG("\nDEBUG --> EGTP : UL Data buffer after encoding header");
731 ODU_PRINT_MSG(egtpMsg.msg, 0, 0);
734 egtpSendMsg(egtpMsg.msg);
735 ODU_PUT_MSG_BUF(egtpMsg.msg);
740 /*******************************************************************
742 * @brief Encodes outgoing message
746 * Function : egtpEncodeMsg
749 * Encodes EGTP message to be sent
751 * @params[in] EGTP message
753 * @return ROK - success
756 * ****************************************************************/
757 uint8_t egtpEncodeHdr(uint8_t *preEncodedHdr, EgtpMsgHdr *preDefHdr, uint8_t *hdrIdx)
759 uint8_t tmpByte = 0; /* Stores one byte of data for enc */
760 uint8_t cnt = EGTP_MAX_HDR_LEN; /* Stores the position */
761 bool extPres = FALSE; /* Flag for indication of S, E or P presense flag */
764 /* Encoding header */
765 tmpByte |= EGTP_MASK_BIT6; /* Setting 6th LSB of 1st byte as version */
766 tmpByte |= EGTP_MASK_BIT5; /* Setting 5th LSB of 1st byte as protocol type */
768 if(preDefHdr->extHdr.udpPort.pres || preDefHdr->extHdr.pdcpNmb.pres)
770 tmpByte |= EGTP_MASK_BIT3; /* Setting 3rd LSB of 1st byte if Extension heaeder is present */
773 if(preDefHdr->seqNum.pres)
775 tmpByte |= EGTP_MASK_BIT2;
778 if(preDefHdr->nPdu.pres)
780 tmpByte |= EGTP_MASK_BIT1;
783 if((tmpByte & EGTP_MASK_BIT1) || (tmpByte & EGTP_MASK_BIT2)||(tmpByte & EGTP_MASK_BIT3))
788 preEncodedHdr[--cnt] = tmpByte;
789 preEncodedHdr[--cnt] = preDefHdr->msgType;
791 /* Encode Tunnel endpoint */
792 preEncodedHdr[--cnt] = 0;
793 preEncodedHdr[--cnt] = 0;
794 nwWord = (uint16_t)(GetHiWord(preDefHdr->teId));
795 preEncodedHdr[--cnt] = (uint8_t)(GetHiByte(nwWord));
796 preEncodedHdr[--cnt] = (uint8_t)(GetLoByte(nwWord));
797 nwWord = (uint16_t)(GetLoWord(preDefHdr->teId));
798 preEncodedHdr[--cnt] = (uint8_t)(GetHiByte(nwWord));
799 preEncodedHdr[--cnt] = (uint8_t)(GetLoByte(nwWord));
801 /* Encode sequence number */
802 if(preDefHdr->seqNum.pres)
804 preEncodedHdr[--cnt] = GetHiByte(preDefHdr->seqNum.val);
805 preEncodedHdr[--cnt] = GetLoByte(preDefHdr->seqNum.val);
809 preEncodedHdr[--cnt] = 0;
810 preEncodedHdr[--cnt] = 0;
813 /* Encode nPdu number */
814 if(preDefHdr->nPdu.pres)
816 preEncodedHdr[--cnt] = preDefHdr->nPdu.val;
820 preEncodedHdr[--cnt] = 0;
823 if(preDefHdr->extHdr.udpPort.pres)
825 preEncodedHdr[--cnt] = EGTP_EXT_HDR_UDP_TYPE;
826 preEncodedHdr[--cnt] = 1;
827 preEncodedHdr[--cnt] = GetHiByte(preDefHdr->extHdr.udpPort.val);
828 preEncodedHdr[--cnt] = GetLoByte(preDefHdr->extHdr.udpPort.val);
831 if(preDefHdr->extHdr.pdcpNmb.pres)
833 preEncodedHdr[--cnt] = EGTP_EXT_HDR_PDCP_TYPE;
834 preEncodedHdr[--cnt] = 1;
835 preEncodedHdr[--cnt] = GetHiByte(preDefHdr->extHdr.pdcpNmb.val);
836 preEncodedHdr[--cnt] = GetLoByte(preDefHdr->extHdr.pdcpNmb.val);
839 if(tmpByte & EGTP_MASK_BIT3)
841 preEncodedHdr[--cnt] = 0;
845 preEncodedHdr[--cnt] = 0;
850 } /* egtpEncodeHdr */
852 /*******************************************************************
854 * @brief Sends message over UDP
858 * Function : egtpSendMsg
861 * Sends message over UDP
863 * @params[in] Message Buffer
864 * @return ROK - success
867 * ****************************************************************/
868 uint8_t egtpSendMsg(Buffer *mBuf)
873 static uint64_t numDataSent = 0;
875 info.region = DU_APP_MEM_REGION;
878 ret = cmInetSendMsg(&egtpCb.sockFd, &egtpCb.dstCb.dstAddr, &info, mBuf, (int16_t *)&txLen, CM_INET_NO_FLAG);
879 if(ret != ROK && ret != RWOULDBLOCK)
881 DU_LOG("\nERROR --> EGTP : Failed sending the message");
886 DU_LOG("\nDEBUG --> EGTP : Sent UL Message [%ld]", numDataSent+1);
893 /*******************************************************************
895 * @brief Receives EGTP message from UDP socket
899 * Function : egtpRecvMsg
902 * Receive incoming messages from UDP socket
905 * @return ROK - success
908 * ****************************************************************/
910 uint8_t egtpRecvMsg()
912 uint8_t ret; /* Return value */
913 uint16_t bufLen; /* Length of received buffer */
914 Buffer *recvBuf; /* Received buffer */
915 CmInetMemInfo memInfo; /* Buffer allocation info */
917 memInfo.region = DU_APP_MEM_REGION;
918 memInfo.pool = DU_POOL;
923 ret = cmInetRecvMsg(&egtpCb.sockFd, &egtpCb.dstCb.dstAddr, &memInfo, &recvBuf, (int16_t *)&bufLen, CM_INET_NO_FLAG);
924 if(ret == ROK && recvBuf != NULLP)
926 DU_LOG("\nDEBUG --> EGTP : Received DL Message[%ld]\n", gConfigInfo.gDlDataRcvdCnt + 1);
927 //ODU_PRINT_MSG(recvBuf, 0 ,0);
928 egtpHdlRecvData(recvBuf);
929 gConfigInfo.gDlDataRcvdCnt++;
937 /*******************************************************************
939 * @brief Handles DL User data received from CU
943 * Function : egtpHdlRecvData
945 * Functionality: Handles DL User data received from CU
947 * @params[in] DL Usre data buffer
948 * @return ROK - success
951 * ****************************************************************/
952 uint8_t egtpHdlRecvData(Buffer *mBuf)
956 /* Decode EGTP header */
957 egtpDecodeHdr(mBuf, &egtpMsg);
959 /* TODO : Send received message to RLC */
960 duHdlEgtpDlData(&egtpMsg);
965 /*******************************************************************
967 * @brief Decodes EGTP header from DL User data
971 * Function : egtpDecodeHdr
973 * Functionality: Decodes EGTP header from DL User data
976 * @return ROK - success
979 * ****************************************************************/
980 uint8_t egtpDecodeHdr(Buffer *mBuf, EgtpMsg *egtpMsg)
982 uint8_t tmpByte[5]; /* Holds 5 byte of data after Decoding */
983 uint8_t version = 0; /* Holds the version type, decoded */
984 uint16_t msgLen = 0; /* Holds the msgLen from the Hdr */
985 uint16_t bufLen = 0; /* Holds the total buffer length */
986 uint8_t extHdrType = 0; /* Holds the Extension hdr type */
987 uint8_t extHdrLen = 0; /* Extension hdr length */
988 bool extPres = FALSE; /* Flag for indication of S, E or P presense flag */
990 ODU_GET_MSG_LEN(mBuf, (int16_t *)&bufLen);
992 /* Decode first byte and storing in temporary variable */
993 ODU_REM_PRE_MSG(&tmpByte[0], mBuf);
995 /* Extracting version fro 1st byte */
996 version = tmpByte[0] >> 5;
998 //DU_LOG("\nDEBUG --> EGTP : Version %d", version);
1000 /* Decode message type */
1001 ODU_REM_PRE_MSG((Data*)&(egtpMsg->msgHdr.msgType), mBuf);
1002 //DU_LOG("\nDEBUG --> EGTP : msgType %d", egtpMsg->msgHdr.msgType);
1004 /****************************************************************************
1005 * Message length param is 2 bytes. So decode next 2 bytes from msg hdr and
1006 * performing OR operation on these two bytes to calculate message length
1007 ***************************************************************************/
1008 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
1009 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
1010 msgLen = (tmpByte[1] << 8) | tmpByte[2];
1013 //DU_LOG("\nDEBUG --> EGTP : msgLen %d", msgLen);
1016 /****************************************************************************
1017 * Tunnel id param is 4 bytes. So decode next 4 bytes from msg hdr and
1018 * perform OR operation on these 4 bytes to calculate tunnel id
1019 ***************************************************************************/
1020 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
1021 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
1022 ODU_REM_PRE_MSG(&tmpByte[3], mBuf);
1023 ODU_REM_PRE_MSG(&tmpByte[4], mBuf);
1024 egtpMsg->msgHdr.teId = (tmpByte[1] << 24) | (tmpByte[2] << 16) | (tmpByte[3] << 8) | tmpByte[4];
1025 //DU_LOG("\nDEBUG --> EGTP : teId %d",egtpMsg->msgHdr.teId);
1028 /* If any one of S, E or PN flag is set, set extension present as true. */
1029 if((tmpByte[0] & EGTP_MASK_BIT1) || (tmpByte[0] & EGTP_MASK_BIT2)||(tmpByte[0] & EGTP_MASK_BIT3))
1034 /* Decode sequence number, if S flag is set in first byte */
1035 if (tmpByte[0] & EGTP_MASK_BIT2)
1037 /************************************************************************
1038 * Sequence num is 2 bytes. So decode next 2 bytes from msg hdr and
1039 * perform OR operation on them
1040 ************************************************************************/
1041 egtpMsg->msgHdr.seqNum.pres = TRUE;
1042 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
1043 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
1044 egtpMsg->msgHdr.seqNum.val = (tmpByte[1] << 8) | tmpByte[2];
1046 /****************************************************************************
1047 * If extPres is true, but S bit is not set, implies, either of PN or E bit
1048 * was set during Encode so accordingly extract Byte fields for seqNum anyway
1049 ***************************************************************************/
1052 /*************************************************************************
1053 * Sequence num is 2 bytes. So decode next 2 bytes from msg hdr and
1054 * perform OR operation on them
1055 ************************************************************************/
1056 egtpMsg->msgHdr.seqNum.pres = 0;
1057 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
1058 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
1059 egtpMsg->msgHdr.seqNum.val = (tmpByte[1] << 8) | tmpByte[2];
1062 /* Decode N-PDU number if present flag is set */
1063 if (tmpByte[0] & EGTP_MASK_BIT1)
1065 egtpMsg->msgHdr.nPdu.pres = TRUE;
1066 ODU_REM_PRE_MSG(&(egtpMsg->msgHdr.nPdu.val), mBuf);
1068 /****************************************************************************
1069 * If extPres is true, but PN bit is not set, implies, either of S or E bit
1070 * was set during Encode. Aaccordingly extract Byte fields of N-PDU num anyway
1071 ***************************************************************************/
1074 egtpMsg->msgHdr.nPdu.pres = TRUE;
1075 ODU_REM_PRE_MSG(&(egtpMsg->msgHdr.nPdu.val), mBuf);
1078 /* If E flag is set in first byte, decode extension header */
1079 if(tmpByte[0] & EGTP_MASK_BIT3)
1081 ODU_REM_PRE_MSG(&extHdrType, mBuf);
1082 while( 0 != extHdrType)
1086 case EGTP_EXT_HDR_UDP_TYPE:
1088 ODU_REM_PRE_MSG(&extHdrLen, mBuf);
1089 if(extHdrLen == 0x01)
1091 /************************************************************
1092 * UDP Port is 2 bytes. So decode next 2 bytes from msg hdr
1093 * and perform OR operation on them
1094 *************************************************************/
1095 egtpMsg->msgHdr.extHdr.udpPort.pres = TRUE;
1096 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
1097 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
1098 egtpMsg->msgHdr.extHdr.udpPort.val = (tmpByte[1] << 8) | tmpByte[2];
1103 case EGTP_EXT_HDR_PDCP_TYPE:
1105 ODU_REM_PRE_MSG(&extHdrLen, mBuf);
1106 if(extHdrLen == 0x01)
1108 /*************************************************************
1109 * PDCP num is 2 bytes. So decode next 2 bytes from msg hdr
1110 * and perform OR operation on them
1111 ************************************************************/
1112 egtpMsg->msgHdr.extHdr.pdcpNmb.pres = TRUE;
1113 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
1114 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
1115 egtpMsg->msgHdr.extHdr.pdcpNmb.val = (tmpByte[1] << 8) | tmpByte[2];
1119 } /* End of switch */
1121 ODU_REM_PRE_MSG(&extHdrType, mBuf);
1123 } /* End of while */
1125 /****************************************************************************
1126 * If extPres is true, but E bit is not set, implies, either of PN or S bit
1127 * was set during Encode so accordingly extract Byte fields for extension
1129 ***************************************************************************/
1132 ODU_REM_PRE_MSG(&extHdrType, mBuf);
1135 egtpMsg->msg = mBuf;
1137 //DU_LOG("\nDEBUG --> EGTP : DL Data Buffer after decoding header ");
1138 //ODU_PRINT_MSG(mBuf, 0, 0);
1140 /* Forward the data to duApp/RLC */
1145 /**********************************************************************
1147 **********************************************************************/