diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt
index 7f9a4d6494a6df4d93f22ad633d87fc2b77bf105..87c51ccb62c3ab8c4eaf17f4acd25e12736ae7cd 100644
--- a/cmake_targets/CMakeLists.txt
+++ b/cmake_targets/CMakeLists.txt
@@ -2155,6 +2155,24 @@ add_definitions(-DASN1_MINIMUM_VERSION=924)
 #################################
 # add executables for operation
 #################################
+add_library(minimal_lib
+  ${OPENAIR_DIR}/common/utils/backtrace.c
+  ${OPENAIR_DIR}/common/utils/LOG/log.c
+  ${OPENAIR_DIR}/common/config/config_userapi.c
+  ${OPENAIR_DIR}/common/config/config_load_configmodule.c
+  ${OPENAIR_DIR}/common/config/config_cmdline.c
+  ${OPENAIR_DIR}/common/utils/minimal_stub.c
+  )
+target_link_libraries(minimal_lib pthread dl)
+
+add_executable(replay_node
+  ${OPENAIR_TARGETS}/ARCH/rfsimulator/stored_node.c
+  )
+target_link_libraries (replay_node minimal_lib)
+
+add_executable(measurement_display
+  ${OPENAIR_DIR}/common/utils/threadPool/measurement_display.c)
+target_link_libraries (measurement_display minimal_lib)
 
 # lte-softmodem is both eNB and UE implementation
 ###################################################
diff --git a/common/utils/minimal_stub.c b/common/utils/minimal_stub.c
new file mode 100644
index 0000000000000000000000000000000000000000..86454fe53f87dad750a11d7c0a1f07d67b5e5379
--- /dev/null
+++ b/common/utils/minimal_stub.c
@@ -0,0 +1,4 @@
+int T_stdout;
+
+void exit_function(const char *file, const char *function, const int line, const char *s) {
+}
diff --git a/common/utils/simple_executable.h b/common/utils/simple_executable.h
new file mode 100644
index 0000000000000000000000000000000000000000..97b29dd502e12bf924f85e058cde35d12b2da704
--- /dev/null
+++ b/common/utils/simple_executable.h
@@ -0,0 +1,33 @@
+#ifndef __SIMPLE_EXE_H__
+#define __SIMPLE_EXE_H__
+#define __USE_GNU
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <pthread.h>
+#include <sched.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/syscall.h>
+#include <sys/time.h>
+#include <stdint.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <arpa/inet.h>
+#include <common/utils/assertions.h>
+#include <common/utils/LOG/log.h>
+#include "common_lib.h"
+
+#ifdef T
+  #undef T
+  #define T(...)
+#endif
+
+#endif
diff --git a/common/utils/threadPool/measurement_display.c b/common/utils/threadPool/measurement_display.c
index ac7beca1fe00bac4b8d29d5906ded4cc5d7d1ea6..8f6e2c239a231c41a0f4c2f151dd3fcee468bf9b 100644
--- a/common/utils/threadPool/measurement_display.c
+++ b/common/utils/threadPool/measurement_display.c
@@ -2,22 +2,8 @@
   Author: Laurent THOMAS, Open Cells
   copyleft: OpenAirInterface Software Alliance and it's licence
 */
+#include <common/utils/simple_executable.h>
 
-#define __USE_GNU
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <pthread.h>
-#include <sched.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/syscall.h>
-#include <sys/time.h>
-#include <stdint.h>
-#include <sys/stat.h>
-#include <fcntl.h>
 #include "thread-pool.h"
 
 #define SEP "\t"
