diff --git a/openair1/PHY/LTE_ESTIMATION/lte_eNB_measurements.c b/openair1/PHY/LTE_ESTIMATION/lte_eNB_measurements.c
index a881773910c70a2719fc47cd178d786372e23e93..2d79158920bb821d71e126822e193c7d50f20fcd 100644
--- a/openair1/PHY/LTE_ESTIMATION/lte_eNB_measurements.c
+++ b/openair1/PHY/LTE_ESTIMATION/lte_eNB_measurements.c
@@ -47,6 +47,7 @@ void lte_eNB_I0_measurements(PHY_VARS_eNB *eNB,
   uint32_t rb;
   int32_t *ul_ch;
   int32_t n0_power_tot;
+  int64_t n0_power_tot2;
   int len;
   int offset;
   // noise measurements
@@ -75,43 +76,47 @@ void lte_eNB_I0_measurements(PHY_VARS_eNB *eNB,
 
   }
 
+  n0_power_tot2=0;
+  int nb_rb=0;
   for (rb=0; rb<frame_parms->N_RB_UL; rb++) {
 
-    n0_power_tot=0;
+    n0_power_tot=0; 
+    int offset0= (frame_parms->first_carrier_offset + (rb*12))%frame_parms->ofdm_symbol_size;
+
     if ((rb_mask[rb>>5]&(1<<(rb&31))) == 0) {  // check that rb was not used in this subframe
+      nb_rb++;
       for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
-
+        measurements->n0_subband_power[aarx][rb] = 0;
+        for (int s=0;s<14-(frame_parms->Ncp<<1);s++) {
       // select the 7th symbol in an uplink subframe
-	offset = (frame_parms->first_carrier_offset + (rb*12))%frame_parms->ofdm_symbol_size;
-	offset += (7*frame_parms->ofdm_symbol_size);
-	ul_ch  = &common_vars->rxdataF[aarx][offset];
-	len = 12;
+	  offset = offset0 + (s*frame_parms->ofdm_symbol_size);
+	  ul_ch  = &common_vars->rxdataF[aarx][offset];
+	  len = 12;
 	// just do first half of middle PRB for odd number of PRBs
-	if (((frame_parms->N_RB_UL&1) == 1) && 
-	    (rb==(frame_parms->N_RB_UL>>1))) {
-	  len=6;
-	}
-	if (clear == 1)
-	  measurements->n0_subband_power[aarx][rb]=0;
+	  if (((frame_parms->N_RB_UL&1) == 1) && 
+	      (rb==(frame_parms->N_RB_UL>>1))) {
+	    len=6;
+	  }
 
-	AssertFatal(ul_ch, "RX signal buffer (freq) problem");
+	  AssertFatal(ul_ch, "RX signal buffer (freq) problem");
 
 
-	measurements->n0_subband_power[aarx][rb] = signal_energy_nodc(ul_ch,len);
-	//((k1*(signal_energy_nodc(ul_ch,len))) 
-	  //  + (k2*measurements->n0_subband_power[aarx][rb]));  
+	  measurements->n0_subband_power[aarx][rb] += signal_energy_nodc(ul_ch,len);
 	  
-	measurements->n0_subband_power_dB[aarx][rb] = dB_fixed(measurements->n0_subband_power[aarx][rb]);
-	//		printf("subframe %d (%d): eNB %d, aarx %d, rb %d len %d: energy %d (%d dB)\n",subframe,offset,eNB_id,aarx,rb,len,signal_energy_nodc(ul_ch,len),  
-	//	       measurements->n0_subband_power_dB[aarx][rb]);
-	n0_power_tot += measurements->n0_subband_power[aarx][rb];
+        }
+        measurements->n0_subband_power[aarx][rb]/=(14-(frame_parms->Ncp<<1));
+        measurements->n0_subband_power_dB[aarx][rb] = dB_fixed(measurements->n0_subband_power[aarx][rb]);
+        n0_power_tot += measurements->n0_subband_power[aarx][rb];
+
       }
-      
-      measurements->n0_subband_power_tot_dB[rb] = dB_fixed(n0_power_tot);
+      n0_power_tot/=frame_parms->nb_antennas_rx;
+      n0_power_tot2 += n0_power_tot;
+      measurements->n0_subband_power_tot_dB[rb] = dB_fixed(n0_power_tot/frame_parms->nb_antennas_rx);
       measurements->n0_subband_power_tot_dBm[rb] = measurements->n0_subband_power_tot_dB[rb] - eNB->rx_total_gain_dB - dB_fixed(frame_parms->N_RB_UL);
       
     }
   }
