JIRA-ID:[ODUHIGH-295]- Tunnel creation in EGTP 88/5588/8
authorsphoorthi <sphoorthi.dayanand@radisys.com>
Wed, 3 Feb 2021 17:44:29 +0000 (23:14 +0530)
committersphoorthi <sphoorthi.dayanand@radisys.com>
Mon, 22 Feb 2021 12:00:27 +0000 (17:30 +0530)
Change-Id: Id3e3d2334fbc1280bfc5d0c993f59c06abf2ca1d
Signed-off-by: sphoorthi <sphoorthi.dayanand@radisys.com>
16 files changed:
src/5gnrmac/mac_ue_mgr.c
src/5gnrrlc/kw_uim.c
src/cm/common_def.c
src/cm/common_def.h
src/cm/du_app_mac_inf.h
src/cm/mac_sch_interface.h
src/codec_utils/common/odu_common_codec.c
src/codec_utils/common/odu_common_codec.h
src/cu_stub/cu_f1ap_msg_hdl.c
src/cu_stub/cu_stub_egtp.c
src/du_app/du_egtp.c
src/du_app/du_f1ap_msg_hdl.c
src/du_app/du_mgr.h
src/du_app/du_msg_hdl.c
src/du_app/du_ue_mgr.c
src/du_app/du_utils.h

index 9f32e9c..1bee3b5 100644 (file)
@@ -1638,7 +1638,6 @@ uint8_t fillSchUeCfg(Pst *pst, SchUeCfg *schUeCfg, MacUeCfg *ueCfg)
         return RFAILED;
       }
       schUeCfg->ambrCfg->ulBr = ueCfg->ambrCfg->ulBr;
-      schUeCfg->ambrCfg->dlBr = ueCfg->ambrCfg->dlBr;
    }
    else
       schUeCfg->ambrCfg = NULLP;
index c9e9e82..222e58b 100755 (executable)
@@ -715,7 +715,7 @@ uint8_t rlcProcDlData(Pst *pst, KwuDatReqInfo *datReq, Buffer *mBuf)
    RlcDlRbCb     *rbCb;       /* RB Control Block */
    RlcCb         *tRlcCb;
 
-   DU_LOG("\nDEBUG  -->  RLC_UL : Received DL Data");
+   DU_LOG("\nDEBUG  -->  RLC_DL : Received DL Data");
 
 #if (ERRCLASS & ERRCLS_INT_PAR)
    if(pst->dstInst >= MAX_RLC_INSTANCES)
@@ -731,7 +731,7 @@ uint8_t rlcProcDlData(Pst *pst, KwuDatReqInfo *datReq, Buffer *mBuf)
    rlcDbmFetchDlRbCbByRbId(tRlcCb, &datReq->rlcId, &rbCb);
    if(!rbCb)
    {
-      DU_LOG("\nERROR  -->  RLC_UL : CellId[%u]:DL RbId [%d] not found",
+      DU_LOG("\nERROR  -->  RLC_DL : CellId[%u]:DL RbId [%d] not found",
             datReq->rlcId.cellId,datReq->rlcId.rbId);
       ODU_PUT_MSG_BUF(mBuf);
 
@@ -769,7 +769,7 @@ uint8_t rlcProcDlData(Pst *pst, KwuDatReqInfo *datReq, Buffer *mBuf)
       }
       default:
       {
-         DU_LOG("\nERROR  -->  RLC_UL : Invalid RB Mode");
+         DU_LOG("\nERROR  -->  RLC_DL : Invalid RB Mode");
          break;
       }
    }
index 0e681d3..9d99246 100644 (file)
@@ -92,8 +92,7 @@ void freqDomRscAllocType0(uint16_t startPrb, uint16_t prbSize, uint8_t *freqDoma
  * ****************************************************************/
 void oduCpyFixBufToMsg(uint8_t *fixBuf, Buffer *mBuf, uint16_t len)                            
 {
-   uint8_t idx, revIdx, temp;
-   uint16_t copyLen;
+   uint16_t idx = 0, revIdx = 0, temp = 0, copyLen = 0;
 
    /* ODU_COPY_FIX_BUF_TO_MSG copies fixed buffer in reverse order. \
     * Hence reversing the fixed buffer before copying in order to \
index 56a9bae..07067a9 100644 (file)
@@ -58,6 +58,7 @@
 #define MAX_NUM_CELL 1
 #define MAX_NUM_UE   1
 #define MAX_NUM_LC   11
+#define MAX_NUM_TUNNEL  2 /* Max. no of Tunnels */
 
 /* 5G ORAN phy delay */
 #define PHY_DELTA 2
index efb935d..f91af25 100644 (file)
@@ -1090,7 +1090,6 @@ typedef struct spCellCfg
 typedef struct ambrCfg
 {
    uint32_t ulBr;   /* UL Bit rate */
-   uint32_t dlBr;   /* DL Bit rate */
 }AmbrCfg;
 
 /* Single Network Slice Selection assistance Info */
index e585379..0808f0f 100644 (file)
@@ -1414,7 +1414,6 @@ typedef struct schLcCfg
 typedef struct schAmbrCfg
 {
    uint32_t   ulBr;   /* Ul BitRate */
-   uint32_t   dlBr;   /* Dl BitRate */
 }SchAmbrCfg;
 
 typedef struct schModulationInfo
index 5ea3c8d..9439554 100644 (file)
@@ -108,7 +108,65 @@ uint8_t bitStringToInt(BIT_STRING_t *bitString, void *value)
    return ROK;
 }
 
+/*******************************************************************
+ *
+ * @brief Function to decode teId value from the octect String
+ *
+ * @details
+ *
+ *    Function : teIdStringToInt
+ *
+ *    Functionality: Function to decode teId value from the octect string
+ *                   It can used as generic function to convert 
+ *                   octect string to uint32_t value 
+ *
+ * @params[in]  buf, value
+ * @return void
+ *
+ * ****************************************************************/
+void teIdStringToInt(uint8_t *buf, uint32_t *val)
+{
+   uint32_t temp1 = 0, temp2 = 0, temp3 = 0;
+
+   temp1 |= buf[0];
+   temp1 <<= 24;
+
+   temp2 |= buf[1];
+   temp2 <<= 16;
 
+   temp3 |= buf[2];
+   temp3 <<= 8;
+   
+   *val = temp1|temp2|temp3|buf[3];
+}
+
+/*******************************************************************
+ *
+ * @brief Function to encode teId value to the octect String
+ *
+ * @details
+ *
+ *    Function : fillTeIdString
+ *
+ *    Functionality: Function to encode teId value to the octect String
+ *                   It can used as generic function to encode 
+ *                   uint32_t value to octect string
+ *
+ * @params[in]  bufSize, value, buf
+ * @return void
+ *
+ * ****************************************************************/
+
+void fillTeIdString(uint8_t bufSize, uint32_t val, uint8_t *buf)
+{
+   uint8_t bitPos;
+
+   for(bitPos = 0; bitPos < TEID_BIT_SIZE; bitPos += 8, bufSize--)
+   {
+      /*extracting bitBits from the bitPos*/
+      buf[bufSize] = (((1 << 8) - 1) & (val >> (bitPos))); 
+   }
+}
 
 /**********************************************************************
   End of file
index 01e0d7a..c670f09 100644 (file)
@@ -21,6 +21,7 @@
 
 #define ENC_BUF_MAX_LEN 400
 #define ENCODE_FAIL -1
+#define TEID_BIT_SIZE 24
 
 char encBuf[ENC_BUF_MAX_LEN];
 int  encBufSize;
@@ -28,6 +29,8 @@ int  encBufSize;
 int PrepFinalEncBuf(const void *buffer, size_t size, void *encodedBuf);
 uint8_t fillBitString(BIT_STRING_t *id, uint8_t unusedBits, uint8_t byteSize, uint8_t val);
 uint8_t bitStringToInt(BIT_STRING_t *bitString, void *val);
+void fillTeIdString(uint8_t bufSize, uint32_t val, uint8_t *buf);
+void teIdStringToInt(uint8_t *buf, uint32_t *val);
 
 #endif
 
index bba7b90..8989735 100644 (file)
 #define DMRS_ADDITIONAL_POS  0          /* DMRS Additional poistion */
 #define RES_ALLOC_TYPE       1          /* Resource allocation type */
 
+#define FIVE_QI_VALUE 9  /*spec 23.501, Table 5.7.4-1*/
+
 /*******************************************************************
 *
 * @brief Sends F1 msg over SCTP
@@ -2027,7 +2029,7 @@ uint8_t BuildQOSInfo(QoSFlowLevelQoSParameters_t *drbQos)
       return RFAILED;
    }
    /*FiveQI*/
-   drbQos->qoS_Characteristics.choice.non_Dynamic_5QI->fiveQI = 0;
+   drbQos->qoS_Characteristics.choice.non_Dynamic_5QI->fiveQI = FIVE_QI_VALUE;
    /*AveragingWindow*/
    CU_ALLOC(drbQos->qoS_Characteristics.choice.non_Dynamic_5QI->averagingWindow,\
         sizeof(AveragingWindow_t));
@@ -2048,11 +2050,10 @@ uint8_t BuildQOSInfo(QoSFlowLevelQoSParameters_t *drbQos)
    *(drbQos->qoS_Characteristics.choice.non_Dynamic_5QI->maxDataBurstVolume) = 0;
 
    /*nRGRAN Allocation Retention Priority*/
-   drbQos->nGRANallocationRetentionPriority.priorityLevel = PriorityLevel_highest;
+   drbQos->nGRANallocationRetentionPriority.priorityLevel = PriorityLevel_lowest;
    drbQos->nGRANallocationRetentionPriority.pre_emptionCapability = Pre_emptionCapability_may_trigger_pre_emption;
    drbQos->nGRANallocationRetentionPriority.pre_emptionVulnerability = Pre_emptionVulnerability_not_pre_emptable;
 
-   /* TO DO: GBR_QoSFlowInformation */
    return ROK;
 }/*End of BuildQOSInfo*/
 
