From fce9f0b5d5f56b2b9058212bf2462b2beabf4d28 Mon Sep 17 00:00:00 2001
From: "Wilson W.K. Thong" <wilsonthong@astri.org>
Date: Thu, 15 Dec 2016 14:01:39 +0800
Subject: [PATCH] avoid detecting DCI0 at subframes where no DCI0s are sent by
 eNB. This happens only in TDD mode

issue !156
---
 openair1/PHY/LTE_TRANSPORT/dci.c           | 57 ++++++++++++----------
 openair1/PHY/impl_defs_lte.h               | 12 ++++-
 openair1/SCHED/defs.h                      |  7 +++
 openair1/SCHED/phy_procedures_lte_common.c | 28 +++++++++++
 4 files changed, 77 insertions(+), 27 deletions(-)

diff --git a/openair1/PHY/LTE_TRANSPORT/dci.c b/openair1/PHY/LTE_TRANSPORT/dci.c
index 38cfc2c8c9..0ed502200b 100644
--- a/openair1/PHY/LTE_TRANSPORT/dci.c
+++ b/openair1/PHY/LTE_TRANSPORT/dci.c
@@ -2648,6 +2648,7 @@ int get_nCCE_offset_l1(int *CCE_table,
 
 void dci_decoding_procedure0(LTE_UE_PDCCH **pdcch_vars,
 			     int do_common,
+			     dci_detect_mode_t mode,
 			     uint8_t subframe,
                              DCI_ALLOC_t *dci_alloc,
                              int16_t eNB_id,
@@ -2685,6 +2686,11 @@ void dci_decoding_procedure0(LTE_UE_PDCCH **pdcch_vars,
   if (nCCE<L2)
     return;
 
+  if (mode == NO_DCI) {
+    LOG_D(PHY, "skip DCI decoding: expect no DCIs at subframe %d\n", subframe);
+    return;
+  }
+
   if (do_common == 1) {
     nb_candidates = (L2==4) ? 4 : 2;
     Yk=0;
@@ -2835,7 +2841,7 @@ void dci_decoding_procedure0(LTE_UE_PDCCH **pdcch_vars,
           *dci_cnt = *dci_cnt+1;
         } else if (crc==pdcch_vars[eNB_id]->crnti) {
 
-          if ((format_c == format0)&&((dci_decoded_output[0]&0x80)==0)) {// check if pdu is format 0 or 1A
+          if ((mode&UL_DCI)&&(format_c == format0)&&((dci_decoded_output[0]&0x80)==0)) {// check if pdu is format 0 or 1A
             if (*format0_found == 0) {
               dci_alloc[*dci_cnt].format     = format0;
               *format0_found = 1;
@@ -2916,6 +2922,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
   uint8_t format1_size_bits=0,format1_size_bytes=0;
   uint8_t format2_size_bits=0,format2_size_bytes=0;
   uint8_t format2A_size_bits=0,format2A_size_bytes=0;
+  dci_detect_mode_t mode = dci_detect_mode_select(&ue->frame_parms,subframe);
 
   switch (frame_parms->N_RB_DL) {
   case 6:
@@ -3118,7 +3125,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
 
     // First check common search spaces at aggregation 4 (SI_RNTI, P_RNTI and RA_RNTI format 0/1A),
     // and UE_SPEC format0 (PUSCH) too while we're at it
-    dci_decoding_procedure0(pdcch_vars,1,subframe,
+    dci_decoding_procedure0(pdcch_vars,1,mode,subframe,
                             dci_alloc,
                             eNB_id,
                             frame_parms,
@@ -3146,7 +3153,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
 
     // Now check common search spaces at aggregation 4 (SI_RNTI,P_RNTI and RA_RNTI and C-RNTI format 1C),
     // and UE_SPEC format0 (PUSCH) too while we're at it
-    dci_decoding_procedure0(pdcch_vars,1,subframe,
+    dci_decoding_procedure0(pdcch_vars,1,mode,subframe,
                             dci_alloc,
                             eNB_id,
                             frame_parms,
@@ -3178,7 +3185,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
 #ifdef DEBUG_DCI_DECODING
     printf("[DCI search] doing common search/format0 aggregation 8\n");
 #endif
-    dci_decoding_procedure0(pdcch_vars,1,subframe,
+    dci_decoding_procedure0(pdcch_vars,1,mode,subframe,
                             dci_alloc,
                             eNB_id,
                             frame_parms,
@@ -3206,7 +3213,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
 
     // Now check common search spaces at aggregation 8 (SI_RNTI and RA_RNTI and C-RNTI format 1C),
     // and UE_SPEC format0 (PUSCH) too while we're at it
-    dci_decoding_procedure0(pdcch_vars,1,subframe,
+    dci_decoding_procedure0(pdcch_vars,1,mode,subframe,
                             dci_alloc,
                             eNB_id,
                             frame_parms,
@@ -3239,7 +3246,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
 
   // Now check UE_SPEC format0/1A ue_spec search spaces at aggregation 8
   //  printf("[DCI search] Format 0/1A aggregation 8\n");
-  dci_decoding_procedure0(pdcch_vars,0,
+  dci_decoding_procedure0(pdcch_vars,0,mode,
                           subframe,
                           dci_alloc,
                           eNB_id,
@@ -3268,7 +3275,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
 
   //  printf("[DCI search] Format 0 aggregation 4\n");
   // Now check UE_SPEC format 0 search spaces at aggregation 4
-  dci_decoding_procedure0(pdcch_vars,0,
+  dci_decoding_procedure0(pdcch_vars,0,mode,
                           subframe,
                           dci_alloc,
                           eNB_id,
@@ -3301,7 +3308,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
 
   //  printf("[DCI search] Format 0 aggregation 2\n");
   // Now check UE_SPEC format 0 search spaces at aggregation 2
-  dci_decoding_procedure0(pdcch_vars,0,
+  dci_decoding_procedure0(pdcch_vars,0,mode,
                           subframe,
                           dci_alloc,
                           eNB_id,
@@ -3330,7 +3337,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
 
   //  printf("[DCI search] Format 0 aggregation 4\n");
   // Now check UE_SPEC format 0 search spaces at aggregation 1
-  dci_decoding_procedure0(pdcch_vars,0,
+  dci_decoding_procedure0(pdcch_vars,0,mode,
                           subframe,
                           dci_alloc,
                           eNB_id,
@@ -3364,7 +3371,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
   if (tmode < 3) {
     // Now check UE_SPEC format 1 search spaces at aggregation 1
     old_dci_cnt=dci_cnt;
-    dci_decoding_procedure0(pdcch_vars,0,subframe,
+    dci_decoding_procedure0(pdcch_vars,0,mode,subframe,
                             dci_alloc,
                             eNB_id,
                             frame_parms,
@@ -3395,7 +3402,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
 
     // Now check UE_SPEC format 1 search spaces at aggregation 2
     old_dci_cnt=dci_cnt;
-    dci_decoding_procedure0(pdcch_vars,0,subframe,
+    dci_decoding_procedure0(pdcch_vars,0,mode,subframe,
                             dci_alloc,
                             eNB_id,
                             frame_parms,
@@ -3427,7 +3434,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
 
     // Now check UE_SPEC format 1 search spaces at aggregation 4
     old_dci_cnt=dci_cnt;
-    dci_decoding_procedure0(pdcch_vars,0,subframe,
+    dci_decoding_procedure0(pdcch_vars,0,mode,subframe,
                             dci_alloc,
                             eNB_id,
                             frame_parms,
@@ -3459,7 +3466,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
     //#ifdef ALL_AGGREGATION
     // Now check UE_SPEC format 1 search spaces at aggregation 8
     old_dci_cnt=dci_cnt;
-    dci_decoding_procedure0(pdcch_vars,0,subframe,
+    dci_decoding_procedure0(pdcch_vars,0,mode,subframe,
                             dci_alloc,
                             eNB_id,
                             frame_parms,
@@ -3493,7 +3500,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
 
 
     // Now check UE_SPEC format 2A_2A search spaces at aggregation 1
-    dci_decoding_procedure0(pdcch_vars,0,
+    dci_decoding_procedure0(pdcch_vars,0,mode,
                             subframe,
                             dci_alloc,
                             eNB_id,
@@ -3524,7 +3531,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
       return(dci_cnt);
 
     // Now check UE_SPEC format 2 search spaces at aggregation 2
-    dci_decoding_procedure0(pdcch_vars,0,
+    dci_decoding_procedure0(pdcch_vars,0,mode,
                             subframe,
                             dci_alloc,
                             eNB_id,
@@ -3555,7 +3562,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
       return(dci_cnt);
 
     // Now check UE_SPEC format 2_2A search spaces at aggregation 4
-    dci_decoding_procedure0(pdcch_vars,0,
+    dci_decoding_procedure0(pdcch_vars,0,mode,
                             subframe,
                             dci_alloc,
                             eNB_id,
@@ -3587,7 +3594,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
 
     //#ifdef ALL_AGGREGATION
     // Now check UE_SPEC format 2_2A search spaces at aggregation 8
-    dci_decoding_procedure0(pdcch_vars,0,
+    dci_decoding_procedure0(pdcch_vars,0,mode,
                             subframe,
                             dci_alloc,
                             eNB_id,
@@ -3613,7 +3620,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
   } else if (tmode == 4) {
 
     // Now check UE_SPEC format 2_2A search spaces at aggregation 1
-    dci_decoding_procedure0(pdcch_vars,0,
+    dci_decoding_procedure0(pdcch_vars,0,mode,
                             subframe,
                             dci_alloc,
                             eNB_id,
@@ -3644,7 +3651,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
       return(dci_cnt);
 
     // Now check UE_SPEC format 2 search spaces at aggregation 2
-    dci_decoding_procedure0(pdcch_vars,0,
+    dci_decoding_procedure0(pdcch_vars,0,mode,
                             subframe,
                             dci_alloc,
                             eNB_id,
@@ -3675,7 +3682,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
       return(dci_cnt);
 
     // Now check UE_SPEC format 2_2A search spaces at aggregation 4
-    dci_decoding_procedure0(pdcch_vars,0,
+    dci_decoding_procedure0(pdcch_vars,0,mode,
                             subframe,
                             dci_alloc,
                             eNB_id,
@@ -3707,7 +3714,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
 
     //#ifdef ALL_AGGREGATION
     // Now check UE_SPEC format 2_2A search spaces at aggregation 8
-    dci_decoding_procedure0(pdcch_vars,0,
+    dci_decoding_procedure0(pdcch_vars,0,mode,
                             subframe,
                             dci_alloc,
                             eNB_id,
@@ -3736,7 +3743,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
 #ifdef DEBUG_DCI_DECODING
     LOG_I(PHY," MU-MIMO check UE_SPEC format 1E_2A_M10PRB\n");
 #endif
-    dci_decoding_procedure0(pdcch_vars,0,
+    dci_decoding_procedure0(pdcch_vars,0,mode,
                             subframe,
                             dci_alloc,
                             eNB_id,
@@ -3768,7 +3775,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
       return(dci_cnt);
 
     // Now check UE_SPEC format 1E_2A_M10PRB search spaces aggregation 2
-    dci_decoding_procedure0(pdcch_vars,0,
+    dci_decoding_procedure0(pdcch_vars,0,mode,
                             subframe,
                             dci_alloc,
                             eNB_id,
@@ -3799,7 +3806,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
       return(dci_cnt);
 
     // Now check UE_SPEC format 1E_2A_M10PRB search spaces aggregation 4
-    dci_decoding_procedure0(pdcch_vars,0,
+    dci_decoding_procedure0(pdcch_vars,0,mode,
                             subframe,
                             dci_alloc,
                             eNB_id,
@@ -3832,7 +3839,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
     //#ifdef ALL_AGGREGATION
 
     // Now check UE_SPEC format 1E_2A_M10PRB search spaces at aggregation 8
-    dci_decoding_procedure0(pdcch_vars,0,
+    dci_decoding_procedure0(pdcch_vars,0,mode,
                             subframe,
                             dci_alloc,
                             eNB_id,
diff --git a/openair1/PHY/impl_defs_lte.h b/openair1/PHY/impl_defs_lte.h
index 9005518e7b..1f1ba75e27 100644
--- a/openair1/PHY/impl_defs_lte.h
+++ b/openair1/PHY/impl_defs_lte.h
@@ -1059,6 +1059,14 @@ typedef enum {
 
 typedef enum {SF_DL, SF_UL, SF_S} lte_subframe_t;
 
-#endif
-
+typedef enum {
+  /// do not detect any DCIs in the current subframe
+  NO_DCI = 0x0,
+  /// detect only downlink DCIs in the current subframe
+  UL_DCI = 0x1,
+  /// detect only uplink DCIs in the current subframe
+  DL_DCI = 0x2,
+  /// detect both uplink and downlink DCIs in the current subframe
+  UL_DL_DCI = 0x3} dci_detect_mode_t;
 
+#endif
diff --git a/openair1/SCHED/defs.h b/openair1/SCHED/defs.h
index 2490a4035c..599ca31735 100644
--- a/openair1/SCHED/defs.h
+++ b/openair1/SCHED/defs.h
@@ -212,6 +212,13 @@ void prach_procedures(PHY_VARS_eNB *eNB);
 
 lte_subframe_t subframe_select(LTE_DL_FRAME_PARMS *frame_parms,uint8_t subframe);
 
+/*! \brief Function to compute which type of DCIs to detect in the given subframe
+  @param frame_parms Pointer to DL frame parameter descriptor
+  @param subframe Subframe index
+  @returns DCI detetion mode type (no DCIs, uplink DCIs, downlink DCIs, both uplink and downlink DCIs)
+ */
+dci_detect_mode_t dci_detect_mode_select(LTE_DL_FRAME_PARMS *frame_parms,uint8_t subframe);
+
 /*! \brief Function to compute subframe type as a function of Frame type and TDD Configuration (implements Table 4.2.2 from 36.211, p.11 from version 8.6) and subframe index.  Same as subframe_select, except that it uses the Mod_id and is provided as a service to the MAC scheduler.
   @param Mod_id Index of eNB
   @param CC_id Component Carrier Index
diff --git a/openair1/SCHED/phy_procedures_lte_common.c b/openair1/SCHED/phy_procedures_lte_common.c
index 239a5e2f8d..b736cb7ae8 100644
--- a/openair1/SCHED/phy_procedures_lte_common.c
+++ b/openair1/SCHED/phy_procedures_lte_common.c
@@ -518,6 +518,34 @@ lte_subframe_t subframe_select(LTE_DL_FRAME_PARMS *frame_parms,unsigned char sub
   }
 }
 
+dci_detect_mode_t dci_detect_mode_select(LTE_DL_FRAME_PARMS *frame_parms,uint8_t subframe)
+{
+  dci_detect_mode_t ret = 0;
+
+  static dci_detect_mode_t Table_8_2_3gpp_36_213[][10] = {
+     //subf0    , subf1     , subf2 , subf3         , subf4     , subf5     , subf6     , subf7 , subf8     , subf9
+      {UL_DL_DCI, UL_DL_DCI , NO_DCI    , NO_DCI    , NO_DCI    , UL_DL_DCI , UL_DL_DCI , NO_DCI, NO_DCI    , NO_DCI    },  // tdd0
+      {DL_DCI   , UL_DL_DCI , NO_DCI    , NO_DCI    , UL_DL_DCI , DL_DCI    , UL_DL_DCI , NO_DCI, NO_DCI    , UL_DL_DCI },  // tdd1
+      {DL_DCI   , DL_DCI    , NO_DCI    , UL_DL_DCI , DL_DCI    , DL_DCI    , DL_DCI    , NO_DCI, UL_DL_DCI , DL_DCI    },  // tdd2
+      {UL_DL_DCI, DL_DCI    , NO_DCI    , NO_DCI    , NO_DCI    , DL_DCI    , DL_DCI    , DL_DCI, UL_DL_DCI , UL_DL_DCI },  // tdd3
+      {DL_DCI   , DL_DCI    , NO_DCI    , NO_DCI    , DL_DCI    , DL_DCI    , DL_DCI    , DL_DCI, UL_DL_DCI , UL_DL_DCI },  // tdd4
+      {DL_DCI   , DL_DCI    , NO_DCI    , DL_DCI    , DL_DCI    , DL_DCI    , DL_DCI    , DL_DCI, UL_DL_DCI , DL_DCI    },  // tdd5
+      {UL_DL_DCI, UL_DL_DCI , NO_DCI    , NO_DCI    , NO_DCI    , UL_DL_DCI , UL_DL_DCI , NO_DCI, NO_DCI    , UL_DL_DCI }}; // tdd6
+
+
+  DevAssert(subframe>=0 && subframe<=9);
+  DevAssert((frame_parms->tdd_config)>=0 && (frame_parms->tdd_config)<=6);
+
+  if (frame_parms->frame_type == FDD) {
+    ret = UL_DL_DCI;
+  } else {
+    ret = Table_8_2_3gpp_36_213[frame_parms->tdd_config][subframe];
+  }
+
+  LOG_D(PHY, "subframe %d: detect UL_DCI=%d, detect DL_DCI=%d\n", subframe, (ret & UL_DCI)>0, (ret & DL_DCI)>0);
+  return ret;
+}
+
 lte_subframe_t get_subframe_direction(uint8_t Mod_id,uint8_t CC_id,uint8_t subframe)
 {
 
-- 
GitLab