From bb3883bff0e9753ba4179682b4c5fbe0cdb73445 Mon Sep 17 00:00:00 2001
From: Sakthivel Velumani <velumani@eurecom.fr>
Date: Wed, 1 Apr 2020 01:26:02 +0200
Subject: [PATCH] 1_1 DCI encoding - added checks from RRC IEs

---
 .../LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c |  4 +-
 .../NR_MAC_gNB/gNB_scheduler_primitives.c     | 72 +++++++++++++------
 openair2/LAYER2/NR_MAC_gNB/mac_proto.h        |  5 +-
 3 files changed, 57 insertions(+), 24 deletions(-)

diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c
index b89f45be0e..0c58ba325a 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c
@@ -387,7 +387,7 @@ int configure_fapi_dl_pdu(int Mod_idP,
   rnti_types[0]   = NR_RNTI_C;
 
   pdcch_pdu_rel15->PayloadSizeBits[0]=nr_dci_size(dci_formats[0],rnti_types[0],pdcch_pdu_rel15->BWPSize);
-  fill_dci_pdu_rel15(pdsch_pdu_rel_15,NULL,pdcch_pdu_rel15,&dci_pdu_rel15[0],dci_formats,rnti_types);
+  fill_dci_pdu_rel15(secondaryCellGroup,pdsch_pdu_rel15,pdcch_pdu_rel15,NULL,&dci_pdu_rel15[0],dci_formats,rnti_types);
 
   LOG_D(MAC, "DCI params: rnti %d, rnti_type %d, dci_format %d\n \
 	                      coreset params: FreqDomainResource %llx, start_symbol %d  n_symb %d\n",
@@ -833,7 +833,7 @@ void nr_schedule_uss_ulsch_phytest(int Mod_idP,
   config_uldci(ubwp,pusch_pdu,pdcch_pdu_rel15, &dci_pdu_rel15[0], dci_formats, rnti_types);
   
   pdcch_pdu_rel15->PayloadSizeBits[0]=nr_dci_size(dci_formats[0],rnti_types[0],pdcch_pdu_rel15->BWPSize);
-  fill_dci_pdu_rel15(NULL,pusch_pdu,pdcch_pdu_rel15,&dci_pdu_rel15[0],dci_formats,rnti_types);
+  fill_dci_pdu_rel15(secondaryCellGroup,NULL,pdcch_pdu_rel15,pusch_pdu,&dci_pdu_rel15[0],dci_formats,rnti_types);
   
 }
 
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
index 51988c9cb3..4e8ef2dd44 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
@@ -544,16 +544,35 @@ void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t* pdcch_pdu,
   }
 }
 
+// TODO: Move the following 2 functions somewhere that UE can also use
+// Table 5.1.2.2.1-1 38.214
+uint8_t getRBGSize(uint16_t bwp_size, long rbg_size_config) {
+  
+  AssertFatal(bwp_size<276,"BWP Size > 275\n");
+  
+  if (bwp_size < 37)  return (rbg_size_config ? 4 : 2);
+  if (bwp_size < 73)  return (rbg_size_config ? 8 : 4);
+  if (bwp_size < 145) return (rbg_size_config ? 16 : 8);
+  if (bwp_size < 276) return 16;
+}
+
+uint8_t getNRBG(uint16_t bwp_size, uint16_t bwp_start, long rbg_size_config) {
+
+  uint8_t rbg_size = getRBGSize(bwp_size,rbg_size_config);
 
+  return (uint8_t)ceil((bwp_size+(bwp_start % rbg_size))/rbg_size);
+}
 
