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"
30 #include "du_app_rlc_inf.h"
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;
66 /**************************************************************************
67 * @brief Function prints the src dest and msg reached to egtp.
71 * Function : callFlowEgtpActvTsk
74 * Function prints the src dest and msg reached to egtp.
76 * @param[in] Pst *pst, Post structure of the primitive.
80 ***************************************************************************/
82 void callFlowEgtpActvTsk(Pst *pst)
86 char destTask[50]="ENTEGTP";
93 strcpy(sourceTask,"ENTDUAPP");
98 strcpy(message,"EVTCFGREQ");
103 strcpy(message,"EVTSRVOPENREQ");
108 strcpy(message,"EVTTNLMGMTREQ");
113 strcpy(message,"Invalid Event");
121 strcpy(sourceTask,"ENTEGTP");
126 strcpy(message,"EVTSTARTPOLL");
131 strcpy(message,"Invalid Event");
139 strcpy(sourceTask,"ENTRLC");
144 strcpy(message,"EVTDATIND");
149 strcpy(message,"Invalid Event");
157 strcpy(sourceTask,"Invalid Source Entity Id");
160 DU_LOG("\nCall Flow: %s -> %s : %s\n", sourceTask, destTask, message);
163 /**************************************************************************
164 * @brief Task Activation callback function.
168 * Function : egtpActvTsk
171 * This function handles all EGTP messages received
172 * This API is registered with SSI during the
173 * Task Registration of DU APP.
175 * @param[in] Pst *pst, Post structure of the primitive.
176 * @param[in] Buffer *mBuf, Packed primitive parameters in the
178 * @return ROK - success
181 ***************************************************************************/
182 uint8_t egtpActvTsk(Pst *pst, Buffer *mBuf)
186 #ifdef CALL_FLOW_DEBUG_LOG
187 callFlowEgtpActvTsk(pst);
198 ret = unpackEgtpCfgReq(egtpCfgReq, pst, mBuf);
203 ret = unpackEgtpSrvOpenReq(egtpSrvOpenReq, pst, mBuf);
208 ret = unpackEgtpTnlMgmtReq(egtpTnlMgmtReq, pst, mBuf);
213 DU_LOG("\nERROR --> EGTP : Invalid event %d", pst->event);
214 ODU_PUT_MSG_BUF(mBuf);
226 DU_LOG("\nDEBUG --> EGTP : Starting Socket Polling");
228 ODU_PUT_MSG_BUF(mBuf);
233 DU_LOG("\nERROR --> EGTP : Invalid event %d", pst->event);
234 ODU_PUT_MSG_BUF(mBuf);
251 DU_LOG("\nERROR --> EGTP : Invalid event %d", pst->event);
259 DU_LOG("\nERROR --> EGTP : Invalid source entity %d", pst->srcEnt);
267 /**************************************************************************
268 * @brief EGTP server configuration
272 * Function : egtpCfgReq
275 * This function handles EGTP configuration request.
277 * @return ROK - success
280 * ***********************************************************************/
281 uint8_t egtpCfgReq(Pst *pst, EgtpConfig egtpCfg)
283 uint8_t ret; /* Return value */
284 Pst rspPst; /* Response Pst structure */
285 CmStatus cfgCfm; /* Configuration Confirm */
287 memcpy(&egtpCb.egtpCfg, &egtpCfg, sizeof(EgtpConfig));
289 egtpCb.recvTptSrvr.addr.address = CM_INET_NTOH_UINT32(egtpCb.egtpCfg.localIp.ipV4Addr);
290 egtpCb.recvTptSrvr.addr.port = EGTP_RECVR_PORT;
292 egtpCb.dstCb.dstIp = CM_INET_NTOH_UINT32(egtpCb.egtpCfg.destIp.ipV4Addr);
293 egtpCb.dstCb.dstPort = egtpCb.egtpCfg.destPort;
294 egtpCb.dstCb.sendTptSrvr.addr.address = CM_INET_NTOH_UINT32(egtpCb.egtpCfg.localIp.ipV4Addr);
295 egtpCb.dstCb.sendTptSrvr.addr.port = egtpCb.egtpCfg.localPort;
296 egtpCb.dstCb.numTunn = 0;
298 ret = cmHashListInit(&(egtpCb.dstCb.teIdLst), 1024, sizeof(EgtpTeIdCb), FALSE, CM_HASH_KEYTYPE_UINT32_MOD, DU_APP_MEM_REGION, DU_POOL);
302 DU_LOG("\nERROR --> EGTP : TeId hash list initialization failed");
303 cfgCfm.status = LCM_PRIM_NOK;
304 cfgCfm.reason = LCM_REASON_HASHING_FAILED;
308 DU_LOG("\nDEBUG --> EGTP : EGTP configuration successful");
309 cfgCfm.status = LCM_PRIM_OK;
310 cfgCfm.reason = LCM_REASON_NOT_APPL;
313 /* Fill response Pst */
314 egtpFillRspPst(pst, &rspPst);
315 rspPst.event = EVTCFGCFM;
317 packEgtpCfgCfm(&rspPst, cfgCfm);
322 /**************************************************************************
323 * @brief Fills post structure to send response
327 * Function : egtpFillRspPst
330 * Fills post struture to send response
332 * @return ROK - success
336 * ***********************************************************************/
337 uint8_t egtpFillRspPst(Pst *pst, Pst *rspPst)
340 memset(rspPst, 0, sizeof(Pst));
341 rspPst->srcEnt = pst->dstEnt;
342 rspPst->srcInst = pst->dstInst;
343 rspPst->srcProcId = pst->dstProcId;
344 rspPst->dstEnt = pst->srcEnt;
345 rspPst->dstInst = pst->srcInst;
346 rspPst->dstProcId = pst->srcProcId;
347 rspPst->selector = ODU_SELECTOR_LC;
348 rspPst->pool= DU_POOL;
353 /**************************************************************************
354 * @brief EGTP server open request
358 * Function : egtpSrvOpenReq
361 * This function handles EGTP open server request.
362 * It opens udp socket to receive/send msgs.
364 * @param[in] Pst *pst, post structure
365 * @return ROK - success
368 ***************************************************************************/
370 uint8_t egtpSrvOpenReq(Pst *pst)
373 uint8_t ret; /* Return value */
374 Pst rspPst; /* Response Pst structure */
375 Pst egtpPst; /* Self post */
376 CmStatus cfm; /* Confirmation status */
377 uint8_t sockType; /* Socket type */
379 DU_LOG("\nDEBUG --> EGTP : Received EGTP open server request");
381 sockType = CM_INET_DGRAM;
382 ret = egtpSrvOpenPrc(sockType, &(egtpCb.recvTptSrvr));
383 /* Opening and Binding receiver socket */
386 DU_LOG("\nERROR --> EGTP : Failed while opening receiver transport server");
389 /* Opening and Binding sender socket */
390 ret = egtpSrvOpenPrc(sockType, &(egtpCb.dstCb.sendTptSrvr));
393 DU_LOG("\nERROR --> EGTP : Failed while opening sender transport server");
397 DU_LOG("\nDEBUG --> EGTP : Receiver socket[%d] and Sender socket[%d] open", egtpCb.recvTptSrvr.sockFd.fd,\
398 egtpCb.dstCb.sendTptSrvr.sockFd.fd);
400 /* Start Socket polling */
401 memset(&egtpPst, 0, sizeof(egtpPst));
402 egtpPst.srcEnt = (Ent)ENTEGTP;
403 egtpPst.srcInst = (Inst)EGTP_INST;
404 egtpPst.srcProcId = DU_PROC;
405 egtpPst.dstEnt = (Ent)ENTEGTP;
406 egtpPst.dstInst = (Inst)EGTP_INST;
407 egtpPst.dstProcId = DU_PROC;
408 egtpPst.event = EVTSTARTPOLL;
409 egtpPst.selector = ODU_SELECTOR_LC;
410 egtpPst.pool= DU_POOL;
411 packEgtpStartPollingReq(&egtpPst);
413 /* Filling and sending response */
414 cfm.status = LCM_PRIM_OK;
415 cfm.reason = LCM_REASON_NOT_APPL;
417 egtpFillRspPst(pst, &rspPst);
418 rspPst.event = EVTSRVOPENCFM;
419 packEgtpSrvOpenCfm(&rspPst, cfm);
424 /*******************************************************************
426 * @brief Processing Sever open request
430 * Function : egtpSrvOpenPrc
436 * @return ROK - success
439 * ****************************************************************/
441 uint8_t egtpSrvOpenPrc(uint8_t sockType, EgtpTptSrvr *server)
444 ret = cmInetSocket(sockType, &(server->sockFd), protType);
447 DU_LOG("\nERROR --> EGTP : Failed to open UDP socket");
450 ret = cmInetBind(&(server->sockFd), &(server->addr));
453 DU_LOG("\nERROR --> EGTP : Failed to bind socket");
460 /**************************************************************************
461 * @brief EGTP tunnel management request
465 * Function : egtpTnlMgmtReq
468 * This function handles EGTP tunnel managament request
470 * @param[in] Tunnel Eveny structure
471 * @return ROK - success
475 * ***************************************************************************/
476 uint8_t egtpTnlMgmtReq(Pst *pst, EgtpTnlEvt tnlEvt)
480 #ifdef CALL_FLOW_DEBUG_LOG
481 DU_LOG("\nCall Flow: ENTDUAPP -> ENTEGTP : TNL_MGMT\n");
484 DU_LOG("\nDEBUG --> EGTP : Received tunnel management request");
485 switch(tnlEvt.action)
487 case EGTP_TNL_MGMT_ADD:
489 ret = egtpTnlAdd(tnlEvt);
492 case EGTP_TNL_MGMT_MOD:
494 ret = egtpTnlMod(tnlEvt);
497 case EGTP_TNL_MGMT_DEL:
499 ret = egtpTnlDel(tnlEvt);
504 DU_LOG("\nERROR --> EGTP : Invalid tunnel management action[%d]", tnlEvt.action);
505 ret = LCM_REASON_INVALID_ACTION;
511 tnlEvt.cfmStatus.status = LCM_PRIM_OK;
512 tnlEvt.cfmStatus.reason = LCM_REASON_NOT_APPL;
516 tnlEvt.cfmStatus.status = LCM_PRIM_NOK;
517 tnlEvt.cfmStatus.reason = ret;
520 DU_LOG("\nDEBUG --> EGTP : Sending Tunnel management confirmation");
521 duHdlEgtpTnlMgmtCfm(tnlEvt);
526 /**************************************************************************
527 * @brief EGTP tunnel addition
531 * Function : egtpTnlAdd
534 * This function handles EGTP tunnel addition
536 * @param[in] Tunnel Event structure
537 * @return ROK - success
540 * ***************************************************************************/
541 uint8_t egtpTnlAdd(EgtpTnlEvt tnlEvt)
544 EgtpTeIdCb *teidCb; /* Tunnel endpoint control block */
545 EgtpMsgHdr preDefHdr; /* pre-define header for this tunnel */
547 DU_LOG("\nINFO --> EGTP : Tunnel addition : LocalTeid[%d] Remote Teid[%d]", tnlEvt.lclTeid, tnlEvt.remTeid);
549 DU_ALLOC(teidCb, sizeof(EgtpTeIdCb));
552 DU_LOG("\nERROR --> EGTP : Memory allocation failed");
553 return LCM_REASON_MEM_NOAVAIL;
556 memset(teidCb, 0, sizeof(EgtpTeIdCb));
557 teidCb->teId = tnlEvt.lclTeid;
558 teidCb->remTeId = tnlEvt.remTeid;
560 ret = cmHashListInsert(&(egtpCb.dstCb.teIdLst), (PTR)teidCb, (uint8_t *)&(teidCb->teId), sizeof(uint32_t));
563 DU_LOG("\nERROR --> EGTP : Failed to insert in hash list");
564 DU_FREE(teidCb, sizeof(EgtpTeIdCb));
565 return LCM_REASON_HASHING_FAILED;
567 egtpCb.dstCb.numTunn++;
569 /* Encoding pre-defined header */
570 memset(&preDefHdr, 0, sizeof(EgtpMsgHdr));
571 preDefHdr.msgType = EGTPU_MSG_GPDU;
572 preDefHdr.teId = teidCb->remTeId;
573 preDefHdr.extHdr.pdcpNmb.pres = FALSE;
574 preDefHdr.extHdr.udpPort.pres = FALSE;
575 preDefHdr.nPdu.pres = FALSE;
577 egtpEncodeHdr((uint8_t *)teidCb->preEncodedHdr.hdr, &preDefHdr, &(teidCb->preEncodedHdr.cnt));
582 /**************************************************************************
583 * @brief EGTP tunnel modification
587 * Function : egtpTnlMod
590 * This function handles EGTP tunnel modification
592 * @param[in] Tunnel Event structure
593 * @return ROK - success
596 * ***************************************************************************/
597 uint8_t egtpTnlMod(EgtpTnlEvt tnlEvt)
599 EgtpTeIdCb *teidCb = NULLP;
601 DU_LOG("\nINFO --> EGTP : Tunnel modification : LocalTeid[%d] Remote Teid[%d]", tnlEvt.lclTeid, tnlEvt.remTeid);
603 cmHashListFind(&(egtpCb.dstCb.teIdLst), (uint8_t *)&(tnlEvt.lclTeid), sizeof(uint32_t), 0, (PTR *)&teidCb);
606 DU_LOG("\nERROR --> EGTP : Tunnel id not found");
609 teidCb->teId = tnlEvt.remTeid;
610 teidCb->remTeId = tnlEvt.remTeid;
614 /**************************************************************************
615 * @brief EGTP tunnel deletion
619 * Function : egtpTnlDel
622 * This function handles EGTP tunnel deletion
624 * @param[in] Tunnel Event structure
625 * @return ROK - success
628 * ***************************************************************************/
629 uint8_t egtpTnlDel(EgtpTnlEvt tnlEvt)
631 EgtpTeIdCb *teidCb = NULLP;
633 DU_LOG("\nINFO --> EGTP : Tunnel deletion : Local Teid[%d] Remote Teid[%d]", tnlEvt.lclTeid, tnlEvt.remTeid);
635 cmHashListFind(&(egtpCb.dstCb.teIdLst), (uint8_t *)&(tnlEvt.lclTeid), sizeof(uint32_t), 0, (PTR *)&teidCb);
638 DU_LOG("\nERROR --> EGTP : Tunnel id[%d] not configured", tnlEvt.lclTeid);
639 return LCM_REASON_INVALID_PAR_VAL;
642 cmHashListDelete(&(egtpCb.dstCb.teIdLst), (PTR)teidCb);
643 DU_FREE(teidCb, sizeof(EgtpTeIdCb));
644 egtpCb.dstCb.numTunn--;
648 /*******************************************************************
650 * @brief Handles data indication
654 * Function : EgtpHdlDatInd
657 * Handles incoming data from peer to be passed
661 * @return ROK - success
664 * ****************************************************************/
665 uint8_t egtpHdlDatInd(EgtpMsg egtpMsg)
667 EgtpTeIdCb *teidCb = NULLP;
673 #ifdef CALL_FLOW_DEBUG_LOG
674 DU_LOG("\nCall Flow: ENTDUAPP -> ENTEGTP : DATA_INDICATION\n");
677 DU_LOG("\nDEBUG --> EGTP : Received Data Indication");
679 cmHashListFind(&(egtpCb.dstCb.teIdLst), (uint8_t *)&(egtpMsg.msgHdr.teId), sizeof(uint32_t), 0, (PTR *)&teidCb);
682 DU_LOG("\nERROR --> EGTP : Tunnel id[%d] not configured", egtpMsg.msgHdr.teId);
683 return LCM_REASON_INVALID_PAR_VAL;
686 msgHdr = &(egtpMsg.msgHdr);
688 hdrLen = teidCb->preEncodedHdr.cnt;
690 if(msgHdr->extHdr.pdcpNmb.pres)
692 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] |= EGTP_MASK_BIT3;
693 teidCb->preEncodedHdr.hdr[hdrLen] = EGTP_EXT_HDR_PDCP_TYPE;
694 teidCb->preEncodedHdr.hdr[--hdrLen] = 1;
695 teidCb->preEncodedHdr.hdr[--hdrLen] = GetHiByte(msgHdr->extHdr.pdcpNmb.val);
696 teidCb->preEncodedHdr.hdr[--hdrLen] = GetLoByte(msgHdr->extHdr.pdcpNmb.val);
697 teidCb->preEncodedHdr.hdr[--hdrLen] = 0;
701 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] &= ~(EGTP_MASK_BIT3);
704 ODU_GET_MSG_LEN(egtpMsg.msg, (int16_t *)&tPduSize);
706 /*Adjust the header to fill the correct length*/
707 msgLen = tPduSize + (EGTP_MAX_HDR_LEN - hdrLen) - 0x08;
709 /***********************************************
710 * Fill the length field of the message header *
711 ***********************************************/
712 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 3] = (uint8_t)GetHiByte(msgLen);
713 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 4] = (uint8_t)GetLoByte(msgLen);
715 /*Update the sequence number*/
716 if(egtpMsg.msgHdr.seqNum.pres)
718 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] |= (EGTP_MASK_BIT2);
719 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 9] = (uint8_t)GetHiByte(egtpMsg.msgHdr.seqNum.val);
720 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 10] = (uint8_t)GetLoByte(egtpMsg.msgHdr.seqNum.val);
724 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] &= ~(EGTP_MASK_BIT2);
727 DU_LOG("\nDEBUG --> EGTP : UL Data buffer before encoding header");
728 ODU_PRINT_MSG(egtpMsg.msg, 0, 0);
730 ODU_ADD_PRE_MSG_MULT(&teidCb->preEncodedHdr.hdr[hdrLen], (EGTP_MAX_HDR_LEN - hdrLen), egtpMsg.msg);
733 DU_LOG("\nDEBUG --> EGTP : UL Data buffer after encoding header");
734 ODU_PRINT_MSG(egtpMsg.msg, 0, 0);
737 egtpSendMsg(egtpMsg.msg);
738 ODU_PUT_MSG_BUF(egtpMsg.msg);
743 /*******************************************************************
745 * @brief Encodes outgoing message
749 * Function : egtpEncodeMsg
752 * Encodes EGTP message to be sent
754 * @params[in] EGTP message
756 * @return ROK - success
759 * ****************************************************************/
760 uint8_t egtpEncodeHdr(uint8_t *preEncodedHdr, EgtpMsgHdr *preDefHdr, uint8_t *hdrIdx)
762 uint8_t tmpByte = 0; /* Stores one byte of data for enc */
763 uint8_t cnt = EGTP_MAX_HDR_LEN; /* Stores the position */
764 bool extPres = FALSE; /* Flag for indication of S, E or P presense flag */
767 /* Encoding header */
768 tmpByte |= EGTP_MASK_BIT6; /* Setting 6th LSB of 1st byte as version */
769 tmpByte |= EGTP_MASK_BIT5; /* Setting 5th LSB of 1st byte as protocol type */
771 if(preDefHdr->extHdr.udpPort.pres || preDefHdr->extHdr.pdcpNmb.pres)
773 tmpByte |= EGTP_MASK_BIT3; /* Setting 3rd LSB of 1st byte if Extension heaeder is present */
776 if(preDefHdr->seqNum.pres)
778 tmpByte |= EGTP_MASK_BIT2;
781 if(preDefHdr->nPdu.pres)
783 tmpByte |= EGTP_MASK_BIT1;
786 if((tmpByte & EGTP_MASK_BIT1) || (tmpByte & EGTP_MASK_BIT2)||(tmpByte & EGTP_MASK_BIT3))
791 preEncodedHdr[--cnt] = tmpByte;
792 preEncodedHdr[--cnt] = preDefHdr->msgType;
794 /* Encode Tunnel endpoint */
795 preEncodedHdr[--cnt] = 0;
796 preEncodedHdr[--cnt] = 0;
797 nwWord = (uint16_t)(GetHiWord(preDefHdr->teId));
798 preEncodedHdr[--cnt] = (uint8_t)(GetHiByte(nwWord));
799 preEncodedHdr[--cnt] = (uint8_t)(GetLoByte(nwWord));
800 nwWord = (uint16_t)(GetLoWord(preDefHdr->teId));
801 preEncodedHdr[--cnt] = (uint8_t)(GetHiByte(nwWord));
802 preEncodedHdr[--cnt] = (uint8_t)(GetLoByte(nwWord));
804 /* Encode sequence number */
805 if(preDefHdr->seqNum.pres)
807 preEncodedHdr[--cnt] = GetHiByte(preDefHdr->seqNum.val);
808 preEncodedHdr[--cnt] = GetLoByte(preDefHdr->seqNum.val);
812 preEncodedHdr[--cnt] = 0;
813 preEncodedHdr[--cnt] = 0;
816 /* Encode nPdu number */
817 if(preDefHdr->nPdu.pres)
819 preEncodedHdr[--cnt] = preDefHdr->nPdu.val;
823 preEncodedHdr[--cnt] = 0;
826 if(preDefHdr->extHdr.udpPort.pres)
828 preEncodedHdr[--cnt] = EGTP_EXT_HDR_UDP_TYPE;
829 preEncodedHdr[--cnt] = 1;
830 preEncodedHdr[--cnt] = GetHiByte(preDefHdr->extHdr.udpPort.val);
831 preEncodedHdr[--cnt] = GetLoByte(preDefHdr->extHdr.udpPort.val);
834 if(preDefHdr->extHdr.pdcpNmb.pres)
836 preEncodedHdr[--cnt] = EGTP_EXT_HDR_PDCP_TYPE;
837 preEncodedHdr[--cnt] = 1;
838 preEncodedHdr[--cnt] = GetHiByte(preDefHdr->extHdr.pdcpNmb.val);
839 preEncodedHdr[--cnt] = GetLoByte(preDefHdr->extHdr.pdcpNmb.val);
842 if(tmpByte & EGTP_MASK_BIT3)
844 preEncodedHdr[--cnt] = 0;
848 preEncodedHdr[--cnt] = 0;
853 } /* egtpEncodeHdr */
855 /*******************************************************************
857 * @brief Sends message over UDP
861 * Function : egtpSendMsg
864 * Sends message over UDP
866 * @params[in] Message Buffer
867 * @return ROK - success
870 * ****************************************************************/
871 uint8_t egtpSendMsg(Buffer *mBuf)
877 static uint64_t numDataSent = 0;
879 info.region = DU_APP_MEM_REGION;
882 dstAddr.port = EGTP_RECVR_PORT;
883 dstAddr.address = egtpCb.dstCb.dstIp;
885 ret = cmInetSendMsg(&(egtpCb.dstCb.sendTptSrvr.sockFd), &dstAddr, &info, \
886 mBuf, (int16_t *)&txLen, CM_INET_NO_FLAG);
887 if(ret != ROK && ret != RWOULDBLOCK)
889 DU_LOG("\nERROR --> EGTP : Failed sending the message");
894 DU_LOG("\nDEBUG --> EGTP : Sent UL Message [%ld]", numDataSent+1);
901 /*******************************************************************
903 * @brief Receives EGTP message from UDP socket
907 * Function : egtpRecvMsg
910 * Receive incoming messages from UDP socket
913 * @return ROK - success
916 * ****************************************************************/
918 uint8_t egtpRecvMsg()
920 uint8_t ret; /* Return value */
921 uint16_t bufLen; /* Length of received buffer */
922 Buffer *recvBuf; /* Received buffer */
923 CmInetAddr fromAddr; /* Egtp data sender address */
924 CmInetMemInfo memInfo; /* Buffer allocation info */
926 memInfo.region = DU_APP_MEM_REGION;
927 memInfo.pool = DU_POOL;
929 fromAddr.port = egtpCb.dstCb.dstPort;
930 fromAddr.address = egtpCb.dstCb.dstIp;
935 ret = cmInetRecvMsg(&(egtpCb.recvTptSrvr.sockFd), &fromAddr, &memInfo, \
936 &recvBuf, (int16_t *)&bufLen, CM_INET_NO_FLAG);
937 if(ret == ROK && recvBuf != NULLP)
939 DU_LOG("\nDEBUG --> EGTP : Received DL Message[%ld]\n", gDlDataRcvdCnt + 1);
940 //ODU_PRINT_MSG(recvBuf, 0 ,0);
941 egtpHdlRecvData(recvBuf);
950 /*******************************************************************
952 * @brief Handles DL User data received from CU
956 * Function : egtpHdlRecvData
958 * Functionality: Handles DL User data received from CU
960 * @params[in] DL Usre data buffer
961 * @return ROK - success
964 * ****************************************************************/
965 uint8_t egtpHdlRecvData(Buffer *mBuf)
969 /* Decode EGTP header */
970 egtpDecodeHdr(mBuf, &egtpMsg);
972 /* TODO : Send received message to RLC */
973 duHdlEgtpDlData(&egtpMsg);
978 /*******************************************************************
980 * @brief Decodes EGTP header from DL User data
984 * Function : egtpDecodeHdr
986 * Functionality: Decodes EGTP header from DL User data
989 * @return ROK - success
992 * ****************************************************************/
993 uint8_t egtpDecodeHdr(Buffer *mBuf, EgtpMsg *egtpMsg)
995 uint8_t tmpByte[5]; /* Holds 5 byte of data after Decoding */
996 uint8_t version = 0; /* Holds the version type, decoded */
997 uint16_t msgLen = 0; /* Holds the msgLen from the Hdr */
998 uint16_t bufLen = 0; /* Holds the total buffer length */
999 uint8_t extHdrType = 0; /* Holds the Extension hdr type */
1000 uint8_t extHdrLen = 0; /* Extension hdr length */
1001 bool extPres = FALSE; /* Flag for indication of S, E or P presense flag */
1003 ODU_GET_MSG_LEN(mBuf, (int16_t *)&bufLen);
1005 /* Decode first byte and storing in temporary variable */
1006 ODU_REM_PRE_MSG(&tmpByte[0], mBuf);
1008 /* Extracting version fro 1st byte */
1009 version = tmpByte[0] >> 5;
1011 //DU_LOG("\nDEBUG --> EGTP : Version %d", version);
1013 /* Decode message type */
1014 ODU_REM_PRE_MSG((Data*)&(egtpMsg->msgHdr.msgType), mBuf);
1015 //DU_LOG("\nDEBUG --> EGTP : msgType %d", egtpMsg->msgHdr.msgType);
1017 /****************************************************************************
1018 * Message length param is 2 bytes. So decode next 2 bytes from msg hdr and
1019 * performing OR operation on these two bytes to calculate message length
1020 ***************************************************************************/
1021 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
1022 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
1023 msgLen = (tmpByte[1] << 8) | tmpByte[2];
1026 //DU_LOG("\nDEBUG --> EGTP : msgLen %d", msgLen);
1029 /****************************************************************************
1030 * Tunnel id param is 4 bytes. So decode next 4 bytes from msg hdr and
1031 * perform OR operation on these 4 bytes to calculate tunnel id
1032 ***************************************************************************/
1033 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
1034 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
1035 ODU_REM_PRE_MSG(&tmpByte[3], mBuf);
1036 ODU_REM_PRE_MSG(&tmpByte[4], mBuf);
1037 egtpMsg->msgHdr.teId = (tmpByte[1] << 24) | (tmpByte[2] << 16) | (tmpByte[3] << 8) | tmpByte[4];
1038 //DU_LOG("\nDEBUG --> EGTP : teId %d",egtpMsg->msgHdr.teId);
1041 /* If any one of S, E or PN flag is set, set extension present as true. */
1042 if((tmpByte[0] & EGTP_MASK_BIT1) || (tmpByte[0] & EGTP_MASK_BIT2)||(tmpByte[0] & EGTP_MASK_BIT3))
1047 /* Decode sequence number, if S flag is set in first byte */
1048 if (tmpByte[0] & EGTP_MASK_BIT2)
1050 /************************************************************************
1051 * Sequence num is 2 bytes. So decode next 2 bytes from msg hdr and
1052 * perform OR operation on them
1053 ************************************************************************/
1054 egtpMsg->msgHdr.seqNum.pres = TRUE;
1055 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
1056 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
1057 egtpMsg->msgHdr.seqNum.val = (tmpByte[1] << 8) | tmpByte[2];
1059 /****************************************************************************
1060 * If extPres is true, but S bit is not set, implies, either of PN or E bit
1061 * was set during Encode so accordingly extract Byte fields for seqNum anyway
1062 ***************************************************************************/
1065 /*************************************************************************
1066 * Sequence num is 2 bytes. So decode next 2 bytes from msg hdr and
1067 * perform OR operation on them
1068 ************************************************************************/
1069 egtpMsg->msgHdr.seqNum.pres = 0;
1070 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
1071 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
1072 egtpMsg->msgHdr.seqNum.val = (tmpByte[1] << 8) | tmpByte[2];
1075 /* Decode N-PDU number if present flag is set */
1076 if (tmpByte[0] & EGTP_MASK_BIT1)
1078 egtpMsg->msgHdr.nPdu.pres = TRUE;
1079 ODU_REM_PRE_MSG(&(egtpMsg->msgHdr.nPdu.val), mBuf);
1081 /****************************************************************************
1082 * If extPres is true, but PN bit is not set, implies, either of S or E bit
1083 * was set during Encode. Aaccordingly extract Byte fields of N-PDU num anyway
1084 ***************************************************************************/
1087 egtpMsg->msgHdr.nPdu.pres = TRUE;
1088 ODU_REM_PRE_MSG(&(egtpMsg->msgHdr.nPdu.val), mBuf);
1091 /* If E flag is set in first byte, decode extension header */
1092 if(tmpByte[0] & EGTP_MASK_BIT3)
1094 ODU_REM_PRE_MSG(&extHdrType, mBuf);
1095 while( 0 != extHdrType)
1099 case EGTP_EXT_HDR_UDP_TYPE:
1101 ODU_REM_PRE_MSG(&extHdrLen, mBuf);
1102 if(extHdrLen == 0x01)
1104 /************************************************************
1105 * UDP Port is 2 bytes. So decode next 2 bytes from msg hdr
1106 * and perform OR operation on them
1107 *************************************************************/
1108 egtpMsg->msgHdr.extHdr.udpPort.pres = TRUE;
1109 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
1110 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
1111 egtpMsg->msgHdr.extHdr.udpPort.val = (tmpByte[1] << 8) | tmpByte[2];
1116 case EGTP_EXT_HDR_PDCP_TYPE:
1118 ODU_REM_PRE_MSG(&extHdrLen, mBuf);
1119 if(extHdrLen == 0x01)
1121 /*************************************************************
1122 * PDCP num is 2 bytes. So decode next 2 bytes from msg hdr
1123 * and perform OR operation on them
1124 ************************************************************/
1125 egtpMsg->msgHdr.extHdr.pdcpNmb.pres = TRUE;
1126 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
1127 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
1128 egtpMsg->msgHdr.extHdr.pdcpNmb.val = (tmpByte[1] << 8) | tmpByte[2];
1132 } /* End of switch */
1134 ODU_REM_PRE_MSG(&extHdrType, mBuf);
1136 } /* End of while */
1138 /****************************************************************************
1139 * If extPres is true, but E bit is not set, implies, either of PN or S bit
1140 * was set during Encode so accordingly extract Byte fields for extension
1142 ***************************************************************************/
1145 ODU_REM_PRE_MSG(&extHdrType, mBuf);
1148 egtpMsg->msg = mBuf;
1150 //DU_LOG("\nDEBUG --> EGTP : DL Data Buffer after decoding header ");
1151 //ODU_PRINT_MSG(mBuf, 0, 0);
1153 /* Forward the data to duApp/RLC */
1158 /**********************************************************************
1160 **********************************************************************/