PDSCH and PUSCH MCS Update [Issue-ID: ODUHIGH-261]
[o-du/l2.git] / src / du_app / du_f1ap_msg_hdl.c
index fe34308..95862d1 100644 (file)
 #include "du_app_rlc_inf.h"
 #include "du_mgr_main.h"
 #include "du_utils.h"
+#include "RAT-Type.h"
+#include "FeatureSetUplinkPerCC.h"
+#include "FeatureSetDownlinkPerCC.h"
+#include "FeatureSets.h"
+#include "UE-NR-Capability.h"
+#include "UE-CapabilityRAT-Container.h"
+#include "UE-CapabilityRAT-ContainerListRRC.h"
 #include "GNB-DU-System-Information.h"
 #include "CellGroupConfigRrc.h"
 #include "MAC-CellGroupConfig.h"
@@ -5508,6 +5515,79 @@ void  freeMacLcCfg(LcCfg *lcCfg)
    memset(lcCfg, 0, sizeof(LcCfg));
 }
 
+/*******************************************************************
+ *
+ * @brief Free UE NR Capability received in UE Context setup request
+ *
+ * @details
+ *
+ *    Function : freeUeNrCapability
+ *
+ *    Functionality:  
+ *       Free UE NR Capability received in UE Context setup request
+ *
+ * @params[in] 
+ * @return ROK     - success
+ *         RFAILED - failure
+ *
+ * ****************************************************************/
+void freeUeNrCapability(void *ueNrCapability)
+{
+   uint8_t idx;
+   FeatureSets_t *featureSets;
+   UE_NR_Capability_t *ueNrCap = (UE_NR_Capability_t *)ueNrCapability;
+
+   if(ueNrCap->rf_Parameters.supportedBandListNR.list.array)
+   {
+      for(idx = 0; idx < ueNrCap->rf_Parameters.supportedBandListNR.list.count; idx++)
+      {
+         if(ueNrCap->rf_Parameters.supportedBandListNR.list.array[idx])
+            free(ueNrCap->rf_Parameters.supportedBandListNR.list.array[idx]);
+      }
+      free(ueNrCap->rf_Parameters.supportedBandListNR.list.array);
+   }
+
+   if(ueNrCap->featureSets)
+   {
+      featureSets = ueNrCap->featureSets;
+      if(featureSets->featureSetsDownlinkPerCC)
+      {
+         if(featureSets->featureSetsDownlinkPerCC->list.array)
+         {
+            for(idx = 0; idx < featureSets->featureSetsDownlinkPerCC->list.count; idx++)
+            {
+               if(featureSets->featureSetsDownlinkPerCC->list.array[idx])
+               {
+                  if(featureSets->featureSetsDownlinkPerCC->list.array[idx]->supportedModulationOrderDL)
+                     free(featureSets->featureSetsDownlinkPerCC->list.array[idx]->supportedModulationOrderDL);
+                  free(featureSets->featureSetsDownlinkPerCC->list.array[idx]);
+               }
+            }
+            free(featureSets->featureSetsDownlinkPerCC->list.array);
+         }
+         free(featureSets->featureSetsDownlinkPerCC);
+      }
+      if(featureSets->featureSetsUplinkPerCC)
+      {
+         if(featureSets->featureSetsUplinkPerCC->list.array)
+         {
+            for(idx = 0; idx < featureSets->featureSetsUplinkPerCC->list.count; idx++)
+            {
+               if(featureSets->featureSetsUplinkPerCC->list.array[idx])
+               {
+                  if(featureSets->featureSetsUplinkPerCC->list.array[idx]->supportedModulationOrderUL)
+                     free(featureSets->featureSetsUplinkPerCC->list.array[idx]->supportedModulationOrderUL);
+                  free(featureSets->featureSetsUplinkPerCC->list.array[idx]);
+               }
+            }
+            free(featureSets->featureSetsUplinkPerCC->list.array);
+         }
+         free(featureSets->featureSetsUplinkPerCC);
+      }
+      free(ueNrCap->featureSets);
+   }   
+}
+
 /*******************************************************************
  *
  * @brief Function to free DuUeCfg
@@ -5526,6 +5606,12 @@ void freeDuUeCfg(DuUeCfg *ueCfg)
 {
    uint8_t lcIdx;
 
+   if(ueCfg->ueNrCapability)
+   {
+      freeUeNrCapability(ueCfg->ueNrCapability);
+      DU_FREE(ueCfg->ueNrCapability, sizeof(UE_NR_Capability_t));
+      ueCfg->ueNrCapability = NULLP;
+   }
    if(ueCfg->cellGrpCfg)
    {
       DU_FREE(ueCfg->cellGrpCfg, sizeof(CellGroupConfigRrc_t));
@@ -6479,7 +6565,7 @@ void extractPdschCfg(PDSCH_Config_t *cuPdschCfg, PdschConfig *macPdschCfg)
         }
       }
    }
-   macPdschCfg->rbgSize = cuPdschCfg->rbg_Size; 
+   macPdschCfg->rbgSize = cuPdschCfg->rbg_Size;
    if(cuPdschCfg->maxNrofCodeWordsScheduledByDCI)
       macPdschCfg->numCodeWordsSchByDci = *(cuPdschCfg->maxNrofCodeWordsScheduledByDCI);
    if(cuPdschCfg->prb_BundlingType.present == PDSCH_Config__prb_BundlingType_PR_staticBundling)
@@ -6726,6 +6812,7 @@ uint8_t extractServingCellReconfig(ServingCellConfig_t *cuSrvCellCfg, ServCellCf
       {
          if(dlBwp->pdcch_Config->choice.setup)
         {
+           macSrvCellCfg->initDlBwp.pdcchPresent = true;
            extractPdcchCfg(dlBwp->pdcch_Config->choice.setup, &macSrvCellCfg->initDlBwp.pdcchCfg);
         }
       }
@@ -6733,6 +6820,7 @@ uint8_t extractServingCellReconfig(ServingCellConfig_t *cuSrvCellCfg, ServCellCf
       {
          if(dlBwp->pdsch_Config->choice.setup)
         {
+           macSrvCellCfg->initDlBwp.pdschPresent = true;
            extractPdschCfg(dlBwp->pdsch_Config->choice.setup, &macSrvCellCfg->initDlBwp.pdschCfg);
         }
       }
@@ -6939,6 +7027,115 @@ uint8_t procUeReCfgCellInfo(MacUeCfg *macUeCfg, void *cellInfo)
    return ret;
 }
 
+/*******************************************************************
+ *
+ * @brief Filling modulation info in mac ue cfg
+ *
+ * @details
+ *
+ *    Function : duFillModulationDetails
+ *
+ *    Functionality: Filling modulation info in mac ue cfg
+ *
+ * @params[in] MAC UE Config to be updated
+ *             Current UE configuration
+ *             UE NR capability from CU
+ * @return ROK     - success
+ *         RFAILED - failure
+ *
+ * ****************************************************************/
+void duFillModulationDetails(MacUeCfg *ueCfg, MacUeCfg *oldUeCfg, void *ueCap)
+{
+   UE_NR_Capability_t *ueNrCap;
+
+   if(ueCap)
+      ueNrCap = (UE_NR_Capability_t *)ueCap;
+
+   /* Filling DL modulation info */
+   if(ueNrCap->featureSets && ueNrCap->featureSets->featureSetsDownlinkPerCC && \
+        ueNrCap->featureSets->featureSetsDownlinkPerCC->list.array[0] && \
+        ueNrCap->featureSets->featureSetsDownlinkPerCC->list.array[0]->supportedModulationOrderDL)
+   {
+      switch(*(ueNrCap->featureSets->featureSetsDownlinkPerCC->list.array[0]->supportedModulationOrderDL))
+      {
+        case ModulationOrder_qpsk:
+           {
+              ueCfg->dlModInfo.modOrder = MOD_ORDER_QPSK;
+              break;
+           }
+        case ModulationOrder_qam16:
+           {
+              ueCfg->dlModInfo.modOrder = MOD_ORDER_QAM16;
+              break;
+           }
+        case ModulationOrder_qam64:
+           {
+              ueCfg->dlModInfo.modOrder = MOD_ORDER_QAM64;
+              ueCfg->dlModInfo.mcsIndex = PDSCH_MCS_INDEX;
+              ueCfg->dlModInfo.mcsTable = MCS_TABLE_QAM64;
+              break;
+           }
+        case ModulationOrder_qam256:
+           {
+              ueCfg->dlModInfo.modOrder = MOD_ORDER_QAM256;
+              break;
+           }
+        default:
+           {
+              DU_LOG("\nDU APP: Incorrect downlink modulation order received. Reatining old modulation configuration");
+              memcpy(&ueCfg->dlModInfo, &oldUeCfg->dlModInfo, sizeof(ModulationInfo));
+              break;
+           }
+      }
+   }
+   else
+   {
+      memcpy(&ueCfg->dlModInfo, &oldUeCfg->dlModInfo, sizeof(ModulationInfo));
+   }
+
+   /* Filling UL modulation info */
+   if(ueNrCap->featureSets && ueNrCap->featureSets->featureSetsUplinkPerCC && \
+        ueNrCap->featureSets->featureSetsUplinkPerCC->list.array[0] && \
+        ueNrCap->featureSets->featureSetsUplinkPerCC->list.array[0]->supportedModulationOrderUL)
+   {
+      switch(*(ueNrCap->featureSets->featureSetsUplinkPerCC->list.array[0]->supportedModulationOrderUL))
+      {
+        case ModulationOrder_qpsk:
+           {
+              ueCfg->ulModInfo.modOrder = MOD_ORDER_QPSK;
+              break;
+           }
+        case ModulationOrder_qam16:
+           {
+              ueCfg->ulModInfo.modOrder = MOD_ORDER_QAM16;
+              ueCfg->ulModInfo.mcsIndex = PUSCH_MCS_INDEX;
+              ueCfg->ulModInfo.mcsTable = MCS_TABLE_QAM64;
+              break;
+           }
+        case ModulationOrder_qam64:
+           {
+              ueCfg->ulModInfo.modOrder = MOD_ORDER_QAM64;
+              break;
+           }
+        case ModulationOrder_qam256:
+           {
+              ueCfg->ulModInfo.modOrder = MOD_ORDER_QAM256;
+              break;
+           }
+        default:
+           {
+              DU_LOG("\nDU APP: Incorrect uplink modulation order received. Reatining old modulation configuration");
+              memcpy(&ueCfg->ulModInfo, &oldUeCfg->ulModInfo, sizeof(ModulationInfo));
+              break;
+           }
+      }
+   }
+   else
+   {
+      memcpy(&ueCfg->ulModInfo, &oldUeCfg->ulModInfo, sizeof(ModulationInfo));
+   }
+}
+
 /*******************************************************************
  *
  * @brief Function to extract cellGrp Info present in cutoDu cont
@@ -7233,6 +7430,87 @@ uint8_t extractDlRrcMsg(uint32_t gnbDuUeF1apId, uint32_t gnbCuUeF1apId, \
    return ret;
 }
 
+/*******************************************************************
+ *
+ * @brief Extract UE capability info 
+ *
+ * @details
+ *
+ *    Function : extractUeCapability
+ *
+ *    Functionality: Extract UE capability info and stores in ue Cb
+ *
+ * @params[in] Octet string of UE capability RAT container list
+ * @return ROK     - success
+ *         RFAILED - failure
+ *
+ * ****************************************************************/
+UE_NR_Capability_t *extractUeCapability(UE_CapabilityRAT_ContainerList_t *ueCapablityListBuf, DuUeCb *ueCb)
+{
+   uint8_t  idx;
+   uint16_t recvBufLen;
+   asn_dec_rval_t rval;
+   UE_NR_Capability_t  *ueNrCap = NULLP;
+   UE_CapabilityRAT_ContainerListRRC_t  *ueCapRatContList = NULLP;
+
+   /* Decoding UE Capability RAT Container List */
+   recvBufLen = ueCapablityListBuf->size;
+   DU_ALLOC(ueCapRatContList, sizeof(UE_CapabilityRAT_ContainerListRRC_t));
+   if(!ueCapRatContList)
+   {
+      DU_LOG("\nF1AP : Memory allocation failed in extractUeCapability");
+      return RFAILED;
+   }
+   memset(ueCapRatContList, 0, sizeof(UE_CapabilityRAT_ContainerListRRC_t));
+   memset(&rval, 0, sizeof(asn_dec_rval_t));
+   rval = aper_decode(0, &asn_DEF_UE_CapabilityRAT_ContainerListRRC, (void **)&ueCapRatContList,
+          ueCapablityListBuf->buf, recvBufLen, 0, 0);
+   if(rval.code == RC_FAIL || rval.code == RC_WMORE)
+   {
+      DU_LOG("\nF1AP : ASN decode failed at decodeCellGrpCfg()");
+      return NULLP;
+   }
+   xer_fprint(stdout, &asn_DEF_UE_CapabilityRAT_ContainerListRRC, ueCapRatContList);
+
+   /* Free encoded buffer after decoding */
+   free(ueCapablityListBuf->buf);
+
+   for(idx = 0; idx < ueCapRatContList->list.count; idx++)
+   {
+      if(ueCapRatContList->list.array[idx]->rat_Type == RAT_Type_nr)
+      {
+         /* Decoding UE NR Capability */
+          recvBufLen = ueCapRatContList->list.array[idx]->ue_CapabilityRAT_Container.size;
+          DU_ALLOC(ueNrCap, sizeof(UE_NR_Capability_t));
+          if(!ueNrCap)
+          {
+             DU_LOG("\nF1AP : Memory allocation failed in extractUeCapability");
+             DU_FREE(ueCapRatContList, sizeof(UE_CapabilityRAT_ContainerListRRC_t));
+             return RFAILED;
+          } 
+          memset(ueNrCap, 0, sizeof(UE_NR_Capability_t));
+          memset(&rval, 0, sizeof(asn_dec_rval_t));
+          rval = aper_decode(0, &asn_DEF_UE_NR_Capability, (void **)&ueNrCap,
+                 ueCapRatContList->list.array[idx]->ue_CapabilityRAT_Container.buf, recvBufLen, 0, 0);
+          if(rval.code == RC_FAIL || rval.code == RC_WMORE)
+          {
+             DU_LOG("\nF1AP : ASN decode failed at decodeCellGrpCfg()");
+             return NULLP;
+          }
+          xer_fprint(stdout, &asn_DEF_UE_NR_Capability, ueNrCap);
+          
+          /* Free encoded buffer after decoding */
+          free(ueCapRatContList->list.array[idx]->ue_CapabilityRAT_Container.buf);
+      }
+      free(ueCapRatContList->list.array[idx]);
+   }
+
+   /* Free Memory*/
+   free(ueCapRatContList->list.array);
+   DU_FREE(ueCapRatContList, sizeof(UE_CapabilityRAT_ContainerListRRC_t));
+   return ueNrCap;
+}
+
 /*******************************************************************
  *
  * @brief Process UE context setup request from CU
@@ -7313,6 +7591,12 @@ uint8_t procF1UeContextSetupReq(F1AP_PDU_t *f1apMsg)
            break;
          case ProtocolIE_ID_id_CUtoDURRCInformation:
            {
+               if(ueSetReq->protocolIEs.list.array[ieIdx]->value.choice.CUtoDURRCInformation.uE_CapabilityRAT_ContainerList)
+               {
+                  duUeCb->f1UeDb->duUeCfg.ueNrCapability = \
+                     extractUeCapability(ueSetReq->protocolIEs.list.array[ieIdx]->value.choice.CUtoDURRCInformation.\
+                        uE_CapabilityRAT_ContainerList, duUeCb);
+               }
               if(ueSetReq->protocolIEs.list.array[ieIdx]->value.choice.CUtoDURRCInformation.iE_Extensions)
               {
                   duUeCb->f1UeDb->duUeCfg.cellGrpCfg = extractCellGrpInfo(ueSetReq->protocolIEs.list.array[ieIdx]->\