diff --git a/openair1/PHY/INIT/lte_init.c b/openair1/PHY/INIT/lte_init.c
index 9adbe319160de019788c8d7db2d1d6c7430b341b..1a4feb0becd9983b4c6080a0cb18a56458cfdaa5 100644
--- a/openair1/PHY/INIT/lte_init.c
+++ b/openair1/PHY/INIT/lte_init.c
@@ -52,6 +52,7 @@
 #include "UTIL/LOG/vcd_signal_dumper.h"
 //#define DEBUG_PHY
 #include "assertions.h"
+#include <math.h>
 
 #ifdef EXMIMO
 extern openair0_rf_map rf_map[MAX_NUM_CCs];
@@ -127,6 +128,8 @@ void phy_config_sib2_eNB(uint8_t Mod_id,
 {
 
   LTE_DL_FRAME_PARMS *lte_frame_parms = &PHY_vars_eNB_g[Mod_id][CC_id]->lte_frame_parms;
+  LTE_eNB_UE_stats *eNB_UE_stats      = PHY_vars_eNB_g[Mod_id][CC_id]->eNB_UE_stats;
+  int32_t rx_total_gain_eNB_dB        = PHY_vars_eNB_g[Mod_id][CC_id]->rx_total_gain_eNB_dB;
   int i;
 
   LOG_D(PHY,"[eNB%d] CCid %d Frame %d: Applying radioResourceConfigCommon\n",Mod_id,CC_id,PHY_vars_eNB_g[Mod_id][CC_id]->proc[8].frame_tx);
@@ -204,6 +207,9 @@ void phy_config_sib2_eNB(uint8_t Mod_id,
   lte_frame_parms->ul_power_control_config_common.p0_NominalPUSCH       = radioResourceConfigCommon->uplinkPowerControlCommon.p0_NominalPUSCH;
   lte_frame_parms->ul_power_control_config_common.alpha                 = radioResourceConfigCommon->uplinkPowerControlCommon.alpha;
   lte_frame_parms->ul_power_control_config_common.p0_NominalPUCCH       = radioResourceConfigCommon->uplinkPowerControlCommon.p0_NominalPUCCH;
+
+
+
   lte_frame_parms->ul_power_control_config_common.deltaPreambleMsg3     = radioResourceConfigCommon->uplinkPowerControlCommon.deltaPreambleMsg3;
   lte_frame_parms->ul_power_control_config_common.deltaF_PUCCH_Format1  = radioResourceConfigCommon->uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format1;
   lte_frame_parms->ul_power_control_config_common.deltaF_PUCCH_Format1b  = radioResourceConfigCommon->uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format1b;
diff --git a/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c b/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c
index dcef22dc998a7a876e0481884ebfd115813039b1..0fa0fc4ce1a0cf7a018db210d1963b661ce3d9d8 100644
--- a/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c
+++ b/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c
@@ -231,12 +231,12 @@ void ue_rrc_measurements(PHY_VARS_UE *phy_vars_ue,
               phy_vars_ue->PHY_measurements.n0_power[aarx] += (((int32_t)rxF_pss[-66]*rxF_pss[-66])+((int32_t)rxF_pss[-65]*rxF_pss[-65]));
 	      //              phy_vars_ue->PHY_measurements.n0_power[aarx] += (((int32_t)rxF_pss[-64]*rxF_pss[-64])+((int32_t)rxF_pss[-63]*rxF_pss[-63]));
 	      //	      printf("pssm32 %d\n",phy_vars_ue->PHY_measurements.n0_power[aarx]);
-              phy_vars_ue->PHY_measurements.n0_power_dB[aarx] = (unsigned short) dB_fixed(phy_vars_ue->PHY_measurements.n0_power[aarx]*phy_vars_ue->lte_frame_parms.ofdm_symbol_size/12);
+              phy_vars_ue->PHY_measurements.n0_power_dB[aarx] = (unsigned short) dB_fixed(phy_vars_ue->PHY_measurements.n0_power[aarx]/12);
               phy_vars_ue->PHY_measurements.n0_power_tot +=  phy_vars_ue->PHY_measurements.n0_power[aarx];
             }
 
-            phy_vars_ue->PHY_measurements.n0_power_tot_dB = (unsigned short) dB_fixed(phy_vars_ue->PHY_measurements.n0_power_tot/(12*aarx*phy_vars_ue->lte_frame_parms.ofdm_symbol_size));
-            phy_vars_ue->PHY_measurements.n0_power_tot_dBm = phy_vars_ue->PHY_measurements.n0_power_tot_dB - phy_vars_ue->rx_total_gain_dB;
+	    phy_vars_ue->PHY_measurements.n0_power_tot_dB = (unsigned short) dB_fixed(phy_vars_ue->PHY_measurements.n0_power_tot/(12*aarx));
+	    phy_vars_ue->PHY_measurements.n0_power_tot_dBm = phy_vars_ue->PHY_measurements.n0_power_tot_dB - phy_vars_ue->rx_total_gain_dB - dB_fixed(phy_vars_ue->lte_frame_parms.ofdm_symbol_size);
 	  }
         }
 	else if ((phy_vars_ue->lte_frame_parms.frame_type == TDD) &&
@@ -263,11 +263,11 @@ void ue_rrc_measurements(PHY_VARS_UE *phy_vars_ue,
 	      phy_vars_ue->PHY_measurements.n0_power[aarx] += (((int32_t)rxF_sss[2+66]*rxF_sss[2+66])+((int32_t)rxF_sss[2+65]*rxF_sss[2+65]));
 	      //	      phy_vars_ue->PHY_measurements.n0_power[aarx] += (((int32_t)rxF_sss[2+64]*rxF_sss[2+64])+((int32_t)rxF_sss[2+63]*rxF_sss[2+63]));
 	      
-	      phy_vars_ue->PHY_measurements.n0_power_dB[aarx] = (unsigned short) dB_fixed(phy_vars_ue->PHY_measurements.n0_power[aarx]/(6*phy_vars_ue->lte_frame_parms.ofdm_symbol_size));
+	      phy_vars_ue->PHY_measurements.n0_power_dB[aarx] = (unsigned short) dB_fixed(phy_vars_ue->PHY_measurements.n0_power[aarx]/(6));
 	      phy_vars_ue->PHY_measurements.n0_power_tot +=  phy_vars_ue->PHY_measurements.n0_power[aarx];	  
 	    }	      
-	    phy_vars_ue->PHY_measurements.n0_power_tot_dB = (unsigned short) dB_fixed(phy_vars_ue->PHY_measurements.n0_power_tot/(6*aarx*phy_vars_ue->lte_frame_parms.ofdm_symbol_size));
-	    phy_vars_ue->PHY_measurements.n0_power_tot_dBm = phy_vars_ue->PHY_measurements.n0_power_tot_dB - phy_vars_ue->rx_total_gain_dB;
+	    phy_vars_ue->PHY_measurements.n0_power_tot_dB = (unsigned short) dB_fixed(phy_vars_ue->PHY_measurements.n0_power_tot/(6*aarx));
+	    phy_vars_ue->PHY_measurements.n0_power_tot_dBm = phy_vars_ue->PHY_measurements.n0_power_tot_dB - phy_vars_ue->rx_total_gain_dB - dB_fixed(phy_vars_ue->lte_frame_parms.ofdm_symbol_size);
 	      
 	    
 	  }
@@ -450,37 +450,6 @@ void lte_ue_measurements(PHY_VARS_UE *phy_vars_ue,
     break;
   }
 
-  /*  // DONE NOW in ue_rrc_measurements
-  if (abstraction_flag!=0) {
-    phy_vars_ue->PHY_measurements.n0_power_tot = 0;
-    for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
-  phy_vars_ue->PHY_measurements.n0_power[aarx] = pow(10.0,phy_vars_ue->N0/10.0)*pow(10.0,((double)phy_vars_ue->rx_total_gain_dB)/10.0);
-  phy_vars_ue->PHY_measurements.n0_power_dB[aarx] = (unsigned short) dB_fixed(phy_vars_ue->PHY_measurements.n0_power[aarx]);
-  phy_vars_ue->PHY_measurements.n0_power_tot +=  phy_vars_ue->PHY_measurements.n0_power[aarx];
-    }
-    phy_vars_ue->PHY_measurements.n0_power_tot_dB = (unsigned short) dB_fixed(phy_vars_ue->PHY_measurements.n0_power_tot);
-    phy_vars_ue->PHY_measurements.n0_power_tot_dBm = phy_vars_ue->PHY_measurements.n0_power_tot_dB - phy_vars_ue->rx_total_gain_dB;
-  }
-  else if (N0_symbol != 0) {
-    phy_vars_ue->PHY_measurements.n0_power_tot = 0;
-    for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
-  #ifndef HW_PREFIX_REMOVAL
-  phy_vars_ue->PHY_measurements.n0_power[aarx] = signal_energy(&phy_vars_ue->lte_ue_common_vars.rxdata[aarx][subframe_offset+frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples0],frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples);
-  #else
-  phy_vars_ue->PHY_measurements.n0_power[aarx] = signal_energy(&phy_vars_ue->lte_ue_common_vars.rxdata[aarx][subframe_offset+frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size);
-  #endif
-  phy_vars_ue->PHY_measurements.n0_power_dB[aarx] = (unsigned short) dB_fixed(phy_vars_ue->PHY_measurements.n0_power[aarx]);
-  phy_vars_ue->PHY_measurements.n0_power_tot +=  phy_vars_ue->PHY_measurements.n0_power[aarx];
-    }
-
-    phy_vars_ue->PHY_measurements.n0_power_tot_dB = (unsigned short) dB_fixed(phy_vars_ue->PHY_measurements.n0_power_tot);
-    phy_vars_ue->PHY_measurements.n0_power_tot_dBm = phy_vars_ue->PHY_measurements.n0_power_tot_dB - phy_vars_ue->rx_total_gain_dB + gain_offset;
-    //    printf("PHY measurements UE %d: n0_power %d (%d)\n",phy_vars_ue->Mod_id,phy_vars_ue->PHY_measurements.n0_power_tot_dBm,phy_vars_ue->PHY_measurements.n0_power_tot_dB);
-  }
-  else {
-    phy_vars_ue->PHY_measurements.n0_power_tot_dBm = phy_vars_ue->PHY_measurements.n0_power_tot_dB - phy_vars_ue->rx_total_gain_dB + gain_offset;
-  }
-  */
   // signal measurements
   for (eNB_id=0; eNB_id<phy_vars_ue->n_connected_eNB; eNB_id++) {
     for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
@@ -537,7 +506,7 @@ void lte_ue_measurements(PHY_VARS_UE *phy_vars_ue,
     phy_vars_ue->PHY_measurements.wideband_cqi_avg[eNB_id] = dB_fixed2(phy_vars_ue->PHY_measurements.rx_power_avg[eNB_id],phy_vars_ue->PHY_measurements.n0_power_avg);
     phy_vars_ue->PHY_measurements.rx_rssi_dBm[eNB_id] = phy_vars_ue->PHY_measurements.rx_power_avg_dB[eNB_id] - phy_vars_ue->rx_total_gain_dB;
 #ifdef DEBUG_MEAS
-    LOG_D(PHY,"[eNB %d] lte_ue_measurements: RSSI %d dBm, RSSI (digital) %d dB\n",
+    LOG_I(PHY,"[eNB %d] lte_ue_measurements: RSSI %d dBm, RSSI (digital) %d dB\n",
           eNB_id,phy_vars_ue->PHY_measurements.rx_rssi_dBm[eNB_id],
           phy_vars_ue->PHY_measurements.rx_power_avg_dB[eNB_id]);
 #endif
diff --git a/openair1/PHY/LTE_TRANSPORT/defs.h b/openair1/PHY/LTE_TRANSPORT/defs.h
index 8a527e2d7a45cba86c9d780e2f032c582662ec12..fa2258be2ecc5fe98757d1c7529ee3659452bad5 100644
--- a/openair1/PHY/LTE_TRANSPORT/defs.h
+++ b/openair1/PHY/LTE_TRANSPORT/defs.h
@@ -565,6 +565,16 @@ typedef struct {
 typedef struct {
   /// UL RSSI per receive antenna
   int32_t UL_rssi[NB_ANTENNAS_RX];
+  /// PUCCH1a/b power (digital linear)
+  int32_t Po_PUCCH;
+  /// PUCCH1a/b power (dBm)
+  int32_t Po_PUCCH_dBm;
+  /// PUCCH1 power (digital linear), conditioned on below threshold
+  int32_t Po_PUCCH1_below;
+  /// PUCCH1 power (digital linear), conditioned on above threshold
+  int32_t Po_PUCCH1_above;
+  /// Indicator that Po_PUCCH has been updated by PHY
+  int32_t Po_PUCCH_update;
   /// DL Wideband CQI index (2 TBs)
   uint8_t DL_cqi[2];
   /// DL Subband CQI index (from HLC feedback)
diff --git a/openair1/PHY/LTE_TRANSPORT/prach.c b/openair1/PHY/LTE_TRANSPORT/prach.c
index c824433ce9f2ccc38f73ad6d1dbf48bfb736a15f..527733cca5a14d35217d37134a932fc6ffabde35 100644
--- a/openair1/PHY/LTE_TRANSPORT/prach.c
+++ b/openair1/PHY/LTE_TRANSPORT/prach.c
@@ -435,6 +435,51 @@ uint8_t get_prach_fmt(uint8_t prach_ConfigIndex,lte_frame_type_t frame_type)
   }
 }
 
+uint8_t get_prach_prb_offset(LTE_DL_FRAME_PARMS *frame_parms, uint8_t tdd_mapindex, uint16_t Nf) 
+{
+  lte_frame_type_t frame_type         = frame_parms->frame_type;
+  uint8_t tdd_config         = frame_parms->tdd_config;
+  uint8_t prach_ConfigIndex  = frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex;
+  uint8_t n_ra_prboffset     = frame_parms->prach_config_common.prach_ConfigInfo.prach_FreqOffset;
+  uint8_t n_ra_prb;
+  uint8_t f_ra,t1_ra;
+  uint8_t prach_fmt = get_prach_fmt(prach_ConfigIndex,frame_type);
+  uint8_t Nsp=2;
+
+  if (frame_type == TDD) { // TDD
+
+    if (tdd_preamble_map[prach_ConfigIndex][tdd_config].num_prach==0) {
+      LOG_E(PHY, "Illegal prach_ConfigIndex %"PRIu8"", prach_ConfigIndex);
+      return(-1);
+    }
+
+    // adjust n_ra_prboffset for frequency multiplexing (p.36 36.211)
+    f_ra = tdd_preamble_map[prach_ConfigIndex][tdd_config].map[tdd_mapindex].f_ra;
+
+    if (prach_fmt < 4) {
+      if ((f_ra&1) == 0) {
+        n_ra_prb = n_ra_prboffset + 6*(f_ra>>1);
+      } else {
+        n_ra_prb = frame_parms->N_RB_UL - 6 - n_ra_prboffset + 6*(f_ra>>1);
+      }
+    } else {
+      if ((tdd_config >2) && (tdd_config<6))
+        Nsp = 2;
+
+      t1_ra = tdd_preamble_map[prach_ConfigIndex][tdd_config].map[0].t1_ra;
+
+      if ((((Nf&1)*(2-Nsp)+t1_ra)&1) == 0) {
+        n_ra_prb = 6*f_ra;
+      } else {
+        n_ra_prb = frame_parms->N_RB_UL - 6*(f_ra+1);
+      }
+    }
+  }
+  else { //FDD
+    n_ra_prb = n_ra_prboffset;
+  }
+  return(n_ra_prb);
+}
 
 int is_prach_subframe(LTE_DL_FRAME_PARMS *frame_parms,uint32_t frame, uint8_t subframe)
 {
@@ -554,12 +599,12 @@ int32_t generate_prach( PHY_VARS_UE *phy_vars_ue, uint8_t eNB_id, uint8_t subfra
 {
 
   lte_frame_type_t frame_type         = phy_vars_ue->lte_frame_parms.frame_type;
-  uint8_t tdd_config         = phy_vars_ue->lte_frame_parms.tdd_config;
+  //uint8_t tdd_config         = phy_vars_ue->lte_frame_parms.tdd_config;
   uint16_t rootSequenceIndex = phy_vars_ue->lte_frame_parms.prach_config_common.rootSequenceIndex;
   uint8_t prach_ConfigIndex  = phy_vars_ue->lte_frame_parms.prach_config_common.prach_ConfigInfo.prach_ConfigIndex;
   uint8_t Ncs_config         = phy_vars_ue->lte_frame_parms.prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig;
   uint8_t restricted_set     = phy_vars_ue->lte_frame_parms.prach_config_common.prach_ConfigInfo.highSpeedFlag;
-  uint8_t n_ra_prboffset     = phy_vars_ue->lte_frame_parms.prach_config_common.prach_ConfigInfo.prach_FreqOffset;
+  //uint8_t n_ra_prboffset     = phy_vars_ue->lte_frame_parms.prach_config_common.prach_ConfigInfo.prach_FreqOffset;
   uint8_t preamble_index     = phy_vars_ue->prach_resources[eNB_id]->ra_PreambleIndex;
   uint8_t tdd_mapindex       = phy_vars_ue->prach_resources[eNB_id]->ra_TDD_map_index;
   int16_t *prachF           = phy_vars_ue->lte_ue_prach_vars[eNB_id]->prachF;
@@ -576,8 +621,8 @@ int32_t generate_prach( PHY_VARS_UE *phy_vars_ue, uint8_t eNB_id, uint8_t subfra
   uint16_t d_start,numshift;
 
   uint8_t prach_fmt = get_prach_fmt(prach_ConfigIndex,frame_type);
-  uint8_t Nsp=2;
-  uint8_t f_ra,t1_ra;
+  //uint8_t Nsp=2;
+  //uint8_t f_ra,t1_ra;
   uint16_t N_ZC = (prach_fmt<4)?839:139;
   uint8_t not_found;
   int k;
@@ -625,9 +670,11 @@ int32_t generate_prach( PHY_VARS_UE *phy_vars_ue, uint8_t eNB_id, uint8_t subfra
     NCS = NCS_restricted[Ncs_config];
   }
 
-  n_ra_prb = n_ra_prboffset;
+  n_ra_prb = get_prach_prb_offset(&(phy_vars_ue->lte_frame_parms), tdd_mapindex, Nf);
   prach_root_sequence_map = (prach_fmt<4) ? prach_root_sequence_map0_3 : prach_root_sequence_map4;
 
+  /*
+  // this code is not part of get_prach_prb_offset
   if (frame_type == TDD) { // TDD
 
     if (tdd_preamble_map[prach_ConfigIndex][tdd_config].num_prach==0) {
@@ -656,6 +703,7 @@ int32_t generate_prach( PHY_VARS_UE *phy_vars_ue, uint8_t eNB_id, uint8_t subfra
       }
     }
   }
+  */
 
   // This is the relative offset (for unrestricted case) in the root sequence table (5.7.2-4 from 36.211) for the given preamble index
   preamble_offset = ((NCS==0)? preamble_index : (preamble_index/(N_ZC/NCS)));
@@ -979,7 +1027,17 @@ int32_t generate_prach( PHY_VARS_UE *phy_vars_ue, uint8_t eNB_id, uint8_t subfra
       ((int16_t*)phy_vars_ue->lte_ue_common_vars.txdata[0])[2*i] = prach[2*j]<<4;
       ((int16_t*)phy_vars_ue->lte_ue_common_vars.txdata[0])[2*i+1] = prach[2*j+1]<<4;
     }
-
+#if defined(EXMIMO)
+	    // handle switch before 1st TX subframe, guarantee that the slot prior to transmission is switch on
+	    for (k=prach_start - (phy_vars_ue->lte_frame_parms.samples_per_tti>>1) ; k<prach_start ; k++) {
+	      if (k<0)
+		phy_vars_ue->lte_ue_common_vars.txdata[0][k+phy_vars_ue->lte_frame_parms.samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME] &= 0xFFFEFFFE;
+	      else if (k>(phy_vars_ue->lte_frame_parms.samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME))
+		phy_vars_ue->lte_ue_common_vars.txdata[0][k-phy_vars_ue->lte_frame_parms.samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME] &= 0xFFFEFFFE;
+	      else
+		phy_vars_ue->lte_ue_common_vars.txdata[0][k] &= 0xFFFEFFFE;
+	    }
+#endif
 #else
 
     for (i=0; i<prach_len; i++) {
@@ -1006,12 +1064,12 @@ void rx_prach(PHY_VARS_eNB *phy_vars_eNB,uint8_t subframe,uint16_t *preamble_ene
   int i;
   lte_frame_type_t frame_type         = phy_vars_eNB->lte_frame_parms.frame_type;
 
-  uint8_t tdd_config         = phy_vars_eNB->lte_frame_parms.tdd_config;
+  //uint8_t tdd_config         = phy_vars_eNB->lte_frame_parms.tdd_config;
   uint16_t rootSequenceIndex = phy_vars_eNB->lte_frame_parms.prach_config_common.rootSequenceIndex;
   uint8_t prach_ConfigIndex  = phy_vars_eNB->lte_frame_parms.prach_config_common.prach_ConfigInfo.prach_ConfigIndex;
   uint8_t Ncs_config         = phy_vars_eNB->lte_frame_parms.prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig;
   uint8_t restricted_set     = phy_vars_eNB->lte_frame_parms.prach_config_common.prach_ConfigInfo.highSpeedFlag;
-  uint8_t n_ra_prboffset     = phy_vars_eNB->lte_frame_parms.prach_config_common.prach_ConfigInfo.prach_FreqOffset;
+  //uint8_t n_ra_prboffset     = phy_vars_eNB->lte_frame_parms.prach_config_common.prach_ConfigInfo.prach_FreqOffset;
   int16_t *prachF           = phy_vars_eNB->lte_eNB_prach_vars.prachF;
   int16_t **rxsigF          = phy_vars_eNB->lte_eNB_prach_vars.rxsigF;
   int16_t **prach_ifft      = phy_vars_eNB->lte_eNB_prach_vars.prach_ifft;
@@ -1028,8 +1086,8 @@ void rx_prach(PHY_VARS_eNB *phy_vars_eNB,uint8_t subframe,uint16_t *preamble_ene
   uint16_t numshift=0;
   uint16_t *prach_root_sequence_map;
   uint8_t prach_fmt = get_prach_fmt(prach_ConfigIndex,frame_type);
-  uint8_t Nsp=2;
-  uint8_t f_ra,t1_ra;
+  //uint8_t Nsp=2;
+  //uint8_t f_ra,t1_ra;
   uint16_t N_ZC = (prach_fmt <4)?839:139;
   uint8_t not_found;
   //  LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_eNB->lte_frame_parms;
@@ -1073,9 +1131,11 @@ void rx_prach(PHY_VARS_eNB *phy_vars_eNB,uint8_t subframe,uint16_t *preamble_ene
 
   start_meas(&phy_vars_eNB->rx_prach);
 
-  n_ra_prb = n_ra_prboffset;
+  n_ra_prb = get_prach_prb_offset(&(phy_vars_eNB->lte_frame_parms),tdd_mapindex,Nf);
   prach_root_sequence_map = (prach_fmt < 4) ? prach_root_sequence_map0_3 : prach_root_sequence_map4;
 
+  /*
+  // this code is now part of get_prach_prb_offset
   if (frame_type == TDD) { // TDD
     // adjust n_ra_prboffset for frequency multiplexing (p.36 36.211)
 
@@ -1102,6 +1162,7 @@ void rx_prach(PHY_VARS_eNB *phy_vars_eNB,uint8_t subframe,uint16_t *preamble_ene
 
     }
   }
+  */
 
   //    printf("NCS %d\n",NCS);
   // PDP is oversampled, e.g. 1024 sample instead of 839
diff --git a/openair1/PHY/LTE_TRANSPORT/print_stats.c b/openair1/PHY/LTE_TRANSPORT/print_stats.c
index 14c53e5f9f2fedc19f5a0b39f92ec3095deb499a..5a2f7e74ea2918659b9d965846b816a2fc3e179d 100644
--- a/openair1/PHY/LTE_TRANSPORT/print_stats.c
+++ b/openair1/PHY/LTE_TRANSPORT/print_stats.c
@@ -104,8 +104,19 @@ int dump_ue_stats(PHY_VARS_UE *phy_vars_ue, char* buffer, int length, runmode_t
 #endif
     len += sprintf(&buffer[len], "[UE PROC] UE mode = %s (%d)\n",mode_string[phy_vars_ue->UE_mode[0]],phy_vars_ue->UE_mode[0]);
     len += sprintf(&buffer[len], "[UE PROC] timing_advance = %d\n",phy_vars_ue->timing_advance);
-    len += sprintf(&buffer[len], "[UE PROC] UE tx power = %d\n", PHY_vars_UE_g[0][0]->tx_power_dBm);
-
+    if (phy_vars_ue->UE_mode[0]==PUSCH) {
+      len += sprintf(&buffer[len], "[UE PROC] Po_PUSCH = %d dBm (PL %d dB, Po_NOMINAL_PUSCH %d dBm, PHR %d dB)\n", 
+		     PHY_vars_UE_g[0][0]->ulsch_ue[0]->Po_PUSCH,
+		     get_PL(phy_vars_ue->Mod_id,phy_vars_ue->CC_id,0),
+		     mac_xface->get_Po_NOMINAL_PUSCH(phy_vars_ue->Mod_id,0),
+		     PHY_vars_UE_g[0][0]->ulsch_ue[0]->PHR);
+      len += sprintf(&buffer[len], "[UE PROC] Po_PUCCH = %d dBm (Po_NOMINAL_PUCCH %d dBm, g_pucch %d dB)\n", 
+		     get_PL(phy_vars_ue->Mod_id,phy_vars_ue->CC_id,0)+
+		     phy_vars_ue->lte_frame_parms.ul_power_control_config_common.p0_NominalPUCCH+
+		     phy_vars_ue->g_pucch[0],
+		     phy_vars_ue->lte_frame_parms.ul_power_control_config_common.p0_NominalPUCCH,
+		     phy_vars_ue->g_pucch[0]);
+    }
     //for (eNB=0;eNB<NUMBER_OF_eNB_MAX;eNB++) {
     for (eNB=0; eNB<1; eNB++) {
       len += sprintf(&buffer[len], "[UE PROC] RX spatial power eNB%d: [%d %d; %d %d] dB\n",
@@ -616,13 +627,18 @@ int dump_eNB_stats(PHY_VARS_eNB *phy_vars_eNB, char* buffer, int length)
 
     if (phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->rnti>0) {
 #endif
-      len += sprintf(&buffer[len],"[eNB PROC] UE %d (%x) Power: (%d,%d) dB, RSSI: (%d,%d) dBm, Sector %d\n",
+      len += sprintf(&buffer[len],"[eNB PROC] UE %d (%x) Power: (%d,%d) dB, Po_PUSCH: (%d,%d) dBm, Po_PUCCH (%d/%d) dBm, Po_PUCCH1 (%d,%d) dBm,  PUCCH1 Thres %d dBm \n",
                      UE_id,
                      phy_vars_eNB->eNB_UE_stats[UE_id].crnti,
                      dB_fixed(phy_vars_eNB->lte_eNB_pusch_vars[UE_id]->ulsch_power[0]),
                      dB_fixed(phy_vars_eNB->lte_eNB_pusch_vars[UE_id]->ulsch_power[1]),
                      phy_vars_eNB->eNB_UE_stats[UE_id].UL_rssi[0],
                      phy_vars_eNB->eNB_UE_stats[UE_id].UL_rssi[1],
+		     dB_fixed(phy_vars_eNB->eNB_UE_stats[UE_id].Po_PUCCH)-phy_vars_eNB->rx_total_gain_eNB_dB,
+		     phy_vars_eNB->lte_frame_parms.ul_power_control_config_common.p0_NominalPUCCH,
+		     dB_fixed(phy_vars_eNB->eNB_UE_stats[UE_id].Po_PUCCH1_below)-phy_vars_eNB->rx_total_gain_eNB_dB,
+		     dB_fixed(phy_vars_eNB->eNB_UE_stats[UE_id].Po_PUCCH1_above)-phy_vars_eNB->rx_total_gain_eNB_dB,
+		     PUCCH1_THRES+phy_vars_eNB->PHY_measurements_eNB[0].n0_power_tot_dBm-dB_fixed(phy_vars_eNB->lte_frame_parms.N_RB_UL),
                      phy_vars_eNB->eNB_UE_stats[UE_id].sector);
 
       for(i=0; i<8; i++)
diff --git a/openair1/PHY/LTE_TRANSPORT/proto.h b/openair1/PHY/LTE_TRANSPORT/proto.h
index 0f671695d97a1fbae96f1b6d21a6284b4abe841c..921dd9f6a4f8f164b6fda6d9eb50f526f4a886a5 100644
--- a/openair1/PHY/LTE_TRANSPORT/proto.h
+++ b/openair1/PHY/LTE_TRANSPORT/proto.h
@@ -1760,5 +1760,8 @@ double computeRhoB_UE(PDSCH_CONFIG_DEDICATED  *pdsch_config_dedicated,
   uint8_t n_antenna_port,
   LTE_UE_DLSCH_t *dlsch_ue);
 */
+
+  uint8_t get_prach_prb_offset(LTE_DL_FRAME_PARMS *frame_parms, uint8_t tdd_mapindex, uint16_t Nf); 
+
 /**@}*/
 #endif
diff --git a/openair1/PHY/LTE_TRANSPORT/pucch.c b/openair1/PHY/LTE_TRANSPORT/pucch.c
index 59e4084e8f2d1ecd0e28992dc58cb180c28e7b8b..4d3f9c857b265857a57a9b1718d6261c7efc8edd 100644
--- a/openair1/PHY/LTE_TRANSPORT/pucch.c
+++ b/openair1/PHY/LTE_TRANSPORT/pucch.c
@@ -443,9 +443,14 @@ int32_t rx_pucch(PHY_VARS_eNB *phy_vars_eNB,
 
 
   LTE_eNB_COMMON *eNB_common_vars                = &phy_vars_eNB->lte_eNB_common_vars;
-  LTE_DL_FRAME_PARMS *frame_parms                = &phy_vars_eNB->lte_frame_parms;
+  LTE_DL_FRAME_PARMS *frame_parms                    = &phy_vars_eNB->lte_frame_parms;
   //  PUCCH_CONFIG_DEDICATED *pucch_config_dedicated = &phy_vars_eNB->pucch_config_dedicated[UE_id];
   int8_t sigma2_dB                                   = phy_vars_eNB->PHY_measurements_eNB[0].n0_power_tot_dB;
+  int32_t *Po_PUCCH                                  = &(phy_vars_eNB->eNB_UE_stats[UE_id].Po_PUCCH);
+  int32_t *Po_PUCCH_dBm                              = &(phy_vars_eNB->eNB_UE_stats[UE_id].Po_PUCCH_dBm);
+  int32_t *Po_PUCCH1_below                           = &(phy_vars_eNB->eNB_UE_stats[UE_id].Po_PUCCH1_below);
+  int32_t *Po_PUCCH1_above                           = &(phy_vars_eNB->eNB_UE_stats[UE_id].Po_PUCCH1_above);
+  int32_t *Po_PUCCH_update                           = &(phy_vars_eNB->eNB_UE_stats[UE_id].Po_PUCCH_update);
   uint32_t u,v,n,aa;
   uint32_t z[12*14];
   int16_t *zptr;
@@ -474,6 +479,24 @@ int32_t rx_pucch(PHY_VARS_eNB *phy_vars_eNB,
   uint32_t v1=frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.seqhop[1+(subframe<<1)];
 
 
+  switch (frame_parms->N_RB_UL) {
+
+  case 6:
+    sigma2_dB -= 8;
+    break;
+  case 25:
+    sigma2_dB -= 14;
+    break;
+  case 50:
+    sigma2_dB -= 17;
+    break;
+  case 100:
+    sigma2_dB -= 20;
+    break;
+  default:
+    sigma2_dB -= 14;
+  }
+
   if ((deltaPUCCH_Shift==0) || (deltaPUCCH_Shift>3)) {
     LOG_E(PHY,"[eNB] rx_pucch: Illegal deltaPUCCH_shift %d (should be 1,2,3)\n",deltaPUCCH_Shift);
     return(-1);
@@ -728,6 +751,7 @@ int32_t rx_pucch(PHY_VARS_eNB *phy_vars_eNB,
         phase_max = phase;
       }
 
+      stat_max /= nsymb; // normalize to energy per symbol
 #ifdef DEBUG_PUCCH_RX
       LOG_D(PHY,"[eNB] PUCCH: stat %d, stat_max %d, phase_max %d\n", stat,stat_max,phase_max);
 #endif
@@ -737,10 +761,17 @@ int32_t rx_pucch(PHY_VARS_eNB *phy_vars_eNB,
     LOG_D(PHY,"[eNB] PUCCH fmt0:  stat_max : %d, sigma2_dB %d, phase_max : %d\n",dB_fixed(stat_max),sigma2_dB,phase_max);
 #endif
 
-    if (sigma2_dB<(dB_fixed(stat_max)-pucch1_thres))  //
+    
+    // This is a moving average of the PUCCH1 statistics conditioned on being above or below the threshold
+    if (sigma2_dB<(dB_fixed(stat_max)-pucch1_thres))  {
       *payload = 1;
-    else
+      *Po_PUCCH1_below = ((*Po_PUCCH1_below<<9) + (stat_max<<9)+1024)>>10;
+    }
+    else {
       *payload = 0;
+      *Po_PUCCH1_above = ((*Po_PUCCH1_above<<9) + (stat_max<<9)+1024)>>10;
+    }
+    *Po_PUCCH_update = 1;
 
   } else if ((fmt == pucch_format1a)||(fmt == pucch_format1b)) {
     stat_max = 0;
@@ -816,6 +847,7 @@ int32_t rx_pucch(PHY_VARS_eNB *phy_vars_eNB,
       }
     } //phase
 
+    stat_max/=nsymb;  //normalize to energy per symbol
 #ifdef DEBUG_PUCCH_RX
     LOG_I(PHY,"[eNB] PUCCH fmt1:  stat_max : %d, phase_max : %d\n",stat_max,phase_max);
 #endif
@@ -823,6 +855,18 @@ int32_t rx_pucch(PHY_VARS_eNB *phy_vars_eNB,
     // Do detection now
     stat_re=0;
     stat_im=0;
+    LOG_I(PHY,"PUCCH1A : Po_PUCCH before %d (%d) dB",dB_fixed(*Po_PUCCH),*Po_PUCCH);
+    *Po_PUCCH = ((*Po_PUCCH<<9) + (stat_max<<9)+1024)>>10;
+    *Po_PUCCH_dBm = dB_fixed(*Po_PUCCH) - phy_vars_eNB->rx_total_gain_eNB_dB;
+    *Po_PUCCH_update = 1;
+ 
+    LOG_I(PHY,"PUCCH1A : stat_max %d (%d,%d,%d) => Po_PUCCH %d\n",
+	  dB_fixed(stat_max),
+	  pucch1_thres+sigma2_dB,
+	  pucch1_thres,
+	  sigma2_dB,
+	  dB_fixed(*Po_PUCCH));
+
 
     if (sigma2_dB<(dB_fixed(stat_max)-pucch1_thres))  {//
 
diff --git a/openair1/PHY/impl_defs_top.h b/openair1/PHY/impl_defs_top.h
index 9e2b01d2965543adae06819e38e4399735c3c10d..509a0e41da79fb2b2935e3b0c09dbe56388aadcf 100755
--- a/openair1/PHY/impl_defs_top.h
+++ b/openair1/PHY/impl_defs_top.h
@@ -248,6 +248,10 @@
 #define AMP_OVER_SQRT2 ((AMP*ONE_OVER_SQRT2_Q15)>>15)
 #define AMP_OVER_2 (AMP>>1)
 
+/// Threshold for PUCCH Format 1 detection
+#define PUCCH1_THRES 3
+/// Threshold for PUCCH Format 1a/1b detection
+#define PUCCH1a_THRES 2
 
 #ifndef OPENAIR_LTE
 ///
diff --git a/openair1/SCHED/defs.h b/openair1/SCHED/defs.h
index 016a52104be4ce433353a1747a9d2c85cce93947..d5737dea337854019dbb6ba93871ad1d006c5975 100644
--- a/openair1/SCHED/defs.h
+++ b/openair1/SCHED/defs.h
@@ -542,7 +542,8 @@ int16_t get_hundred_times_delta_IF_eNB(PHY_VARS_eNB *phy_vars_eNB,uint8_t UE_id,
 
 int16_t get_hundred_times_delta_IF_mac(module_id_t module_idP, uint8_t CC_id, rnti_t rnti, uint8_t harq_pid);
 
-int16_t get_target_ul_rx_power(module_id_t module_idP, uint8_t CC_id);
+int16_t get_target_pusch_rx_power(module_id_t module_idP, uint8_t CC_id);
+int16_t get_target_pucch_rx_power(module_id_t module_idP, uint8_t CC_id);
 
 int get_ue_active_harq_pid(uint8_t Mod_id,uint8_t CC_id,uint16_t rnti,int frame, uint8_t subframe,uint8_t *harq_pid,uint8_t *round,uint8_t ul_flag);
 
diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c
index dc304a60bcf02257e8332746762eb31337b46948..c919ea1506c01dc39815a1c94d80427cefcc1830 100755
--- a/openair1/SCHED/phy_procedures_lte_eNb.c
+++ b/openair1/SCHED/phy_procedures_lte_eNb.c
@@ -74,8 +74,6 @@
 #define NS_PER_SLOT 500000
 
 #define PUCCH 1
-#define PUCCH1_THRES 15
-#define PUCCH1a_THRES 15
 
 extern int exit_openair;
 //extern void do_OFDM_mod(mod_sym_t **txdataF, int32_t **txdata, uint32_t frame, uint16_t next_slot, LTE_DL_FRAME_PARMS *frame_parms);
@@ -161,6 +159,15 @@ int32_t add_ue(int16_t rnti, PHY_VARS_eNB *phy_vars_eNB)
         phy_vars_eNB->dlsch_eNB[i][0]->rnti = rnti;
         phy_vars_eNB->ulsch_eNB[i]->rnti = rnti;
         phy_vars_eNB->eNB_UE_stats[i].crnti = rnti;
+
+	phy_vars_eNB->eNB_UE_stats[i].Po_PUCCH1_below = 0;
+	phy_vars_eNB->eNB_UE_stats[i].Po_PUCCH1_above = (int32_t)pow(10.0,.1*(phy_vars_eNB->lte_frame_parms.ul_power_control_config_common.p0_NominalPUCCH+phy_vars_eNB->rx_total_gain_eNB_dB));
+	phy_vars_eNB->eNB_UE_stats[i].Po_PUCCH        = (int32_t)pow(10.0,.1*(phy_vars_eNB->lte_frame_parms.ul_power_control_config_common.p0_NominalPUCCH+phy_vars_eNB->rx_total_gain_eNB_dB));
+	LOG_I(PHY,"Initializing Po_PUCCH: p0_NominalPUCCH %d, gain %d => %d\n",
+	      phy_vars_eNB->lte_frame_parms.ul_power_control_config_common.p0_NominalPUCCH,
+	      phy_vars_eNB->rx_total_gain_eNB_dB,
+	      phy_vars_eNB->eNB_UE_stats[i].Po_PUCCH);
+  
         return(i);
       }
     }
@@ -383,12 +390,18 @@ int get_nCCE_offset(const unsigned char L, const int nCCE, const int common_dci,
   }
 }
 
-int16_t get_target_ul_rx_power(const module_id_t module_idP, const uint8_t CC_id)
+int16_t get_target_pusch_rx_power(const module_id_t module_idP, const uint8_t CC_id)
 {
   //return PHY_vars_eNB_g[module_idP][CC_id]->PHY_measurements_eNB[0].n0_power_tot_dBm;
   return PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.ul_power_control_config_common.p0_NominalPUSCH;
 }
 
+int16_t get_target_pucch_rx_power(const module_id_t module_idP, const uint8_t CC_id)
+{
+  //return PHY_vars_eNB_g[module_idP][CC_id]->PHY_measurements_eNB[0].n0_power_tot_dBm;
+  return PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.ul_power_control_config_common.p0_NominalPUCCH;
+}
+
 #ifdef EMOS
 void phy_procedures_emos_eNB_TX(unsigned char subframe, PHY_VARS_eNB *phy_vars_eNB)
 {
diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c
index 1dcf48d56aa1b83d65ce464461f251dba000bc8d..513c2efa50cecafa46f64af8294bb63360689df9 100755
--- a/openair1/SCHED/phy_procedures_lte_ue.c
+++ b/openair1/SCHED/phy_procedures_lte_ue.c
@@ -759,19 +759,6 @@ void phy_procedures_UE_TX(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint8_t abstra
       if (phy_vars_ue->ulsch_ue[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag == 1) {
 
         generate_ul_signal = 1;
-        // FK 20140908: the power control cannot be done here, since we do not have the spectral efficiency yet. this is only done in ulsch_encoding
-        /*
-        #ifdef OPENAIR2
-        pusch_power_cntl(phy_vars_ue,subframe_tx,eNB_id,1, abstraction_flag);
-        phy_vars_ue->tx_power_dBm = phy_vars_ue->ulsch_ue[eNB_id]->Po_PUSCH;
-        #else
-        phy_vars_ue->tx_power_dBm = UE_TX_POWER;
-        #endif
-        phy_vars_ue->tx_total_RE = phy_vars_ue->ulsch_ue[eNB_id]->harq_processes[harq_pid]->nb_rb*12;
-
-        LOG_D(PHY,"[UE  %d][PUSCH %d] Frame %d subframe %d harq pid %d, Po_PUSCH : %d dBm\n",
-              Mod_id,harq_pid,frame_tx,subframe_tx,harq_pid, phy_vars_ue->tx_power_dBm);
-        */
 
         // deactivate service request
         phy_vars_ue->ulsch_ue[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag = 0;
@@ -985,8 +972,8 @@ void phy_procedures_UE_TX(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint8_t abstra
 #else
           tx_amp = AMP;
 #endif
-          LOG_D(PHY,"[UE  %d][PUSCH %d] Frame %d subframe %d, generating PUSCH, Po_PUSCH: %d dBm (max %d dBm), amp %d\n",
-                Mod_id,harq_pid,frame_tx,subframe_tx,phy_vars_ue->tx_power_dBm,phy_vars_ue->tx_power_max_dBm, tx_amp);
+	  LOG_D(PHY,"[UE  %d][PUSCH %d] Frame %d subframe %d, generating PUSCH, Po_PUSCH: %d dBm (max %d dBm), amp %d\n",
+		Mod_id,harq_pid,frame_tx,subframe_tx,phy_vars_ue->tx_power_dBm,phy_vars_ue->tx_power_max_dBm, tx_amp);
           start_meas(&phy_vars_ue->ulsch_modulation_stats);
           ulsch_modulation(phy_vars_ue->lte_ue_common_vars.txdataF,
 			   tx_amp,
@@ -1326,7 +1313,6 @@ void phy_procedures_UE_TX(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint8_t abstra
               ((short*)phy_vars_ue->lte_ue_common_vars.txdata[aa])[2*k+1] = ((short*)dummy_tx_buffer)[2*l+1]<<4;
             }
 #if defined(EXMIMO)
-	    /*
 	    // handle switch before 1st TX subframe, guarantee that the slot prior to transmission is switch on
 	    for (k=ulsch_start - (frame_parms->samples_per_tti>>1) ; k<ulsch_start ; k++) {
 	      if (k<0)
@@ -1336,7 +1322,6 @@ void phy_procedures_UE_TX(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint8_t abstra
 	      else
 		phy_vars_ue->lte_ue_common_vars.txdata[aa][k] &= 0xFFFEFFFE;
 	    }
-	    */
 #endif
 #endif