-void fill_dci_pdu_rel15(nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15,
-      nfapi_nr_pusch_pdu_t *pusch_pdu,
+void fill_dci_pdu_rel15(NR_CellGroupConfig_t *secondaryCellGroup,
+      nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15,
       nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15,
+      nfapi_nr_pusch_pdu_t  *pusch_pdu,
 			dci_pdu_rel15_t *dci_pdu_rel15,
 			int *dci_formats,
 			int *rnti_types
 			) {
   
+  NR_PDSCH_Config_t *pdsch_config = secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup;
   uint16_t N_RB = pdcch_pdu_rel15->BWPSize;
   uint8_t fsize=0, pos=0;
   uint8_t nbits=0;
@@ -875,24 +894,25 @@ void fill_dci_pdu_rel15(nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15,
       *dci_pdu |= ((uint64_t)dci_pdu_rel15->format_indicator&1)<<(dci_size-pos);
 
       // Carrier indicator
-      if (!dci_pdu_rel15->carrier_indicator) {// TODO: check if UE configured with CrossCarrierSchedulingConfig
+      if (secondaryCellGroup->spCellConfig->spCellConfigDedicated->crossCarrierSchedulingConfig != NULL) {
         pos+=3;
         *dci_pdu |= ((uint64_t)dci_pdu_rel15->carrier_indicator&0x7)<<(dci_size-pos);
       }
 
       // BWP indicator
-      uint8_t n_bwp_rrc = 0; // TODO: get this parameter from RRC
+      uint8_t n_dl_bwp = secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count;
       
-      nbits = (uint8_t)((n_bwp_rrc < 4) ? ceil(log2(n_bwp_rrc+1)) : ceil(log2(n_bwp_rrc))); 
+      nbits = (uint8_t)((n_dl_bwp < 4) ? ceil(log2(n_dl_bwp+1)) : ceil(log2(n_dl_bwp))); 
       pos+=nbits;
-      *dci_pdu |= ((uint64_t)dci_pdu_rel15->bwp_indicator&((1<<nbits)-1)<<(dci_size-pos);
+      *dci_pdu |= ((uint64_t)dci_pdu_rel15->bwp_indicator&((1<<nbits)-1))<<(dci_size-pos);
 
       // Frequency domain resource assignment
-      uint16_t numRBG = 0; // TODO: replace with N_RBG (couldn't find it)
+      long rbg_size_config = secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->rbg_Size;
+      uint16_t numRBG = getNRBG(pdsch_pdu_rel15->BWPSize,pdsch_pdu_rel15->BWPStart,rbg_size_config);
 
-      if (pdsch_pdu_rel15->resourceAlloc == 0)
+      if (pdsch_config->resourceAllocation == 0)
         nbits = numRBG;
-      else if (pdsch_pdu_rel15->resourceAlloc == 1)
+      else if (pdsch_config->resourceAllocation == 1)
         nbits = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) );
       else
         nbits = ((int)ceil( log2( (N_RB*(N_RB+1))>>1 ) )>numRBG) ? (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) )+1 : numRBG+1;
@@ -901,33 +921,43 @@ void fill_dci_pdu_rel15(nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15,
       *dci_pdu |= ((uint64_t)dci_pdu_rel15->frequency_domain_assignment&((1<<nbits)-1)) << (dci_size-pos);
 
       // Time domain resource assignment
-      uint8_t num_entries;
-      if (0) // TODO: check if pdschTimeDomainAllocationList exists
-        num_entries = 0; // TODO: replace with number of entries in pdschTimeDomainAllocationList
+      NR_PDSCH_TimeDomainResourceAllocationList_t *pdsch_timeDomList = secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[0]->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList;
+      int num_entries;
+      if (pdsch_timeDomList != NULL)
+        num_entries = pdsch_timeDomList->list.count;
       else
-        num_entries = 16;
+        num_entries = 16; // num of entries in default table
 
       nbits = (int)ceil(log2(num_entries));
       pos+=nbits;
       *dci_pdu |= ((uint64_t)dci_pdu_rel15->time_domain_assignment&((1<<nbits)-1)) << (dci_size-pos);
 
       // VRB-to-PRB mapping
-      if (pdsch_pdu_rel15->resourceAlloc == 1) {
+      if (pdsch_config->resourceAllocation == 1) {
         pos++;
         *dci_pdu |= ((uint64_t)dci_pdu_rel15->vrb_to_prb_mapping&1)<<(dci_size-pos);
       }
       
       // PRB bundling size indicator
-      if (0) {// TODO: check if prb-BundlingType is dynamic
+      if (secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->prb_BundlingType.present == 2) {
         pos++;
         *dci_pdu |= ((uint64_t)dci_pdu_rel15->prb_bundling_size_indicator&1)<<(dci_size-pos);
       }
 
       // Rate matching indicator
-      // TODO: check for rateMatchPatternGroup
+      NR_RateMatchPatternGroup_t *group1 = secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->rateMatchPatternGroup1;
+      NR_RateMatchPatternGroup_t *group2 = secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->rateMatchPatternGroup2; 
+      nbits = 0;
+      if ((group1 != NULL) && (group2 != NULL))
+        nbits = 2;
+      if ((group1 != NULL) != (group2 != NULL))
+        nbits = 1;
+      pos+=nbits;
+      *dci_pdu |= ((uint64_t)dci_pdu_rel15->rate_matching_indicator&((1<<nbits)-1))<<(dci_size-pos);
+
 
       // ZP CSI-RS trigger
-      uint8_t nZP = 0; // TODO: replace with number of aperiodic ZP CSI-RS resource sets
+      uint8_t nZP = secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->aperiodic_ZP_CSI_RS_ResourceSetsToAddModList->list.count; 
       nbits = (int)ceil(log2(nZP+1));
       pos+=nbits;
       *dci_pdu |= ((uint64_t)dci_pdu_rel15->zp_csi_rs_trigger&((1<<nbits)-1)) << (dci_size-pos);
@@ -949,13 +979,15 @@ void fill_dci_pdu_rel15(nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15,
       *dci_pdu |= ((uint64_t)dci_pdu_rel15->harq_pid&0xf)<<(dci_size-pos);
 
       // Downlink assignment index
-      if (0) { // TODO: check if UE has more than 1 serving cell AND pdsch-HARQ-ACK-Codebook is dynamic
+      if (secondaryCellGroup->physicalCellGroupConfig->pdsch_HARQ_ACK_Codebook == 1) { // at this point the UE has multiple serving cells
         pos+=4;
         *dci_pdu |= ((uint64_t)dci_pdu_rel15->dai&0xf)<<(dci_size-pos);
-      } else if (0) { // TODO: check if UE had only 1 serving cell AND "
+      }
+/*      else if (0) {
         pos+=2;
         *dci_pdu |= ((uint64_t)dci_pdu_rel15->dai&0x3)<<(dci_size-pos);
       }
+*/
 
       // TPC command for scheduled PUCCH  2bit
       pos+=2;
@@ -966,7 +998,7 @@ void fill_dci_pdu_rel15(nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15,
       *dci_pdu |= ((uint64_t)dci_pdu_rel15->pucch_resource_indicator&0x7)<<(dci_size-pos);
 
       // PDSCH-to-HARQ_feedback timing indicator
-      uint8_t I = 0; // TODO: replace with number of entries in dl-DataToUL-ACK
+      uint8_t I = secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pucch_Config->choice.setup->dl_DataToUL_ACK->list.count;
       nbits = (int)ceil(log2(I));
       pos+=nbits;
       *dci_pdu |= ((uint64_t)dci_pdu_rel15->pdsch_to_harq_feedback_timing_indicator&((1<<nbits)-1))<<(dci_size-pos);
diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
index d73b32a17b..fd02368c0d 100644
--- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
+++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
@@ -130,9 +130,10 @@ void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t* pdcch_pdu,
                         NR_ServingCellConfigCommon_t *scc,
                         NR_BWP_Downlink_t *bwp);
 
-void fill_dci_pdu_rel15(nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15,
-                        nfapi_nr_pusch_pdu_t *pusch_pdu,
+void fill_dci_pdu_rel15(NR_CellGroupConfig_t *secondaryCellGroup,
+                        nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15,
                         nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15,
+                        nfapi_nr_pusch_pdu_t  *pusch_pdu,
                         dci_pdu_rel15_t *dci_pdu_rel15,
                         int *dci_formats,
                         int *rnti_types);
-- 
2.26.2