diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt
index 3dbb61b5aec615544e728523304a10c0b48474fb..b24db90edbf1fb502b304d49863fd95f308d09f7 100644
--- a/cmake_targets/CMakeLists.txt
+++ b/cmake_targets/CMakeLists.txt
@@ -241,6 +241,7 @@ add_boolean_option(UE_AUTOTEST_TRACE   False "Activate UE autotest specific logs
 add_boolean_option(UE_DEBUG_TRACE      False "Activate UE debug trace")
 add_boolean_option(UE_TIMING_TRACE     False "Activate UE timing trace")
 add_boolean_option(DISABLE_LOG_X       False "Deactivate all LOG_* macros")
+add_boolean_option(USRP_REC_PLAY       False "Enable USRP record playback mode")
 
 add_boolean_option(DEBUG_CONSOLE False "makes debugging easier, disables stdout/stderr buffering")
 
@@ -1803,6 +1804,7 @@ add_executable(lte-softmodem-nos1
   ${OPENAIR_TARGETS}/RT/USER/rt_wrapper.c
   ${OPENAIR_TARGETS}/RT/USER/lte-ue.c
   ${OPENAIR_TARGETS}/RT/USER/lte-enb.c
+  ${OPENAIR_TARGETS}/RT/USER/lte-ru.c
   ${OPENAIR_TARGETS}/RT/USER/lte-softmodem.c
   ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c
   ${OPENAIR_TARGETS}/SIMU/USER/init_lte.c
@@ -1933,7 +1935,7 @@ add_executable(oaisim_nos1
   ${x2ap_h}
   ${OPENAIR_BIN_DIR}/messages_xml.h
   ${OPENAIR_TARGETS}/RT/USER/lte-ue.c
-  ${OPENAIR_TARGETS}/RT/USER/lte-enb.c
+  ${OPENAIR_TARGETS}/RT/USER/lte-ru.c
   ${OPENAIR_TARGETS}/RT/USER/rt_wrapper.c
   ${OPENAIR_TARGETS}/SIMU/USER/channel_sim.c
   ${OPENAIR_TARGETS}/SIMU/USER/init_lte.c
diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai
index d3a13c41c93cab31eda220e1e7c5d2240b709322..d625dfa159e3dbc768115f2eba37913fb2d08ff9 100755
--- a/cmake_targets/build_oai
+++ b/cmake_targets/build_oai
@@ -66,6 +66,7 @@ UE_AUTOTEST_TRACE="False"
 UE_DEBUG_TRACE="False"
 UE_TIMING_TRACE="False"
 DISABLE_LOG_X="False"
+USRP_REC_PLAY="False"
 BUILD_ECLIPSE=0
 trap handle_ctrl_c INT
 
@@ -158,6 +159,8 @@ Options
    Disable all LOG_* macros
 --build-eclipse
    Build eclipse project files. Paths are auto corrected by fixprj.sh
+--usrp-recplay
+   Build for I/Q record-playback modes
 Usage (first build):
  oaisim (eNB + UE): ./build_oai -I  --oaisim -x --install-system-files
  Eurecom EXMIMO + COTS UE : ./build_oai -I  --eNB -x --install-system-files
@@ -350,6 +353,10 @@ function main() {
             BUILD_TELNETSRV=1
             echo_info "Build embedded telnet server"
             shift ;;			
+        --usrp-recplay)
+            USRP_REC_PLAY="True"
+            echo_info "Enabling USRP record playback mode"
+            shift 1;;
         -h | --help)
             print_help
             exit 1;;
@@ -540,6 +547,7 @@ function main() {
     echo "set (UE_DEBUG_TRACE $UE_DEBUG_TRACE)"        >>  $cmake_file
     echo "set (UE_TIMING_TRACE $UE_TIMING_TRACE)"        >>  $cmake_file
     echo "set (DISABLE_LOG_X $DISABLE_LOG_X)"        >>  $cmake_file
+    echo "set (USRP_REC_PLAY $USRP_REC_PLAY)"        >>  $cmake_file
     if [ "$UE" = 1 -a "$NOS1" = "0" ] ; then
      echo_info "Compiling UE S1 build : enabling Linux and NETLINK"
      echo "set (LINUX True )"              >>  $cmake_file
diff --git a/common/config/config_cmdline.c b/common/config/config_cmdline.c
index 42ea7259c31963ff871c201b8215745086532223..cb24cc52222f3a4fed6af979b61882a4db234c39 100644
--- a/common/config/config_cmdline.c
+++ b/common/config/config_cmdline.c
@@ -52,9 +52,12 @@ char defbool[2]="1";
      switch(cfgoptions->type)
        {
        	case TYPE_STRING:
-           config_check_valptr(cfgoptions, (char **)(cfgoptions->strptr), sizeof(char *));
-           config_check_valptr(cfgoptions, cfgoptions->strptr, strlen(tmpval+1));
-           sprintf(*(cfgoptions->strptr), "%s",tmpval);
+           if (cfgoptions->numelt == 0 ) {
+              config_check_valptr(cfgoptions, cfgoptions->strptr, strlen(tmpval)+1);
+              sprintf(*(cfgoptions->strptr), "%s",tmpval);
+            } else {
+              sprintf( (char *)(cfgoptions->strptr), "%s",tmpval);              
+           }
            printf_cmdl("[CONFIG] %s set to  %s from command line\n", cfgoptions->optname, tmpval);
 	   optisset=1;
         break;
diff --git a/common/config/config_load_configmodule.c b/common/config/config_load_configmodule.c
index 8351d4d82c143bf05601638fcebe4e80e1f02039..ff66d22a1c847bd783ccd43211709b1e5bf741c1 100644
--- a/common/config/config_load_configmodule.c
+++ b/common/config/config_load_configmodule.c
@@ -129,20 +129,21 @@ int i;
 
 /* default */
   if (cfgparam == NULL) {
-     cfgparam = "libconfig:oaisoftmodem.conf";
+     tmpflags = tmpflags | CONFIG_NOOOPT;
+     cfgparam = DEFAULT_CFGMODE ":" DEFAULT_CFGFILENAME;
      }
 /* parse the config parameters to set the config source */
    i = sscanf(cfgparam,"%m[^':']:%ms",&cfgmode,&modeparams);
    if (i< 0) {
        fprintf(stderr,"[CONFIG] %s, %d, sscanf error parsing config source  %s: %s\n", __FILE__, __LINE__,cfgparam, strerror(errno));
-       cfgmode=strdup("libconfig");
-       modeparams = strdup("oaisoftmodem.conf");
+       cfgmode=strdup(DEFAULT_CFGMODE);
+       modeparams = strdup(DEFAULT_CFGFILENAME);
    }
    else if ( i == 1 ) {
   /* -O argument doesn't contain ":" separator, assume -O <conf file> option, default cfgmode to libconfig
      with one parameter, the path to the configuration file */
        modeparams=cfgmode;
-       cfgmode=strdup("libconfig");
+       cfgmode=strdup(DEFAULT_CFGMODE);
    }
 
    cfgptr = malloc(sizeof(configmodule_interface_t));
diff --git a/common/config/config_load_configmodule.h b/common/config/config_load_configmodule.h
index 71c642f68054180bf521dfcd8a7e0f12bc39e57b..76f074cd6c38cf805938f28567237368b2d8e253 100644
--- a/common/config/config_load_configmodule.h
+++ b/common/config/config_load_configmodule.h
@@ -46,6 +46,7 @@
 #define CONFIG_DEBUGCMDLINE   4        // print command line processing messages
 #define CONFIG_HELP           8        // print help message
 #define CONFIG_ABORT          16       // config failed,abort execution 
+#define CONFIG_NOOOPT         32       // no -O option found when parsing command line 
 
 
 typedef int(*configmodule_initfunc_t)(char *cfgP[],int numP);
diff --git a/common/config/config_userapi.c b/common/config/config_userapi.c
index ad2e355d528153d8591ba7f89065b7c6cdeae2a4..4e49f2c56a8e69afeac77a2ebb2fd1f5fc24b588 100644
--- a/common/config/config_userapi.c
+++ b/common/config/config_userapi.c
@@ -50,7 +50,11 @@ configmodule_interface_t *config_get_if(void)
 char * config_check_valptr(paramdef_t *cfgoptions, char **ptr, int length) 
 {
 
-     printf_ptrs("-- %s 0x%08lx %i\n",cfgoptions->optname,(uintptr_t)(*ptr),length);
+     printf_ptrs("[CONFIG] %s ptr: 0x%08lx requested size: %i\n",cfgoptions->optname,(uintptr_t)(ptr),length);
+     if(cfgoptions->numelt > 0) { /* already allocated */
+          return *ptr;
+     }
+
      if (*ptr == NULL) {
         *ptr = malloc(length);
         if ( *ptr != NULL) {
@@ -147,3 +151,7 @@ int config_isparamset(paramdef_t *params,int paramidx)
       return 0;
   }
 }
+
+int config_getparamval_fromparamdefidx(paramdef_t *cfgoptions,int paramidx) {
+    return -1;
+}
diff --git a/common/config/config_userapi.h b/common/config/config_userapi.h
index 6acaacf7166b3e3dcac77c46bff4bef5b7d4d807..5bbc20a950bfb2150a6bfb0945821a08008dab41 100644
--- a/common/config/config_userapi.h
+++ b/common/config/config_userapi.h
@@ -38,6 +38,9 @@
 extern "C"
 {
 #endif
+#define DEFAULT_CFGFILENAME "oaisoftmodem.conf"
+#define DEFAULT_CFGMODE     "libconfig"
+
 #define CONFIG_GETSOURCE    ( (config_get_if()==NULL) ? NULL : config_get_if()->cfgmode       )
 #define CONFIG_GETNUMP      ( (config_get_if()==NULL) ? 0    : config_get_if()->num_cfgP      )
 #define CONFIG_GETP(P)      ( (config_get_if()==NULL) ? NULL : config_get_if()->cfgP[P]       )
@@ -51,6 +54,7 @@ extern int config_get(paramdef_t *params,int numparams, char *prefix);
 extern int config_isparamset(paramdef_t *params,int paramidx);
 extern void config_assign_int(paramdef_t *cfgoptions, char *fullname, int val);
 extern int config_process_cmdline(paramdef_t *cfgoptions,int numoptions, char *prefix);
+extern int config_getparamval_fromparamdefidx(paramdef_t *cfgoptions,int paramidx);
 #define config_getlist config_get_if()->getlist
 #define CONFIG_GETCONFFILE (config_get_if()->cfgP[0])
 
diff --git a/common/config/libconfig/config_libconfig.c b/common/config/libconfig/config_libconfig.c
index 35a70dfcc79d49fd560a5f8952f4441812c24bf9..00f5f38b8fba60a042b42ebde78f78e6e87c886e 100644
--- a/common/config/libconfig/config_libconfig.c
+++ b/common/config/libconfig/config_libconfig.c
@@ -104,17 +104,28 @@ int config_libconfig_get(paramdef_t *cfgoptions,int numoptions, char *prefix )
                            cfgpath,str,cfgoptions[i].numelt); 
                   str[strlen(str)-1] = 0;
               }
-              config_check_valptr(&(cfgoptions[i]), (char **)(&(cfgoptions[i].strptr)), sizeof(char *));
-              config_check_valptr(&(cfgoptions[i]), cfgoptions[i].strptr, strlen(str)+1);
-              sprintf( *(cfgoptions[i].strptr) , "%s", str);
-              printf_params("[LIBCONFIG] %s: %s\n", cfgpath,*(cfgoptions[i].strptr) );
+              if (cfgoptions[i].numelt == 0 ) {
+                  config_check_valptr(&(cfgoptions[i]), (char **)(&(cfgoptions[i].strptr)), sizeof(char *));
+                  config_check_valptr(&(cfgoptions[i]), cfgoptions[i].strptr, strlen(str)+1);
+                  sprintf( *(cfgoptions[i].strptr) , "%s", str);
+                  printf_params("[LIBCONFIG] %s: %s\n", cfgpath,*(cfgoptions[i].strptr) );
+              } else {
+                 sprintf( (char *)(cfgoptions[i].strptr) , "%s", str);
+                 printf_params("[LIBCONFIG] %s: %s\n", cfgpath,(char *)cfgoptions[i].strptr );
+              }
            } else {
 	      if( cfgoptions[i].defstrval != NULL) {
                  defval=1;
-                 config_check_valptr(&(cfgoptions[i]), (char **)(&(cfgoptions[i].strptr)), sizeof(char *));
-                 config_check_valptr(&(cfgoptions[i]), cfgoptions[i].strptr, strlen(cfgoptions[i].defstrval)+1);
-                 sprintf(*(cfgoptions[i].strptr), "%s",cfgoptions[i].defstrval);
-                 printf_params("[LIBCONFIG] %s set to default value %s\n", cfgpath, *(cfgoptions[i].strptr));
+ 
+                 if (cfgoptions[i].numelt == 0 ) {
+                     config_check_valptr(&(cfgoptions[i]), (char **)(&(cfgoptions[i].strptr)), sizeof(char *));
+                     config_check_valptr(&(cfgoptions[i]), cfgoptions[i].strptr, strlen(cfgoptions[i].defstrval)+1);
+                     sprintf(*(cfgoptions[i].strptr), "%s",cfgoptions[i].defstrval);
+                     printf_params("[LIBCONFIG] %s set to default value %s\n", cfgpath, *(cfgoptions[i].strptr));
+                 } else {
+                    sprintf((char *)(cfgoptions[i].strptr), "%s",cfgoptions[i].defstrval);
+                    printf_params("[LIBCONFIG] %s set to default value %s\n", cfgpath, (char *)cfgoptions[i].strptr);
+                 }
               } else {
 	         notfound=1;
               } 
@@ -183,7 +194,7 @@ int config_libconfig_get(paramdef_t *cfgoptions,int numoptions, char *prefix )
               read_intarray(&cfgoptions[i],setting,cfgpath);
            } else {
               if( cfgoptions[i].defintarrayval != NULL) {
-                config_check_valptr(&(cfgoptions[i]),(char **)&(cfgoptions[i].iptr), sizeof(int32_t));
+                config_check_valptr(&(cfgoptions[i]),(char **)&(cfgoptions[i].iptr), sizeof(int32_t*));
                 cfgoptions[i].iptr=cfgoptions[i].defintarrayval;
                 defval=1;
                 for (int j=0; j<cfgoptions[i].numelt ; j++) {
diff --git a/openair1/PHY/LTE_TRANSPORT/pucch.c b/openair1/PHY/LTE_TRANSPORT/pucch.c
index 61d2cc0e9b3a841e904e45452fe511df20cab387..c8da27bcb8cf3d60caf22f54e6c38f68750a3ffd 100644
--- a/openair1/PHY/LTE_TRANSPORT/pucch.c
+++ b/openair1/PHY/LTE_TRANSPORT/pucch.c
@@ -1871,6 +1871,23 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB,
 	eNB->pucch1ab_stats_cnt[j][i]=0;
       }
     }
+#if defined(USRP_REC_PLAY)
+    // It's probably bad to do this statically only once.
+    // Looks like the above is incomplete.
+    // Such reset needs to be done once a UE PHY structure is being used/re-used
+    // Don't know if this is ever possible in current architecture
+    for (i=0;i<10240;i++) {
+      for (j=0;j<NUMBER_OF_UE_MAX;j++) {
+	eNB->pucch1_stats[j][i]=0;
+	eNB->pucch1_stats_thres[j][i]=0;
+      }
+    }
+    for (i=0;i<20480;i++) {
+      for (j=0;j<NUMBER_OF_UE_MAX;j++) {
+	eNB->pucch1ab_stats[j][i]=0;
+      }
+    }
+#endif    
     first_call=0;
   }
 
@@ -2152,8 +2169,9 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB,
     } //phase
 
 //    stat_max *= nsymb;  // normalize to energy per symbol
-//    stat_max /= (frame_parms->N_RB_UL*12); // 
+//    stat_max /= (frame_parms->N_RB_UL*12); //
     stat_max /= (nsymb*12);
+    
 #ifdef DEBUG_PUCCH_RX
     printf("[eNB] PUCCH: stat %d, stat_max %d, phase_max %d\n", stat,stat_max,phase_max);
 #endif
@@ -2289,8 +2307,13 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB,
     stat_im=0;
 
     // Do detection now
+#if defined(USRP_REC_PLAY)
+    // It looks like the value is a bit messy when RF is replayed.
+    // For instance i assume to skip pucch1_thres from the test below.
+    if (sigma2_dB<(dB_fixed(stat_max)))  {//
+#else
     if (sigma2_dB<(dB_fixed(stat_max)-pucch1_thres))  {//
-
+#endif
       chL = (nsymb>>1)-4;
       chest_mag=0;
       cfo =  (frame_parms->Ncp==0) ? &cfo_pucch_np[14*phase_max] : &cfo_pucch_ep[12*phase_max];
@@ -2431,7 +2454,11 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB,
       if (fmt==pucch_format1b)
         *(1+payload) = (stat_im<0) ? 1 : 2;
     } else { // insufficient energy on PUCCH so NAK
+#if defined(USRP_REC_PLAY)
+      LOG_I(PHY,"PUCCH 1a/b: NAK subframe %d : sigma2_dB %d, stat_max %d, pucch1_thres %d\n",subframe,sigma2_dB,dB_fixed(stat_max),pucch1_thres);
+#else
       LOG_I(PHY,"PUCCH 1a/b: subframe %d : sigma2_dB %d, stat_max %d, pucch1_thres %d\n",subframe,sigma2_dB,dB_fixed(stat_max),pucch1_thres);
+#endif      
       *payload = 4;  // DTX
       ((int16_t*)&eNB->pucch1ab_stats[UE_id][(subframe<<10) + (eNB->pucch1ab_stats_cnt[UE_id][subframe])])[0] = (int16_t)(stat_re);
       ((int16_t*)&eNB->pucch1ab_stats[UE_id][(subframe<<10) + (eNB->pucch1ab_stats_cnt[UE_id][subframe])])[1] = (int16_t)(stat_im);
diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c
index a1ad4c5375781ffb9d6ab37d5936c8b864d37d62..6094f5294029e1a54149216165d0c1089a91c619 100644
--- a/openair1/SCHED/phy_procedures_lte_ue.c
+++ b/openair1/SCHED/phy_procedures_lte_ue.c
@@ -2939,12 +2939,12 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint
 	  
 	  //dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
 	  ue->UE_mode[eNB_id] = PUSCH;
-	  
-	} else {
+	}
+      } else {
 	  LOG_E(PHY,"[UE  %d] Frame %d, subframe %d: Problem in DCI!\n",ue->Mod_id,frame_rx,subframe_rx);
 	  dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
 	}
-      }
+    }
       
       else if ((dci_alloc_rx[i].rnti == SI_RNTI) &&
 	       ((dci_alloc_rx[i].format == format1A) || (dci_alloc_rx[i].format == format1C))) {
@@ -2977,7 +2977,6 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint
 	
 	}
       }
