[Epic-ID: ODUHIGH-406][Task-ID: ODUHIGH-423]UE context creation at RLC in Target...
[o-du/l2.git] / src / cu_stub / cu_stub_egtp.c
index b8a82de..0def93c 100644 (file)
  
 /* This file contains all EGTP related functionality */
 
-#include <stdio.h>
+#include "common_def.h"
+#include "OCTET_STRING.h"
+#include "cu_stub_sctp.h"
+#include "cu_f1ap_msg_hdl.h"
 #include "cu_stub_egtp.h"
-
-/* Global variable declaration */
-EgtpGlobalCb egtpCb;
+#include "cu_stub.h"
+#include "cm_inet.h"
+#include "cm_tpt.h"
+#include "cm_inet.x"
+#include "cm_tpt.x"
 
 /**************************************************************************
  * @brief Task Initiation callback function. 
@@ -46,10 +52,13 @@ EgtpGlobalCb egtpCb;
  ***************************************************************************/
 S16 egtpActvInit()
 {
-  DU_LOG("\n\nEGTP : Initializing");
-  cmMemset ((U8 *)&egtpCb, 0, sizeof(EgtpGlobalCb));
+  DU_LOG("\n\nDEBUG  -->  EGTP : Initializing");
+  memset (&egtpCb, 0, sizeof(EgtpGlobalCb));
+  
+  //Initializing with INVALID value
+  memset(egtpCb.gCntPdu, 0xFF , sizeof(uint8_t)*(MAX_TEID+1)); 
   protType = CM_INET_PROTO_UDP;
-  RETVALUE(ROK);
+  return ROK;
 }
 
 
@@ -72,37 +81,26 @@ S16 egtpActvInit()
  *         RFAILED - failure
  *
  ***************************************************************************/