+  if (nb_rb>0) measurements->n0_subband_power_avg_dB = dB_fixed(n0_power_tot2/nb_rb);
 }
 
 void lte_eNB_srs_measurements(PHY_VARS_eNB *eNB,
diff --git a/openair1/PHY/LTE_TRANSPORT/if5_tools.c b/openair1/PHY/LTE_TRANSPORT/if5_tools.c
index 1e0dd9db1b7af5110b3c30425ec33de7c5755912..f39f3ef872021d12fb73273f7a165e104d59cf75 100644
--- a/openair1/PHY/LTE_TRANSPORT/if5_tools.c
+++ b/openair1/PHY/LTE_TRANSPORT/if5_tools.c
@@ -1070,6 +1070,8 @@ void send_IF5(RU_t *ru, openair0_timestamp proc_timestamp, int subframe, uint8_t
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF5, 1 );
   if (packet_type == IF5_RRH_GW_DL) {    
     if (eth->compression == ALAW_COMPRESS) {
+     AssertFatal(1==0,"IF5 compression needs reworking\n");
+/*
       if (eth->flags == ETH_RAW_MODE) {
         data_block = (uint16_t*)(alaw_buffer + APP_HEADER_SIZE_BYTES + MAC_HEADER_SIZE_BYTES);
       } else {
@@ -1100,28 +1102,31 @@ void send_IF5(RU_t *ru, openair0_timestamp proc_timestamp, int subframe, uint8_t
         LOG_D(HW,"[SF %d] IF_Write_Time: %"PRId64"\n",subframe,clock_difftime_ns(start_comp, end_comp));
         VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF0, 0 );
       }
+*/
     } else if (eth->compression == NO_COMPRESS) {
 
-      for (i=0; i < fp->nb_antennas_tx; i++)
-        txp[i] = (void*)&ru->common.txdata[i][subframe*fp->samples_per_tti];
+      for (i=0; i < ru->nb_tx; i++)
+        txp[i] = (int32_t*)&ru->common.txdata[i][subframe*fp->samples_per_tti];
     
       for (packet_id=0; packet_id < spsf / spp_eth; packet_id++) {
-        VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SEND_IF5_PKT_ID, packet_id );
-        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF0, 1 );
-        clock_gettime( CLOCK_MONOTONIC, &start_comp);
-        ru->ifdevice.trx_write_func(&ru->ifdevice,
-				    (proc_timestamp + packet_id*spp_eth),
-				    (void**)txp,
-				    spp_eth,
-				    fp->nb_antennas_tx,
-				    0);
-        clock_gettime( CLOCK_MONOTONIC, &end_comp);
-        LOG_D(HW,"[SF %d] IF_Write_Time: %"PRId64"\n",subframe,clock_difftime_ns(start_comp, end_comp));
-        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF0, 0 );  
-        for (i=0; i < fp->nb_antennas_tx; i++)
-          txp[i] += spp_eth;
+        for (int aid=0; aid<ru->nb_tx;aid++) {
+          //VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SEND_IF5_PKT_ID, packet_id );
+          //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF0, 1 );
+          clock_gettime( CLOCK_MONOTONIC, &start_comp);
+          ru->ifdevice.trx_write_func2(&ru->ifdevice,
+	  			       (proc_timestamp + packet_id*spp_eth-500)*(30720/spsf),
+				       (void*)txp[aid],
+				       spp_eth,
+				       aid,
+				       0); 
+          LOG_D(HW,"SF %d : packet %d, TS %llu\n",subframe,packet_id,(unsigned long long)(proc_timestamp+packet_id*spp_eth));
+          clock_gettime( CLOCK_MONOTONIC, &end_comp);
+          LOG_D(HW,"[SF %d] IF_Write_Time: %"PRId64"\n",subframe,clock_difftime_ns(start_comp, end_comp));
+          //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF0, 0 );  
+	  txp[aid] += spp_eth;
 
-      }
+        }
+     }
     }
   } else if (packet_type == IF5_RRH_GW_UL) {
     if (eth->compression == ALAW_COMPRESS) {
@@ -1131,8 +1136,8 @@ void send_IF5(RU_t *ru, openair0_timestamp proc_timestamp, int subframe, uint8_t
         data_block = (uint16_t*)(alaw_buffer + APP_HEADER_SIZE_BYTES);
       }
       for (packet_id=0; packet_id < spsf / spp_eth; packet_id++) {
-        VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SEND_IF5_PKT_ID, packet_id );
-        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_COMPR_IF, 1 );
+        //VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SEND_IF5_PKT_ID, packet_id );
+        //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_COMPR_IF, 1 );
         clock_gettime( CLOCK_MONOTONIC, &start_comp);
         for (i=0; i < fp->nb_antennas_rx; i++) {
           for (element_id=0; element_id< spp_eth; element_id++){
@@ -1142,8 +1147,8 @@ void send_IF5(RU_t *ru, openair0_timestamp proc_timestamp, int subframe, uint8_t
         }
         clock_gettime( CLOCK_MONOTONIC, &end_comp);
         LOG_D(HW,"[SF %d] Compress_Time: %"PRId64"\n",subframe,clock_difftime_ns(start_comp, end_comp));
-        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_COMPR_IF, 0 );
-        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF0, 1 );
+        //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_COMPR_IF, 0 );
+        //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF0, 1 );
         clock_gettime( CLOCK_MONOTONIC, &start_comp);
         ru->ifdevice.trx_write_func(&ru->ifdevice,
                                      (proc_timestamp + packet_id*spp_eth),
@@ -1310,9 +1315,9 @@ void send_IF5(RU_t *ru, openair0_timestamp proc_timestamp, int subframe, uint8_t
 void recv_IF5(RU_t *ru, openair0_timestamp *proc_timestamp, int subframe, uint16_t packet_type) {
 
   LTE_DL_FRAME_PARMS *fp=ru->frame_parms;
-  int32_t *txp[fp->nb_antennas_tx], *rxp[fp->nb_antennas_rx]; 
+  int32_t *txp[ru->nb_tx], *rxp[ru->nb_rx]; 
 
-  uint16_t packet_id=0, i=0, element_id=0;
+  uint16_t packet_id=0, i=0;
 #ifdef DEBUG_UL_MOBIPASS
   //int8_t dummy_buffer_rx[fp->samples_per_tti*2];
   uint8_t rxe;
@@ -1321,11 +1326,12 @@ void recv_IF5(RU_t *ru, openair0_timestamp *proc_timestamp, int subframe, uint16
 
   int32_t spp_eth  = (int32_t) ru->ifdevice.openair0_cfg->samples_per_packet;
   int32_t spsf     = (int32_t) ru->ifdevice.openair0_cfg->samples_per_frame/10;
-  void    *alaw_buffer = ru->ifbuffer.rx; 
-  uint16_t *data_block = NULL;
-  uint16_t *j      = NULL;
 
-  openair0_timestamp timestamp[spsf / spp_eth];
+  openair0_timestamp timestamp[ru->nb_rx*spsf / spp_eth];
+  long timein[ru->nb_rx*spsf/spp_eth];
+  long timeout[ru->nb_rx*spsf/spp_eth];
+  struct timespec if_time;
+ 
   memset(timestamp, 0, sizeof(timestamp));
   eth_state_t *eth = (eth_state_t*) (ru->ifdevice.priv);
 
@@ -1333,6 +1339,9 @@ void recv_IF5(RU_t *ru, openair0_timestamp *proc_timestamp, int subframe, uint16
   
   if (packet_type == IF5_RRH_GW_DL) {
     if (eth->compression == ALAW_COMPRESS) {
+     AssertFatal(1==0,"IF5 compression needs reworking\n");
+
+/*
       if (eth->flags == ETH_RAW_MODE) {
         data_block = (uint16_t*)(alaw_buffer + APP_HEADER_SIZE_BYTES + MAC_HEADER_SIZE_BYTES);
       } else {
@@ -1364,13 +1373,14 @@ void recv_IF5(RU_t *ru, openair0_timestamp *proc_timestamp, int subframe, uint16
         LOG_D(HW,"[SF %d] Decomperss_Time: %"PRId64"\n",subframe,clock_difftime_ns(start_decomp, end_decomp));
         VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_DECOMPR_IF, 0 );
       }
+*/
     } else if (eth->compression == NO_COMPRESS) {
       for (i=0; i < fp->nb_antennas_tx; i++)
         txp[i] = (void*)&ru->common.txdata[i][subframe*fp->samples_per_tti];
     
       for (packet_id=0; packet_id < spsf / spp_eth; packet_id++) {
-        VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RECV_IF5_PKT_ID, packet_id );
-        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF0, 1 );  
+        //VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RECV_IF5_PKT_ID, packet_id );
+        //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF0, 1 );  
         clock_gettime( CLOCK_MONOTONIC, &start_decomp);
         ru->ifdevice.trx_read_func(&ru->ifdevice,
 				   &timestamp[packet_id],
@@ -1379,7 +1389,7 @@ void recv_IF5(RU_t *ru, openair0_timestamp *proc_timestamp, int subframe, uint16
 				   fp->nb_antennas_tx);
         clock_gettime( CLOCK_MONOTONIC, &end_decomp);
         LOG_D(HW,"[SF %d] IF_Read_Time: %"PRId64"\n",subframe,clock_difftime_ns(start_decomp, end_decomp));
-        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF0, 0 );  
+        //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF0, 0 );  
         for (i=0; i < fp->nb_antennas_tx; i++)
           txp[i] += spp_eth;
 
@@ -1389,6 +1399,8 @@ void recv_IF5(RU_t *ru, openair0_timestamp *proc_timestamp, int subframe, uint16
     
   } else if (packet_type == IF5_RRH_GW_UL) { 
     if (eth->compression == ALAW_COMPRESS) {
+     AssertFatal(1==0,"IF5 compression needs reworking\n");
+/*
       if (eth->flags == ETH_RAW_MODE) {
         data_block = (uint16_t*)(alaw_buffer + APP_HEADER_SIZE_BYTES + MAC_HEADER_SIZE_BYTES);
       } else {
@@ -1419,197 +1431,55 @@ void recv_IF5(RU_t *ru, openair0_timestamp *proc_timestamp, int subframe, uint16
         LOG_D(HW,"[SF %d] Decomperss_Time: %"PRId64"\n",subframe,clock_difftime_ns(start_decomp, end_decomp));
         VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_DECOMPR_IF, 0 );
       }
+*/
     } else if (eth->compression == NO_COMPRESS) {
-      for (i=0; i < fp->nb_antennas_rx; i++)
-        rxp[i] = (void*)&ru->common.rxdata[i][subframe*fp->samples_per_tti];
-    
-      for (packet_id=0; packet_id < spsf / spp_eth; packet_id++) {
-        VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SEND_IF5_PKT_ID, packet_id );
-        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF0, 1 );
-        clock_gettime( CLOCK_MONOTONIC, &start_decomp);
-        ru->ifdevice.trx_read_func(&ru->ifdevice,
+      int16_t temp_rx[spp_eth*2] __attribute__((aligned(32))); 
+      for (i=0; i < ru->nb_rx; i++)
+        rxp[i] = &ru->common.rxdata[i][subframe*fp->samples_per_tti];
+      int aid;
+      int firstTS=1;
+      openair0_timestamp oldTS=0;
+
+      for (packet_id=0; packet_id < ru->nb_rx*spsf / spp_eth; packet_id++) {
+        //VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SEND_IF5_PKT_ID, packet_id );
+        //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF0, 1 );
+        clock_gettime( CLOCK_MONOTONIC, &if_time);
+        timein[packet_id] = if_time.tv_nsec;
+        ru->ifdevice.trx_read_func2(&ru->ifdevice,
 				   &timestamp[packet_id],
-				   (void**)rxp,
+				   (void*)temp_rx,
 				   spp_eth,
-				   fp->nb_antennas_rx);
-        clock_gettime( CLOCK_MONOTONIC, &end_decomp);
-        LOG_D(HW,"[SF %d] IF_Read_Time: %"PRId64"\n",subframe,clock_difftime_ns(start_decomp, end_decomp));
-        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF0, 0 );            
-        for (i=0; i < fp->nb_antennas_rx; i++)
-          rxp[i] += spp_eth;
-
-      }
-    }
-    *proc_timestamp = timestamp[0];
-      
-  } else if (packet_type == IF5_MOBIPASS) {
-    if (ru->if_timing == synch_to_mobipass_standalone) {
-      uint16_t db_fulllength = PAYLOAD_MOBIPASS_NUM_SAMPLES;
-      openair0_timestamp timestamp_mobipass[fp->samples_per_tti/db_fulllength];
-      int32_t *rx_buffer=NULL;
-      __m128i *data_block=NULL, *data_block_head=NULL;
-      __m128i *rxp128;
-      __m128i r0;
-
-      unsigned char _rx_buffer[MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t + db_fulllength*sizeof(int16_t)];
-      rx_buffer = (int32_t *)_rx_buffer;
-      data_block_head = (__m128i *)((uint8_t *)rx_buffer + MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t);
-
-      rxp[0] = (void*)&ru->common.rxdata[0][subframe*ru->frame_parms->samples_per_tti];
-      rxp128 = (__m128i *) (rxp[0]);
-
-      packet_id=0;
-      while(packet_id<fp->samples_per_tti/db_fulllength) {
-        data_block = data_block_head;
-
-        ru->ifdevice.trx_read_func(&ru->ifdevice,
-                                         &timestamp_mobipass[packet_id],
-                                         (void**)&rx_buffer,
-                                         db_fulllength,
-                                          1
-                                          );
-
-          //store rxdata and increase packet_id
-          rxp[0] = (void*)&ru->common.rxdata[0][(subframe*ru->frame_parms->samples_per_tti)+packet_id*db_fulllength];
-          rxp128 = (__m128i *) (rxp[0]);
-          for (i=0; i<db_fulllength>>2; i+=2) {
-            r0 = _mm_loadu_si128(data_block++);
-            *rxp128++ =_mm_slli_epi16(_mm_srai_epi16(_mm_unpacklo_epi8(r0,r0),8),4);
-            *rxp128++ =_mm_slli_epi16(_mm_srai_epi16(_mm_unpackhi_epi8(r0,r0),8),4);
-          }
-          packet_id++;
-      }//end while
-
-      *proc_timestamp = ntohl(timestamp_mobipass[0]);
-    } else {
-      
-      uint16_t db_fulllength = PAYLOAD_MOBIPASS_NUM_SAMPLES;
-      openair0_timestamp timestamp_mobipass[fp->samples_per_tti/db_fulllength];
-#ifdef DEBUG_UL_MOBIPASS
-      int lower_offset = 0;
-      int  upper_offset = 70000;
-#endif
-      int subframe_skip = 0;
-      int reset_flag = 0;
-      int32_t *rx_buffer=NULL;
-      __m128i *data_block=NULL, *data_block_head=NULL;
-      __m128i *rxp128;
-      __m128i r0;
-
-      //rx_buffer = memalign(16, MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t + db_fulllength*sizeof(int16_t));
-      rx_buffer = malloc(MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t + db_fulllength*sizeof(int16_t));
-      IF5_mobipass_header_t *header = (IF5_mobipass_header_t *)((uint8_t *)rx_buffer + MAC_HEADER_SIZE_BYTES);
-      data_block_head = (__m128i *)((uint8_t *)rx_buffer + MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t);
-   
-      rxp[0] = (void*)&ru->common.rxdata[0][subframe*ru->frame_parms->samples_per_tti];
-      rxp128 = (__m128i *) (rxp[0]);
-   
-      RU_proc_t *proc = &ru->proc;
-/*
-   //   while(packet_id<fp->samples_per_tti/db_fulllength) {
-        data_block = data_block_head;
-
-        eNB->ifdevice.trx_read_func(&eNB->ifdevice,
-                                         &ts0,
-                                         (void**)&rx_buffer,
-                                         db_fulllength,
-                                          1
-                                          );
+				   &aid);
+        clock_gettime( CLOCK_MONOTONIC, &if_time);
+        timeout[packet_id] = if_time.tv_nsec;
+        timestamp[packet_id] /= (30720/spsf);
+        LOG_D(PHY,"subframe %d: Received packet %d: aid %d, TS %llu, oldTS %llu, diff %lld, \n",subframe,packet_id,aid,(unsigned long long)timestamp[packet_id],(unsigned long long)oldTS,(unsigned long long)(timestamp[packet_id]-timestamp[0]));
+        if (aid==0) {
+           if (firstTS==1) firstTS=0;
+           else if (oldTS + 256 != timestamp[packet_id]) {
+              LOG_I(PHY,"oldTS %llu, newTS %llu, diff %llu, timein %lu, timeout %lu\n",(long long unsigned int)oldTS,(long long unsigned int)timestamp[packet_id],(long long unsigned int)timestamp[packet_id]-oldTS,timein[packet_id],timeout[packet_id]); 
+              for (int i=0;i<=packet_id;i++) LOG_I(PHY,"packet %d TS %llu, timein %lu, timeout %lu\n",i,(long long unsigned int)timestamp[i],timein[i],timeout[i]);
+              AssertFatal(1==0,"fronthaul problem\n");
+           }
 
-        if ((header->seqno == 1)&&(first_packet==1))  { 
-           first_packet = 0;  //ignore the packets before synchnorization
-           packet_id = 0;
-          ts_offset = ntohl(ts0);
-        } 
-        if (first_packet==0) { 
-          packet_cnt++;
-          ts = ntohl(ts0);
-          packet_id = (ts-ts_offset)/db_fulllength;
-          packet_id = packet_id % (fp->samples_per_tti/db_fulllength);
-
-          printf("[IF5_tools]packet_id:%d\n", packet_id);
-          // if (ts_stored == 0) {
-          //   ts_stored = 1;
-          *proc_timestamp = ntohl(ts - (packet_id*db_fulllength));
-          // }
-          rxp[0] = (void*)&eNB->common_vars.rxdata[0][0][(subframe*eNB->frame_parms.samples_per_tti)+packet_id*db_fulllength];
-          rxp128 = (__m128i *) (rxp[0]);
-
-          for (i=0; i<db_fulllength>>2; i+=2) {
-            r0 = _mm_loadu_si128(data_block++);
-            *rxp128++ =_mm_slli_epi16(_mm_srai_epi16(_mm_unpacklo_epi8(r0,r0),8),4);
-            *rxp128++ =_mm_slli_epi16(_mm_srai_epi16(_mm_unpackhi_epi8(r0,r0),8),4);
-          }
+           oldTS = timestamp[packet_id];
         }
-    //  }//end while
-*/
    
 
-      packet_id=0; 
-      while(packet_id<fp->samples_per_tti/db_fulllength) {
-        data_block = data_block_head;
-
-	
-	ru->ifdevice.trx_read_func(&ru->ifdevice,
-				 &timestamp_mobipass[packet_id],
-				 (void**)&rx_buffer,
-				 db_fulllength,
-				 1
-				 );
-#ifdef DEBUG_UL_MOBIPASS
-        if (((proc->timestamp_tx + lower_offset) > ntohl(timestamp_mobipass[packet_id])) || ((proc->timestamp_tx + upper_offset) < ntohl(timestamp_mobipass[packet_id]))) {
-          //ignore the packet
-          subframe_skip_extra = (subframe_skip_extra + 1)%67;         
-         LOG_D("[Mobipass] ignored packet, id:[%d,%d], proc->timestamp_tx:%llu, proc->timestamp_rx:%llu, seqno:%d\n", packet_id,subframe_skip_extra, proc->timestamp_tx, ntohl(timestamp_mobipass[packet_id]), header->seqno);
-        }             
-#endif
-        //skip SUBFRAME_SKIP_NUM_MOBIPASS additional UL packets
-        if ((start_flag == 1) && (subframe_skip < SUBFRAME_SKIP_NUM_MOBIPASS)){
-          subframe_skip++;
-          offset_cnt = header->seqno;
-        } else {
-          if ((offset_cnt != header->seqno) && (start_flag == 0) && (proc->first_rx > 3)){
-#ifdef DEBUG_UL_MOBIPASS
-             LOG_D(PHY,"[Mobipass] Reset sequence number, offset_cnt:%d, header->seqno:%d, packet_id:%d\n", offset_cnt, header->seqno, packet_id);
-#endif
-             reset_flag=1;
-          }
-          if ((reset_flag == 1) && (proc->first_rx > 3 ) && (start_flag == 0) && (packet_id == 0)) {
-             packet_id = 1;  
-             reset_flag = 0;
-          }
-          start_flag = 0;
-
-          //store rxdata and increase packet_id
-          rxp[0] = (void*)&ru->common.rxdata[0][(subframe*ru->frame_parms->samples_per_tti)+packet_id*db_fulllength];
-          rxp128 = (__m128i *) (rxp[0]);
-          for (i=0; i<db_fulllength>>2; i+=2) {
-            r0 = _mm_loadu_si128(data_block++);
-            *rxp128++ =_mm_slli_epi16(_mm_srai_epi16(_mm_unpacklo_epi8(r0,r0),8),4);
-            *rxp128++ =_mm_slli_epi16(_mm_srai_epi16(_mm_unpackhi_epi8(r0,r0),8),4);
-          }   
-          packet_id++; 
-          offset_cnt = (header->seqno+1)&255;
-        }
-      }//end while
-    
-        *proc_timestamp = ntohl(timestamp_mobipass[0]); 
-#ifdef DEBUG_UL_MOBIPASS
-	LOG_I(PHY,"[Mobipass][Recv_MOBIPASS] timestamp: %llu\n ",  *proc_timestamp);
-	if (eNB->CC_id>0) {
-	  rxe = dB_fixed(signal_energy(rxp[0],fp->samples_per_tti)); 
-	  if (rxe > 0){
-	    LOG_I(PHY,"[Mobipass] frame:%d, subframe:%d, energy %d\n", (*proc_timestamp/(10*fp->samples_per_tti))&1023,subframe, rxe);
-	    
-	    //    LOG_M("rxsigmb.m","rxs",(void*)dummy_buffer_rx, fp->samples_per_tti,1, 5); 
-	    //    exit(-1);
-	  }
-	}
-#endif
-      free(rx_buffer);
+        // HYPOTHESIS: first packet per subframe has lowest timestamp of subframe
+        // should detect out of order and act accordingly ....
+        AssertFatal(aid==0 || aid==1,"aid %d != 0 or 1\n",aid);
+        //LOG_I(PHY,"rxp[%d] %p, dest %p, offset %d (%lld,%lld)\n",aid,rxp[aid],rxp[aid]+(timestamp[packet_id]-timestamp[0]),(timestamp[packet_id]-timestamp[0]),timestamp[packet_id],timestamp[0]);
+        memcpy((void*)(rxp[aid]+(timestamp[packet_id]-timestamp[0])),
+               (void*)temp_rx,
+               spp_eth<<2);
+        clock_gettime( CLOCK_MONOTONIC, &end_decomp);
+        LOG_D(HW,"[SF %d] IF_Read_Time: %"PRId64"\n",subframe,clock_difftime_ns(start_decomp, end_decomp));
+        //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF0, 0 );            
 
-     
+      }
     }
+    *proc_timestamp = timestamp[0];
   } else {
     AssertFatal(1==0, "recv_IF5 - Unknown packet_type %x", packet_type);     
   }  
diff --git a/openair1/PHY/LTE_TRANSPORT/prach.c b/openair1/PHY/LTE_TRANSPORT/prach.c
index d3ed2ed4391b04a3272107817204edceaae54e5b..31e97741fdb22e36ee2189206357d75a067626b0 100644
--- a/openair1/PHY/LTE_TRANSPORT/prach.c
+++ b/openair1/PHY/LTE_TRANSPORT/prach.c
@@ -89,7 +89,7 @@ void rx_prach0(PHY_VARS_eNB *eNB,
   int32_t *prach_ifft=(int32_t *)NULL;
   int32_t **prach_ifftp=(int32_t **)NULL;
   int prach_ifft_cnt=0;
-
+  int exit_flag=0;
   LTE_DL_FRAME_PARMS *fp;
   int nb_rx;
   if(eNB)  {
@@ -177,32 +177,33 @@ void rx_prach0(PHY_VARS_eNB *eNB,
   }
 
   AssertFatal(ru!=NULL,"ru is null\n");
-
+  int8_t dBEn0=0;
   for (aa=0; aa<nb_rx; aa++) {
-    if (ru->if_south == LOCAL_RF) { // set the time-domain signal if we have to use it in this node
+    if (ru->if_south == LOCAL_RF || ru->function == NGFI_RAU_IF5) { // set the time-domain signal if we have to use it in this node
       // DJP - indexing below in subframe zero takes us off the beginning of the array???
       prach[aa] = (int16_t *)&ru->common.rxdata[aa][(subframe*fp->samples_per_tti)-ru->N_TA_offset];
 
       if (LOG_DUMPFLAG(PRACH)) {
         int32_t en0=signal_energy((int32_t *)prach[aa],fp->samples_per_tti);
-        int8_t dbEn0 = dB_fixed(en0);
-        int8_t rach_dBm = dbEn0 - ru->rx_total_gain_dB;
+        dBEn0 = dB_fixed(en0);
+        int8_t rach_dBm = dBEn0 - ru->rx_total_gain_dB;
         char buffer[80];
 
-        if (dbEn0>32 && prach[0]!= NULL) {
+        if (dBEn0>30 && prach[0]!= NULL) {
           static int counter=0;
-          sprintf(buffer, "%s%d", "/tmp/prach_rx",counter);
-          LOG_M(buffer,"prach_rx",prach[0],fp->samples_per_tti,1,13);
+          sprintf(buffer, "%s%d", "/tmp/prach_rx.m",counter);
+          LOG_M(buffer,"prach_rx",prach[0],fp->samples_per_tti,1,1);
+          exit_flag=1;
         }
 
-        if (dB_fixed(en0)>32) {
+        if (dBEn0>30) {
           sprintf(buffer, "rach_dBm:%d",rach_dBm);
 
-          if (prach[0]!= NULL) LOG_M("prach_rx","prach_rx",prach[0],fp->samples_per_tti,1,1);
+          if (prach[0]!= NULL) LOG_M("prach_rx.m","prach_rx",prach[0],fp->samples_per_tti,1,1);
 
           LOG_I(PHY,"RU %d, br_flag %d ce_level %d frame %d subframe %d per_tti:%d prach:%p (energy %d) TA:%d %s rxdata:%p index:%d\n",
                 ru->idx,br_flag,ce_level,frame_prach,subframe,fp->samples_per_tti,
-                prach[aa],dbEn0,ru->N_TA_offset,buffer,ru->common.rxdata[aa],
+                prach[aa],dBEn0,ru->N_TA_offset,buffer,ru->common.rxdata[aa],
                 (subframe*fp->samples_per_tti)-ru->N_TA_offset);
         }
       }
@@ -415,7 +416,7 @@ void rx_prach0(PHY_VARS_eNB *eNB,
     if ( LOG_DEBUGFLAG(PRACH)) {
       int en = dB_fixed(signal_energy((int32_t *)&rxsigF[0][0],840));
 
-      if ((en > 60)&&(br_flag==1)) LOG_I(PHY,"PRACH (br_flag %d,ce_level %d, n_ra_prb %d, k %d): Frame %d, Subframe %d => %d dB\n",br_flag,ce_level,n_ra_prb,k,frame_prach,subframe,en);
+      if ((en > 10)&&(br_flag==1)) LOG_I(PHY,"PRACH (br_flag %d,ce_level %d, n_ra_prb %d, k %d): Frame %d, Subframe %d => %d dB\n",br_flag,ce_level,n_ra_prb,k,frame_prach,subframe,en);
     }
   }
 
@@ -454,9 +455,9 @@ void rx_prach0(PHY_VARS_eNB *eNB,
 
   for (preamble_index=0 ; preamble_index<64 ; preamble_index++) {
     if (LOG_DEBUGFLAG(PRACH)) {
-      int en = dB_fixed(signal_energy((int32_t *)&rxsigF[0][0],840));
+    //  int en = dB_fixed(signal_energy((int32_t *)&rxsigF[0][0],840));
 
-      if (en>60) LOG_I(PHY,"frame %d, subframe %d : Trying preamble %d (br_flag %d)\n",frame_prach,subframe,preamble_index,br_flag);
+      if (dBEn0>30) LOG_I(PHY,"frame %d, subframe %d : Trying preamble %d (br_flag %d)\n",frame_prach,subframe,preamble_index,br_flag);
     }
 
     if (restricted_set == 0) {
@@ -539,10 +540,10 @@ void rx_prach0(PHY_VARS_eNB *eNB,
 
     // Compute DFT of RX signal (conjugate input, results in conjugate output) for each new rootSequenceIndex
     if (LOG_DEBUGFLAG(PRACH)) {
-      int en = dB_fixed(signal_energy((int32_t *)&rxsigF[0][0],840));
+      //en = dB_fixed(signal_energy((int32_t *)&rxsigF[0][0],840));
 
-      if (en>60) LOG_I(PHY,"frame %d, subframe %d : preamble index %d: offset %d, preamble shift %d (br_flag %d, en %d)\n",
-                         frame_prach,subframe,preamble_index,preamble_offset,preamble_shift,br_flag,en);
+      if (dBEn0>30) LOG_I(PHY,"frame %d, subframe %d : preamble index %d: offset %d, preamble shift %d (br_flag %d, en %d)\n",
+                         frame_prach,subframe,preamble_index,preamble_offset,preamble_shift,br_flag,dBEn0);
     }
 
     log2_ifft_size = 10;
@@ -564,13 +565,13 @@ void rx_prach0(PHY_VARS_eNB *eNB,
 
       memset(prachF, 0, sizeof(int16_t)*2*1024 );
 
-      if (LOG_DUMPFLAG(PRACH)) {
+    if (LOG_DUMPFLAG(PRACH)) {
         if (prach[0]!= NULL) LOG_M("prach_rx0.m","prach_rx0",prach[0],6144+792,1,1);
 
         LOG_M("prach_rx1.m","prach_rx1",prach[1],6144+792,1,1);
         LOG_M("prach_rxF0.m","prach_rxF0",rxsigF[0],12288,1,1);
         LOG_M("prach_rxF1.m","prach_rxF1",rxsigF[1],12288,1,1);
-      }
+    }
 
       for (aa=0; aa<nb_rx; aa++) {
         // Do componentwise product with Xu* on each antenna
@@ -633,9 +634,9 @@ void rx_prach0(PHY_VARS_eNB *eNB,
           *max_preamble         = preamble_index;
 
           if (LOG_DEBUGFLAG(PRACH)) {
-            int en = dB_fixed(signal_energy((int32_t *)&rxsigF[0][0],840));
+        //    int en = dB_fixed(signal_energy((int32_t *)&rxsigF[0][0],840));
 
-            if ((en>60) && (br_flag==1))
+            if (dBEn0>30)
               LOG_D(PHY,"frame %d, subframe %d : max_preamble_energy %d, max_preamble_delay %d, max_preamble %d (br_flag %d,ce_level %d, levdB %d, lev %d)\n",
                     frame_prach,subframe,
                     *max_preamble_energy,*max_preamble_delay,
@@ -648,10 +649,10 @@ void rx_prach0(PHY_VARS_eNB *eNB,
 
   *avg_preamble_energy=dB_fixed(avg_en/64);
 
-  if (LOG_DUMPFLAG(PRACH)) {
+  if (exit_flag==1) {
     int en = dB_fixed(signal_energy((int32_t *)&rxsigF[0][0],840));
 
-    if (en>60) {
+    if (en>30) {
       k = (12*n_ra_prb) - 6*fp->N_RB_UL;
 
       if (k<0) k+=fp->ofdm_symbol_size;
@@ -665,19 +666,20 @@ void rx_prach0(PHY_VARS_eNB *eNB,
         LOG_M("prach_rxF_comp0.m","prach_rxF_comp0",prachF,1024,1,1);
         LOG_M("Xu.m","xu",Xu,N_ZC,1,1);
         LOG_M("prach_ifft0.m","prach_t0",prach_ifft,1024,1,1);
-        exit(-1);
+        LOG_M("SF2_3.m","sf2_3",&ru->common.rxdata[0][2*fp->samples_per_tti],2*fp->samples_per_tti,1,1);
       } else {
         LOG_E(PHY,"Dumping prach (br_flag %d), k = %d (n_ra_prb %d)\n",br_flag,k,n_ra_prb);
         LOG_M("rxsigF_br.m","prach_rxF_br",&rxsigF[0][0],12288,1,1);
         LOG_M("prach_rxF_comp0_br.m","prach_rxF_comp0_br",prachF,1024,1,1);
         LOG_M("Xu_br.m","xu_br",Xu,N_ZC,1,1);
         LOG_M("prach_ifft0_br.m","prach_t0_br",prach_ifft,1024,1,1);
-        exit(-1);
       }
     }
   } /* LOG_DUMPFLAG(PRACH) */
 
   if (eNB) stop_meas(&eNB->rx_prach);
+  AssertFatal(exit_flag==0,"exiting\n");
+
 }
 
 
diff --git a/openair1/PHY/MODULATION/ofdm_mod.c b/openair1/PHY/MODULATION/ofdm_mod.c
index 92aea419af0064e43a0083b208c1183c7008a4fc..2d86b46742449b308ee24c93de1225b5ebe19a66 100644
--- a/openair1/PHY/MODULATION/ofdm_mod.c
+++ b/openair1/PHY/MODULATION/ofdm_mod.c
@@ -90,9 +90,8 @@ void PHY_ofdm_mod(int *input,                       /// pointer to complex input
 
   if(nb_symbols == 0) return;
 
-  short temp[2*2*6144*4] __attribute__((aligned(32)));
-  unsigned short i,j;
-  short k;
+  int16_t temp[2*2*6144*4] __attribute__((aligned(32)));
+  int i,j;
 
   volatile int *output_ptr=(int*)0;
 
@@ -190,18 +189,9 @@ void PHY_ofdm_mod(int *input,                       /// pointer to complex input
       if (fftsize==128) 
 #endif
       {
-        /*for (j=0; j<fftsize ; j++) {
-          output_ptr[j] = temp_ptr[j];
-        }*/
-        memcpy1((void*)output_ptr,(void*)temp_ptr,fftsize<<2);
+        memcpy((void*)output_ptr,(void*)temp_ptr,fftsize<<2);
       }
-
-      j=fftsize;
-
-      for (k=-1; k>=-nb_prefix_samples; k--) {
-        output_ptr[k] = output_ptr[--j];
-      }
-
+      memcpy((void*)&output_ptr[-nb_prefix_samples],(void*)&output_ptr[fftsize-nb_prefix_samples],nb_prefix_samples<<2);
       break;
 
     case CYCLIC_SUFFIX:
diff --git a/openair1/PHY/defs_eNB.h b/openair1/PHY/defs_eNB.h
index 557b8bfc30e0108105f79f7d3328ee6bf2b05bc7..f1021ead9b2ab9fb2bc36a4e59e051e492aec26a 100644
--- a/openair1/PHY/defs_eNB.h
+++ b/openair1/PHY/defs_eNB.h
@@ -389,6 +389,8 @@ typedef struct {
   short n0_subband_power_tot_dB[100];
   //! estimated avg noise power per RB (dBm)
   short n0_subband_power_tot_dBm[100];
+  //! etimated avg noise power over all RB (dB)
+  short n0_subband_power_avg_dB;
   // eNB measurements (per user)
   //! estimated received spatial signal power (linear)
   unsigned int   rx_spatial_power[NUMBER_OF_UE_MAX][2][2];
diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c
index 5f0ff6cff09d71602204424d2604f776e3019b41..a37f95bcb341b7d7470d6606003d91e1a08b7d3e 100644
--- a/openair1/SCHED/phy_procedures_lte_eNb.c
+++ b/openair1/SCHED/phy_procedures_lte_eNb.c
@@ -757,8 +757,8 @@ void fill_sr_indication(int UEid, PHY_VARS_eNB *eNB,uint16_t rnti,int frame,int
   //  pdu->rx_ue_information.handle                       = handle;
   pdu->rx_ue_information.tl.tag                       = NFAPI_RX_UE_INFORMATION_TAG;
   pdu->rx_ue_information.rnti                         = rnti;
-  int SNRtimes10 = dB_fixed_times10(stat) - 10 * eNB->measurements.n0_subband_power_dB[0][0];
-  LOG_D(PHY,"stat %d subbandpower %d, SNRtimes10 %d\n", stat, eNB->measurements.n0_subband_power_dB[0][0], SNRtimes10);
+  int SNRtimes10 = dB_fixed_times10(stat) - 10 * eNB->measurements.n0_subband_power_avg_dB;
+  LOG_D(PHY,"stat %d subband n0 %d, SNRtimes10 %d\n", stat, eNB->measurements.n0_subband_power_avg_dB, SNRtimes10);
   pdu->ul_cqi_information.tl.tag = NFAPI_UL_CQI_INFORMATION_TAG;
 
   if      (SNRtimes10 < -640) pdu->ul_cqi_information.ul_cqi=0;
@@ -1604,8 +1604,8 @@ void fill_rx_indication(PHY_VARS_eNB *eNB,
     timing_advance_update = 63;
 
   pdu->rx_indication_rel8.timing_advance = timing_advance_update;
-  // estimate UL_CQI for MAC (from antenna port 0 only)
-  int SNRtimes10 = dB_fixed_times10(eNB->pusch_vars[UE_id]->ulsch_power[0]) - 10 * eNB->measurements.n0_subband_power_dB[0][0];
+  // estimate UL_CQI for MAC 
+  int SNRtimes10 = dB_fixed_times10(eNB->pusch_vars[UE_id]->ulsch_power[0] + ((eNB->frame_parms.nb_antennas_rx>1) ?eNB->pusch_vars[UE_id]->ulsch_power[1] : 0 )) - 10 * eNB->measurements.n0_subband_power_avg_dB;
 
   if (SNRtimes10 < -640)
     pdu->rx_indication_rel8.ul_cqi = 0;
@@ -1614,8 +1614,8 @@ void fill_rx_indication(PHY_VARS_eNB *eNB,
   else
     pdu->rx_indication_rel8.ul_cqi = (640 + SNRtimes10) / 5;
 
-  LOG_D(PHY,"[PUSCH %d] Frame %d Subframe %d Filling RX_indication with SNR %d (%d), timing_advance %d (update %d)\n",
-        harq_pid,frame,subframe,SNRtimes10,pdu->rx_indication_rel8.ul_cqi,pdu->rx_indication_rel8.timing_advance,
+  LOG_D(PHY,"[PUSCH %d] Frame %d Subframe %d Filling RX_indication with SNR %d (%d,%d), timing_advance %d (update %d)\n",
+        harq_pid,frame,subframe,SNRtimes10,pdu->rx_indication_rel8.ul_cqi,eNB->measurements.n0_subband_power_avg_dB,pdu->rx_indication_rel8.timing_advance,
         timing_advance_update);
   eNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus++;
   eNB->UL_INFO.rx_ind.sfn_sf = frame<<4 | subframe;
@@ -1919,7 +1919,7 @@ void fill_uci_harq_indication (int UEid, PHY_VARS_eNB *eNB, LTE_eNB_UCI *uci, in
   pdu->rx_ue_information.rnti                         = uci->rnti;
   // estimate UL_CQI for MAC (from antenna port 0 only)
   pdu->ul_cqi_information.tl.tag = NFAPI_UL_CQI_INFORMATION_TAG;
-  int SNRtimes10 = dB_fixed_times10(uci->stat) - 10 * eNB->measurements.n0_subband_power_dB[0][0];
+  int SNRtimes10 = dB_fixed_times10(uci->stat) - 10 * eNB->measurements.n0_subband_power_avg_dB;
 
   if (SNRtimes10 < -100)
     LOG_I (PHY, "uci->stat %d \n", uci->stat);
@@ -2132,17 +2132,17 @@ void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) {
 
   lte_eNB_I0_measurements (eNB, subframe, 0, eNB->first_run_I0_measurements);
   int min_I0=1000,max_I0=0;
-
-  if ((frame==0) && (subframe==4)) {
+  int amin=0,amax=0;
+  if ((frame==0) && (subframe==3)) {
     for (int i=0; i<eNB->frame_parms.N_RB_UL; i++) {
       if (i==(eNB->frame_parms.N_RB_UL>>1) - 1) i+=2;
 
-      if (eNB->measurements.n0_subband_power_tot_dB[i]<min_I0) min_I0 = eNB->measurements.n0_subband_power_tot_dB[i];
+      if (eNB->measurements.n0_subband_power_tot_dB[i]<min_I0) {min_I0 = eNB->measurements.n0_subband_power_tot_dB[i]; amin=i;}
 
-      if (eNB->measurements.n0_subband_power_tot_dB[i]>max_I0) max_I0 = eNB->measurements.n0_subband_power_tot_dB[i];
+      if (eNB->measurements.n0_subband_power_tot_dB[i]>max_I0) {max_I0 = eNB->measurements.n0_subband_power_tot_dB[i]; amax=i;}
     }
 
-    LOG_I (PHY, "max_I0 %d, min_I0 %d\n", max_I0, min_I0);
+    LOG_I (PHY, "max_I0 %d (rb %d), min_I0 %d (rb %d), avg I0 %d\n", max_I0, amax, min_I0, amin, eNB->measurements.n0_subband_power_avg_dB);
   }
 
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX_UESPEC, 0 );
diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c
index 12aace577c72e1f8aa7b34c7022f46cf71c02706..d3f55785c9f7e9940b70c6d46dc99d1c3bfc009b 100644
--- a/openair1/SIMULATION/LTE_PHY/dlsim.c
+++ b/openair1/SIMULATION/LTE_PHY/dlsim.c
@@ -487,7 +487,7 @@ int n_ch_rlz = 1;
 int rx_sample_offset = 0;
 int xforms=0;
 int dump_table=0;
-int loglvl=OAILOG_WARNING;
+int loglvl=OAILOG_INFO;
 int mcs1=0,mcs2=0,mcs_i=0,dual_stream_UE = 0,awgn_flag=0;
 int two_thread_flag=0;
 int num_rounds = 4;//,fix_rounds=0;
@@ -670,7 +670,7 @@ int main(int argc, char **argv) {
     { "XForms", "Display the soft scope", PARAMFLAG_BOOL, iptr:&xforms,  defintval:0, TYPE_INT, 0 },
     { "Yperfect_ce","Perfect CE", PARAMFLAG_BOOL, iptr:&perfect_ce,  defintval:0, TYPE_INT, 0 },
     { "Zdump", "dump table",PARAMFLAG_BOOL,  iptr:&dump_table, defintval:0, TYPE_INT, 0 },
-    { "Loglvl", "log level",0, iptr:&loglvl,  defintval:OAILOG_DEBUG, TYPE_INT, 0 },
+    { "Loglvl", "log level",0, iptr:&loglvl,  defintval:OAILOG_INFO, TYPE_INT, 0 },
     { "zn_rx", "Number of RX antennas used in UE",0, iptr:NULL,  defintval:2, TYPE_INT, 0 },
     { "gchannel", "[A:M] Use 3GPP 25.814 SCM-A/B/C/D('A','B','C','D') or 36-101 EPA('E'), EVA ('F'),ETU('G') models (ignores delay spread and Ricean factor), Rayghleigh8 ('H'), Rayleigh1('I'), Rayleigh1_corr('J'), Rayleigh1_anticorr ('K'),  Rice8('L'), Rice1('M')",0, strptr:NULL,  defstrval:NULL, TYPE_STRING, 0 },
     { "verbose", "display debug text", PARAMFLAG_BOOL,  iptr:&verbose, defintval:0, TYPE_INT, 0 },
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
index 997fc6691e7da517f8430319029e7ef62b8a76f2..b62df74082faa98060dbede5563095dd0cd5b9ed 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
@@ -182,7 +182,7 @@ rx_sdu(const module_id_t enb_mod_idP,
         UE_template_ptr->scheduled_ul_bytes = 0;
       }
     } else {  // sduP == NULL => error
-      LOG_W(MAC, "[eNB %d][PUSCH %d] CC_id %d %d.%d ULSCH in error in round %d, ul_cqi %d, UE_id %d, RNTI %x (len %d)\n",
+      LOG_D(MAC, "[eNB %d][PUSCH %d] CC_id %d %d.%d ULSCH in error in round %d, ul_cqi %d, UE_id %d, RNTI %x (len %d)\n",
             enb_mod_idP,
             harq_pid,
             CC_idP,
diff --git a/openair2/X2AP/x2ap_eNB_generate_messages.c b/openair2/X2AP/x2ap_eNB_generate_messages.c
index e066535df931cb6b77b1df610d1b3ba46b7433fd..23973328f28d69f98cc5338ed0ebb62bd4664425 100644
--- a/openair2/X2AP/x2ap_eNB_generate_messages.c
+++ b/openair2/X2AP/x2ap_eNB_generate_messages.c
@@ -1439,7 +1439,7 @@ int x2ap_eNB_generate_ENDC_x2_setup_response(
           }
 
           if (instance_p->frame_type[i] == FDD) {
-                  servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.present = X2AP_EUTRA_Mode_Info_PR_fDD;
+            servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.present = X2AP_EUTRA_Mode_Info_PR_fDD;
             servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.fDD.dL_EARFCN = instance_p->fdd_earfcn_DL[i];
             servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.fDD.uL_EARFCN = instance_p->fdd_earfcn_UL[i];
         	  switch (instance_p->N_RB_DL[i]) {
@@ -1473,12 +1473,98 @@ int x2ap_eNB_generate_ENDC_x2_setup_response(
             }
           }
           else {
-        	  AssertFatal(0,"X2Setupresponse not supported for TDD!");
+            servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.present = X2AP_EUTRA_Mode_Info_PR_tDD;
+            servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.eARFCN = instance_p->fdd_earfcn_DL[i];
+
+            switch (instance_p->subframeAssignment[i]) {
+            case 0:
+              servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa0;
+              break;
+            case 1:
+              servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa1;
+              break;
+            case 2:
+              servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa2;
+              break;
+            case 3:
+              servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa3;
+              break;
+            case 4:
+              servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa4;
+              break;
+            case 5:
+              servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa5;
+              break;
+            case 6:
+              servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa6;
+              break;
+            default:
+              AssertFatal(0,"Failed: Check value for subframeAssignment");
+              break;
+            }
+            switch (instance_p->specialSubframe[i]) {
+            case 0:
+              servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp0;
+              break;
+            case 1:
+              servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp1;
+              break;
+            case 2:
+              servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp2;
+              break;
+            case 3:
+              servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp3;
+              break;
+            case 4:
+              servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp4;
+              break;
+            case 5:
+              servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp5;
+              break;
+            case 6:
+              servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp6;
+              break;
+            case 7:
+              servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp7;
+              break;
+            case 8:
+              servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp8;
+              break;
+            default:
+              AssertFatal(0,"Failed: Check value for subframeAssignment");
+              break;
+            }
+            servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.cyclicPrefixDL=X2AP_CyclicPrefixDL_normal;
+            servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.cyclicPrefixUL=X2AP_CyclicPrefixUL_normal;
+
+            switch (instance_p->N_RB_DL[i]) {
+            case 6:
+              servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw6;
+              break;
+            case 15:
+              servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw15;
+              break;
+            case 25:
+              servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw25;
+              break;
+            case 50:
+              servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw50;
+              break;
+            case 75:
+              servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw75;
+              break;
+            case 100:
+              servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw100;
+              break;
+            default:
+              AssertFatal(0,"Failed: Check value for N_RB_DL/N_RB_UL");
+              break;
+            }
           }
         }
-        ASN_SEQUENCE_ADD(&ie_ENB_ENDC->value.choice.ServedEUTRAcellsENDCX2ManagementList.list, servedCellMember);
+      ASN_SEQUENCE_ADD(&ie_ENB_ENDC->value.choice.ServedEUTRAcellsENDCX2ManagementList.list, servedCellMember);
       }
-    }
+  }
   ASN_SEQUENCE_ADD(&ie->value.choice.RespondingNodeType_EndcX2Setup.choice.respond_eNB.list, ie_ENB_ENDC);
 
 
diff --git a/targets/ARCH/COMMON/common_lib.c b/targets/ARCH/COMMON/common_lib.c
index 3066f0906fd8a193dffc12e257a4a40424124ae9..3a69d4c991f1de68e057875691d718f1433e5d9f 100644
--- a/targets/ARCH/COMMON/common_lib.c
+++ b/targets/ARCH/COMMON/common_lib.c
@@ -112,6 +112,9 @@ int load_lib(openair0_device *device,
 	  else
           deflibname=OAI_RF_LIBNAME;
       shlib_fdesc[0].fname="device_init";
+  } else if (flag == RAU_REMOTE_THIRDPARTY_RADIO_HEAD) {
+    deflibname=OAI_THIRDPARTY_TP_LIBNAME;
+    shlib_fdesc[0].fname="transport_init";
   } else {
 	  deflibname=OAI_TP_LIBNAME;
 	  shlib_fdesc[0].fname="transport_init";
diff --git a/targets/ARCH/COMMON/common_lib.h b/targets/ARCH/COMMON/common_lib.h
index 778c8165eb8b5b9198745834231c29fecc7c77af..85ee80ea7cdf443a01559cb27cdc265f09ababa2 100644
--- a/targets/ARCH/COMMON/common_lib.h
+++ b/targets/ARCH/COMMON/common_lib.h
@@ -41,6 +41,8 @@
 #define OAI_RF_LIBNAME        "oai_device"
 /* name of shared library implementing the transport */
 #define OAI_TP_LIBNAME        "oai_transpro"
+/* name of shared library implementing a third-party transport */
+#define OAI_THIRDPARTY_TP_LIBNAME        "thirdparty_transpro"
 /* name of shared library implementing the rf simulator */
 #define OAI_RFSIM_LIBNAME     "rfsimulator"
 /* name of shared library implementing the basic simulator */
@@ -51,10 +53,9 @@
 /* flags for BBU to determine whether the attached radio head is local or remote */
 #define RAU_LOCAL_RADIO_HEAD  0
 #define RAU_REMOTE_RADIO_HEAD 1
-
+#define RAU_REMOTE_THIRDPARTY_RADIO_HEAD 2
 #define MAX_WRITE_THREAD_PACKAGE     10
 #define MAX_WRITE_THREAD_BUFFER_SIZE 8
-
 #ifndef MAX_CARDS
   #define MAX_CARDS 8
 #endif
@@ -367,13 +368,23 @@ struct openair0_device_t {
   /*! \brief Called to send samples to the RF target
       @param device pointer to the device structure specific to the RF hardware target
       @param timestamp The timestamp at whicch the first sample MUST be sent
-      @param buff Buffer which holds the samples
+      @param buff Buffer which holds the samples (2 dimensional)
       @param nsamps number of samples to be sent
-      @param antenna_id index of the antenna if the device has multiple anteannas
+      @param number of antennas 
       @param flags flags must be set to TRUE if timestamp parameter needs to be applied
   */
   int (*trx_write_func)(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps,int antenna_id, int flags);
 
+  /*! \brief Called to send samples to the RF target
+      @param device pointer to the device structure specific to the RF hardware target
+      @param timestamp The timestamp at whicch the first sample MUST be sent
+      @param buff Buffer which holds the samples (1 dimensional)
+      @param nsamps number of samples to be sent
+      @param antenna_id index of the antenna if the device has multiple anteannas
+      @param flags flags must be set to TRUE if timestamp parameter needs to be applied
+  */
+  int (*trx_write_func2)(openair0_device *device, openair0_timestamp timestamp, void *buff, int nsamps,int antenna_id, int flags);
+
   /*! \brief Receive samples from hardware.
    * Read \ref nsamps samples from each channel to buffers. buff[0] is the array for
    * the first channel. *ptimestamp is the time at which the first sample
@@ -382,10 +393,24 @@ struct openair0_device_t {
    * \param[out] ptimestamp the time at which the first sample was received.
    * \param[out] buff An array of pointers to buffers for received samples. The buffers must be large enough to hold the number of samples \ref nsamps.
    * \param nsamps Number of samples. One sample is 2 byte I + 2 byte Q => 4 byte.
-   * \param antenna_id Index of antenna for which to receive samples
+   * \param num_antennas number of antennas from which to receive samples
    * \returns the number of sample read
    */
-  int (*trx_read_func)(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps,int antenna_id);
+
+  int (*trx_read_func)(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps,int num_antennas);
+
+  /*! \brief Receive samples from hardware, this version provides a single antenna at a time and returns.
+   * Read \ref nsamps samples from each channel to buffers. buff[0] is the array for
+   * the first channel. *ptimestamp is the time at which the first sample
+   * was received.
+   * \param device the hardware to use
+   * \param[out] ptimestamp the time at which the first sample was received.
+   * \param[out] buff A pointers to a buffer for received samples. The buffer must be large enough to hold the number of samples \ref nsamps.
+   * \param nsamps Number of samples. One sample is 2 byte I + 2 byte Q => 4 byte.
+   * \param antenna_id Index of antenna from which samples were received
+   * \returns the number of sample read
+   */
+  int (*trx_read_func2)(openair0_device *device, openair0_timestamp *ptimestamp, void *buff, int nsamps,int *antenna_id);
 
   /*! \brief print the device statistics
    * \param device the hardware to use
@@ -431,6 +456,25 @@ struct openair0_device_t {
    */
   void (*configure_rru)(int idx, void *arg);
 
+/*! \brief Pointer to generic RRU private information
+   */
+
+  void *thirdparty_priv;
+
+  /*! \brief Callback for Third-party RRU Initialization routine
+     \param device the hardware configuration to use
+   */
+  int (*thirdparty_init)(openair0_device *device);
+  /*! \brief Callback for Third-party RRU Cleanup routine
+     \param device the hardware configuration to use
+   */
+  int (*thirdparty_cleanup)(openair0_device *device);
+
+  /*! \brief Callback for Third-party start streaming routine
+     \param device the hardware configuration to use
+   */
+  int (*thirdparty_startstreaming)(openair0_device *device);
+
   /*! \brief RRU Configuration callback
    * \param idx RU index
    * \param arg pointer to capabilities or configuration
diff --git a/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c b/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c
index d893c66b526bf2602b80b21f86b556cb92095c4e..9c0a9e3f6530bdd0788d736291ea2bbee6e3786c 100644
--- a/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c
+++ b/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c
@@ -102,23 +102,15 @@ int eth_socket_init_raw(openair0_device *device) {
   eth->local_addrd_ll.sll_family   = AF_PACKET;
   eth->local_addrd_ll.sll_ifindex  = eth->if_index.ifr_ifindex;
   /* hear traffic from specific protocol*/
-  if (eth->flags == ETH_RAW_IF5_MOBIPASS) {
-     eth->local_addrd_ll.sll_protocol = htons(0xbffe);
-  } else{ 
-     eth->local_addrc_ll.sll_protocol = htons((short)device->eth_params->my_portc);
-     eth->local_addrd_ll.sll_protocol = htons((short)device->eth_params->my_portd);
-  }
+  eth->local_addrc_ll.sll_protocol = htons((short)device->eth_params->my_portc);
+  eth->local_addrd_ll.sll_protocol = htons((short)device->eth_params->my_portd);
+  
   eth->local_addrc_ll.sll_halen    = ETH_ALEN;
   eth->local_addrc_ll.sll_pkttype  = PACKET_OTHERHOST;
   eth->local_addrd_ll.sll_halen    = ETH_ALEN;
   eth->local_addrd_ll.sll_pkttype  = PACKET_OTHERHOST;
   eth->addr_len = sizeof(struct sockaddr_ll);
   
-  if ((eth->flags != ETH_RAW_IF5_MOBIPASS ) && 
-      (bind(eth->sockfdc,(struct sockaddr *)&eth->local_addrc_ll,eth->addr_len)<0)) {
-    perror("ETHERNET: Cannot bind to socket (control)");
-    exit(0);
-  }
   if (bind(eth->sockfdd,(struct sockaddr *)&eth->local_addrd_ll,eth->addr_len)<0) {
     perror("ETHERNET: Cannot bind to socket (user)");
     exit(0);
@@ -127,12 +119,9 @@ int eth_socket_init_raw(openair0_device *device) {
  /* Construct the Ethernet header */ 
  ether_aton_r(local_mac, (struct ether_addr *)(&(eth->ehd.ether_shost)));
  ether_aton_r(remote_mac, (struct ether_addr *)(&(eth->ehd.ether_dhost)));
- if (eth->flags == ETH_RAW_IF5_MOBIPASS) {
-   eth->ehd.ether_type = htons(0xbffe);
- } else {
-   eth->ehc.ether_type = htons((short)device->eth_params->my_portc);
-   eth->ehd.ether_type = htons((short)device->eth_params->my_portd);
- } 
+ eth->ehc.ether_type = htons((short)device->eth_params->my_portc);
+ eth->ehd.ether_type = htons((short)device->eth_params->my_portd);
+  
  printf("[%s] binding to hardware address %x:%x:%x:%x:%x:%x\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"),eth->ehd.ether_shost[0],eth->ehd.ether_shost[1],eth->ehd.ether_shost[2],eth->ehd.ether_shost[3],eth->ehd.ether_shost[4],eth->ehd.ether_shost[5]);
  
  return 0;
@@ -216,8 +205,6 @@ int trx_eth_write_raw_IF4p5(openair0_device *device, openair0_timestamp timestam
     packet_size = RAW_IF4p5_PULFFT_SIZE_BYTES(nblocks);    
   } else if (flags == IF4p5_PULTICK) {
     packet_size = RAW_IF4p5_PULTICK_SIZE_BYTES;    
-  } else if (flags == IF5_MOBIPASS) {
-    packet_size = RAW_IF5_MOBIPASS_SIZE_BYTES;
   } else {
     packet_size = RAW_IF4p5_PRACH_SIZE_BYTES;
   }
@@ -430,53 +417,6 @@ int trx_eth_read_raw_IF4p5(openair0_device *device, openair0_timestamp *timestam
 }
 
 
-int trx_eth_read_raw_IF5_mobipass(openair0_device *device, openair0_timestamp *timestamp, void **buff, int nsamps, int cc) {
-  // Read nblocks info from packet itself
-  
-  int bytes_received=0;
-  eth_state_t *eth = (eth_state_t*)device->priv;
-  int ret;
-
-  ssize_t packet_size =  28; //MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t ;
-//   ssize_t packet_size =  MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t + 640*sizeof(int16_t);
- 
-  bytes_received = recv(eth->sockfdd,
-                        buff[0],
-                        packet_size,
-                        MSG_PEEK);
-
-  if (bytes_received ==-1) {
-          eth->num_rx_errors++;
-          perror("[MOBIPASS]ETHERNET IF5 READ (header): ");
-          exit(-1);
-  }
-
-  IF5_mobipass_header_t *test_header = (IF5_mobipass_header_t*)((uint8_t *)buff[0] + MAC_HEADER_SIZE_BYTES);
-  *timestamp = test_header->time_stamp;
-  packet_size =  MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t + 640*sizeof(int16_t);
-
-  while(bytes_received < packet_size) {
-    ret = recv(eth->sockfdd,
-	       buff[0],
-	       packet_size,
-	       0);
-    if (bytes_received ==-1) {
-      eth->num_rx_errors++;
-      perror("[MOBIPASS] ETHERNET IF5 READ (payload): ");
-      return(-1);
-    } else {
-      bytes_received+=ret;
-      eth->rx_actual_nsamps = bytes_received>>1;
-      eth->rx_count++;
-    }
-  }
- 
-  eth->rx_nsamps = nsamps;
-  return(bytes_received);
-
-
-}
-
 int eth_set_dev_conf_raw(openair0_device *device) {
 
   eth_state_t *eth = (eth_state_t*)device->priv;
diff --git a/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_udp.c b/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_udp.c
index 473d129aafe5151cbcde95774f9c80e05809d5aa..2dfb4a7bf1321c253105a0e0971bd9cdfa60b6d3 100644
--- a/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_udp.c
+++ b/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_udp.c
@@ -47,7 +47,7 @@
 #include "ethernet_lib.h"
 #include "common/ran_context.h"
 
-#define DEBUG 0
+//#define DEBUG 1
 
 // These are for IF5 and must be put into the device structure if multiple RUs in the same RAU !!!!!!!!!!!!!!!!!
 uint16_t pck_seq_num = 1;
@@ -142,8 +142,8 @@ int eth_socket_init_udp(openair0_device *device) {
     perror("ETHERNET: Cannot set SO_REUSEADDR option on socket (control)");
     exit(0);
   }
-  if (setsockopt(eth->sockfdd, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int))) {
-    perror("ETHERNET: Cannot set SO_REUSEADDR option on socket (user)");
+  if (setsockopt(eth->sockfdd, SOL_SOCKET, SO_NO_CHECK, &enable, sizeof(int))) {
+    perror("ETHERNET: Cannot set SO_NO_CHECK option on socket (user)");
     exit(0);
   }
   
@@ -202,8 +202,9 @@ int trx_eth_read_udp_IF4p5(openair0_device *device, openair0_timestamp *timestam
           goto again;
         }
       } else {
-        perror("ETHERNET IF4p5 READ");
-        printf("(%s):\n", strerror(errno));
+	return(-1);
+        //perror("ETHERNET IF4p5 READ");
+        //printf("(%s):\n", strerror(errno));
       }
     } else {
       *timestamp = test_header->sub_type;
@@ -264,36 +265,82 @@ int trx_eth_write_udp_IF4p5(openair0_device *device, openair0_timestamp timestam
   return (bytes_sent);  	  
 }
 
-int trx_eth_write_udp(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps,int cc, int flags) {	
+int trx_eth_write_udp(openair0_device *device, openair0_timestamp timestamp, void *buff, int nsamps,int cc, int flags) {	
   
   int bytes_sent=0;
   eth_state_t *eth = (eth_state_t*)device->priv;
   int sendto_flag =0;
-  int i=0;
+
   //sendto_flag|=flags;
   eth->tx_nsamps=nsamps;
 
  
 
-  for (i=0;i<cc;i++) {	
-    /* buff[i] points to the position in tx buffer where the payload to be sent is
-       buff2 points to the position in tx buffer where the packet header will be placed */
-    void *buff2 = (void*)(buff[i]- APP_HEADER_SIZE_BYTES); 
+
+  int nsamps2;  // aligned to upper 32 or 16 byte boundary
+  
+#if defined(__x86_64) || defined(__i386__)
+#ifdef __AVX2__
+  nsamps2 = (nsamps+7)>>3;
+  __m256i buff_tx[nsamps2+1];
+  __m256i *buff_tx2=buff_tx+1;
+#else
+  nsamps2 = (nsamps+3)>>2;
+  __m128i buff_tx[nsamps2+2];
+  __m128i *buff_tx2=buff_tx+2;
+#endif
+#elif defined(__arm__) || defined(__aarch64__)
+  nsamps2 = (nsamps+3)>>2;
+  int16x8_t buff_tx[nsamps2+2];
+  int16x8_t *buff_tx2=buff_tx+2;
+#else
+#error Unsupported CPU architecture, ethernet device cannot be built
+#endif
+
     
-    /* we don't want to ovewrite with the header info the previous tx buffer data so we store it*/
-    int32_t temp0 = *(int32_t *)buff2;
-    openair0_timestamp  temp1 = *(openair0_timestamp *)(buff2 + sizeof(int32_t));
+    // bring TX data into 12 LSBs for softmodem RX
+  for (int j=0; j<nsamps2; j++) {
+#if defined(__x86_64__) || defined(__i386__)
+#ifdef __AVX2__
+    buff_tx2[j] = _mm256_slli_epi16(((__m256i *)buff)[j],4);
+#else
+    buff_tx2[j] = _mm_slli_epi16(((__m128i *)buff)[j],4);
+#endif
+#elif defined(__arm__)
+    buff_tx2[j] = vshlq_n_s16(((int16x8_t *)buff)[j],4);
+#endif
+  }
+
+        /* buff[i] points to the position in tx buffer where the payload to be sent is
+       buff2 points to the position in tx buffer where the packet header will be placed */
+    void *buff2 = ((void*)buff_tx2)- APP_HEADER_SIZE_BYTES; 
     
+   
+ 
     bytes_sent = 0;
     
     /* constract application header */
-    // eth->pck_header.seq_num = pck_seq_num;
-    //eth->pck_header.antenna_id = 1+(i<<1);
-    //eth->pck_header.timestamp = timestamp;
-    *(uint16_t *)buff2 = eth->pck_seq_num;
-    *(uint16_t *)(buff2 + sizeof(uint16_t)) = 1+(i<<1);
-    *(openair0_timestamp *)(buff2 + sizeof(int32_t)) = timestamp;
-    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TX_SEQ_NUM, eth->pck_seq_num);
+    // ECPRI Protocol revision + reserved bits (1 byte)
+    *(uint8_t *)buff2 = ECPRIREV;
+    // ECPRI Message type (1 byte)
+    *(uint8_t *)(buff2 + 1) = 64;
+    // ECPRI Payload Size (2 bytes)
+    AssertFatal(nsamps<16381,"nsamps > 16381\n");
+    *(uint8_t *)(buff2 + 2) = (nsamps<<2)>>8;
+    *(uint8_t *)(buff2 + 3) = (nsamps<<2)&0xff;
+    // ECPRI PC_ID (2 bytes)
+    *(uint16_t *)(buff2 + 4) = cc;
+    // OAI modified SEQ_ID (4 bytes)
+    *(uint64_t *)(buff2 + 6) = ((uint64_t )timestamp)*6;
+
+    /*
+    printf("ECPRI TX (REV %x, MessType %d, Payload size %d, PC_ID %d, TS %llu\n",
+	   *(uint8_t *)buff2,
+	   *(uint8_t *)(buff2+1),
+	   *(uint16_t *)(buff2+2),
+	   *(uint16_t *)(buff2+4),
+	   *(uint64_t *)(buff2+6));
+	   */	   	   
     
     int sent_byte;
     if (eth->compression == ALAW_COMPRESS) {
@@ -311,7 +358,7 @@ int trx_eth_write_udp(openair0_device *device, openair0_timestamp timestamp, voi
 	     bytes_sent);
 #endif
       /* Send packet */
-      bytes_sent += sendto(eth->sockfdd,
+      bytes_sent = sendto(eth->sockfdd,
 			   buff2, 
                            sent_byte,
 			   sendto_flag,
@@ -339,17 +386,13 @@ int trx_eth_write_udp(openair0_device *device, openair0_timestamp timestamp, voi
       }
     //}
                   
-      /* tx buffer values restored */  
-      *(int32_t *)buff2 = temp0;
-      *(openair0_timestamp *)(buff2 + sizeof(int32_t)) = temp1;
-  }
- 
   return (bytes_sent-APP_HEADER_SIZE_BYTES)>>2;
 }
       
 
+#define NOSHIFT 1
 
-int trx_eth_read_udp(openair0_device *device, openair0_timestamp *timestamp, void **buff, int nsamps, int cc) {
+int trx_eth_read_udp(openair0_device *device, openair0_timestamp *timestamp, void *buff, int nsamps, int *cc) {
   
   int bytes_received=0;
   eth_state_t *eth = (eth_state_t*)device->priv;
@@ -357,105 +400,98 @@ int trx_eth_read_udp(openair0_device *device, openair0_timestamp *timestamp, voi
   int rcvfrom_flag =0;
   int block_cnt=0;
   int again_cnt=0;
-  int i=0;
-
+  static int packet_cnt=0;
+  int payload_size = UDP_PACKET_SIZE_BYTES(nsamps);
+
+#if defined(__x86_64__) || defined(__i386__)
+#ifdef __AVX2__
+    int nsamps2 = (payload_size>>5)+1;
+  __m256i temp_rx[nsamps2];
+  char *temp_rx0 = ((char *)&temp_rx[1])-APP_HEADER_SIZE_BYTES;
+#else
+    int nsamps2 = (payload_size>>4)+1;
+  __m128i temp_rx[nsamps2];
+  char *temp_rx0 = ((char *)&temp_rx[1])-APP_HEADER_SIZE_BYTES;  
+#endif
+#elif defined(__arm__) || defined(__aarch64__)
+  int nsamps2 = (payload_size>>4)+1
+  int16x8_t temp_rx[nsamps2];
+  char *temp_rx0 = ((char *)&temp_rx[1])-APP_HEADER_SIZE_BYTES;  
+#else
+#error Unsupported CPU architecture device cannot be built
+  int nsamps2 = (payload_size>>2)+1;
+  int32_t temp_rx[payload_size>>2];
+  char* *temp_rx0 = ((char *)&temp_rx[1]) - APP_HEADER_SIZE_BYTES;  
+#endif
+  
   eth->rx_nsamps=nsamps;
 
-  for (i=0;i<cc;i++) {
-    /* buff[i] points to the position in rx buffer where the payload to be received will be placed
-       buff2 points to the position in rx buffer where the packet header will be placed */
-    void *buff2 = (void*)(buff[i]- APP_HEADER_SIZE_BYTES);
-    
-    /* we don't want to ovewrite with the header info the previous rx buffer data so we store it*/
-    int32_t temp0 = *(int32_t *)buff2;
-    openair0_timestamp temp1 = *(openair0_timestamp *)(buff2 + sizeof(int32_t));
-    
-    bytes_received=0;
-    block_cnt=0;
-    int receive_bytes;
-    if (eth->compression == ALAW_COMPRESS) {
-      receive_bytes = UDP_PACKET_SIZE_BYTES_ALAW(nsamps);
-    } else {
-      receive_bytes = UDP_PACKET_SIZE_BYTES(nsamps);
-    }
-    
-    while(bytes_received < receive_bytes) {
-    again:
-#if DEBUG   
-	   printf("------- RX------: buff2 current position=%d remaining_bytes=%d  bytes_recv=%d \n",
-		  (void *)(buff2+bytes_received),
-		  receive_bytes - bytes_received,
-		  bytes_received);
-#endif
-      bytes_received +=recvfrom(eth->sockfdd,
-				buff2,
-	                        receive_bytes,
-				rcvfrom_flag,
-				(struct sockaddr *)&eth->dest_addrd,
-				(socklen_t *)&eth->addr_len);
-      
-      if (bytes_received ==-1) {
-	eth->num_rx_errors++;
-	if (errno == EAGAIN) {
-	  again_cnt++;
-	  usleep(10);
-	  if (again_cnt == 1000) {
+  bytes_received=0;
+  block_cnt=0;
+  AssertFatal(eth->compression == NO_COMPRESS, "IF5 compression not supported for now\n");
+  
+  while(bytes_received < payload_size) {
+  again:
+    bytes_received +=recvfrom(eth->sockfdd,
+			      temp_rx0,
+			      payload_size,
+			      rcvfrom_flag,
+			      (struct sockaddr *)&eth->dest_addrd,
+			      (socklen_t *)&eth->addr_len);
+    packet_cnt++;
+    if (bytes_received ==-1) {
+      eth->num_rx_errors++;
+      if (errno == EAGAIN) {
+	again_cnt++;
+	usleep(10);
+	if (again_cnt == 1000) {
 	  perror("ETHERNET READ: ");
 	  exit(-1);
-	  } else {
-	    printf("AGAIN AGAIN AGAIN AGAIN AGAIN AGAIN AGAIN AGAIN AGAIN AGAIN AGAIN AGAIN \n");
-	    goto again;
-	  }	  
-	} else if (errno == EWOULDBLOCK) {
-	     block_cnt++;
-	     usleep(10);	  
-	     if (block_cnt == 1000) {
-      perror("ETHERNET READ: ");
-      exit(-1);
-    } else {
-	    printf("BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK \n");
-	    goto again;
-	  }
+	} else {
+	  bytes_received=0;
+	  goto again;
+	}	  
+      } else if (errno == EWOULDBLOCK) {
+	block_cnt++;
+	usleep(10);	  
+	if (block_cnt == 1000) {
+	  perror("ETHERNET READ: ");
+	  exit(-1);
+	} else {
+	  printf("BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK \n");
+	  goto again;
 	}
-      } else {
-#if DEBUG   
-	   printf("------- RX------: nu=%d an_id=%d ts%d bytes_recv=%d\n",
-		  *(int16_t *)buff2,
-		  *(int16_t *)(buff2 + sizeof(int16_t)),
-		  *(openair0_timestamp *)(buff2 + sizeof(int32_t)),
-		  bytes_received);
-
-	   dump_packet((device->host_type == RAU_HOST)? "RAU":"RRU", buff2, UDP_PACKET_SIZE_BYTES(nsamps),RX_FLAG);	  
-#endif  
-	   
-	   /* store the timestamp value from packet's header */
-	   *timestamp =  *(openair0_timestamp *)(buff2 + sizeof(int32_t));
-	   /* store the sequence number of the previous packet received */    
-	   if (eth->pck_seq_num_cur == 0) {
-	     eth->pck_seq_num_prev = *(uint16_t *)buff2;
-	   } else {
-	     eth->pck_seq_num_prev = eth->pck_seq_num_cur;
-	   }
-	   /* get the packet sequence number from packet's header */
-	   eth->pck_seq_num_cur = *(uint16_t *)buff2;
-	   if ( ( eth->pck_seq_num_cur != (eth->pck_seq_num_prev + 1) ) && !((eth->pck_seq_num_prev==MAX_PACKET_SEQ_NUM(nsamps,device->openair0_cfg->samples_per_frame)) && (eth->pck_seq_num_cur==1 )) && !((eth->pck_seq_num_prev==1) && (eth->pck_seq_num_cur==1))) {	     
-	     //#if DEBUG
-	     printf("Out of order packet received: current_packet=%d previous_packet=%d timestamp=%"PRId64"\n",eth->pck_seq_num_cur,eth->pck_seq_num_prev,*timestamp);
-	     //#endif
-	   }
-	   VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RX_SEQ_NUM,eth->pck_seq_num_cur);
-	   VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RX_SEQ_NUM_PRV,eth->pck_seq_num_prev);
-						    eth->rx_actual_nsamps=bytes_received>>2;
-						    eth->rx_count++;
-      }	 
-	     
       }
-      /* tx buffer values restored */  
-      *(int32_t *)buff2 = temp0;
-      *(openair0_timestamp *)(buff2 + sizeof(int32_t)) = temp1;
-	  
-    }      
-  return (bytes_received-APP_HEADER_SIZE_BYTES)>>2;
+    } else {
+      /* store the timestamp value from packet's header */
+      *timestamp =  *(openair0_timestamp *)(temp_rx0 + ECPRICOMMON_BYTES+ECPRIPCID_BYTES);
+      // convert TS to samples, /3 for 30.72 Ms/s, /6 for 15.36 Ms/s, /12 for 7.68 Ms/s, etc.
+      *timestamp = *timestamp/6;
+      // handle 1.4,3,5,10,15 MHz cases
+      *cc        = *(uint16_t*)(temp_rx0 + ECPRICOMMON_BYTES);
+    }
+    eth->rx_actual_nsamps=payload_size>>2;
+    eth->rx_count++;
+  }	 
+
+#ifdef NOSHIFT
+  memcpy(buff,(void*)(temp_rx+1),payload_size); 
+#else
+  // populate receive buffer in lower 12-bits from 16-bit representation
+  for (int j=1; j<nsamps2; j++) {
+#if defined(__x86_64__) || defined(__i386__)
+#ifdef __AVX2__
+       ((__m256i *)buff)[j-1] = _mm256_srai_epi16(temp_rx[j],2);
+#else
+       ((__m128i *)buff)[j-1] = _mm_srai_epi16(temp_rx[j],2);
+#endif
+#elif defined(__arm__)
+       ((int16x8_t *)buff)[j] = vshrq_n_s16(temp_rx[i][j],2);
+#endif
+  }
+#endif
+  
+  return (payload_size>>2);
 }
 
 
diff --git a/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c b/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c
index 1d3c280f0e5d18a6485e5bd9f45cb9f3e0bae916..dce410de47e0fb1dcd49dc8258c7d5606e8b26d3 100644
--- a/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c
+++ b/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c
@@ -52,11 +52,20 @@ int num_devices_eth = 0;
 struct sockaddr_in dest_addr[MAX_INST];
 int dest_addr_len[MAX_INST];
 
+int load_lib(openair0_device *device,
+             openair0_config_t *openair0_cfg,
+             eth_params_t *cfg,
+             uint8_t flag);
 
 int trx_eth_start(openair0_device *device)
 {
     eth_state_t *eth = (eth_state_t*)device->priv;
 
+    if (eth->flags == ETH_UDP_IF5_ECPRI_MODE) {
+       AssertFatal(device->thirdparty_init != NULL, "device->thirdparty_init is null\n");
+       AssertFatal(device->thirdparty_init(device) == 0, "third-party init failed\n");
+       device->openair0_cfg->samples_per_packet = 256;
+    }
     /* initialize socket */
     if (eth->flags == ETH_RAW_MODE) {
         printf("Setting ETHERNET to ETH_RAW_IF5_MODE\n");
@@ -121,11 +130,6 @@ int trx_eth_start(openair0_device *device)
 
 
 
-    } else if (eth->flags == ETH_RAW_IF5_MOBIPASS) {
-        printf("Setting ETHERNET to RAW_IF5_MODE\n");
-        if (eth_socket_init_raw(device)!=0)   return -1;
-        if(ethernet_tune (device,RCV_TIMEOUT,999999)!=0)  return -1;
-
     } else {
         printf("Setting ETHERNET to UDP_IF5_MODE\n");
         if (eth_socket_init_udp(device)!=0)   return -1;
@@ -137,8 +141,7 @@ int trx_eth_start(openair0_device *device)
           if(eth_get_dev_conf_udp(device)!=0)  return -1;
           }*/
 
-        /* adjust MTU wrt number of samples per packet */
-        if(ethernet_tune (device,MTU_SIZE,UDP_IF4p5_PRACH_SIZE_BYTES)!=0)  return -1;
+        //if(ethernet_tune (device,MTU_SIZE,UDP_IF4p5_PRACH_SIZE_BYTES)!=0)  return -1;
 
         if(ethernet_tune (device,RCV_TIMEOUT,999999)!=0)  return -1;
     }
@@ -166,9 +169,15 @@ void trx_eth_end(openair0_device *device)
 }
 
 
-int trx_eth_stop(openair0_device *device)
-{
-    return(0);
+
+int trx_eth_stop(openair0_device *device) {
+  eth_state_t *eth = (eth_state_t*)device->priv;
+  
+  if (eth->flags == ETH_UDP_IF5_ECPRI_MODE) {
+    AssertFatal(device->thirdparty_cleanup != NULL, "device->thirdparty_cleanup is null\n");
+    AssertFatal(device->thirdparty_cleanup(device) == 0, "third-party cleanup failed\n");
+  }
+  return(0);
 }
 
 
@@ -387,20 +396,11 @@ int transport_init(openair0_device *device,
     eth_state_t *eth = (eth_state_t*)malloc(sizeof(eth_state_t));
     memset(eth, 0, sizeof(eth_state_t));
 
-    if (eth_params->transp_preference == 1) {
-        eth->flags = ETH_RAW_MODE;
-    } else if (eth_params->transp_preference == 0) {
-        eth->flags = ETH_UDP_MODE;
-    } else if (eth_params->transp_preference == 3) {
-        eth->flags = ETH_RAW_IF4p5_MODE;
-    } else if (eth_params->transp_preference == 2) {
-        eth->flags = ETH_UDP_IF4p5_MODE;
-    } else if (eth_params->transp_preference == 4) {
-        eth->flags = ETH_RAW_IF5_MOBIPASS;
-    } else {
-        printf("transport_init: Unknown transport preference %d - default to RAW", eth_params->transp_preference);
-        eth->flags = ETH_RAW_MODE;
-    }
+    eth->flags = eth_params->transp_preference;
+
+    // load third-party driver
+    if (eth->flags == ETH_UDP_IF5_ECPRI_MODE) load_lib(device,openair0_cfg,eth_params,RAU_REMOTE_THIRDPARTY_RADIO_HEAD);
+
 
     if (eth_params->if_compress == 0) {
         eth->compression = NO_COMPRESS;
@@ -423,12 +423,17 @@ int transport_init(openair0_device *device,
     device->trx_set_gains_func   = trx_eth_set_gains;
     device->trx_write_init       = trx_eth_write_init;
 
-    if (eth->flags == ETH_RAW_MODE) {
+    device->trx_read_func2 = NULL;
+    device->trx_read_func = NULL;
+    device->trx_write_func2 = NULL;
+    device->trx_write_func = NULL;
+
+    if  (eth->flags == ETH_RAW_MODE) {
         device->trx_write_func   = trx_eth_write_raw;
         device->trx_read_func    = trx_eth_read_raw;
-    } else if (eth->flags == ETH_UDP_MODE) {
-        device->trx_write_func   = trx_eth_write_udp;
-        device->trx_read_func    = trx_eth_read_udp;
+    } else if (eth->flags == ETH_UDP_MODE || eth->flags == ETH_UDP_IF5_ECPRI_MODE) {
+        device->trx_write_func2   = trx_eth_write_udp;
+        device->trx_read_func2    = trx_eth_read_udp;
         device->trx_ctlsend_func = trx_eth_ctlsend_udp;
         device->trx_ctlrecv_func = trx_eth_ctlrecv_udp;
     } else if (eth->flags == ETH_RAW_IF4p5_MODE) {
@@ -439,9 +444,6 @@ int transport_init(openair0_device *device,
         device->trx_read_func    = trx_eth_read_udp_IF4p5;
         device->trx_ctlsend_func = trx_eth_ctlsend_udp;
         device->trx_ctlrecv_func = trx_eth_ctlrecv_udp;
-    } else if (eth->flags == ETH_RAW_IF5_MOBIPASS) {
-        device->trx_write_func   = trx_eth_write_raw_IF4p5;
-        device->trx_read_func    = trx_eth_read_raw_IF5_mobipass;
     } else {
         //device->trx_write_func   = trx_eth_write_udp_IF4p5;
         //device->trx_read_func    = trx_eth_read_udp_IF4p5;
diff --git a/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h b/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h
index 65b2def60d549e4733c198673d95a5e5511f3e86..ad64ac1a8a3b91120540e391d2bd95e878206616 100644
--- a/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h
+++ b/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h
@@ -49,7 +49,10 @@
 #define RX_FLAG 0
 
 #include "if_defs.h"
-#define APP_HEADER_SIZE_BYTES (sizeof(int32_t) + sizeof(openair0_timestamp))
+#define ECPRICOMMON_BYTES 4
+#define ECPRIPCID_BYTES 2
+#define APP_HEADER_SIZE_BYTES (ECPRICOMMON_BYTES + ECPRIPCID_BYTES + sizeof(openair0_timestamp))
+#define ECPRIREV 1 // ECPRI Version 1, C=0 - single ECPRI message per OAI TX packet
 
 /*!\brief opaque ethernet data structure */
 typedef struct {
@@ -234,8 +237,8 @@ int ethernet_tune(openair0_device *device, unsigned int option, int value);
 * @ingroup  _oai
 */
 int eth_socket_init_udp(openair0_device *device);
-int trx_eth_write_udp(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps,int cc, int flags);
-int trx_eth_read_udp(openair0_device *device, openair0_timestamp *timestamp, void **buff, int nsamps, int cc);
+int trx_eth_write_udp(openair0_device *device, openair0_timestamp timestamp, void *buff, int nsamps,int cc, int flags);
+int trx_eth_read_udp(openair0_device *device, openair0_timestamp *timestamp, void *buff, int nsamps, int *cc);
 
 
 int eth_socket_init_raw(openair0_device *device);
diff --git a/targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h b/targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h
index 0f2147847a6145230078b8e4f30f16d9c23eef12..47205cf8b8bdc72f6f985860eeafefc9b570f961 100644
--- a/targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h
+++ b/targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h
@@ -36,15 +36,17 @@
 #include <netinet/ether.h>
 #include <stdint.h>
 
+#ifndef LITE_COMPILATION
 #include "PHY/LTE_TRANSPORT/if4_tools.h"
 #include "PHY/LTE_TRANSPORT/if5_tools.h"
+#endif
 
 // ETH transport preference modes
-#define ETH_UDP_MODE        0
-#define ETH_RAW_MODE        1
+#define ETH_UDP_MODE          0
+#define ETH_RAW_MODE          1
 #define ETH_UDP_IF4p5_MODE    2
 #define ETH_RAW_IF4p5_MODE    3
-#define ETH_RAW_IF5_MOBIPASS    4    
+#define ETH_UDP_IF5_ECPRI_MODE  4    
 
 // COMMOM HEADER LENGTHS
 
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc_b38_if5_ENDC.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc_b38_if5_ENDC.conf
new file mode 100644
index 0000000000000000000000000000000000000000..9b611b3f07816e9107d316d335b77fbb406671a1
--- /dev/null
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc_b38_if5_ENDC.conf
@@ -0,0 +1,243 @@
+Active_eNBs = ( "eNB_Eurecom_VCO_B38");
+# Asn1_verbosity, choice in: none, info, annoying
+Asn1_verbosity = "none";
+
+eNBs =
+(
+ {
+    # real_time choice in {hard, rt-preempt, no}
+    real_time       =  "no";
+
+    ////////// Identification parameters:
+    eNB_ID    =  0xe00;
+
+    cell_type =  "CELL_MACRO_ENB";
+
+    eNB_name  =  "eNB_Eurecom_VCO_B38";
+
+    // Tracking area code, 0x0000 and 0xfffe are reserved values
+    tracking_area_code = 1;
+
+    plmn_list = ( { mcc = 222; mnc = 01; mnc_length = 2; } );
+
+       ////////// Physical parameters:
+
+    component_carriers = (
+      {
+        node_function                                         = "NGFI_RCC_IF5";
+        node_timing                                           = "synch_to_ext_device";
+        node_synch_ref                                        = 0;
+        frame_type					      = "TDD";
+        tdd_config 					      = 1;
+        tdd_config_s            			      = 0;
+        prefix_type             			      = "NORMAL";
+        eutra_band              			      = 38;
+        downlink_frequency      			      = 2585000000L;
+        uplink_frequency_offset 			      = 0;
+        Nid_cell					      = 0;
+        N_RB_DL                 			      = 100;
+        Nid_cell_mbsfn          			      = 0;
+        nb_antenna_ports          			      = 1;
+        nb_antennas_tx          			      = 1;
+        nb_antennas_rx          			      = 1;
+        tx_gain                                            = 90;
+        rx_gain                                            = 125;
+        prach_root              			      = 0;
+        prach_config_index      			      = 0;
+        prach_high_speed        			      = "DISABLE";
+        prach_zero_correlation  			      = 5;
+        prach_freq_offset       			      = 2;
+        pucch_delta_shift       			      = 1;
+        pucch_nRB_CQI           			      = 1;
+        pucch_nCS_AN            			      = 0;
+        pucch_n1_AN             			      = 0;
+        pdsch_referenceSignalPower 			      = 10;
+        pdsch_p_b                  			      = 0;
+        pusch_n_SB                 			      = 1;
+        pusch_enable64QAM          			      = "DISABLE";
+        pusch_hoppingMode                                  = "interSubFrame";
+        pusch_hoppingOffset                                = 0;
+        pusch_groupHoppingEnabled  			      = "ENABLE";
+        pusch_groupAssignment      			      = 0;
+        pusch_sequenceHoppingEnabled		   	      = "DISABLE";
+        pusch_nDMRS1                                       = 1;
+        phich_duration                                     = "NORMAL";
+        phich_resource                                     = "ONESIXTH";
+        srs_enable                                         = "DISABLE";
+      /*  srs_BandwidthConfig                                =;
+        srs_SubframeConfig                                 =;
+        srs_ackNackST                                      =;
+        srs_MaxUpPts                                       =;*/
+
+        pusch_p0_Nominal                                   = -96;
+        pusch_alpha                                        = "AL1";
+        pucch_p0_Nominal                                   = -106;
+        msg3_delta_Preamble                                = 6;
+        pucch_deltaF_Format1                               = "deltaF2";
+        pucch_deltaF_Format1b                              = "deltaF3";
+        pucch_deltaF_Format2                               = "deltaF0";
+        pucch_deltaF_Format2a                              = "deltaF0";
+        pucch_deltaF_Format2b		    	      = "deltaF0";
+
+        rach_numberOfRA_Preambles                          = 64;
+        rach_preamblesGroupAConfig                         = "DISABLE";
+      /*
+        rach_sizeOfRA_PreamblesGroupA                      = ;
+        rach_messageSizeGroupA                             = ;
+        rach_messagePowerOffsetGroupB                      = ;
+      */
+        rach_powerRampingStep                              = 4;
+        rach_preambleInitialReceivedTargetPower            = -108;
+        rach_preambleTransMax                              = 10;
+        rach_raResponseWindowSize                          = 10;
+        rach_macContentionResolutionTimer                  = 48;
+        rach_maxHARQ_Msg3Tx                                = 4;
+
+        pcch_default_PagingCycle                           = 128;
+        pcch_nB                                            = "oneT";
+        bcch_modificationPeriodCoeff			      = 2;
+        ue_TimersAndConstants_t300			      = 1000;
+        ue_TimersAndConstants_t301			      = 1000;
+        ue_TimersAndConstants_t310			      = 1000;
+        ue_TimersAndConstants_t311			      = 10000;
+        ue_TimersAndConstants_n310			      = 20;
+        ue_TimersAndConstants_n311			      = 1;
+
+	ue_TransmissionMode				      = 1;
+      }
+    );
+
+
+    srb1_parameters :
+    {
+        # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500]
+        timer_poll_retransmit    = 80;
+
+        # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200]
+        timer_reordering         = 35;
+
+        # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500]
+        timer_status_prohibit    = 0;
+
+        # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)]
+        poll_pdu                 =  4;
+
+        # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)]
+        poll_byte                =  99999;
+
+        # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32]
+        max_retx_threshold       =  4;
+    }
+
+    # ------- SCTP definitions
+    SCTP :
+    {
+        # Number of streams to use in input/output
+        SCTP_INSTREAMS  = 2;
+        SCTP_OUTSTREAMS = 2;
+    };
+
+    ////////// MME parameters:
+    mme_ip_address      = ( { ipv4       = "192.168.18.150";
+                              ipv6       = "192:168:30::17";
+                              active     = "yes";
+                              preference = "ipv4";
+                            }
+                          );
+
+    enable_measurement_reports = "no";
+
+    ///X2
+    enable_x2 = "yes";
+    t_reloc_prep      = 1000;      /* unit: millisecond */
+    tx2_reloc_overall = 2000;      /* unit: millisecond */
+    t_dc_prep         = 1000;
+    t_dc_overall      = 2000;
+
+    NETWORK_INTERFACES :
+    {
+        ENB_INTERFACE_NAME_FOR_S1_MME            = "bond0";
+        ENB_IPV4_ADDRESS_FOR_S1_MME              = "192.168.18.203/24";
+        ENB_INTERFACE_NAME_FOR_S1U               = "bond0";
+        ENB_IPV4_ADDRESS_FOR_S1U                 = "192.168.18.203/24";
+        ENB_PORT_FOR_S1U                         = 2152; # Spec 2152
+        ENB_IPV4_ADDRESS_FOR_X2C                 = "192.168.18.203/24";
+        ENB_PORT_FOR_X2C                         = 36422; # Spec 36422
+    };
+
+    log_config :
+    {
+      global_log_level                      ="debug";
+      global_log_verbosity                  ="medium";
+      hw_log_level                          ="info";
+      hw_log_verbosity                      ="medium";
+      phy_log_level                         ="info";
+      phy_log_verbosity                     ="medium";
+      mac_log_level                         ="info";
+      mac_log_verbosity                     ="high";
+      rlc_log_level                         ="info";
+      rlc_log_verbosity                     ="medium";
+      pdcp_log_level                        ="info";
+      pdcp_log_verbosity                    ="medium";
+      rrc_log_level                         ="info";
+      rrc_log_verbosity                     ="medium";
+   };
+
+  }
+);
+MACRLCs = (
+	{
+        num_cc = 1;
+        tr_s_preference = "local_L1";
+        tr_n_preference = "local_RRC";
+        scheduler_mode = "fairRR";
+        puSch10xSnr     =  100;
+        puCch10xSnr     =  100;
+        }  
+);
+
+L1s = (
+    	{
+	num_cc = 1;
+	tr_n_preference = "local_mac";
+        prach_dtx_threshold = 150;
+        }  
+);
+
+RUs = (
+    {		  
+        local_if_name  = "bond0";
+        remote_address = "192.168.18.222";
+        local_address  = "192.168.18.203";
+        local_portc    = 50000;
+        remote_portc   = 55444;
+        local_portd    = 52001;
+        remote_portd   = 52183;
+        local_rf       = "no"
+        tr_preference  = "udp_ecpri_if5"
+        nb_tx          = 1
+        nb_rx          = 1
+        att_tx         = 5 
+        att_rx         = 0;
+        eNB_instances  = [0];
+    }
+);  
+
+THREAD_STRUCT = (
+  {
+    #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
+    parallel_config    = "PARALLEL_RU_L1_TRX_SPLIT";
+    #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
+    worker_config      = "WORKER_ENABLE";
+  }
+);
+
+NETWORK_CONTROLLER :
+{
+    FLEXRAN_ENABLED        = "no";
+    FLEXRAN_INTERFACE_NAME = "lo";
+    FLEXRAN_IPV4_ADDRESS   = "127.0.0.1";
+    FLEXRAN_PORT           = 2210;
+    FLEXRAN_CACHE          = "/mnt/oai_agent_cache";
+    FLEXRAN_AWAIT_RECONF   = "no";
+};
diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c
index 7d6cb9c429121b7329013982cca3b7b979c8ecfc..1347d75fb06939f6b3fbf5526f9f1fbc0c08c09a 100644
--- a/targets/RT/USER/lte-enb.c
+++ b/targets/RT/USER/lte-enb.c
@@ -461,10 +461,9 @@ void eNB_top(PHY_VARS_eNB *eNB,
     L1_proc->subframe_rx  = ru_proc->tti_rx;
     L1_proc->frame_tx     = (L1_proc->subframe_rx > (9-sf_ahead)) ? (L1_proc->frame_rx+1)&1023 : L1_proc->frame_rx;
     L1_proc->subframe_tx  = (L1_proc->subframe_rx + sf_ahead)%10;
-
+    
     if (rxtx(eNB,L1_proc,string) < 0)
-      LOG_E(PHY,"eNB %d CC_id %d failed during execution\n",eNB->Mod_id,eNB->CC_id);
-
+      LOG_E(PHY,"eNB %d CC_id %d failed during execution\n",eNB->Mod_id,eNB->CC_id);  
     ru_proc->timestamp_tx = L1_proc->timestamp_tx;
     ru_proc->tti_tx  = L1_proc->subframe_tx;
     ru_proc->frame_tx     = L1_proc->frame_tx;
@@ -1168,6 +1167,7 @@ void init_eNB_afterRU(void) {
 
       for (ru_id=0,aa=0; ru_id<eNB->num_RU; ru_id++) {
         eNB->frame_parms.nb_antennas_rx    += eNB->RU_list[ru_id]->nb_rx;
+
         AssertFatal(eNB->RU_list[ru_id]->common.rxdataF!=NULL,
                     "RU %d : common.rxdataF is NULL\n",
                     eNB->RU_list[ru_id]->idx);
diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c
index 4e3a6612736a9ea4e8ed9cf468d55f7c8e8aa50e..56c2cb23dd43114975300a5c41b160c38c6a8551 100644
--- a/targets/RT/USER/lte-ru.c
+++ b/targets/RT/USER/lte-ru.c
@@ -120,6 +120,8 @@ void configure_rru(int idx,
 void reset_proc(RU_t *ru);
 int connect_rau(RU_t *ru);
 
+void wait_eNBs(void);
+
 const char ru_states[6][9] = {"RU_IDLE","RU_CONFIG","RU_READY","RU_RUN","RU_ERROR","RU_SYNC"};
 
 extern uint16_t sf_ahead;
@@ -141,16 +143,12 @@ extern uint16_t sf_ahead;
 static inline void fh_if5_south_out(RU_t *ru,int frame, int subframe, uint64_t timestamp) {
   if (ru == RC.ru[0]) VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, ru->proc.timestamp_tx&0xffffffff );
 
+  ru->south_out_cnt++;
+
   send_IF5(ru, timestamp, subframe, &ru->seqno, IF5_RRH_GW_DL);
 }
 
 
-// southbound IF5 fronthaul for Mobipass packet format
-static inline void fh_if5_mobipass_south_out(RU_t *ru,int frame, int subframe, uint64_t timestamp) {
-  if (ru == RC.ru[0]) VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, ru->proc.timestamp_tx&0xffffffff );
-
-  send_IF5(ru, timestamp, subframe, &ru->seqno, IF5_MOBIPASS);
-}
 
 
 // southbound IF4p5 fronthaul
@@ -189,11 +187,12 @@ void fh_if5_south_in(RU_t *ru,
   recv_IF5(ru, &proc->timestamp_rx, *subframe, IF5_RRH_GW_UL);
   proc->frame_rx    = (proc->timestamp_rx / (fp->samples_per_tti*10))&1023;
   proc->tti_rx = (proc->timestamp_rx / fp->samples_per_tti)%10;
-
+  
   if (proc->first_rx == 0) {
     if (proc->tti_rx != *subframe) {
-      LOG_E(PHY,"Received Timestamp doesn't correspond to the time we think it is (proc->tti_rx %d, subframe %d)\n",proc->tti_rx,*subframe);
-      exit_fun("Exiting");
+      LOG_E(PHY,"Received Timestamp doesn't correspond to the time we think it is (proc->tti_rx %d, subframe %d), resynching\n",proc->tti_rx,*subframe);
+      *frame=proc->frame_rx;
+      *subframe=proc->tti_rx;
     }
 
     if (proc->frame_rx != *frame) {
@@ -324,48 +323,6 @@ void fh_slave_south_in(RU_t *ru,
 }
 
 
-// asynchronous inbound if5 fronthaul from south (Mobipass)
-void fh_if5_south_asynch_in_mobipass(RU_t *ru,
-                                     int *frame,
-                                     int *subframe) {
-  RU_proc_t *proc        = &ru->proc;
-  LTE_DL_FRAME_PARMS *fp = ru->frame_parms;
-  recv_IF5(ru, &proc->timestamp_rx, *subframe, IF5_MOBIPASS);
-  pthread_mutex_lock(&proc->mutex_asynch_rxtx);
-  int offset_mobipass = 40120;
-  pthread_mutex_lock(&proc->mutex_asynch_rxtx);
-  proc->tti_rx = ((proc->timestamp_rx-offset_mobipass)/fp->samples_per_tti)%10;
-  proc->frame_rx    = ((proc->timestamp_rx-offset_mobipass)/(fp->samples_per_tti*10))&1023;
-  proc->tti_rx = (proc->timestamp_rx/fp->samples_per_tti)%10;
-  proc->frame_rx    = (proc->timestamp_rx/(10*fp->samples_per_tti))&1023;
-
-  if (proc->first_rx == 1) {
-    proc->first_rx =2;
-    *subframe = proc->tti_rx;
-    *frame    = proc->frame_rx;
-    LOG_E(PHY,"[Mobipass]timestamp_rx:%llu, frame_rx %d, subframe: %d\n",(unsigned long long int)proc->timestamp_rx,proc->frame_rx,proc->tti_rx);
-  } else {
-    if (proc->tti_rx != *subframe) {
-      proc->first_rx++;
-      LOG_E(PHY,"[Mobipass]timestamp:%llu, tti_rx %d is not what we expect %d, first_rx:%d\n",(unsigned long long int)proc->timestamp_rx, proc->tti_rx,*subframe, proc->first_rx);
-      //exit_fun("Exiting");
-    }
-
-    if (proc->frame_rx != *frame) {
-      proc->first_rx++;
-      LOG_E(PHY,"[Mobipass]timestamp:%llu, frame_rx %d is not what we expect %d, first_rx:%d\n",(unsigned long long int)proc->timestamp_rx,proc->frame_rx,*frame, proc->first_rx);
-      // exit_fun("Exiting");
-    }
-
-    // temporary solution
-    *subframe = proc->tti_rx;
-    *frame    = proc->frame_rx;
-  }
-
-  pthread_mutex_unlock(&proc->mutex_asynch_rxtx);
-} // eNodeB_3GPP_BBU
-
-
 // asynchronous inbound if4p5 fronthaul from south
 void fh_if4p5_south_asynch_in(RU_t *ru,
                               int *frame,
@@ -456,7 +413,7 @@ void fh_if5_north_asynch_in(RU_t *ru,
   int tti_tx,frame_tx;
   openair0_timestamp timestamp_tx;
   recv_IF5(ru, &timestamp_tx, *subframe, IF5_RRH_GW_DL);
-  //      printf("Received subframe %d (TS %llu) from RCC\n",tti_tx,timestamp_tx);
+  //      LOG_I(PHY,"Received subframe %d (TS %llu) from RCC\n",tti_tx,timestamp_tx);
   tti_tx = (timestamp_tx/fp->samples_per_tti)%10;
   frame_tx    = (timestamp_tx/(fp->samples_per_tti*10))&1023;
   VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU, proc->frame_tx );
@@ -696,7 +653,7 @@ void rx_rf(RU_t *ru,
     ru->ts_offset = proc->timestamp_rx;
     proc->timestamp_rx = 0;
   } else if (resynch==0 && (proc->timestamp_rx - old_ts != fp->samples_per_tti)) {
-    LOG_I(PHY,"rx_rf: rfdevice timing drift of %"PRId64" samples (ts_off %"PRId64")\n",proc->timestamp_rx - old_ts - fp->samples_per_tti,ru->ts_offset);
+    LOG_D(PHY,"rx_rf: rfdevice timing drift of %"PRId64" samples (ts_off %"PRId64")\n",proc->timestamp_rx - old_ts - fp->samples_per_tti,ru->ts_offset);
     ru->ts_offset += (proc->timestamp_rx - old_ts - fp->samples_per_tti);
     proc->timestamp_rx = ts-ru->ts_offset;
   }
@@ -761,7 +718,7 @@ void rx_rf(RU_t *ru,
     *subframe = proc->tti_rx;
   }
 
-  //printf("timestamp_rx %lu, frame %d(%d), subframe %d(%d)\n",ru->timestamp_rx,proc->frame_rx,frame,proc->tti_rx,subframe);
+  //LOG_I(PHY,"timestamp_rx %lu, frame %d(%d), subframe %d(%d)\n",ru->timestamp_rx,proc->frame_rx,frame,proc->tti_rx,subframe);
   VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS, proc->timestamp_rx&0xffffffff );
 
   if (rxs != fp->samples_per_tti) {
@@ -929,12 +886,8 @@ static void *ru_thread_asynch_rxtx( void *param ) {
 
       LOG_D(PHY,"ru_thread_asynch_rxtx: Waiting on incoming fronthaul\n");
 
-      // asynchronous receive from south (Mobipass)
-      if (ru->fh_south_asynch_in) {
-        ru->fh_south_asynch_in(ru, &frame, &subframe);
-      }
       // asynchronous receive from north (RRU IF4/IF5)
-      else if (ru->fh_north_asynch_in) {
+      if (ru->fh_north_asynch_in) {
         if (subframe_select(ru->frame_parms,subframe)!=SF_UL)
           ru->fh_north_asynch_in(ru, &frame, &subframe);
       } else
@@ -1185,21 +1138,22 @@ void wakeup_L1s(RU_t *ru) {
   L1_proc_t *proc         = &eNB->proc;
   struct timespec t;
   LOG_D(PHY, "wakeup_L1s (num %d) for RU %d (%d.%d) ru->eNB_top:%p\n", ru->num_eNB, ru->idx, ru->proc.frame_rx, ru->proc.tti_rx, ru->eNB_top);
-  // call eNB function directly
   char string[20];
   sprintf(string, "Incoming RU %d", ru->idx);
+
+  // call eNB function directly
   VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_WAKEUP_L1S_RU+ru->idx, ru->proc.frame_rx);
   VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_WAKEUP_L1S_RU+ru->idx, ru->proc.tti_rx);
   AssertFatal(0==pthread_mutex_lock(&proc->mutex_RU),"");
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_LOCK_MUTEX_RU+ru->idx, 1);
-  //printf("wakeup_L1s: Frame %d, Subframe %d: RU %d done (wait_cnt %d),RU_mask[%d] %x\n",
-  //          ru->proc.frame_rx,ru->proc.subframe_rx,ru->idx,ru->wait_cnt,ru->proc.subframe_rx,proc->RU_mask[ru->proc.subframe_rx]);
+  //LOG_I(PHY,"wakeup_L1s: Frame %d, Subframe %d: RU %d done (wait_cnt %d),RU_mask[%d] %x\n",
+  //          ru->proc.frame_rx,ru->proc.tti_rx,ru->idx,ru->wait_cnt,ru->proc.tti_rx,proc->RU_mask[ru->proc.tti_rx]);
   //VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_WAKEUP_L1S_RU+ru->idx, ru->proc.frame_rx);
-  //VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_WAKEUP_L1S_RU+ru->idx, ru->proc.subframe_rx);
+  //VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_WAKEUP_L1S_RU+ru->idx, ru->proc.tti_rx);
   clock_gettime(CLOCK_MONOTONIC, &ru->proc.t[ru->proc.tti_rx]);
 
   if (proc->RU_mask[ru->proc.tti_rx] == 0) {
-    //clock_gettime(CLOCK_MONOTONIC,&proc->t[ru->proc.subframe_rx]);
+    //clock_gettime(CLOCK_MONOTONIC,&proc->t[ru->proc.tti_rx]);
     proc->t[ru->proc.tti_rx] = ru->proc.t[ru->proc.tti_rx];
     //start_meas(&proc->ru_arrival_time);
     LOG_D(PHY,"RU %d starting timer for frame %d subframe %d\n", ru->idx, ru->proc.frame_rx, ru->proc.tti_rx);
@@ -1212,13 +1166,13 @@ void wakeup_L1s(RU_t *ru) {
           eNB->RU_list[i]->idx, eNB->RU_list[i]->proc.frame_rx, eNB->RU_list[i]->proc.tti_rx, ru_states[eNB->RU_list[i]->state]);
 
     if (ru == eNB->RU_list[i] && eNB->RU_list[i]->wait_cnt == 0) {
-      //AssertFatal((proc->RU_mask&(1<<i)) == 0, "eNB %d frame %d, subframe %d : previous information from RU %d (num_RU %d,mask %x) has not been served yet!\n", eNB->Mod_id,ru->proc.frame_rx,ru->proc.subframe_rx,ru->idx,eNB->num_RU,proc->RU_mask);
+      //AssertFatal((proc->RU_mask&(1<<i)) == 0, "eNB %d frame %d, subframe %d : previous information from RU %d (num_RU %d,mask %x) has not been served yet!\n", eNB->Mod_id,ru->proc.frame_rx,ru->proc.tti_rx,ru->idx,eNB->num_RU,proc->RU_mask);
       proc->RU_mask[ru->proc.tti_rx] |= (1<<i);
     } else if (/*eNB->RU_list[i]->state == RU_SYNC ||*/(eNB->RU_list[i]->is_slave==1 && eNB->RU_list[i]->wait_cnt>0 && ru!=eNB->RU_list[i] && ru->is_slave==0) ) {
       proc->RU_mask[ru->proc.tti_rx] |= (1<<i);
     }
 
-    //printf("RU %d, RU_mask[%d] %d, i %d, frame %d, slave %d, ru->cnt %d, i->cnt %d\n",ru->idx,ru->proc.subframe_rx,proc->RU_mask[ru->proc.subframe_rx],i,ru->proc.frame_rx,ru->is_slave,ru->wait_cnt,eNB->RU_list[i]->wait_cnt);
+    //LOG_I(PHY,"RU %d, RU_mask[%d] %d, i %d, frame %d, slave %d, ru->cnt %d, i->cnt %d\n",ru->idx,ru->proc.tti_rx,proc->RU_mask[ru->proc.tti_rx],i,ru->proc.frame_rx,ru->is_slave,ru->wait_cnt,eNB->RU_list[i]->wait_cnt);
     VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_MASK_RU, proc->RU_mask[ru->proc.tti_rx]);
 
     if (ru->is_slave == 0 && ( (proc->RU_mask[ru->proc.tti_rx]&(1<<i)) == 1 ) && eNB->RU_list[i]->state == RU_RUN) { //This is master & the RRU has already been received
@@ -1233,21 +1187,21 @@ void wakeup_L1s(RU_t *ru) {
   }
 
   //clock_gettime(CLOCK_MONOTONIC,&t);
-  //LOG_I(PHY,"RU mask is now %x, time is %lu\n",proc->RU_mask[ru->proc.subframe_rx], t.tv_nsec - proc->t[ru->proc.subframe_rx].tv_nsec);
+  //LOG_I(PHY,"RU mask is now %x, time is %lu\n",proc->RU_mask[ru->proc.tti_rx], t.tv_nsec - proc->t[ru->proc.tti_rx].tv_nsec);
 
   if (proc->RU_mask[ru->proc.tti_rx] == (1<<eNB->num_RU)-1) { // all RUs have provided their information so continue on and wakeup eNB top
     LOG_D(PHY,"ru_mask is %d \n ", proc->RU_mask[ru->proc.tti_rx]);
     LOG_D(PHY,"the number of RU is %d, the current ru is RU %d \n ", (1<<eNB->num_RU)-1, ru->idx);
-    LOG_D(PHY,"ru->proc.subframe_rx is %d \n", ru->proc.tti_rx);
+    LOG_D(PHY,"ru->proc.tti_rx is %d \n", ru->proc.tti_rx);
     LOG_D(PHY,"Resetting mask frame %d, subframe %d, this is RU %d\n", ru->proc.frame_rx, ru->proc.tti_rx, ru->idx);
     proc->RU_mask[ru->proc.tti_rx] = 0;
     VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_MASK_RU, proc->RU_mask[ru->proc.tti_rx]);
     clock_gettime(CLOCK_MONOTONIC,&t);
     //stop_meas(&proc->ru_arrival_time);
-    /*AssertFatal(t.tv_nsec < proc->t[ru->proc.subframe_rx].tv_nsec+5000000, "Time difference for subframe %d (Frame %d) => %lu > 5ms, this is RU %d\n",
-                  ru->proc.subframe_rx, ru->proc.frame_rx, t.tv_nsec - proc->t[ru->proc.subframe_rx].tv_nsec, ru->idx);*/
+    /*AssertFatal(t.tv_nsec < proc->t[ru->proc.tti_rx].tv_nsec+5000000, "Time difference for subframe %d (Frame %d) => %lu > 5ms, this is RU %d\n",
+                  ru->proc.tti_rx, ru->proc.frame_rx, t.tv_nsec - proc->t[ru->proc.tti_rx].tv_nsec, ru->idx);*/
     //VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_WAKEUP_L1S_RU+ru->idx, ru->proc.frame_rx);
-    //VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_WAKEUP_L1S_RU+ru->idx, ru->proc.subframe_rx);
+    //VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_WAKEUP_L1S_RU+ru->idx, ru->proc.tti_rx);
     AssertFatal(0==pthread_mutex_unlock(&proc->mutex_RU),"");
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_LOCK_MUTEX_RU+ru->idx, 0 );
     // unlock RUs that are waiting for eNB processing to be completed
@@ -1280,8 +1234,8 @@ void wakeup_L1s(RU_t *ru) {
   }
 
   //      pthread_mutex_unlock(&proc->mutex_RU);
-  //      LOG_D(PHY,"wakeup eNB top for for subframe %d\n", ru->proc.subframe_rx);
-  //      ru->eNB_top(eNB_list[0],ru->proc.frame_rx,ru->proc.subframe_rx,string);
+  //      LOG_D(PHY,"wakeup eNB top for for subframe %d\n", ru->proc.tti_rx);
+  //      ru->eNB_top(eNB_list[0],ru->proc.frame_rx,ru->proc.tti_rx,string);
   ru->proc.emulate_rf_busy = 0;
 }
 
@@ -1350,7 +1304,7 @@ void fill_rf_config(RU_t *ru,
                     char *rf_config_file) {
   LTE_DL_FRAME_PARMS *fp   = ru->frame_parms;
   openair0_config_t *cfg   = &ru->openair0_cfg;
-  //printf("////////////////numerology in config = %d\n",numerology);
+  //LOG_I(PHY,"////////////////numerology in config = %d\n",numerology);
   int numerology = get_softmodem_params()->numerology;
 
   if(fp->N_RB_DL == 100) {
@@ -1377,7 +1331,7 @@ void fill_rf_config(RU_t *ru,
       cfg->tx_bw = 40e6;
       cfg->rx_bw = 40e6;
     } else {
-      printf("Wrong input for numerology %d\n setting to 20MHz normal CP configuration",numerology);
+      LOG_I(PHY,"Wrong input for numerology %d\n setting to 20MHz normal CP configuration",numerology);
       cfg->sample_rate=30.72e6;
       cfg->samples_per_frame = 307200;
       cfg->tx_bw = 10e6;
@@ -1416,7 +1370,7 @@ void fill_rf_config(RU_t *ru,
     cfg->tx_gain[i] = (double)ru->att_tx;
     cfg->rx_gain[i] = ru->max_rxgain-(double)ru->att_rx;
     cfg->configFilename = rf_config_file;
-    printf("channel %d, Setting tx_gain offset %f, rx_gain offset %f, tx_freq %f, rx_freq %f\n",
+    LOG_I(PHY,"channel %d, Setting tx_gain offset %f, rx_gain offset %f, tx_freq %f, rx_freq %f\n",
            i, cfg->tx_gain[i],
            cfg->rx_gain[i],
            cfg->tx_freq[i],
@@ -1437,9 +1391,9 @@ int setup_RU_buffers(RU_t *ru) {
 
   if (ru) {
     frame_parms = ru->frame_parms;
-    printf("setup_RU_buffers: frame_parms = %p\n",frame_parms);
+    LOG_I(PHY,"setup_RU_buffers: frame_parms = %p\n",frame_parms);
   } else {
-    printf("RU not initialized (NULL pointer)\n");
+    LOG_I(PHY,"RU not initialized (NULL pointer)\n");
     return(-1);
   }
 
@@ -1462,7 +1416,7 @@ int setup_RU_buffers(RU_t *ru) {
       ru->sf_extension       /= 4;
       ru->end_of_burst_delay /= 4;
     } else {
-      printf("not handled, todo\n");
+      LOG_I(PHY,"not handled, todo\n");
       exit(1);
     }
   } else {
@@ -1476,13 +1430,13 @@ int setup_RU_buffers(RU_t *ru) {
     for (i=0; i<ru->nb_rx; i++) {
       card = i/4;
       ant = i%4;
-      printf("Mapping RU id %d, rx_ant %d, on card %d, chain %d\n",ru->idx,i,ru->rf_map.card+card, ru->rf_map.chain+ant);
+      LOG_I(PHY,"Mapping RU id %d, rx_ant %d, on card %d, chain %d\n",ru->idx,i,ru->rf_map.card+card, ru->rf_map.chain+ant);
       free(ru->common.rxdata[i]);
       ru->common.rxdata[i] = ru->openair0_cfg.rxbase[ru->rf_map.chain+ant];
-      printf("rxdata[%d] @ %p\n",i,ru->common.rxdata[i]);
+      LOG_I(PHY,"rxdata[%d] @ %p\n",i,ru->common.rxdata[i]);
 
       for (j=0; j<16; j++) {
-        printf("rxbuffer %d: %x\n",j,ru->common.rxdata[i][j]);
+        LOG_I(PHY,"rxbuffer %d: %x\n",j,ru->common.rxdata[i][j]);
         ru->common.rxdata[i][j] = 16-j;
       }
     }
@@ -1490,13 +1444,13 @@ int setup_RU_buffers(RU_t *ru) {
     for (i=0; i<ru->nb_tx; i++) {
       card = i/4;
       ant = i%4;
-      printf("Mapping RU id %d, tx_ant %d, on card %d, chain %d\n",ru->idx,i,ru->rf_map.card+card, ru->rf_map.chain+ant);
+      LOG_I(PHY,"Mapping RU id %d, tx_ant %d, on card %d, chain %d\n",ru->idx,i,ru->rf_map.card+card, ru->rf_map.chain+ant);
       free(ru->common.txdata[i]);
       ru->common.txdata[i] = ru->openair0_cfg.txbase[ru->rf_map.chain+ant];
-      printf("txdata[%d] @ %p\n",i,ru->common.txdata[i]);
+      LOG_I(PHY,"txdata[%d] @ %p\n",i,ru->common.txdata[i]);
 
       for (j=0; j<16; j++) {
-        printf("txbuffer %d: %x\n",j,ru->common.txdata[i][j]);
+        LOG_I(PHY,"txbuffer %d: %x\n",j,ru->common.txdata[i][j]);
         ru->common.txdata[i][j] = 16-j;
       }
     }
@@ -1623,7 +1577,7 @@ static void *ru_thread_tx( void *param ) {
       }
 
       if (eNB_proc->RU_mask_tx != (1<<eNB->num_RU)-1) {  // not all RUs have provided their information so return
-        //printf("Not all RUs have provided their info (mask = %d), RU %d, num_RUs %d\n", eNB_proc->RU_mask_tx,ru->idx,eNB->num_RU);
+        //LOG_I(PHY,"Not all RUs have provided their info (mask = %d), RU %d, num_RUs %d\n", eNB_proc->RU_mask_tx,ru->idx,eNB->num_RU);
         AssertFatal((ret=pthread_mutex_unlock(&eNB_proc->mutex_RU_tx))==0,"mutex_unlock returns %d\n",ret);
       } else { // all RUs TX are finished so send the ready signal to eNB processing
         eNB_proc->RU_mask_tx = 0;
@@ -1644,7 +1598,7 @@ static void *ru_thread_tx( void *param ) {
       }
     }
 
-    //printf("ru_thread_tx: Frame %d, Subframe %d: RU %d done (wait_cnt %d),RU_mask_tx %d\n",
+    //LOG_I(PHY,"ru_thread_tx: Frame %d, Subframe %d: RU %d done (wait_cnt %d),RU_mask_tx %d\n",
     //eNB_proc->frame_rx,eNB_proc->subframe_rx,ru->idx,ru->wait_cnt,eNB_proc->RU_mask_tx);
   }
 
@@ -1676,12 +1630,10 @@ static void *ru_thread( void *param ) {
   LOG_I(PHY,"Starting RU %d (%s,%s),\n", ru->idx, NB_functions[ru->function], NB_timing[ru->if_timing]);
 
   if(get_softmodem_params()->emulate_rf) {
-    fill_rf_config(ru,ru->rf_config_file);
-    init_frame_parms(ru->frame_parms,1);
     phy_init_RU(ru);
 
     if (setup_RU_buffers(ru)!=0) {
-      printf("Exiting, cannot initialize RU Buffers\n");
+      LOG_I(PHY,"Exiting, cannot initialize RU Buffers\n");
       exit(-1);
     }
 
@@ -1693,24 +1645,20 @@ static void *ru_thread( void *param ) {
     ru->state = RU_RUN;
   } else if (ru->has_ctrl_prt == 0) {
     // There is no control port: start everything here
-    LOG_I(PHY, "RU %d has not ctrl port\n",ru->idx);
+    LOG_I(PHY, "RU %d has no OAI ctrl port\n",ru->idx);
 
-    if (ru->if_south == LOCAL_RF) {
-      fill_rf_config(ru,ru->rf_config_file);
-      init_frame_parms(ru->frame_parms,1);
-      ru->frame_parms->nb_antennas_rx = ru->nb_rx;
-      phy_init_RU(ru);
-      openair0_device_load(&ru->rfdevice,&ru->openair0_cfg);
+    fill_rf_config(ru,ru->rf_config_file);
+    init_frame_parms(ru->frame_parms,1);
+    ru->frame_parms->nb_antennas_rx = ru->nb_rx;
 
-      if (setup_RU_buffers(ru)!=0) {
-        printf("Exiting, cannot initialize RU Buffers\n");
-        exit(-1);
-      }
+    if (ru->if_south == LOCAL_RF)       openair0_device_load(&ru->rfdevice,&ru->openair0_cfg);
 
-      AssertFatal((ret=pthread_mutex_lock(&RC.ru_mutex))==0,"mutex_lock returns %d\n",ret);
-      RC.ru_mask &= ~(1<<ru->idx);
-      pthread_cond_signal(&RC.ru_cond);
-      AssertFatal((ret=pthread_mutex_unlock(&RC.ru_mutex))==0,"mutex_unlock returns %d\n",ret);
+    phy_init_RU(ru);
+      
+      
+    if (setup_RU_buffers(ru)!=0) {
+        LOG_I(PHY,"Exiting, cannot initialize RU Buffers\n");
+	      exit(-1);
     }
 
     AssertFatal((ret=pthread_mutex_lock(&RC.ru_mutex))==0,"mutex_lock returns %d\n",ret);
@@ -1745,9 +1693,9 @@ static void *ru_thread( void *param ) {
 
       // Start RF device if any
       if (ru->start_rf) {
-        if (ru->start_rf(ru) != 0)
-          LOG_E(HW,"Could not start the RF device\n");
-        else LOG_I(PHY,"RU %d rf device ready\n",ru->idx);
+	if (ru->start_rf(ru) != 0)
+	  AssertFatal(1==0,"Could not start the RF device\n");
+	else LOG_I(PHY,"RU %d rf device ready\n",ru->idx);
       } else LOG_D(PHY,"RU %d no rf device\n",ru->idx);
     }
 
@@ -1781,7 +1729,6 @@ static void *ru_thread( void *param ) {
       // synchronization on input FH interface, acquire signals/data and block
       if (ru->fh_south_in) ru->fh_south_in(ru,&frame,&subframe);
       else AssertFatal(1==0, "No fronthaul interface at south port");
-
 #ifdef PHY_TX_THREAD
 
       if(first_phy_tx == 0) {
@@ -1945,7 +1892,7 @@ static void *ru_thread( void *param ) {
     } // ru->state = RU_RUN
   } // while !oai_exit
 
-  printf( "Exiting ru_thread \n");
+  LOG_I(PHY, "Exiting ru_thread \n");
 
   if (!(get_softmodem_params()->emulate_rf)) {
     if (ru->stop_rf != NULL) {
@@ -2190,6 +2137,12 @@ static void *rf_tx( void *param ) {
 #endif
 
 
+
+int start_streaming(RU_t *ru) {
+  LOG_I(PHY,"Starting streaming on third-party RRU\n");
+  return(ru->ifdevice.thirdparty_startstreaming(&ru->ifdevice));
+}
+
 int start_if(struct RU_t_s *ru,struct PHY_VARS_eNB_s *eNB) {
   return(ru->ifdevice.trx_start_func(&ru->ifdevice));
 }
@@ -2235,7 +2188,7 @@ void reset_proc(RU_t *ru) {
 
 
 void init_RU_proc(RU_t *ru) {
-  int i=0, ret;
+  int i=0;
   RU_proc_t *proc;
   pthread_attr_t *attr_FH=NULL, *attr_FH1=NULL, *attr_prach=NULL, *attr_asynch=NULL, *attr_synch=NULL, *attr_emulateRF=NULL, *attr_ctrl=NULL, *attr_prach_br=NULL;
   //pthread_attr_t *attr_fep=NULL;
@@ -2304,7 +2257,17 @@ void init_RU_proc(RU_t *ru) {
   attr_prach_br  = &proc->attr_prach_br;
 #endif
 
-  if (ru->function!=eNodeB_3GPP) pthread_create( &proc->pthread_ctrl, attr_ctrl, ru_thread_control, (void *)ru );
+  if (ru->has_ctrl_prt == 1) pthread_create( &proc->pthread_ctrl, attr_ctrl, ru_thread_control, (void*)ru );
+  else {
+    if (ru->start_if) {
+      LOG_I(PHY,"Starting IF interface for RU %d\n",ru->idx);
+      AssertFatal(
+                  ru->start_if(ru,NULL)   == 0, "Could not start the IF device\n");
+
+      if (ru->if_south != LOCAL_RF) wait_eNBs();
+    }
+  }
+
 
   pthread_create( &proc->pthread_FH, attr_FH, ru_thread, (void *)ru );
 #if defined(PRE_SCD_THREAD)
@@ -2343,23 +2306,6 @@ void init_RU_proc(RU_t *ru) {
     LOG_I(PHY,"%s() DJP - added creation of pthread_prach\n", __FUNCTION__);
     pthread_create( &proc->pthread_prach, attr_prach, ru_thread_prach, (void *)ru );
     ru->state=RU_RUN;
-    if(!get_softmodem_params()->emulate_rf)
-    {
-      fill_rf_config(ru,ru->rf_config_file);
-      init_frame_parms(ru->frame_parms,1);
-      ru->frame_parms->nb_antennas_rx = ru->nb_rx;
-      phy_init_RU(ru);
-      ret = openair0_device_load(&ru->rfdevice,&ru->openair0_cfg);
-      if (ret < 0) {
-         LOG_I(PHY,"Exiting, cannot load device. Make sure that your SDR board is connected!\n");
-         exit(1);
-      }
-
-      if (setup_RU_buffers(ru)!=0) {
-        LOG_I(PHY,"Exiting, cannot initialize RU Buffers\n");
-        exit(1);
-      }
-    }
   }
 
   if (get_thread_worker_conf() == WORKER_ENABLE) {
@@ -2368,7 +2314,7 @@ void init_RU_proc(RU_t *ru) {
   }
 
   if (opp_enabled == 1) pthread_create(&ru->ru_stats_thread,NULL,ru_stats_thread,(void *)ru);
-
+/*
   if (ru->function == eNodeB_3GPP) {
     usleep(10000);
     LOG_I(PHY, "Signaling main thread that RU %d (is_slave %d,send_dmrs %d) is ready in state %s\n",ru->idx,ru->is_slave,ru->generate_dmrs_sync,ru_states[ru->state]);
@@ -2377,6 +2323,7 @@ void init_RU_proc(RU_t *ru) {
     pthread_cond_signal(&RC.ru_cond);
     AssertFatal((ret=pthread_mutex_unlock(&RC.ru_mutex))==0,"mutex_unlock returns %d\n",ret);
   }
+  */
 }
 
 
@@ -2539,6 +2486,7 @@ void init_precoding_weights(PHY_VARS_eNB *eNB) {
 void set_function_spec_param(RU_t *ru) {
   int ret;
 
+
   switch (ru->if_south) {
     case LOCAL_RF:   // this is an RU with integrated RF (RRU, eNB)
       if (ru->function ==  NGFI_RRU_IF5) {                 // IF5 RRU
@@ -2559,10 +2507,10 @@ void set_function_spec_param(RU_t *ru) {
         reset_meas(&ru->compression);
         reset_meas(&ru->transport);
         ret = openair0_transport_load(&ru->ifdevice,&ru->openair0_cfg,&ru->eth_params);
-        printf("openair0_transport_init returns %d for ru_id %d\n", ret, ru->idx);
+        LOG_I(PHY,"NGFI_RRU_IF5: openair0_transport_init returns %d for ru_id %d\n", ret, ru->idx);
 
         if (ret<0) {
-          printf("Exiting, cannot initialize transport protocol\n");
+          LOG_I(PHY,"Exiting, cannot initialize transport protocol\n");
           exit(-1);
         }
       } else if (ru->function == NGFI_RRU_IF4p5) {
@@ -2583,10 +2531,10 @@ void set_function_spec_param(RU_t *ru) {
         reset_meas(&ru->compression);
         reset_meas(&ru->transport);
         ret = openair0_transport_load(&ru->ifdevice,&ru->openair0_cfg,&ru->eth_params);
-        printf("openair0_transport_init returns %d for ru_id %d\n", ret, ru->idx);
+        LOG_I(PHY,"NGFI_RRU_if4p5 : openair0_transport_init returns %d for ru_id %d\n", ret, ru->idx);
 
         if (ret<0) {
-          printf("Exiting, cannot initialize transport protocol\n");
+          LOG_I(PHY,"Exiting, cannot initialize transport protocol\n");
           exit(-1);
         }
 
@@ -2606,7 +2554,7 @@ void set_function_spec_param(RU_t *ru) {
       ru->fh_south_out           = tx_rf;                               // local synchronous RF TX
       ru->start_rf               = start_rf;                            // need to start the local RF interface
       ru->stop_rf                = stop_rf;
-      printf("configuring ru_id %d (start_rf %p)\n", ru->idx, start_rf);
+      LOG_I(PHY,"NFGI_RRU_IF4p5: configuring ru_id %d (start_rf %p)\n", ru->idx, start_rf);
       /*
         if (ru->function == eNodeB_3GPP) { // configure RF parameters only for 3GPP eNodeB, we need to get them from RAU otherwise
         fill_rf_config(ru,rf_config_file);
@@ -2616,7 +2564,7 @@ void set_function_spec_param(RU_t *ru) {
 
         ret = openair0_device_load(&ru->rfdevice,&ru->openair0_cfg);
         if (setup_RU_buffers(ru)!=0) {
-        printf("Exiting, cannot initialize RU Buffers\n");
+        LOG_I(PHY,"Exiting, cannot initialize RU Buffers\n");
         exit(-1);
         }*/
       break;
@@ -2629,25 +2577,22 @@ void set_function_spec_param(RU_t *ru) {
 
       if (ru->if_timing == synch_to_other) {
         ru->fh_south_in          = fh_slave_south_in;                  // synchronize to master
-        ru->fh_south_out         = fh_if5_mobipass_south_out;          // use send_IF5 for mobipass
-        ru->fh_south_asynch_in   = fh_if5_south_asynch_in_mobipass;    // UL is asynchronous
       } else {
         ru->fh_south_in          = fh_if5_south_in;     // synchronous IF5 reception
         ru->fh_south_out         = fh_if5_south_out;    // synchronous IF5 transmission
         ru->fh_south_asynch_in   = NULL;                // no asynchronous UL
       }
-
-      ru->start_rf               = NULL;                 // no local RF
+      ru->start_rf               = ru->eth_params.transp_preference == ETH_UDP_IF5_ECPRI_MODE ? start_streaming : NULL;
       ru->stop_rf                = NULL;
       ru->start_if               = start_if;             // need to start if interface for IF5
       ru->ifdevice.host_type     = RAU_HOST;
       ru->ifdevice.eth_params    = &ru->eth_params;
       ru->ifdevice.configure_rru = configure_ru;
       ret = openair0_transport_load(&ru->ifdevice,&ru->openair0_cfg,&ru->eth_params);
-      printf("openair0_transport_init returns %d for ru_id %d\n", ret, ru->idx);
+      LOG_I(PHY,"REMOTE_IF5: openair0_transport_init returns %d for ru_id %d\n", ret, ru->idx);
 
       if (ret<0) {
-        printf("Exiting, cannot initialize transport protocol\n");
+        LOG_I(PHY,"Exiting, cannot initialize transport protocol\n");
         exit(-1);
       }
 
@@ -2670,10 +2615,10 @@ void set_function_spec_param(RU_t *ru) {
       ru->ifdevice.eth_params    = &ru->eth_params;
       ru->ifdevice.configure_rru = configure_ru;
       ret = openair0_transport_load(&ru->ifdevice, &ru->openair0_cfg, &ru->eth_params);
-      printf("openair0_transport_init returns %d for ru_id %d\n", ret, ru->idx);
+      LOG_I(PHY,"REMOTE IF4p5: openair0_transport_init returns %d for ru_id %d\n", ret, ru->idx);
 
       if (ret<0) {
-        printf("Exiting, cannot initialize transport protocol\n");
+        LOG_I(PHY,"Exiting, cannot initialize transport protocol\n");
         exit(-1);
       }
 
@@ -2687,12 +2632,14 @@ void set_function_spec_param(RU_t *ru) {
       }
 
       malloc_IF4p5_buffer(ru);
+
       break;
 
     default:
       LOG_E(PHY,"RU with invalid or unknown southbound interface type %d\n",ru->if_south);
       break;
   } // switch on interface type
+
 }
 
 //extern void RCconfig_RU(void);
@@ -2782,6 +2729,11 @@ void init_RU(char *rf_config_file, int send_dmrssync) {
 
     LOG_I(PHY, "Initializing RRU descriptor %d : (%s,%s,%d)\n", ru_id, ru_if_types[ru->if_south], NB_timing[ru->if_timing], ru->function);
     set_function_spec_param(ru);
+    if (ru->function != NGFI_RRU_IF4p5 && ru->function != NGFI_RRU_IF5) {
+       fill_rf_config(ru,ru->rf_config_file);
+       init_frame_parms(ru->frame_parms,1);
+    }
+
     LOG_I(PHY, "Starting ru_thread %d, is_slave %d, send_dmrs %d\n", ru_id, ru->is_slave, ru->generate_dmrs_sync);
     init_RU_proc(ru);
   } // for ru_id
@@ -2795,7 +2747,7 @@ void stop_ru(RU_t *ru) {
 #if defined(PRE_SCD_THREAD) || defined(PHY_TX_THREAD)
   int *status;
 #endif
-  printf("Stopping RU %p processing threads\n",(void *)ru);
+  LOG_I(PHY,"Stopping RU %p processing threads\n",(void *)ru);
 #if defined(PRE_SCD_THREAD)
 
   if(ru) {
@@ -2849,7 +2801,7 @@ void init_ru_vnf(void) {
   pthread_mutex_init(&RC.ru_mutex,NULL);
   pthread_cond_init(&RC.ru_cond,NULL);
   // read in configuration file)
-  printf("configuring RU from file\n");
+  LOG_I(PHY,"configuring RU from file\n");
   RCconfig_RU();
   LOG_I(PHY,"number of L1 instances %d, number of RU %d, number of CPU cores %d\n",RC.nb_L1_inst,RC.nb_RU,get_nprocs());
 
@@ -2939,7 +2891,7 @@ void RCconfig_RU(void) {
       RC.ru[j]                                    = (RU_t *)malloc(sizeof(RU_t));
       memset((void *)RC.ru[j],0,sizeof(RU_t));
       RC.ru[j]->idx                                 = j;
-      printf("Creating RC.ru[%d]:%p\n", j, RC.ru[j]);
+      LOG_I(PHY,"Creating RC.ru[%d]:%p\n", j, RC.ru[j]);
       RC.ru[j]->if_timing                           = synch_to_ext_device;
 
       if (RC.nb_L1_inst >0)
@@ -2949,7 +2901,7 @@ void RCconfig_RU(void) {
 
       for (i=0; i<RC.ru[j]->num_eNB; i++) RC.ru[j]->eNB_list[i] = RC.eNB[RUParamList.paramarray[j][RU_ENB_LIST_IDX].iptr[i]][0];
 
-      RC.ru[j]->has_ctrl_prt                        = 1;
+      RC.ru[j]->has_ctrl_prt                        = 0;
 
       if (config_isparamset(RUParamList.paramarray[j], RU_SDR_ADDRS)) {
         RC.ru[j]->openair0_cfg.sdr_addrs = strdup(*(RUParamList.paramarray[j][RU_SDR_ADDRS].strptr));
@@ -2996,7 +2948,7 @@ void RCconfig_RU(void) {
           RC.ru[j]->if_south                        = LOCAL_RF;
           RC.ru[j]->function                        = eNodeB_3GPP;
           RC.ru[j]->state                           = RU_RUN;
-          printf("Setting function for RU %d to eNodeB_3GPP\n",j);
+          LOG_I(PHY,"Setting function for RU %d to eNodeB_3GPP\n",j);
         } else {
           RC.ru[j]->eth_params.local_if_name            = strdup(*(RUParamList.paramarray[j][RU_LOCAL_IF_NAME_IDX].strptr));
           RC.ru[j]->eth_params.my_addr                  = strdup(*(RUParamList.paramarray[j][RU_LOCAL_ADDRESS_IDX].strptr));
@@ -3006,42 +2958,43 @@ void RCconfig_RU(void) {
 
           // Check if control port set
           if  (!(config_isparamset(RUParamList.paramarray[j],RU_REMOTE_PORTC_IDX)) ) {
-            printf("Removing control port for RU %d\n",j);
+            LOG_I(PHY,"Removing control port for RU %d\n",j);
             RC.ru[j]->has_ctrl_prt            = 0;
           } else {
             RC.ru[j]->eth_params.my_portc                 = *(RUParamList.paramarray[j][RU_LOCAL_PORTC_IDX].uptr);
             RC.ru[j]->eth_params.remote_portc             = *(RUParamList.paramarray[j][RU_REMOTE_PORTC_IDX].uptr);
-            printf(" Control port %u \n",RC.ru[j]->eth_params.my_portc);
+            LOG_I(PHY," Control port %u \n",RC.ru[j]->eth_params.my_portc);
           }
 
           if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "udp") == 0) {
             RC.ru[j]->if_south                        = LOCAL_RF;
             RC.ru[j]->function                        = NGFI_RRU_IF5;
             RC.ru[j]->eth_params.transp_preference    = ETH_UDP_MODE;
-            printf("Setting function for RU %d to NGFI_RRU_IF5 (udp)\n",j);
+            LOG_I(PHY,"Setting function for RU %d to NGFI_RRU_IF5 (udp)\n",j);
           } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw") == 0) {
             RC.ru[j]->if_south                        = LOCAL_RF;
             RC.ru[j]->function                        = NGFI_RRU_IF5;
             RC.ru[j]->eth_params.transp_preference    = ETH_RAW_MODE;
-            printf("Setting function for RU %d to NGFI_RRU_IF5 (raw)\n",j);
+            LOG_I(PHY,"Setting function for RU %d to NGFI_RRU_IF5 (raw)\n",j);
           } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "udp_if4p5") == 0) {
             RC.ru[j]->if_south                        = LOCAL_RF;
             RC.ru[j]->function                        = NGFI_RRU_IF4p5;
             RC.ru[j]->eth_params.transp_preference    = ETH_UDP_IF4p5_MODE;
-            printf("Setting function for RU %d to NGFI_RRU_IF4p5 (udp)\n",j);
+            RC.ru[j]->has_ctrl_prt                   =1;
+            LOG_I(PHY,"Setting function for RU %d to NGFI_RRU_IF4p5 (udp)\n",j);
           } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw_if4p5") == 0) {
             RC.ru[j]->if_south                        = LOCAL_RF;
             RC.ru[j]->function                        = NGFI_RRU_IF4p5;
             RC.ru[j]->eth_params.transp_preference    = ETH_RAW_IF4p5_MODE;
-            printf("Setting function for RU %d to NGFI_RRU_IF4p5 (raw)\n",j);
+            LOG_I(PHY,"Setting function for RU %d to NGFI_RRU_IF4p5 (raw)\n",j);
           }
 
-          printf("RU %d is_slave=%s\n",j,*(RUParamList.paramarray[j][RU_IS_SLAVE_IDX].strptr));
+          LOG_I(PHY,"RU %d is_slave=%s\n",j,*(RUParamList.paramarray[j][RU_IS_SLAVE_IDX].strptr));
 
           if (strcmp(*(RUParamList.paramarray[j][RU_IS_SLAVE_IDX].strptr), "yes") == 0) RC.ru[j]->is_slave=1;
           else RC.ru[j]->is_slave=0;
 
-          printf("RU %d ota_sync_enabled=%s\n",j,*(RUParamList.paramarray[j][RU_OTA_SYNC_ENABLE_IDX].strptr));
+          LOG_I(PHY,"RU %d ota_sync_enabled=%s\n",j,*(RUParamList.paramarray[j][RU_OTA_SYNC_ENABLE_IDX].strptr));
 
           if (strcmp(*(RUParamList.paramarray[j][RU_OTA_SYNC_ENABLE_IDX].strptr), "yes") == 0) RC.ru[j]->ota_sync_enable=1;
           else RC.ru[j]->ota_sync_enable=0;
@@ -3055,8 +3008,8 @@ void RCconfig_RU(void) {
 
         for (i=0; i<RC.ru[j]->num_bands; i++) RC.ru[j]->band[i] = RUParamList.paramarray[j][RU_BAND_LIST_IDX].iptr[i];
       } //strcmp(local_rf, "yes") == 0
-      else {
-        printf("RU %d: Transport %s\n",j,*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr));
+else {
+        LOG_I(PHY,"RU %d: Transport %s\n",j,*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr));
         RC.ru[j]->eth_params.local_if_name      = strdup(*(RUParamList.paramarray[j][RU_LOCAL_IF_NAME_IDX].strptr));
         RC.ru[j]->eth_params.my_addr            = strdup(*(RUParamList.paramarray[j][RU_LOCAL_ADDRESS_IDX].strptr));
         RC.ru[j]->eth_params.remote_addr        = strdup(*(RUParamList.paramarray[j][RU_REMOTE_ADDRESS_IDX].strptr));
@@ -3064,34 +3017,34 @@ void RCconfig_RU(void) {
         RC.ru[j]->eth_params.remote_portc       = *(RUParamList.paramarray[j][RU_REMOTE_PORTC_IDX].uptr);
         RC.ru[j]->eth_params.my_portd           = *(RUParamList.paramarray[j][RU_LOCAL_PORTD_IDX].uptr);
         RC.ru[j]->eth_params.remote_portd       = *(RUParamList.paramarray[j][RU_REMOTE_PORTD_IDX].uptr);
-
+      
         if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "udp") == 0) {
-          RC.ru[j]->if_south                     = REMOTE_IF5;
-          RC.ru[j]->function                     = NGFI_RAU_IF5;
-          RC.ru[j]->eth_params.transp_preference = ETH_UDP_MODE;
+	  RC.ru[j]->if_south                     = REMOTE_IF5;
+	  RC.ru[j]->function                     = NGFI_RAU_IF5;
+	  RC.ru[j]->eth_params.transp_preference = ETH_UDP_MODE;
+        } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "udp_ecpri_if5") == 0) {
+	  RC.ru[j]->if_south                     = REMOTE_IF5;
+	  RC.ru[j]->function                     = NGFI_RAU_IF5;
+	  RC.ru[j]->eth_params.transp_preference = ETH_UDP_IF5_ECPRI_MODE;
         } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw") == 0) {
-          RC.ru[j]->if_south                     = REMOTE_IF5;
-          RC.ru[j]->function                     = NGFI_RAU_IF5;
-          RC.ru[j]->eth_params.transp_preference = ETH_RAW_MODE;
+	  RC.ru[j]->if_south                     = REMOTE_IF5;
+	  RC.ru[j]->function                     = NGFI_RAU_IF5;
+	  RC.ru[j]->eth_params.transp_preference = ETH_RAW_MODE;
         } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "udp_if4p5") == 0) {
-          RC.ru[j]->if_south                     = REMOTE_IF4p5;
-          RC.ru[j]->function                     = NGFI_RAU_IF4p5;
-          RC.ru[j]->eth_params.transp_preference = ETH_UDP_IF4p5_MODE;
+	  RC.ru[j]->if_south                     = REMOTE_IF4p5;
+	  RC.ru[j]->function                     = NGFI_RAU_IF4p5;
+  	  RC.ru[j]->eth_params.transp_preference = ETH_UDP_IF4p5_MODE;
+	  RC.ru[j]->has_ctrl_prt                 = 1;
         } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw_if4p5") == 0) {
-          RC.ru[j]->if_south                     = REMOTE_IF4p5;
-          RC.ru[j]->function                     = NGFI_RAU_IF4p5;
-          RC.ru[j]->eth_params.transp_preference = ETH_RAW_IF4p5_MODE;
-        } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw_if5_mobipass") == 0) {
-          RC.ru[j]->if_south                     = REMOTE_IF5;
-          RC.ru[j]->function                     = NGFI_RAU_IF5;
-          RC.ru[j]->if_timing                    = synch_to_other;
-          RC.ru[j]->eth_params.transp_preference = ETH_RAW_IF5_MOBIPASS;
+	  RC.ru[j]->if_south                     = REMOTE_IF4p5;
+	  RC.ru[j]->function                     = NGFI_RAU_IF4p5;
+	  RC.ru[j]->eth_params.transp_preference = ETH_RAW_IF4p5_MODE;
+	
+          if (strcmp(*(RUParamList.paramarray[j][RU_IS_SLAVE_IDX].strptr), "yes") == 0) RC.ru[j]->is_slave=1;
+          else RC.ru[j]->is_slave=0;
         }
-
-        if (strcmp(*(RUParamList.paramarray[j][RU_IS_SLAVE_IDX].strptr), "yes") == 0) RC.ru[j]->is_slave=1;
-        else RC.ru[j]->is_slave=0;
       }  /* strcmp(local_rf, "yes") != 0 */
-
+      
       RC.ru[j]->nb_tx                             = *(RUParamList.paramarray[j][RU_NB_TX_IDX].uptr);
       RC.ru[j]->nb_rx                             = *(RUParamList.paramarray[j][RU_NB_RX_IDX].uptr);
       RC.ru[j]->att_tx                            = *(RUParamList.paramarray[j][RU_ATT_TX_IDX].uptr);
diff --git a/targets/RT/USER/rcc_if5.gtkw b/targets/RT/USER/rcc_if5.gtkw
index d64a9ca0fb2e0352c5f9f7a584ad2225cd140249..34c6bab5d13b26fb44e8ff1b0a0173ae88577d33 100644
--- a/targets/RT/USER/rcc_if5.gtkw
+++ b/targets/RT/USER/rcc_if5.gtkw
@@ -1,41 +1,67 @@
 [*]
-[*] GTKWave Analyzer v3.3.58 (w)1999-2014 BSI
-[*] Sun Jul 31 13:30:42 2016
+[*] GTKWave Analyzer v3.3.66 (w)1999-2015 BSI
+[*] Tue Sep 24 06:59:08 2019
 [*]
 [dumpfile] "/tmp/openair_dump_eNB.vcd"
-[dumpfile_mtime] "Sun Jul 31 13:21:59 2016"
-[dumpfile_size] 18273240
-[savefile] "/home/fourmi/openairinterface5g/targets/RT/USER/rcc_if5.gtkw"
-[timestart] 24070893000
-[size] 1301 716
-[pos] 309 0
-*-19.793451 29026062100 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
-[sst_width] 284
-[signals_width] 262
+[dumpfile_mtime] "Mon Sep 23 20:04:56 2019"
+[dumpfile_size] 1625759
+[savefile] "/home/orange/aw2s/openairinterface5g/targets/RT/USER/rcc_if5.gtkw"
+[timestart] 12600104000
+[size] 1215 1000
+[pos] 0 22
+*-19.506693 12600920638 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
+[sst_width] 386
+[signals_width] 344
 [sst_expanded] 1
-[sst_vpaned_height] 294
+[sst_vpaned_height] 303
+@29
+functions.send_if5
+@28
+functions.recv_if5
 @24
 variables.trx_ts[63:0]
 variables.trx_tst[63:0]
 @28
-functions.send_if5
-functions.recv_if5
 functions.eNB_thread_rxtx0
 @24
+variables.frame_number_RX0_RU[63:0]
+variables.subframe_number_RX0_RU[63:0]
+variables.frame_number_TX0_RU[63:0]
+variables.subframe_number_TX0_RU[63:0]
+@28
+functions.mac_schedule_dlsch
+functions.macxface_eNB_dlsch_ulsch_scheduler
+functions.macxface_ue_scheduler
+functions.phy_eNB_ofdm_mod_l
+@24
 variables.frame_number_RX0_eNB[63:0]
 variables.subframe_number_RX0_eNB[63:0]
 variables.frame_number_TX0_eNB[63:0]
 variables.subframe_number_TX0_eNB[63:0]
-@28
-functions.eNB_thread_rxtx1
-@24
 variables.frame_number_RX1_eNB[63:0]
 variables.subframe_number_RX1_eNB[63:0]
 variables.frame_number_TX1_eNB[63:0]
 variables.subframe_number_TX1_eNB[63:0]
 @28
+functions.phy_eNB_dlsch_modulation
+functions.phy_eNB_dlsch_encoding
+functions.phy_eNB_dlsch_scrambling
+functions.phy_eNB_beam_precoding
+functions.phy_enb_pdcch_tx
+functions.phy_enb_prach_rx
+functions.phy_procedures_ru_feprx0
+functions.phy_procedures_eNb_rx_uespec0
+functions.phy_procedures_eNb_rx_uespec1
+functions.phy_enb_sfgen
+functions.phy_procedures_eNb_tx0
+functions.phy_procedures_eNb_tx1
+functions.phy_procedures_ru_feprx1
+functions.phy_procedures_ru_feptx_ofdm0
+functions.phy_procedures_ru_feptx_ofdm1
+functions.phy_procedures_ru_feptx_prec0
+functions.phy_procedures_ru_feptx_prec1
+functions.eNB_thread_rxtx1
 functions.phy_enb_sfgen
-functions.phy_eNB_slot_fep
 functions.phy_enb_prach_rx
 @24
 variables.dci_info[63:0]
diff --git a/targets/RT/USER/ru_control.c b/targets/RT/USER/ru_control.c
index 6daf0f4dfac678a831fcfa0d08c7e7545eab5720..7ac6a8913ef3be0d7eea86a16993aa0126a55617 100644
--- a/targets/RT/USER/ru_control.c
+++ b/targets/RT/USER/ru_control.c
@@ -524,7 +524,7 @@ void* ru_thread_control( void* param )
   }
 
   
-  ru->state = (ru->function==eNodeB_3GPP)? RU_RUN : RU_IDLE;
+  ru->state = (ru->function==eNodeB_3GPP || ru->if_south == REMOTE_IF5)? RU_RUN : RU_IDLE;
   LOG_I(PHY,"Control channel ON for RU %d\n", ru->idx);
 
   while (!oai_exit) // Change the cond