@@ -2204,14 +2205,15 @@ uint8_t BuildULTnlInfo(ULUPTNLInformation_ToBeSetup_List_t *ulInfo)
    {
       return RFAILED;
    }
+   /* NOTE: Below IP address must be changed if running on different IP configuration */
    ulInfo->list.array[idx]->uLUPTNLInformation.choice.gTPTunnel->\
-      transportLayerAddress.buf[0] = 4;
+      transportLayerAddress.buf[0] = 192;
    ulInfo->list.array[idx]->uLUPTNLInformation.choice.gTPTunnel->\
-      transportLayerAddress.buf[1] = 4;
+      transportLayerAddress.buf[1] = 168;
    ulInfo->list.array[idx]->uLUPTNLInformation.choice.gTPTunnel->\
-      transportLayerAddress.buf[2] = 4;
+      transportLayerAddress.buf[2] = 130;
    ulInfo->list.array[idx]->uLUPTNLInformation.choice.gTPTunnel->\
-      transportLayerAddress.buf[3] = 5;
+      transportLayerAddress.buf[3] = 82;
    ulInfo->list.array[idx]->uLUPTNLInformation.choice.gTPTunnel->\
       transportLayerAddress.bits_unused = 0;
    /*GTP TEID*/
@@ -2226,13 +2228,13 @@ uint8_t BuildULTnlInfo(ULUPTNLInformation_ToBeSetup_List_t *ulInfo)
       return RFAILED;
    }
    ulInfo->list.array[idx]->uLUPTNLInformation.choice.gTPTunnel->\
-      gTP_TEID.buf[0] = 11;
+     gTP_TEID.buf[0] = 0;
    ulInfo->list.array[idx]->uLUPTNLInformation.choice.gTPTunnel->\
       gTP_TEID.buf[1] = 0;
    ulInfo->list.array[idx]->uLUPTNLInformation.choice.gTPTunnel->\
       gTP_TEID.buf[2] = 0;
    ulInfo->list.array[idx]->uLUPTNLInformation.choice.gTPTunnel->\
-      gTP_TEID.buf[3] = 2;
+      gTP_TEID.buf[3] = 1;
 
    return ROK;
 }/*End of BuildULTnlInfo*/
@@ -6830,13 +6832,13 @@ uint8_t BuildUlTnlInfoforDrb2(ULUPTNLInformation_ToBeSetup_List_t *ulInfo)
       return RFAILED;
    }
    ulInfo->list.array[arrIdx]->uLUPTNLInformation.choice.gTPTunnel->\
-      gTP_TEID.buf[0] = 11;
+      gTP_TEID.buf[0] = 0;
    ulInfo->list.array[arrIdx]->uLUPTNLInformation.choice.gTPTunnel->\
       gTP_TEID.buf[1] = 0;
    ulInfo->list.array[arrIdx]->uLUPTNLInformation.choice.gTPTunnel->\
       gTP_TEID.buf[2] = 0;
    ulInfo->list.array[arrIdx]->uLUPTNLInformation.choice.gTPTunnel->\
-      gTP_TEID.buf[3] = 1;
+      gTP_TEID.buf[3] = 2;
 
    return ROK;
 }/*End of BuildULTnlInfo*/
index 9893e83..f2b6da6 100644 (file)
@@ -93,7 +93,7 @@ uint8_t egtpInitReq()
    }
 
    tnlEvt.action = EGTP_TNL_MGMT_ADD;
-   tnlEvt.lclTeid = 10;
+   tnlEvt.lclTeid = 1;
    tnlEvt.remTeid = 1;
    ret = cuEgtpTnlMgmtReq(tnlEvt);
    if(ret != ROK)