-S16 egtpInitReq()
+uint8_t egtpInitReq()
 {
-   S16 ret = ROK;
-   EgtpTnlEvt tnlEvt;
-
+   uint8_t ret = ROK;
+   
+   egtpCb.egtpCfg = cuCb.cuCfgParams.egtpParams;
    ret = cuEgtpCfgReq();
    if(ret != ROK)
    {
-      DU_LOG("\nEGTP : Configuration failed");
-      RETVALUE(ret);
+      DU_LOG("\nERROR  -->  EGTP : Configuration failed");
+      return (ret);
    }
 
    ret = cuEgtpSrvOpenReq();
    if(ret != ROK)
    {
-       DU_LOG("\nEGTP : Transport server open request failed");
-       RETVALUE(ret);
+       DU_LOG("\nERROR  -->  EGTP : Transport server open request failed");
+       return (ret);
    }
 
-   tnlEvt.action = EGTP_TNL_MGMT_ADD;
-   tnlEvt.lclTeid = 10;
-   tnlEvt.remTeid = 1;
-   ret = cuEgtpTnlMgmtReq(tnlEvt);
-   if(ret != ROK)
-   {
-      DU_LOG("\n EGTP : Tunnel management request failed");
-      RETVALUE(RFAILED);
-   }
-
-   RETVALUE(ret);
-
+   return ret;
 } /* egtpInitReq */
 
 /**************************************************************************
@@ -121,32 +119,37 @@ S16 egtpInitReq()
  * ***********************************************************************/
 S16 cuEgtpCfgReq()
 {
-   U8 ret;
-
-   cmMemcpy((U8 *)&egtpCb.egtpCfg, (U8 *)&cuCfgParams.egtpParams, (PTR)sizeof(EgtpParams));
-
-   egtpCb.recvTptSrvr.addr.address = CM_INET_NTOH_U32(egtpCb.egtpCfg.localIp.ipV4Addr);
-   egtpCb.recvTptSrvr.addr.port = EGTP_DFLT_PORT;
+   uint8_t ret, destIdx =0;
+   
+   memcpy(&egtpCb.egtpCfg, &cuCb.cuCfgParams.egtpParams, sizeof(CuEgtpParams));
+   
+   for(destIdx=0; destIdx < egtpCb.egtpCfg.numDu; destIdx++)
+   {
+      egtpCb.recvTptSrvr.addr.address = CM_INET_NTOH_UINT32(egtpCb.egtpCfg.egtpAssoc[destIdx].localIp.ipV4Addr);
+      egtpCb.recvTptSrvr.addr.port = EGTP_RECVR_PORT;
 
-   egtpCb.dstCb.dstIp = CM_INET_NTOH_U32(egtpCb.egtpCfg.destIp.ipV4Addr);
-   egtpCb.dstCb.dstPort = egtpCb.egtpCfg.destPort;
-   egtpCb.dstCb.sendTptSrvr.addr.address = CM_INET_NTOH_U32(egtpCb.egtpCfg.localIp.ipV4Addr);
-   egtpCb.dstCb.sendTptSrvr.addr.port = egtpCb.egtpCfg.localPort;
-   egtpCb.dstCb.numTunn = 0;
+      egtpCb.dstCb[destIdx].duId = destIdx+1;
+      egtpCb.dstCb[destIdx].dstIp = CM_INET_NTOH_UINT32(egtpCb.egtpCfg.egtpAssoc[destIdx].destIp.ipV4Addr);
+      egtpCb.dstCb[destIdx].dstPort = egtpCb.egtpCfg.egtpAssoc[destIdx].destPort;
+      egtpCb.dstCb[destIdx].sendTptSrvr.addr.address = CM_INET_NTOH_UINT32(egtpCb.egtpCfg.egtpAssoc[destIdx].localIp.ipV4Addr);
+      egtpCb.dstCb[destIdx].sendTptSrvr.addr.port = egtpCb.egtpCfg.egtpAssoc[destIdx].localPort;
+      egtpCb.dstCb[destIdx].numTunn = 0;
 
-   ret = cmHashListInit(&(egtpCb.dstCb.teIdLst), 1024, sizeof(EgtpTeIdCb), FALSE, CM_HASH_KEYTYPE_U32MOD, CU_APP_MEM_REG, CU_POOL);
+      ret = cmHashListInit(&(egtpCb.dstCb[destIdx].teIdLst), 1024, sizeof(EgtpTeIdCb), FALSE, CM_HASH_KEYTYPE_UINT32_MOD, CU_APP_MEM_REG, CU_POOL);
 
-   if(ret != ROK)
-   {
-      DU_LOG("\nEGTP : TeId hash list initialization failed");
-      RETVALUE(RFAILED);
-   }
-   else
-   {
-      DU_LOG("\nEGTP : Configuration successful");
+      if(ret != ROK)
+      {
+         DU_LOG("\nERROR  -->  EGTP : TeId hash list initialization failed");
+         return RFAILED;
+      }
+      else
+      {
+         DU_LOG("\nINFO  -->  EGTP : Configuration successful");
+      }
    }
+   egtpCb.numDu = egtpCb.egtpCfg.numDu; 
 
-   RETVALUE(ROK);
+   return ROK;
 } /* cuEgtpCfgReq */
 
 /**************************************************************************
@@ -169,41 +172,45 @@ S16 cuEgtpCfgReq()
 S16 cuEgtpSrvOpenReq(Pst *pst)
 {
 
-   U8 ret;
+   uint8_t ret, destIdx;
+
+   DU_LOG("\nINFO  -->  EGTP : Received open server request");
 
-   DU_LOG("\nEGTP : Received open server request");
    sockType = CM_INET_DGRAM;
-   if(ret = (cmInetSocket(sockType, &(egtpCb.recvTptSrvr.sockFd), protType)) != ROK)
+   if((ret = (cmInetSocket(sockType, &(egtpCb.recvTptSrvr.sockFd), protType))) != ROK)
    {
-      DU_LOG("\nEGTP : Failed to open UDP socket");
-      RETVALUE(RFAILED);
+      DU_LOG("\nERROR  -->  EGTP : Failed to open UDP socket");
+      return RFAILED;
    }
 
    ret = cmInetBind(&(egtpCb.recvTptSrvr.sockFd), &(egtpCb.recvTptSrvr.addr));
    if(ret != ROK)
    {
-      DU_LOG("\nEGTP : Failed to bind socket");
-      RETVALUE(RFAILED);
+      DU_LOG("\nERROR  -->  EGTP : Failed to bind socket");
+      return RFAILED;
    }
+   
+   for(destIdx=0; destIdx < egtpCb.egtpCfg.numDu; destIdx++)
+   {
+      if(ret = (cmInetSocket(sockType, &(egtpCb.dstCb[destIdx].sendTptSrvr.sockFd), protType)) != ROK)
+      {  
+         DU_LOG("\nERROR  -->  EGTP : Failed to open UDP socket");
+         return RFAILED;
+      }
 
-   if(ret = (cmInetSocket(sockType, &(egtpCb.dstCb.sendTptSrvr.sockFd), protType)) != ROK)
-   {  
-      DU_LOG("\nEGTP : Failed to open UDP socket");
-      RETVALUE(RFAILED);
-   }
-      
-   ret = cmInetBind(&(egtpCb.dstCb.sendTptSrvr.sockFd), &(egtpCb.dstCb.sendTptSrvr.addr));
-   if(ret != ROK)
-   {  
-      DU_LOG("\nEGTP : Failed to bind socket");
-      RETVALUE(RFAILED);
-   }
-       
-   /* TODO: set socket options */
+      ret = cmInetBind(&(egtpCb.dstCb[destIdx].sendTptSrvr.sockFd), &(egtpCb.dstCb[destIdx].sendTptSrvr.addr));
+      if(ret != ROK)
+      {  
+         DU_LOG("\nERROR  -->  EGTP : Failed to bind socket");
+         return RFAILED;
+      }
+
+      /* TODO: set socket options */
 
-   DU_LOG("\nEGTP : Receiver socket[%d] and Sender socket[%d] open", egtpCb.recvTptSrvr.sockFd.fd, egtpCb.dstCb.sendTptSrvr.sockFd.fd);
-   RETVALUE(ROK);
+      DU_LOG("\nINFO  -->  EGTP : Receiver socket[%d] and Sender socket[%d] open", egtpCb.recvTptSrvr.sockFd.fd,\
+            egtpCb.dstCb[destIdx].sendTptSrvr.sockFd.fd);
+   }
+   return ROK;
 } /* cuEgtpSrvOpenReq */
 
 
@@ -224,36 +231,36 @@ S16 cuEgtpSrvOpenReq(Pst *pst)
  *
  
  * ***************************************************************************/
-S16 cuEgtpTnlMgmtReq(EgtpTnlEvt tnlEvt)
+S16 cuEgtpTnlMgmtReq(uint32_t duId, EgtpTnlEvt tnlEvt)
 {
    S8 ret;
 
-   DU_LOG("\nEGTP : Received tunnel management request");
+   DU_LOG("\nINFO  -->  EGTP : Received tunnel management request");
    switch(tnlEvt.action)
    {
       case EGTP_TNL_MGMT_ADD:
       {
-         ret = cuEgtpTnlAdd(tnlEvt);
+         ret = cuEgtpTnlAdd(duId, tnlEvt);
          break;
       }
       case EGTP_TNL_MGMT_MOD:
       {
-         ret = cuEgtpTnlMod(tnlEvt);
+         ret = cuEgtpTnlMod(duId, tnlEvt);
          break;
       }
       case EGTP_TNL_MGMT_DEL:
       {
-         ret = cuEgtpTnlDel(tnlEvt);
+         ret = cuEgtpTnlDel(duId, tnlEvt);
          break;
       }
       default:
       {
-         DU_LOG("\nEGTP : Invalid tunnel management action[%d]", tnlEvt.action);
+         DU_LOG("\nERROR  -->  EGTP : Invalid tunnel management action[%d]", tnlEvt.action);
          ret = RFAILED;
       }
    }
 
-   RETVALUE(ret);
+   return (ret);
 }
 
 /**************************************************************************
@@ -271,49 +278,51 @@ S16 cuEgtpTnlMgmtReq(EgtpTnlEvt tnlEvt)
  *         RFAILED - failure
  *
  * ***************************************************************************/