@@ -26,7 +12,7 @@ uint64_t cpuCyclesMicroSec;
 
 int main(int argc, char *argv[]) {
   if(argc != 2) {
-    printf("Need one paramter: the trace Linux pipe (fifo)");
+    printf("Need one parameter: the trace Linux pipe (fifo)");
     exit(1);
   }
 
diff --git a/executables/nr-ue.c b/executables/nr-ue.c
index cf0db424438888ad45de2422733d436ca2c65e95..7c96f141595b70b790a708d7e95332d8b4632051 100644
--- a/executables/nr-ue.c
+++ b/executables/nr-ue.c
@@ -125,6 +125,34 @@ extern double cpuf;
 #define DAQ_PERIOD      66667ULL
 #define FIFO_PRIORITY   40
 
+
+void init_thread(int core, char *name) {
+  pthread_setname_np(pthread_self(),name);
+  cpu_set_t cpuset;
+  CPU_ZERO(&cpuset);
+
+  if (core >0)
+    CPU_SET(core, &cpuset);
+
+  AssertFatal( 0 == pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset), "");
+  struct sched_param sp;
+  sp.sched_priority = FIFO_PRIORITY;
+  AssertFatal(pthread_setschedparam(pthread_self(),SCHED_FIFO,&sp)==0,
+              "Can't set thread priority, Are you root?\n");
+  /* Check the actual affinity mask assigned to the thread */
+  cpu_set_t *cset=CPU_ALLOC(CPU_SETSIZE);
+
+  if (0 == pthread_getaffinity_np(pthread_self(), CPU_ALLOC_SIZE(CPU_SETSIZE), cset)) {
+    char txt[512]= {0};
+
+    for (int j = 0; j < CPU_SETSIZE; j++)
+      if (CPU_ISSET(j, cset))
+        sprintf(txt+strlen(txt), " %d ", j);
+
+    printf("CPU Affinity of thread %s is %s\n", name, txt);
+  }
+}
+
 typedef enum {
   pss=0,
   pbch=1,
@@ -535,6 +563,7 @@ int computeSamplesShift(PHY_VARS_NR_UE *UE) {
 }
 
 void *UE_thread(void *arg) {
+  init_thread(1, "IQ samples");
   PHY_VARS_NR_UE *UE = (PHY_VARS_NR_UE *) arg;
   //  int tx_enabled = 0;
   openair0_timestamp timestamp;
diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c
index 24f8d4eb0d54fb97b42bae8fe88180ec6b0259b9..0a2f0ac2d5d4961a31a03f0d3864d18a19ca4f8f 100644
--- a/executables/nr-uesoftmodem.c
+++ b/executables/nr-uesoftmodem.c
@@ -541,7 +541,6 @@ void set_default_frame_parms(NR_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]) {
     frame_parms[CC_id]->nb_antennas_tx      = 1;
     frame_parms[CC_id]->nb_antennas_rx      = 1;
     //frame_parms[CC_id]->nushift             = 0;
-
     // NR: Init to legacy LTE 20Mhz params
     frame_parms[CC_id]->numerology_index  = 0;
     frame_parms[CC_id]->ttis_per_subframe = 1;
@@ -685,7 +684,7 @@ int main( int argc, char **argv ) {
   set_taus_seed (0);
   tpool_t pool;
   Tpool = &pool;
-  char params[]="-1,-1,-1,-1";
+  char params[]="2,3";
   initTpool(params, Tpool, false);
   cpuf=get_cpu_freq_GHz();
   itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info);
@@ -712,9 +711,7 @@ int main( int argc, char **argv ) {
     frame_parms[CC_id]->nb_antennas_rx     = nb_antenna_rx;
     frame_parms[CC_id]->nb_antenna_ports_eNB = 1; //initial value overwritten by initial sync later
     LOG_I(PHY,"Set nb_rx_antenna %d , nb_tx_antenna %d \n",frame_parms[CC_id]->nb_antennas_rx, frame_parms[CC_id]->nb_antennas_tx);
-
     get_band(downlink_frequency[CC_id][0], &frame_parms[CC_id]->eutra_band,   &uplink_frequency_offset[CC_id][0], &frame_parms[CC_id]->frame_type);
- 
   }
 
   NB_UE_INST=1;
diff --git a/executables/nr-uesoftmodem.h b/executables/nr-uesoftmodem.h
index 8bc07936f6b776741fb0b73cb9e60e7581fe5be4..078a8066c3c2c97088e00e2b3b8d624660eef0d4 100644
--- a/executables/nr-uesoftmodem.h
+++ b/executables/nr-uesoftmodem.h
@@ -236,7 +236,6 @@ extern double cpuf;
 extern int setup_ue_buffers(PHY_VARS_NR_UE **phy_vars_ue, openair0_config_t *openair0_cfg);
 extern void fill_ue_band_info(void);
 extern void init_UE(int);
-extern void init_thread(int sched_runtime, int sched_deadline, int sched_fifo, cpu_set_t *cpuset, char *name);
 extern void reset_opp_meas(void);
 extern void print_opp_meas(void);
 void *UE_thread(void *arg);
diff --git a/targets/ARCH/COMMON/common_lib.h b/targets/ARCH/COMMON/common_lib.h
index d14b2457c942f61abf65e1e2b9b2d24d5535ebcb..09ad515324b823b86ba416236923ae696e611019 100644
--- a/targets/ARCH/COMMON/common_lib.h
+++ b/targets/ARCH/COMMON/common_lib.h
@@ -19,8 +19,8 @@
  *      contact@openairinterface.org
  */
 
-/*! \file common_lib.h 
- * \brief common APIs for different RF frontend device 
+/*! \file common_lib.h
+ * \brief common APIs for different RF frontend device
  * \author HongliangXU, Navid Nikaein
  * \date 2015
  * \version 0.2
@@ -45,21 +45,16 @@
 #define RAU_REMOTE_RADIO_HEAD 1
 
 #ifndef MAX_CARDS
-#define MAX_CARDS 8
+  #define MAX_CARDS 8
 #endif
 
 typedef int64_t openair0_timestamp;
 typedef volatile int64_t openair0_vtimestamp;
 
- 
+
 /*!\brief structrue holds the parameters to configure USRP devices*/
 typedef struct openair0_device_t openair0_device;
 
-
-
-
-
-
 //#define USRP_GAIN_OFFSET (56.0)  // 86 calibrated for USRP B210 @ 2.6 GHz to get equivalent RS EPRE in OAI to SMBV100 output
 
 typedef enum {
@@ -80,9 +75,6 @@ typedef enum {
  */
 /*!\brief RF device types
  */
-#ifdef OCP_FRAMEWORK
-#include <enums.h>
-#else
 typedef enum {
   MIN_RF_DEV_TYPE = 0,
   /*!\brief device is ExpressMIMO */
@@ -104,7 +96,6 @@ typedef enum {
   MAX_RF_DEV_TYPE
 
 } dev_type_t;
-#endif
 
 /*!\brief transport protocol types
  */
@@ -122,16 +113,16 @@ typedef enum {
 /*!\brief  openair0 device host type */
 typedef enum {
   MIN_HOST_TYPE = 0,
- /*!\brief device functions within a RAU */
+  /*!\brief device functions within a RAU */
   RAU_HOST,
- /*!\brief device functions within a RRU */
+  /*!\brief device functions within a RRU */
   RRU_HOST,
   MAX_HOST_TYPE
 
-}host_type_t;
+} host_type_t;
 
 
-/*! \brief RF Gain clibration */ 
+/*! \brief RF Gain clibration */
 typedef struct {
   //! Frequency for which RX chain was calibrated
   double freq;
@@ -159,7 +150,7 @@ typedef struct {
   duplex_mode_t duplex_mode;
   //! number of downlink resource blocks
   int num_rb_dl;
-  //! number of samples per frame 
+  //! number of samples per frame
   unsigned int  samples_per_frame;
   //! the sample rate for both transmit and receive.
   double sample_rate;
@@ -174,9 +165,9 @@ typedef struct {
   //! number of TX channels (=TX antennas)
   int tx_num_channels;
   //! \brief RX base addresses for mmapped_dma
-  int32_t* rxbase[4];
+  int32_t *rxbase[4];
   //! \brief TX base addresses for mmapped_dma
-  int32_t* txbase[4];
+  int32_t *txbase[4];
   //! \brief Center frequency in Hz for RX.
   //! index: [0..rx_num_channels[
   double rx_freq[4];
@@ -187,7 +178,7 @@ typedef struct {
   //! \brief Pointer to Calibration table for RX gains
   rx_gain_calib_table_t *rx_gain_calib_table;
 
-  //! mode for rxgain (ExpressMIMO2) 
+  //! mode for rxgain (ExpressMIMO2)
   rx_gain_t rxg_mode[4];
   //! \brief Gain for RX in dB.
   //! index: [0..rx_num_channels]
@@ -201,15 +192,15 @@ typedef struct {
   double rx_bw;
   //! TX bandwidth in Hz
   double tx_bw;
-  //! clock source 
+  //! clock source
   clock_source_t clock_source;
   //! Manual SDR IP address
-//#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) 
+  //#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
   char *sdr_addrs;
   //! Auto calibration flag
   int autocal[4];
   //! rf devices work with x bits iqs when oai have its own iq format
-  //! the two following parameters are used to convert iqs 
+  //! the two following parameters are used to convert iqs
   int iq_txshift;
   int iq_rxrescale;
   //! Configuration file for LMS7002M
@@ -230,7 +221,7 @@ typedef struct {
   unsigned int   sf_read_delay;     // read delay in replay mode
   unsigned int   sf_write_delay;    // write delay in replay mode
   unsigned int   eth_mtu;           // ethernet MTU
-#endif  
+#endif
 
   //! number of samples per tti
   unsigned int  samples_per_tti;
@@ -241,7 +232,7 @@ typedef struct {
 
 } openair0_config_t;
 
-/*! \brief RF mapping */ 
+/*! \brief RF mapping */
 typedef struct {
   //! card id
   int card;
@@ -288,14 +279,14 @@ struct openair0_device_t {
 
   /*!brief Component Carrier ID of this device */
   int CC_id;
-  
+
   /*!brief Type of this device */
   dev_type_t type;
 
   /*!brief Transport protocol type that the device suppports (in case I/Q samples need to be transported) */
   transport_type_t transp_type;
 
-   /*!brief Type of the device's host (RAU/RRU) */
+  /*!brief Type of the device's host (RAU/RRU) */
   host_type_t host_type;
 
   /* !brief RF frontend parameters set by application */
@@ -317,25 +308,25 @@ struct openair0_device_t {
   /*! \brief Called to send a request message between RAU-RRU on control port
       @param device pointer to the device structure specific to the RF hardware target
       @param msg pointer to the message structure passed between RAU-RRU
-      @param msg_len length of the message  
-  */  
+      @param msg_len length of the message
+  */
   int (*trx_ctlsend_func)(openair0_device *device, void *msg, ssize_t msg_len);
 
   /*! \brief Called to receive a reply  message between RAU-RRU on control port
       @param device pointer to the device structure specific to the RF hardware target
       @param msg pointer to the message structure passed between RAU-RRU
-      @param msg_len length of the message  
-  */  
+      @param msg_len length of the message
+  */
   int (*trx_ctlrecv_func)(openair0_device *device, void *msg, ssize_t msg_len);
 
   /*! \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 timestamp The timestamp at whicch the first sample MUST be sent
       @param buff Buffer which holds the samples
       @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_func)(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps,int antenna_id, int flags);
 
   /*! \brief Receive samples from hardware.
@@ -351,55 +342,80 @@ struct openair0_device_t {
    */
   int (*trx_read_func)(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps,int antenna_id);
 
-  /*! \brief print the device statistics  
+  /*! \brief print the device statistics
    * \param device the hardware to use
    * \returns  0 on success
    */
   int (*trx_get_stats_func)(openair0_device *device);
 
-  /*! \brief Reset device statistics  
+  /*! \brief Reset device statistics
    * \param device the hardware to use
-   * \returns 0 in success 
+   * \returns 0 in success
    */
   int (*trx_reset_stats_func)(openair0_device *device);
 
-  /*! \brief Terminate operation of the transceiver -- free all associated resources 
+  /*! \brief Terminate operation of the transceiver -- free all associated resources
    * \param device the hardware to use
    */
   void (*trx_end_func)(openair0_device *device);
 
-  /*! \brief Stop operation of the transceiver 
+  /*! \brief Stop operation of the transceiver
    */
   int (*trx_stop_func)(openair0_device *device);
 
   /* Functions API related to UE*/
 
-  /*! \brief Set RX feaquencies 
+  /*! \brief Set RX feaquencies
    * \param device the hardware to use
    * \param openair0_cfg RF frontend parameters set by application
-   * \param exmimo_dump_config  dump EXMIMO configuration 
-   * \returns 0 in success 
+   * \param exmimo_dump_config  dump EXMIMO configuration
+   * \returns 0 in success
    */
-  int (*trx_set_freq_func)(openair0_device* device, openair0_config_t *openair0_cfg,int exmimo_dump_config);
-  
+  int (*trx_set_freq_func)(openair0_device *device, openair0_config_t *openair0_cfg,int exmimo_dump_config);
+
   /*! \brief Set gains
    * \param device the hardware to use
    * \param openair0_cfg RF frontend parameters set by application
-   * \returns 0 in success 
+   * \returns 0 in success
    */
-  int (*trx_set_gains_func)(openair0_device* device, openair0_config_t *openair0_cfg);
+  int (*trx_set_gains_func)(openair0_device *device, openair0_config_t *openair0_cfg);
 
   /*! \brief RRU Configuration callback
    * \param idx RU index
    * \param arg pointer to capabilities or configuration
    */
-  void (*configure_rru)(int idx, void* arg);
+  void (*configure_rru)(int idx, void *arg);
 };
 
 /* type of device init function, implemented in shared lib */
 typedef int(*oai_device_initfunc_t)(openair0_device *device, openair0_config_t *openair0_cfg);
 /* type of transport init function, implemented in shared lib */
-typedef int(*oai_transport_initfunc_t)(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t * eth_params);
+typedef int(*oai_transport_initfunc_t)(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t *eth_params);
+#define UE_MAGICDL_FDD 0xA5A5A5A5A5A5A5A5  // UE DL FDD record
+#define UE_MAGICUL_FDD 0x5A5A5A5A5A5A5A5A  // UE UL FDD record
+#define UE_MAGICDL_TDD 0xA6A6A6A6A6A6A6A6  // UE DL TDD record
+#define UE_MAGICUL_TDD 0x6A6A6A6A6A6A6A6A  // UE UL TDD record
+
+#define ENB_MAGICDL_FDD 0xB5B5B5B5B5B5B5B5  // eNB DL FDD record
+#define ENB_MAGICUL_FDD 0x5B5B5B5B5B5B5B5B  // eNB UL FDD record
+#define ENB_MAGICDL_TDD 0xB6B6B6B6B6B6B6B6  // eNB DL TDD record
+#define ENB_MAGICUL_TDD 0x6B6B6B6B6B6B6B6B  // eNB UL TDD record
+
+#define OPTION_LZ4  0x00000001          // LZ4 compression (option_value is set to compressed size)
+
+#define sample_t uint32_t // 2*16 bits complex number
+
+typedef struct {
+  uint64_t magic;          // Magic value (see defines above)
+  uint32_t size;           // Number of samples per antenna to follow this header
+  uint32_t nbAnt;          // Total number of antennas following this header
+  // Samples per antenna follow this header,
+  // i.e. nbAnt = 2 => this header+samples_antenna_0+samples_antenna_1
+  // data following this header in bytes is nbAnt*size*sizeof(sample_t)
+  uint64_t timestamp;      // Timestamp value of first sample
+  uint32_t option_value;   // Option value
+  uint32_t option_flag;    // Option flag
+} samplesBlockHeader_t;
 
 #ifdef __cplusplus
 extern "C"
@@ -407,23 +423,23 @@ extern "C"
 #endif
 
 
-  /*! \brief Initialize openair RF target. It returns 0 if OK */
-  int openair0_device_load(openair0_device *device, openair0_config_t *openair0_cfg);  
-  /*! \brief Initialize transport protocol . It returns 0 if OK */
-  int openair0_transport_load(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t * eth_params);
+/*! \brief Initialize openair RF target. It returns 0 if OK */
+int openair0_device_load(openair0_device *device, openair0_config_t *openair0_cfg);
+/*! \brief Initialize transport protocol . It returns 0 if OK */
+int openair0_transport_load(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t *eth_params);
 
-  
- /*! \brief Get current timestamp of USRP
-  * \param device the hardware to use
-  */
-  openair0_timestamp get_usrp_time(openair0_device *device);
 
- /*! \brief Set RX frequencies 
-  * \param device the hardware to use
-  * \param openair0_cfg RF frontend parameters set by application
-  * \returns 0 in success 
-  */
-  int openair0_set_rx_frequencies(openair0_device* device, openair0_config_t *openair0_cfg);
+/*! \brief Get current timestamp of USRP
+ * \param device the hardware to use
+ */
+openair0_timestamp get_usrp_time(openair0_device *device);
+
+/*! \brief Set RX frequencies
+ * \param device the hardware to use
+ * \param openair0_cfg RF frontend parameters set by application
+ * \returns 0 in success
+ */
+int openair0_set_rx_frequencies(openair0_device *device, openair0_config_t *openair0_cfg);
 #define gettid() syscall(__NR_gettid)
 /*@}*/
 
diff --git a/targets/ARCH/rfsimulator/simulator.c b/targets/ARCH/rfsimulator/simulator.c
index a17327b03ecc5791cadc7cef76fbecc9d3205da8..0edc587263b892b3d6b42b56deb183223a8f5516 100644
--- a/targets/ARCH/rfsimulator/simulator.c
+++ b/targets/ARCH/rfsimulator/simulator.c
@@ -27,22 +27,15 @@
 #define sample_t uint32_t // 2*16 bits complex number
 #define sampleToByte(a,b) ((a)*(b)*sizeof(sample_t))
 #define byteToSample(a,b) ((a)/(sizeof(sample_t)*(b)))
-#define MAGICeNB 0xA5A5A5A5A5A5A5A5
-#define MAGICUE  0x5A5A5A5A5A5A5A5A
 
-typedef struct {
-  uint64_t magic;
-  uint32_t size;
-  uint32_t nbAnt;
-  uint64_t timestamp;
-} transferHeader;
+#define sample_t uint32_t // 2*16 bits complex number
 
 typedef struct buffer_s {
   int conn_sock;
   bool alreadyRead;
   uint64_t lastReceivedTS;
   bool headerMode;
-  transferHeader th;
+  samplesBlockHeader_t th;
   char *transferPtr;
   uint64_t remainToTransfer;
   char *circularBufEnd;
@@ -55,6 +48,7 @@ typedef struct {
   uint64_t typeStamp;
   uint64_t initialAhead;
   char *ip;
+  int saveIQfile;
   buffer_t buf[FD_SETSIZE];
 } rfsimulator_state_t;
 
@@ -65,7 +59,7 @@ void allocCirBuf(rfsimulator_state_t *bridge, int sock) {
   ptr->conn_sock=sock;
   ptr->headerMode=true;
   ptr->transferPtr=(char *)&ptr->th;
-  ptr->remainToTransfer=sizeof(transferHeader);
+  ptr->remainToTransfer=sizeof(samplesBlockHeader_t);
   int sendbuff=1000*1000*10;
   AssertFatal ( setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &sendbuff, sizeof(sendbuff)) == 0, "");
   struct epoll_event ev= {0};
@@ -87,7 +81,7 @@ void socketError(rfsimulator_state_t *bridge, int sock) {
     LOG_W(HW,"Lost socket \n");
     removeCirBuf(bridge, sock);
 
-    if (bridge->typeStamp==MAGICUE)
+    if (bridge->typeStamp==UE_MAGICDL_FDD)
       exit(1);
   }
 }
@@ -120,6 +114,11 @@ void setblocking(int sock, enum blocking_t active) {
 static bool flushInput(rfsimulator_state_t *t);
 
 void fullwrite(int fd, void *_buf, int count, rfsimulator_state_t *t) {
+  if (t->saveIQfile != -1) {
+    if (write(t->saveIQfile, _buf, count) != count )
+      LOG_E(HW,"write in save iq file failed (%s)\n",strerror(errno));
+  }
+
   char *buf = _buf;
   int l;
   setblocking(fd, notBlocking);
@@ -145,7 +144,7 @@ void fullwrite(int fd, void *_buf, int count, rfsimulator_state_t *t) {
 
 int server_start(openair0_device *device) {
   rfsimulator_state_t *t = (rfsimulator_state_t *) device->priv;
-  t->typeStamp=MAGICeNB;
+  t->typeStamp=ENB_MAGICDL_FDD;
   AssertFatal((t->listen_sock = socket(AF_INET, SOCK_STREAM, 0)) >= 0, "");
   int enable = 1;
   AssertFatal(setsockopt(t->listen_sock, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) == 0, "");
@@ -168,7 +167,7 @@ sin_addr:
 
 int start_ue(openair0_device *device) {
   rfsimulator_state_t *t = device->priv;
-  t->typeStamp=MAGICUE;
+  t->typeStamp=UE_MAGICDL_FDD;
   int sock;
   AssertFatal((sock = socket(AF_INET, SOCK_STREAM, 0)) >= 0, "");
   struct sockaddr_in addr = {
@@ -207,7 +206,7 @@ int rfsimulator_write(openair0_device *device, openair0_timestamp timestamp, voi
     buffer_t *ptr=&t->buf[i];
 
     if (ptr->conn_sock >= 0 ) {
-      transferHeader header= {t->typeStamp, nsamps, nbAnt, timestamp};
+      samplesBlockHeader_t header= {t->typeStamp, nsamps, nbAnt, timestamp};
       fullwrite(ptr->conn_sock,&header, sizeof(header), t);
       sample_t tmpSamples[nsamps][nbAnt];
 
@@ -290,8 +289,8 @@ static bool flushInput(rfsimulator_state_t *t) {
 
       // check the header and start block transfer
       if ( b->headerMode==true && b->remainToTransfer==0) {
-        AssertFatal( (t->typeStamp == MAGICUE  && b->th.magic==MAGICeNB) ||
-                     (t->typeStamp == MAGICeNB && b->th.magic==MAGICUE), "Socket Error in protocol");
+        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;
 
@@ -322,7 +321,7 @@ static bool flushInput(rfsimulator_state_t *t) {
 
           b->headerMode=true;
           b->transferPtr=(char *)&b->th;
-          b->remainToTransfer=sizeof(transferHeader);
+          b->remainToTransfer=sizeof(samplesBlockHeader_t);
           b->th.magic=-1;
         }
       }
@@ -447,10 +446,22 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
   }
 
   rfsimulator->typeStamp = strncasecmp(rfsimulator->ip,"enb",3) == 0 ?
-                           MAGICeNB:
-                           MAGICUE;
-  LOG_I(HW,"rfsimulator: running as %s\n", rfsimulator-> typeStamp == MAGICeNB ? "eNB" : "UE");
-  device->trx_start_func       = rfsimulator->typeStamp == MAGICeNB ?
+                           ENB_MAGICDL_FDD:
+                           UE_MAGICDL_FDD;
+  LOG_I(HW,"rfsimulator: running as %s\n", rfsimulator-> typeStamp == ENB_MAGICDL_FDD ? "eNB" : "UE");
+  char *saveF;
+
+  if ((saveF=getenv("saveIQfile")) != NULL) {
+    rfsimulator->saveIQfile=open(saveF,O_APPEND| O_CREAT|O_TRUNC | O_WRONLY, 0666);
+
+    if ( rfsimulator->saveIQfile != -1 )
+      LOG_I(HW,"rfsimulator: will save written IQ samples  in %s\n", saveF);
+    else
+      LOG_E(HW, "can't open %s for IQ saving (%s)\n", saveF, strerror(errno));
+  } else
+    rfsimulator->saveIQfile = -1;
+
+  device->trx_start_func       = rfsimulator->typeStamp == ENB_MAGICDL_FDD ?
                                  server_start :
                                  start_ue;
   device->trx_get_stats_func   = rfsimulator_get_stats;
diff --git a/targets/ARCH/rfsimulator/stored_node.c b/targets/ARCH/rfsimulator/stored_node.c
new file mode 100644
index 0000000000000000000000000000000000000000..7380f5f3048a15b1c11feb78589c76ba8eb6f193
--- /dev/null
+++ b/targets/ARCH/rfsimulator/stored_node.c
@@ -0,0 +1,142 @@
+/*
+  Author: Laurent THOMAS, Open Cells
+  copyleft: OpenAirInterface Software Alliance and it's licence
+*/
+
+#include <common/utils/simple_executable.h>
+
+
+void fullwrite(int fd, void *_buf, int count) {
+  char *buf = _buf;
+  int l;
+
+  while (count) {
+    l = write(fd, buf, count);
+
+    if (l <= 0) {
+      if (errno==EINTR)
+        continue;
+
+      if(errno==EAGAIN) {
+        continue;
+      } else {
+        AssertFatal(false,"Lost socket\n");
+      }
+
+      count -= l;
+      buf += l;
+    }
+  }
+}
+
+int server_start(short port) {
+  int listen_sock;
+  AssertFatal((listen_sock = socket(AF_INET, SOCK_STREAM, 0)) >= 0, "");
+  int enable = 1;
+  AssertFatal(setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) == 0, "");
+  struct sockaddr_in addr = {
+sin_family:
+    AF_INET,
+sin_port:
+    htons(port),
+sin_addr:
+    { s_addr: INADDR_ANY }
+  };
+  bind(listen_sock, (struct sockaddr *)&addr, sizeof(addr));
+  AssertFatal(listen(listen_sock, 5) == 0, "");
+  return accept(listen_sock,NULL,NULL);
+}
+
+int client_start(char *IP, short port) {
+  int sock;
+  AssertFatal((sock = socket(AF_INET, SOCK_STREAM, 0)) >= 0, "");
+  struct sockaddr_in addr = {
+sin_family:
+    AF_INET,
+sin_port:
+    htons(port),
+sin_addr:
+    { s_addr: INADDR_ANY }
+  };
+  addr.sin_addr.s_addr = inet_addr(IP);
+  bool connected=false;
+
+  while(!connected) {
+    LOG_I(HW,"rfsimulator: trying to connect to %s:%d\n", IP, port);
+
+    if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == 0) {
+      LOG_I(HW,"rfsimulator: connection established\n");
+      connected=true;
+    }
+
+    perror("simulated node");
+    sleep(1);
+  }
+
+  return sock;
+}
+
+enum  blocking_t {
+  notBlocking,
+  blocking
+};
+
+void setblocking(int sock, enum blocking_t active) {
+  int opts;
+  AssertFatal( (opts = fcntl(sock, F_GETFL)) >= 0,"");
+
+  if (active==blocking)
+    opts = opts & ~O_NONBLOCK;
+  else
+    opts = opts | O_NONBLOCK;
+
+  AssertFatal(fcntl(sock, F_SETFL, opts) >= 0, "");
+}
+
+int main(int argc, char *argv[]) {
+  if(argc != 4) {
+    printf("Need parameters: source file, server or destination IP, TCP port\n");
+    exit(1);
+  }
+
+  int fd;
+  AssertFatal((fd=open(argv[1],O_RDONLY)) != -1, "file: %s", argv[1]);
+  off_t fileSize=lseek(fd, 0, SEEK_END);
+  int serviceSock;
+
+  if (strcmp(argv[2],"server")==0) {
+    serviceSock=server_start(atoi(argv[3]));
+  } else {
+    client_start(argv[2],atoi(argv[3]));
+  }
+
+  samplesBlockHeader_t header;
+  int bufSize=100000;
+  void *buff=malloc(bufSize);
+
+  while (1) {
+    //Rewind the file to loop on the samples
+    if ( lseek(fd, 0, SEEK_CUR) >= fileSize )
+      lseek(fd, 0, SEEK_SET);
+
+    // Read one block and send it
+    setblocking(serviceSock, blocking);
+    AssertFatal(read(fd,&header,sizeof(header)), "");
+    fullwrite(serviceSock, &header, sizeof(header));
+    int dataSize=sizeof(sample_t)*header.size*header.nbAnt;
+
+    if (dataSize>bufSize)
+      buff=realloc(buff,dataSize);
+
+    AssertFatal(read(fd,buff,dataSize) == dataSize, "");
+    fullwrite(serviceSock, buff, dataSize);
+    // Purge incoming samples
+    setblocking(serviceSock, notBlocking);
+
+    while(recv(serviceSock,buff, bufSize, MSG_DONTWAIT) > 0) {
+    }
+  }
+
+  return 0;
+}
+