diff --git a/openair1/PHY/LTE_TRANSPORT/phich.c b/openair1/PHY/LTE_TRANSPORT/phich.c
index d363d4dcf65faf9312a1dc70357f45eab7f5f6a8..5ebe555d4f510f8eb0f24a16c6e9c22cb5490d99 100644
--- a/openair1/PHY/LTE_TRANSPORT/phich.c
+++ b/openair1/PHY/LTE_TRANSPORT/phich.c
@@ -135,6 +135,17 @@ unsigned char subframe2_ul_harq(LTE_DL_FRAME_PARMS *frame_parms,unsigned char su
 
     break;
 
+  case 4:
+     if ( (subframe == 8) || (subframe == 9) ) {
+       return(subframe-8);
+     } else {
+       LOG_E(PHY,"phich.c: subframe2_ul_harq, illegal subframe %d for tdd_config %d\n",
+             subframe,frame_parms->tdd_config);
+       return(0);
+     }
+
+     break;
+
   }
 
   return(0);
diff --git a/openair1/SCHED/phy_procedures_lte_common.c b/openair1/SCHED/phy_procedures_lte_common.c
index 314f934a8112e5c689ddba83c7217089a5fade74..07793413340866a16b5e36ace4ed0f4f08222dda 100644
--- a/openair1/SCHED/phy_procedures_lte_common.c
+++ b/openair1/SCHED/phy_procedures_lte_common.c
@@ -105,7 +105,47 @@ void get_Msg3_alloc(LTE_DL_FRAME_PARMS *frame_parms,
         *frame = (current_frame+2) & 1023;
         break;
       }
-    }
+    } else if (frame_parms->tdd_config == 4) {
+        switch (current_subframe) {
+
+        case 0:
+        case 4:
+        case 5:
+        case 6:
+          *subframe = 2;
+          *frame = (current_frame+1) & 1023;
+          break;
+
+        case 7:
+          *subframe = 3;
+          *frame = (current_frame+1) & 1023;
+          break;
+
+        case 8:
+        case 9:
+          *subframe = 2;
+          *frame = (current_frame+2) & 1023;
+          break;
+        }
+      } else if (frame_parms->tdd_config == 5) {
+          switch (current_subframe) {
+
+          case 0:
+          case 4:
+          case 5:
+          case 6:
+            *subframe = 2;
+            *frame = (current_frame+1) & 1023;
+            break;
+
+          case 7:
+          case 8:
+          case 9:
+            *subframe = 2;
+            *frame = (current_frame+2) & 1023;
+            break;
+          }
+        }
   }
 }
 
@@ -137,6 +177,13 @@ void get_Msg3_alloc_ret(LTE_DL_FRAME_PARMS *frame_parms,
       // original PUSCH in 3, PHICH in 9, ret in 3 next frame
       // original PUSCH in 4, PHICH in 0, ret in 4 next frame
       *frame=(current_frame+1) & 1023;
+    } else if (frame_parms->tdd_config == 4) {
+        // original PUSCH in 2, PHICH in 8, ret in 2 next frame
+        // original PUSCH in 3, PHICH in 9, ret in 3 next frame
+        *frame=(current_frame+1) & 1023;
+    } else if (frame_parms->tdd_config == 5) {
+        // original PUSCH in 2, PHICH in 8, ret in 2 next frame
+        *frame=(current_frame+1) & 1023;
     }
   }
 }