-S16 cuEgtpTnlAdd(EgtpTnlEvt tnlEvt)
+S16 cuEgtpTnlAdd(uint32_t duId, EgtpTnlEvt tnlEvt)
 {
    S16   ret;
    EgtpTeIdCb     *teidCb;
    EgtpMsgHdr   preDefHdr; /* pre-define header for this tunnel */
    
 
-   DU_LOG("\nEGTP : Tunnel addition : LocalTeid[%d] Remote Teid[%d]", tnlEvt.lclTeid, tnlEvt.remTeid);
+   DU_LOG("\nINFO  -->  EGTP : Tunnel addition : LocalTeid[%d] Remote Teid[%d]", tnlEvt.lclTeid, tnlEvt.remTeid);
 
-   ret = SGetSBuf(CU_APP_MEM_REG, CU_POOL, (Data **)&teidCb, (Size)sizeof(EgtpTeIdCb));
-   if(ret != ROK)
+   CU_ALLOC(teidCb, (Size)sizeof(EgtpTeIdCb));
+
+   if(teidCb == NULLP)
    {
-      DU_LOG("\nEGTP : Memory allocation failed");
-      RETVALUE(RFAILED);
+      DU_LOG("\nERROR  -->  EGTP : Memory allocation failed");
+      return RFAILED;
    }
 
-
-   cmMemset((U8 *)teidCb, 0, sizeof(EgtpTeIdCb));
+   memset(teidCb, 0, sizeof(EgtpTeIdCb));
    teidCb->teId = tnlEvt.lclTeid;
    teidCb->remTeId = tnlEvt.remTeid;
 
-   ret = cmHashListInsert(&(egtpCb.dstCb.teIdLst), (PTR)teidCb, (U8 *)&(teidCb->teId), sizeof(U32));
+   ret = cmHashListInsert(&(egtpCb.dstCb[duId-1].teIdLst), (PTR)teidCb, (uint8_t *)&(teidCb->teId), sizeof(uint32_t));
    if(ret != ROK)
    {
-      DU_LOG("\nEGTP : Failed to insert in hash list");
-      SPutSBuf(CU_APP_MEM_REG, CU_POOL, (Data *)teidCb, (Size)sizeof(EgtpTeIdCb));
-      RETVALUE(RFAILED);
+      DU_LOG("\nERROR  -->  EGTP : Failed to insert in hash list");
+      CU_FREE(teidCb, (Size)sizeof(EgtpTeIdCb));
+      return RFAILED;
    }
-   egtpCb.dstCb.numTunn++;
+   egtpCb.dstCb[duId-1].numTunn++;
 
    /* Encoding pre-defined header */
-   cmMemset((U8*)&preDefHdr, 0, sizeof(EgtpMsgHdr));
+   memset(&preDefHdr, 0, sizeof(EgtpMsgHdr));
    preDefHdr.msgType = EGTPU_MSG_GPDU;
    preDefHdr.teId = teidCb->remTeId;
    preDefHdr.extHdr.pdcpNmb.pres = FALSE;
    preDefHdr.extHdr.udpPort.pres = FALSE;
-   preDefHdr.nPdu.pres = FALSE;
-   
-   cuEgtpEncodeHdr((U8 *)teidCb->preEncodedHdr.hdr, &preDefHdr, &(teidCb->preEncodedHdr.cnt));
+   preDefHdr.nPdu.pres = TRUE; //Including nPdu when sending data
+   preDefHdr.nPdu.val = 0;
+
+   cuEgtpEncodeHdr((uint8_t *)teidCb->preEncodedHdr.hdr, &preDefHdr, &(teidCb->preEncodedHdr.cnt));
+   egtpCb.gCntPdu[teidCb->remTeId] = 0;//Resetting the Cnt Value for this DRB which indicates its creation
 
 /*   SPutSBuf(CU_APP_MEM_REG, CU_POOL, (Data *)teidCb, (Size)sizeof(EgtpTeIdCb));*/
 
-   RETVALUE(ROK);
+   return ROK;
 } /* cuEgtpTnlAdd */
 
 /**************************************************************************
@@ -331,25 +340,25 @@ S16 cuEgtpTnlAdd(EgtpTnlEvt tnlEvt)
  *         RFAILED - failure
  * 
  * ***************************************************************************/
-S16 cuEgtpTnlMod(EgtpTnlEvt tnlEvt)
+S16 cuEgtpTnlMod(uint32_t duId, EgtpTnlEvt tnlEvt)
 {
 #if 0
    S16   ret;
    EgtpTeIdCb     *teidCb = NULLP;
 
-   printf("\nTunnel modification : LocalTeid[%d] Remote Teid[%d]", tnlEvt.lclTeid, tnlEvt.remTeid);
+   DU_LOG("\nDEBUG  -->  CU_STUB : Tunnel modification : LocalTeid[%d] Remote Teid[%d]", tnlEvt.lclTeid, tnlEvt.remTeid);
 
-   cmHashListFind(&(egtpCb.dstCb.teIdLst), (U8 *)&(tnlEvt.teId), sizeof(U32), 0, (PTR *)&teidCb);
+   cmHashListFind(&(egtpCb.dstCb[duId-1].teIdLst), (uint8_t *)&(tnlEvt.teId), sizeof(uint32_t), 0, (PTR *)&teidCb);
    if(teidCb == NULLP)
    {
-      printf("\nTunnel id not found");
-      RETVALUE(RFAILED);
+      DU_LOG("\nDEBUG --> CU_STUBTunnel id not found");
+      return RFAILED;
    }  
    
    teidCb->teId = tnlEvt.lclTeid;
    teidCb->remTeId = tnlEvt.remTeid;
 #endif
-   RETVALUE(ROK);
+   return ROK;
 }
 
 /**************************************************************************
@@ -367,24 +376,24 @@ S16 cuEgtpTnlMod(EgtpTnlEvt tnlEvt)
  *         RFAILED - failure
  * 
  * ***************************************************************************/
