diff --git a/openair1/PHY/LTE_TRANSPORT/dci.c b/openair1/PHY/LTE_TRANSPORT/dci.c
index 824caa52fa49e07f6647333127a7968df9f0ef9d..55a12a253a44509935e786b76a49bab5ad5c6ca5 100644
--- a/openair1/PHY/LTE_TRANSPORT/dci.c
+++ b/openair1/PHY/LTE_TRANSPORT/dci.c
@@ -2663,6 +2663,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,
@@ -2704,6 +2705,11 @@ void dci_decoding_procedure0(LTE_UE_PDCCH **pdcch_vars,
     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;
@@ -2854,7 +2860,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;
@@ -2935,6 +2941,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:
@@ -3137,7 +3144,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,
@@ -3165,7 +3172,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,
@@ -3197,7 +3204,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,
@@ -3225,7 +3232,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,
@@ -3258,7 +3265,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,
@@ -3287,7 +3294,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,
@@ -3320,7 +3327,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,
@@ -3349,7 +3356,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,
@@ -3383,7 +3390,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
   if ((tmode < 3) || (tmode == 7)) {
     // 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,
@@ -3414,7 +3421,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,
@@ -3446,7 +3453,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,
@@ -3478,7 +3485,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,
@@ -3512,7 +3519,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,
@@ -3543,7 +3550,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,
@@ -3574,7 +3581,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,
@@ -3606,7 +3613,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,
@@ -3632,7 +3639,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,
@@ -3663,7 +3670,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,
@@ -3694,7 +3701,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,
@@ -3726,7 +3733,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,
@@ -3755,7 +3762,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,
@@ -3787,7 +3794,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,
@@ -3818,7 +3825,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,
@@ -3851,7 +3858,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/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c
index e7b0cc6d45eaa9d6a4b6bf28a20afde55a7fb96d..aaf8b13c823f5e5ebb4b5adb1ccc09f212d202ac 100644
--- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c
+++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c
@@ -5627,8 +5627,11 @@ uint8_t subframe2harq_pid(LTE_DL_FRAME_PARMS *frame_parms,uint32_t frame,uint8_t
     printf("dci_tools.c: subframe2_harq_pid, subframe %d for FDD \n",subframe);
     #endif
   */
+
+  uint8_t ret = 255;
+
   if (frame_parms->frame_type == FDD) {
-    return(((frame<<1)+subframe)&7);
+    ret = (((frame<<1)+subframe)&7);
   } else {
 
     switch (frame_parms->tdd_config) {
@@ -5641,17 +5644,17 @@ uint8_t subframe2harq_pid(LTE_DL_FRAME_PARMS *frame_parms,uint32_t frame,uint8_t
         switch (subframe) {
         case 2:
         case 3:
-          return(subframe-2);
+          ret = (subframe-2);
           break;
 
         case 7:
         case 8:
-          return(subframe-5);
+          ret = (subframe-5);
           break;
 
         default:
           LOG_E(PHY,"subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n",subframe,frame_parms->tdd_config);
-          return(255);
+          ret = (255);
           break;
         }
 
@@ -5661,72 +5664,78 @@ uint8_t subframe2harq_pid(LTE_DL_FRAME_PARMS *frame_parms,uint32_t frame,uint8_t
       if ((subframe!=2) && (subframe!=7)) {
         LOG_E(PHY,"subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n",subframe,frame_parms->tdd_config);
         mac_xface->macphy_exit("subframe2_harq_pid, Illegal subframe");
-        return(255);
+        ret = (255);
       }
 
-      return(subframe/7);
+      ret = (subframe/7);
       break;
 
     case 3:
       if ((subframe<2) || (subframe>4)) {
         LOG_E(PHY,"subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n",subframe,frame_parms->tdd_config);
-        return(255);
+        ret = (255);
       }
 
-      return(subframe-2);
+      ret = (subframe-2);
       break;
 
     case 4:
       if ((subframe<2) || (subframe>3)) {
         LOG_E(PHY,"subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n",subframe,frame_parms->tdd_config);
-        return(255);
+        ret = (255);
       }
 
-      return(subframe-2);
+      ret = (subframe-2);
       break;
 
     case 5:
       if (subframe!=2) {
         LOG_E(PHY,"subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n",subframe,frame_parms->tdd_config);
-        return(255);
+        ret = (255);
       }
 
-      return(subframe-2);
+      ret = (subframe-2);
       break;
 
     default:
       LOG_E(PHY,"subframe2_harq_pid, Unsupported TDD mode %d\n",frame_parms->tdd_config);
-      return(255);
+      ret = (255);
 
     }
   }
 
-  return(255);
+  if (ret == 255) {
+    LOG_E(PHY, "invalid harq_pid(%d) at SFN/SF = %d/%d\n", ret, frame, subframe);
+    mac_xface->macphy_exit("invalid harq_pid");
+  }
+  return ret;
 }
 
 uint8_t pdcch_alloc2ul_subframe(LTE_DL_FRAME_PARMS *frame_parms,uint8_t n)
 {
+  uint8_t ul_subframe = 255;
 
   if ((frame_parms->frame_type == TDD) &&
       (frame_parms->tdd_config == 1) &&
       ((n==1)||(n==6))) // tdd_config 0,1 SF 1,5
-    return((n+6)%10);
+    ul_subframe = ((n+6)%10);
   else if ((frame_parms->frame_type == TDD) &&
            (frame_parms->tdd_config == 6) &&
            ((n==0)||(n==1)||(n==5)||(n==6)))
-    return((n+7)%10);
+    ul_subframe = ((n+7)%10);
   else if ((frame_parms->frame_type == TDD) &&
            (frame_parms->tdd_config == 6) &&
            (n==9)) // tdd_config 6 SF 9
-    return((n+5)%10);
+    ul_subframe = ((n+5)%10);
   else
-    return((n+4)%10);
+    ul_subframe = ((n+4)%10);
 
+  LOG_D(PHY, "subframe %d: PUSCH subframe = %d\n", n, ul_subframe);
+  return ul_subframe;
 }
 
 uint8_t ul_subframe2pdcch_alloc_subframe(LTE_DL_FRAME_PARMS *frame_parms,uint8_t n)
 {
-
   if ((frame_parms->frame_type == TDD) &&
       (frame_parms->tdd_config == 1) &&
       ((n==7)||(n==2))) // tdd_config 0,1 SF 1,5
@@ -5746,21 +5755,25 @@ uint8_t ul_subframe2pdcch_alloc_subframe(LTE_DL_FRAME_PARMS *frame_parms,uint8_t
 
 uint32_t pdcch_alloc2ul_frame(LTE_DL_FRAME_PARMS *frame_parms,uint32_t frame, uint8_t n)
 {
+  uint32_t ul_frame = 255;
 
   if ((frame_parms->frame_type == TDD) &&
       (frame_parms->tdd_config == 1) &&
       ((n==1)||(n==6))) // tdd_config 0,1 SF 1,5
-    return(frame + (n==1 ? 0 : 1));
+    ul_frame = (frame + (n==1 ? 0 : 1));
   else if ((frame_parms->frame_type == TDD) &&
            (frame_parms->tdd_config == 6) &&
            ((n==0)||(n==1)||(n==5)||(n==6)))
-    return(frame + (n>=5 ? 1 : 0));
+    ul_frame = (frame + (n>=5 ? 1 : 0));
   else if ((frame_parms->frame_type == TDD) &&
            (frame_parms->tdd_config == 6) &&
            (n==9)) // tdd_config 6 SF 9
-    return(frame+1);
+    ul_frame = (frame+1);
   else
-    return(frame+(n>=6 ? 1 : 0));
+    ul_frame = (frame+(n>=6 ? 1 : 0));
+
+  LOG_D(PHY, "frame %d subframe %d: PUSCH frame = %d\n", frame, n, ul_frame);
+  return ul_frame;
 
 }
 
diff --git a/openair1/PHY/LTE_TRANSPORT/phich.c b/openair1/PHY/LTE_TRANSPORT/phich.c
index 9fcdc774cadb1e4af41348fdf80c29ae712380f4..100b508394e187bb300834aac856fb1abf5e3323 100644
--- a/openair1/PHY/LTE_TRANSPORT/phich.c
+++ b/openair1/PHY/LTE_TRANSPORT/phich.c
@@ -142,125 +142,134 @@ unsigned char subframe2_ul_harq(LTE_DL_FRAME_PARMS *frame_parms,unsigned char su
 
 uint8_t phich_frame2_pusch_frame(LTE_DL_FRAME_PARMS *frame_parms,frame_t frame,uint8_t subframe)
 {
+  uint8_t pusch_frame = 255;
   if (frame_parms->frame_type == FDD) {
-    return((subframe<4) ? (frame - 1) : frame);
+    pusch_frame = ((subframe<4) ? (frame - 1) : frame);
   } else {
     // Note this is not true, but it doesn't matter, the frame number is irrelevant for TDD!
-    return(frame);
+    pusch_frame = (frame);
   }
+
+  LOG_D(PHY, "frame %d subframe %d: PUSCH frame = %d\n", frame, subframe, pusch_frame);
+  return pusch_frame;
 }
 
 uint8_t phich_subframe2_pusch_subframe(LTE_DL_FRAME_PARMS *frame_parms,uint8_t subframe)
 {
+  uint8_t pusch_subframe = 255;
 
   if (frame_parms->frame_type == FDD)
-    return(subframe<4 ? (subframe+6) : (subframe-4));
+    pusch_subframe = (subframe<4 ? (subframe+6) : (subframe-4));
 
   switch (frame_parms->tdd_config) {
   case 0:
     if (subframe == 0)
-      return(3);
+      pusch_subframe = (3);
     else if (subframe == 5) {
-      return (8);
+      pusch_subframe = (8);
     } else if (subframe == 6)
-      return (2);
+      pusch_subframe = (2);
     else if (subframe == 1)
-      return (7);
+      pusch_subframe = (7);
     else {
       LOG_E(PHY, "phich.c: phich_subframe2_pusch_subframe, illegal subframe %d for tdd_config %d\n",
             subframe,frame_parms->tdd_config);
-      return(0);
+      pusch_subframe = (0);
     }
 
     break;
 
   case 1:
     if (subframe == 6)
-      return(2);
+      pusch_subframe = (2);
     else if (subframe == 9)
-      return (3);
+      pusch_subframe = (3);
     else if (subframe == 1)
-      return (7);
+      pusch_subframe = (7);
     else if (subframe == 4)
-      return (8);
+      pusch_subframe = (8);
     else {
       LOG_E(PHY,"phich.c: phich_subframe2_pusch_subframe, illegal subframe %d for tdd_config %d\n",
             subframe,frame_parms->tdd_config);
-      return(0);
+      pusch_subframe = (0);
     }
 
     break;
 
   case 2:
     if (subframe == 8)
-      return(2);
+      pusch_subframe = (2);
     else if (subframe == 3)
-      return (7);
+      pusch_subframe = (7);
     else {
       LOG_E(PHY,"phich.c: phich_subframe2_pusch_subframe, illegal subframe %d for tdd_config %d\n",
             subframe,frame_parms->tdd_config);
-      return(0);
+      pusch_subframe = (0);
     }
 
     break;
 
   case 3:
     if ( (subframe == 8) || (subframe == 9) ) {
-      return(subframe-6);
+      pusch_subframe = (subframe-6);
     } else if (subframe==0)
-      return(4);
+      pusch_subframe = (4);
     else {
       LOG_E(PHY,"phich.c: phich_subframe2_pusch_subframe, illegal subframe %d for tdd_config %d\n",
             subframe,frame_parms->tdd_config);
-      return(0);
+      pusch_subframe = (0);
     }
 
     break;
 
   case 4:
     if ( (subframe == 8) || (subframe == 9) ) {
-      return(subframe-6);
+      pusch_subframe = (subframe-6);
     } else {
       LOG_E(PHY,"phich.c: phich_subframe2_pusch_subframe, illegal subframe %d for tdd_config %d\n",
             subframe,frame_parms->tdd_config);
-      return(0);
+      pusch_subframe = (0);
     }
 
     break;
 
   case 5:
     if (subframe == 8) {
-      return(2);
+      pusch_subframe = (2);
     } else {
       LOG_E(PHY,"phich.c: phich_subframe2_pusch_subframe, illegal subframe %d for tdd_config %d\n",
             subframe,frame_parms->tdd_config);
-      return(0);
+      pusch_subframe = (0);
     }
 
     break;
 
   case 6:
     if (subframe == 6) {
-      return(2);
+      pusch_subframe = (2);
     } else if (subframe == 9) {
-      return(3);
+      pusch_subframe = (3);
     } else if (subframe == 0) {
-      return(4);
+      pusch_subframe = (4);
     } else if (subframe == 1) {
-      return(7);
+      pusch_subframe = (7);
     } else if (subframe == 5) {
-      return(8);
+      pusch_subframe = (8);
     } else {
       LOG_E(PHY,"phich.c: phich_subframe2_pusch_subframe, illegal subframe %d for tdd_config %d\n",
             subframe,frame_parms->tdd_config);
-      return(0);
+      pusch_subframe = (0);
     }
 
     break;
 
+  default:
+    LOG_E(PHY, "no implementation for TDD UL/DL-config = %d!\n", frame_parms->tdd_config);
+    pusch_subframe = (0);
   }
 
-  return(0);
+  LOG_D(PHY, "subframe  %d: PUSCH subframe = %d\n", subframe, pusch_subframe);
+  return pusch_subframe;
 }
 
 int check_pcfich(LTE_DL_FRAME_PARMS *frame_parms,uint16_t reg)
diff --git a/openair1/PHY/impl_defs_lte.h b/openair1/PHY/impl_defs_lte.h
index 7a30bff6abefa8ae8b0f4599cce5da4c9919994d..32fb08a2275dfddda4bd6b79621ab0cf2cf322d4 100644
--- a/openair1/PHY/impl_defs_lte.h
+++ b/openair1/PHY/impl_defs_lte.h
@@ -1098,6 +1098,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 a9cb8d0f10b79db306b2286473c058e9e6bb2a57..0c91d669fde3128c99ba1a93eca53e1e7259ef52 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 239a5e2f8d136adb0d3ec5b95e700363550686d4..b736cb7ae8f55d8ce83fb42dc693ddb579096419 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)
 {