diff --git a/openair1/PHY/LTE_TRANSPORT/if4_tools.c b/openair1/PHY/LTE_TRANSPORT/if4_tools.c
index 8f01fc5369c9515a0eb135f9ae8ae1ee7cfaa28f..655c61c15cadd61d0e9767507fd9c3d31dd99058 100644
--- a/openair1/PHY/LTE_TRANSPORT/if4_tools.c
+++ b/openair1/PHY/LTE_TRANSPORT/if4_tools.c
@@ -133,7 +133,7 @@ void send_IF4p5(PHY_VARS_eNB *eNB, int frame, int subframe, uint16_t packet_type
     }		
   } else if (packet_type == IF4p5_PRACH) {
     // FIX: hard coded prach samples length
-    db_fulllength = 839*2;
+    db_fulllength = 840*2;
 
     IF4p5_header_t *prach_header = (IF4p5_header_t *)(tx_buffer + MAC_HEADER_SIZE_BYTES);
     data_block = (uint16_t*)(tx_buffer + MAC_HEADER_SIZE_BYTES + sizeof_IF4p5_header_t);
diff --git a/openair1/PHY/LTE_TRANSPORT/prach.c b/openair1/PHY/LTE_TRANSPORT/prach.c
index 0adb8685f0d5be4bb33f2fbe3d266ce9e4c452fe..df28dfd6fa7a77d95d787a003639d7f65e3a4dc0 100644
--- a/openair1/PHY/LTE_TRANSPORT/prach.c
+++ b/openair1/PHY/LTE_TRANSPORT/prach.c
@@ -1065,7 +1065,7 @@ void rx_prach(PHY_VARS_eNB *eNB,
 
   int i;
   lte_frame_type_t frame_type = eNB->frame_parms.frame_type;
-  int subframe                = eNB->proc.subframe_rx;
+  int subframe                = eNB->proc.subframe_prach;
   uint16_t rootSequenceIndex  = eNB->frame_parms.prach_config_common.rootSequenceIndex;
   uint8_t prach_ConfigIndex   = eNB->frame_parms.prach_config_common.prach_ConfigInfo.prach_ConfigIndex;
   uint8_t Ncs_config          = eNB->frame_parms.prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig;
@@ -1101,6 +1101,8 @@ void rx_prach(PHY_VARS_eNB *eNB,
   int fft_size,log2_ifft_size;
   uint8_t nb_ant_rx = 1; //eNB->frame_parms.nb_antennas_rx;
 
+  //  int en;
+
   for (aa=0; aa<nb_ant_rx; aa++) {
     prach[aa] = (int16_t*)&eNB->common_vars.rxdata[0][aa][subframe*eNB->frame_parms.samples_per_tti-eNB->N_TA_offset];
   }
@@ -1282,8 +1284,11 @@ void rx_prach(PHY_VARS_eNB *eNB,
     k*=2;
     
     /// **** send_IF4 of rxsigF to RCC **** ///    
-    send_IF4p5(eNB, eNB->proc.frame_rx, eNB->proc.subframe_rx, IF4p5_PRACH, k);
+    send_IF4p5(eNB, eNB->proc.frame_prach, eNB->proc.subframe_prach, IF4p5_PRACH, k);
 
+    //    en = dB_fixed(signal_energy(&rxsigF[0][k],840));
+    //    if (en>60)
+    //      printf("PRACH: Frame %d, Subframe %d => %d dB\n",eNB->proc.frame_rx,eNB->proc.subframe_rx,en);
     return;
   } else if (eNB->node_function == NGFI_RCC_IF4p5) {
     k = (12*n_ra_prb) - 6*eNB->frame_parms.N_RB_UL;
@@ -1469,11 +1474,24 @@ void rx_prach(PHY_VARS_eNB *eNB,
 #endif
       // if (aa=1) write_output("prach_rxF_comp1.m","prach_rxF_comp1",prachF,1024,1,1);
       }// antennas_rx
+
 #ifdef PRACH_DEBUG
-      write_output("prach_ifft0.m","prach_t0",prach_ifft[0],2048,1,1);
+      if (en>40) {
+	k = (12*n_ra_prb) - 6*eNB->frame_parms.N_RB_UL;
+	
+	if (k<0)
+	  k+=(eNB->frame_parms.ofdm_symbol_size);
+	
+	k*=12;
+	k+=13;
+	k*=2;
+	printf("Dumping prach, k = %d (n_ra_prb %d)\n",k,n_ra_prb);
+	write_output("rxsigF.m","prach_rxF",&rxsigF[0][k],840,1,1);
+	write_output("prach_rxF_comp0.m","prach_rxF_comp0",prachF,1024,1,1);
+	write_output("prach_ifft0.m","prach_t0",prach_ifft[0],1024,1,1);
+	exit(-1);
+      }
 #endif
-      // write_output("prach_ifft1.m","prach_t1",prach_ifft[1],2048,1,1);
-      
     } // new dft
     
     // check energy in nth time shift
diff --git a/openair1/PHY/defs.h b/openair1/PHY/defs.h
index dd78e575bb487fe68f503237e2583e2a09bf83a3..9b5db4b421b367d9f17f6ad7dd84f4629c4e3efa 100755
--- a/openair1/PHY/defs.h
+++ b/openair1/PHY/defs.h
@@ -260,6 +260,8 @@ typedef struct eNB_proc_t_s {
   pthread_t pthread_asynch_rxtx;
   /// flag to indicate first RX acquisition
   int first_rx;
+  /// flag to indicate first TX transmission
+  int first_tx;
   /// pthread attributes for FH processing thread
   pthread_attr_t attr_FH;
   /// pthread attributes for prach processing thread
@@ -362,14 +364,15 @@ typedef struct PHY_VARS_eNB_s {
   eNB_func_t           node_function;
   eNB_timing_t         node_timing;
   int                  abstraction_flag;
-  void                 (*do_prach)(struct PHY_VARS_eNB_s *eNB,eNB_proc_t *proc);
-  void                 (*fep)(struct PHY_VARS_eNB_s *eNB,eNB_proc_t *proc);
+  void                 (*do_prach)(struct PHY_VARS_eNB_s *eNB);
+  void                 (*fep)(struct PHY_VARS_eNB_s *eNB);
   void                 (*proc_uespec_rx)(struct PHY_VARS_eNB_s *eNB,eNB_rxtx_proc_t *proc,const relaying_type_t r_type);
   void                 (*proc_tx)(struct PHY_VARS_eNB_s *eNB,eNB_rxtx_proc_t *proc,relaying_type_t r_type,PHY_VARS_RN *rn);
   void                 (*tx_fh)(struct PHY_VARS_eNB_s *eNB,eNB_rxtx_proc_t *proc);
-  void                 (*rx_fh)(struct PHY_VARS_eNB_s *eNB,eNB_proc_t *proc,int *frame, int *subframe);
+  void                 (*rx_fh)(struct PHY_VARS_eNB_s *eNB,int *frame, int *subframe);
   int                  (*start_rf)(struct PHY_VARS_eNB_s *eNB);
   int                  (*start_if)(struct PHY_VARS_eNB_s *eNB);
+  void                 (*fh_asynch)(struct PHY_VARS_eNB_s *eNB,int *frame, int *subframe);
   uint8_t              local_flag;
   uint32_t             rx_total_gain_dB;
   LTE_DL_FRAME_PARMS   frame_parms;
diff --git a/openair1/PHY/vars.h b/openair1/PHY/vars.h
index 85bfe7a2a65b41b88e6da9c0af695f4106da2667..b8cb33239d33c08b2d6a20bb0e0bf089983c7ff9 100755
--- a/openair1/PHY/vars.h
+++ b/openair1/PHY/vars.h
@@ -139,7 +139,7 @@ double beta2_dlsch[6][MCS_COUNT] = { {2.52163, 0.83231, 0.77472, 1.36536, 1.1682
 
 */
 
-char eNB_functions[5][20]={"eNodeB_3GPP","eNodeB_3GPP_BBU","NGFI_RRU_IF5","NGFI_RRU_IF4","NGFI_RCC_IF4"};
+char eNB_functions[6][20]={"eNodeB_3GPP","eNodeB_3GPP_BBU","NGFI_RCC_IF4p5","NGFI_RAI_IF4p5","NGFI_RRU_IF5","NGFI_RRU_IF4p5",};
 char eNB_timing[2][20]={"synch_to_ext_device","synch_to_other"};
 
 
diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c
index 6bf9273776003438af03b98ff31d55384338f21e..b1c37e95790e636719c7c1da720511b3424dca45 100755
--- a/openair1/SCHED/phy_procedures_lte_eNb.c
+++ b/openair1/SCHED/phy_procedures_lte_eNb.c
@@ -1950,12 +1950,14 @@ void prach_procedures(PHY_VARS_eNB *eNB) {
           break;
         }
 
+	/*
 	mac_xface->initiate_ra_proc(eNB->Mod_id,
 				    eNB->CC_id,
 				    frame,
 				    preamble_max,
 				    preamble_delay_list[preamble_max]*update_TA,
 				    0,subframe,0);
+	*/
       }      
 
     } else {
@@ -2490,8 +2492,9 @@ void cba_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,int UE_id,int harq_p
 
 }
 
-void eNB_fep_full(PHY_VARS_eNB *eNB,eNB_proc_t *proc) {
+void eNB_fep_full(PHY_VARS_eNB *eNB) {
 
+  eNB_proc_t *proc = &eNB->proc;
   int l;
   LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
 
@@ -2503,7 +2506,7 @@ void eNB_fep_full(PHY_VARS_eNB *eNB,eNB_proc_t *proc) {
 		&eNB->common_vars,
 		l,
 		proc->subframe_rx<<1,
-		  0,
+		0,
 		0
 		);
     slot_fep_ul(fp,
@@ -2519,14 +2522,13 @@ void eNB_fep_full(PHY_VARS_eNB *eNB,eNB_proc_t *proc) {
   
   if (eNB->node_function == NGFI_RRU_IF4p5) {
     /// **** send_IF4 of rxdataF to RCC (no prach now) **** ///
-    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF4, 1 );   
     send_IF4p5(eNB, proc->frame_rx, proc->subframe_rx, IF4p5_PULFFT, 0);
-    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF4, 0 );   
-    }    
+  }    
 }
 
-void eNB_fep_rru_if5(PHY_VARS_eNB *eNB,eNB_proc_t *proc) {
+void eNB_fep_rru_if5(PHY_VARS_eNB *eNB) {
 
+  eNB_proc_t *proc=&eNB->proc;
   uint8_t seqno=0;
 
   /// **** send_IF5 of rxdata to BBU **** ///       
@@ -2536,8 +2538,9 @@ void eNB_fep_rru_if5(PHY_VARS_eNB *eNB,eNB_proc_t *proc) {
 
 }
 
-void do_prach(PHY_VARS_eNB *eNB,eNB_proc_t *proc) {
+void do_prach(PHY_VARS_eNB *eNB) {
 
+  eNB_proc_t *proc = &eNB->proc;
   LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
 
   // check if we have to detect PRACH first
@@ -2594,9 +2597,9 @@ void phy_procedures_eNB_common_RX(PHY_VARS_eNB *eNB){
   LOG_D(PHY,"[eNB %d] Frame %d: Doing phy_procedures_eNB_common_RX(%d)\n",eNB->Mod_id,frame,subframe);
 
 
-  if (eNB->fep) eNB->fep(eNB,proc);
+  if (eNB->fep) eNB->fep(eNB);
 
-  if (eNB->do_prach) eNB->do_prach(eNB,proc);
+  if (eNB->do_prach) eNB->do_prach(eNB);
   
 
 
diff --git a/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c b/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c
index 02ca6ee7eb4018ce334dab2c80cc35826acc21ac..3e06cf035641d1b6a8da1e73f9dbb9add19eb464 100644
--- a/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c
+++ b/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c
@@ -224,7 +224,8 @@ int trx_eth_write_raw_IF4p5(openair0_device *device, openair0_timestamp timestam
   eth->tx_nsamps = nblocks;
   
   memcpy(buff[0], (void*)&eth->eh, MAC_HEADER_SIZE_BYTES);	
-         
+
+
   bytes_sent = send(eth->sockfd[Mod_id],
                     buff[0], 
                     packet_size,
diff --git a/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c b/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c
index d5305588168e57b33126242e378ea528373e6f29..869777b6bf77169557ecb7945eaac27d8a750f88 100644
--- a/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c
+++ b/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c
@@ -83,7 +83,7 @@ int trx_eth_start(openair0_device *device) {
     }
     /* adjust MTU wrt number of samples per packet */
     if(ethernet_tune (device,MTU_SIZE,RAW_IF4p5_PRACH_SIZE_BYTES)!=0)  return -1;
-        if(ethernet_tune (device,RCV_TIMEOUT,5000)!=0)  return -1;
+        if(ethernet_tune (device,RCV_TIMEOUT,999999)!=0)  return -1;
 
   } else if (eth->flags == ETH_UDP_IF4p5_MODE) {
     
diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c
index b0d1eb3d0ecdadc7984b2d2b092efe06c5f4bc3d..d6e262a4d55f13e137feb7af8777b763f82d6fdb 100644
--- a/targets/RT/USER/lte-enb.c
+++ b/targets/RT/USER/lte-enb.c
@@ -365,13 +365,11 @@ void proc_tx_rru_if4p5(PHY_VARS_eNB *eNB,
   symbol_mask = 0;
   symbol_mask_full = (1<<eNB->frame_parms.symbols_per_tti)-1;
   
-  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF4, 1 );  
+
   do { 
     recv_IF4p5(eNB, &proc->frame_tx, &proc->subframe_tx, &packet_type, &symbol_number);
     symbol_mask = symbol_mask | (1<<symbol_number);
   } while (symbol_mask != symbol_mask_full); 
-  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF4, 0 );   
-
 
   do_OFDM_mod_rt(proc->subframe_tx, eNB);
 }
@@ -640,6 +638,151 @@ static void wait_system_ready (char *message, volatile int *start_flag) {
 }
 #endif
 
+
+// asynchronous UL with IF4p5 (RCC,RAU,eNodeB_BBU)
+void fh_if5_asynch_UL(PHY_VARS_eNB *eNB,int *frame,int *subframe) {
+
+  eNB_proc_t *proc       = &eNB->proc;
+  LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
+
+  recv_IF5(eNB, &proc->timestamp_rx, *subframe, IF5_RRH_GW_UL); 
+
+  proc->subframe_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 != 0) {
+    proc->first_rx = 0;
+    *subframe = proc->subframe_rx;
+    *frame    = proc->frame_rx; 
+  }
+  else {
+    if (proc->subframe_rx != *subframe) {
+      LOG_E(PHY,"subframe_rx %d is not what we expect %d\n",proc->subframe_rx,*subframe);
+      exit_fun("Exiting");
+    }
+    if (proc->frame_rx != *frame) {
+      LOG_E(PHY,"subframe_rx %d is not what we expect %d\n",proc->frame_rx,*frame);  
+      exit_fun("Exiting");
+    }
+  }
+} // eNodeB_3GPP_BBU 
+
+// asynchronous UL with IF4p5 (RCC,RAU,eNodeB_BBU)
+void fh_if4p5_asynch_UL(PHY_VARS_eNB *eNB,int *frame,int *subframe) {
+
+  LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
+  eNB_proc_t *proc       = &eNB->proc;
+
+  uint16_t packet_type;
+  uint32_t symbol_number,symbol_mask,symbol_mask_full,prach_rx;
+
+
+  symbol_number = 0;
+  symbol_mask = 0;
+  symbol_mask_full = (1<<fp->symbols_per_tti)-1;
+  prach_rx = 0;
+
+  do {   // Blocking, we need a timeout on this !!!!!!!!!!!!!!!!!!!!!!!
+    recv_IF4p5(eNB, &proc->frame_rx, &proc->subframe_rx, &packet_type, &symbol_number);
+    if (proc->first_rx != 0) {
+      *frame = proc->frame_rx;
+      *subframe = proc->subframe_rx;
+      proc->first_rx = 0;
+    }
+    else {
+      if (proc->frame_rx != *frame) {
+	LOG_E(PHY,"frame_rx %d is not what we expect %d\n",proc->frame_rx,*frame);
+	exit_fun("Exiting");
+      }
+      if (proc->subframe_rx != *subframe) {
+	LOG_E(PHY,"subframe_rx %d is not what we expect %d\n",proc->subframe_rx,*subframe);
+	exit_fun("Exiting");
+      }
+    }
+    if (packet_type == IF4p5_PULFFT) {
+      symbol_mask = symbol_mask | (1<<symbol_number);
+      prach_rx = (is_prach_subframe(fp, proc->frame_rx, proc->subframe_rx)>0) ? 1 : 0;                            
+    } else if (packet_type == IF4p5_PRACH) {
+      prach_rx = 0;
+    }
+  } while( (symbol_mask != symbol_mask_full) || (prach_rx == 1));    
+  
+
+} 
+
+
+void fh_if5_asynch_DL(PHY_VARS_eNB *eNB,int *frame,int *subframe) {
+
+  LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
+  eNB_proc_t *proc       = &eNB->proc;
+  int subframe_tx,frame_tx;
+  openair0_timestamp timestamp_tx;
+
+  recv_IF5(eNB, &timestamp_tx, *subframe, IF5_RRH_GW_DL); 
+      //      printf("Received subframe %d (TS %llu) from RCC\n",subframe_tx,timestamp_tx);
+
+  subframe_tx = (timestamp_tx/fp->samples_per_tti)%10;
+  frame_tx    = (timestamp_tx/(fp->samples_per_tti*10))&1023;
+
+  if (proc->first_tx != 0) {
+    *subframe = subframe_tx;
+    *frame    = frame_tx;
+    proc->first_tx = 0;
+  }
+  else {
+    if (subframe_tx != *subframe) {
+      LOG_E(PHY,"subframe_tx %d is not what we expect %d\n",subframe_tx,*subframe);
+      exit_fun("Exiting");
+    }
+    if (frame_tx != *frame) { 
+      LOG_E(PHY,"frame_tx %d is not what we expect %d\n",frame_tx,*frame);
+      exit_fun("Exiting");
+    }
+  }
+}
+
+void fh_if4p5_asynch_DL(PHY_VARS_eNB *eNB,int *frame,int *subframe) {
+
+  LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
+  eNB_proc_t *proc       = &eNB->proc;
+
+  uint16_t packet_type;
+  uint32_t symbol_number,symbol_mask,symbol_mask_full;
+  int subframe_tx,frame_tx;
+
+  symbol_number = 0;
+  symbol_mask = 0;
+  symbol_mask_full = (1<<fp->symbols_per_tti)-1;
+
+  do {   // Blocking, we need a timeout on this !!!!!!!!!!!!!!!!!!!!!!!
+    recv_IF4p5(eNB, &frame_tx, &subframe_tx, &packet_type, &symbol_number);
+    if (proc->first_tx != 0) {
+      *frame    = frame_tx;
+      *subframe = subframe_tx;
+      proc->first_tx = 0;
+    }
+    else {
+      if (frame_tx != *frame) {
+	LOG_E(PHY,"frame_tx %d is not what we expect %d\n",frame_tx,*frame);
+	exit_fun("Exiting");
+      }
+      if (subframe_tx != *subframe) {
+	LOG_E(PHY,"subframe_tx %d is not what we expect %d\n",subframe_tx,*subframe);
+	exit_fun("Exiting");
+      }
+    }
+    if (packet_type == IF4p5_PDLFFT) {
+      symbol_mask = symbol_mask | (1<<symbol_number);
+    }
+    else {
+      LOG_E(PHY,"Illegal IF4p5 packet type (should only be IF4p5_PDLFFT%d\n",packet_type);
+      exit_fun("Exiting");
+    }
+  } while (symbol_mask != symbol_mask_full);    
+  
+  do_OFDM_mod_rt(subframe_tx, eNB);
+} 
+
 /*!
  * \brief The Asynchronous RX/TX FH thread of RAU/RCC/eNB/RRU.
  * This handles the RX FH for an asynchronous RRU/UE
@@ -653,16 +796,9 @@ static void* eNB_thread_asynch_rxtx( void* param ) {
   eNB_proc_t *proc = (eNB_proc_t*)param;
   PHY_VARS_eNB *eNB = PHY_vars_eNB_g[0][proc->CC_id];
   LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
-  openair0_timestamp timestamp_rx,timestamp_tx;
-  int frame_rx,subframe_rx=0,subframe_tx=0;
-  static int first_rx = 1;
-  static int first_tx = 1;
-  uint16_t packet_type;
-  uint32_t symbol_number=0;
-  uint32_t symbol_mask, symbol_mask_full;
-  int prach_rx;
-  int dummy_rx[fp->nb_antennas_rx][fp->samples_per_tti]; 
-  int rxs=0;
+
+  int subframe=0, frame=0; 
+
 
 #ifdef DEADLINE_SCHEDULER
   struct sched_attr attr;
@@ -781,94 +917,35 @@ static void* eNB_thread_asynch_rxtx( void* param ) {
 
   printf( "devices ok (eNB_thread_asynch_rx)\n");
 
-  while (!oai_exit) { 
-    if (eNB->node_function == eNodeB_3GPP) { // acquisition from RF
-      
-      if (eNB->rfdevice.trx_read_func)
-	rxs = eNB->rfdevice.trx_read_func(&eNB->rfdevice,
-					  &proc->timestamp_rx,
-					  (void**)dummy_rx,
-					  fp->samples_per_tti,
-					  fp->nb_antennas_rx);
-      else {
-	printf("eNB asynch RX\n");
-	sleep(1);
-      }
-      if (rxs!=fp->samples_per_tti) {
-	exit_fun("error receiving samples\n");
-      }
-    }
-    else if (eNB->node_function == eNodeB_3GPP_BBU) { // acquisition from IF
-      /// **** recv_IF5 of rxdata from RRH **** ///       
-      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF5, 1 );  
-      recv_IF5(eNB, &timestamp_rx, subframe_rx++, IF5_RRH_GW_UL); 
-      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF5, 0 );  
-      if (first_rx == 1) {
-	first_rx = 0;
-	subframe_rx = (timestamp_rx/fp->samples_per_tti)%10;
-      }
-      else {
-	// check timestamp
-	if ((timestamp_rx - proc->timestamp_rx) < (2*fp->samples_per_tti))
-	  printf("RX overflow ...\n");
-	
-      }
-    } // eNodeB_3GPP_BBU 
-    
-    else if (eNB->node_function == NGFI_RRU_IF5) {
-      /// **** recv_IF5 of rxdata from RRH **** ///
 
-      subframe_tx = (subframe_tx+1)%10;
-      
-      recv_IF5(eNB, &timestamp_tx, subframe_tx, IF5_RRH_GW_DL); 
-      //      printf("Received subframe %d (TS %llu) from RCC\n",subframe_tx,timestamp_tx);
-      if (first_tx == 1) {
-	first_tx = 0;
-	subframe_tx = (timestamp_tx/fp->samples_per_tti)%10;
+  while (!oai_exit) { 
+   
+    if (oai_exit) break;   
 
-      }
-      
-    }
-    else if (eNB->node_function == NGFI_RCC_IF4p5) {
-      /// **** recv_IF4p5 of rxdataF from RRU **** ///
-      /// **** recv_IF4p5 of rxsigF from RRU **** ///
-      // get frame/subframe information from IF4p5 interface
-      // timed loop (200 us)
-      
-      symbol_number = 0;
-      symbol_mask = 0;
-      symbol_mask_full = (1<<fp->symbols_per_tti)-1;
-      prach_rx = 0;
-      
-      do {   // Blocking, we need a timeout on this !!!!!!!!!!!!!!!!!!!!!!!
-        recv_IF4p5(eNB, &frame_rx, &subframe_rx, &packet_type, &symbol_number);
-	
-        if (packet_type == IF4p5_PULFFT) {
-          symbol_mask = symbol_mask | (1<<symbol_number);
-          prach_rx = (is_prach_subframe(fp, proc->frame_rx, proc->subframe_rx)>0) ? 1 : 0;                            
-        } else if (packet_type == IF4p5_PRACH) {
-          prach_rx = 0;
-        }
-      } while( (symbol_mask != symbol_mask_full) || (prach_rx == 1));    
+    if (subframe==9) { 
+      subframe=0;
+      frame++;
+      frame&=1023;
+    } else {
+      subframe++;
+    }      
 
-      if (proc->first_rx == 0) {
-        if (subframe_rx < proc->subframe_rx+2){
-          LOG_E(PHY,"RX overflow (proc->subframe_rx %d, subframe_rx %d)\n",proc->subframe_rx,subframe_rx);
-        }
-      } else {
-        proc->first_rx = 0;
-      }
-    } // node_timing == synch_to_externs, node_function = NGFI_IF4
-    else { // should not get here
-      AssertFatal(1==0, "Unknown eNB->node_function %d",eNB->node_function);
-    }
+    if (eNB->fh_asynch) eNB->fh_asynch(eNB,&frame,&subframe);
+    else AssertFatal(1==0, "Unknown eNB->node_function %d",eNB->node_function);
+    
   }
+
   eNB_thread_asynch_rxtx_status=0;
   return(&eNB_thread_asynch_rxtx_status);
 }
 
-void rx_rf(PHY_VARS_eNB *eNB,eNB_proc_t *proc,int *frame,int *subframe) {
 
+
+
+
+void rx_rf(PHY_VARS_eNB *eNB,int *frame,int *subframe) {
+
+  eNB_proc_t *proc = &eNB->proc;
   LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
   void *rxp[fp->nb_antennas_rx],*txp[fp->nb_antennas_tx]; 
   unsigned int rxs,txs;
@@ -883,10 +960,10 @@ void rx_rf(PHY_VARS_eNB *eNB,eNB_proc_t *proc,int *frame,int *subframe) {
     // prepare tx buffer pointers
 	
     for (i=0; i<fp->nb_antennas_tx; i++)
-      txp[i] = (void*)&eNB->common_vars.txdata[0][i][((proc->subframe_rx+2)%10)*fp->samples_per_tti];
+      txp[i] = (void*)&eNB->common_vars.txdata[0][i][((proc->subframe_rx+3)%10)*fp->samples_per_tti];
     
     txs = eNB->rfdevice.trx_write_func(&eNB->rfdevice,
-				       proc->timestamp_rx+(2*fp->samples_per_tti)-openair0_cfg[0].tx_sample_advance,
+				       proc->timestamp_rx+(3*fp->samples_per_tti)-openair0_cfg[0].tx_sample_advance,
 				       txp,
 				       fp->samples_per_tti,
 				       fp->nb_antennas_tx,
@@ -946,9 +1023,10 @@ void rx_rf(PHY_VARS_eNB *eNB,eNB_proc_t *proc,int *frame,int *subframe) {
   
 }
 
-void rx_fh_if5(PHY_VARS_eNB *eNB,eNB_proc_t *proc,int *frame, int *subframe) {
+void rx_fh_if5(PHY_VARS_eNB *eNB,int *frame, int *subframe) {
 
   LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
+  eNB_proc_t *proc = &eNB->proc;
 
   recv_IF5(eNB, &proc->timestamp_rx, *subframe, IF5_RRH_GW_UL); 
 
@@ -975,7 +1053,9 @@ void rx_fh_if5(PHY_VARS_eNB *eNB,eNB_proc_t *proc,int *frame, int *subframe) {
 
 }
 
-void rx_fh_if4p5(PHY_VARS_eNB *eNB,eNB_proc_t *proc,int *subframe,int *frame) {
+void rx_fh_if4p5(PHY_VARS_eNB *eNB,int *subframe,int *frame) {
+
+  eNB_proc_t *proc = &eNB->proc;
 
   LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
 
@@ -990,9 +1070,7 @@ void rx_fh_if4p5(PHY_VARS_eNB *eNB,eNB_proc_t *proc,int *subframe,int *frame) {
   prach_rx = 0;
   
   do {   // Blocking, we need a timeout on this !!!!!!!!!!!!!!!!!!!!!!!
-    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF4, 1 );   
     recv_IF4p5(eNB, &proc->frame_rx, &proc->subframe_rx, &packet_type, &symbol_number);
-    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF4, 0 );   
     
     if (packet_type == IF4p5_PULFFT) {
       symbol_mask = symbol_mask | (1<<symbol_number);
@@ -1021,6 +1099,26 @@ void rx_fh_if4p5(PHY_VARS_eNB *eNB,eNB_proc_t *proc,int *subframe,int *frame) {
   
 }
 
+void rx_fh_slave(PHY_VARS_eNB *eNB,int *frame,int *subframe) {
+  // This case is for synchronization to another thread
+  // it just waits for an external event.  The actual rx_rh is handle by the asynchronous RX thread
+  eNB_proc_t *proc=&eNB->proc;
+
+  if (pthread_mutex_lock(&proc->mutex_FH) != 0) {
+    LOG_E( PHY, "[SCHED][eNB] error locking mutex for FH Slave\n");
+    exit_fun( "error locking mutex" );
+  }
+  
+  while (proc->instance_cnt_FH < 0) {
+    pthread_cond_wait( &proc->cond_FH,&proc->mutex_FH ); 
+  }      
+  proc->instance_cnt_FH++;
+  
+  pthread_mutex_unlock( &proc->mutex_FH );
+  
+}
+
+
 int wakeup_rxtx(eNB_proc_t *proc,eNB_rxtx_proc_t *proc_rxtx,LTE_DL_FRAME_PARMS *fp) {
 
   int i;
@@ -1263,7 +1361,7 @@ static void* eNB_thread_FH( void* param ) {
     if (eNB->start_rf(eNB) != 0)
       LOG_E(HW,"Could not start the RF device\n");
 
-  // unlock asnych_rxtx thread
+  // wakeup asnych_rxtx thread
   pthread_mutex_lock(&proc->mutex_asynch_rxtx);
   proc->instance_cnt_asynch_rxtx=0;
   pthread_mutex_unlock(&proc->mutex_asynch_rxtx);
@@ -1274,6 +1372,8 @@ static void* eNB_thread_FH( void* param ) {
    
     if (oai_exit) break;   
 
+
+    // this is to check that we are in synch with the fronthaul timing
     if (subframe==9) { 
       subframe=0;
       frame++;
@@ -1282,36 +1382,10 @@ static void* eNB_thread_FH( void* param ) {
       subframe++;
     }      
 
-    // This case is for synchronization to another thread
-    if ((eNB->node_timing == synch_to_other) &&
-       ((eNB->node_function == NGFI_RCC_IF4p5) ||
-        (eNB->node_function == eNodeB_3GPP_BBU))) {   
-      //wait for event
-
-      // how long should we wait here, for MOBIPASS this could be long
-      //      if (pthread_mutex_timedlock(&proc->mutex_FH,&wait) != 0) {
-      if (pthread_mutex_lock(&proc->mutex_FH) != 0) {
-        LOG_E( PHY, "[SCHED][eNB] error locking mutex for FH\n");
-        exit_fun( "error locking mutex" );
-        break;
-      }
-      
-      while (proc->instance_cnt_FH < 0) {
-        // most of the time the thread is waiting here
-        // proc->instance_cnt_FH is -1
-        pthread_cond_wait( &proc->cond_FH,&proc->mutex_FH ); // this unlocks mutex_rxtx while waiting and then locks it again
-      }      
-      proc->instance_cnt_FH++;
-
-    }
-    // Remaining cases are all for synchronization on FH interface
-    else if ((eNB->node_timing == synch_to_ext_device) && 
-	     (eNB->rx_fh))
-      eNB->rx_fh(eNB,proc,&frame,&subframe);
-
-    else { // should not get here
-      AssertFatal(1==0, "Unknown fronthaul interface : eNB->node_function %d",eNB->node_function);
-    }
+ 
+    // synchronization on FH interface, acquire signals/data and block
+    if (eNB->rx_fh) eNB->rx_fh(eNB,&frame,&subframe);
+    else AssertFatal(1==0, "No fronthaul interface : eNB->node_function %d",eNB->node_function);
 
     T(T_ENB_MASTER_TICK, T_INT(0), T_INT(proc->frame_rx), T_INT(proc->subframe_rx));
 
@@ -1494,7 +1568,7 @@ static void* eNB_thread_prach( void* param ) {
       break;
     }
    
-
+    
     prach_procedures(eNB);
     
     if (pthread_mutex_lock(&proc->mutex_prach) != 0) {
@@ -1567,8 +1641,9 @@ void init_eNB_proc(int inst) {
     proc->instance_cnt_asynch_rxtx = -1;
     proc->CC_id = CC_id;
     
-    proc->first_rx=4;
-    
+    proc->first_rx=1;
+    proc->first_tx=1;
+
     pthread_mutex_init( &proc_rxtx[0].mutex_rxtx, NULL);
     pthread_mutex_init( &proc_rxtx[1].mutex_rxtx, NULL);
     pthread_mutex_init( &proc->mutex_prach, NULL);
@@ -1584,7 +1659,8 @@ void init_eNB_proc(int inst) {
     pthread_create( &proc->pthread_FH, &proc->attr_FH, eNB_thread_FH, &eNB->proc );
     pthread_create( &proc->pthread_prach, &proc->attr_prach, eNB_thread_prach, &eNB->proc );
     if ((eNB->node_timing == synch_to_other) ||
-	(eNB->node_function == NGFI_RRU_IF5))
+	(eNB->node_function == NGFI_RRU_IF5) ||
+	(eNB->node_function == NGFI_RRU_IF4p5))
       pthread_create( &proc->pthread_asynch_rxtx, &proc->attr_asynch_rxtx, eNB_thread_asynch_rxtx, &eNB->proc );
 #else 
     pthread_create( &proc_rxtx[0].pthread_rxtx, NULL, eNB_thread_rxtx, &eNB->proc_rxtx[0] );
@@ -1784,9 +1860,9 @@ int start_rf(PHY_VARS_eNB *eNB) {
   return(eNB->rfdevice.trx_start_func(&eNB->rfdevice));
 }
 
-extern void eNB_fep_rru_if5(PHY_VARS_eNB *eNB,eNB_proc_t *proc);
-extern void eNB_fep_full(PHY_VARS_eNB *eNB,eNB_proc_t *proc);
-extern void do_prach(PHY_VARS_eNB *eNB,eNB_proc_t *proc);
+extern void eNB_fep_rru_if5(PHY_VARS_eNB *eNB);
+extern void eNB_fep_full(PHY_VARS_eNB *eNB);
+extern void do_prach(PHY_VARS_eNB *eNB);
 
 void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst,eth_params_t *eth_params) {
   
@@ -1813,6 +1889,7 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst
 	eNB->rx_fh                = rx_rf;
 	eNB->start_rf             = start_rf;
 	eNB->start_if             = start_if;
+	eNB->fh_asynch            = fh_if5_asynch_DL;
 	ret = openair0_device_load(&eNB->rfdevice, &openair0_cfg[0]);
         if (ret<0) {
           printf("Exiting, cannot initialize rf device\n");
@@ -1831,9 +1908,10 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst
 	eNB->do_prach             = do_prach;
 	eNB->fep                  = eNB_fep_full;
 	eNB->proc_uespec_rx       = NULL;
-	eNB->proc_tx              = proc_tx_rru_if4p5;
+	eNB->proc_tx              = NULL;//proc_tx_rru_if4p5;
 	eNB->tx_fh                = NULL;
 	eNB->rx_fh                = rx_rf;
+	eNB->fh_asynch            = fh_if4p5_asynch_DL;
 	eNB->start_rf             = start_rf;
 	eNB->start_if             = start_if;
 	ret = openair0_device_load(&eNB->rfdevice, &openair0_cfg[0]);
@@ -1862,6 +1940,7 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst
 	eNB->rx_fh                = rx_rf;
 	eNB->start_rf             = start_rf;
 	eNB->start_if             = NULL;
+        eNB->fh_asynch            = NULL;
 	ret = openair0_device_load(&eNB->rfdevice, &openair0_cfg[0]);
         if (ret<0) {
           printf("Exiting, cannot initialize rf device\n");
@@ -1877,11 +1956,14 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst
 	eNB->proc_tx        = proc_tx_full;
 	eNB->tx_fh          = tx_fh_if5;
 	eNB->rx_fh          = rx_fh_if5;
+        eNB->fh_asynch      = (eNB->node_timing == synch_to_other) ? fh_if5_asynch_UL : NULL;
+
 	eNB->start_rf       = NULL;
 	eNB->start_if       = start_if;
 	eNB->rfdevice.host_type   = BBU_HOST;
 
 	eNB->ifdevice.host_type   = BBU_HOST;
+
         ret = openair0_transport_load(&eNB->ifdevice, &openair0_cfg[0], (eth_params+CC_id));
         printf("openair0_transport_init returns %d for CC_id %d\n",ret,CC_id);
         if (ret<0) {
@@ -1890,14 +1972,15 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst
         }
 	break;
       case NGFI_RCC_IF4p5:
-	eNB->do_prach       = do_prach;
-	eNB->fep            = NULL;
-	eNB->proc_uespec_rx = phy_procedures_eNB_uespec_RX;
-	eNB->proc_tx        = proc_tx_high;
-	eNB->tx_fh          = tx_fh_if4p5;
-	eNB->rx_fh          = rx_fh_if4p5;
-	eNB->start_rf       = NULL;
-	eNB->start_if       = start_if;
+	eNB->do_prach             = do_prach;
+	eNB->fep                  = NULL;
+	eNB->proc_uespec_rx       = phy_procedures_eNB_uespec_RX;
+	eNB->proc_tx              = proc_tx_high;
+	eNB->tx_fh                = tx_fh_if4p5;
+	eNB->rx_fh                = rx_fh_if4p5;
+	eNB->start_rf             = NULL;
+	eNB->start_if             = start_if;
+        eNB->fh_asynch            = (eNB->node_timing == synch_to_other) ? fh_if4p5_asynch_UL : NULL;
 	eNB->rfdevice.host_type   = BBU_HOST;
 	eNB->ifdevice.host_type   = BBU_HOST;
         ret = openair0_transport_load(&eNB->ifdevice, &openair0_cfg[0], (eth_params+CC_id));
@@ -1916,6 +1999,7 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst
 	eNB->proc_tx        = proc_tx_high;
 	eNB->tx_fh          = tx_fh_if4p5; 
 	eNB->rx_fh          = rx_fh_if4p5; 
+        eNB->fh_asynch      = (eNB->node_timing == synch_to_other) ? fh_if4p5_asynch_UL : NULL;
 	eNB->start_rf       = NULL;
 	eNB->start_if       = start_if;
 
diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c
index cf5528598f7aa1c4032743a3f46c63123485d66d..fc16d11e7d51f9025434f63bcd81838333cc6b67 100644
--- a/targets/RT/USER/lte-softmodem.c
+++ b/targets/RT/USER/lte-softmodem.c
@@ -1088,6 +1088,8 @@ static void get_options (int argc, char **argv)
       }
 
       for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
+	
+
         node_function[CC_id]  = enb_properties->properties[i]->cc_node_function[CC_id];
         node_timing[CC_id]    = enb_properties->properties[i]->cc_node_timing[CC_id];
         node_synch_ref[CC_id] = enb_properties->properties[i]->cc_node_synch_ref[CC_id];
@@ -1104,6 +1106,13 @@ static void get_options (int argc, char **argv)
         frame_parms[CC_id]->nb_antennas_tx      =  enb_properties->properties[i]->nb_antennas_tx[CC_id];
         frame_parms[CC_id]->nb_antennas_tx_eNB  =  enb_properties->properties[i]->nb_antennas_tx[CC_id];
         frame_parms[CC_id]->nb_antennas_rx      =  enb_properties->properties[i]->nb_antennas_rx[CC_id];
+
+	frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.prach_ConfigIndex = enb_properties->properties[i]->prach_config_index[CC_id];
+	frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.prach_FreqOffset  = enb_properties->properties[i]->prach_freq_offset[CC_id];
+
+	frame_parms[CC_id]->mode1_flag         = (transmission_mode == 1) ? 1 : 0;
+	frame_parms[CC_id]->threequarter_fs    = threequarter_fs;
+
         //} // j
       }
 
@@ -1182,6 +1191,156 @@ int T_port = 2021;    /* default port to listen to to wait for the tracer */
 int T_dont_fork = 0;  /* default is to fork, see 'T_init' to understand */
 #endif
 
+void set_default_frame_parms() {
+
+  int CC_id;
+
+  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
+    frame_parms[CC_id] = (LTE_DL_FRAME_PARMS*) malloc(sizeof(LTE_DL_FRAME_PARMS));
+    /* Set some default values that may be overwritten while reading options */
+    frame_parms[CC_id]->frame_type          = FDD;
+    frame_parms[CC_id]->tdd_config          = 3;
+    frame_parms[CC_id]->tdd_config_S        = 0;
+    frame_parms[CC_id]->N_RB_DL             = 100;
+    frame_parms[CC_id]->N_RB_UL             = 100;
+    frame_parms[CC_id]->Ncp                 = NORMAL;
+    frame_parms[CC_id]->Ncp_UL              = NORMAL;
+    frame_parms[CC_id]->Nid_cell            = 0;
+    frame_parms[CC_id]->num_MBSFN_config    = 0;
+    frame_parms[CC_id]->nb_antennas_tx_eNB  = 1;
+    frame_parms[CC_id]->nb_antennas_tx      = 1;
+    frame_parms[CC_id]->nb_antennas_rx      = 1;
+
+    frame_parms[CC_id]->nushift             = 0;
+
+    frame_parms[CC_id]->phich_config_common.phich_resource = oneSixth;
+    frame_parms[CC_id]->phich_config_common.phich_duration = normal;
+    // UL RS Config
+    frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift = 0;//n_DMRS1 set to 0
+    frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled = 0;
+    frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled = 0;
+    frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH = 0;
+
+    frame_parms[CC_id]->prach_config_common.rootSequenceIndex=22;
+    frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig=1;
+    frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.prach_ConfigIndex=0;
+    frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.highSpeedFlag=0;
+    frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.prach_FreqOffset=0;
+
+    downlink_frequency[CC_id][0] = 2680000000; // Use float to avoid issue with frequency over 2^31.
+    downlink_frequency[CC_id][1] = downlink_frequency[CC_id][0];
+    downlink_frequency[CC_id][2] = downlink_frequency[CC_id][0];
+    downlink_frequency[CC_id][3] = downlink_frequency[CC_id][0];
+    //printf("Downlink for CC_id %d frequency set to %u\n", CC_id, downlink_frequency[CC_id][0]);
+
+  }
+
+}
+
+void init_openair0() {
+
+  int card;
+  int i;
+
+  for (card=0; card<MAX_CARDS; card++) {
+
+    openair0_cfg[card].mmapped_dma=mmapped_dma;
+    openair0_cfg[card].configFilename = NULL;
+
+    if(frame_parms[0]->N_RB_DL == 100) {
+      if (frame_parms[0]->threequarter_fs) {
+	openair0_cfg[card].sample_rate=23.04e6;
+	openair0_cfg[card].samples_per_frame = 230400; 
+	openair0_cfg[card].tx_bw = 10e6;
+	openair0_cfg[card].rx_bw = 10e6;
+      }
+      else {
+	openair0_cfg[card].sample_rate=30.72e6;
+	openair0_cfg[card].samples_per_frame = 307200; 
+	openair0_cfg[card].tx_bw = 10e6;
+	openair0_cfg[card].rx_bw = 10e6;
+      }
+    } else if(frame_parms[0]->N_RB_DL == 50) {
+      openair0_cfg[card].sample_rate=15.36e6;
+      openair0_cfg[card].samples_per_frame = 153600;
+      openair0_cfg[card].tx_bw = 5e6;
+      openair0_cfg[card].rx_bw = 5e6;
+    } else if (frame_parms[0]->N_RB_DL == 25) {
+      openair0_cfg[card].sample_rate=7.68e6;
+      openair0_cfg[card].samples_per_frame = 76800;
+      openair0_cfg[card].tx_bw = 2.5e6;
+      openair0_cfg[card].rx_bw = 2.5e6;
+    } else if (frame_parms[0]->N_RB_DL == 6) {
+      openair0_cfg[card].sample_rate=1.92e6;
+      openair0_cfg[card].samples_per_frame = 19200;
+      openair0_cfg[card].tx_bw = 1.5e6;
+      openair0_cfg[card].rx_bw = 1.5e6;
+    }
+
+    if (frame_parms[0]->frame_type==TDD)
+      openair0_cfg[card].duplex_mode = duplex_mode_TDD;
+    else //FDD
+      openair0_cfg[card].duplex_mode = duplex_mode_FDD;
+
+    
+    if (local_remote_radio == BBU_REMOTE_RADIO_HEAD) {      
+      openair0_cfg[card].remote_addr    = eth_params->remote_addr;
+      openair0_cfg[card].remote_port    = eth_params->remote_port;
+      openair0_cfg[card].my_addr        = eth_params->my_addr;
+      openair0_cfg[card].my_port        = eth_params->my_port;    
+    } 
+    
+    printf("HW: Configuring card %d, nb_antennas_tx/rx %d/%d\n",card,
+           ((UE_flag==0) ? PHY_vars_eNB_g[0][0]->frame_parms.nb_antennas_tx : PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_tx),
+           ((UE_flag==0) ? PHY_vars_eNB_g[0][0]->frame_parms.nb_antennas_rx : PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_rx));
+    openair0_cfg[card].Mod_id = 0;
+
+    if (UE_flag) {
+      printf("ETHERNET: Configuring UE ETH for %s:%d\n",rrh_UE_ip,rrh_UE_port);
+      openair0_cfg[card].remote_addr   = &rrh_UE_ip[0];
+      openair0_cfg[card].remote_port = rrh_UE_port;
+    } 
+
+    openair0_cfg[card].num_rb_dl=frame_parms[0]->N_RB_DL;
+
+
+    openair0_cfg[card].tx_num_channels=min(2,((UE_flag==0) ? PHY_vars_eNB_g[0][0]->frame_parms.nb_antennas_tx : PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_tx));
+    openair0_cfg[card].rx_num_channels=min(2,((UE_flag==0) ? PHY_vars_eNB_g[0][0]->frame_parms.nb_antennas_rx : PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_rx));
+
+    for (i=0; i<4; i++) {
+
+      if (i<openair0_cfg[card].tx_num_channels)
+	openair0_cfg[card].tx_freq[i] = (UE_flag==0) ? downlink_frequency[0][i] : downlink_frequency[0][i]+uplink_frequency_offset[0][i];
+      else
+	openair0_cfg[card].tx_freq[i]=0.0;
+
+      if (i<openair0_cfg[card].rx_num_channels)
+	openair0_cfg[card].rx_freq[i] = (UE_flag==0) ? downlink_frequency[0][i] + uplink_frequency_offset[0][i] : downlink_frequency[0][i];
+      else
+	openair0_cfg[card].rx_freq[i]=0.0;
+
+      printf("Card %d, channel %d, Setting tx_gain %f, rx_gain %f, tx_freq %f, rx_freq %f\n",
+             card,i, openair0_cfg[card].tx_gain[i],
+             openair0_cfg[card].rx_gain[i],
+             openair0_cfg[card].tx_freq[i],
+             openair0_cfg[card].rx_freq[i]);
+      
+      openair0_cfg[card].autocal[i] = 1;
+      openair0_cfg[card].tx_gain[i] = tx_gain[0][i];
+      if (UE_flag == 0) {
+	openair0_cfg[card].rx_gain[i] = PHY_vars_eNB_g[0][0]->rx_total_gain_dB;
+      }
+      else {
+	openair0_cfg[card].rx_gain[i] = PHY_vars_UE_g[0][0]->rx_total_gain_dB;
+      }
+
+
+    }
+
+
+  }
+}
+
 int main( int argc, char **argv )
 {
   int i,aa,card=0;
@@ -1190,8 +1349,7 @@ int main( int argc, char **argv )
 #endif
 
   int CC_id;
-  uint16_t Nid_cell = 0;
-  uint8_t  cooperation_flag=0,  abstraction_flag=0;
+  uint8_t  abstraction_flag=0;
   uint8_t beta_ACK=0,beta_RI=0,beta_CQI=2;
 
 #if defined (XFORMS)
@@ -1211,39 +1369,18 @@ int main( int argc, char **argv )
   memset(tx_max_power,0,sizeof(int)*MAX_NUM_CCs);
   set_latency_target();
 
-  // det defaults
-  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
-    frame_parms[CC_id] = (LTE_DL_FRAME_PARMS*) malloc(sizeof(LTE_DL_FRAME_PARMS));
-    /* Set some default values that may be overwritten while reading options */
-    frame_parms[CC_id]->frame_type          = FDD;
-    frame_parms[CC_id]->tdd_config          = 3;
-    frame_parms[CC_id]->tdd_config_S        = 0;
-    frame_parms[CC_id]->N_RB_DL             = 100;
-    frame_parms[CC_id]->N_RB_UL             = 100;
-    frame_parms[CC_id]->Ncp                 = NORMAL;
-    frame_parms[CC_id]->Ncp_UL              = NORMAL;
-    frame_parms[CC_id]->Nid_cell            = Nid_cell;
-    frame_parms[CC_id]->num_MBSFN_config    = 0;
-    frame_parms[CC_id]->nb_antennas_tx_eNB  = 1;
-    frame_parms[CC_id]->nb_antennas_tx      = 1;
-    frame_parms[CC_id]->nb_antennas_rx      = 1;
-  }
+  // set default parameters
+  set_default_frame_parms(frame_parms);
 
-  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
-    downlink_frequency[CC_id][0] = 2680000000; // Use float to avoid issue with frequency over 2^31.
-    downlink_frequency[CC_id][1] = downlink_frequency[CC_id][0];
-    downlink_frequency[CC_id][2] = downlink_frequency[CC_id][0];
-    downlink_frequency[CC_id][3] = downlink_frequency[CC_id][0];
-    //printf("Downlink for CC_id %d frequency set to %u\n", CC_id, downlink_frequency[CC_id][0]);
-  }
+  // initialize logging
   logInit();
+
+  // get options and fill parameters from configuration file
+  get_options (argc, argv); //Command-line options, enb_properties
+
+
  
-  rf_config_file[0]='\0';
-  get_options (argc, argv); //Command-line options
-  if (rf_config_file[0] == '\0')
-    openair0_cfg[0].configFilename = NULL;
-  else
-    openair0_cfg[0].configFilename = rf_config_file;
+
   
 #if T_TRACER
   T_init(T_port, T_wait, T_dont_fork);
@@ -1363,26 +1500,12 @@ int main( int argc, char **argv )
 
   // init the parameters
   for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
-    frame_parms[CC_id]->nushift            = 0;
-
-    if (UE_flag==0) {
 
-    } else {
-      //UE_flag==1
+    if (UE_flag==1) {
       frame_parms[CC_id]->nb_antennas_tx     = 1;
       frame_parms[CC_id]->nb_antennas_rx     = 1;
       frame_parms[CC_id]->nb_antennas_tx_eNB = (transmission_mode == 1) ? 1 : 2; //initial value overwritten by initial sync later
     }
-
-    frame_parms[CC_id]->mode1_flag         = (transmission_mode == 1) ? 1 : 0;
-    frame_parms[CC_id]->phich_config_common.phich_resource = oneSixth;
-    frame_parms[CC_id]->phich_config_common.phich_duration = normal;
-    // UL RS Config
-    frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift = 0;//n_DMRS1 set to 0
-    frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled = 0;
-    frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled = 0;
-    frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH = 0;
-    frame_parms[CC_id]->threequarter_fs = threequarter_fs;
     init_ul_hopping(frame_parms[CC_id]);
     init_frame_parms(frame_parms[CC_id],1);
     //   phy_init_top(frame_parms[CC_id]);
@@ -1392,11 +1515,7 @@ int main( int argc, char **argv )
 
   for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
     //init prach for openair1 test
-    frame_parms[CC_id]->prach_config_common.rootSequenceIndex=22;
-    frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig=1;
-    frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.prach_ConfigIndex=0;
-    frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.highSpeedFlag=0;
-    frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.prach_FreqOffset=0;
+
     // prach_fmt = get_prach_fmt(frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex, frame_parms->frame_type);
     // N_ZC = (prach_fmt <4)?839:139;
   }
@@ -1457,7 +1576,7 @@ int main( int argc, char **argv )
     PHY_vars_eNB_g[0] = malloc(sizeof(PHY_VARS_eNB*));
 
     for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
-      PHY_vars_eNB_g[0][CC_id] = init_lte_eNB(frame_parms[CC_id],0,frame_parms[CC_id]->Nid_cell,cooperation_flag,transmission_mode,abstraction_flag);
+      PHY_vars_eNB_g[0][CC_id] = init_lte_eNB(frame_parms[CC_id],0,frame_parms[CC_id]->Nid_cell,0,transmission_mode,abstraction_flag);
       PHY_vars_eNB_g[0][CC_id]->CC_id = CC_id;
 
       if (phy_test==1) PHY_vars_eNB_g[0][CC_id]->mac_enabled = 0;
@@ -1497,107 +1616,9 @@ int main( int argc, char **argv )
 
   dump_frame_parms(frame_parms[0]);
 
-  for (card=0; card<MAX_CARDS; card++) {
-
-    openair0_cfg[card].mmapped_dma=mmapped_dma;
-
-    if(frame_parms[0]->N_RB_DL == 100) {
-      if (frame_parms[0]->threequarter_fs) {
-	openair0_cfg[card].sample_rate=23.04e6;
-	openair0_cfg[card].samples_per_frame = 230400; 
-	openair0_cfg[card].tx_bw = 10e6;
-	openair0_cfg[card].rx_bw = 10e6;
-      }
-      else {
-	openair0_cfg[card].sample_rate=30.72e6;
-	openair0_cfg[card].samples_per_frame = 307200; 
-	openair0_cfg[card].tx_bw = 10e6;
-	openair0_cfg[card].rx_bw = 10e6;
-      }
-    } else if(frame_parms[0]->N_RB_DL == 50) {
-      openair0_cfg[card].sample_rate=15.36e6;
-      openair0_cfg[card].samples_per_frame = 153600;
-      openair0_cfg[card].tx_bw = 5e6;
-      openair0_cfg[card].rx_bw = 5e6;
-    } else if (frame_parms[0]->N_RB_DL == 25) {
-      openair0_cfg[card].sample_rate=7.68e6;
-      openair0_cfg[card].samples_per_frame = 76800;
-      openair0_cfg[card].tx_bw = 2.5e6;
-      openair0_cfg[card].rx_bw = 2.5e6;
-    } else if (frame_parms[0]->N_RB_DL == 6) {
-      openair0_cfg[card].sample_rate=1.92e6;
-      openair0_cfg[card].samples_per_frame = 19200;
-      openair0_cfg[card].tx_bw = 1.5e6;
-      openair0_cfg[card].rx_bw = 1.5e6;
-    }
-
-    if (frame_parms[0]->frame_type==TDD)
-      openair0_cfg[card].duplex_mode = duplex_mode_TDD;
-    else //FDD
-      openair0_cfg[card].duplex_mode = duplex_mode_FDD;
-
-    
-    if (local_remote_radio == BBU_REMOTE_RADIO_HEAD) {      
-      openair0_cfg[card].remote_addr    = eth_params->remote_addr;
-      openair0_cfg[card].remote_port    = eth_params->remote_port;
-      openair0_cfg[card].my_addr        = eth_params->my_addr;
-      openair0_cfg[card].my_port        = eth_params->my_port;    
-    } 
-    
-    printf("HW: Configuring card %d, nb_antennas_tx/rx %d/%d\n",card,
-           ((UE_flag==0) ? PHY_vars_eNB_g[0][0]->frame_parms.nb_antennas_tx : PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_tx),
-           ((UE_flag==0) ? PHY_vars_eNB_g[0][0]->frame_parms.nb_antennas_rx : PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_rx));
-    openair0_cfg[card].Mod_id = 0;
-#ifdef ETHERNET
-
-    if (UE_flag) {
-      printf("ETHERNET: Configuring UE ETH for %s:%d\n",rrh_UE_ip,rrh_UE_port);
-      openair0_cfg[card].remote_addr   = &rrh_UE_ip[0];
-      openair0_cfg[card].remote_port = rrh_UE_port;
-    } 
-
-    openair0_cfg[card].num_rb_dl=frame_parms[0]->N_RB_DL;
-#endif
-
-    // in the case of the USRP, the following variables need to be initialized before the init
-    // since the USRP only supports one CC (for the moment), we initialize all the cards with first CC.
-    // in the case of EXMIMO2, these values are overwirtten in the function setup_eNB/UE_buffer
-
-    openair0_cfg[card].tx_num_channels=min(2,((UE_flag==0) ? PHY_vars_eNB_g[0][0]->frame_parms.nb_antennas_tx : PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_tx));
-    openair0_cfg[card].rx_num_channels=min(2,((UE_flag==0) ? PHY_vars_eNB_g[0][0]->frame_parms.nb_antennas_rx : PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_rx));
-
-    for (i=0; i<4; i++) {
-
-      if (i<openair0_cfg[card].tx_num_channels)
-	openair0_cfg[card].tx_freq[i] = (UE_flag==0) ? downlink_frequency[0][i] : downlink_frequency[0][i]+uplink_frequency_offset[0][i];
-      else
-	openair0_cfg[card].tx_freq[i]=0.0;
+  init_openair0();
 
-      if (i<openair0_cfg[card].rx_num_channels)
-	openair0_cfg[card].rx_freq[i] = (UE_flag==0) ? downlink_frequency[0][i] + uplink_frequency_offset[0][i] : downlink_frequency[0][i];
-      else
-	openair0_cfg[card].rx_freq[i]=0.0;
 
-      printf("Card %d, channel %d, Setting tx_gain %f, rx_gain %f, tx_freq %f, rx_freq %f\n",
-             card,i, openair0_cfg[card].tx_gain[i],
-             openair0_cfg[card].rx_gain[i],
-             openair0_cfg[card].tx_freq[i],
-             openair0_cfg[card].rx_freq[i]);
-      
-      openair0_cfg[card].autocal[i] = 1;
-      openair0_cfg[card].tx_gain[i] = tx_gain[0][i];
-      if (UE_flag == 0) {
-	openair0_cfg[card].rx_gain[i] = PHY_vars_eNB_g[0][0]->rx_total_gain_dB;
-      }
-      else {
-	openair0_cfg[card].rx_gain[i] = PHY_vars_UE_g[0][0]->rx_total_gain_dB;
-      }
-
-
-    }
-
-
-  }
 
 #ifndef DEADLINE_SCHEDULER
 
@@ -1644,15 +1665,21 @@ int main( int argc, char **argv )
   openair0_cfg[0].log_level = glog_level;
 
   
-  mac_xface = malloc(sizeof(MAC_xface));
+
 
   int eMBMS_active=0;
-  
-  l2_init(frame_parms[0],eMBMS_active,(uecap_xer_in==1)?uecap_xer:NULL,
-	  0,// cba_group_active
-	  0); // HO flag
-  
-  mac_xface->macphy_exit = &exit_fun;
+  if (node_function[0] >=NGFI_RAU_IF4p5) { // don't initialize L2 for RRU
+    mac_xface = malloc(sizeof(MAC_xface));  
+    l2_init(frame_parms[0],eMBMS_active,(uecap_xer_in==1)?uecap_xer:NULL,
+	    0,// cba_group_active
+	    0); // HO flag
+    mac_xface->macphy_exit = &exit_fun;
+  }
+  else if (node_function[0] == NGFI_RRU_IF4p5) { // Initialize PRACH in this case
+
+  }
+
+
 
 #if defined(ENABLE_ITTI)
 
@@ -1672,7 +1699,7 @@ int main( int argc, char **argv )
       printf("Filling UE band info\n");
       fill_ue_band_info();
       mac_xface->dl_phy_sync_success (0, 0, 0, 1);
-    } else
+    } else if (node_function[0]>NGFI_RRU_IF4p5)
       mac_xface->mrbch_phy_sync_failure (0, 0, 0);
   }
 
diff --git a/targets/SIMU/USER/init_lte.c b/targets/SIMU/USER/init_lte.c
index 583891f1ac369f1eff4fb695c718e553c3a639e1..756d7058701d79cb3547280deee9d96606858166 100644
--- a/targets/SIMU/USER/init_lte.c
+++ b/targets/SIMU/USER/init_lte.c
@@ -70,6 +70,7 @@ PHY_VARS_eNB* init_lte_eNB(LTE_DL_FRAME_PARMS *frame_parms,
         NUMBER_OF_UE_MAX, NUMBER_OF_eNB_MAX, NUMBER_OF_HARQ_PID_MAX);
   LOG_I(PHY,"init eNB: N_RB_DL %d\n", frame_parms->N_RB_DL);
   LOG_I(PHY,"init eNB: Transmission mode %d\n", transmission_mode);
+  LOG_I(PHY,"init eNB: prach_config_index %d\n", frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex);
 
   for (i=0; i<NUMBER_OF_UE_MAX; i++) {
     for (j=0; j<2; j++) {