-S16 cuEgtpTnlDel(EgtpTnlEvt tnlEvt)
+S16 cuEgtpTnlDel(uint32_t duId, EgtpTnlEvt tnlEvt)
 {
    EgtpTeIdCb     *teidCb = NULLP;
 
-   DU_LOG("\nEGTP : Tunnel deletion : Local Teid[%d] Remote Teid[%d]", tnlEvt.lclTeid, tnlEvt.remTeid);
+   DU_LOG("\nDEBUG  -->  EGTP : Tunnel deletion : Local Teid[%d] Remote Teid[%d]", tnlEvt.lclTeid, tnlEvt.remTeid);
    
-   cmHashListFind(&(egtpCb.dstCb.teIdLst), (U8 *)&(tnlEvt.lclTeid), sizeof(U32), 0, (PTR *)&teidCb);
+   cmHashListFind(&(egtpCb.dstCb[duId-1].teIdLst), (uint8_t *)&(tnlEvt.lclTeid), sizeof(uint32_t), 0, (PTR *)&teidCb);
    if(teidCb == NULLP)
    {
-      DU_LOG("\nEGTP : Tunnel id[%d] not configured", tnlEvt.lclTeid);
-      RETVALUE(RFAILED);
+      DU_LOG("\nERROR  -->  EGTP : Tunnel id[%d] not configured", tnlEvt.lclTeid);
+      return RFAILED;
    } 
 
-   cmHashListDelete(&(egtpCb.dstCb.teIdLst), (PTR)teidCb);
-   SPutSBuf(CU_APP_MEM_REG, CU_POOL, (Data *)teidCb, (Size)sizeof(EgtpTeIdCb));
-   egtpCb.dstCb.numTunn--;
+   cmHashListDelete(&(egtpCb.dstCb[duId-1].teIdLst), (PTR)teidCb);
+   CU_FREE(teidCb, (Size)sizeof(EgtpTeIdCb));
+   egtpCb.dstCb[duId-1].numTunn--;
 
-   RETVALUE(ROK);
+   return ROK;
 } /* cuEgtpTnlDel */
 
 /*******************************************************************
@@ -404,12 +413,12 @@ S16 cuEgtpTnlDel(EgtpTnlEvt tnlEvt)
  *         RFAILED - failure
  *
  * ****************************************************************/
-S16 cuEgtpEncodeHdr(U8 *preEncodedHdr, EgtpMsgHdr *preDefHdr, U8 *hdrIdx)
+S16 cuEgtpEncodeHdr(uint8_t *preEncodedHdr, EgtpMsgHdr *preDefHdr, uint8_t *hdrIdx)
 {
-   U8         tmpByte = 0;                 /* Stores one byte of data for enc */
-   U8         cnt     = EGTP_MAX_HDR_LEN;  /* Stores the position */
+   uint8_t         tmpByte = 0;                 /* Stores one byte of data for enc */
+   uint8_t         cnt     = EGTP_MAX_HDR_LEN;  /* Stores the position */
    Bool       extPres = FALSE;             /* Flag for indication of S, E or P presense flag */
-   U16        nwWord = 0;
+   uint16_t        nwWord = 0;
 
    /* Encoding header */
    tmpByte |= EGTP_MASK_BIT6;   /* Setting 6th LSB of 1st byte as version */
@@ -440,12 +449,12 @@ S16 cuEgtpEncodeHdr(U8 *preEncodedHdr, EgtpMsgHdr *preDefHdr, U8 *hdrIdx)
    /* Encode Tunnel endpoint */
    preEncodedHdr[--cnt] = 0;
    preEncodedHdr[--cnt] = 0;
-   nwWord = (U16)(GetHiWord(preDefHdr->teId));
-   preEncodedHdr[--cnt] = (U8)(GetHiByte(nwWord));
-   preEncodedHdr[--cnt] = (U8)(GetLoByte(nwWord));
-   nwWord = (U16)(GetLoWord(preDefHdr->teId));
-   preEncodedHdr[--cnt] = (U8)(GetHiByte(nwWord));
-   preEncodedHdr[--cnt] = (U8)(GetLoByte(nwWord));
+   nwWord = (uint16_t)(GetHiWord(preDefHdr->teId));
+   preEncodedHdr[--cnt] = (uint8_t)(GetHiByte(nwWord));
+   preEncodedHdr[--cnt] = (uint8_t)(GetLoByte(nwWord));
+   nwWord = (uint16_t)(GetLoWord(preDefHdr->teId));
+   preEncodedHdr[--cnt] = (uint8_t)(GetHiByte(nwWord));
+   preEncodedHdr[--cnt] = (uint8_t)(GetLoByte(nwWord));
     
    /* Encode sequence number */
    if(preDefHdr->seqNum.pres)
@@ -494,51 +503,83 @@ S16 cuEgtpEncodeHdr(U8 *preEncodedHdr, EgtpMsgHdr *preDefHdr, U8 *hdrIdx)
    } 
    
    *hdrIdx = cnt;
-   RETVALUE(ROK);
+   return ROK;
 
 } /* egtpEncodeHdr */
 