@@ -627,21 +627,31 @@ S16 cuEgtpDecodeHdr(Buffer *mBuf)
 
 S16 cuEgtpDatReq()
 {
-   uint16_t cnt = 0;
+   uint8_t ret = ROK, cnt = 0;
    EgtpMsg  egtpMsg;
 
    /* Build Application message that is supposed to come from app to egtp */
-   BuildAppMsg(&egtpMsg);
+   ret = BuildAppMsg(&egtpMsg);
+   if(ret != ROK)
+   {
+      DU_LOG("\nERROR  -->  EGTP : Failed to build App Msg");
+      return RFAILED;
+   }
 
    /* Encode EGTP header to build final EGTP message */
-   BuildEgtpMsg(&egtpMsg);
-
+   ret = BuildEgtpMsg(&egtpMsg);
+   if(ret != ROK)
+   {
+      DU_LOG("\nERROR  -->  EGTP : Failed to build EGTP Msg");
+      return RFAILED;
+   }
    /* Send Message to peer */
    while(cnt < 200)
    {
       DU_LOG("\nDEBUG  -->  EGTP : Sending message[%d]", cnt+1);
       cuEgtpSendMsg(egtpMsg.msg);
       cnt++;
+      //sleep(1);
    }
 
    ODU_PUT_MSG_BUF(egtpMsg.msg);
@@ -652,8 +662,19 @@ S16 cuEgtpDatReq()
 
 S16 BuildAppMsg(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;
  
@@ -746,7 +767,7 @@ S16 BuildAppMsg(EgtpMsg  *egtpMsg)
    egtpMsg->msgHdr.seqNum.pres = FALSE;
    egtpMsg->msgHdr.extHdr.udpPort.pres = FALSE;
    egtpMsg->msgHdr.extHdr.pdcpNmb.pres = FALSE;
-   egtpMsg->msgHdr.teId = 10;
+   egtpMsg->msgHdr.teId = 1;
    egtpMsg->msg = mBuf;
 
    return ret;
index bb82d2b..57a820f 100644 (file)
@@ -375,7 +375,7 @@ uint8_t egtpSrvOpenPrc(uint8_t sockType, EgtpTptSrvr *server)
  * ***************************************************************************/
 uint8_t egtpTnlMgmtReq(Pst *pst, EgtpTnlEvt tnlEvt)
 {
-   S8 ret;
+   uint8_t ret = ROK;
 
    DU_LOG("\nDEBUG   -->  EGTP : Received tunnel management request");
    switch(tnlEvt.action)
@@ -416,7 +416,7 @@ uint8_t egtpTnlMgmtReq(Pst *pst, EgtpTnlEvt tnlEvt)
    DU_LOG("\nDEBUG   -->  EGTP : Sending Tunnel management confirmation");
    duHdlEgtpTnlMgmtCfm(tnlEvt);
 
-   return ROK;
+   return ret;
 }
 
 /**************************************************************************
@@ -492,23 +492,18 @@ uint8_t egtpTnlAdd(EgtpTnlEvt tnlEvt)
  * ***************************************************************************/
 uint8_t egtpTnlMod(EgtpTnlEvt tnlEvt)
 {
-#if 0
-   uint8_t   ret;
    EgtpTeIdCb     *teidCb = NULLP;
 
-   DU_LOG("\nINFO   -->  Tunnel modification : LocalTeid[%d] Remote Teid[%d]", tnlEvt.lclTeid, tnlEvt.remTeid);
+   DU_LOG("\nINFO   -->  EGTP : Tunnel modification : LocalTeid[%d] Remote Teid[%d]", tnlEvt.lclTeid, tnlEvt.remTeid);
 
-   cmHashListFind(&(egtpCb.dstCb.teIdLst), (uint8_t *)&(tnlEvt.teId), sizeof(uint32_t), 0, (PTR *)&teidCb);
+   cmHashListFind(&(egtpCb.dstCb.teIdLst), (uint8_t *)&(tnlEvt.lclTeid), sizeof(uint32_t), 0, (PTR *)&teidCb);
    if(teidCb == NULLP)
    {
-      DU_LOG("\nERROR  -->  Tunnel id not found");
+      DU_LOG("\nERROR  -->  EGTP : Tunnel id not found");
       return RFAILED;
    }  
-   
-   teidCb->teId = tnlEvt.lclTeid;
-   DU_LOG("\nINFO  -->  Tunnel id is" , teidCb->teId);
+   teidCb->teId = tnlEvt.remTeid;
    teidCb->remTeId = tnlEvt.remTeid;
-#endif
    return ROK;
 }
 
@@ -543,7 +538,6 @@ uint8_t egtpTnlDel(EgtpTnlEvt tnlEvt)
    cmHashListDelete(&(egtpCb.dstCb.teIdLst), (PTR)teidCb);
    DU_FREE(teidCb, sizeof(EgtpTeIdCb));
    egtpCb.dstCb.numTunn--;
-
    return ROK;
 }
 
index ff73b8e..4213471 100644 (file)
 #include "du_mgr.h"
 #include "du_cell_mgr.h"
 #include "du_f1ap_msg_hdl.h"
+#include "DRBs-Setup-Item.h"
+#include "DLUPTNLInformation-ToBeSetup-List.h"
+#include "DLUPTNLInformation-ToBeSetup-Item.h"
+#include "UPTransportLayerInformation.h"
+#include "GTPTunnel.h"
 
 DuCfgParams duCfgParam;
 
@@ -6756,6 +6761,11 @@ void freeDuUeCfg(DuUeCfg *ueCfg)
    {
       freeMacLcCfg(&ueCfg->macLcCfg[lcIdx]);
    }
+   for(lcIdx = 0; lcIdx < ueCfg->numDrb; lcIdx++)
+   {
+      DU_FREE(ueCfg->upTnlInfo[lcIdx].tnlCfg1, sizeof(GtpTnlCfg));
+      memset(&ueCfg->upTnlInfo[lcIdx], 0, sizeof(UpTnlCfg));
+   }
 }
 
 /*******************************************************************
@@ -7133,10 +7143,81 @@ void extractQosInfo(DrbQosInfo *qosToAdd, QoSFlowLevelQoSParameters_t *qosFlowCf
    qosToAdd->ulPduSessAggMaxBitRate = 0;
 }
 
-uint8_t extractDrbCfg(DRBs_ToBeSetup_Item_t *drbItem, LcCfg *macLcToAdd)
+/*******************************************************************
+ *
+ * @brief Function to extract GTP Tunnel Info from CU
+ *
+ * @details
+ *
+ *    Function : extractUpTnlInfo
+ *
+ *    Functionality: Function to extract GTP Tunnel Info from CU
+ *
+ * @params[in] F1AP message
+ * @return ROK/RFAILED
+ *
+ * ****************************************************************/
+
+uint8_t extractUpTnlInfo(uint8_t drbId, uint8_t configType,\
+   ULUPTNLInformation_ToBeSetup_List_t *tnlInfo, UpTnlCfg *upTnlInfo)
+{
+   uint8_t tnlIdx;
+   uint32_t ipv4_du = 0;
+   GTPTunnel_t *gtpTunnel = NULLP;
+
+   upTnlInfo->drbId = drbId; 
+   upTnlInfo->configType = configType;
+   cmInetAddr((char *)DU_IP_V4_ADDR, &ipv4_du);
+
+   for(tnlIdx=0; tnlIdx < tnlInfo->list.count; tnlIdx++)
+   {
+      if(tnlInfo->list.array[tnlIdx]->uLUPTNLInformation.present == UPTransportLayerInformation_PR_gTPTunnel)
+      {
+        if(tnlInfo->list.array[tnlIdx]->uLUPTNLInformation.choice.gTPTunnel)
+        {
+           gtpTunnel = tnlInfo->list.array[tnlIdx]->uLUPTNLInformation.choice.gTPTunnel;
+           DU_ALLOC(upTnlInfo->tnlCfg1, sizeof(GtpTnlCfg));
+            if(upTnlInfo->tnlCfg1 == NULLP)
+           {
+               DU_LOG("\nERROR  -->  F1AP : extractUpTnlInfo: Failed to allocate mmeory for tunnel cfg 1");
+               return RFAILED;
+           }
+           bitStringToInt(&gtpTunnel->transportLayerAddress, &upTnlInfo->tnlCfg1->ulTnlAddress);
+           upTnlInfo->tnlCfg1->dlTnlAddress = ipv4_du;
+           if(gtpTunnel->gTP_TEID.size > 0)
+           {
+              teIdStringToInt(gtpTunnel->gTP_TEID.buf, &upTnlInfo->tnlCfg1->teId);
+           }
+        }
+        break;
+      }
+   }
+   return ROK;
+}
+
+/*******************************************************************
+ *
+ * @brief Function to extract DRB info received from CU
+ *
+ * @details
+ *
+ *    Function : extractDrbCfg
+ *
+ *    Functionality: Function to extract DRB info received from CU
+ *
+ * @params[in] F1AP message
+ * @return void
+ *
+ * ****************************************************************/
+uint8_t extractDrbCfg(DRBs_ToBeSetup_Item_t *drbItem, LcCfg *macLcToAdd, UpTnlCfg *upTnlInfo)
 {
    DRB_Information_t *drbInfo = NULLP;
 
+   if(extractUpTnlInfo(drbItem->dRBID, CONFIG_ADD, &drbItem->uLUPTNLInformation_ToBeSetup_List, upTnlInfo) != ROK)
+   {
+      DU_LOG("\nERROR  -->  DUAPP : Failed to extract tunnel Cfg at extractDrbCfg()");
+      return RFAILED;
+   }
    if(drbItem->qoSInformation.present == QoSInformation_PR_choice_extension)
    {
       if(drbItem->qoSInformation.choice.choice_extension->value.present ==
@@ -7180,17 +7261,21 @@ uint8_t extractDrbCfg(DRBs_ToBeSetup_Item_t *drbItem, LcCfg *macLcToAdd)
    return ROK;
 }
 
-uint8_t extractMacRbCfg(uint8_t lcId, DRBs_ToBeSetup_Item_t *drbCfg, LogicalChannelConfig_t *ulLcCfg, LcCfg *lcCfg)
+uint8_t extractMacRbCfg(uint8_t lcId, DRBs_ToBeSetup_Item_t *drbCfg, LogicalChannelConfig_t *ulLcCfg, LcCfg *lcCfg,\
+   UpTnlCfg *upTnlInfo)
 {
    uint8_t ret = ROK;
 
    if(drbCfg)
    {
-      ret = extractDrbCfg(drbCfg, lcCfg);
-      if(ret == RFAILED)
+      if(drbCfg != NULLP)
       {
-         DU_LOG("ERROR  -->  F1AP : Failed to build Drb Qos at extractMacRbCfg()");
-        return ret;
+         ret = extractDrbCfg(drbCfg, lcCfg, upTnlInfo);
+         if(ret == RFAILED)
+         {
+            DU_LOG("ERROR  -->  F1AP : Failed to build Drb Qos at extractMacRbCfg()");
+            return ret;
+         }
       }
    }
    else
@@ -7213,7 +7298,7 @@ uint8_t extractMacRbCfg(uint8_t lcId, DRBs_ToBeSetup_Item_t *drbCfg, LogicalChan
 }
 
 uint8_t procMacLcCfg(uint8_t lcId, uint8_t rbType, uint8_t configType,\
-   DRBs_ToBeSetup_Item_t *drbItem, LogicalChannelConfig_t *ulLcCfg, LcCfg *lcCfg)
+   DRBs_ToBeSetup_Item_t *drbItem, LogicalChannelConfig_t *ulLcCfg, LcCfg *lcCfg, UpTnlCfg *upTnlInfo)
 {
    uint8_t ret = ROK;
 
@@ -7221,11 +7306,11 @@ uint8_t procMacLcCfg(uint8_t lcId, uint8_t rbType, uint8_t configType,\
    lcCfg->configType = configType;
    if(rbType == RB_TYPE_SRB)
    {
-      ret = extractMacRbCfg(lcId, NULL, ulLcCfg, lcCfg);
+      ret = extractMacRbCfg(lcId, NULL, ulLcCfg, lcCfg, NULL);
    }
    else if(rbType == RB_TYPE_DRB)
    {
-      ret = extractMacRbCfg(lcId, drbItem, ulLcCfg, lcCfg);
+      ret = extractMacRbCfg(lcId, drbItem, ulLcCfg, lcCfg, upTnlInfo);
    }
    return ret;
 }
@@ -7298,7 +7383,7 @@ uint8_t extractRlcCfgToAddMod(struct CellGroupConfigRrc__rlc_BearerToAddModList
      memset(&ueCfgDb->macLcCfg[idx], 0, sizeof(LcCfg));
      memset(&ueCfgDb->rlcLcCfg[idx], 0, sizeof(RlcBearerCfg));
      procRlcLcCfg(rbId, lcId, rbType, rlcMode, CONFIG_UNKNOWN, f1RlcCfg, &(ueCfgDb->rlcLcCfg[idx]));
-     ret = procMacLcCfg(lcId, rbType, CONFIG_UNKNOWN, NULL, macUlLcCfg, &ueCfgDb->macLcCfg[idx]);
+     ret = procMacLcCfg(lcId, rbType, CONFIG_UNKNOWN, NULL, macUlLcCfg, &ueCfgDb->macLcCfg[idx], NULL);
      if(ret == RFAILED)
      {
         DU_LOG("\nERROR  -->  DU APP : Failed while filling MAC LC config at extractRlcCfgToAddMod()");
@@ -9288,7 +9373,7 @@ uint8_t procSrbListToSetup(SRBs_ToBeSetup_Item_t * srbItem, LcCfg *macLcToAdd, R
    procRlcLcCfg(srbItem->sRBID, srbItem->sRBID, RB_TYPE_SRB, RLC_AM, CONFIG_ADD, NULL, rlcLcToAdd);
 
    /* Filling MAC INFO */
-   ret = procMacLcCfg(srbItem->sRBID, RB_TYPE_SRB, CONFIG_ADD, NULL, NULL, macLcToAdd);
+   ret = procMacLcCfg(srbItem->sRBID, RB_TYPE_SRB, CONFIG_ADD, NULL, NULL, macLcToAdd, NULL);
    if(ret == RFAILED)
    { 
       DU_LOG("\nERROR  -->  F1AP : Failed at MAC LC Cfg in procSrbListToSetup()");
@@ -9375,7 +9460,8 @@ uint8_t extractSrbListToSetup(SRBs_ToBeSetup_List_t *srbCfg, DuUeCfg *ueCfgDb)
  *
  * ****************************************************************/
 
-uint8_t procDrbListToSetup(uint8_t lcId, DRBs_ToBeSetup_Item_t *drbItem, LcCfg *macLcToAdd, RlcBearerCfg *rlcLcToAdd)
+uint8_t procDrbListToSetup(uint8_t lcId, DRBs_ToBeSetup_Item_t *drbItem,\
+   LcCfg *macLcToAdd, RlcBearerCfg *rlcLcToAdd, UpTnlCfg *upTnlInfo)
 {
    uint8_t ret = ROK;
 
@@ -9383,10 +9469,10 @@ uint8_t procDrbListToSetup(uint8_t lcId, DRBs_ToBeSetup_Item_t *drbItem, LcCfg *
    procRlcLcCfg(drbItem->dRBID, lcId, RB_TYPE_DRB, drbItem->rLCMode, CONFIG_ADD, NULL, rlcLcToAdd);
 
    /* Filling MAC INFO */
-   ret = procMacLcCfg(lcId, RB_TYPE_DRB, CONFIG_ADD, drbItem, NULL, macLcToAdd);
+   ret = procMacLcCfg(lcId, RB_TYPE_DRB, CONFIG_ADD, drbItem, NULL, macLcToAdd, upTnlInfo);
    if(ret == RFAILED)
    { 
-      DU_LOG("\nERROR  -->  F1AP : Failed at RLC LC Cfg in extractDrbListToSetup()");
+      DU_LOG("\nERROR  --> F1AP : Failed at RLC LC Cfg in procDrbListToSetup()");
       return ret;
    }
 
@@ -9423,22 +9509,24 @@ uint8_t extractDrbListToSetup(uint8_t lcId, DRBs_ToBeSetup_List_t *drbCfg, DuUeC
          drbItem = &drbCfg->list.array[drbIdx]->value.choice.DRBs_ToBeSetup_Item;
         if(ueCfgDb->numMacLcs > MAX_NUM_LC)
         { 
-            DU_LOG("\nERROR   -->  F1AP:  MAX LC Reached in MAC ");
+            DU_LOG("\nERROR  -->  F1AP :  MAX LC Reached in MAC at extractDrbListToSetup()");
            ret = RFAILED;
            break;
         }
         if(ueCfgDb->numRlcLcs > MAX_NUM_LC)
         {
-            DU_LOG("\nERROR   -->  F1AP:  MAX LC Reached in RLC");
+            DU_LOG("\nERROR  -->  F1AP :  MAX LC Reached in RLC at extractDrbListToSetup()");
            ret = RFAILED;
            break;
         }
         memset(&ueCfgDb->macLcCfg[ueCfgDb->numMacLcs], 0, sizeof(LcCfg));
         memset(&ueCfgDb->rlcLcCfg[ueCfgDb->numRlcLcs], 0, sizeof(RlcBearerCfg));
          ret = procDrbListToSetup(lcId, drbItem, &ueCfgDb->macLcCfg[ueCfgDb->numMacLcs],\
-           &ueCfgDb->rlcLcCfg[ueCfgDb->numRlcLcs]);
+           &ueCfgDb->rlcLcCfg[ueCfgDb->numRlcLcs], &ueCfgDb->upTnlInfo[ueCfgDb->numDrb]);
+
         ueCfgDb->numRlcLcs++;
         ueCfgDb->numMacLcs++;
+        ueCfgDb->numDrb++;
         if(ret == RFAILED)
         {
             DU_LOG("\nERROR  -->  F1AP :  Failed at extractDrbListToSetup()");
@@ -9478,7 +9566,7 @@ uint8_t extractDlRrcMsg(uint32_t gnbDuUeF1apId, uint32_t gnbCuUeF1apId, \
       DU_ALLOC_SHRABL_BUF(dlRrcMsg->rrcMsgPdu, dlRrcMsg->rrcMsgSize);
       if(!dlRrcMsg->rrcMsgPdu)
       {
-         DU_LOG("\nERROR  -->  DU APP : Memory allocation failed for RRC Msg in procUeCtxtSetupReq");
+         DU_LOG("\nERROR  --> DU APP : Memory allocation failed for RRC Msg in extractDlRrcMsg()");
          ret = RFAILED;
       }
       else
@@ -9833,7 +9921,6 @@ uint8_t procF1UeContextSetupReq(F1AP_PDU_t *f1apMsg)
                     memset(duUeCb->f1UeDb->duUeCfg.ambrCfg, 0, sizeof(AmbrCfg)); 
                      memcpy(&duUeCb->f1UeDb->duUeCfg.ambrCfg->ulBr,
                     ueSetReq->protocolIEs.list.array[ieIdx]->value.choice.BitRate.buf, bitRateSize);
-                     duUeCb->f1UeDb->duUeCfg.ambrCfg->dlBr = 0;
                  }
               }
               else
@@ -9860,6 +9947,57 @@ uint8_t procF1UeContextSetupReq(F1AP_PDU_t *f1apMsg)
 
 }
 
+/*******************************************************************
+ * @brief Free the memory allocated for Dl Tunnel Info
+ *
+ * @details
+ *
+ *    Function : freeDlTnlInfo
+ *
+ *    Functionality:
+ *       Free the memory allocated for Dl Tunnel Info
+ *
+ * @params[in] DLUPTNLInformation_ToBeSetup_List_t *
+ * @return void
+ *
+ * ****************************************************************/
+
+void freeDlTnlInfo(DLUPTNLInformation_ToBeSetup_List_t *tnlInfo)
+{
+   uint8_t arrIdx = 0;
+
+   for(arrIdx=0; arrIdx < tnlInfo->list.count; arrIdx++)
+   {
+      DU_FREE(tnlInfo->list.array[arrIdx]->dLUPTNLInformation.choice.gTPTunnel, sizeof(GTPTunnel_t));
+   }
+}
+
+/*******************************************************************
+ * @brief Free the memory allocated for DRB setup List
+ *
+ * @details
+ *
+ *    Function : freeDrbSetupList
+ *
+ *    Functionality:
+ *       Free the memory allocated for DRB setup list
+ *
+ * @params[in] DRBs_Setup_List_t *
+ * @return void
+ *
+ * ****************************************************************/
+void freeDrbSetupList(DRBs_Setup_List_t *drbSetupList)
+{
+   uint8_t arrIdx = 0;
+   DRBs_Setup_ItemIEs_t *drbItemIe = NULLP;
+
+   for(arrIdx = 0; arrIdx < drbSetupList->list.count; arrIdx++)
+   {
+      drbItemIe = ((DRBs_Setup_ItemIEs_t *)drbSetupList->list.array[arrIdx]);
+      freeDlTnlInfo(&drbItemIe->value.choice.DRBs_Setup_Item.dLUPTNLInformation_ToBeSetup_List);
+   }
+}
+
 /*******************************************************************
  * @brief Free the memory allocated for UE Setup response
  *
@@ -9910,6 +10048,11 @@ void FreeUeContextSetupRsp(F1AP_PDU_t *f1apMsg)
                           }
                           break;
                        }
+                    case ProtocolIE_ID_id_DRBs_Setup_List:
+                       {
+                           freeDrbSetupList(&ueSetRsp->protocolIEs.list.array[idx]->value.choice.DRBs_Setup_List); 
+                           break;
+                       }
                     default:
                        DU_LOG("\nERROR  -->  DUAPP: Invalid Id %ld at FreeUeContextSetupRsp()",\
                        ueSetRsp->protocolIEs.list.array[idx]->id);
@@ -9978,6 +10121,158 @@ uint8_t EncodeUeCntxtDuToCuInfo(CellGroupConfig_t *duToCuCellGrp, CellGroupConfi
    return ROK;
 }
 
+/*******************************************************************
+ *
+ * @brief Fills Dl Gtp tunnel Info
+ *
+ * @details
+ *
+ *    Function : fillGtpTunnelforDl
+ *
+ *    Functionality: Fills Dl Gtp tunnel Info
+ *
+ * @params[in] 
+ *
+ * @return ROK     - success
+ *         RFAILED - failure
+ *
+ * ****************************************************************/
+
+uint8_t fillGtpTunnelforDl(GTPTunnel_t *gtpDl, GtpTnlCfg *gtpUeCfg)
+{
+   uint8_t bufSize = 0;
+
+   gtpDl->transportLayerAddress.size   = 4*sizeof(uint8_t);
+   DU_ALLOC(gtpDl->transportLayerAddress.buf, gtpDl->transportLayerAddress.size);
+   if(gtpDl->transportLayerAddress.buf == NULLP)
+   {
+      return RFAILED;
+   }
+   memcpy(gtpDl->transportLayerAddress.buf, &gtpUeCfg->dlTnlAddress, gtpDl->transportLayerAddress.size);
+
+   /*GTP TEID*/
+   gtpDl->gTP_TEID.size = 4 * sizeof(uint8_t);
+   DU_ALLOC(gtpDl->gTP_TEID.buf, gtpDl->gTP_TEID.size);
+   if(gtpDl->gTP_TEID.buf == NULLP)
+   {
+      return RFAILED;
+   }
+   bufSize = 3; /*forming an Octect String*/
+   fillTeIdString(bufSize, gtpUeCfg->teId, gtpDl->gTP_TEID.buf);
+
+   return ROK;
+}
+
+/*******************************************************************
+ *
+ * @brief Fills DL Tunnel Setup List
+ *
+ * @details
+ *
+ *    Function : fillDlTnlSetupList
+ *
+ *    Functionality: Fills the DL Tunnel Setup List
+ *
+ * @params[in] 
+ *
+ * @return ROK     - success
+ *         RFAILED - failure
+ *
+ * ****************************************************************/
+
+uint8_t fillDlTnlSetupList(DLUPTNLInformation_ToBeSetup_List_t *dlTnlInfo, UpTnlCfg *tnlCfg)
+{
+   uint8_t ret = ROK, arrIdx = 0, eleCount = 0;
+
+   eleCount = 1;
+   dlTnlInfo->list.count = eleCount; 
+   dlTnlInfo->list.size = (eleCount * sizeof(DLUPTNLInformation_ToBeSetup_Item_t *));
+
+   /* Initialize the DL Tnl Setup List Members */
+   DU_ALLOC(dlTnlInfo->list.array, dlTnlInfo->list.size);
+   if(dlTnlInfo->list.array == NULLP)
+   {
+      DU_LOG(" ERROR  -->  F1AP : Memory allocation for DL Tnl Setup List in fillDlTnlSetupList()");
+      ret = RFAILED;
+   }
+   for(arrIdx=0; arrIdx < eleCount; arrIdx++)
+   {
+      DU_ALLOC(dlTnlInfo->list.array[arrIdx], sizeof(DLUPTNLInformation_ToBeSetup_Item_t));
+      if(dlTnlInfo->list.array[arrIdx] == NULLP)
+      {
+         DU_LOG(" ERROR  -->  F1AP : Memory allocation for arrIdx [%d] failed in fillDlTnlSetupList()", arrIdx);
+         return RFAILED;
+      }
+      dlTnlInfo->list.array[arrIdx]->dLUPTNLInformation.present = UPTransportLayerInformation_PR_gTPTunnel;
+      DU_ALLOC(dlTnlInfo->list.array[arrIdx]->dLUPTNLInformation.choice.gTPTunnel, sizeof(GTPTunnel_t));
+      if(dlTnlInfo->list.array[arrIdx]->dLUPTNLInformation.choice.gTPTunnel == NULLP)
+      {
+         DU_LOG(" ERROR  -->  F1AP : Memory allocation for DL tunnel info in fillDlTnlSetupList()");
+         return RFAILED;
+      }
+      ret = fillGtpTunnelforDl(dlTnlInfo->list.array[arrIdx]->dLUPTNLInformation.choice.gTPTunnel,\
+               tnlCfg->tnlCfg1);
+      if(ret != ROK)
+         break;
+   }
+   return ret;
+}
+
+/*******************************************************************
+ *
+ * @brief Fills the Drb Setup List for Ue Context Setup Response
+ *
+ * @details
+ *
+ *    Function : fillDrbSetupList
+ *
+ *    Functionality: Fills the Drb Setup List for Ue Context Setup Response
+ *
+ * @params[in] 
+ *
+ * @return ROK     - success
+ *         RFAILED - failure
+ *
+ * ****************************************************************/
+uint8_t fillDrbSetupList(DRBs_Setup_List_t *drbSetupList, DuUeCfg *ueCfg)
+{
+   uint8_t ret = ROK, arrIdx = 0, eleCount = 0;
+   DRBs_Setup_ItemIEs_t *drbItemIe = NULLP;
+
+   eleCount = ueCfg->numDrb;
+   drbSetupList->list.count = eleCount;
+   drbSetupList->list.size = \
+       (eleCount * sizeof(DRBs_Setup_Item_t *));
+
+   /* Initialize the Drb Setup List Members */
+   DU_ALLOC(drbSetupList->list.array, drbSetupList->list.size);
+   if(drbSetupList->list.array == NULLP)
+   {
+      DU_LOG(" ERROR  -->  F1AP : Memory allocation for DRB Setup List in fillDrbSetupList()");
+      ret = RFAILED;
+   }
+
+   for(arrIdx=0; arrIdx < eleCount; arrIdx++)
+   {
+      DU_ALLOC(drbSetupList->list.array[arrIdx], sizeof(DRBs_Setup_Item_t));
+      if(drbSetupList->list.array[arrIdx] == NULLP)
+      {
+         DU_LOG(" ERROR  -->  F1AP : Memory allocation for arrIdx [%d] failed in fillDrbSetupList()", arrIdx);
+         return RFAILED;
+      }
+      drbItemIe = ((DRBs_Setup_ItemIEs_t *)drbSetupList->list.array[arrIdx]);
+      drbItemIe->id = ProtocolIE_ID_id_DRBs_Setup_Item;
+      drbItemIe->criticality = Criticality_reject;
+      drbItemIe->value.present = DRBs_Setup_ItemIEs__value_PR_DRBs_Setup_Item;
+      drbItemIe->value.choice.DRBs_Setup_Item.dRBID = ueCfg->upTnlInfo[arrIdx].drbId;
+      ret = fillDlTnlSetupList(&drbItemIe->value.choice.DRBs_Setup_Item.dLUPTNLInformation_ToBeSetup_List,\
+          &ueCfg->upTnlInfo[arrIdx]);
+      if(ret != ROK)
+         break;
+   }
+   return ret;
+}
+
 /*******************************************************************
  *
  * @brief Builds and sends the UE Setup Response
@@ -10036,7 +10331,7 @@ uint8_t BuildAndSendUeContextSetupRsp(uint8_t ueIdx, uint8_t cellId)
 
       ueSetRsp =
         &f1apMsg->choice.successfulOutcome->value.choice.UEContextSetupResponse;
-      elementCnt = 3;
+      elementCnt = 4;
       ueSetRsp->protocolIEs.list.count = elementCnt;
       ueSetRsp->protocolIEs.list.size = \
                                        elementCnt * sizeof(UEContextSetupResponse_t *);
@@ -10101,18 +10396,42 @@ uint8_t BuildAndSendUeContextSetupRsp(uint8_t ueIdx, uint8_t cellId)
            cellGrpCfg = (CellGroupConfigRrc_t*)ueCb->f1UeDb->duUeCfg.cellGrpCfg;
            ret = EncodeUeCntxtDuToCuInfo(&ueSetRsp->protocolIEs.list.array[idx]->value.\
                     choice.DUtoCURRCInformation.cellGroupConfig, cellGrpCfg);
-           /* Free UeContext Db created during Ue context Req */
-           freeF1UeDb(ueCb->f1UeDb);
-           ueCb->f1UeDb = NULLP;
+            if(ret == RFAILED)
+           {
+               DU_LOG("\nERROR  -->  F1AP : Failed to EncodeUeCntxtDuToCuInfo in BuildAndSendUeContextSetupRsp()");
+               freeF1UeDb(ueCb->f1UeDb);
+               ueCb->f1UeDb = NULLP;
+               break;
+           }
          }
       }
       else
       {
-         DU_LOG("\nERROR  -->  F1AP: Failed to form DUtoCU RRCInfo at BuildAndSendUeContextSetupRsp()");
+         DU_LOG("\nERROR  -->  F1AP : Failed to form DUtoCU RRCInfo at BuildAndSendUeContextSetupRsp()");
          ret = RFAILED;
+         break;
       }
+
+      /* Drb Setup List */
+      idx++;
+      ueSetRsp->protocolIEs.list.array[idx]->id  = \
+                                ProtocolIE_ID_id_DRBs_Setup_List;
+      ueSetRsp->protocolIEs.list.array[idx]->criticality = Criticality_reject;
+      ueSetRsp->protocolIEs.list.array[idx]->value.present =\
+                                UEContextSetupResponseIEs__value_PR_DRBs_Setup_List;
+      ret = fillDrbSetupList(&ueSetRsp->protocolIEs.list.array[idx]->value.choice.DRBs_Setup_List,\
+               &ueCb->f1UeDb->duUeCfg);
       if(ret == RFAILED)
+      {
+         DU_LOG("\nERROR  -->  F1AP : Failed to fillDrbSetupList in BuildAndSendUeContextSetupRsp()");
+         freeF1UeDb(ueCb->f1UeDb);
+         ueCb->f1UeDb = NULLP;
          break;
+      }
+
+       /* Free UeContext Db created during Ue context Req */
+       freeF1UeDb(ueCb->f1UeDb);
+       ueCb->f1UeDb = NULLP;
 
       xer_fprint(stdout, &asn_DEF_F1AP_PDU, f1apMsg);
 
@@ -10124,14 +10443,14 @@ uint8_t BuildAndSendUeContextSetupRsp(uint8_t ueIdx, uint8_t cellId)
       /* Encode results */
       if(encRetVal.encoded == ENCODE_FAIL)
       {
-        DU_LOG( "\nERROR  -->  F1AP : Could not encode UE Context Setup Request structure (at %s)\n",\
+        DU_LOG( "\nERROR  -->  F1AP : Could not encode UE Context Setup Response structure (at %s)\n",\
               encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
         ret = RFAILED;
         break;
       }
       else
       {
-        DU_LOG("\nDEBUG   -->  F1AP : Created APER encoded buffer for UE Context Setup Request\n");
+        DU_LOG("\nDEBUG   -->  F1AP : Created APER encoded buffer for UE Context Setup Response\n");
         for(int i=0; i< encBufSize; i++)
         {
            printf("%x",encBuf[i]);
@@ -10141,7 +10460,7 @@ uint8_t BuildAndSendUeContextSetupRsp(uint8_t ueIdx, uint8_t cellId)
       /* Sending  msg  */
       if(SendF1APMsg(DU_APP_MEM_REGION,DU_POOL)        != ROK)
       {
-        DU_LOG("\nERROR  -->  F1AP : Sending UE Context Setup Request Failed");
+        DU_LOG("\nERROR  -->  F1AP : Sending UE Context Setup Response failed");
         ret = RFAILED;
         break;
       }
index c48583a..9182bc3 100644 (file)
@@ -97,6 +97,23 @@ typedef struct f1DlRrcMsg
    uint8_t  *rrcMsgPdu;
 }F1DlRrcMsg;
 
+typedef struct gtpTnlCfg
+{
+   uint32_t ulTnlAddress;  /* remote Address */
+   uint32_t dlTnlAddress;  /* local Address */
+   uint32_t teId;
+}GtpTnlCfg;
+
+typedef struct upTnlCfg
+{
+   ConfigType configType;
+   uint8_t cellId;
+   uint8_t ueIdx;
+   uint8_t drbId;
+   GtpTnlCfg *tnlCfg1; /* Tunnel 1 */
+   GtpTnlCfg *tnlCfg2; /* Tunnel 2 */
+}UpTnlCfg;
+
 typedef struct duUeCfg
 {
    void *cellGrpCfg;
@@ -106,6 +123,8 @@ typedef struct duUeCfg
    uint8_t numMacLcs;        /* Mac Ue Cfg */
    LcCfg   macLcCfg[MAX_NUM_LC];
    AmbrCfg *ambrCfg;
+   uint8_t numDrb;
+   UpTnlCfg upTnlInfo[MAX_NUM_DRB];  /* User plane TNL Info*/
 }DuUeCfg;
 
 typedef struct f1UeContextSetup
@@ -183,6 +202,8 @@ typedef struct duCb
    DuCellCb*     actvCellLst[MAX_NUM_CELL];    /* List of cells activated/to be activated of type DuCellCb */
    uint32_t       numUe;            /* current number of UEs */
    UeCcchCtxt     ueCcchCtxt[MAX_NUM_UE]; /* mapping of gnbDuUeF1apId to CRNTI required for CCCH processing*/
+   uint8_t       numDrb;           /* current number of DRbs*/
+   UpTnlCfg*     upTnlCfg[MAX_NUM_DRB]; /* tunnel info for every Drb */
 }DuCb;
 
 
@@ -234,7 +255,7 @@ uint8_t duBuildEgtpCfgReq();
 uint8_t duHdlEgtpCfgComplete(CmStatus cfm);
 uint8_t duSendEgtpSrvOpenReq();
 uint8_t duHdlEgtpSrvOpenComplete(CmStatus cfm);
-uint8_t duSendEgtpTnlMgmtReq(uint8_t action, uint32_t lclTeid, uint32_t remTeid);
+uint8_t duSendEgtpTnlMgmtReq(uint8_t action, uint32_t teIdMod, GtpTnlCfg *tnlInfo);
 uint8_t duSendEgtpDatInd(Buffer *mBuf);
 uint8_t duHdlSchCfgComplete(Pst *pst, RgMngmt *cfm);
 uint8_t duBuildAndSendMacCellStart();
index 3887cc8..af63f7c 100644 (file)
@@ -1136,9 +1136,6 @@ uint8_t duHdlEgtpSrvOpenComplete(CmStatus cfm)
    if(cfm.status == LCM_PRIM_OK)
    {
       DU_LOG("\nDEBUG   -->  DU_APP : EGTP server opened successfully");
-#ifdef EGTP_TEST
-      duSendEgtpTnlMgmtReq(EGTP_TNL_MGMT_ADD, EGTP_LCL_TEID, EGTP_REM_TEID);
-#endif
    }
    else
    {
@@ -1168,19 +1165,28 @@ uint8_t duHdlEgtpSrvOpenComplete(CmStatus cfm)
  *
  * ****************************************************************/
 
-uint8_t duSendEgtpTnlMgmtReq(uint8_t action, uint32_t lclTeid, uint32_t remTeid)
+uint8_t duSendEgtpTnlMgmtReq(uint8_t action, uint32_t teIdTobeMod, GtpTnlCfg *ueCbTnlCfg)
 {
+   uint8_t ret =ROK;
    Pst pst;
    EgtpTnlEvt tnlEvt;
 
-   tnlEvt.action = action;
-   tnlEvt.lclTeid = lclTeid;
-   tnlEvt.remTeid = remTeid;
+   DU_LOG("\nDEBUG   -->  DU_APP : Sending EGTP tunnel management request for teId [%d]", ueCbTnlCfg->teId);
 
-   DU_LOG("\nDEBUG   -->  DU_APP : Sending EGTP tunnel management request");
+   /* ADD/MOD/DEL per tunnel */
+   tnlEvt.action = action;
+   tnlEvt.remTeid = ueCbTnlCfg->teId;
+   if(action != EGTP_TNL_MGMT_ADD)
+   {
+      tnlEvt.lclTeid = teIdTobeMod;
+   }
+   else
+   {
+      tnlEvt.lclTeid = ueCbTnlCfg->teId;
+   }
    duFillEgtpPst(&pst, EVTTNLMGMTREQ);
-   egtpTnlMgmtReq(&pst, tnlEvt);
-   return ROK;
+   ret = egtpTnlMgmtReq(&pst, tnlEvt);
+   return ret;
 }
 
 /*******************************************************************
@@ -1736,16 +1742,9 @@ uint8_t DuProcRlcRrcDeliveryReport(Pst *pst, RrcDeliveryReport *rrcDeliveryRepor
 uint8_t DuProcRlcUlUserDataTrans(Pst *pst, RlcUlUserDatInfo *ulUserData)
 {
    uint8_t  rbIdx;
-   DuCellCb *cellCb;
-   DuUeCb   ueCb;
    EgtpMsg  egtpMsg;
    Buffer   *mBuf;
 
-   if(duGetCellCb(ulUserData->cellId, &cellCb) != ROK)
-      return RFAILED;
-
-   ueCb = cellCb->ueCb[ulUserData->ueIdx -1];
-
    DU_LOG("\nDEBUG  -->  DU APP : Received UL user data");
 
    /* Fill EGTP header */
@@ -1756,18 +1755,17 @@ uint8_t DuProcRlcUlUserDataTrans(Pst *pst, RlcUlUserDatInfo *ulUserData)
    egtpMsg.msgHdr.extHdr.pdcpNmb.pres = FALSE;
 
    /* Fetch EGTP tunnel info */
-   /* TODO : keep the "#if 0" code block and test once DL User data changes are submitted */
-#if 0
-   for(rbIdx = 0; rbIdx < MAX_NUM_DRB; rbIdx++)
+   for(rbIdx = 0; rbIdx < duCb.numDrb; rbIdx++)
    {
-      if(ueCb.ulTnlCfg[rbIx]->drbId == ulUserData->rbId)
+      if((duCb.upTnlCfg[rbIdx] != NULLP) && (duCb.upTnlCfg[rbIdx]->drbId == ulUserData->rbId))
       {
-         egtpMsg.msgHdr.teId = ueCb.ulTnlCfg[rbIx]->tnlCfg.teId;
+        if(duCb.upTnlCfg[rbIdx]->tnlCfg1)
+        {
+            egtpMsg.msgHdr.teId = duCb.upTnlCfg[rbIdx]->tnlCfg1->teId; /*As we are supporting only 1 tunnel per DRB*/
+           break;
+        }
       }
    }
-#else
-   egtpMsg.msgHdr.teId = 1;
-#endif
 
    if (ODU_GET_MSG_BUF(DU_APP_MEM_REGION, DU_POOL, &mBuf) != ROK)
    {
index d863ece..153ebf0 100644 (file)
 #include "du_f1ap_msg_hdl.h"
 #include "du_ue_mgr.h"
 
-#ifdef EGTP_TEST
-uint32_t sduId = 0;
-#endif
-
 DuMacDlCcchInd packMacDlCcchIndOpts[] =
 {
    packMacDlCcchInd,   /* Loose coupling */
@@ -79,6 +75,11 @@ DuMacUeReconfigReq packMacUeReconfigReqOpts[] =
    MacProcUeReconfigReq,       /* TIght coupling */
    packDuMacUeReconfigReq     /* Light weight-loose coupling */
 };
+
+#ifdef EGTP_TEST
+uint32_t sduId = 0;
+#endif
+
 /*******************************************************************
  *
  * @brief Handles EGTP data from CU 
@@ -920,7 +921,6 @@ uint8_t fillAmbr(AmbrCfg **macAmbr, AmbrCfg *ueDbAmbr)
       }
       memset(*macAmbr, 0, sizeof(AmbrCfg));
       (*macAmbr)->ulBr = ueDbAmbr->ulBr;
-      (*macAmbr)->dlBr = ueDbAmbr->dlBr;
    }
    else
    {
@@ -1800,6 +1800,190 @@ uint8_t duUpdateRlcLcCfg(RlcUeCfg *rlcUeCfg, F1UeContextSetupDb *f1UeDb)
 }
 
 
+/*******************************************************************
+ *
+ * @brief Function to fill Tunnel Config to Add/Mod
+ * 
+ *
+ * @details
+ *
+ *    Function : fillTnlCfgToAddMod
+ *
+ *    Functionality: Function to fill tunnel Config to Add/Mod
+ *
+ * @params[in] Pointer to tnlCfgDb,
+ *             pointer to f1TnlCfg
+ * @return ROK     - success
+ *         RFAILED - failure
+ *
+ * ****************************************************************/
+uint8_t fillTnlCfgToAddMod(UpTnlCfg **ueCbTnlCfg, UpTnlCfg *f1TnlCfg)
+{
+   if(*ueCbTnlCfg == NULLP)
+   {
+      /* copying to DuCb Tnl Cfg */
+      DU_ALLOC(*ueCbTnlCfg, sizeof(UpTnlCfg));
+      if(*ueCbTnlCfg == NULLP)
+      {
+         DU_LOG("\nERROR  -->  DU_APP : fillTnlCfgToAddMod: Memory Alloc failed for drbId[%d]", f1TnlCfg->drbId);
+         return RFAILED;
+      }
+   }
+   memset(*ueCbTnlCfg, 0, sizeof(UpTnlCfg));
+   (*ueCbTnlCfg)->configType = f1TnlCfg->configType;
+   (*ueCbTnlCfg)->cellId    = f1TnlCfg->cellId;
+   (*ueCbTnlCfg)->ueIdx     = f1TnlCfg->ueIdx;
+   (*ueCbTnlCfg)->drbId     = f1TnlCfg->drbId;
+   if(f1TnlCfg->tnlCfg1)
+   {
+      if((*ueCbTnlCfg)->tnlCfg1 == NULLP)
+      {
+         DU_ALLOC((*ueCbTnlCfg)->tnlCfg1, sizeof(GtpTnlCfg));
+         if((*ueCbTnlCfg)->tnlCfg1 == NULLP)
+         {
+            DU_LOG("\nERROR  -->  DU_APP : fillTnlCfgToAddMod: Memory Alloc failed for tnlCfg1 for drbId[%d]", f1TnlCfg->drbId);
+            return RFAILED;
+         }
+      }
+      memset((*ueCbTnlCfg)->tnlCfg1, 0, sizeof(GtpTnlCfg));
+      (*ueCbTnlCfg)->tnlCfg1->teId = f1TnlCfg->tnlCfg1->teId;
+      (*ueCbTnlCfg)->tnlCfg1->ulTnlAddress = f1TnlCfg->tnlCfg1->ulTnlAddress;
+      (*ueCbTnlCfg)->tnlCfg1->dlTnlAddress = f1TnlCfg->tnlCfg1->dlTnlAddress;
+   }
+   return ROK;
+}
+
+/*******************************************************************
+ *
+ * @brief Processing the tunnel Request to EGTP
+ *        
+ * @details
+ *
+ *    Function : duProcEgtpTunnelCfg
+ *
+ *    Functionality: Processing the tunnel Request to EGTP
+ *
+ * @params[in] UptnlCfg *duTnlCfg, UpTnlCfg *f1TnlCfg 
+ * @return ROK     - success
+ *         RFAILED - failure
+ *
+ * ****************************************************************/
+
+uint8_t duProcEgtpTunnelCfg(uint8_t ueCbIdx, UpTnlCfg *duTnlCfg, UpTnlCfg *f1TnlCfg)
+{
+   uint8_t ret = RFAILED, delIdx;
+
+   if(f1TnlCfg->tnlCfg1 == NULLP)
+   {
+      DU_LOG("\nERROR  -->  DU_APP : Tunnel config not found");
+      return ret;
+   }
+
+   if(f1TnlCfg->configType == CONFIG_ADD)
+   {
+      if(duSendEgtpTnlMgmtReq(EGTP_TNL_MGMT_ADD, NULLP, f1TnlCfg->tnlCfg1) == ROK)
+      {
+        if(fillTnlCfgToAddMod(&duCb.upTnlCfg[duCb.numDrb], f1TnlCfg) == ROK)
+        {
+           duCb.numDrb++;
+           ret = ROK;
+        }
+      }      
+   }
+   else if(f1TnlCfg->configType == CONFIG_MOD)
+   {
+      if(duSendEgtpTnlMgmtReq(EGTP_TNL_MGMT_MOD, duTnlCfg->tnlCfg1->teId, f1TnlCfg->tnlCfg1) == ROK)
+      {
+        if(fillTnlCfgToAddMod(&duTnlCfg, f1TnlCfg) == ROK)
+        {
+           ret = ROK;
+        }
+      }   
+   }
+   else if(f1TnlCfg->configType == CONFIG_DEL)
+   {
+      if(duSendEgtpTnlMgmtReq(EGTP_TNL_MGMT_DEL, duTnlCfg->tnlCfg1->teId, f1TnlCfg->tnlCfg1) == ROK)
+      {           
+        /* Free memory at drbIdx */
+        DU_FREE(duTnlCfg->tnlCfg1, sizeof(GtpTnlCfg));
+        DU_FREE(duTnlCfg, sizeof(UpTnlCfg));
+        duCb.numDrb--;
+        for(delIdx = ueCbIdx; delIdx < duCb.numDrb; delIdx++)
+        {
+           /* moving all elements one index ahead */
+           ret = fillTnlCfgToAddMod(&duCb.upTnlCfg[delIdx], duCb.upTnlCfg[delIdx+1]);
+           if(ret != ROK)
+           {
+              return ret;
+           }
+        }
+      }   
+   }
+   return ret;
+}
+
+/***********************************************************************
+ *
+ * @brief Function to fill Tunnel Config
+ *        and sends tunnel Req to EGTP
+ * 
+ *
+ * @details
+ *
+ *    Function : duUpdateTunnelCfgDb
+ *
+ *    Functionality: Function to fill tunnel Config
+ *                   and sends tunnel Cfg Req to EGTP
+ *
+ * @params[in] ueIdx, cellId, DuUeCfg 
+ * @return ROK     - success
+ *         RFAILED - failure
+ *
+ * ****************************************************************/
+
+uint8_t duUpdateTunnelCfgDb(uint8_t ueIdx, uint8_t cellId, DuUeCfg *duUeCfg)
+{
+   uint8_t ret = ROK, drbIdx, duCbDrbIdx;
+   bool drbFound = false;
+
+   /*If Add/Mod tunnels request for that DRB is successful in EGTP */
+   /*then update drbId and tunnel Info in duCb */
+   for(drbIdx=0; drbIdx < duUeCfg->numDrb; drbIdx++)
+   {
+      duUeCfg->upTnlInfo[drbIdx].cellId = cellId;
+      duUeCfg->upTnlInfo[drbIdx].ueIdx = ueIdx;
+      for(duCbDrbIdx = 0; duCbDrbIdx < duCb.numDrb; duCbDrbIdx++)
+      {
+        if(duCb.upTnlCfg[duCbDrbIdx]->drbId == duUeCfg->upTnlInfo[drbIdx].drbId)
+        {
+           drbFound = true; /* existing DRB */
+           if(duProcEgtpTunnelCfg(duCbDrbIdx, duCb.upTnlCfg[duCbDrbIdx], &duUeCfg->upTnlInfo[drbIdx]) != ROK)
+           {
+              DU_LOG("\nERROR  -> DU_APP : duUpdateTunnelCfgDb: Failed to modify tunnel req for Drb id[%d]",
+              duUeCfg->upTnlInfo[drbIdx].drbId);
+              ret = RFAILED;
+           }
+           break;
+        }
+        else
+           drbFound = false;
+      }
+      if(!drbFound && ret == ROK)/* new DRB to Add */
+      {
+        if(duProcEgtpTunnelCfg(NULLP, NULLP, &duUeCfg->upTnlInfo[drbIdx]) != ROK)
+        {
+            DU_LOG("\nERROR  -> DU_APP : duUpdateTunnelCfgDb: Failed to add tunnel req for Drb id[%d]",
+           duUeCfg->upTnlInfo[drbIdx].drbId);
+           ret = RFAILED;
+           break;
+        }
+      }
+      else
+         break;
+   }
+   return ret;
+}
+
 /*******************************************************************
  *
  * @brief @brief To update DuUeCb Mac and Rlc Ue Cfg
@@ -1845,6 +2029,14 @@ uint8_t duUpdateDuUeCbCfg(uint8_t ueIdx, uint8_t cellId)
          ret = duUpdateMacCfg(&ueCb->macUeCfg, ueCb->f1UeDb);
          if(ret == RFAILED)
             DU_LOG("\nERROR  -->  DU APP : Failed while updating MAC LC Config at duUpdateDuUeCbCfg()");
+         else
+        {
+           if(duUpdateTunnelCfgDb(ueIdx, cellId, &ueCb->f1UeDb->duUeCfg) != ROK)
+           {
+               DU_LOG("\nERROR  -->  DU_APP : Failed to establish tunnel in duUpdateDuUeCbCfg()");
+              return RFAILED;
+           }
+        }
       }
       else
          DU_LOG("\nERROR  -->  DU APP : Failed while updating RLC LC Config at duUpdateDuUeCbCfg()");
index cd89677..c755845 100644 (file)
 
 /* free a static buffer */
 #define DU_FREE(_datPtr, _size)                                 \
-   if(_datPtr)                                                  \
+{                                                               \
+   if(_datPtr != NULLP)                                                  \
+   {                                                            \
       SPutSBuf(DU_APP_MEM_REGION, DU_POOL,                      \
-         (Data *)_datPtr, _size);
-
+         (Data *)_datPtr, _size);                               \
+      _datPtr = NULLP;                                          \
+   }                                                            \
+}
 /* Allocate shared memory to be used for LWLC
  * during inter-layer communication */
 #define DU_ALLOC_SHRABL_BUF(_buf, _size)                     \