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 #ifdef CALL_FLOW_DEBUG_LOG
67 /**************************************************************************
68 * @brief Function prints the src dest and msg reached to egtp.
72 * Function : callFlowEgtpActvTsk
75 * Function prints the src dest and msg reached to egtp.
77 * @param[in] Pst *pst, Post structure of the primitive.
81 ***************************************************************************/
83 void callFlowEgtpActvTsk(Pst *pst)
87 char destTask[50]="ENTEGTP";
94 strcpy(sourceTask,"ENTDUAPP");
99 strcpy(message,"EVTCFGREQ");
104 strcpy(message,"EVTSRVOPENREQ");
109 strcpy(message,"EVTTNLMGMTREQ");
114 strcpy(message,"Invalid Event");
122 strcpy(sourceTask,"ENTEGTP");
127 strcpy(message,"EVTSTARTPOLL");
132 strcpy(message,"Invalid Event");
140 strcpy(sourceTask,"ENTRLC");
145 strcpy(message,"EVTDATIND");
150 strcpy(message,"Invalid Event");
158 strcpy(sourceTask,"Invalid Source Entity Id");
161 DU_LOG("\nCall Flow: %s -> %s : %s\n", sourceTask, destTask, message);
165 /**************************************************************************
166 * @brief Task Activation callback function.
170 * Function : egtpActvTsk
173 * This function handles all EGTP messages received
174 * This API is registered with SSI during the
175 * Task Registration of DU APP.
177 * @param[in] Pst *pst, Post structure of the primitive.
178 * @param[in] Buffer *mBuf, Packed primitive parameters in the
180 * @return ROK - success
183 ***************************************************************************/
184 uint8_t egtpActvTsk(Pst *pst, Buffer *mBuf)
188 #ifdef CALL_FLOW_DEBUG_LOG
189 callFlowEgtpActvTsk(pst);
200 ret = unpackEgtpCfgReq(egtpCfgReq, pst, mBuf);
205 ret = unpackEgtpSrvOpenReq(egtpSrvOpenReq, pst, mBuf);
210 ret = unpackEgtpTnlMgmtReq(egtpTnlMgmtReq, pst, mBuf);
215 DU_LOG("\nERROR --> EGTP : Invalid event %d", pst->event);
216 ODU_PUT_MSG_BUF(mBuf);
228 DU_LOG("\nDEBUG --> EGTP : Starting Socket Polling");
230 ODU_PUT_MSG_BUF(mBuf);
235 DU_LOG("\nERROR --> EGTP : Invalid event %d", pst->event);
236 ODU_PUT_MSG_BUF(mBuf);
253 DU_LOG("\nERROR --> EGTP : Invalid event %d", pst->event);
261 DU_LOG("\nERROR --> EGTP : Invalid source entity %d", pst->srcEnt);
269 /**************************************************************************
270 * @brief EGTP server configuration
274 * Function : egtpCfgReq
277 * This function handles EGTP configuration request.
279 * @return ROK - success
282 * ***********************************************************************/
283 uint8_t egtpCfgReq(Pst *pst, EgtpConfig egtpCfg)
285 uint8_t ret; /* Return value */
286 Pst rspPst; /* Response Pst structure */
287 CmStatus cfgCfm; /* Configuration Confirm */
289 memcpy(&egtpCb.egtpCfg, &egtpCfg, sizeof(EgtpConfig));
291 egtpCb.recvTptSrvr.addr.address = CM_INET_NTOH_UINT32(egtpCb.egtpCfg.localIp.ipV4Addr);
292 egtpCb.recvTptSrvr.addr.port = EGTP_RECVR_PORT;
294 egtpCb.dstCb.dstIp = CM_INET_NTOH_UINT32(egtpCb.egtpCfg.destIp.ipV4Addr);
295 egtpCb.dstCb.dstPort = egtpCb.egtpCfg.destPort;
296 egtpCb.dstCb.sendTptSrvr.addr.address = CM_INET_NTOH_UINT32(egtpCb.egtpCfg.localIp.ipV4Addr);
297 egtpCb.dstCb.sendTptSrvr.addr.port = egtpCb.egtpCfg.localPort;
298 egtpCb.dstCb.numTunn = 0;
300 ret = cmHashListInit(&(egtpCb.dstCb.teIdLst), 1024, sizeof(EgtpTeIdCb), FALSE, CM_HASH_KEYTYPE_UINT32_MOD, DU_APP_MEM_REGION, DU_POOL);
304 DU_LOG("\nERROR --> EGTP : TeId hash list initialization failed");
305 cfgCfm.status = LCM_PRIM_NOK;
306 cfgCfm.reason = LCM_REASON_HASHING_FAILED;
310 DU_LOG("\nDEBUG --> EGTP : EGTP configuration successful");
311 cfgCfm.status = LCM_PRIM_OK;
312 cfgCfm.reason = LCM_REASON_NOT_APPL;
315 /* Fill response Pst */
316 egtpFillRspPst(pst, &rspPst);
317 rspPst.event = EVTCFGCFM;
319 packEgtpCfgCfm(&rspPst, cfgCfm);
324 /**************************************************************************
325 * @brief Fills post structure to send response
329 * Function : egtpFillRspPst
332 * Fills post struture to send response
334 * @return ROK - success
338 * ***********************************************************************/
339 uint8_t egtpFillRspPst(Pst *pst, Pst *rspPst)
342 memset(rspPst, 0, sizeof(Pst));
343 rspPst->srcEnt = pst->dstEnt;
344 rspPst->srcInst = pst->dstInst;
345 rspPst->srcProcId = pst->dstProcId;
346 rspPst->dstEnt = pst->srcEnt;
347 rspPst->dstInst = pst->srcInst;
348 rspPst->dstProcId = pst->srcProcId;
349 rspPst->selector = ODU_SELECTOR_LC;
350 rspPst->pool= DU_POOL;
355 /**************************************************************************
356 * @brief EGTP server open request
360 * Function : egtpSrvOpenReq
363 * This function handles EGTP open server request.
364 * It opens udp socket to receive/send msgs.
366 * @param[in] Pst *pst, post structure
367 * @return ROK - success
370 ***************************************************************************/
372 uint8_t egtpSrvOpenReq(Pst *pst)
375 uint8_t ret; /* Return value */
376 Pst rspPst; /* Response Pst structure */
377 Pst egtpPst; /* Self post */
378 CmStatus cfm; /* Confirmation status */
379 uint8_t sockType; /* Socket type */
381 DU_LOG("\nDEBUG --> EGTP : Received EGTP open server request");
383 sockType = CM_INET_DGRAM;
384 ret = egtpSrvOpenPrc(sockType, &(egtpCb.recvTptSrvr));
385 /* Opening and Binding receiver socket */
388 DU_LOG("\nERROR --> EGTP : Failed while opening receiver transport server");
391 /* Opening and Binding sender socket */
392 ret = egtpSrvOpenPrc(sockType, &(egtpCb.dstCb.sendTptSrvr));
395 DU_LOG("\nERROR --> EGTP : Failed while opening sender transport server");
399 DU_LOG("\nDEBUG --> EGTP : Receiver socket[%d] and Sender socket[%d] open", egtpCb.recvTptSrvr.sockFd.fd,\
400 egtpCb.dstCb.sendTptSrvr.sockFd.fd);
402 /* Start Socket polling */
403 memset(&egtpPst, 0, sizeof(egtpPst));
404 egtpPst.srcEnt = (Ent)ENTEGTP;
405 egtpPst.srcInst = (Inst)EGTP_INST;
406 egtpPst.srcProcId = DU_PROC;
407 egtpPst.dstEnt = (Ent)ENTEGTP;
408 egtpPst.dstInst = (Inst)EGTP_INST;
409 egtpPst.dstProcId = DU_PROC;
410 egtpPst.event = EVTSTARTPOLL;
411 egtpPst.selector = ODU_SELECTOR_LC;
412 egtpPst.pool= DU_POOL;
413 packEgtpStartPollingReq(&egtpPst);
415 /* Filling and sending response */
416 cfm.status = LCM_PRIM_OK;
417 cfm.reason = LCM_REASON_NOT_APPL;
419 egtpFillRspPst(pst, &rspPst);
420 rspPst.event = EVTSRVOPENCFM;
421 packEgtpSrvOpenCfm(&rspPst, cfm);
426 /*******************************************************************
428 * @brief Processing Sever open request
432 * Function : egtpSrvOpenPrc
438 * @return ROK - success
441 * ****************************************************************/
443 uint8_t egtpSrvOpenPrc(uint8_t sockType, EgtpTptSrvr *server)
446 ret = cmInetSocket(sockType, &(server->sockFd), protType);
449 DU_LOG("\nERROR --> EGTP : Failed to open UDP socket");
452 ret = cmInetBind(&(server->sockFd), &(server->addr));
455 DU_LOG("\nERROR --> EGTP : Failed to bind socket");
462 /**************************************************************************
463 * @brief EGTP tunnel management request
467 * Function : egtpTnlMgmtReq
470 * This function handles EGTP tunnel managament request
472 * @param[in] Tunnel Eveny structure
473 * @return ROK - success
477 * ***************************************************************************/
478 uint8_t egtpTnlMgmtReq(Pst *pst, EgtpTnlEvt tnlEvt)
482 #ifdef CALL_FLOW_DEBUG_LOG
483 DU_LOG("\nCall Flow: ENTDUAPP -> ENTEGTP : TNL_MGMT\n");
486 DU_LOG("\nDEBUG --> EGTP : Received tunnel management request");
487 switch(tnlEvt.action)
489 case EGTP_TNL_MGMT_ADD:
491 ret = egtpTnlAdd(tnlEvt);
494 case EGTP_TNL_MGMT_MOD:
496 ret = egtpTnlMod(tnlEvt);
499 case EGTP_TNL_MGMT_DEL:
501 ret = egtpTnlDel(tnlEvt);
506 DU_LOG("\nERROR --> EGTP : Invalid tunnel management action[%d]", tnlEvt.action);
507 ret = LCM_REASON_INVALID_ACTION;
513 tnlEvt.cfmStatus.status = LCM_PRIM_OK;
514 tnlEvt.cfmStatus.reason = LCM_REASON_NOT_APPL;
518 tnlEvt.cfmStatus.status = LCM_PRIM_NOK;
519 tnlEvt.cfmStatus.reason = ret;
522 DU_LOG("\nDEBUG --> EGTP : Sending Tunnel management confirmation");
523 duHdlEgtpTnlMgmtCfm(tnlEvt);
528 /**************************************************************************
529 * @brief EGTP tunnel addition
533 * Function : egtpTnlAdd
536 * This function handles EGTP tunnel addition
538 * @param[in] Tunnel Event structure
539 * @return ROK - success
542 * ***************************************************************************/
543 uint8_t egtpTnlAdd(EgtpTnlEvt tnlEvt)
546 EgtpTeIdCb *teidCb; /* Tunnel endpoint control block */
547 EgtpMsgHdr preDefHdr; /* pre-define header for this tunnel */
549 DU_LOG("\nINFO --> EGTP : Tunnel addition : LocalTeid[%d] Remote Teid[%d]", tnlEvt.lclTeid, tnlEvt.remTeid);
551 DU_ALLOC(teidCb, sizeof(EgtpTeIdCb));
554 DU_LOG("\nERROR --> EGTP : Memory allocation failed");
555 return LCM_REASON_MEM_NOAVAIL;
558 memset(teidCb, 0, sizeof(EgtpTeIdCb));
559 teidCb->teId = tnlEvt.lclTeid;
560 teidCb->remTeId = tnlEvt.remTeid;
562 ret = cmHashListInsert(&(egtpCb.dstCb.teIdLst), (PTR)teidCb, (uint8_t *)&(teidCb->teId), sizeof(uint32_t));
565 DU_LOG("\nERROR --> EGTP : Failed to insert in hash list");
566 DU_FREE(teidCb, sizeof(EgtpTeIdCb));
567 return LCM_REASON_HASHING_FAILED;
569 egtpCb.dstCb.numTunn++;
571 /* Encoding pre-defined header */
572 memset(&preDefHdr, 0, sizeof(EgtpMsgHdr));
573 preDefHdr.msgType = EGTPU_MSG_GPDU;
574 preDefHdr.teId = teidCb->remTeId;
575 preDefHdr.extHdr.pdcpNmb.pres = FALSE;
576 preDefHdr.extHdr.udpPort.pres = FALSE;
577 preDefHdr.nPdu.pres = FALSE;
579 egtpEncodeHdr((uint8_t *)teidCb->preEncodedHdr.hdr, &preDefHdr, &(teidCb->preEncodedHdr.cnt));
584 /**************************************************************************
585 * @brief EGTP tunnel modification
589 * Function : egtpTnlMod
592 * This function handles EGTP tunnel modification
594 * @param[in] Tunnel Event structure
595 * @return ROK - success
598 * ***************************************************************************/
599 uint8_t egtpTnlMod(EgtpTnlEvt tnlEvt)
601 EgtpTeIdCb *teidCb = NULLP;
603 DU_LOG("\nINFO --> EGTP : Tunnel modification : LocalTeid[%d] Remote Teid[%d]", tnlEvt.lclTeid, tnlEvt.remTeid);
605 cmHashListFind(&(egtpCb.dstCb.teIdLst), (uint8_t *)&(tnlEvt.lclTeid), sizeof(uint32_t), 0, (PTR *)&teidCb);
608 DU_LOG("\nERROR --> EGTP : Tunnel id not found");
611 teidCb->teId = tnlEvt.remTeid;
612 teidCb->remTeId = tnlEvt.remTeid;
616 /**************************************************************************
617 * @brief EGTP tunnel deletion
621 * Function : egtpTnlDel
624 * This function handles EGTP tunnel deletion
626 * @param[in] Tunnel Event structure
627 * @return ROK - success
630 * ***************************************************************************/
631 uint8_t egtpTnlDel(EgtpTnlEvt tnlEvt)
633 EgtpTeIdCb *teidCb = NULLP;
635 DU_LOG("\nINFO --> EGTP : Tunnel deletion : Local Teid[%d] Remote Teid[%d]", tnlEvt.lclTeid, tnlEvt.remTeid);
637 cmHashListFind(&(egtpCb.dstCb.teIdLst), (uint8_t *)&(tnlEvt.lclTeid), sizeof(uint32_t), 0, (PTR *)&teidCb);
640 DU_LOG("\nERROR --> EGTP : Tunnel id[%d] not configured", tnlEvt.lclTeid);
641 return LCM_REASON_INVALID_PAR_VAL;
644 cmHashListDelete(&(egtpCb.dstCb.teIdLst), (PTR)teidCb);
645 DU_FREE(teidCb, sizeof(EgtpTeIdCb));
646 egtpCb.dstCb.numTunn--;
650 /*******************************************************************
652 * @brief Handles data indication
656 * Function : EgtpHdlDatInd
659 * Handles incoming data from peer to be passed
663 * @return ROK - success
666 * ****************************************************************/
667 uint8_t egtpHdlDatInd(EgtpMsg egtpMsg)
669 EgtpTeIdCb *teidCb = NULLP;
675 #ifdef CALL_FLOW_DEBUG_LOG
676 DU_LOG("\nCall Flow: ENTDUAPP -> ENTEGTP : DATA_INDICATION\n");
679 DU_LOG("\nDEBUG --> EGTP : Received Data Indication");
681 cmHashListFind(&(egtpCb.dstCb.teIdLst), (uint8_t *)&(egtpMsg.msgHdr.teId), sizeof(uint32_t), 0, (PTR *)&teidCb);
684 DU_LOG("\nERROR --> EGTP : Tunnel id[%d] not configured", egtpMsg.msgHdr.teId);
685 return LCM_REASON_INVALID_PAR_VAL;
688 msgHdr = &(egtpMsg.msgHdr);
690 hdrLen = teidCb->preEncodedHdr.cnt;
692 if(msgHdr->extHdr.pdcpNmb.pres)
694 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] |= EGTP_MASK_BIT3;
695 teidCb->preEncodedHdr.hdr[hdrLen] = EGTP_EXT_HDR_PDCP_TYPE;
696 teidCb->preEncodedHdr.hdr[--hdrLen] = 1;
697 teidCb->preEncodedHdr.hdr[--hdrLen] = GetHiByte(msgHdr->extHdr.pdcpNmb.val);
698 teidCb->preEncodedHdr.hdr[--hdrLen] = GetLoByte(msgHdr->extHdr.pdcpNmb.val);
699 teidCb->preEncodedHdr.hdr[--hdrLen] = 0;
703 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] &= ~(EGTP_MASK_BIT3);
706 ODU_GET_MSG_LEN(egtpMsg.msg, (int16_t *)&tPduSize);
708 /*Adjust the header to fill the correct length*/
709 msgLen = tPduSize + (EGTP_MAX_HDR_LEN - hdrLen) - 0x08;
711 /***********************************************
712 * Fill the length field of the message header *
713 ***********************************************/
714 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 3] = (uint8_t)GetHiByte(msgLen);
715 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 4] = (uint8_t)GetLoByte(msgLen);
717 /*Update the sequence number*/
718 if(egtpMsg.msgHdr.seqNum.pres)
720 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] |= (EGTP_MASK_BIT2);
721 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 9] = (uint8_t)GetHiByte(egtpMsg.msgHdr.seqNum.val);
722 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 10] = (uint8_t)GetLoByte(egtpMsg.msgHdr.seqNum.val);
726 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] &= ~(EGTP_MASK_BIT2);
729 DU_LOG("\nDEBUG --> EGTP : UL Data buffer before encoding header");
730 ODU_PRINT_MSG(egtpMsg.msg, 0, 0);
732 ODU_ADD_PRE_MSG_MULT(&teidCb->preEncodedHdr.hdr[hdrLen], (EGTP_MAX_HDR_LEN - hdrLen), egtpMsg.msg);
735 DU_LOG("\nDEBUG --> EGTP : UL Data buffer after encoding header");
736 ODU_PRINT_MSG(egtpMsg.msg, 0, 0);
739 egtpSendMsg(egtpMsg.msg);
740 ODU_PUT_MSG_BUF(egtpMsg.msg);
745 /*******************************************************************
747 * @brief Encodes outgoing message
751 * Function : egtpEncodeMsg
754 * Encodes EGTP message to be sent
756 * @params[in] EGTP message
758 * @return ROK - success
761 * ****************************************************************/
762 uint8_t egtpEncodeHdr(uint8_t *preEncodedHdr, EgtpMsgHdr *preDefHdr, uint8_t *hdrIdx)
764 uint8_t tmpByte = 0; /* Stores one byte of data for enc */
765 uint8_t cnt = EGTP_MAX_HDR_LEN; /* Stores the position */
766 bool extPres = FALSE; /* Flag for indication of S, E or P presense flag */
769 /* Encoding header */
770 tmpByte |= EGTP_MASK_BIT6; /* Setting 6th LSB of 1st byte as version */
771 tmpByte |= EGTP_MASK_BIT5; /* Setting 5th LSB of 1st byte as protocol type */
773 if(preDefHdr->extHdr.udpPort.pres || preDefHdr->extHdr.pdcpNmb.pres)
775 tmpByte |= EGTP_MASK_BIT3; /* Setting 3rd LSB of 1st byte if Extension heaeder is present */
778 if(preDefHdr->seqNum.pres)
780 tmpByte |= EGTP_MASK_BIT2;
783 if(preDefHdr->nPdu.pres)
785 tmpByte |= EGTP_MASK_BIT1;
788 if((tmpByte & EGTP_MASK_BIT1) || (tmpByte & EGTP_MASK_BIT2)||(tmpByte & EGTP_MASK_BIT3))
793 preEncodedHdr[--cnt] = tmpByte;
794 preEncodedHdr[--cnt] = preDefHdr->msgType;
796 /* Encode Tunnel endpoint */
797 preEncodedHdr[--cnt] = 0;
798 preEncodedHdr[--cnt] = 0;
799 nwWord = (uint16_t)(GetHiWord(preDefHdr->teId));
800 preEncodedHdr[--cnt] = (uint8_t)(GetHiByte(nwWord));
801 preEncodedHdr[--cnt] = (uint8_t)(GetLoByte(nwWord));
802 nwWord = (uint16_t)(GetLoWord(preDefHdr->teId));
803 preEncodedHdr[--cnt] = (uint8_t)(GetHiByte(nwWord));
804 preEncodedHdr[--cnt] = (uint8_t)(GetLoByte(nwWord));
806 /* Encode sequence number */
807 if(preDefHdr->seqNum.pres)
809 preEncodedHdr[--cnt] = GetHiByte(preDefHdr->seqNum.val);
810 preEncodedHdr[--cnt] = GetLoByte(preDefHdr->seqNum.val);
814 preEncodedHdr[--cnt] = 0;
815 preEncodedHdr[--cnt] = 0;
818 /* Encode nPdu number */
819 if(preDefHdr->nPdu.pres)
821 preEncodedHdr[--cnt] = preDefHdr->nPdu.val;
825 preEncodedHdr[--cnt] = 0;
828 if(preDefHdr->extHdr.udpPort.pres)
830 preEncodedHdr[--cnt] = EGTP_EXT_HDR_UDP_TYPE;
831 preEncodedHdr[--cnt] = 1;
832 preEncodedHdr[--cnt] = GetHiByte(preDefHdr->extHdr.udpPort.val);
833 preEncodedHdr[--cnt] = GetLoByte(preDefHdr->extHdr.udpPort.val);
836 if(preDefHdr->extHdr.pdcpNmb.pres)
838 preEncodedHdr[--cnt] = EGTP_EXT_HDR_PDCP_TYPE;
839 preEncodedHdr[--cnt] = 1;
840 preEncodedHdr[--cnt] = GetHiByte(preDefHdr->extHdr.pdcpNmb.val);
841 preEncodedHdr[--cnt] = GetLoByte(preDefHdr->extHdr.pdcpNmb.val);
844 if(tmpByte & EGTP_MASK_BIT3)
846 preEncodedHdr[--cnt] = 0;
850 preEncodedHdr[--cnt] = 0;
855 } /* egtpEncodeHdr */
857 /*******************************************************************
859 * @brief Sends message over UDP
863 * Function : egtpSendMsg
866 * Sends message over UDP
868 * @params[in] Message Buffer
869 * @return ROK - success
872 * ****************************************************************/
873 uint8_t egtpSendMsg(Buffer *mBuf)
879 static uint64_t numDataSent = 0;
881 info.region = DU_APP_MEM_REGION;
884 dstAddr.port = EGTP_RECVR_PORT;
885 dstAddr.address = egtpCb.dstCb.dstIp;
887 ret = cmInetSendMsg(&(egtpCb.dstCb.sendTptSrvr.sockFd), &dstAddr, &info, \
888 mBuf, (int16_t *)&txLen, CM_INET_NO_FLAG);
889 if(ret != ROK && ret != RWOULDBLOCK)
891 DU_LOG("\nERROR --> EGTP : Failed sending the message");
896 DU_LOG("\nDEBUG --> EGTP : Sent UL Message [%ld]", numDataSent+1);
903 /*******************************************************************
905 * @brief Receives EGTP message from UDP socket
909 * Function : egtpRecvMsg
912 * Receive incoming messages from UDP socket
915 * @return ROK - success
918 * ****************************************************************/
920 uint8_t egtpRecvMsg()
922 uint8_t ret; /* Return value */
923 uint16_t bufLen; /* Length of received buffer */
924 Buffer *recvBuf; /* Received buffer */
925 CmInetAddr fromAddr; /* Egtp data sender address */
926 CmInetMemInfo memInfo; /* Buffer allocation info */
928 memInfo.region = DU_APP_MEM_REGION;
929 memInfo.pool = DU_POOL;
931 fromAddr.port = egtpCb.dstCb.dstPort;
932 fromAddr.address = egtpCb.dstCb.dstIp;
937 ret = cmInetRecvMsg(&(egtpCb.recvTptSrvr.sockFd), &fromAddr, &memInfo, \
938 &recvBuf, (int16_t *)&bufLen, CM_INET_NO_FLAG);
939 if(ret == ROK && recvBuf != NULLP)
941 DU_LOG("\nDEBUG --> EGTP : Received DL Message[%ld]\n", gDlDataRcvdCnt + 1);
942 //ODU_PRINT_MSG(recvBuf, 0 ,0);
943 egtpHdlRecvData(recvBuf);
952 /*******************************************************************
954 * @brief Handles DL User data received from CU
958 * Function : egtpHdlRecvData
960 * Functionality: Handles DL User data received from CU
962 * @params[in] DL Usre data buffer
963 * @return ROK - success
966 * ****************************************************************/
967 uint8_t egtpHdlRecvData(Buffer *mBuf)
971 /* Decode EGTP header */
972 egtpDecodeHdr(mBuf, &egtpMsg);
974 /* TODO : Send received message to RLC */
975 duHdlEgtpDlData(&egtpMsg);
980 /*******************************************************************
982 * @brief Decodes EGTP header from DL User data
986 * Function : egtpDecodeHdr
988 * Functionality: Decodes EGTP header from DL User data
991 * @return ROK - success
994 * ****************************************************************/
995 uint8_t egtpDecodeHdr(Buffer *mBuf, EgtpMsg *egtpMsg)
997 uint8_t tmpByte[5]; /* Holds 5 byte of data after Decoding */
998 uint8_t version = 0; /* Holds the version type, decoded */
999 uint16_t msgLen = 0; /* Holds the msgLen from the Hdr */
1000 uint16_t bufLen = 0; /* Holds the total buffer length */
1001 uint8_t extHdrType = 0; /* Holds the Extension hdr type */
1002 uint8_t extHdrLen = 0; /* Extension hdr length */
1003 bool extPres = FALSE; /* Flag for indication of S, E or P presense flag */
1005 ODU_GET_MSG_LEN(mBuf, (int16_t *)&bufLen);
1007 /* Decode first byte and storing in temporary variable */
1008 ODU_REM_PRE_MSG(&tmpByte[0], mBuf);
1010 /* Extracting version fro 1st byte */
1011 version = tmpByte[0] >> 5;
1013 //DU_LOG("\nDEBUG --> EGTP : Version %d", version);
1015 /* Decode message type */
1016 ODU_REM_PRE_MSG((Data*)&(egtpMsg->msgHdr.msgType), mBuf);
1017 //DU_LOG("\nDEBUG --> EGTP : msgType %d", egtpMsg->msgHdr.msgType);
1019 /****************************************************************************
1020 * Message length param is 2 bytes. So decode next 2 bytes from msg hdr and
1021 * performing OR operation on these two bytes to calculate message length
1022 ***************************************************************************/
1023 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
1024 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
1025 msgLen = (tmpByte[1] << 8) | tmpByte[2];
1028 //DU_LOG("\nDEBUG --> EGTP : msgLen %d", msgLen);
1031 /****************************************************************************
1032 * Tunnel id param is 4 bytes. So decode next 4 bytes from msg hdr and
1033 * perform OR operation on these 4 bytes to calculate tunnel id
1034 ***************************************************************************/
1035 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
1036 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
1037 ODU_REM_PRE_MSG(&tmpByte[3], mBuf);
1038 ODU_REM_PRE_MSG(&tmpByte[4], mBuf);
1039 egtpMsg->msgHdr.teId = (tmpByte[1] << 24) | (tmpByte[2] << 16) | (tmpByte[3] << 8) | tmpByte[4];
1040 //DU_LOG("\nDEBUG --> EGTP : teId %d",egtpMsg->msgHdr.teId);
1043 /* If any one of S, E or PN flag is set, set extension present as true. */
1044 if((tmpByte[0] & EGTP_MASK_BIT1) || (tmpByte[0] & EGTP_MASK_BIT2)||(tmpByte[0] & EGTP_MASK_BIT3))
1049 /* Decode sequence number, if S flag is set in first byte */
1050 if (tmpByte[0] & EGTP_MASK_BIT2)
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 = TRUE;
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];
1061 /****************************************************************************
1062 * If extPres is true, but S bit is not set, implies, either of PN or E bit
1063 * was set during Encode so accordingly extract Byte fields for seqNum anyway
1064 ***************************************************************************/
1067 /*************************************************************************
1068 * Sequence num is 2 bytes. So decode next 2 bytes from msg hdr and
1069 * perform OR operation on them
1070 ************************************************************************/
1071 egtpMsg->msgHdr.seqNum.pres = 0;
1072 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
1073 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
1074 egtpMsg->msgHdr.seqNum.val = (tmpByte[1] << 8) | tmpByte[2];
1077 /* Decode N-PDU number if present flag is set */
1078 if (tmpByte[0] & EGTP_MASK_BIT1)
1080 egtpMsg->msgHdr.nPdu.pres = TRUE;
1081 ODU_REM_PRE_MSG(&(egtpMsg->msgHdr.nPdu.val), mBuf);
1083 /****************************************************************************
1084 * If extPres is true, but PN bit is not set, implies, either of S or E bit
1085 * was set during Encode. Aaccordingly extract Byte fields of N-PDU num anyway
1086 ***************************************************************************/
1089 egtpMsg->msgHdr.nPdu.pres = TRUE;
1090 ODU_REM_PRE_MSG(&(egtpMsg->msgHdr.nPdu.val), mBuf);
1093 /* If E flag is set in first byte, decode extension header */
1094 if(tmpByte[0] & EGTP_MASK_BIT3)
1096 ODU_REM_PRE_MSG(&extHdrType, mBuf);
1097 while( 0 != extHdrType)
1101 case EGTP_EXT_HDR_UDP_TYPE:
1103 ODU_REM_PRE_MSG(&extHdrLen, mBuf);
1104 if(extHdrLen == 0x01)
1106 /************************************************************
1107 * UDP Port is 2 bytes. So decode next 2 bytes from msg hdr
1108 * and perform OR operation on them
1109 *************************************************************/
1110 egtpMsg->msgHdr.extHdr.udpPort.pres = TRUE;
1111 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
1112 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
1113 egtpMsg->msgHdr.extHdr.udpPort.val = (tmpByte[1] << 8) | tmpByte[2];
1118 case EGTP_EXT_HDR_PDCP_TYPE:
1120 ODU_REM_PRE_MSG(&extHdrLen, mBuf);
1121 if(extHdrLen == 0x01)
1123 /*************************************************************
1124 * PDCP num is 2 bytes. So decode next 2 bytes from msg hdr
1125 * and perform OR operation on them
1126 ************************************************************/
1127 egtpMsg->msgHdr.extHdr.pdcpNmb.pres = TRUE;
1128 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
1129 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
1130 egtpMsg->msgHdr.extHdr.pdcpNmb.val = (tmpByte[1] << 8) | tmpByte[2];
1134 } /* End of switch */
1136 ODU_REM_PRE_MSG(&extHdrType, mBuf);
1138 } /* End of while */
1140 /****************************************************************************
1141 * If extPres is true, but E bit is not set, implies, either of PN or S bit
1142 * was set during Encode so accordingly extract Byte fields for extension
1144 ***************************************************************************/
1147 ODU_REM_PRE_MSG(&extHdrType, mBuf);
1150 egtpMsg->msg = mBuf;
1152 //DU_LOG("\nDEBUG --> EGTP : DL Data Buffer after decoding header ");
1153 //ODU_PRINT_MSG(mBuf, 0, 0);
1155 /* Forward the data to duApp/RLC */
1160 /**********************************************************************
1162 **********************************************************************/