+/*******************************************************************
+ *
+ * @brief This handles the any EGTP received message 
+ *
+ * @details
+ *
+ *    Function : cuEgtpHdlRecvMsg 
+ * 
+ *    Functionality:
+ *       This handles the any EGTP received message
+ *
+ * @params[in]  Message Buffer 
+ * @return ROK     - success
+ *         RFAILED - failure
+ *
+ * ****************************************************************/
 S16 cuEgtpHdlRecvMsg(Buffer *mBuf)
 {
    /*Decoding of EGTP message header */
+   
    cuEgtpDecodeHdr(mBuf);
-
+   
    /* Start Pumping data from CU to DU */
-   RETVALUE(cuEgtpDatReq());
+   //return (cuEgtpDatReq());
 
 }
 
+/*******************************************************************
+ *
+ * @brief Decodes message header
+ *
+ * @details
+ *
+ *    Function : cuEgtpDecodeHdr 
+ * 
+ *    Functionality:
+ *       Decodes EGTP message haeder
+ *
+ * @params[in]  Message Buffer 
+ * @return ROK     - success
+ *         RFAILED - failure
+ *
+ * ****************************************************************/
 S16 cuEgtpDecodeHdr(Buffer *mBuf)
 {
    EgtpMsg  egtpMsg;
-   S16      retVal  = ROK;       /* Holds the return value */
-   U8       tmpByte[5];         /* Holds one byte of data after Dec */
-   U8       version = 0;         /* Holds the version type, decoded */
+   uint8_t       tmpByte[5];         /* Holds one byte of data after Dec */
+   uint8_t       version = 0;         /* Holds the version type, decoded */
    MsgLen   msgLen  = 0;         /* Holds the msgLen from the Hdr */
    MsgLen   bufLen  = 0;         /* Holds the total buffer length */
-   U8       extHdrType = 0;       /* Holds the Extension hdr type */
-   U8       extHdrLen = 0;        /* Extension hdr length */
+   uint8_t       extHdrType = 0;       /* Holds the Extension hdr type */
+   uint8_t       extHdrLen = 0;        /* Extension hdr length */
    Bool     extPres = FALSE;      /* Flag for indication of S, E or P presense flag */
 
-   SFndLenMsg(mBuf, &bufLen);
+   ODU_GET_MSG_LEN(mBuf, &bufLen);
 
    /* Decode version */
-   SRemPreMsg(&tmpByte[0], mBuf);
+   ODU_REM_PRE_MSG(&tmpByte[0], mBuf);
    version = tmpByte[0] >> 5;
 
    /* Decode message type */
-   SRemPreMsg((Data*)&(egtpMsg.msgHdr.msgType), mBuf);
+   ODU_REM_PRE_MSG((Data*)&(egtpMsg.msgHdr.msgType), mBuf);
 
    /* Decode message length */
-   SRemPreMsg(&tmpByte[1], mBuf);
-   SRemPreMsg(&tmpByte[2], mBuf);
+   ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
+   ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
    msgLen = (tmpByte[1] << 8) | tmpByte[2];
 
    /* Decode tunnel id */
-   SRemPreMsg(&tmpByte[1], mBuf);
-   SRemPreMsg(&tmpByte[2], mBuf);
-   SRemPreMsg(&tmpByte[3], mBuf);
-   SRemPreMsg(&tmpByte[4], mBuf);
+   ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
+   ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
+   ODU_REM_PRE_MSG(&tmpByte[3], mBuf);
+   ODU_REM_PRE_MSG(&tmpByte[4], mBuf);
    egtpMsg.msgHdr.teId = (tmpByte[1] << 24) | (tmpByte[2] << 16) | (tmpByte[3] << 8) | tmpByte[4];
 
    if((tmpByte[0] & EGTP_MASK_BIT1) || (tmpByte[0] & EGTP_MASK_BIT2)||(tmpByte[0] & EGTP_MASK_BIT3))
@@ -550,15 +591,15 @@ S16 cuEgtpDecodeHdr(Buffer *mBuf)
    if ( tmpByte[0] & EGTP_MASK_BIT2 )
    {
       egtpMsg.msgHdr.seqNum.pres = TRUE;
-      SRemPreMsg(&tmpByte[1], mBuf);
-      SRemPreMsg(&tmpByte[2], mBuf);
+      ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
+      ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
       egtpMsg.msgHdr.seqNum.val = (tmpByte[1] << 8) | tmpByte[2];
    }
    else  if(extPres)
    {
       egtpMsg.msgHdr.seqNum.pres = 0;
-      SRemPreMsg(&tmpByte[1], mBuf);
-      SRemPreMsg(&tmpByte[2], mBuf);
+      ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
+      ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
       egtpMsg.msgHdr.seqNum.val = (tmpByte[1] << 8) | tmpByte[2];
    }
 
@@ -566,29 +607,29 @@ S16 cuEgtpDecodeHdr(Buffer *mBuf)
    if ( tmpByte[0] & EGTP_MASK_BIT1 )
    {
       egtpMsg.msgHdr.nPdu.pres = TRUE;
-      SRemPreMsg(&(egtpMsg.msgHdr.nPdu.val), mBuf);
+      ODU_REM_PRE_MSG(&(egtpMsg.msgHdr.nPdu.val), mBuf);
    }
    else if(extPres)
    {
       egtpMsg.msgHdr.nPdu.pres = TRUE;
-      SRemPreMsg(&(egtpMsg.msgHdr.nPdu.val), mBuf);
+      ODU_REM_PRE_MSG(&(egtpMsg.msgHdr.nPdu.val), mBuf);
    }
 
    if(extPres & EGTP_MASK_BIT1)
    {
-      SRemPreMsg(&extHdrType, mBuf);
+      ODU_REM_PRE_MSG(&extHdrType, mBuf);
       while( 0 != extHdrType)
       {
          switch (extHdrType)
          {
             case EGTP_EXT_HDR_UDP_TYPE:
             {
-               SRemPreMsg(&extHdrLen, mBuf);
+               ODU_REM_PRE_MSG(&extHdrLen, mBuf);
                if(extHdrLen == 0x01)
                {
                   egtpMsg.msgHdr.extHdr.udpPort.pres = TRUE;
-                  SRemPreMsg(&tmpByte[1], mBuf);
-                  SRemPreMsg(&tmpByte[2], mBuf);
+                  ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
+                  ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
                   egtpMsg.msgHdr.extHdr.udpPort.val = (tmpByte[1] << 8) | tmpByte[2];
                }
                break;
@@ -596,79 +637,139 @@ S16 cuEgtpDecodeHdr(Buffer *mBuf)
 
             case EGTP_EXT_HDR_PDCP_TYPE:
             {
-               SRemPreMsg(&extHdrLen, mBuf);
+               ODU_REM_PRE_MSG(&extHdrLen, mBuf);
                if(extHdrLen == 0x01)
                {
                   egtpMsg.msgHdr.extHdr.pdcpNmb.pres = TRUE;
-                  SRemPreMsg(&tmpByte[1], mBuf);
-                  SRemPreMsg(&tmpByte[2], mBuf);
+                  ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
+                  ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
                   egtpMsg.msgHdr.extHdr.pdcpNmb.val = (tmpByte[1] << 8) | tmpByte[2];
                }
                break;
             }
          } /* End of switch */
 
-         SRemPreMsg(&extHdrType, mBuf);
+         ODU_REM_PRE_MSG(&extHdrType, mBuf);
 
       } /* End of while */
    } /* End of if(extPres & EGTP_MASK_BIT1) */
    else if(extPres)
    {
-      SRemPreMsg(&extHdrType, mBuf);
+      ODU_REM_PRE_MSG(&extHdrType, mBuf);
    }
 
-   DU_LOG("\nEGTP : Message Buffer after decoding header ");
-   SPrntMsg(mBuf, 0, 0);
+   DU_LOG("\nDEBUG  -->  EGTP : Message Buffer after decoding header [TEID:%d]",egtpMsg.msgHdr.teId);
+   ODU_PRINT_MSG(mBuf, 0, 0);
 
-   RETVALUE(ROK);
+   SPutMsg(mBuf);
+
+   return ROK;
      
 } /* End of cuEgtpDecodeHdr */
 
-S16 cuEgtpDatReq()
+/*******************************************************************
+ *
+ * @brief This function is responsible to build application message, encode EGTP
+ * header to it and send to DU over tunnel (teId)
+ *
+ * @details
+ *
+ *    Function : cuEgtpDatReq
+ * 
+ *    Functionality:
+ *       function is responsible to build application message, encode EGTP
+ *       header to it and send to DU over tunnel (teId) 
+ *
+ * @params[in]  uint8_t teId
+ *
+ * @return ROK     - success
+ *         RFAILED - failure
+ *
+ * ****************************************************************/
+uint16_t cuEgtpDatReq(uint8_t teId)
 {
-   U8 cnt = 0;
+   uint8_t ret = ROK, cnt = 0, duId =0;
    EgtpMsg  egtpMsg;
 
-   /* Build Application message that is supposed to come from app to egtp */
-   BuildAppMsg(&egtpMsg);
-
-   /* Encode EGTP header to build final EGTP message */
-   BuildEgtpMsg(&egtpMsg);
-
-   /* Send Message to peer */
-   while(cnt < 20)
+   egtpMsg.msgHdr.teId = teId;
+   
+   if(egtpCb.gCntPdu[teId] == 0xFF) //DRB not created
    {
-      DU_LOG("\nEGTP : Sending message[%d]", cnt+1);
-      cuEgtpSendMsg(egtpMsg.msg);
-      cnt++;
+      DU_LOG("\nERROR  -->  EGTP : DRB  not created");
+      return RFAILED ;
    }
+   for(duId = 1; duId<=egtpCb.numDu; duId++)
+   {
+      /* Build Application message that is supposed to come from app to egtp */
+      ret = BuildAppMsg(duId, &egtpMsg);
+      if(ret != ROK)
+      {
+         DU_LOG("\nERROR  -->  EGTP : Failed to build App Msg");
+         return RFAILED;
+      }
 
-   SPutMsg(egtpMsg.msg);
-
-   RETVALUE(ROK);
+      /* Encode EGTP header to build final EGTP message */
+      ret = BuildEgtpMsg(duId, &egtpMsg);
+      if(ret != ROK)
+      {
+         DU_LOG("\nERROR  -->  EGTP : Failed to build EGTP Msg");
+         return RFAILED;
+      }
+      cuEgtpSendMsg(duId, egtpMsg.msg);
+      ODU_PUT_MSG_BUF(egtpMsg.msg);
+   }
+   return ROK;
 }
 
 
-S16 BuildAppMsg(EgtpMsg  *egtpMsg)
+/*******************************************************************
+ *
+ * @brief Builds application message to be sent to DU in DL path
+ *
+ * @details
+ *
+ *    Function : BuildAppMsg
+ * 
+ *    Functionality:
+ *      Builds application message to be sent to DU in DL path
+ *
+ * @params[in] uint32_t duId,EGTP message
+ *             
+ * @return ROK     - success
+ *         RFAILED - failure
+ *
+ * ****************************************************************/
+S16 BuildAppMsg(uint32_t duId, EgtpMsg  *egtpMsg)
 {
-   char data[30] = "This is EGTP data from CU";
-   int datSize = 30;
+   char data[1215] = "In telecommunications, 5G is the fifth generation technology standard for broadband cellular"
+   " networks, which cellular phone companies began deploying worldwide in 2019, and is the planned successor to the 4G "
+   " networks which provide connectivity to most current cellphones. 5G networks are predicted to have more than 1.7"
+   " billion subscribers worldwide by 2025, according to the GSM Association.Like its predecessors, 5G networks are"
+   " cellular networks,in which the service area is divided into small geographical areas called cells.All 5G wireless"
+   " devices in a cell are connected to the Internet and telephone network by radio waves through local antenna in the"
+   " cell. The main advantage of the new networks is that they will have greater bandwidth, giving higher download"
+   " speeds, eventually up to 10 gigabits per second(Gbit/s). Due to the increased bandwidth, it is expected the"
+   " networks will not exclusively serve cellphones like existing cellular networks, but also be used as general"
+   " internet service providers for laptops and desktop computers, competing with existing ISPs such as cable"
+   " internet, and also will make possible new applications in internet of things (IoT) and machine to machine areas.";
+
+   int datSize = 1215;
  
    Buffer   *mBuf;
  
-   if(SGetMsg(CU_APP_MEM_REG, CU_POOL, &mBuf) == ROK)
+   if(ODU_GET_MSG_BUF(CU_APP_MEM_REG, CU_POOL, &mBuf) == ROK)
    {
-      if(SAddPstMsgMult((Data *)data, datSize, mBuf) != ROK)
+      if(ODU_ADD_POST_MSG_MULT((Data *)data, datSize, mBuf) != ROK)
       {
-         DU_LOG("\nEGTP : SAddPstMsgMult failed");
-         SPutMsg(mBuf);
-         RETVALUE(RFAILED);
+         DU_LOG("\nERROR  -->  EGTP : ODU_ADD_POST_MSG_MULT failed");
+         ODU_PUT_MSG_BUF(mBuf);
+         return RFAILED;
       }
    }
    else
    {
-       DU_LOG("\nEGTP : Failed to allocate memory");
-       RETVALUE(RFAILED);
+       DU_LOG("\nERROR  -->  EGTP : Failed to allocate memory");
+       return RFAILED;
    }
  
    /* filling IPv4 header */
@@ -676,14 +777,14 @@ S16 BuildAppMsg(EgtpMsg  *egtpMsg)
    MsgLen    mLen;
  
    mLen = 0;
-   SFndLenMsg(mBuf, &mLen);
+   ODU_GET_MSG_LEN(mBuf, &mLen);
 
-   cmMemset((U8 *)&ipv4Hdr, 0, sizeof(CmIpv4Hdr));
+   memset(&ipv4Hdr, 0, sizeof(CmIpv4Hdr));
    ipv4Hdr.length = CM_IPV4_HDRLEN + mLen;
    ipv4Hdr.hdrVer = 0x45;
    ipv4Hdr.proto = 1;
-   ipv4Hdr.srcAddr = CM_INET_NTOH_U32(egtpCb.egtpCfg.localIp.ipV4Addr);
-   ipv4Hdr.destAddr = CM_INET_NTOH_U32(egtpCb.egtpCfg.destIp.ipV4Addr);
+   ipv4Hdr.srcAddr = CM_INET_NTOH_UINT32(egtpCb.egtpCfg.egtpAssoc[duId-1].localIp.ipV4Addr);
+   ipv4Hdr.destAddr = CM_INET_NTOH_UINT32(egtpCb.egtpCfg.egtpAssoc[duId-1].destIp.ipV4Addr);
  
    /* Packing IPv4 header into buffer */
    S16          ret, cnt, idx;
@@ -692,8 +793,8 @@ S16 BuildAppMsg(EgtpMsg  *egtpMsg)
  
    /* initialize locals */
    cnt = 0;
-   cmMemset(revPkArray, 0, CM_IPV4_HDRLEN);
-   cmMemset(pkArray, 0, CM_IPV4_HDRLEN);
+   memset(revPkArray, 0, CM_IPV4_HDRLEN);
+   memset(pkArray, 0, CM_IPV4_HDRLEN);
 
    /* Pack Header Version */
    pkArray[cnt++] = ipv4Hdr.hdrVer;
@@ -738,33 +839,55 @@ S16 BuildAppMsg(EgtpMsg  *egtpMsg)
       revPkArray[idx] = pkArray[CM_IPV4_HDRLEN - idx -1];
  
    /* this function automatically reverses revPkArray */
-   ret = SAddPreMsgMult(revPkArray, (MsgLen)cnt, mBuf);
+   ret = ODU_ADD_PRE_MSG_MULT(revPkArray, (MsgLen)cnt, mBuf);
  
    egtpMsg->msgHdr.msgType = EGTPU_MSG_GPDU;
-   egtpMsg->msgHdr.nPdu.pres = FALSE;
+   egtpMsg->msgHdr.nPdu.pres = TRUE;
+
+   if(egtpCb.gCntPdu[egtpMsg->msgHdr.teId] != NUM_DL_PACKETS)
+     egtpCb.gCntPdu[egtpMsg->msgHdr.teId]++;
+   else
+     egtpCb.gCntPdu[egtpMsg->msgHdr.teId] = 1;
+
+   egtpMsg->msgHdr.nPdu.val = egtpCb.gCntPdu[egtpMsg->msgHdr.teId];
    egtpMsg->msgHdr.seqNum.pres = FALSE;
    egtpMsg->msgHdr.extHdr.udpPort.pres = FALSE;
    egtpMsg->msgHdr.extHdr.pdcpNmb.pres = FALSE;
-   egtpMsg->msgHdr.teId = 10;
    egtpMsg->msg = mBuf;
 
-   RETVALUE(ROK);
+   return ret;
 }
 
-
-S16 BuildEgtpMsg(EgtpMsg *egtpMsg)
+/*******************************************************************
+ *
+ * @brief Encodes EGTP header to application message to send to DU
+ *
+ * @details
+ *
+ *    Function : BuildEgtpMsg
+ * 
+ *    Functionality:
+ *        Encodes EGTP header to application message to send to DU
+ *
+ * @params[in] uint32_t duId,EGTP message
+ *             
+ * @return ROK     - success
+ *         RFAILED - failure
+ *
+ * ****************************************************************/
+S16 BuildEgtpMsg(uint32_t duId, EgtpMsg *egtpMsg)
 {
    EgtpTeIdCb   *teidCb = NULLP;
    MsgLen tPduSize;
-   U8     hdrLen;
-   U32    msgLen;
+   uint8_t     hdrLen;
+   uint32_t    msgLen;
    EgtpMsgHdr   *msgHdr;
  
-   cmHashListFind(&(egtpCb.dstCb.teIdLst), (U8 *)&(egtpMsg->msgHdr.teId), sizeof(U32), 0, (PTR *)&teidCb);
+   cmHashListFind(&(egtpCb.dstCb[duId-1].teIdLst), (uint8_t *)&(egtpMsg->msgHdr.teId), sizeof(uint32_t), 0, (PTR *)&teidCb);
    if(teidCb == NULLP)
    {
-      DU_LOG("\nEGTP : Tunnel id[%d] not configured", egtpMsg->msgHdr.teId);
-      RETVALUE(LCM_REASON_INVALID_PAR_VAL);
+      DU_LOG("\nERROR  -->  EGTP : Tunnel id[%d] not configured", egtpMsg->msgHdr.teId);
+      return (LCM_REASON_INVALID_PAR_VAL);
    }
 
    msgHdr = &(egtpMsg->msgHdr);
@@ -785,7 +908,7 @@ S16 BuildEgtpMsg(EgtpMsg *egtpMsg)
       teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] &= ~(EGTP_MASK_BIT3);
    }
  
