diff --git a/common/utils/system.c b/common/utils/system.c
index dcec681e2dcf2596b78352560672439e7bba58ee..31c1035129998da9a8340b1b80895e0dd4d44120 100644
--- a/common/utils/system.c
+++ b/common/utils/system.c
@@ -28,13 +28,23 @@
  * separate process solves this problem.
  */
 
+#define _GNU_SOURCE
 #include "system.h"
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <pthread.h>
 #include <string.h>
-
+#include <stdint.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include <errno.h>
+#include <pthread.h>
+#include <common/utils/assertions.h>
+#include <common/utils/LOG/log.h>
 #define MAX_COMMAND 4096
 
 static int command_pipe_read;
@@ -50,37 +60,37 @@ static int module_initialized = 0;
 /* util functions                                                   */
 /********************************************************************/
 
-static void lock_system(void)
-{
+static void lock_system(void) {
   if (pthread_mutex_lock(&lock) != 0) {
     printf("pthread_mutex_lock fails\n");
     abort();
   }
 }
 
-static void unlock_system(void)
-{
+static void unlock_system(void) {
   if (pthread_mutex_unlock(&lock) != 0) {
     printf("pthread_mutex_unlock fails\n");
     abort();
   }
 }
 
-static void write_pipe(int p, char *b, int size)
-{
+static void write_pipe(int p, char *b, int size) {
   while (size) {
     int ret = write(p, b, size);
+
     if (ret <= 0) exit(0);
+
     b += ret;
     size -= ret;
   }
 }
 
-static void read_pipe(int p, char *b, int size)
-{
+static void read_pipe(int p, char *b, int size) {
   while (size) {
     int ret = read(p, b, size);
+
     if (ret <= 0) exit(0);
+
     b += ret;
     size -= ret;
   }
@@ -95,14 +105,13 @@ static void read_pipe(int p, char *b, int size)
  * when the main process exits, because then a "read" on the pipe
  * will return 0, in which case "read_pipe" exits.
  */
-static void background_system_process(void)
-{
+static void background_system_process(void) {
   int len;
   int ret;
   char command[MAX_COMMAND+1];
 
   while (1) {
-    read_pipe(command_pipe_read, (char*)&len, sizeof(int));
+    read_pipe(command_pipe_read, (char *)&len, sizeof(int));
     read_pipe(command_pipe_read, command, len);
     ret = system(command);
     write_pipe(result_pipe_write, (char *)&ret, sizeof(int));
@@ -114,8 +123,7 @@ static void background_system_process(void)
 /*     return -1 on error, 0 on success                             */
 /********************************************************************/
 
-int background_system(char *command)
-{
+int background_system(char *command) {
   int res;
   int len;
 
@@ -125,18 +133,22 @@ int background_system(char *command)
   }
 
   len = strlen(command)+1;
+
   if (len > MAX_COMMAND) {
     printf("FATAL: command too long. Increase MAX_COMMAND (%d).\n", MAX_COMMAND);
     printf("command was: '%s'\n", command);
     abort();
   }
+
   /* only one command can run at a time, so let's lock/unlock */
   lock_system();
-  write_pipe(command_pipe_write, (char*)&len, sizeof(int));
+  write_pipe(command_pipe_write, (char *)&len, sizeof(int));
   write_pipe(command_pipe_write, command, len);
-  read_pipe(result_pipe_read, (char*)&res, sizeof(int));
+  read_pipe(result_pipe_read, (char *)&res, sizeof(int));
   unlock_system();
+
   if (res == -1 || !WIFEXITED(res) || WEXITSTATUS(res) != 0) return -1;
+
   return 0;
 }
 
@@ -146,17 +158,16 @@ int background_system(char *command)
 /*     to be called very early by the main processing               */
 /********************************************************************/
 
-void start_background_system(void)
-{
+void start_background_system(void) {
   int p[2];
   pid_t son;
-
   module_initialized = 1;
 
   if (pipe(p) == -1) {
     perror("pipe");
     exit(1);
   }
+
   command_pipe_read  = p[0];
   command_pipe_write = p[1];
 
@@ -164,10 +175,11 @@ void start_background_system(void)
     perror("pipe");
     exit(1);
   }
+
   result_pipe_read  = p[0];
   result_pipe_write = p[1];
-
   son = fork();
+
   if (son == -1) {
     perror("fork");
     exit(1);
@@ -181,6 +193,56 @@ void start_background_system(void)
 
   close(result_pipe_read);
   close(command_pipe_write);
-
   background_system_process();
 }
+
+
+void threadCreate(pthread_t* t, void * (*func)(void*), void * param, char* name, int affinity, int priority){
+  pthread_attr_t attr;
+  pthread_attr_init(&attr);
+  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+  pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
+  pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
+  struct sched_param sparam={0};
+  sparam.sched_priority = priority;
+  pthread_attr_setschedparam(&attr, &sparam);
+
+  pthread_create(t, &attr, func, param);
+
+  pthread_setname_np(*t, name);
+  if (affinity != -1 ) {
+    cpu_set_t cpuset;
+    CPU_ZERO(&cpuset);
+    CPU_SET(affinity, &cpuset);
+    AssertFatal( pthread_setaffinity_np(*t, sizeof(cpu_set_t), &cpuset) == 0, "Error setting processor affinity");
+  }
+
+  pthread_attr_destroy(&attr);
+}
+
+// Block CPU C-states deep sleep
+void configure_linux(void) {
+  int ret;
+  static int latency_target_fd=-1;
+  uint32_t latency_target_value=10; // in microseconds
+  if (latency_target_fd == -1) {
+    if ( (latency_target_fd = open("/dev/cpu_dma_latency", O_RDWR)) != -1 ) {
+      ret = write(latency_target_fd, &latency_target_value, sizeof(latency_target_value));
+      if (ret == 0) {
+	printf("# error setting cpu_dma_latency to %d!: %s\n", latency_target_value, strerror(errno));
+	close(latency_target_fd);
+	latency_target_fd=-1;
+	return;
+      }
+    }
+  }
+  if (latency_target_fd != -1) 
+    LOG_I(HW,"# /dev/cpu_dma_latency set to %dus\n", latency_target_value);
+  else
+    LOG_E(HW,"Can't set /dev/cpu_dma_latency to %dus\n", latency_target_value);
+
+  // Set CPU frequency to it's maximum
+  if ( 0 != system("for d in /sys/devices/system/cpu/cpu[0-9]*; do cat $d/cpufreq/cpuinfo_max_freq > $d/cpufreq/scaling_min_freq; done"))
+	  LOG_W(HW,"Can't set cpu frequency\n");
+  
+}
diff --git a/common/utils/system.h b/common/utils/system.h
index 658c17adc1a476ce68c03d1510623c87c382ab29..a89a6c5b1729f0b968fbfd4baed9cfd3cce85b10 100644
--- a/common/utils/system.h
+++ b/common/utils/system.h
@@ -21,6 +21,12 @@
 
 #ifndef _SYSTEM_H_OAI_
 #define _SYSTEM_H_OAI_
+#include <stdint.h>
+#include <pthread.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 
 /****************************************************
  * send a command to the background process
@@ -36,4 +42,23 @@ int background_system(char *command);
 
 void start_background_system(void);
 
+void set_latency_target(void);
+void configure_linux(void);
+
+void threadCreate(pthread_t* t, void * (*func)(void*), void * param, char* name, int affinity, int priority);
+#define OAI_PRIORITY_RT_LOW sched_get_priority_min(SCHED_FIFO)
+#define OAI_PRIORITY_RT sched_get_priority_max(SCHED_FIFO)-10
+#define OAI_PRIORITY_RT_MAX sched_get_priority_max(SCHED_FIFO)
+
+void thread_top_init(char *thread_name,
+                     int affinity,
+                     uint64_t runtime,
+                     uint64_t deadline,
+                     uint64_t period);
+
+#ifdef __cplusplus
+}
+#endif
+
+
 #endif /* _SYSTEM_H_OAI_ */
diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c
index 28dd38b65a1c2a9d803d1fae7813f109c409aa5a..801bc8d4dc6f891e83c2c7adf759f0e269c2a421 100644
--- a/openair1/SCHED/phy_procedures_lte_eNb.c
+++ b/openair1/SCHED/phy_procedures_lte_eNb.c
@@ -230,13 +230,11 @@ void common_signal_procedures (PHY_VARS_eNB *eNB,int frame, int subframe) {
 
 
 
-void pdsch_procedures(PHY_VARS_eNB *eNB,
+bool dlsch_procedures(PHY_VARS_eNB *eNB,
                       L1_rxtx_proc_t *proc,
                       int harq_pid,
                       LTE_eNB_DLSCH_t *dlsch,
-                      LTE_eNB_DLSCH_t *dlsch1,
-                      LTE_eNB_UE_stats *ue_stats,
-                      int ra_flag) {
+                      LTE_eNB_UE_stats *ue_stats) {
   int frame=proc->frame_tx;
   int subframe=proc->subframe_tx;
   LTE_DL_eNB_HARQ_t *dlsch_harq=dlsch->harq_processes[harq_pid];
@@ -265,27 +263,6 @@ void pdsch_procedures(PHY_VARS_eNB *eNB,
           dlsch_harq->round);
   }
 
-  MSC_LOG_TX_MESSAGE(
-    MSC_PHY_ENB,MSC_PHY_UE,
-    NULL,0,
-    "%05u:%02u PDSCH/DLSCH input size = %"PRIu16", G %d, nb_rb %"PRIu16", TBS %"PRIu16", pmi_alloc %"PRIx16", rv %"PRIu8" (round %"PRIu8")",
-    frame, subframe,
-    dlsch_harq->TBS/8,
-    get_G(fp,
-          dlsch_harq->nb_rb,
-          dlsch_harq->rb_alloc,
-          dlsch_harq->Qm,
-          dlsch_harq->Nl,
-          dlsch_harq->pdsch_start,
-          frame,
-          subframe,
-          dlsch_harq->mimo_mode==TM7?7:0),
-    dlsch_harq->nb_rb,
-    dlsch_harq->TBS,
-    pmi2hex_2Ar1(dlsch_harq->pmi_alloc),
-    dlsch_harq->rvidx,
-    dlsch_harq->round);
-
   if (ue_stats) ue_stats->dlsch_sliding_cnt++;
 
   if (dlsch_harq->round == 0) {
@@ -300,15 +277,17 @@ void pdsch_procedures(PHY_VARS_eNB *eNB,
 #endif
   }
 
-  if (dlsch->rnti!=0xffff) LOG_D(PHY,"Generating DLSCH/PDSCH pdu:%p pdsch_start:%d frame:%d subframe:%d nb_rb:%d rb_alloc:%d Qm:%d Nl:%d round:%d\n",
-                                   dlsch_harq->pdu,dlsch_harq->pdsch_start,frame,subframe,dlsch_harq->nb_rb,dlsch_harq->rb_alloc[0],dlsch_harq->Qm,dlsch_harq->Nl,dlsch_harq->round);
+  if (dlsch->rnti!=0xffff)
+    LOG_D(PHY,"Generating DLSCH/PDSCH pdu:%p pdsch_start:%d frame:%d subframe:%d nb_rb:%d rb_alloc:%d Qm:%d Nl:%d round:%d\n",
+	  dlsch_harq->pdu,dlsch_harq->pdsch_start,frame,subframe,dlsch_harq->nb_rb,dlsch_harq->rb_alloc[0],
+	  dlsch_harq->Qm,dlsch_harq->Nl,dlsch_harq->round);
 
   // 36-212
   if (NFAPI_MODE==NFAPI_MONOLITHIC || NFAPI_MODE==NFAPI_MODE_PNF) { // monolthic OR PNF - do not need turbo encoding on VNF
     if (dlsch_harq->pdu==NULL) {
       LOG_E(PHY,"dlsch_harq->pdu == NULL SFN/SF:%04d%d dlsch[rnti:%x] dlsch_harq[pdu:%p pdsch_start:%d Qm:%d Nl:%d round:%d nb_rb:%d rb_alloc[0]:%d]\n", frame,subframe,dlsch->rnti, dlsch_harq->pdu,
             dlsch_harq->pdsch_start,dlsch_harq->Qm,dlsch_harq->Nl,dlsch_harq->round,dlsch_harq->nb_rb,dlsch_harq->rb_alloc[0]);
-      return;
+      return false;
     }
 
     start_meas(&eNB->dlsch_encoding_stats);
@@ -330,44 +309,57 @@ void pdsch_procedures(PHY_VARS_eNB *eNB,
     if(eNB->dlsch_encoding_stats.p_time>500*3000 && opp_enabled == 1) {
       print_meas_now(&eNB->dlsch_encoding_stats,"total coding",stderr);
     }
-
-    // 36-211
-    start_meas(&eNB->dlsch_scrambling_stats);
-    dlsch_scrambling(fp,
-                     0,
-                     dlsch,
-                     harq_pid,
-                     get_G(fp,
-                           dlsch_harq->nb_rb,
-                           dlsch_harq->rb_alloc,
-                           dlsch_harq->Qm,
-                           dlsch_harq->Nl,
-                           dlsch_harq->pdsch_start,
-                           frame,subframe,
-                           0),
-                     0,
-                     frame,
-                     subframe<<1);
-    stop_meas(&eNB->dlsch_scrambling_stats);
-    start_meas(&eNB->dlsch_modulation_stats);
-    dlsch_modulation(eNB,
-                     eNB->common_vars.txdataF,
-                     AMP,
-                     frame,
-                     subframe,
-                     dlsch_harq->pdsch_start,
-                     dlsch,
-                     dlsch->ue_type==0 ? dlsch1 : (LTE_eNB_DLSCH_t *)NULL);
-    stop_meas(&eNB->dlsch_modulation_stats);
-  }
-
 #ifdef PHY_TX_THREAD
-  dlsch->active[subframe] = 0;
+    dlsch->active[subframe] = 0;
 #else
-  dlsch->active = 0;
+    dlsch->active = 0;
 #endif
-  dlsch_harq->round++;
-  LOG_D(PHY,"Generating DLSCH/PDSCH dlsch_harq[round:%d]\n",dlsch_harq->round);
+    dlsch_harq->round++;
+    LOG_D(PHY,"Generated DLSCH dlsch_harq[round:%d]\n",dlsch_harq->round);
+    return true;
+  }
+  return false;
+}
+
+void pdsch_procedures(PHY_VARS_eNB *eNB,
+                      L1_rxtx_proc_t *proc,
+                      int harq_pid,
+                      LTE_eNB_DLSCH_t *dlsch,
+                      LTE_eNB_DLSCH_t *dlsch1) {
+  int frame=proc->frame_tx;
+  int subframe=proc->subframe_tx;
+  LTE_DL_eNB_HARQ_t *dlsch_harq=dlsch->harq_processes[harq_pid];
+  LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
+  // 36-211
+  start_meas(&eNB->dlsch_scrambling_stats);
+  dlsch_scrambling(fp,
+		   0,
+		   dlsch,
+		   harq_pid,
+		   get_G(fp,
+			 dlsch_harq->nb_rb,
+			 dlsch_harq->rb_alloc,
+			 dlsch_harq->Qm,
+			 dlsch_harq->Nl,
+			 dlsch_harq->pdsch_start,
+			 frame,subframe,
+			 0),
+		   0,
+		   frame,
+		   subframe<<1);
+  stop_meas(&eNB->dlsch_scrambling_stats);
+  start_meas(&eNB->dlsch_modulation_stats);
+  dlsch_modulation(eNB,
+		   eNB->common_vars.txdataF,
+		   AMP,
+		   frame,
+		   subframe,
+		   dlsch_harq->pdsch_start,
+		   dlsch,
+		   dlsch->ue_type==0 ? dlsch1 : (LTE_eNB_DLSCH_t *)NULL);
+  stop_meas(&eNB->dlsch_modulation_stats);
+
+  LOG_D(PHY,"Generated PDSCH dlsch_harq[round:%d]\n",dlsch_harq->round);
 }
 
 
@@ -531,14 +523,18 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
                 dlsch0->harq_ids[frame%2][6],
                 dlsch0->harq_ids[frame%2][7]);
       } else {
-        // generate pdsch
-        pdsch_procedures(eNB,
+	if (dlsch_procedures(eNB,
                          proc,
                          harq_pid,
                          dlsch0,
-                         dlsch1,
-                         &eNB->UE_stats[(uint32_t)UE_id],
-                         0);
+                         &eNB->UE_stats[(uint32_t)UE_id])) {
+	  // if we generate dlsch, we must generate pdsch
+	  pdsch_procedures(eNB,
+			   proc,
+			   harq_pid,
+			   dlsch0,
+			   dlsch1);
+	}
       }
     } else if ((dlsch0)&&(dlsch0->rnti>0)&&
 #ifdef PHY_TX_THREAD
diff --git a/openair1/SIMULATION/TOOLS/random_channel.c b/openair1/SIMULATION/TOOLS/random_channel.c
index 8341c574da2968b8a361cdc82c3801bf8a91b998..f056d51b5d3c49a55a71e058ec2b061f2f911022 100644
--- a/openair1/SIMULATION/TOOLS/random_channel.c
+++ b/openair1/SIMULATION/TOOLS/random_channel.c
@@ -1204,6 +1204,10 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
   return(chan_desc);
 }
 
+void free_channel_desc_scm(channel_desc_t * ch) {
+	// Must be made cleanly, a lot of leaks...
+	free(ch);
+}
 
 int random_channel(channel_desc_t *desc, uint8_t abstraction_flag) {
 
diff --git a/targets/ARCH/COMMON/common_lib.c b/targets/ARCH/COMMON/common_lib.c
index c1685e11ecd5beab3aeed890c8fee63a634132c1..010f54a3ba4e45d4203256388022dfa15f2a5dcf 100644
--- a/targets/ARCH/COMMON/common_lib.c
+++ b/targets/ARCH/COMMON/common_lib.c
@@ -105,7 +105,7 @@ int load_lib(openair0_device *device, openair0_config_t *openair0_cfg, eth_param
   if ( IS_SOFTMODEM_BASICSIM ) {
     libname=OAI_BASICSIM_LIBNAME;
     shlib_fdesc[0].fname="device_init";
-  } else if ( IS_SOFTMODEM_RFSIM ) {
+  } else if ( IS_SOFTMODEM_RFSIM && flag == RAU_LOCAL_RADIO_HEAD) {
     libname=OAI_RFSIM_LIBNAME;
     shlib_fdesc[0].fname="device_init";
   } else if (flag == RAU_LOCAL_RADIO_HEAD) {
diff --git a/targets/ARCH/rfsimulator/simulator.c b/targets/ARCH/rfsimulator/simulator.c
index 3b23d6de066484a5e8d9f440f70fe1d1e9c1a545..d30848609628788682ce08c629b9ec18b633f2b6 100644
--- a/targets/ARCH/rfsimulator/simulator.c
+++ b/targets/ARCH/rfsimulator/simulator.c
@@ -47,8 +47,8 @@ pthread_mutex_t Sockmutex;
 
 typedef struct buffer_s {
   int conn_sock;
-  bool alreadyRead;
-  uint64_t lastReceivedTS;
+  openair0_timestamp lastReceivedTS;
+  openair0_timestamp lastWroteTS;
   bool headerMode;
   samplesBlockHeader_t th;
   char *transferPtr;
@@ -60,7 +60,7 @@ typedef struct buffer_s {
 
 typedef struct {
   int listen_sock, epollfd;
-  uint64_t nextTimestamp;
+  openair0_timestamp nextTimestamp;
   uint64_t typeStamp;
   char *ip;
   int saveIQfile;
@@ -104,9 +104,9 @@ void rxAddInput( struct complex16 *input_sig, struct complex16 *after_channel_si
   // Fixme: how to convert a noise in Watt into a 12 bits value out of the RF ADC ?
   // the parameter "-s" is declared as SNR, but the input power is not well defined
   // −132.24 dBm is a LTE subcarrier noise, that was used in origin code (15KHz BW thermal noise)
-  const double rxGain= 132.24 - snr_dB; 
+  const double rxGain= 132.24 - snr_dB;
   // sqrt(4*noise_figure_watt) is the thermal noise factor (volts)
-  // fixme: the last constant is pure trial results to make decent noise 
+  // fixme: the last constant is pure trial results to make decent noise
   const double noise_per_sample = sqrt(4*noise_figure_watt) * pow(10,rxGain/20) *10;
   // Fixme: we don't fill the offset length samples at begining ?
   // anyway, in today code, channel_offset=0
@@ -135,9 +135,6 @@ void rxAddInput( struct complex16 *input_sig, struct complex16 *after_channel_si
     }
 
     out_ptr->r += round(rx_tmp.x*pathLossLinear + noise_per_sample*gaussdouble(0.0,1.0));
-    printf("in: %d, out %d= %f*%f + %f*%f\n",
-      input_sig[((TS+i)*nbTx)%CirSize].r, out_ptr->r , rx_tmp.x,
-      pathLossLinear, noise_per_sample,gaussdouble(0.0,1.0));
     out_ptr->i += round(rx_tmp.y*pathLossLinear + noise_per_sample*gaussdouble(0.0,1.0));
     out_ptr++;
   }
@@ -156,8 +153,8 @@ void allocCirBuf(rfsimulator_state_t *bridge, int sock) {
   AssertFatal ( (ptr->circularBuf=(sample_t *) malloc(sampleToByte(CirSize,1))) != NULL, "");
   ptr->circularBufEnd=((char *)ptr->circularBuf)+sampleToByte(CirSize,1);
   ptr->conn_sock=sock;
-  ptr->alreadyRead=false;
   ptr->lastReceivedTS=0;
+  ptr->lastWroteTS=0;
   ptr->headerMode=true;
   ptr->transferPtr=(char *)&ptr->th;
   ptr->remainToTransfer=sizeof(samplesBlockHeader_t);
@@ -322,21 +319,22 @@ sin_addr:
 
   setblocking(sock, notBlocking);
   allocCirBuf(t, sock);
-  t->buf[sock].alreadyRead=true; // UE will start blocking on read
   return 0;
 }
 
-uint64_t lastW=-1;
 int rfsimulator_write(openair0_device *device, openair0_timestamp timestamp, void **samplesVoid, int nsamps, int nbAnt, int flags) {
   rfsimulator_state_t *t = device->priv;
   LOG_D(HW,"sending %d samples at time: %ld\n", nsamps, timestamp);
 
+
   for (int i=0; i<FD_SETSIZE; i++) {
-    buffer_t *ptr=&t->buf[i];
+    buffer_t *b=&t->buf[i];
 
-    if (ptr->conn_sock >= 0 ) {
+    if (b->conn_sock >= 0 ) {
+      if ( abs((double)b->lastWroteTS-timestamp) > (double)CirSize)
+	LOG_E(HW,"Tx/Rx shift too large Tx:%lu, Rx:%lu\n", b->lastWroteTS, b->lastReceivedTS);
       samplesBlockHeader_t header= {t->typeStamp, nsamps, nbAnt, timestamp};
-      fullwrite(ptr->conn_sock,&header, sizeof(header), t);
+      fullwrite(b->conn_sock,&header, sizeof(header), t);
       sample_t tmpSamples[nsamps][nbAnt];
 
       for(int a=0; a<nbAnt; a++) {
@@ -346,17 +344,17 @@ int rfsimulator_write(openair0_device *device, openair0_timestamp timestamp, voi
           tmpSamples[s][a]=in[s];
       }
 
-      if (ptr->conn_sock >= 0 )
-        fullwrite(ptr->conn_sock, (void *)tmpSamples, sampleToByte(nsamps,nbAnt), t);
+      if (b->conn_sock >= 0 ) {
+        fullwrite(b->conn_sock, (void *)tmpSamples, sampleToByte(nsamps,nbAnt), t);
+        b->lastWroteTS=timestamp+nsamps;
+      }
     }
   }
 
-  lastW=timestamp;
   LOG_D(HW,"sent %d samples at time: %ld->%ld, energy in first antenna: %d\n",
         nsamps, timestamp, timestamp+nsamps, signal_energy(samplesVoid[0], nsamps) );
   // Let's verify we don't have incoming data
   // This is mandatory when the opposite side don't transmit
-  // This is mandatory when the opposite side don't transmit
   flushInput(t, 0);
   pthread_mutex_unlock(&Sockmutex);
   return nsamps;
@@ -428,7 +426,6 @@ static bool flushInput(rfsimulator_state_t *t, int timeout) {
         AssertFatal( (t->typeStamp == UE_MAGICDL_FDD  && b->th.magic==ENB_MAGICDL_FDD) ||
                      (t->typeStamp == ENB_MAGICDL_FDD && b->th.magic==UE_MAGICDL_FDD), "Socket Error in protocol");
         b->headerMode=false;
-        b->alreadyRead=true;
 
         if ( b->lastReceivedTS != b->th.timestamp) {
           int nbAnt= b->th.nbAnt;
@@ -444,8 +441,8 @@ static bool flushInput(rfsimulator_state_t *t, int timeout) {
         }
 
         b->lastReceivedTS=b->th.timestamp;
-        AssertFatal(lastW == -1 || ( abs((double)lastW-b->lastReceivedTS) < (double)CirSize),
-                    "Tx/Rx shift too large Tx:%lu, Rx:%lu\n", lastW, b->lastReceivedTS);
+        AssertFatal(b->lastWroteTS == 0 || ( abs((double)b->lastWroteTS-b->lastReceivedTS) < (double)CirSize),
+                    "Tx/Rx shift too large Tx:%lu, Rx:%lu\n", b->lastWroteTS, b->lastReceivedTS);
         b->transferPtr=(char *)&b->circularBuf[b->lastReceivedTS%CirSize];
         b->remainToTransfer=sampleToByte(b->th.size, b->th.nbAnt);
       }
@@ -501,15 +498,33 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo
       return nsamps;
     }
   } else {
+    
     bool have_to_wait;
 
     do {
       have_to_wait=false;
 
       for ( int sock=0; sock<FD_SETSIZE; sock++) {
-        if ( t->buf[sock].circularBuf && t->buf[sock].alreadyRead )
-          if ( t->buf[sock].lastReceivedTS == 0 ||
-               (t->nextTimestamp+nsamps) > t->buf[sock].lastReceivedTS ) {
+	buffer_t *b=&t->buf[sock];
+        if ( b->circularBuf) {
+          LOG_D(HW,"sock: %d, lastWroteTS: %lu, lastRecvTS: %lu, TS must be avail: %lu\n",
+                sock, b->lastWroteTS,
+                b->lastReceivedTS,
+                t->nextTimestamp+nsamps);
+	  if (  b->lastReceivedTS > b->lastWroteTS ) {
+	    // The caller momdem (NB, UE, ...) must send Tx in advance, so we fill TX if Rx is in advance
+	    // This occurs for example when UE is in sync mode: it doesn't transmit
+	    // with USRP, it seems ok: if "tx stream" is off, we may consider it actually cuts the Tx power
+	    struct complex16 v={0};
+	    void *samplesVoid[b->th.nbAnt];
+	    for ( int i=0; i <b->th.nbAnt; i++)
+	      samplesVoid[i]=(void*)&v;
+	    rfsimulator_write(device, b->lastReceivedTS, samplesVoid, 1, b->th.nbAnt, 0);
+	  }
+	}
+
+        if ( b->circularBuf )
+          if ( t->nextTimestamp+nsamps > b->lastReceivedTS ) {
             have_to_wait=true;
             break;
           }
@@ -532,7 +547,7 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo
   for (int sock=0; sock<FD_SETSIZE; sock++) {
     buffer_t *ptr=&t->buf[sock];
 
-    if ( ptr->circularBuf && ptr->alreadyRead ) {
+    if ( ptr->circularBuf ) {
       bool reGenerateChannel=false;
 
       //fixme: when do we regenerate