-    }
 
     else if ((dci_alloc_rx[i].rnti == P_RNTI) &&
        ((dci_alloc_rx[i].format == format1A) || (dci_alloc_rx[i].format == format1C))) {
diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c
index 9141a85d33293c55b14a0b3d514eb9398d1bcaf1..f2f89ad1ca73550888e57b55311cf7945f894155 100644
--- a/openair2/ENB_APP/enb_config.c
+++ b/openair2/ENB_APP/enb_config.c
@@ -2592,7 +2592,9 @@ void RCConfig(void) {
 
 
 /* get global parameters, defined outside any section in the config file */
-  
+ 
+  printf("Getting ENBSParams\n");
+ 
   config_get( ENBSParams,sizeof(ENBSParams)/sizeof(paramdef_t),NULL); 
   RC.nb_inst = ENBSParams[ENB_ACTIVE_ENBS_IDX].numelt;
  
diff --git a/openair2/LAYER2/MAC/defs.h b/openair2/LAYER2/MAC/defs.h
index 65e090e370ec5660cec4449ddff0c531a6c2249c..43d8167fe604315290e416dbd8190fbfcffae392 100644
--- a/openair2/LAYER2/MAC/defs.h
+++ b/openair2/LAYER2/MAC/defs.h
@@ -128,7 +128,11 @@
 /*!\brief Maximum number od control elemenets */
 #define MAX_NUM_CE 5
 /*!\brief Maximum number of random access process */
+#if defined(USRP_REC_PLAY)
+#define NB_RA_PROC_MAX 1
+#else
 #define NB_RA_PROC_MAX 4
+#endif
 /*!\brief size of buffer status report table */
 #define BSR_TABLE_SIZE 64
 /*!\brief The power headroom reporting range is from -23 ...+40 dB and beyond, with step 1 */
diff --git a/openair2/LAYER2/MAC/eNB_scheduler.c b/openair2/LAYER2/MAC/eNB_scheduler.c
index f7c3f5829d6b9005d632dcc9b5866011b86c1ed0..2c3b88306a821b435d7d31da6364ee710395f6ee 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler.c
@@ -352,17 +352,17 @@ schedule_SR(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP)
 	    ul_req =
 		&RC.mac[module_idP]->UL_req[CC_id].ul_config_request_body;
 
+	    // drop the allocation if the UE hasn't send RRCConnectionSetupComplete yet
+	    if (mac_eNB_get_rrc_status
+		(module_idP, UE_RNTI(module_idP, UE_id)) < RRC_CONNECTED)
+		continue;
+
 	    AssertFatal(UE_list->
 			UE_template[CC_id][UE_id].physicalConfigDedicated
 			!= NULL,
 			"physicalConfigDedicated is null for UE %d\n",
 			UE_id);
 
-	    // drop the allocation if the UE hasn't send RRCConnectionSetupComplete yet
-	    if (mac_eNB_get_rrc_status
-		(module_idP, UE_RNTI(module_idP, UE_id)) < RRC_CONNECTED)
-		continue;
-
 	    if ((SRconfig =
 		 UE_list->
 		 UE_template[CC_id][UE_id].physicalConfigDedicated->
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_RA.c b/openair2/LAYER2/MAC/eNB_scheduler_RA.c
index 939f35f2ebd405d0624729efbe87012a774b12cd..327f5faafe16182cceb24ed5736661b47b0f186b 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_RA.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_RA.c
@@ -1579,7 +1579,25 @@ initiate_ra_proc(module_id_t module_idP,
 	    ra[i].Msg2_subframe = (subframeP + 4) % 10;
 	    /* TODO: find better procedure to allocate RNTI */
 	    do {
+#if defined(USRP_REC_PLAY) // deterministic rnti in usrp record/playback mode
+	        static int drnti[NUMBER_OF_UE_MAX] = { 0xbda7, 0x71da, 0x9c40, 0xc350, 0x2710, 0x4e20, 0x7530, 0x1388, 0x3a98, 0x61a8, 0x88b8, 0xafc8, 0xd6d8, 0x1b58, 0x4268, 0x6978 };
+	        int j = 0;
+		int nb_ue = 0;
+		for (j = 0; j < NUMBER_OF_UE_MAX; j++) {
+		    if (UE_RNTI(module_idP, j) > 0) {
+		        nb_ue++;
+		    } else {
+		        break;
+		    }
+		}
+		if (nb_ue >= NUMBER_OF_UE_MAX) {
+		    printf("No more free RNTI available, increase NUMBER_OF_UE_MAX\n");
+		    abort();
+		}
+		ra[i].rnti = drnti[nb_ue];
+#else	
 		ra[i].rnti = taus();
+#endif
 		loop++;
 	    }
 	    while (loop != 100 &&
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c
index 42c50d8063a5450574b0ccc9610e6b234cb22621..df84675dc1e3fc28dcc1f76061fa5b0e01cf862d 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c
@@ -1349,9 +1349,14 @@ fill_nfapi_harq_information(module_id_t module_idP,
 
     AssertFatal(UE_id >= 0, "UE_id cannot be found, impossible\n");
     AssertFatal(UE_list != NULL, "UE_list is null\n");
+#if 0
+    /* TODO: revisit, don't use Assert, it's perfectly possible to
+     * have physicalConfigDedicated NULL here
+     */
     AssertFatal(UE_list->UE_template[CC_idP][UE_id].
 		physicalConfigDedicated != NULL,
 		"physicalConfigDedicated for rnti %x is null\n", rntiP);
+#endif
 
     harq_information->harq_information_rel11.num_ant_ports = 1;
 
@@ -2057,6 +2062,9 @@ int add_new_ue(module_id_t mod_idP, int cc_idP, rnti_t rntiP, int harq_pidP
 	UE_list->ordered_ULCCids[0][UE_id] = cc_idP;
 	UE_list->num_UEs++;
 	UE_list->active[UE_id] = TRUE;
+#if defined(USRP_REC_PLAY) // not specific to record/playback ?
+	UE_list->UE_template[cc_idP][UE_id].pre_assigned_mcs_ul = 0;
+#endif    
 
 #ifdef Rel14
 	UE_list->UE_template[cc_idP][UE_id].rach_resource_type =
@@ -3585,11 +3593,9 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id,
     uint8_t *pdu;
 
 #ifdef Rel14
-    AssertFatal(UE_list->
-		UE_template[pCCid][UE_id].physicalConfigDedicated->
-		pucch_ConfigDedicated != NULL,
-		"pucch_ConfigDedicated is null!\n");
-    if ((UE_list->UE_template[pCCid][UE_id].physicalConfigDedicated->ext7)
+    if (UE_list->UE_template[pCCid][UE_id].physicalConfigDedicated != NULL &&
+        UE_list->UE_template[pCCid][UE_id].physicalConfigDedicated->pucch_ConfigDedicated != NULL &&
+        (UE_list->UE_template[pCCid][UE_id].physicalConfigDedicated->ext7)
 	&& (UE_list->UE_template[pCCid][UE_id].
 	    physicalConfigDedicated->ext7->pucch_ConfigDedicated_r13)
 	&&
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
index 343d391538c27573a5cbbac883f519ee7bf34b99..421eab7cd768f9c64997b280eba1a780a85359ea 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
@@ -268,6 +268,9 @@ rx_sdu(const module_id_t enb_mod_idP,
 		      "[eNB %d] Frame %d, Subframe %d CC_id %d MAC CE_LCID %d (ce %d/%d): CRNTI %x (UE_id %d) in Msg3\n",
 		      enb_mod_idP, frameP, subframeP, CC_idP, rx_ces[i], i,
 		      num_ce, old_rnti, old_UE_id);
+		/* receiving CRNTI means that the current rnti has to go away */
+		cancel_ra_proc(enb_mod_idP, CC_idP, frameP,
+			       current_rnti);
 		if (old_UE_id != -1) {
 		    /* TODO: if the UE did random access (followed by a MAC uplink with
 		     * CRNTI) because none of its scheduling request was granted, then
@@ -288,9 +291,6 @@ rx_sdu(const module_id_t enb_mod_idP,
 			mac_eNB_rrc_ul_in_sync(enb_mod_idP, CC_idP, frameP,
 					       subframeP, old_rnti);
 		    }
-		    /* receiving CRNTI means that the current rnti has to go away */
-		    cancel_ra_proc(enb_mod_idP, CC_idP, frameP,
-				   current_rnti);
 		    current_rnti = old_rnti;
 		}
 		crnti_rx = 1;
diff --git a/openair2/LAYER2/MAC/main.c b/openair2/LAYER2/MAC/main.c
index fcaab0b80b035ec1bf45f9c19c14fc84857a144a..534f603dfd8e04e69795a51e440a2dc43b813c3d 100644
--- a/openair2/LAYER2/MAC/main.c
+++ b/openair2/LAYER2/MAC/main.c
@@ -210,7 +210,7 @@ void mac_init_cell_params(int Mod_idP, int CC_idP)
     UE_TEMPLATE *UE_template;
 
     LOG_D(MAC, "[MSC_NEW][FRAME 00000][MAC_eNB][MOD %02d][]\n", Mod_idP);
-    COMMON_channels_t *cc = &RC.mac[Mod_idP]->common_channels[CC_idP];
+    //COMMON_channels_t *cc = &RC.mac[Mod_idP]->common_channels[CC_idP];
 
     memset(&RC.mac[Mod_idP]->eNB_stats, 0, sizeof(eNB_STATS));
     UE_template =
diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_security.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_security.c
index d395f959819098e9ff7e4db191afeddd1d823b6e..2554eb145ab9de975100795e207efe6276e39978 100644
--- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_security.c
+++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_security.c
@@ -220,7 +220,7 @@ pdcp_validate_security(
   stream_decrypt(pdcp_pP->cipheringAlgorithm,
                  &decrypt_params,
                  &buffer_decrypted);
-
+#if !defined(USRP_REC_PLAY)
   if (srb_flagP) {
     /* Now check the integrity of the complete PDU */
     decrypt_params.message    = pdcp_pdu_buffer;
@@ -241,7 +241,7 @@ pdcp_validate_security(
       return -1;
     }
   }
-
+#endif
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_VALIDATE_SECURITY, VCD_FUNCTION_OUT);
 
   return 0;
diff --git a/openair2/RRC/LITE/L2_interface.c b/openair2/RRC/LITE/L2_interface.c
index 408e0e817546a3f3833459e0bc0c33ea256f9b7f..504bf8ee9b9dd9f86852259927d331a59336ce52 100644
--- a/openair2/RRC/LITE/L2_interface.c
+++ b/openair2/RRC/LITE/L2_interface.c
@@ -807,7 +807,10 @@ mac_UE_get_rrc_status(
 )
 //------------------------------------------------------------------------------
 {
-  return(UE_rrc_inst[Mod_idP].Info[indexP].State);
+  if (UE_rrc_inst)
+    return(UE_rrc_inst[Mod_idP].Info[indexP].State);
+  else
+    return(-1);
 }
 
 //-------------------------------------------------------------------------------------------//
diff --git a/openair2/RRC/LITE/defs.h b/openair2/RRC/LITE/defs.h
index 0811818c722717b6bda8236cc20879cc3140a1d8..9d7f7fdf2d169d4104de8c5ff5662d51aa2bfc85 100644
--- a/openair2/RRC/LITE/defs.h
+++ b/openair2/RRC/LITE/defs.h
@@ -242,7 +242,11 @@ typedef enum HO_STATE_e {
 // #define NUM_MAX_CBA_GROUP 4 // in the platform_constants
 
 /* TS 36.331: RRC-TransactionIdentifier ::= INTEGER (0..3) */
+#if defined(USRP_REC_PLAY)
+#define RRC_TRANSACTION_IDENTIFIER_NUMBER  1
+#else
 #define RRC_TRANSACTION_IDENTIFIER_NUMBER  3
+#endif
 
 typedef struct {
   unsigned short transport_block_size;                  /*!< \brief Minimum PDU size in bytes provided by RLC to MAC layer interface */
diff --git a/openair2/RRC/LITE/rrc_eNB.c b/openair2/RRC/LITE/rrc_eNB.c
index 28d69826523702c7a0bdf48a9a432e6504613a92..c8b42d41b354160400dc7317cf58821ef4a95ef5 100644
--- a/openair2/RRC/LITE/rrc_eNB.c
+++ b/openair2/RRC/LITE/rrc_eNB.c
@@ -627,12 +627,12 @@ void rrc_eNB_emulation_notify_ue_module_id(
       return;
     }
     for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
-      if (RC.rrc[enb_module_id].carrier[CC_id].sib1 != NULL) {
+      if (&RC.rrc[enb_module_id]->carrier[CC_id].sib1 != NULL) {
         if (
-          (RC.rrc[enb_module_id].carrier[CC_id].sib1->cellAccessRelatedInfo.cellIdentity.buf[0] == cell_identity_byte0P) &&
-          (RC.rrc[enb_module_id].carrier[CC_id].sib1->cellAccessRelatedInfo.cellIdentity.buf[1] == cell_identity_byte1P) &&
-          (RC.rrc[enb_module_id].carrier[CC_id].sib1->cellAccessRelatedInfo.cellIdentity.buf[2] == cell_identity_byte2P) &&
-          (RC.rrc[enb_module_id].carrier[CC_id].sib1->cellAccessRelatedInfo.cellIdentity.buf[3] == cell_identity_byte3P)
+          (&RC.rrc[enb_module_id]->carrier[CC_id].sib1->cellAccessRelatedInfo.cellIdentity.buf[0] == cell_identity_byte0P) &&
+          (&RC.rrc[enb_module_id]->carrier[CC_id].sib1->cellAccessRelatedInfo.cellIdentity.buf[1] == cell_identity_byte1P) &&
+          (&RC.rrc[enb_module_id]->carrier[CC_id].sib1->cellAccessRelatedInfo.cellIdentity.buf[2] == cell_identity_byte2P) &&
+          (&RC.rrc[enb_module_id]->carrier[CC_id].sib1->cellAccessRelatedInfo.cellIdentity.buf[3] == cell_identity_byte3P)
         ) {
           ue_context_p = rrc_eNB_get_ue_context(
                            RC.rrc[enb_module_id],
diff --git a/openair2/RRC/LITE/rrc_eNB_S1AP.c b/openair2/RRC/LITE/rrc_eNB_S1AP.c
index 55adb217facd8ecaacde5e83e08fccd6bb5091ec..24ee3c06dafa7a46b8920697db8969b87a806f55 100644
--- a/openair2/RRC/LITE/rrc_eNB_S1AP.c
+++ b/openair2/RRC/LITE/rrc_eNB_S1AP.c
@@ -390,8 +390,10 @@ rrc_pdcp_config_security(
                      ue_context_pP->ue_context.kenb,
                      &kRRCint);
 
+#if !defined(USRP_REC_PLAY)
 #define DEBUG_SECURITY 1
-
+#endif
+  
 #if defined (DEBUG_SECURITY)
 #undef msg
 #define msg printf
diff --git a/openair2/UTIL/LOG/log.h b/openair2/UTIL/LOG/log.h
index 7b6d41f7e0d0043da664924494b57cba6b042132..1d795740b673839bc46fc97960dd73c1e284e7b1 100644
--- a/openair2/UTIL/LOG/log.h
+++ b/openair2/UTIL/LOG/log.h
@@ -314,8 +314,8 @@ void *log_thread_function(void * list);
 /*   optname                              helpstr   paramflags    XXXptr	             defXXXval				      type	     numelt	*/
 /*--------------------------------------------------------------------------------------------------------------------------------------------------------------*/
 #define LOG_GLOBALPARAMS_DESC { \
-{LOG_CONFIG_STRING_GLOBAL_LOG_LEVEL,    NULL,	    0,  	 strptr:(char **)&gloglevel, defstrval:log_level_names[2].name,       TYPE_STRING,  sizeof(gloglevel)}, \
-{LOG_CONFIG_STRING_GLOBAL_LOG_VERBOSITY,NULL,	    0,  	 strptr:(char **)&glogverbo, defstrval:log_verbosity_names[2].name,   TYPE_STRING,  sizeof(glogverbo)}, \
+{LOG_CONFIG_STRING_GLOBAL_LOG_LEVEL,    NULL,	    0,  	 strptr:(char **)&gloglevel, defstrval:log_level_names[2].name,       TYPE_STRING,  0}, \
+{LOG_CONFIG_STRING_GLOBAL_LOG_VERBOSITY,NULL,	    0,  	 strptr:(char **)&glogverbo, defstrval:log_verbosity_names[2].name,   TYPE_STRING,  0}, \
 {LOG_CONFIG_STRING_GLOBAL_LOG_ONLINE,   NULL,	    0,  	 iptr:&(g_log->onlinelog),   defintval:1,                             TYPE_INT,      0,              }, \
 {LOG_CONFIG_STRING_GLOBAL_LOG_INFILE,   NULL,	    0,  	 iptr:&(g_log->filelog),     defintval:0,                             TYPE_INT,      0,              }, \
 }
diff --git a/targets/ARCH/COMMON/common_lib.h b/targets/ARCH/COMMON/common_lib.h
index 6214c81cc693b86c3de7235d4681c11bb22f2be7..2dc1650bfd719208ef5e182b0b79f76e5f12ff55 100644
--- a/targets/ARCH/COMMON/common_lib.h
+++ b/targets/ARCH/COMMON/common_lib.h
@@ -207,6 +207,15 @@ typedef struct {
   int iq_rxrescale;
   //! Configuration file for LMS7002M
   char *configFilename;
+#if defined(USRP_REC_PLAY)
+  unsigned short sf_mode;           // 1=record, 2=replay
+  char           sf_filename[1024]; // subframes file path
+  unsigned int   sf_max;            // max number of recorded subframes
+  unsigned int   sf_loops;          // number of loops in replay mode
+  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  
 } openair0_config_t;
 
 /*! \brief RF mapping */ 
diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp
index 30faf8d2b7aefc890973ee59da70274bd203dc0a..8b62a8e69855a36410e191c6832aa91009170906 100644
--- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp
+++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp
@@ -270,11 +270,53 @@ static int sync_to_gps(openair0_device *device)
     return EXIT_SUCCESS;
 }
 
+#if defined(USRP_REC_PLAY)
+#include "usrp_lib.h"
+static FILE    *pFile = NULL;
+int             mmapfd = 0;
+struct stat     sb;
+iqrec_t        *ms_sample = NULL;                      // memory for all subframes
+unsigned int    nb_samples = 0;
+unsigned int    cur_samples = 0;
+int64_t         wrap_count = 0;
+int64_t         wrap_ts = 0;
+unsigned int    u_sf_mode = 0;                         // 1=record, 2=replay
+unsigned int    u_sf_record = 0;                       // record mode
+unsigned int    u_sf_replay = 0;                       // replay mode
+char            u_sf_filename[1024];                   // subframes file path
+unsigned int    u_sf_max = DEF_NB_SF;                  // max number of recorded subframes
+unsigned int    u_sf_loops = DEF_SF_NB_LOOP;           // number of loops in replay mode
+unsigned int    u_sf_read_delay = DEF_SF_DELAY_READ;   // read delay in replay mode
+unsigned int    u_sf_write_delay = DEF_SF_DELAY_WRITE; // write delay in replay mode
+char           *tmp_filename[1];                       // use an array of pointer (libconfig does not seems to work with char array yet)
+
+char config_opt_sf_file[] = CONFIG_OPT_SF_FILE;
+char config_def_sf_file[] = DEF_SF_FILE;
+char config_hlp_sf_file[] = CONFIG_HLP_SF_FILE;
+char config_opt_sf_rec[] = CONFIG_OPT_SF_REC;
+char config_hlp_sf_rec[] = CONFIG_HLP_SF_REC;
+char config_opt_sf_rep[] = CONFIG_OPT_SF_REP;
+char config_hlp_sf_rep[] = CONFIG_HLP_SF_REP;
+char config_opt_sf_max[] = CONFIG_OPT_SF_MAX;
+char config_hlp_sf_max[] = CONFIG_HLP_SF_MAX;
+char config_opt_sf_loops[] = CONFIG_OPT_SF_LOOPS;
+char config_hlp_sf_loops[] = CONFIG_HLP_SF_LOOPS;
+char config_opt_sf_rdelay[] = CONFIG_OPT_SF_RDELAY;
+char config_hlp_sf_rdelay[] = CONFIG_HLP_SF_RDELAY;
+char config_opt_sf_wdelay[] = CONFIG_OPT_SF_WDELAY;
+char config_hlp_sf_wdelay[] = CONFIG_HLP_SF_WDELAY;
+
+#endif
+
 /*! \brief Called to start the USRP transceiver. Return 0 if OK, < 0 if error
     @param device pointer to the device structure specific to the RF hardware target
 */
 static int trx_usrp_start(openair0_device *device) {
 
+#if defined(USRP_REC_PLAY)
+    if (u_sf_mode != 2) { // not replay mode
+#endif      
+
     usrp_state_t *s = (usrp_state_t*)device->priv;
 
 
@@ -313,12 +355,21 @@ static int trx_usrp_start(openair0_device *device) {
     s->rx_count = 0;
     s->tx_count = 0;
     s->rx_timestamp = 0;
+#if defined(USRP_REC_PLAY)
+    }
+#endif      
     return 0;
 }
 /*! \brief Terminate operation of the USRP transceiver -- free all associated resources
  * \param device the hardware to use
  */
 static void trx_usrp_end(openair0_device *device) {
+#if defined(USRP_REC_PLAY) // For some ugly reason, this can be called several times...
+  static int done = 0;
+  if (done == 1) return;
+  done = 1;
+  if (u_sf_mode != 2) { // not subframes replay
+#endif  
     usrp_state_t *s = (usrp_state_t*)device->priv;
 
     s->rx_stream->issue_stream_cmd(uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS);
@@ -326,7 +377,45 @@ static void trx_usrp_end(openair0_device *device) {
     s->tx_md.end_of_burst = true;
     s->tx_stream->send("", 0, s->tx_md);
     s->tx_md.end_of_burst = false;
-
+#if defined(USRP_REC_PLAY)
+    }
+#endif
+#if defined(USRP_REC_PLAY)
+    if (u_sf_mode == 1) { // subframes store
+      pFile = fopen (u_sf_filename,"wb+");
+      if (pFile == NULL) {
+	std::cerr << "Cannot open " << u_sf_filename << std::endl;
+      } else {
+	unsigned int i = 0;
+	unsigned int modu = 0;
+	if ((modu = nb_samples % 10) != 0) {
+	  nb_samples -= modu; // store entire number of frames
+	}
+	std::cerr << "Writing " << nb_samples << " subframes to " << u_sf_filename << " ..." << std::endl;
+	for (i = 0; i < nb_samples; i++) {
+	  fwrite(ms_sample+i, sizeof(unsigned char), sizeof(iqrec_t), pFile);
+	}
+	fclose (pFile);
+	std::cerr << "File " << u_sf_filename << " closed." << std::endl;
+      }
+    }
+    if (u_sf_mode == 1) { // record
+      if (ms_sample != NULL) {
+	free((void*)ms_sample);
+	ms_sample = NULL;
+      }
+    }
+    if (u_sf_mode == 2) { // replay
+      if (ms_sample != MAP_FAILED) {
+	munmap(ms_sample, sb.st_size);
+	ms_sample = NULL;
+      }
+      if (mmapfd != 0) {
+	close(mmapfd);
+	mmapfd = 0;
+      }
+    }
+#endif    
 }
 
 /*! \brief Called to send samples to the USRP RF target
@@ -339,6 +428,9 @@ static void trx_usrp_end(openair0_device *device) {
 */
 static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps, int cc, int flags) {
   int ret=0;
+#if defined(USRP_REC_PLAY)
+  if (u_sf_mode != 2) { // not replay mode
+#endif    
   usrp_state_t *s = (usrp_state_t*)device->priv;
   
   int nsamps2;  // aligned to upper 32 or 16 byte boundary
@@ -405,6 +497,15 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp,
   
   if (ret != nsamps)
     LOG_E(PHY,"[xmit] tx samples %d != %d\n",ret,nsamps);
+#if defined(USRP_REC_PLAY)
+  } else {
+    struct timespec req;
+    req.tv_sec = 0;
+    req.tv_nsec = u_sf_write_delay * 1000;
+    nanosleep(&req, NULL);
+    ret = nsamps;
+  }
+#endif    
 
   return ret;
 }
@@ -421,9 +522,12 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp,
  * \returns the number of sample read
 */
 static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps, int cc) {
-    usrp_state_t *s = (usrp_state_t*)device->priv;
-    int samples_received=0,i,j;
-    int nsamps2;  // aligned to upper 32 or 16 byte boundary
+  usrp_state_t *s = (usrp_state_t*)device->priv;
+  int samples_received=0,i,j;
+  int nsamps2;  // aligned to upper 32 or 16 byte boundary
+#if defined(USRP_REC_PLAY)
+  if (u_sf_mode != 2) { // not replay mode
+#endif    
 #if defined(__x86_64) || defined(__i386__)
 #ifdef __AVX2__
     nsamps2 = (nsamps+7)>>3;
@@ -490,7 +594,45 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp
     s->rx_count += nsamps;
     s->rx_timestamp = s->rx_md.time_spec.to_ticks(s->sample_rate);
     *ptimestamp = s->rx_timestamp;
-    return samples_received;
+#if defined (USRP_REC_PLAY)
+  }
+#endif    
+#if defined(USRP_REC_PLAY)
+  if (u_sf_mode == 1) { // record mode
+    // Copy subframes to memory (later dump on a file)
+    if (nb_samples < u_sf_max) {
+      (ms_sample+nb_samples)->header = BELL_LABS_IQ_HEADER; 
+      (ms_sample+nb_samples)->ts = *ptimestamp;
+      memcpy((ms_sample+nb_samples)->samples, buff[0], nsamps*4);
+      nb_samples++;
+    }
+  } else if (u_sf_mode == 2) { // replay mode
+    if (cur_samples == nb_samples) {
+      cur_samples = 0;
+      wrap_count++;
+      if (wrap_count == u_sf_loops) {
+	std::cerr << "USRP device terminating subframes replay mode after " << u_sf_loops << " loops." << std::endl;
+	return 0; // should make calling process exit
+      }
+      wrap_ts = wrap_count * (nb_samples * (((int)(device->openair0_cfg[0].sample_rate)) / 1000));
+    }
+    if (cur_samples < nb_samples) {
+      *ptimestamp = (ms_sample[0].ts + (cur_samples * (((int)(device->openair0_cfg[0].sample_rate)) / 1000))) + wrap_ts;
+      if (cur_samples == 0) {
+	std::cerr << "starting subframes file with wrap_count=" << wrap_count << " wrap_ts=" << wrap_ts
+		  << " ts=" << *ptimestamp << std::endl;
+      }
+      memcpy(buff[0], &ms_sample[cur_samples].samples[0], nsamps*4);
+      cur_samples++;
+    }
+    struct timespec req;
+    req.tv_sec = 0;
+    req.tv_nsec = u_sf_read_delay * 1000;
+    nanosleep(&req, NULL);
+    return nsamps;
+  }
+#endif
+  return samples_received;
 }
 
 /*! \brief Compares two variables within precision
@@ -684,12 +826,135 @@ int trx_usrp_reset_stats(openair0_device* device) {
     return(0);
 }
 
+#if defined(USRP_REC_PLAY)
+extern "C" {
+/*! \brief Initializer for USRP record/playback config
+ * \param parameter array description
+ * \returns  0 on success
+ */
+int trx_usrp_recplay_config_init(paramdef_t *usrp_recplay_params) {
+    // --subframes-file
+    memcpy(usrp_recplay_params[0].optname, config_opt_sf_file, strlen(config_opt_sf_file));
+    usrp_recplay_params[0].helpstr = config_hlp_sf_file;
+    usrp_recplay_params[0].paramflags=PARAMFLAG_NOFREE;
+    usrp_recplay_params[0].strptr=(char **)&tmp_filename[0];
+    usrp_recplay_params[0].defstrval = NULL;
+    usrp_recplay_params[0].type=TYPE_STRING;
+    usrp_recplay_params[0].numelt=sizeof(u_sf_filename);
+    // --subframes-record
+    memcpy(usrp_recplay_params[1].optname, config_opt_sf_rec, strlen(config_opt_sf_rec));
+    usrp_recplay_params[1].helpstr = config_hlp_sf_rec;
+    usrp_recplay_params[1].paramflags=PARAMFLAG_BOOL;
+    usrp_recplay_params[1].uptr=&u_sf_record;
+    usrp_recplay_params[1].defuintval=0;
+    usrp_recplay_params[1].type=TYPE_UINT;
+    usrp_recplay_params[1].numelt=0;
+    // --subframes-replay
+    memcpy(usrp_recplay_params[2].optname, config_opt_sf_rep, strlen(config_opt_sf_rep));
+    usrp_recplay_params[2].helpstr = config_hlp_sf_rep;
+    usrp_recplay_params[2].paramflags=PARAMFLAG_BOOL;
+    usrp_recplay_params[2].uptr=&u_sf_replay;
+    usrp_recplay_params[2].defuintval=0;
+    usrp_recplay_params[2].type=TYPE_UINT;
+    usrp_recplay_params[2].numelt=0;
+    // --subframes-max
+    memcpy(usrp_recplay_params[3].optname, config_opt_sf_max, strlen(config_opt_sf_max));
+    usrp_recplay_params[3].helpstr = config_hlp_sf_max;
+    usrp_recplay_params[3].paramflags=0;
+    usrp_recplay_params[3].uptr=&u_sf_max;
+    usrp_recplay_params[3].defuintval=DEF_NB_SF;
+    usrp_recplay_params[3].type=TYPE_UINT;
+    usrp_recplay_params[3].numelt=0;
+    // --subframes-loops
+    memcpy(usrp_recplay_params[4].optname, config_opt_sf_loops, strlen(config_opt_sf_loops));
+    usrp_recplay_params[4].helpstr = config_hlp_sf_loops;
+    usrp_recplay_params[4].paramflags=0;
+    usrp_recplay_params[4].uptr=&u_sf_loops;
+    usrp_recplay_params[4].defuintval=DEF_SF_NB_LOOP;
+    usrp_recplay_params[4].type=TYPE_UINT;
+    usrp_recplay_params[4].numelt=0;
+    // --subframes-read-delay
+    memcpy(usrp_recplay_params[5].optname, config_opt_sf_rdelay, strlen(config_opt_sf_rdelay));
+    usrp_recplay_params[5].helpstr = config_hlp_sf_rdelay;
+    usrp_recplay_params[5].paramflags=0;
+    usrp_recplay_params[5].uptr=&u_sf_read_delay;
+    usrp_recplay_params[5].defuintval=DEF_SF_DELAY_READ;
+    usrp_recplay_params[5].type=TYPE_UINT;
+    usrp_recplay_params[5].numelt=0;
+    // --subframes-write-delay
+    memcpy(usrp_recplay_params[6].optname, config_opt_sf_wdelay, strlen(config_opt_sf_wdelay));
+    usrp_recplay_params[6].helpstr = config_hlp_sf_wdelay;
+    usrp_recplay_params[6].paramflags=0;
+    usrp_recplay_params[6].uptr=&u_sf_write_delay;
+    usrp_recplay_params[6].defuintval=DEF_SF_DELAY_WRITE;
+    usrp_recplay_params[6].type=TYPE_UINT;
+    usrp_recplay_params[6].numelt=0;
+
+    return 0; // always ok
+}
+}
+#endif
+
 extern "C" {
     /*! \brief Initialize Openair USRP target. It returns 0 if OK
     * \param device the hardware to use
          * \param openair0_cfg RF frontend parameters set by application
          */
     int device_init(openair0_device* device, openair0_config_t *openair0_cfg) {
+#if defined(USRP_REC_PLAY)
+      paramdef_t usrp_recplay_params[7];
+      // to check
+      static int done = 0;
+      if (done == 1) {
+	return 0;
+      } // prevent from multiple init
+      done = 1;
+      // end to check
+      memset(usrp_recplay_params, 0, 7*sizeof(paramdef_t));
+      memset(&u_sf_filename[0], 0, 1024);
+      tmp_filename[0] = u_sf_filename;
+      if (trx_usrp_recplay_config_init(usrp_recplay_params) != 0) {
+	std::cerr << "USRP device record/replay mode configuration error exiting" << std::endl;
+	return -1;
+      }
+      config_process_cmdline(usrp_recplay_params,sizeof(usrp_recplay_params)/sizeof(paramdef_t),NULL);
+
+      if (strlen(tmp_filename[0]) != 0) {
+	(void) strcpy(u_sf_filename, tmp_filename[0]);
+      } else {
+	(void) strcpy(u_sf_filename, DEF_SF_FILE);
+      }
+
+      if (u_sf_replay == 1) u_sf_mode = 2;
+      if (u_sf_record == 1) u_sf_mode = 1;
+      
+      if (u_sf_mode == 2) {
+	// Replay subframes from from file
+        int bw_gain_adjust=0;
+        device->openair0_cfg = openair0_cfg;
+	device->type = USRP_B200_DEV;
+	openair0_cfg[0].rx_gain_calib_table = calib_table_b210_38;
+	bw_gain_adjust=1;
+	openair0_cfg[0].tx_sample_advance     = 80;
+	openair0_cfg[0].tx_bw                 = 20e6;
+	openair0_cfg[0].rx_bw                 = 20e6;
+        openair0_cfg[0].iq_txshift = 4;//shift
+        openair0_cfg[0].iq_rxrescale = 15;//rescale iqs
+	set_rx_gain_offset(&openair0_cfg[0],0,bw_gain_adjust);
+        device->priv = NULL;
+        device->trx_start_func = trx_usrp_start;
+        device->trx_write_func = trx_usrp_write;
+        device->trx_read_func  = trx_usrp_read;
+        device->trx_get_stats_func = trx_usrp_get_stats;
+        device->trx_reset_stats_func = trx_usrp_reset_stats;
+        device->trx_end_func   = trx_usrp_end;
+        device->trx_stop_func  = trx_usrp_stop;
+        device->trx_set_freq_func = trx_usrp_set_freq;
+        device->trx_set_gains_func   = trx_usrp_set_gains;
+        device->openair0_cfg = openair0_cfg;
+	std::cerr << "USRP device initialized in subframes replay mode for " << u_sf_loops << " loops." << std::endl;
+      } else {
+#endif
         uhd::set_thread_priority_safe(1.0);
         usrp_state_t *s = (usrp_state_t*)calloc(sizeof(usrp_state_t),1);
         
@@ -705,6 +970,11 @@ extern "C" {
         int vers=0,subvers=0,subsubvers=0;
         int bw_gain_adjust=0;
 
+#if defined(USRP_REC_PLAY)
+	if (u_sf_mode == 1) {
+	  std::cerr << "USRP device initialized in subframes record mode" << std::endl;
+	}
+#endif	
         sscanf(uhd::get_version_string().c_str(),"%d.%d.%d",&vers,&subvers,&subsubvers);
         LOG_I(PHY,"Checking for USRPs : UHD %s (%d.%d.%d)\n",
               uhd::get_version_string().c_str(),vers,subvers,subsubvers);
@@ -742,7 +1012,9 @@ extern "C" {
             //s->usrp->set_master_clock_rate(usrp_master_clock);
 
             openair0_cfg[0].rx_gain_calib_table = calib_table_x310;
-
+#if defined(USRP_REC_PLAY)
+	    std::cerr << "-- Using calibration table: calib_table_x310" << std::endl; // Bell Labs info
+#endif	    
             switch ((int)openair0_cfg[0].sample_rate) {
             case 30720000:
                 // from usrp_time_offset
@@ -801,9 +1073,15 @@ extern "C" {
             if ((vers == 3) && (subvers == 9) && (subsubvers>=2)) {
                 openair0_cfg[0].rx_gain_calib_table = calib_table_b210;
                 bw_gain_adjust=0;
+#if defined(USRP_REC_PLAY)
+		std::cerr << "-- Using calibration table: calib_table_b210" << std::endl; // Bell Labs info
+#endif		
             } else {
                 openair0_cfg[0].rx_gain_calib_table = calib_table_b210_38;
                 bw_gain_adjust=1;
+#if defined(USRP_REC_PLAY)
+		std::cerr << "-- Using calibration table: calib_table_b210_38" << std::endl; // Bell Labs info
+#endif		
             }
 
             switch ((int)openair0_cfg[0].sample_rate) {
@@ -965,6 +1243,45 @@ extern "C" {
            } 
         }
  
+#if defined(USRP_REC_PLAY)
+      }
+#endif
+#if defined(USRP_REC_PLAY)
+      if (u_sf_mode == 1) { // record mode	
+	ms_sample = (iqrec_t*) malloc(u_sf_max * sizeof(iqrec_t));
+	if (ms_sample == NULL) {
+	  std::cerr<< "Memory allocation failed for subframe record or replay mode." << std::endl;
+	  exit(-1);
+	}
+	memset(ms_sample, 0, u_sf_max * BELL_LABS_IQ_BYTES_PER_SF);
+      }
+      if (u_sf_mode == 2) {
+	// use mmap
+	mmapfd = open(u_sf_filename, O_RDONLY | O_LARGEFILE);
+	if (mmapfd != 0) {
+	  fstat(mmapfd, &sb);
+	  std::cerr << "Loading subframes using mmap() from " << u_sf_filename << " size=" << (uint64_t)sb.st_size << " bytes ..." << std::endl;
+	  ms_sample = (iqrec_t*) mmap(NULL, sb.st_size, PROT_WRITE, MAP_PRIVATE, mmapfd, 0);
+	  if (ms_sample != MAP_FAILED) {
+	    nb_samples = (sb.st_size / sizeof(iqrec_t));
+	    int aligned = (((unsigned long)ms_sample & 31) == 0)? 1:0;
+	    std::cerr<< "Loaded "<< nb_samples << " subframes." << std::endl;
+	    if (aligned == 0) {
+	      std::cerr<< "mmap address is not 32 bytes aligned, exiting." << std::endl;
+	      close(mmapfd);
+	      exit(-1);
+	    }
+	  } else {
+	    std::cerr << "Cannot mmap file, exiting." << std::endl;
+	    close(mmapfd);
+	    exit(-1);
+	  }
+	} else {
+	    std::cerr << "Cannot open " << u_sf_filename << " , exiting." << std::endl;
+	    exit(-1);
+	}
+      }
+#endif	
         return 0;
     }
 }
diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.h b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.h
new file mode 100644
index 0000000000000000000000000000000000000000..47ba171f1b9805973d2076629037bb9e920d22c9
--- /dev/null
+++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.h
@@ -0,0 +1,89 @@
+#ifndef __USRP_LIB_H
+#define __USRP_LIB_H
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+
+/** usrp_lib.h
+ *
+ * \author: bruno.mongazon-cazavet@nokia-bell-labs.com
+ */
+
+#if defined (USRP_REC_PLAY)
+
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include "common/config/config_paramdesc.h"
+#include "common/config/config_userapi.h"
+
+#define BELL_LABS_IQ_HEADER       0xabababababababab
+#define BELL_LABS_IQ_PER_SF       7680 // Up to 5MHz bw for now
+#define BELL_LABS_IQ_BYTES_PER_SF (BELL_LABS_IQ_PER_SF * 4)
+typedef struct {
+  int64_t       header;
+  int64_t       ts;
+  int64_t       rfu1;
+  int64_t       rfu2; // pad for 256 bits alignement required by AVX2
+  unsigned char samples[BELL_LABS_IQ_BYTES_PER_SF]; // iq's for one subframe
+} iqrec_t;
+#define DEF_NB_SF           120000               // default nb of sf or ms to capture (2 minutes at 5MHz)
+#define DEF_SF_FILE         "/home/nokia/iqfile" // default subframes file name
+#define DEF_SF_DELAY_READ   400                  // default read delay  µs (860=real)
+#define DEF_SF_DELAY_WRITE  15                   // default write delay µs (15=real)
+#define DEF_SF_NB_LOOP      5                    // default nb loops
+
+
+/* help strings definition for command line options, used in CMDLINE_XXX_DESC macros and printed when -h option is used */
+#define CONFIG_HLP_SF_FILE      "Path of the file used for subframes record or replay"
+#define CONFIG_HLP_SF_REC       "Record subframes from USRP driver into a file for later replay"
+#define CONFIG_HLP_SF_REP       "Replay subframes into USRP driver from a file"
+#define CONFIG_HLP_SF_MAX       "Maximum count of subframes to be recorded in subframe file"
+#define CONFIG_HLP_SF_LOOPS     "Number of loops to replay of the entire subframes file"
+#define CONFIG_HLP_SF_RDELAY    "Delay in microseconds to read a subframe in replay mode"
+#define CONFIG_HLP_SF_WDELAY    "Delay in microseconds to write a subframe in replay mode"
+
+/* keyword strings for command line options, used in CMDLINE_XXX_DESC macros and printed when -h option is used */
+#define CONFIG_OPT_SF_FILE      "subframes-file"
+#define CONFIG_OPT_SF_REC       "subframes-record"
+#define CONFIG_OPT_SF_REP       "subframes-replay"
+#define CONFIG_OPT_SF_MAX       "subframes-max"
+#define CONFIG_OPT_SF_LOOPS     "subframes-loops"
+#define CONFIG_OPT_SF_RDELAY    "subframes-read-delay"
+#define CONFIG_OPT_SF_WDELAY    "subframes-write-delay"
+
+/* For information only - the macro is not usable in C++ */
+/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
+/*                                            command line parameters for USRP record/playback                                                                               */
+/*   optname                     helpstr                paramflags                      XXXptr                  defXXXval                            type           numelt   */
+/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
+#define USRP_RECPLAY_PARAMS_DESC {  \
+{"subframes-file",        	 CONFIG_HLP_SF_FILE,	0,		  strptr:(char **)&u_sf_filename,       defstrval:DEF_SF_FILE, 		   TYPE_STRING,   sizeof(u_sf_filename)}, \
+{"subframes-record",      	 CONFIG_HLP_SF_REC,	PARAMFLAG_BOOL,	  uptr:&u_sf_record,	                defuintval:0,			   TYPE_UINT,	  0}, \
+{"subframes-replay",      	 CONFIG_HLP_SF_REP,	PARAMFLAG_BOOL,	  uptr:&u_sf_replay,	                defuintval:0,			   TYPE_UINT,	  0}, \
+{"subframes-max",              	 CONFIG_HLP_SF_MAX,    	0,                uptr:&u_sf_max,			defintval:DEF_NB_SF,	       	   TYPE_UINT,	  0}, \
+{"subframes-loops",           	 CONFIG_HLP_SF_LOOPS,   0,                uptr:&u_sf_loops,			defintval:DEF_SF_NB_LOOP,	   TYPE_UINT,	  0}, \
+{"subframes-read-delay",         CONFIG_HLP_SF_RDELAY,  0,                uptr:&u_sf_read_delay,	      	defintval:DEF_SF_DELAY_READ,	   TYPE_UINT,	  0}, \
+{"subframes-write-delay",        CONFIG_HLP_SF_WDELAY,  0,                uptr:&u_sf_write_delay,		defintval:DEF_SF_DELAY_WRITE,	   TYPE_UINT,	  0}, \
+}
+#endif // BELL_LABS_MUST
+#endif // __USRP_LIB_H
+
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.oaisim.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.oaisim.conf
index af262223f01f574c3890062c85192e7fce2156d9..24ae36a0a4c7c671f0cc4ad4754f1d6b233397a6 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.oaisim.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.oaisim.conf
@@ -17,3 +17,20 @@ RUs = (
     }
 );  
 
+log_config = { 
+      global_log_level                      ="debug";
+      global_log_verbosity                  ="medium";
+      hw_log_level                          ="info";
+      hw_log_verbosity                      ="medium";
+      phy_log_level                         ="debug";
+      phy_log_verbosity                     ="medium";
+      mac_log_level                         ="debug";
+      mac_log_verbosity                     ="high";
+      rlc_log_level                         ="info";
+      rlc_log_verbosity                     ="medium";
+      pdcp_log_level                        ="info";
+      pdcp_log_verbosity                    ="medium";
+      rrc_log_level                         ="info";
+      rrc_log_verbosity                     ="medium";
+};
+
diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c
index 3dfa2f59366e14a1675aa23abfb3063b101b48d4..e90fc4335c5edd68369163e1cde3fcc9f474dc0b 100644
--- a/targets/RT/USER/lte-softmodem.c
+++ b/targets/RT/USER/lte-softmodem.c
@@ -227,6 +227,9 @@ threads_t threads= {-1,-1,-1,-1,-1,-1,-1};
  */
 uint8_t abstraction_flag=0;
 
+/* forward declarations */
+void set_default_frame_parms(LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]);
+
 /*---------------------BMC: timespec helpers -----------------------------*/
 
 struct timespec min_diff_time = { .tv_sec = 0, .tv_nsec = 0 };
@@ -593,10 +596,11 @@ static void get_options(void) {
 
   
   if (UE_flag > 0) {
+     uint8_t n_rb_dl;
      paramdef_t cmdline_uemodeparams[] =CMDLINE_UEMODEPARAMS_DESC;
      paramdef_t cmdline_ueparams[] =CMDLINE_UEPARAMS_DESC;
 
-
+     set_default_frame_parms(frame_parms);
 
      config_process_cmdline( cmdline_uemodeparams,sizeof(cmdline_uemodeparams)/sizeof(paramdef_t),NULL);
      config_process_cmdline( cmdline_ueparams,sizeof(cmdline_ueparams)/sizeof(paramdef_t),NULL);
@@ -606,22 +610,21 @@ static void get_options(void) {
   	  input_fd = fopen(loopfile,"r");
   	  AssertFatal(input_fd != NULL,"Please provide a valid input file\n");
       }
+
       if ( (cmdline_uemodeparams[CMDLINE_CALIBUERX_IDX].paramflags &  PARAMFLAG_PARAMSET) != 0) mode = rx_calib_ue;
       if ( (cmdline_uemodeparams[CMDLINE_CALIBUERXMED_IDX].paramflags &  PARAMFLAG_PARAMSET) != 0) mode = rx_calib_ue_med;
       if ( (cmdline_uemodeparams[CMDLINE_CALIBUERXBYP_IDX].paramflags &  PARAMFLAG_PARAMSET) != 0) mode = rx_calib_ue_byp;
-      if ( *(cmdline_uemodeparams[CMDLINE_DEBUGUEPRACH_IDX].uptr) > 0) mode = debug_prach;
-      if ( *(cmdline_uemodeparams[CMDLINE_NOL2CONNECT_IDX].uptr) > 0)  mode = no_L2_connect;
-      if ( *(cmdline_uemodeparams[CMDLINE_CALIBPRACHTX_IDX].uptr) > 0) mode = calib_prach_tx; 
+      if ( (cmdline_uemodeparams[CMDLINE_DEBUGUEPRACH_IDX].paramflags &  PARAMFLAG_PARAMSET) != 0) mode = debug_prach;
+      if ( (cmdline_uemodeparams[CMDLINE_NOL2CONNECT_IDX].paramflags &  PARAMFLAG_PARAMSET) != 0)  mode = no_L2_connect;
+      if ( (cmdline_uemodeparams[CMDLINE_CALIBPRACHTX_IDX].paramflags &  PARAMFLAG_PARAMSET) != 0) mode = calib_prach_tx; 
       if (dumpframe  > 0)  mode = rx_dump_frame;
       
       if ( downlink_frequency[0][0] > 0) {
-  	  for (CC_id=1; CC_id<MAX_NUM_CCs; CC_id++) {
-  	    downlink_frequency[CC_id][1] = downlink_frequency[0][0];
-  	    downlink_frequency[CC_id][2] = downlink_frequency[0][0];
-  	    downlink_frequency[CC_id][3] = downlink_frequency[0][0];
-  	    printf("Downlink for CC_id %d frequency set to %u\n", CC_id, downlink_frequency[CC_id][0]);
-  	  }
-      UE_scan=0;
+	printf("Downlink frequency set to %u\n", downlink_frequency[0][0]);
+	for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
+	  frame_parms[CC_id]->dl_CarrierFreq = downlink_frequency[0][0];
+	}
+	UE_scan=0;
       } 
 
       if (tddflag > 0) {
@@ -629,38 +632,38 @@ static void get_options(void) {
 	     frame_parms[CC_id]->frame_type = TDD;
       }
 
-      if (frame_parms[0]->N_RB_DL !=0) {
-  	  if ( frame_parms[0]->N_RB_DL < 6 ) {
-  	     frame_parms[0]->N_RB_DL = 6;
-  	     printf ( "%i: Invalid number of ressource blocks, adjusted to 6\n",frame_parms[0]->N_RB_DL);
-  	  }
-  	  if ( frame_parms[0]->N_RB_DL > 100 ) {
-  	     frame_parms[0]->N_RB_DL = 100;
-  	     printf ( "%i: Invalid number of ressource blocks, adjusted to 100\n",frame_parms[0]->N_RB_DL);
-  	  }
-  	  if ( frame_parms[0]->N_RB_DL > 50 && frame_parms[0]->N_RB_DL < 100 ) {
-  	     frame_parms[0]->N_RB_DL = 50;
-  	     printf ( "%i: Invalid number of ressource blocks, adjusted to 50\n",frame_parms[0]->N_RB_DL);
-  	  }
-  	  if ( frame_parms[0]->N_RB_DL > 25 && frame_parms[0]->N_RB_DL < 50 ) {
-  	     frame_parms[0]->N_RB_DL = 25;
-  	     printf ( "%i: Invalid number of ressource blocks, adjusted to 25\n",frame_parms[0]->N_RB_DL);
-  	  }
-  	  UE_scan = 0;
-  	  frame_parms[0]->N_RB_UL=frame_parms[0]->N_RB_DL;
-  	  for (CC_id=1; CC_id<MAX_NUM_CCs; CC_id++) {
-  	      frame_parms[CC_id]->N_RB_DL=frame_parms[0]->N_RB_DL;
-  	      frame_parms[CC_id]->N_RB_UL=frame_parms[0]->N_RB_UL;
-  	  }
+      if (n_rb_dl !=0) {
+	printf("NB_RB set to %d\n",n_rb_dl);
+	if ( n_rb_dl < 6 ) {
+	  n_rb_dl = 6;
+	  printf ( "%i: Invalid number of ressource blocks, adjusted to 6\n",n_rb_dl);
+	}
+	if ( n_rb_dl > 100 ) {
+	  n_rb_dl = 100;
+	  printf ( "%i: Invalid number of ressource blocks, adjusted to 100\n",n_rb_dl);
+	}
+	if ( n_rb_dl > 50 && n_rb_dl < 100 ) {
+	  n_rb_dl = 50;
+	  printf ( "%i: Invalid number of ressource blocks, adjusted to 50\n",n_rb_dl);
+	}
+	if ( n_rb_dl > 25 && n_rb_dl < 50 ) {
+	  n_rb_dl = 25;
+	  printf ( "%i: Invalid number of ressource blocks, adjusted to 25\n",n_rb_dl);
+	}
+	UE_scan = 0;
+	for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
+	  frame_parms[CC_id]->N_RB_DL=n_rb_dl;
+	  frame_parms[CC_id]->N_RB_UL=n_rb_dl;
+	}
       }
 
-
-      for (CC_id=1;CC_id<MAX_NUM_CCs;CC_id++) {
-  	    tx_max_power[CC_id]=tx_max_power[0];
-	    rx_gain[0][CC_id] = rx_gain[0][0];
-	    tx_gain[0][CC_id] = tx_gain[0][0];
+      for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
+	tx_max_power[CC_id]=tx_max_power[0];
+	rx_gain[0][CC_id] = rx_gain[0][0];
+	tx_gain[0][CC_id] = tx_gain[0][0];
       }
   } /* UE_flag > 0 */
+
 #if T_TRACER
   paramdef_t cmdline_ttraceparams[] =CMDLINE_TTRACEPARAMS_DESC ;
   config_process_cmdline( cmdline_ttraceparams,sizeof(cmdline_ttraceparams)/sizeof(paramdef_t),NULL);   
@@ -675,10 +678,11 @@ static void get_options(void) {
       NB_RU	  = RC.nb_RU;
       printf("Configuration: nb_rrc_inst %d, nb_L1_inst %d, nb_ru %d\n",NB_eNB_INST,RC.nb_L1_inst,NB_RU);
     }
-  } else if (UE_flag == 1 && (CONFIG_GETCONFFILE != NULL)) {
+  } else if (UE_flag == 1 && (!(CONFIG_ISFLAGSET(CONFIG_NOOOPT))) ) {
     // Here the configuration file is the XER encoded UE capabilities
     // Read it in and store in asn1c data structures
-    strcpy(uecap_xer,CONFIG_GETCONFFILE);
+    sprintf(uecap_xer,"%stargets/PROJECTS/GENERIC-LTE-EPC/CONF/UE_config.xml",getenv("OPENAIR_HOME"));
+    printf("%s\n",uecap_xer);
     uecap_xer_in=1;
   } /* UE with config file  */
 }
@@ -691,7 +695,7 @@ int T_dont_fork = 0;  /* default is to fork, see 'T_init' to understand */
 #endif
 
 
-void set_default_frame_parms(LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]);
+
 void set_default_frame_parms(LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]) {
 
   int CC_id;
@@ -728,11 +732,12 @@ void set_default_frame_parms(LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]) {
     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];
+//    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]);
+    frame_parms[CC_id]->dl_CarrierFreq=downlink_frequency[CC_id][0];
 
   }
 
@@ -905,14 +910,14 @@ int main( int argc, char **argv )
 
 
   // set default parameters
-  if (UE_flag == 1) set_default_frame_parms(frame_parms);
+  //if (UE_flag == 1) set_default_frame_parms(frame_parms);
 
   logInit();
 
   printf("Reading in command-line options\n");
 
   get_options (); 
-  if (CONFIG_ISFLAGSET(CONFIG_ABORT)) {
+  if (CONFIG_ISFLAGSET(CONFIG_ABORT) && UE_flag == 0) {
       fprintf(stderr,"Getting configuration failed\n");
       exit(-1);
   }
@@ -931,7 +936,7 @@ int main( int argc, char **argv )
     printf("configuring for UE\n");
 
     set_comp_log(HW,      LOG_DEBUG,  LOG_HIGH, 1);
-    set_comp_log(PHY,     LOG_DEBUG,   LOG_HIGH, 1);
+    set_comp_log(PHY,     LOG_INFO,   LOG_HIGH, 1);
     set_comp_log(MAC,     LOG_INFO,   LOG_HIGH, 1);
     set_comp_log(RLC,     LOG_INFO,   LOG_HIGH | FLAG_THREAD, 1);
     set_comp_log(PDCP,    LOG_INFO,   LOG_HIGH, 1);
@@ -1080,8 +1085,9 @@ int main( int argc, char **argv )
 	else if (frame_parms[CC_id]->N_RB_DL == 25)
 	  UE[CC_id]->N_TA_offset = 624/4;
       }
-      
+    init_openair0();      
     }
+
   }
 
   fill_modeled_runtime_table(runtime_phy_rx,runtime_phy_tx);
@@ -1130,8 +1136,6 @@ int main( int argc, char **argv )
   
   
 #if defined(ENABLE_ITTI)
-  
-  
   if ((UE_flag == 1)||
       (RC.nb_inst > 0))  {
     
@@ -1149,16 +1153,6 @@ int main( int argc, char **argv )
   }
 #endif
   
-  if (phy_test==0) {
-    if (UE_flag==1) {
-      printf("Filling UE band info\n");
-      fill_ue_band_info();
-      dl_phy_sync_success (0, 0, 0, 1);
-    } 
-  }
-  
-  
-  
   
   mlockall(MCL_CURRENT | MCL_FUTURE);
   
@@ -1225,14 +1219,18 @@ int main( int argc, char **argv )
   rt_sleep_ns(10*100000000ULL);
   
   
-  
-  
   // start the main threads
   if (UE_flag == 1) {
     int eMBMS_active = 0;
     init_UE(1,eMBMS_active,uecap_xer_in);
+
+    if (phy_test==0) {
+      printf("Filling UE band info\n");
+      fill_ue_band_info();
+      dl_phy_sync_success (0, 0, 0, 1);
+    }
+
     number_of_cards = 1;
-    
     for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
       PHY_vars_UE_g[0][CC_id]->rf_map.card=0;
       PHY_vars_UE_g[0][CC_id]->rf_map.chain=CC_id+chain_offset;
diff --git a/targets/RT/USER/lte-softmodem.h b/targets/RT/USER/lte-softmodem.h
index c0cc6ba77ca3b815c7193226bc367ac4a94a6789..44e35c88a385319e896142e77ec05d5a62a9eb01 100644
--- a/targets/RT/USER/lte-softmodem.h
+++ b/targets/RT/USER/lte-softmodem.h
@@ -65,7 +65,7 @@
 #define CONFIG_HLP_NOSNGLT       "Disables single-thread mode in lte-softmodem\n" 
 #define CONFIG_HLP_TADV          "Set timing_advance\n"
 #define CONFIG_HLP_DLF           "Set the downlink frequency for all component carriers\n"
-#define CONFIG_HLP_CHOFF         "Channel id offset"
+#define CONFIG_HLP_CHOFF         "Channel id offset\n"
 #define CONFIG_HLP_SOFTS         "Enable soft scope and L1 and L2 stats (Xforms)\n"
 #define CONFIG_HLP_EXMCAL        "Calibrate the EXMIMO borad, available files: exmimo2_2arxg.lime exmimo2_2brxg.lime \n"
 #define CONFIG_HLP_ITTIL         "Generate ITTI analyzser logs (similar to wireshark logs but with more details)\n"
@@ -127,7 +127,7 @@
 {"ue-nb-ant-tx",     	       CONFIG_HLP_UENANTT,    0,		u8ptr:&nb_antenna_tx,		    defuintval:1,   TYPE_UINT8,    0},     \
 {"ue-scan-carrier",  	       CONFIG_HLP_UESCAN,     PARAMFLAG_BOOL,	iptr:&UE_scan_carrier,  	    defintval:0,    TYPE_INT,	   0},     \
 {"ue-max-power",     	       NULL,		      0,		iptr:&(tx_max_power[0]),	    defintval:90,   TYPE_INT,	   0},     \
-{"r"  ,                        CONFIG_HLP_PRB,        0,                u8ptr:&(frame_parms[0]->N_RB_DL),   defintval:0,    TYPE_UINT8,    0},     \
+{"r"  ,                        CONFIG_HLP_PRB,        0,                u8ptr:&n_rb_dl,                     defintval:0,    TYPE_UINT8,    0},     \
 }
 
 
diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c
index cf0754f63d7d5fea1e8810f7c00cc7459e583a16..913ae958fc113af682b1ff17823e2f9bca898855 100644
--- a/targets/RT/USER/lte-ue.c
+++ b/targets/RT/USER/lte-ue.c
@@ -303,6 +303,7 @@ static void *UE_thread_synch(void *arg)
     } while (ind < sizeof(eutra_bands) / sizeof(eutra_bands[0]));
   
     if (found == 0) {
+      LOG_E(PHY,"Can't find EUTRA band for frequency %d",UE->frame_parms.dl_CarrierFreq);
       exit_fun("Can't find EUTRA band for frequency");
       return &UE_thread_synch_retval;
     }
diff --git a/targets/SIMU/USER/oaisim_functions.c b/targets/SIMU/USER/oaisim_functions.c
index dce104dc0afba2b16288141c66e996f1877684f5..778f250a78756553dbbb2b9f8bae429abc595d04 100644
--- a/targets/SIMU/USER/oaisim_functions.c
+++ b/targets/SIMU/USER/oaisim_functions.c
@@ -782,7 +782,10 @@ void get_simulation_options(int argc, char *argv[])
     }
   }
 
-  
+  if ( load_configmodule(argc,argv) == NULL) {
+    exit_fun("[SOFTMODEM] Error, configuration module init failed\n");
+  } 
+ 
   if (RC.config_file_name != NULL) {
     /* Read eNB configuration file */
     RCConfig();