-   SFndLenMsg(egtpMsg->msg, &tPduSize);
+   ODU_GET_MSG_LEN(egtpMsg->msg, &tPduSize);
 
    /*Adjust the header to fill the correct length*/
    msgLen = tPduSize +  (EGTP_MAX_HDR_LEN - hdrLen) - 0x08;
@@ -793,30 +916,54 @@ S16 BuildEgtpMsg(EgtpMsg *egtpMsg)
    /***********************************************
     * Fill the length field of the message header *
     ***********************************************/
-   teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 3] = (U8)GetHiByte(msgLen);
-   teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 4] = (U8)GetLoByte(msgLen);
+   teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 3] = (uint8_t)GetHiByte(msgLen);
+   teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 4] = (uint8_t)GetLoByte(msgLen);
 
    /*Update the sequence number*/
    if(egtpMsg->msgHdr.seqNum.pres)
    {
       teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] |= (EGTP_MASK_BIT2);
-      teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 9] = (U8)GetHiByte(egtpMsg->msgHdr.seqNum.val);
-      teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 10] = (U8)GetLoByte(egtpMsg->msgHdr.seqNum.val);
+      teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 9] = (uint8_t)GetHiByte(egtpMsg->msgHdr.seqNum.val);
+      teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 10] = (uint8_t)GetLoByte(egtpMsg->msgHdr.seqNum.val);
    }
    else
    {
       teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] &= ~(EGTP_MASK_BIT2);
    }
 