@@ -253,6 +300,24 @@ unsigned char ul_ACK_subframe2_dl_subframe(LTE_DL_FRAME_PARMS *frame_parms,unsig
 
       break;
 
+    case 4:
+          if (subframe == 2) {  // ACK subframes 0, 4 and 5
+            //if (ACK_index==2)
+            //  return(1); TBC
+            if (ACK_index==2)
+            return(0);
+
+            return(4+ACK_index);
+          } else if (subframe == 3) { // ACK subframes 6, 7 8 and 9
+            return(6+ACK_index);  // To be updated
+          } else {
+            LOG_E(PHY,"phy_procedures_lte_common.c/subframe2_dl_harq_pid: illegal subframe %d for tdd_config %d\n",
+                  subframe,frame_parms->tdd_config);
+            return(0);
+          }
+
+          break;
+
     case 1:
       if (subframe == 2) {  // ACK subframes 5 and 6
         return(5+ACK_index);
@@ -297,6 +362,30 @@ unsigned char ul_ACK_subframe2_M(LTE_DL_FRAME_PARMS *frame_parms,unsigned char s
 
       break;
 
+    case 4:
+          if (subframe == 2) {  // ACK subframes 0,4 and 5
+            return(3); // should be 4
+          } else if (subframe == 3) { // ACK subframes 6,7,8 and 9
+            return(4);
+          } else {
+            LOG_E(PHY,"phy_procedures_lte_common.c/subframe2_dl_harq_pid: illegal subframe %d for tdd_config %d\n",
+                  subframe,frame_parms->tdd_config);
+            return(0);
+          }
+
+          break;
+
+    case 5:
+              if (subframe == 2) {  // ACK subframes 0,3,4,5,6,7,8 and 9
+                return(8); // should be 3
+              } else {
+                LOG_E(PHY,"phy_procedures_lte_common.c/subframe2_dl_harq_pid: illegal subframe %d for tdd_config %d\n",
+                      subframe,frame_parms->tdd_config);
+                return(0);
+              }
+
+              break;
+
     case 1:
       if (subframe == 2) {  // ACK subframes 5 and 6
         return(2);
@@ -331,7 +420,7 @@ uint8_t get_reset_ack(LTE_DL_FRAME_PARMS *frame_parms,
                 uint8_t do_reset) // 1 to reset ACK/NACK status : 0 otherwise
 {
   uint8_t status=0;
-  uint8_t subframe_ul=0xff, subframe_dl0=0xff, subframe_dl1=0xff;
+  uint8_t subframe_ul=0xff, subframe_dl0=0xff, subframe_dl1=0xff,subframe_dl2=0xff, subframe_dl3=0xff;
 
   //  printf("get_ack: SF %d\n",subframe);
   if (frame_parms->frame_type == FDD) {
@@ -485,6 +574,63 @@ uint8_t get_reset_ack(LTE_DL_FRAME_PARMS *frame_parms,
 
       break;
 
+    case 4:
+          if (subframe_tx == 2) {  // ACK subframes 4, 5 and 0
+            subframe_dl0 = 4;
+            subframe_dl1 = 5;
+            subframe_dl2 = 0;
+            subframe_ul  = 2;
+            //printf("subframe_tx 2, TDD config 3: harq_ack[5] = %d (%d),harq_ack[6] = %d (%d)\n",harq_ack[5].ack,harq_ack[5].send_harq_status,harq_ack[6].ack,harq_ack[6].send_harq_status);
+          } else if (subframe_tx == 3) { // ACK subframes 6, 7 8 and 9
+            subframe_dl0 = 6;
+            subframe_dl1 = 7;
+            subframe_dl2 = 8;
+            subframe_dl3 = 9;
+            subframe_ul  = 3;
+            //printf("Subframe 3, TDD config 3: harq_ack[7] = %d,harq_ack[8] = %d\n",harq_ack[7].ack,harq_ack[8].ack);
+            //printf("status %d : o_ACK (%d,%d)\n", status,o_ACK[0],o_ACK[1]);
+          } else {
+            LOG_E(PHY,"phy_procedures_lte.c: get_ack, illegal subframe_tx %d for tdd_config %d\n",
+                  subframe_tx,frame_parms->tdd_config);
+            return(0);
+          }
+
+          // report ACK/NACK status
+          o_ACK[cw_idx] = 0;
+          if (harq_ack[subframe_dl0].send_harq_status == 1)
+            o_ACK[cw_idx] = harq_ack[subframe_dl0].ack;
+
+          if (harq_ack[subframe_dl1].send_harq_status == 1)
+            o_ACK[cw_idx] &= harq_ack[subframe_dl1].ack;
+
+          if (harq_ack[subframe_dl2].send_harq_status == 1)
+            o_ACK[cw_idx] &= harq_ack[subframe_dl2].ack;
+
+          if (harq_ack[subframe_dl3].send_harq_status == 1)
+            o_ACK[cw_idx] &= harq_ack[subframe_dl3].ack;
+
+          pN_bundled[0] = harq_ack[subframe_rx].vDAI_UL;
+          status = harq_ack[subframe_dl0].send_harq_status + harq_ack[subframe_dl1].send_harq_status + harq_ack[subframe_dl2].send_harq_status + harq_ack[subframe_dl3].send_harq_status;
+
+          LOG_I(PHY,"TDD Config3 UL Sfn %d, dl Sfn0 %d status %d o_Ack %d, dl Sfn1 %d status %d o_Ack %d dl Sfn2 %d status %d o_Ack %d dl Sfn3 %d status %d o_Ack %d subframe_rx %d N_bundled %d status %d\n",
+                subframe_tx, subframe_dl0, harq_ack[subframe_dl0].send_harq_status,harq_ack[subframe_dl0].ack,
+              subframe_dl1, harq_ack[subframe_dl1].send_harq_status,harq_ack[subframe_dl1].ack,
+              subframe_dl2, harq_ack[subframe_dl2].send_harq_status,harq_ack[subframe_dl2].ack,
+              subframe_dl3, harq_ack[subframe_dl3].send_harq_status,harq_ack[subframe_dl3].ack,subframe_rx, pN_bundled[0], status);
+          if (do_reset) {
+            // reset ACK/NACK status
+            harq_ack[subframe_dl0].ack = 2;
+            harq_ack[subframe_dl1].ack = 2;
+            harq_ack[subframe_dl2].ack = 2;
+            harq_ack[subframe_dl3].ack = 2;
+            harq_ack[subframe_dl0].send_harq_status = 0;
+            harq_ack[subframe_dl1].send_harq_status = 0;
+            harq_ack[subframe_dl2].send_harq_status = 0;
+            harq_ack[subframe_dl3].send_harq_status = 0;
+          }
+
+          break;
+
     }
   }
 
@@ -609,6 +755,29 @@ lte_subframe_t subframe_select(LTE_DL_FRAME_PARMS *frame_parms,unsigned char sub
       return(255);
     }
 
+  case 4:
+      if  ((subframe<1) || (subframe>=4))
+        return(SF_DL);
+      else if ((subframe>1) && (subframe < 4))
+        return(SF_UL);
+      else if (subframe==1)
+        return (SF_S);
+      else  {
+        LOG_E(PHY,"[PHY_PROCEDURES_LTE] Unknown subframe number\n");
+        return(255);
+      }
+
+  case 5:
+        if  ((subframe<1) || (subframe>=3))
+          return(SF_DL);
+        else if ((subframe>1) && (subframe < 3))
+          return(SF_UL);
+        else if (subframe==1)
+          return (SF_S);
+        else  {
+          LOG_E(PHY,"[PHY_PROCEDURES_LTE] Unknown subframe number\n");
+          return(255);
+        }
     break;
 
   default:
@@ -683,13 +852,13 @@ unsigned int is_phich_subframe(LTE_DL_FRAME_PARMS *frame_parms,unsigned char sub
       break;
 
     case 4:
-      if ((subframe == 0) || (subframe == 8) )
+      if ((subframe == 8) || (subframe == 9) )
         return(1);
 
       break;
 
     case 5:
-      if (subframe == 0)
+      if (subframe == 8)
         return(1);
 
       break;
diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c
index 663dc33b49696e294882b89875fedbb67741fa7c..cba893eafbc87adb6e87a1347b1822b340fc5333 100644
--- a/openair1/SCHED/phy_procedures_lte_ue.c
+++ b/openair1/SCHED/phy_procedures_lte_ue.c
@@ -700,13 +700,14 @@ uint16_t get_n1_pucch(PHY_VARS_UE *ue,
 {
 
   LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
-  uint8_t nCCE0,nCCE1,harq_ack1,harq_ack0;
+  uint8_t nCCE0,nCCE1,nCCE2,nCCE3,harq_ack1,harq_ack0,harq_ack3,harq_ack2;
   ANFBmode_t bundling_flag;
-  uint16_t n1_pucch0=0,n1_pucch1=0;
+  uint16_t n1_pucch0=0,n1_pucch1=0,n1_pucch2=0,n1_pucch3=0,n1_pucch_inter,pucch_sel_inter;
   static uint8_t candidate_dl[9]; // which downlink(s) the current ACK/NACK is associating to
   uint8_t last_dl=0xff; // the last downlink with valid DL-DCI. for calculating the PUCCH resource index
   int sf;
   int M;
+  uint8_t ack_counter=0;
   // clear this, important for case where n1_pucch selection is not used
   int subframe=proc->subframe_tx;
 
@@ -726,10 +727,10 @@ uint16_t get_n1_pucch(PHY_VARS_UE *ue,
 #ifdef DEBUG_PHY_PROC
 
     if (bundling_flag==bundling) {
-      LOG_D(PHY,"[UE%d] Frame %d subframe %d : get_n1_pucch, bundling, SR %d/%d\n",ue->Mod_id,proc->frame_tx,subframe,SR,
+      LOG_I(PHY,"[UE%d] Frame %d subframe %d : get_n1_pucch, bundling, SR %d/%d\n",ue->Mod_id,proc->frame_tx,subframe,SR,
             ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex);
     } else {
-      LOG_D(PHY,"[UE%d] Frame %d subframe %d : get_n1_pucch, multiplexing, SR %d/%d\n",ue->Mod_id,proc->frame_tx,subframe,SR,
+      LOG_I(PHY,"[UE%d] Frame %d subframe %d : get_n1_pucch, multiplexing, SR %d/%d\n",ue->Mod_id,proc->frame_tx,subframe,SR,
             ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex);
     }
 
@@ -835,6 +836,11 @@ uint16_t get_n1_pucch(PHY_VARS_UE *ue,
       if (ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[5+last_dl].send_harq_status>0)  // n-6 // subframe 5 is to be ACK/NAKed
         harq_ack0 = ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[5+last_dl].ack;
 
+      LOG_D(PHY,"SFN/SF %d/%d calculating n1_pucch cce0=%d n1_pucch0=%d cce1=%d n1_pucch1=%d\n",
+                                      proc->frame_tx%1024,
+                                      proc->subframe_tx,
+                                      nCCE0,n1_pucch0,
+                                      nCCE1,n1_pucch1);
 
       if (harq_ack1!=2) { // n-6 // subframe 6,8,0 and maybe 5,7,9 is to be ACK/NAKed
 
@@ -891,6 +897,243 @@ uint16_t get_n1_pucch(PHY_VARS_UE *ue,
 
       break;
 
+    case 4:  // DL:S:UL:UL:DL:DL:DL:DL:DL:DL
+          // in this configuration we have M=4 from pg 68 of 36.213 (v8.6)
+          // Note: this doesn't allow using subframe 1 for PDSCH transmission!!! (i.e. SF 1 cannot be acked in SF 2)
+          // set ACK/NAKs to DTX
+          harq_ack3 = 2; // DTX
+          harq_ack2 = 2; // DTX
+          harq_ack1 = 2; // DTX
+          harq_ack0 = 2; // DTX
+          // This is the offset for a particular subframe (2,3,4) => (0,2,4)
+          //last_dl = (subframe-2)<<1;
+          if (subframe == 2) {
+          // i=0
+          //nCCE0 = ue->pdcch_vars[proc->subframe_rx & 0x1][eNB_id]->nCCE[2+subframe];
+          nCCE0 = ue->pdcch_vars[proc->subframe_rx & 0x1][eNB_id]->nCCE[(8+subframe)%10];
+          n1_pucch0 = 2*get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0+ frame_parms->pucch_config_common.n1PUCCH_AN;
+          // i=1
+          nCCE1 = ue->pdcch_vars[proc->subframe_rx & 0x1][eNB_id]->nCCE[2+subframe];
+          n1_pucch1 = get_Np(frame_parms->N_RB_DL,nCCE1,0) + get_Np(frame_parms->N_RB_DL,nCCE1,1) + nCCE1 + frame_parms->pucch_config_common.n1PUCCH_AN;
+          // i=2
+          nCCE2 = ue->pdcch_vars[proc->subframe_rx & 0x1][eNB_id]->nCCE[(8+subframe)%10];
+          n1_pucch2 = 2*get_Np(frame_parms->N_RB_DL,nCCE2,1) + nCCE2+ frame_parms->pucch_config_common.n1PUCCH_AN;
+          // i=3
+          //nCCE3 = ue->pdcch_vars[proc->subframe_rx & 0x1][eNB_id]->nCCE[(9+subframe)%10];
+          //n1_pucch3 = get_Np(frame_parms->N_RB_DL,nCCE3,1) + nCCE3 + frame_parms->pucch_config_common.n1PUCCH_AN;
+
+          // set ACK/NAK to values if not DTX
+          if (ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[(8+subframe)%10].send_harq_status>0)  // n-6 // subframe 6 is to be ACK/NAKed
+            harq_ack0 = ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[(8+subframe)%10].ack;
+
+          if (ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[2+subframe].send_harq_status>0)  // n-6 // subframe 5 is to be ACK/NAKed
+            harq_ack1 = ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[2+subframe].ack;
+
+          if (ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[3+subframe].send_harq_status>0)  // n-6 // subframe 6 is to be ACK/NAKed
+            harq_ack2 = ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[3+subframe].ack;
+
+          //if (ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[(9+subframe)%10].send_harq_status>0)  // n-6 // subframe 5 is to be ACK/NAKed
+            //harq_ack3 = ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[(9+subframe)%10].ack;
+          //LOG_I(PHY,"SFN/SF %d/%d calculating n1_pucch cce0=%d n1_pucch0=%d cce1=%d n1_pucch1=%d cce2=%d n1_pucch2=%d\n",
+          //                      proc->frame_tx%1024,
+          //                      proc->subframe_tx,
+          //                      nCCE0,n1_pucch0,
+          //                      nCCE1,n1_pucch1, nCCE2, n1_pucch2);
+          }else if (subframe == 3) {
+          // i=0
+
+          nCCE0 = ue->pdcch_vars[proc->subframe_rx & 0x1][eNB_id]->nCCE[4+subframe];
+          n1_pucch0 = 3*get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0+ frame_parms->pucch_config_common.n1PUCCH_AN;
+          // i=1
+          nCCE1 = ue->pdcch_vars[proc->subframe_rx & 0x1][eNB_id]->nCCE[5+subframe];
+          n1_pucch1 = 2*get_Np(frame_parms->N_RB_DL,nCCE1,0) + get_Np(frame_parms->N_RB_DL,nCCE1,1) + nCCE1 + frame_parms->pucch_config_common.n1PUCCH_AN;
+          // i=2
+          nCCE2 = ue->pdcch_vars[proc->subframe_rx & 0x1][eNB_id]->nCCE[(6+subframe)];
+          n1_pucch2 = get_Np(frame_parms->N_RB_DL,nCCE2,0) + 2*get_Np(frame_parms->N_RB_DL,nCCE2,1) + nCCE2+ frame_parms->pucch_config_common.n1PUCCH_AN;
+          // i=3
+          nCCE3 = ue->pdcch_vars[proc->subframe_rx & 0x1][eNB_id]->nCCE[(3+subframe)];
+          n1_pucch3 = 3*get_Np(frame_parms->N_RB_DL,nCCE3,1) + nCCE3 + frame_parms->pucch_config_common.n1PUCCH_AN;
+
+          // set ACK/NAK to values if not DTX
+          if (ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[4+subframe].send_harq_status>0)  // n-6 // subframe 6 is to be ACK/NAKed
+          harq_ack0 = ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[4+subframe].ack;
+
+          if (ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[5+subframe].send_harq_status>0)  // n-6 // subframe 5 is to be ACK/NAKed
+          harq_ack1 = ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[5+subframe].ack;
+
+          if (ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[(6+subframe)].send_harq_status>0)  // n-6 // subframe 6 is to be ACK/NAKed
+          harq_ack2 = ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[(6+subframe)].ack;
+
+          if (ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[(3+subframe)].send_harq_status>0)  // n-6 // subframe 5 is to be ACK/NAKed
+          harq_ack3 = ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[(3+subframe)].ack;
+          }
+
+          //LOG_I(PHY,"SFN/SF %d/%d calculating n1_pucch cce0=%d n1_pucch0=%d harq_ack0=%d cce1=%d n1_pucch1=%d harq_ack1=%d cce2=%d n1_pucch2=%d harq_ack2=%d cce3=%d n1_pucch3=%d harq_ack3=%d bundling_flag=%d\n",
+          //                                proc->frame_tx%1024,
+          //                                proc->subframe_tx,
+          //                                nCCE0,n1_pucch0,harq_ack0,
+          //                                nCCE1,n1_pucch1,harq_ack1, nCCE2, n1_pucch2, harq_ack2,
+          //                                nCCE3, n1_pucch3, harq_ack3, bundling_flag);
+
+          if ((bundling_flag==bundling)&&(SR == 0)) {  // This is for bundling without SR,
+             if ((harq_ack0!=2) ) {
+                b[0] = harq_ack0;
+                n1_pucch_inter = n1_pucch0;
+                pucch_sel_inter = 0;
+             }
+             if ((harq_ack1!=2) ) {
+                b[0] = b[0]&harq_ack1;
+                n1_pucch_inter = n1_pucch1;
+                pucch_sel_inter = 1;
+             }
+             if ((harq_ack2!=2) ) {
+                b[0] = b[0]&harq_ack2;
+                n1_pucch_inter = n1_pucch2;
+                pucch_sel_inter = 2;
+             }
+             if ((harq_ack3!=2) ) {
+                b[0] = b[0]&harq_ack3;
+                n1_pucch_inter = n1_pucch3;
+                pucch_sel_inter = 3;
+             }
+
+             if (subframe == 3) {
+                n1_pucch_inter = n1_pucch2;
+             } else if (subframe == 2) {
+                n1_pucch_inter = n1_pucch2;
+             }
+
+             //LOG_I(PHY,"SFN/SF %d/%d calculating n1_pucch n1_pucch_inter=%d pucch_sel_inter=%d b[0]=%d b[1]=%d \n",
+             //                                           proc->frame_tx%1024,
+             //                                           proc->subframe_tx,n1_pucch_inter,
+             //                                           pucch_sel_inter,b[0],b[1]);
+
+              return(n1_pucch_inter);
+
+            } else if ((bundling_flag==multiplexing)&&(SR==0)) { // Table 10.1
+
+              if ((harq_ack0 == 1) && (harq_ack1 == 1) && (harq_ack2 == 1) && (harq_ack3 == 1)) {
+                b[1] = 1;
+                b[0] = 1;
+                return(n1_pucch1);
+              } else if ((harq_ack0 == 1) && (harq_ack1 == 1) && (harq_ack2 == 1) && ((harq_ack3 == 2) || (harq_ack3 == 0))) {
+                b[0] = 1;
+                b[1] = 0;
+                return(n1_pucch1);
+              } else if (((harq_ack0 == 0) || (harq_ack0 == 2)) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && (harq_ack2 == 0) && (harq_ack3 == 2)) {
+                b[1] = 1;
+                b[0] = 1;
+                return(n1_pucch2);
+              } else if ((harq_ack0 == 1) && (harq_ack1 == 1) && ((harq_ack2 == 2) || (harq_ack2 == 0)) && (harq_ack3 == 1)) {
+                b[1] = 1;
+                b[0] = 0;
+                return(n1_pucch1);
+              } else if ((harq_ack0 == 0) && (harq_ack1 == 2) && (harq_ack2 == 2) && (harq_ack3 == 2)) {
+                b[1] = 1;
+                b[0] = 0;
+                return(n1_pucch0);
+              } else if ((harq_ack0 == 1) && (harq_ack1 == 1) && ((harq_ack2 == 2) || (harq_ack2 == 0)) && ((harq_ack3 == 2) || (harq_ack3 == 0))) {
+                b[1] = 1;
+                b[0] = 0;
+                return(n1_pucch1);
+              } else if ((harq_ack0 == 1) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && (harq_ack2 == 1) && (harq_ack3 == 1)) {
+                b[0] = 0;
+                b[1] = 1;
+                return(n1_pucch3);
+              } else if (((harq_ack0 == 0) || (harq_ack0 == 2)) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && ((harq_ack2 == 2) || (harq_ack2 == 0)) && (harq_ack3 == 0)) {
+                b[1] = 1;
+                b[0] = 1;
+                return(n1_pucch3);
+              } else if ((harq_ack0 == 1) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && (harq_ack2 == 1) && ((harq_ack3 == 2) || (harq_ack3 == 0))) {
+                b[0] = 0;
+                b[1] = 1;
+                return(n1_pucch2);
+              } else if ((harq_ack0 == 1) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && ((harq_ack2 == 2) || (harq_ack2 == 0)) && (harq_ack3 == 1)) {
+                b[0] = 0;
+                b[1] = 1;
+                return(n1_pucch0);
+              } else if ((harq_ack0 == 1) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && ((harq_ack2 == 2) || (harq_ack2 == 0)) && ((harq_ack3 == 2) || (harq_ack3 == 0))) {
+                b[0] = 0;
+                b[1] = 1;
+                return(n1_pucch0);
+              } else if (((harq_ack0 == 2) || (harq_ack0 == 0)) && (harq_ack1 == 1) && (harq_ack2 == 1) && (harq_ack3 == 1)) {
+                b[0] = 0;
+                b[1] = 1;
+                return(n1_pucch3);
+              } else if (((harq_ack0 == 2) || (harq_ack0 == 0)) && (harq_ack1 == 0) && (harq_ack2 == 2) && (harq_ack3 == 2)) {
+                b[0] = 0;
+                b[1] = 0;
+                return(n1_pucch1);
+              } else if (((harq_ack0 == 2) || (harq_ack0 == 0)) && (harq_ack1 == 1) && (harq_ack2 == 1) && ((harq_ack3 == 2) || (harq_ack3 == 0))) {
+                b[0] = 1;
+                b[1] = 0;
+                return(n1_pucch2);
+              } else if (((harq_ack0 == 2) || (harq_ack0 == 0)) && (harq_ack1 == 1) && ((harq_ack2 == 2) || (harq_ack2 == 0)) && (harq_ack3 == 1)) {
+                b[0] = 1;
+                b[1] = 0;
+                return(n1_pucch3);
+              } else if (((harq_ack0 == 2) || (harq_ack0 == 0)) && (harq_ack1 == 1) && ((harq_ack2 == 2) || (harq_ack2 == 0)) && ((harq_ack3 == 2) || (harq_ack3 == 0))) {
+                b[0] = 0;
+                b[1] = 1;
+                return(n1_pucch1);
+              } else if (((harq_ack0 == 2) || (harq_ack0 == 0)) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && (harq_ack2 == 1) && (harq_ack3 == 1)) {
+                b[0] = 0;
+                b[1] = 1;
+                return(n1_pucch3);
+              } else if (((harq_ack0 == 2) || (harq_ack0 == 0)) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && (harq_ack2 == 1) && ((harq_ack3 == 2) || (harq_ack3 == 0))) {
+                b[0] = 0;
+                b[1] = 0;
+                return(n1_pucch2);
+              } else if (((harq_ack0 == 2) || (harq_ack0 == 0)) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && (harq_ack3 == 1) && ((harq_ack2 == 2) || (harq_ack2 == 0))) {
+                b[0] = 0;
+                b[1] = 0;
+                return(n1_pucch3);
+                }
+
+            } else if (SR==1) { // SR and 0,1,or 2 ACKS, (first 3 entries in Table 7.3-1 of 36.213)
+              // this should be number of ACKs (including
+              if (harq_ack0==1)
+                 ack_counter ++;
+              if (harq_ack1==1)
+                 ack_counter ++;
+              if (harq_ack2==1)
+                 ack_counter ++;
+              if (harq_ack3==1)
+                 ack_counter ++;
+
+            switch (ack_counter) {
+               case 0:
+                 b[0] = 0;
+                 b[1] = 0;
+               break;
+
+               case 1:
+                 b[0] = 1;
+                 b[1] = 1;
+               break;
+
+               case 2:
+                 b[0] = 1;
+                 b[1] = 0;
+               break;
+
+               case 3:
+                 b[0] = 0;
+                 b[1] = 1;
+               break;
+
+               case 4:
+                 b[0] = 1;
+                 b[1] = 1;
+               break;
+            }
+
+            ack_counter = 0;
+            return(ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex);
+          }
+
+          break;
+
     }  // switch tdd_config
   }