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"
33 /**************************************************************************
34 * @brief Task Initiation callback function.
38 * Function : egtpActvInit
41 * This function is supplied as one of parameters during EGTP's
42 * task registration. SSI will invoke this function once, after
43 * it creates and attaches this TAPA Task to a system task.
45 * @param[in] Ent entity, the entity ID of this task.
46 * @param[in] Inst inst, the instance ID of this task.
47 * @param[in] Region region, the region ID registered for memory
49 * @param[in] Reason reason.
50 * @return ROK - success
52 ***************************************************************************/
53 uint8_t egtpActvInit(Ent entity, Inst inst, Region region, Reason reason)
55 DU_LOG("\n\nDEBUG --> EGTP : Initializing");
57 memset (&egtpCb, 0, sizeof(EgtpGlobalCb));
58 protType = CM_INET_PROTO_UDP;
64 /**************************************************************************
65 * @brief Function prints the src dest and msg reached to egtp.
69 * Function : callFlowEgtpActvTsk
72 * Function prints the src dest and msg reached to egtp.
74 * @param[in] Pst *pst, Post structure of the primitive.
78 ***************************************************************************/
80 void callFlowEgtpActvTsk(Pst *pst)
84 char destTask[50]="ENTEGTP";
91 strcpy(sourceTask,"ENTDUAPP");
96 strcpy(message,"EVTCFGREQ");
101 strcpy(message,"EVTSRVOPENREQ");
106 strcpy(message,"EVTTNLMGMTREQ");
111 strcpy(message,"Invalid Event");
119 strcpy(sourceTask,"ENTEGTP");
124 strcpy(message,"EVTSTARTPOLL");
129 strcpy(message,"Invalid Event");
137 strcpy(sourceTask,"ENTRLC");
142 strcpy(message,"EVTDATIND");
147 strcpy(message,"Invalid Event");
155 strcpy(sourceTask,"Invalid Source Entity Id");
158 DU_LOG("\nCall Flow: %s -> %s : %s\n", sourceTask, destTask, message);
161 /**************************************************************************
162 * @brief Task Activation callback function.
166 * Function : egtpActvTsk
169 * This function handles all EGTP messages received
170 * This API is registered with SSI during the
171 * Task Registration of DU APP.
173 * @param[in] Pst *pst, Post structure of the primitive.
174 * @param[in] Buffer *mBuf, Packed primitive parameters in the
176 * @return ROK - success
179 ***************************************************************************/
180 uint8_t egtpActvTsk(Pst *pst, Buffer *mBuf)
184 #ifdef CALL_FLOW_DEBUG_LOG
185 callFlowEgtpActvTsk(pst);
196 ret = unpackEgtpCfgReq(egtpCfgReq, pst, mBuf);
201 ret = unpackEgtpSrvOpenReq(egtpSrvOpenReq, pst, mBuf);
206 ret = unpackEgtpTnlMgmtReq(egtpTnlMgmtReq, pst, mBuf);
211 DU_LOG("\nERROR --> EGTP : Invalid event %d", pst->event);
212 ODU_PUT_MSG_BUF(mBuf);
224 DU_LOG("\nDEBUG --> EGTP : Starting Socket Polling");
226 ODU_PUT_MSG_BUF(mBuf);
231 DU_LOG("\nERROR --> EGTP : Invalid event %d", pst->event);
232 ODU_PUT_MSG_BUF(mBuf);
249 DU_LOG("\nERROR --> EGTP : Invalid event %d", pst->event);
257 DU_LOG("\nERROR --> EGTP : Invalid source entity %d", pst->srcEnt);
265 /**************************************************************************
266 * @brief EGTP server configuration
270 * Function : egtpCfgReq
273 * This function handles EGTP configuration request.
275 * @return ROK - success
278 * ***********************************************************************/
279 uint8_t egtpCfgReq(Pst *pst, EgtpConfig egtpCfg)
281 uint8_t ret; /* Return value */
282 Pst rspPst; /* Response Pst structure */
283 CmStatus cfgCfm; /* Configuration Confirm */
285 memcpy(&egtpCb.egtpCfg, &egtpCfg, sizeof(EgtpConfig));
287 egtpCb.recvTptSrvr.addr.address = CM_INET_NTOH_UINT32(egtpCb.egtpCfg.localIp.ipV4Addr);
288 egtpCb.recvTptSrvr.addr.port = EGTP_DFLT_PORT;
290 egtpCb.dstCb.dstIp = CM_INET_NTOH_UINT32(egtpCb.egtpCfg.destIp.ipV4Addr);
291 egtpCb.dstCb.dstPort = egtpCb.egtpCfg.destPort;
292 egtpCb.dstCb.sendTptSrvr.addr.address = CM_INET_NTOH_UINT32(egtpCb.egtpCfg.localIp.ipV4Addr);
293 egtpCb.dstCb.sendTptSrvr.addr.port = egtpCb.egtpCfg.localPort;
294 egtpCb.dstCb.numTunn = 0;
296 ret = cmHashListInit(&(egtpCb.dstCb.teIdLst), 1024, sizeof(EgtpTeIdCb), FALSE, CM_HASH_KEYTYPE_UINT32_MOD, DU_APP_MEM_REGION, DU_POOL);
300 DU_LOG("\nERROR --> EGTP : TeId hash list initialization failed");
301 cfgCfm.status = LCM_PRIM_NOK;
302 cfgCfm.reason = LCM_REASON_HASHING_FAILED;
306 DU_LOG("\nDEBUG --> EGTP : EGTP configuration successful");
307 cfgCfm.status = LCM_PRIM_OK;
308 cfgCfm.reason = LCM_REASON_NOT_APPL;
311 /* Fill response Pst */
312 egtpFillRspPst(pst, &rspPst);
313 rspPst.event = EVTCFGCFM;
315 packEgtpCfgCfm(&rspPst, cfgCfm);
320 /**************************************************************************
321 * @brief Fills post structure to send response
325 * Function : egtpFillRspPst
328 * Fills post struture to send response
330 * @return ROK - success
334 * ***********************************************************************/
335 uint8_t egtpFillRspPst(Pst *pst, Pst *rspPst)
338 memset(rspPst, 0, sizeof(Pst));
339 rspPst->srcEnt = pst->dstEnt;
340 rspPst->srcInst = pst->dstInst;
341 rspPst->srcProcId = pst->dstProcId;
342 rspPst->dstEnt = pst->srcEnt;
343 rspPst->dstInst = pst->srcInst;
344 rspPst->dstProcId = pst->srcProcId;
345 rspPst->selector = ODU_SELECTOR_LC;
346 rspPst->pool= DU_POOL;
351 /**************************************************************************
352 * @brief EGTP server open request
356 * Function : egtpSrvOpenReq
359 * This function handles EGTP open server request.
360 * It opens udp socket to receive/send msgs.
362 * @param[in] Pst *pst, post structure
363 * @return ROK - success
366 ***************************************************************************/
368 uint8_t egtpSrvOpenReq(Pst *pst)
371 uint8_t ret; /* Return value */
372 Pst rspPst; /* Response Pst structure */
373 Pst egtpPst; /* Self post */
374 CmStatus cfm; /* Confirmation status */
375 uint8_t sockType; /* Socket type */
377 DU_LOG("\nDEBUG --> EGTP : Received EGTP open server request");
379 sockType = CM_INET_DGRAM;
380 ret = egtpSrvOpenPrc(sockType, &(egtpCb.recvTptSrvr));
381 /* Opening and Binding receiver socket */
384 DU_LOG("\nERROR --> EGTP : Failed while opening receiver transport server");
387 /* Opening and Binding sender socket */
388 ret = egtpSrvOpenPrc(sockType, &(egtpCb.dstCb.sendTptSrvr));
391 DU_LOG("\nERROR --> EGTP : Failed while opening sender transport server");
395 DU_LOG("\nDEBUG --> EGTP : Receiver socket[%d] and Sender socket[%d] open", egtpCb.recvTptSrvr.sockFd.fd,\
396 egtpCb.dstCb.sendTptSrvr.sockFd.fd);
398 /* Start Socket polling */
399 memset(&egtpPst, 0, sizeof(egtpPst));
400 egtpPst.srcEnt = (Ent)ENTEGTP;
401 egtpPst.srcInst = (Inst)EGTP_INST;
402 egtpPst.srcProcId = DU_PROC;
403 egtpPst.dstEnt = (Ent)ENTEGTP;
404 egtpPst.dstInst = (Inst)EGTP_INST;
405 egtpPst.dstProcId = DU_PROC;
406 egtpPst.event = EVTSTARTPOLL;
407 egtpPst.selector = ODU_SELECTOR_LC;
408 egtpPst.pool= DU_POOL;
409 packEgtpStartPollingReq(&egtpPst);
411 /* Filling and sending response */
412 cfm.status = LCM_PRIM_OK;
413 cfm.reason = LCM_REASON_NOT_APPL;
415 egtpFillRspPst(pst, &rspPst);
416 rspPst.event = EVTSRVOPENCFM;
417 packEgtpSrvOpenCfm(&rspPst, cfm);
422 /*******************************************************************
424 * @brief Processing Sever open request
428 * Function : egtpSrvOpenPrc
434 * @return ROK - success
437 * ****************************************************************/
439 uint8_t egtpSrvOpenPrc(uint8_t sockType, EgtpTptSrvr *server)
442 ret = cmInetSocket(sockType, &(server->sockFd), protType);
445 DU_LOG("\nERROR --> EGTP : Failed to open UDP socket");
448 ret = cmInetBind(&(server->sockFd), &(server->addr));
451 DU_LOG("\nERROR --> EGTP : Failed to bind socket");
458 /**************************************************************************
459 * @brief EGTP tunnel management request
463 * Function : egtpTnlMgmtReq
466 * This function handles EGTP tunnel managament request
468 * @param[in] Tunnel Eveny structure
469 * @return ROK - success
473 * ***************************************************************************/
474 uint8_t egtpTnlMgmtReq(Pst *pst, EgtpTnlEvt tnlEvt)
478 #ifdef CALL_FLOW_DEBUG_LOG
479 DU_LOG("\nCall Flow: ENTDUAPP -> ENTEGTP : TNL_MGMT\n");
482 DU_LOG("\nDEBUG --> EGTP : Received tunnel management request");
483 switch(tnlEvt.action)
485 case EGTP_TNL_MGMT_ADD:
487 ret = egtpTnlAdd(tnlEvt);
490 case EGTP_TNL_MGMT_MOD:
492 ret = egtpTnlMod(tnlEvt);
495 case EGTP_TNL_MGMT_DEL:
497 ret = egtpTnlDel(tnlEvt);
502 DU_LOG("\nERROR --> EGTP : Invalid tunnel management action[%d]", tnlEvt.action);
503 ret = LCM_REASON_INVALID_ACTION;
509 tnlEvt.cfmStatus.status = LCM_PRIM_OK;
510 tnlEvt.cfmStatus.reason = LCM_REASON_NOT_APPL;
514 tnlEvt.cfmStatus.status = LCM_PRIM_NOK;
515 tnlEvt.cfmStatus.reason = ret;
518 DU_LOG("\nDEBUG --> EGTP : Sending Tunnel management confirmation");
519 duHdlEgtpTnlMgmtCfm(tnlEvt);
524 /**************************************************************************
525 * @brief EGTP tunnel addition
529 * Function : egtpTnlAdd
532 * This function handles EGTP tunnel addition
534 * @param[in] Tunnel Event structure
535 * @return ROK - success
538 * ***************************************************************************/
539 uint8_t egtpTnlAdd(EgtpTnlEvt tnlEvt)
542 EgtpTeIdCb *teidCb; /* Tunnel endpoint control block */
543 EgtpMsgHdr preDefHdr; /* pre-define header for this tunnel */
545 DU_LOG("\nINFO --> EGTP : Tunnel addition : LocalTeid[%d] Remote Teid[%d]", tnlEvt.lclTeid, tnlEvt.remTeid);
547 DU_ALLOC(teidCb, sizeof(EgtpTeIdCb));
550 DU_LOG("\nERROR --> EGTP : Memory allocation failed");
551 return LCM_REASON_MEM_NOAVAIL;
554 memset(teidCb, 0, sizeof(EgtpTeIdCb));
555 teidCb->teId = tnlEvt.lclTeid;
556 teidCb->remTeId = tnlEvt.remTeid;
558 ret = cmHashListInsert(&(egtpCb.dstCb.teIdLst), (PTR)teidCb, (uint8_t *)&(teidCb->teId), sizeof(uint32_t));
561 DU_LOG("\nERROR --> EGTP : Failed to insert in hash list");
562 DU_FREE(teidCb, sizeof(EgtpTeIdCb));
563 return LCM_REASON_HASHING_FAILED;
565 egtpCb.dstCb.numTunn++;
567 /* Encoding pre-defined header */
568 memset(&preDefHdr, 0, sizeof(EgtpMsgHdr));
569 preDefHdr.msgType = EGTPU_MSG_GPDU;
570 preDefHdr.teId = teidCb->remTeId;
571 preDefHdr.extHdr.pdcpNmb.pres = FALSE;
572 preDefHdr.extHdr.udpPort.pres = FALSE;
573 preDefHdr.nPdu.pres = FALSE;
575 egtpEncodeHdr((uint8_t *)teidCb->preEncodedHdr.hdr, &preDefHdr, &(teidCb->preEncodedHdr.cnt));
580 /**************************************************************************
581 * @brief EGTP tunnel modification
585 * Function : egtpTnlMod
588 * This function handles EGTP tunnel modification
590 * @param[in] Tunnel Event structure
591 * @return ROK - success
594 * ***************************************************************************/
595 uint8_t egtpTnlMod(EgtpTnlEvt tnlEvt)
597 EgtpTeIdCb *teidCb = NULLP;
599 DU_LOG("\nINFO --> EGTP : Tunnel modification : LocalTeid[%d] Remote Teid[%d]", tnlEvt.lclTeid, tnlEvt.remTeid);
601 cmHashListFind(&(egtpCb.dstCb.teIdLst), (uint8_t *)&(tnlEvt.lclTeid), sizeof(uint32_t), 0, (PTR *)&teidCb);
604 DU_LOG("\nERROR --> EGTP : Tunnel id not found");
607 teidCb->teId = tnlEvt.remTeid;
608 teidCb->remTeId = tnlEvt.remTeid;
612 /**************************************************************************
613 * @brief EGTP tunnel deletion
617 * Function : egtpTnlDel
620 * This function handles EGTP tunnel deletion
622 * @param[in] Tunnel Event structure
623 * @return ROK - success
626 * ***************************************************************************/
627 uint8_t egtpTnlDel(EgtpTnlEvt tnlEvt)
629 EgtpTeIdCb *teidCb = NULLP;
631 DU_LOG("\nINFO --> EGTP : Tunnel deletion : Local Teid[%d] Remote Teid[%d]", tnlEvt.lclTeid, tnlEvt.remTeid);
633 cmHashListFind(&(egtpCb.dstCb.teIdLst), (uint8_t *)&(tnlEvt.lclTeid), sizeof(uint32_t), 0, (PTR *)&teidCb);
636 DU_LOG("\nERROR --> EGTP : Tunnel id[%d] not configured", tnlEvt.lclTeid);
637 return LCM_REASON_INVALID_PAR_VAL;
640 cmHashListDelete(&(egtpCb.dstCb.teIdLst), (PTR)teidCb);
641 DU_FREE(teidCb, sizeof(EgtpTeIdCb));
642 egtpCb.dstCb.numTunn--;
646 /*******************************************************************
648 * @brief Handles data indication
652 * Function : EgtpHdlDatInd
655 * Handles incoming data from peer to be passed
659 * @return ROK - success
662 * ****************************************************************/
663 uint8_t egtpHdlDatInd(EgtpMsg egtpMsg)
665 EgtpTeIdCb *teidCb = NULLP;
671 #ifdef CALL_FLOW_DEBUG_LOG
672 DU_LOG("\nCall Flow: ENTDUAPP -> ENTEGTP : DATA_INDICATION\n");
675 DU_LOG("\nDEBUG --> EGTP : Received Data Indication");
677 cmHashListFind(&(egtpCb.dstCb.teIdLst), (uint8_t *)&(egtpMsg.msgHdr.teId), sizeof(uint32_t), 0, (PTR *)&teidCb);
680 DU_LOG("\nERROR --> EGTP : Tunnel id[%d] not configured", egtpMsg.msgHdr.teId);
681 return LCM_REASON_INVALID_PAR_VAL;
684 msgHdr = &(egtpMsg.msgHdr);
686 hdrLen = teidCb->preEncodedHdr.cnt;
688 if(msgHdr->extHdr.pdcpNmb.pres)
690 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] |= EGTP_MASK_BIT3;
691 teidCb->preEncodedHdr.hdr[hdrLen] = EGTP_EXT_HDR_PDCP_TYPE;
692 teidCb->preEncodedHdr.hdr[--hdrLen] = 1;
693 teidCb->preEncodedHdr.hdr[--hdrLen] = GetHiByte(msgHdr->extHdr.pdcpNmb.val);
694 teidCb->preEncodedHdr.hdr[--hdrLen] = GetLoByte(msgHdr->extHdr.pdcpNmb.val);
695 teidCb->preEncodedHdr.hdr[--hdrLen] = 0;
699 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] &= ~(EGTP_MASK_BIT3);
702 ODU_GET_MSG_LEN(egtpMsg.msg, (int16_t *)&tPduSize);
704 /*Adjust the header to fill the correct length*/
705 msgLen = tPduSize + (EGTP_MAX_HDR_LEN - hdrLen) - 0x08;
707 /***********************************************
708 * Fill the length field of the message header *
709 ***********************************************/
710 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 3] = (uint8_t)GetHiByte(msgLen);
711 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 4] = (uint8_t)GetLoByte(msgLen);
713 /*Update the sequence number*/
714 if(egtpMsg.msgHdr.seqNum.pres)
716 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] |= (EGTP_MASK_BIT2);
717 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 9] = (uint8_t)GetHiByte(egtpMsg.msgHdr.seqNum.val);
718 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 10] = (uint8_t)GetLoByte(egtpMsg.msgHdr.seqNum.val);
722 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] &= ~(EGTP_MASK_BIT2);
725 DU_LOG("\nDEBUG --> EGTP : UL Data buffer before encoding header");
726 ODU_PRINT_MSG(egtpMsg.msg, 0, 0);
728 ODU_ADD_PRE_MSG_MULT(&teidCb->preEncodedHdr.hdr[hdrLen], (EGTP_MAX_HDR_LEN - hdrLen), egtpMsg.msg);
731 DU_LOG("\nDEBUG --> EGTP : UL Data buffer after encoding header");
732 ODU_PRINT_MSG(egtpMsg.msg, 0, 0);
735 egtpSendMsg(egtpMsg.msg);
736 ODU_PUT_MSG_BUF(egtpMsg.msg);
741 /*******************************************************************
743 * @brief Encodes outgoing message
747 * Function : egtpEncodeMsg
750 * Encodes EGTP message to be sent
752 * @params[in] EGTP message
754 * @return ROK - success
757 * ****************************************************************/
758 uint8_t egtpEncodeHdr(uint8_t *preEncodedHdr, EgtpMsgHdr *preDefHdr, uint8_t *hdrIdx)
760 uint8_t tmpByte = 0; /* Stores one byte of data for enc */
761 uint8_t cnt = EGTP_MAX_HDR_LEN; /* Stores the position */
762 bool extPres = FALSE; /* Flag for indication of S, E or P presense flag */
765 /* Encoding header */
766 tmpByte |= EGTP_MASK_BIT6; /* Setting 6th LSB of 1st byte as version */
767 tmpByte |= EGTP_MASK_BIT5; /* Setting 5th LSB of 1st byte as protocol type */
769 if(preDefHdr->extHdr.udpPort.pres || preDefHdr->extHdr.pdcpNmb.pres)
771 tmpByte |= EGTP_MASK_BIT3; /* Setting 3rd LSB of 1st byte if Extension heaeder is present */
774 if(preDefHdr->seqNum.pres)
776 tmpByte |= EGTP_MASK_BIT2;
779 if(preDefHdr->nPdu.pres)
781 tmpByte |= EGTP_MASK_BIT1;
784 if((tmpByte & EGTP_MASK_BIT1) || (tmpByte & EGTP_MASK_BIT2)||(tmpByte & EGTP_MASK_BIT3))
789 preEncodedHdr[--cnt] = tmpByte;
790 preEncodedHdr[--cnt] = preDefHdr->msgType;
792 /* Encode Tunnel endpoint */
793 preEncodedHdr[--cnt] = 0;
794 preEncodedHdr[--cnt] = 0;
795 nwWord = (uint16_t)(GetHiWord(preDefHdr->teId));
796 preEncodedHdr[--cnt] = (uint8_t)(GetHiByte(nwWord));
797 preEncodedHdr[--cnt] = (uint8_t)(GetLoByte(nwWord));
798 nwWord = (uint16_t)(GetLoWord(preDefHdr->teId));
799 preEncodedHdr[--cnt] = (uint8_t)(GetHiByte(nwWord));
800 preEncodedHdr[--cnt] = (uint8_t)(GetLoByte(nwWord));
802 /* Encode sequence number */
803 if(preDefHdr->seqNum.pres)
805 preEncodedHdr[--cnt] = GetHiByte(preDefHdr->seqNum.val);
806 preEncodedHdr[--cnt] = GetLoByte(preDefHdr->seqNum.val);
810 preEncodedHdr[--cnt] = 0;
811 preEncodedHdr[--cnt] = 0;
814 /* Encode nPdu number */
815 if(preDefHdr->nPdu.pres)
817 preEncodedHdr[--cnt] = preDefHdr->nPdu.val;
821 preEncodedHdr[--cnt] = 0;
824 if(preDefHdr->extHdr.udpPort.pres)
826 preEncodedHdr[--cnt] = EGTP_EXT_HDR_UDP_TYPE;
827 preEncodedHdr[--cnt] = 1;
828 preEncodedHdr[--cnt] = GetHiByte(preDefHdr->extHdr.udpPort.val);
829 preEncodedHdr[--cnt] = GetLoByte(preDefHdr->extHdr.udpPort.val);
832 if(preDefHdr->extHdr.pdcpNmb.pres)
834 preEncodedHdr[--cnt] = EGTP_EXT_HDR_PDCP_TYPE;
835 preEncodedHdr[--cnt] = 1;
836 preEncodedHdr[--cnt] = GetHiByte(preDefHdr->extHdr.pdcpNmb.val);
837 preEncodedHdr[--cnt] = GetLoByte(preDefHdr->extHdr.pdcpNmb.val);
840 if(tmpByte & EGTP_MASK_BIT3)
842 preEncodedHdr[--cnt] = 0;
846 preEncodedHdr[--cnt] = 0;
851 } /* egtpEncodeHdr */
853 /*******************************************************************
855 * @brief Sends message over UDP
859 * Function : egtpSendMsg
862 * Sends message over UDP
864 * @params[in] Message Buffer
865 * @return ROK - success
868 * ****************************************************************/
869 uint8_t egtpSendMsg(Buffer *mBuf)
875 static uint64_t numDataSent = 0;
877 info.region = DU_APP_MEM_REGION;
880 dstAddr.port = EGTP_DFLT_PORT;
881 dstAddr.address = egtpCb.dstCb.dstIp;
883 ret = cmInetSendMsg(&(egtpCb.dstCb.sendTptSrvr.sockFd), &dstAddr, &info, \
884 mBuf, (int16_t *)&txLen, CM_INET_NO_FLAG);
885 if(ret != ROK && ret != RWOULDBLOCK)
887 DU_LOG("\nERROR --> EGTP : Failed sending the message");
892 DU_LOG("\nDEBUG --> EGTP : Sent UL Message [%ld]", numDataSent+1);
899 /*******************************************************************
901 * @brief Receives EGTP message from UDP socket
905 * Function : egtpRecvMsg
908 * Receive incoming messages from UDP socket
911 * @return ROK - success
914 * ****************************************************************/
916 uint8_t egtpRecvMsg()
918 uint8_t ret; /* Return value */
919 uint16_t bufLen; /* Length of received buffer */
920 Buffer *recvBuf; /* Received buffer */
921 CmInetAddr fromAddr; /* Egtp data sender address */
922 CmInetMemInfo memInfo; /* Buffer allocation info */
924 memInfo.region = DU_APP_MEM_REGION;
925 memInfo.pool = DU_POOL;
927 fromAddr.port = egtpCb.dstCb.dstPort;
928 fromAddr.address = egtpCb.dstCb.dstIp;
933 ret = cmInetRecvMsg(&(egtpCb.recvTptSrvr.sockFd), &fromAddr, &memInfo, \
934 &recvBuf, (int16_t *)&bufLen, CM_INET_NO_FLAG);
935 if(ret == ROK && recvBuf != NULLP)
937 DU_LOG("\nDEBUG --> EGTP : Received DL Message[%ld]\n", gDlDataRcvdCnt + 1);
938 //ODU_PRINT_MSG(recvBuf, 0 ,0);
939 egtpHdlRecvData(recvBuf);
948 /*******************************************************************
950 * @brief Handles DL User data received from CU
954 * Function : egtpHdlRecvData
956 * Functionality: Handles DL User data received from CU
958 * @params[in] DL Usre data buffer
959 * @return ROK - success
962 * ****************************************************************/
963 uint8_t egtpHdlRecvData(Buffer *mBuf)
967 /* Decode EGTP header */
968 egtpDecodeHdr(mBuf, &egtpMsg);
970 /* TODO : Send received message to RLC */
971 duHdlEgtpDlData(&egtpMsg);
976 /*******************************************************************
978 * @brief Decodes EGTP header from DL User data
982 * Function : egtpDecodeHdr
984 * Functionality: Decodes EGTP header from DL User data
987 * @return ROK - success
990 * ****************************************************************/
991 uint8_t egtpDecodeHdr(Buffer *mBuf, EgtpMsg *egtpMsg)
993 uint8_t tmpByte[5]; /* Holds 5 byte of data after Decoding */
994 uint8_t version = 0; /* Holds the version type, decoded */
995 uint16_t msgLen = 0; /* Holds the msgLen from the Hdr */
996 uint16_t bufLen = 0; /* Holds the total buffer length */
997 uint8_t extHdrType = 0; /* Holds the Extension hdr type */
998 uint8_t extHdrLen = 0; /* Extension hdr length */
999 bool extPres = FALSE; /* Flag for indication of S, E or P presense flag */
1001 ODU_GET_MSG_LEN(mBuf, (int16_t *)&bufLen);
1003 /* Decode first byte and storing in temporary variable */
1004 ODU_REM_PRE_MSG(&tmpByte[0], mBuf);
1006 /* Extracting version fro 1st byte */
1007 version = tmpByte[0] >> 5;
1009 //DU_LOG("\nDEBUG --> EGTP : Version %d", version);
1011 /* Decode message type */
1012 ODU_REM_PRE_MSG((Data*)&(egtpMsg->msgHdr.msgType), mBuf);
1013 //DU_LOG("\nDEBUG --> EGTP : msgType %d", egtpMsg->msgHdr.msgType);
1015 /****************************************************************************
1016 * Message length param is 2 bytes. So decode next 2 bytes from msg hdr and
1017 * performing OR operation on these two bytes to calculate message length
1018 ***************************************************************************/
1019 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
1020 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
1021 msgLen = (tmpByte[1] << 8) | tmpByte[2];
1024 //DU_LOG("\nDEBUG --> EGTP : msgLen %d", msgLen);
1027 /****************************************************************************
1028 * Tunnel id param is 4 bytes. So decode next 4 bytes from msg hdr and
1029 * perform OR operation on these 4 bytes to calculate tunnel id
1030 ***************************************************************************/
1031 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
1032 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
1033 ODU_REM_PRE_MSG(&tmpByte[3], mBuf);
1034 ODU_REM_PRE_MSG(&tmpByte[4], mBuf);
1035 egtpMsg->msgHdr.teId = (tmpByte[1] << 24) | (tmpByte[2] << 16) | (tmpByte[3] << 8) | tmpByte[4];
1036 //DU_LOG("\nDEBUG --> EGTP : teId %d",egtpMsg->msgHdr.teId);
1039 /* If any one of S, E or PN flag is set, set extension present as true. */
1040 if((tmpByte[0] & EGTP_MASK_BIT1) || (tmpByte[0] & EGTP_MASK_BIT2)||(tmpByte[0] & EGTP_MASK_BIT3))
1045 /* Decode sequence number, if S flag is set in first byte */
1046 if (tmpByte[0] & EGTP_MASK_BIT2)
1048 /************************************************************************
1049 * Sequence num is 2 bytes. So decode next 2 bytes from msg hdr and
1050 * perform OR operation on them
1051 ************************************************************************/
1052 egtpMsg->msgHdr.seqNum.pres = TRUE;
1053 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
1054 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
1055 egtpMsg->msgHdr.seqNum.val = (tmpByte[1] << 8) | tmpByte[2];
1057 /****************************************************************************
1058 * If extPres is true, but S bit is not set, implies, either of PN or E bit
1059 * was set during Encode so accordingly extract Byte fields for seqNum anyway
1060 ***************************************************************************/
1063 /*************************************************************************
1064 * Sequence num is 2 bytes. So decode next 2 bytes from msg hdr and
1065 * perform OR operation on them
1066 ************************************************************************/
1067 egtpMsg->msgHdr.seqNum.pres = 0;
1068 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
1069 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
1070 egtpMsg->msgHdr.seqNum.val = (tmpByte[1] << 8) | tmpByte[2];
1073 /* Decode N-PDU number if present flag is set */
1074 if (tmpByte[0] & EGTP_MASK_BIT1)
1076 egtpMsg->msgHdr.nPdu.pres = TRUE;
1077 ODU_REM_PRE_MSG(&(egtpMsg->msgHdr.nPdu.val), mBuf);
1079 /****************************************************************************
1080 * If extPres is true, but PN bit is not set, implies, either of S or E bit
1081 * was set during Encode. Aaccordingly extract Byte fields of N-PDU num anyway
1082 ***************************************************************************/
1085 egtpMsg->msgHdr.nPdu.pres = TRUE;
1086 ODU_REM_PRE_MSG(&(egtpMsg->msgHdr.nPdu.val), mBuf);
1089 /* If E flag is set in first byte, decode extension header */
1090 if(tmpByte[0] & EGTP_MASK_BIT3)
1092 ODU_REM_PRE_MSG(&extHdrType, mBuf);
1093 while( 0 != extHdrType)
1097 case EGTP_EXT_HDR_UDP_TYPE:
1099 ODU_REM_PRE_MSG(&extHdrLen, mBuf);
1100 if(extHdrLen == 0x01)
1102 /************************************************************
1103 * UDP Port is 2 bytes. So decode next 2 bytes from msg hdr
1104 * and perform OR operation on them
1105 *************************************************************/
1106 egtpMsg->msgHdr.extHdr.udpPort.pres = TRUE;
1107 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
1108 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
1109 egtpMsg->msgHdr.extHdr.udpPort.val = (tmpByte[1] << 8) | tmpByte[2];
1114 case EGTP_EXT_HDR_PDCP_TYPE:
1116 ODU_REM_PRE_MSG(&extHdrLen, mBuf);
1117 if(extHdrLen == 0x01)
1119 /*************************************************************
1120 * PDCP num is 2 bytes. So decode next 2 bytes from msg hdr
1121 * and perform OR operation on them
1122 ************************************************************/
1123 egtpMsg->msgHdr.extHdr.pdcpNmb.pres = TRUE;
1124 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
1125 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
1126 egtpMsg->msgHdr.extHdr.pdcpNmb.val = (tmpByte[1] << 8) | tmpByte[2];
1130 } /* End of switch */
1132 ODU_REM_PRE_MSG(&extHdrType, mBuf);
1134 } /* End of while */
1136 /****************************************************************************
1137 * If extPres is true, but E bit is not set, implies, either of PN or S bit
1138 * was set during Encode so accordingly extract Byte fields for extension
1140 ***************************************************************************/
1143 ODU_REM_PRE_MSG(&extHdrType, mBuf);
1146 egtpMsg->msg = mBuf;
1148 //DU_LOG("\nDEBUG --> EGTP : DL Data Buffer after decoding header ");
1149 //ODU_PRINT_MSG(mBuf, 0, 0);
1151 /* Forward the data to duApp/RLC */
1156 /**********************************************************************
1158 **********************************************************************/