-   SAddPreMsgMult(&teidCb->preEncodedHdr.hdr[hdrLen], (EGTP_MAX_HDR_LEN - hdrLen), egtpMsg->msg);
-
-   DU_LOG("\nEGTP : Sending message buffer");
-   SPrntMsg(egtpMsg->msg, 0, 0);
+   /*Update the nPdU number*/
+   if(egtpMsg->msgHdr.nPdu.pres)
+   {
+      teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] |= (EGTP_MASK_BIT1);
+      teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 11] = egtpMsg->msgHdr.nPdu.val;
+   }
+   else
+   {
+      teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] &= ~(EGTP_MASK_BIT1);
+   }
 
-   RETVALUE(ROK);
+   ODU_ADD_PRE_MSG_MULT(&teidCb->preEncodedHdr.hdr[hdrLen], (EGTP_MAX_HDR_LEN - hdrLen), egtpMsg->msg);
+   return ROK;
 }
 
-S16 cuEgtpSendMsg(Buffer *mBuf)
+/*******************************************************************
+ *
+ * @brief Send the egtp message to the destination DU
+ *
+ * @details
+ *
+ *    Function : cuEgtpSendMsg 
+ * 
+ *    Functionality:
+ *       Send the egtp message to the destination DU
+ *
+ * @params[in] uint32_t duId 
+ *             Message Buffer 
+ * @return ROK     - success
+ *         RFAILED - failure
+ *
+ * ****************************************************************/
+S16 cuEgtpSendMsg(uint32_t duId, Buffer *mBuf)
 {
    S16            ret;
    MsgLen         txLen;
@@ -826,17 +973,17 @@ S16 cuEgtpSendMsg(Buffer *mBuf)
    info.region = CU_APP_MEM_REG;
    info.pool = CU_POOL;
  
-   dstAddr.port = EGTP_DFLT_PORT;
-   dstAddr.address = egtpCb.dstCb.dstIp;
+   dstAddr.port =  EGTP_RECVR_PORT;
+   dstAddr.address = egtpCb.dstCb[duId-1].dstIp;
  
-   ret = cmInetSendMsg(&(egtpCb.dstCb.sendTptSrvr.sockFd), &dstAddr, &info, mBuf, &txLen, CM_INET_NO_FLAG);
+   ret = cmInetSendMsg(&(egtpCb.dstCb[duId-1].sendTptSrvr.sockFd), &dstAddr, &info, mBuf, &txLen, CM_INET_NO_FLAG);
    if(ret != ROK && ret != RWOULDBLOCK)
    {
-      DU_LOG("\nEGTP : Message send failure");
-      RETVALUE(RFAILED);
+      DU_LOG("\nERROR  -->  EGTP : Message send failure");
+      return RFAILED;
    }
    
-   DU_LOG("\nEGTP : Message Sent");
+   DU_LOG("\nDEBUG  -->  EGTP : Message Sent");
  
-   RETVALUE(ROK);
+   return ROK;
 }