diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt
index 6a5627b396e23f244b21b724257ff5ec679dee91..1e5f71b8ae7d9e4720192e8e212ea56de5ba8880 100644
--- a/cmake_targets/CMakeLists.txt
+++ b/cmake_targets/CMakeLists.txt
@@ -1949,6 +1949,8 @@ add_executable(lte-softmodem-stub
   ${OPENAIR_TARGETS}/COMMON/create_tasks.c
   ${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c
   ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c
+  ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/multicast_link.c
+  ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/socket.c
   ${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c
   ${OPENAIR_DIR}/common/utils/utils.c
   ${OPENAIR_DIR}/common/utils/system.c
diff --git a/nfapi/nfapi_pnf.c b/nfapi/nfapi_pnf.c
index 076707ee327bb83e099b2c192acdf096989e6dcd..7699440db85f0be5e5f6afa83230a6e189846ae9 100644
--- a/nfapi/nfapi_pnf.c
+++ b/nfapi/nfapi_pnf.c
@@ -645,7 +645,7 @@ int param_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi
 
   // P7 PNF Port
   nfapi_resp.nfapi_config.p7_pnf_port.tl.tag = NFAPI_NFAPI_P7_PNF_PORT_TAG;
-  nfapi_resp.nfapi_config.p7_pnf_port.value = 32123; // DJP - hard code alert!!!! FIXME TODO
+  nfapi_resp.nfapi_config.p7_pnf_port.value = 32123; // 32123; // DJP - hard code alert!!!! FIXME TODO
   nfapi_resp.num_tlv++;
 
   nfapi_pnf_param_resp(config, &nfapi_resp);
@@ -1326,7 +1326,7 @@ int start_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi
 
     p7_config->remote_p7_port = phy_info->remote_port;
     p7_config->remote_p7_addr = phy_info->remote_addr;
-    p7_config->local_p7_port = 32123; // DJP - good grief cannot seem to get the right answer phy_info->local_port;
+    p7_config->local_p7_port = 32123; //32123; // DJP - good grief cannot seem to get the right answer phy_info->local_port;
     //DJP p7_config->local_p7_addr = (char*)phy_info->local_addr.c_str();
     p7_config->local_p7_addr = phy_info->local_addr;
 
@@ -1353,6 +1353,7 @@ int start_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi
 
     if(phy_info->timing_info_mode & 0x2)
     {
+    	LOG_I(MAC, "Panos-D: Configure timing info aperiodic");
       p7_config->timing_info_mode_aperiodic = 1;
     }
 
@@ -1846,6 +1847,7 @@ void oai_subframe_ind(uint16_t sfn, uint16_t sf)
 	  //printf("Panos-D: oai_subframe_ind 1, buffer size:%d", p7_config_g->subframe_buffer_size);
 
 	  uint16_t sfn_sf_tx = sfn<<4 | sf;
+	  //LOG_I(MAC, " Panos-D: oai_subframe_ind SFN/SF: %d.%d, SFN_Tx: %d \n", sfn, sf, sfn_sf_tx);
 
     if ((sfn % 100 == 0) && sf==0)
     {
diff --git a/nfapi/nfapi_vnf.c b/nfapi/nfapi_vnf.c
index d987ad732b4a7d54ffb754b6d920e2325d1264c9..e694b6e609b589ac08839b5f74c41f8abadef557 100644
--- a/nfapi/nfapi_vnf.c
+++ b/nfapi/nfapi_vnf.c
@@ -1362,7 +1362,7 @@ void configure_nfapi_vnf(char *vnf_addr, int vnf_p5_port)
 
   vnf.p7_vnfs[0].timing_window = 32;
   vnf.p7_vnfs[0].periodic_timing_enabled = 1;
-  vnf.p7_vnfs[0].aperiodic_timing_enabled = 0;
+  vnf.p7_vnfs[0].aperiodic_timing_enabled = 1;
   vnf.p7_vnfs[0].periodic_timing_period = 10;
 
   vnf.p7_vnfs[0].config = nfapi_vnf_p7_config_create();
diff --git a/openair1/PHY/LTE_TRANSPORT/defs.h b/openair1/PHY/LTE_TRANSPORT/defs.h
index 8701bb8d061bb64b4967eb741aa9266b14603dd9..f3db52b18eddcd4dc27c753930139e2806180f24 100644
--- a/openair1/PHY/LTE_TRANSPORT/defs.h
+++ b/openair1/PHY/LTE_TRANSPORT/defs.h
@@ -930,6 +930,9 @@ typedef struct {
   uint32_t n_prime_PRB;
   /// m_nprime_PRB_PSSCH (36.213 14.1.3)
   uint32_t m_nprime_PRB_PSCCH;
+  /// payload length 
+  int payload_length;
+  /// pointer to payload
   uint8_t *payload;
 } SLSCH_t;
 
@@ -937,6 +940,26 @@ typedef struct {
 
 } SLDCH_t;
 
+#define TTI_SYNC 0
+#define SLSS 1
+#define SLDCH 2
+#define SLSCH 3
+
+typedef struct UE_tport_header_s {
+  int packet_type;
+  uint16_t absSF;
+} UE_tport_header_t;
+
+typedef struct UE_tport_s {
+  UE_tport_header_t header; 
+  union {
+    SLSS_t slss;
+    SLDCH_t sldch;
+    SLSCH_t slsch;
+  };
+  uint8_t payload[1500];  
+} UE_tport_t;
+
 #endif
 
 /**@}*/
diff --git a/openair1/PHY/LTE_TRANSPORT/prach.c b/openair1/PHY/LTE_TRANSPORT/prach.c
index 5f1b3ce448ae42cb905f2c0d6d26969e03ea94e5..e6b2720b7700206ff627b40259dda12419f8c61b 100644
--- a/openair1/PHY/LTE_TRANSPORT/prach.c
+++ b/openair1/PHY/LTE_TRANSPORT/prach.c
@@ -584,9 +584,12 @@ int is_prach_subframe0(LTE_DL_FRAME_PARMS *frame_parms,uint8_t prach_ConfigIndex
 }
 
 int is_prach_subframe(LTE_DL_FRAME_PARMS *frame_parms,uint32_t frame, uint8_t subframe) {
+
   
   uint8_t prach_ConfigIndex  = frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex;
+  //LOG_I(MAC, "Panos-D: is_prach_subframe 2 \n");
   int prach_mask             = is_prach_subframe0(frame_parms,prach_ConfigIndex,frame,subframe);
+  //LOG_I(MAC, "Panos-D: is_prach_subframe 3 \n");
 
 #ifdef Rel14
   int i;
@@ -596,6 +599,7 @@ int is_prach_subframe(LTE_DL_FRAME_PARMS *frame_parms,uint32_t frame, uint8_t su
       prach_mask|=(is_prach_subframe0(frame_parms,frame_parms->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[i],frame,subframe)<<(i+1));
   }
 #endif
+  //LOG_I(MAC, "Panos-D: is_prach_subframe 4 \n");
   return(prach_mask);
 }
 
diff --git a/openair1/PHY/LTE_TRANSPORT/proto.h b/openair1/PHY/LTE_TRANSPORT/proto.h
index 5f93b4e546a921672da761738d300532e6b126e6..5d7cae6c7c9a05534a809ac99f255af84ed8f142 100644
--- a/openair1/PHY/LTE_TRANSPORT/proto.h
+++ b/openair1/PHY/LTE_TRANSPORT/proto.h
@@ -1482,20 +1482,26 @@ uint8_t generate_dci_top_emul(PHY_VARS_eNB *phy_vars_eNB,
 /*! \brief Top-level generation route for Sidelink BCH,PSS and SSS
   \param ue pointer to UE descriptor
   \param slss pointer to SLSS configuration and payload
+  \param frame_tx Frame number
+  \param subframe_tx subframe number
 */
-void generate_slss(PHY_VARS_UE *ue,SLSS_t *slss);
+void generate_slss(PHY_VARS_UE *ue,SLSS_t *slss,int frame_tx,int subframe_tx);
 
 /*! \brief Top-level generation route for Sidelink Discovery Channel
   \param ue pointer to UE descriptor
   \param sldch pointer to SLDCH configuration and payload
+  \param frame_tx Frame number
+  \param subframe_tx subframe number
 */
-void generate_sldch(PHY_VARS_UE *ue,SLDCH_t *sldch);
+void generate_sldch(PHY_VARS_UE *ue,SLDCH_t *sldch,int frame_tx,int subframe_tx);
 
 /*! \brief Top-level generation route for Sidelink Shared Channel
   \param ue pointer to UE descriptor
   \param slsch pointer to SLSCH configuration and payload
+  \param frame_tx Frame number
+  \param subframe_tx subframe number
 */
-void generate_slsch(PHY_VARS_UE *ue,SLSCH_t *slss);
+void generate_slsch(PHY_VARS_UE *ue,SLSCH_t *slss,int frame_tx,int subframe_tx);
 
 void generate_64qam_table(void);
 void generate_16qam_table(void);
diff --git a/openair1/PHY/defs.h b/openair1/PHY/defs.h
index b6477af1de8f042012c4f72e4bb83ada952d896b..2082de7f52771030b60a51c0ab3baa9eb0174bce 100644
--- a/openair1/PHY/defs.h
+++ b/openair1/PHY/defs.h
@@ -1454,6 +1454,10 @@ typedef struct {
   time_stats_t tx_prach;
   time_stats_t timer_stats;
 
+  pthread_mutex_t timer_mutex;
+  pthread_cond_t timer_cond;
+  int instance_cnt_timer;
+
   /// RF and Interface devices per CC
 
   openair0_device rfdevice; 
@@ -1575,6 +1579,26 @@ static inline void wait_sync(char *thread_name) {
 
 }
 
+static inline int wakeup_thread(pthread_mutex_t *mutex,pthread_cond_t *cond,int *instance_cnt,char *name) {
+
+  if (pthread_mutex_lock(mutex) != 0) {
+    LOG_E( PHY, "error locking mutex for %s\n",name);
+    exit_fun("nothing to add");
+    return(-1);
+  }
+  *instance_cnt = *instance_cnt + 1;
+
+  // the thread can now be woken up
+  if (pthread_cond_signal(cond) != 0) {
+    LOG_E( PHY, "ERROR pthread_cond_signal\n");
+    exit_fun( "ERROR pthread_cond_signal" );
+    return(-1);
+  }
+  
+  pthread_mutex_unlock(mutex);
+  return(0);
+}
+
 static inline int wait_on_condition(pthread_mutex_t *mutex,pthread_cond_t *cond,int *instance_cnt,char *name) {
   if (pthread_mutex_lock(mutex) != 0) {
     LOG_E( PHY, "[SCHED][eNB] error locking mutex for %s\n",name);
diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c
index 961cfc7e7ffef94167ac03c34eeda8f73ca695b4..71b94499997a030c3382e6fb5a6220ae33c9b6f4 100644
--- a/openair1/SCHED/phy_procedures_lte_ue.c
+++ b/openair1/SCHED/phy_procedures_lte_ue.c
@@ -2379,13 +2379,13 @@ void phy_procedures_UE_SL_TX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc) {
   LOG_D(PHY,"****** start Sidelink TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, subframe_tx);
 
   // check for SLBCH/SLSS
-  if ((slss = ue_get_slss(ue->Mod_id,ue->CC_id,frame_tx,subframe_tx)) != NULL) generate_slss(ue,slss);
+  if ((slss = ue_get_slss(ue->Mod_id,ue->CC_id,frame_tx,subframe_tx)) != NULL) generate_slss(ue,slss,frame_tx,subframe_tx);
 
   // check for SLDCH
-  if ((sldch = ue_get_sldch(ue->Mod_id,ue->CC_id,frame_tx,subframe_tx)) != NULL) generate_sldch(ue,sldch);
+  if ((sldch = ue_get_sldch(ue->Mod_id,ue->CC_id,frame_tx,subframe_tx)) != NULL) generate_sldch(ue,sldch,frame_tx,subframe_tx);
 
   // check for SLSCH
-  if ((slsch = ue_get_slsch(ue->Mod_id,ue->CC_id,frame_tx,subframe_tx)) != NULL) generate_slsch(ue,slsch);
+  if ((slsch = ue_get_slsch(ue->Mod_id,ue->CC_id,frame_tx,subframe_tx)) != NULL) generate_slsch(ue,slsch,frame_tx,subframe_tx);
 
 }
 
diff --git a/openair2/LAYER2/MAC/ra_procedures.c b/openair2/LAYER2/MAC/ra_procedures.c
index ef19a4c532c0f14ff19e108c057a693fbf851479..b8d091800858e7a7b48c17a7b8eb55d7c7daced6 100644
--- a/openair2/LAYER2/MAC/ra_procedures.c
+++ b/openair2/LAYER2/MAC/ra_procedures.c
@@ -106,6 +106,7 @@ void get_prach_resources(module_id_t module_idP,
                          uint8_t first_Msg3,
                          RACH_ConfigDedicated_t *rach_ConfigDedicated)
 {
+	LOG_I(MAC, "Panos-D: get_prach_resources 1");
 
   uint8_t Msg3_size = UE_mac_inst[module_idP].RA_Msg3_size;
   PRACH_RESOURCES_t *prach_resources = &UE_mac_inst[module_idP].RA_prach_resources;
@@ -195,17 +196,20 @@ void get_prach_resources(module_id_t module_idP,
 
   if (first_Msg3 == 1) {
     if (noGroupB == 1) {
+    	LOG_I(MAC, "Panos-D: get_prach_resources 2");
       // use Group A procedure
       UE_mac_inst[module_idP].RA_prach_resources.ra_PreambleIndex  = (taus())%numberOfRA_Preambles;
       UE_mac_inst[module_idP].RA_prach_resources.ra_RACH_MaskIndex = 0;
       UE_mac_inst[module_idP].RA_usedGroupA = 1;
     } else if ((Msg3_size <messageSizeGroupA) ||
                (get_PL(module_idP,0,eNB_index) > PLThreshold)) {
+    	LOG_I(MAC, "Panos-D: get_prach_resources 3");
       // use Group A procedure
       UE_mac_inst[module_idP].RA_prach_resources.ra_PreambleIndex  = (taus())%sizeOfRA_PreamblesGroupA;
       UE_mac_inst[module_idP].RA_prach_resources.ra_RACH_MaskIndex = 0;
       UE_mac_inst[module_idP].RA_usedGroupA = 1;
     } else { // use Group B
+    	LOG_I(MAC, "Panos-D: get_prach_resources 4");
       UE_mac_inst[module_idP].RA_prach_resources.ra_PreambleIndex  = sizeOfRA_PreamblesGroupA +
         (taus())%(numberOfRA_Preambles - sizeOfRA_PreamblesGroupA);
       UE_mac_inst[module_idP].RA_prach_resources.ra_RACH_MaskIndex = 0;
@@ -246,6 +250,7 @@ void get_prach_resources(module_id_t module_idP,
 
   // choose RA-RNTI
   UE_mac_inst[module_idP].RA_prach_resources.ra_RNTI = 1 + t_id + 10*f_id;
+  LOG_I(MAC, "Panos-D: get_prach_resources 4");
 }
 
 void Msg1_transmitted(module_id_t module_idP,uint8_t CC_id,frame_t frameP, uint8_t eNB_id)
@@ -290,12 +295,13 @@ void Msg3_transmitted(module_id_t module_idP,uint8_t CC_id,frame_t frameP, uint8
 PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP,int CC_id,frame_t frameP, uint8_t eNB_indexP,sub_frame_t subframeP)
 {
 
-
+  LOG_I(MAC, "Panos-D: ue_get_rach 1");
   uint8_t                  Size               = 0;
   UE_MODE_t UE_mode;
   // Panos: Modification for phy_stub_ue operation
   if(nfapi_mode == 3) { // Panos: phy_stub_ue mode
 	  UE_mode = UE_mac_inst[module_idP].UE_mode[0];
+	  LOG_I(MAC, "Panos-D: ue_get_rach 2, E_mode: %d", UE_mode);
   }
   else { // Full stack mode
 	  UE_mode = get_ue_mode(module_idP,0,eNB_indexP);
@@ -315,13 +321,16 @@ PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP,int CC_id,frame_t frameP,
 	      "Transmission on secondary CCs is not supported yet\n");
 
   if (UE_mode == PRACH) {
+	  LOG_I(MAC, "Panos-D: ue_get_rach 3");
     if (UE_mac_inst[module_idP].radioResourceConfigCommon) {
       rach_ConfigCommon = &UE_mac_inst[module_idP].radioResourceConfigCommon->rach_ConfigCommon;
     } else {
+    	//AssertFatal(UE_mac_inst[module_idP].radioResourceConfigCommon!=NULL,"RadioResourceConfigCommon Null");
       return(NULL);
     }
 
     if (UE_mac_inst[module_idP].RA_active == 0) {
+    	LOG_I(MAC, "Panos-D: ue_get_rach 4");
       LOG_I(MAC,"RA not active\n");
       // check if RRC is ready to initiate the RA procedure
       Size = mac_rrc_data_req(module_idP,
@@ -339,7 +348,7 @@ PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP,int CC_id,frame_t frameP,
       LOG_I(MAC,"[UE %d] Frame %d: Requested RRCConnectionRequest, got %d bytes\n",module_idP,frameP,Size);
       
       if (Size>0) {
-	
+    	  LOG_I(MAC, "Panos-D: ue_get_rach 5");
 	UE_mac_inst[module_idP].RA_active                        = 1;
 	UE_mac_inst[module_idP].RA_PREAMBLE_TRANSMISSION_COUNTER = 1;
 	UE_mac_inst[module_idP].RA_Msg3_size                     = Size+sizeof(SCH_SUBHEADER_SHORT)+sizeof(SCH_SUBHEADER_SHORT);
diff --git a/openair2/LAYER2/MAC/ue_procedures.c b/openair2/LAYER2/MAC/ue_procedures.c
index df0df3572ff919cf5599b7433132514d3815d2d1..35b76a0650d7fd826ce7a61debcaac7252a20f20 100644
--- a/openair2/LAYER2/MAC/ue_procedures.c
+++ b/openair2/LAYER2/MAC/ue_procedures.c
@@ -139,7 +139,7 @@ void ue_init_mac(module_id_t module_idP)
 
   if(nfapi_mode == 3) {
 	  pthread_mutex_init(&UE_mac_inst[module_idP].UL_INFO_mutex,NULL);
-	  UE_mac_inst[module_idP].UE_mode[0] = PRACH;
+	  UE_mac_inst[module_idP].UE_mode[0] = NOT_SYNCHED; //PRACH;
 	  UE_mac_inst[module_idP].first_ULSCH_Tx =0;
 	  UE_mac_inst[module_idP].dl_config_req = NULL;
 	  UE_mac_inst[module_idP].ul_config_req = NULL;
@@ -2696,8 +2696,8 @@ SLSCH_t *ue_get_slsch(module_id_t module_idP,int CC_id,frame_t frameP,sub_frame_
     rlc_status = mac_rlc_status_ind(module_idP, 0x1234,0,frameP,subframeP,ENB_FLAG_NO,MBMS_FLAG_NO,
 				    3,
 				    0xFFFF);
-    if (rlc_status.bytes_in_buffer > 0) {
-      LOG_I(MAC,"Scheduling for %d bytes in Sidelink buffer\n",rlc_status.bytes_in_buffer);
+    if (rlc_status.bytes_in_buffer > 2) {
+      LOG_I(MAC,"SFN.SF %d.%d: Scheduling for %d bytes in Sidelink buffer\n",frameP,subframeP,rlc_status.bytes_in_buffer);
       // Fill in group id for off-network communications
       ue->sltx_active = 1;
     }
@@ -2707,34 +2707,42 @@ SLSCH_t *ue_get_slsch(module_id_t module_idP,int CC_id,frame_t frameP,sub_frame_
     // 10 PRBs, mcs 19
     int TBS = 4584/8;
     int req;
-
+    
+    
     rlc_status = mac_rlc_status_ind(module_idP, 0x1234,0,frameP,subframeP,ENB_FLAG_NO,MBMS_FLAG_NO,
 				    3,
 				    0xFFFF);
     if (TBS<=rlc_status.bytes_in_buffer) req=TBS;
     else req = rlc_status.bytes_in_buffer;
-
-    sdu_length = mac_rlc_data_req(module_idP,
-				  0x1234,
-				  0,
-				  frameP,
-				  ENB_FLAG_NO,
-				  MBMS_FLAG_NO,
-				  3,
-				  req,
-				  (char*)ue->slsch_pdu.payload);
-    LOG_I(MAC,"got %d bytes from Sidelink buffer (%d requested)\n",sdu_length,req);
-    if (sdu_length > 0) {
-      slsch->payload = (unsigned char*)ue->slsch_pdu.payload;
-      slsch->rvidx   = 0;
-      // fill in SLSCH configuration
-      return(&ue->slsch);
-    }
-    else { // handle retransmission of SDU
-      slsch->rvidx = rvtab[absSF&3];
-      return(&ue->slsch);
+    
+    if (req>0) {
+      sdu_length = mac_rlc_data_req(module_idP,
+				    0x1234,
+				    0,
+				    frameP,
+				    ENB_FLAG_NO,
+				    MBMS_FLAG_NO,
+				    3,				    
+				    req,
+				    (char*)ue->slsch_pdu.payload);
+      
+      if (sdu_length > 0) {
+	LOG_I(MAC,"SFN.SF %d.%d : got %d bytes from Sidelink buffer (%d requested)\n",frameP,subframeP,sdu_length,req);
+	slsch->payload = (unsigned char*)ue->slsch_pdu.payload;
+	slsch->rvidx   = 0;
+	slsch->payload_length = TBS;
+	// fill in SLSCH configuration
+	return(&ue->slsch);
+      }
+      else ue->sltx_active = 0;
     }
+
+  } else if ((absSF%40)>3 && ue->sltx_active == 1) { // handle retransmission of SDU
+    LOG_I(MAC,"SFN.SF %d.%d : retransmission\n",frameP,subframeP);
+    slsch->rvidx = rvtab[absSF&3];
+    return(&ue->slsch);
   }
+
   
   return(NULL);
 }
diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c
index 95a58e4ee7ac2c8d64f087fb22f62cdc0f8bf84c..7fd33d5a43c440920ed266b030f5b8099989d347 100644
--- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c
+++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c
@@ -893,7 +893,7 @@ pdcp_run (
   int           result;
   protocol_ctxt_t  ctxt;
 #endif
-
+  
   if (ctxt_pP->enb_flag) {
     start_meas(&eNB_pdcp_stats[ctxt_pP->module_id].pdcp_run);
   } else {
@@ -1720,7 +1720,7 @@ rrc_pdcp_config_req (
     }
 
     pdcp_p->first_missing_pdu = -1;
-    LOG_I(PDCP,PROTOCOL_PDCP_CTXT_FMT" Config request : Action ADD:  radio bearer id %d (already added) configured\n",
+    LOG_D(PDCP,PROTOCOL_PDCP_CTXT_FMT" Config request : Action ADD:  radio bearer id %d (already added) configured\n",
 	  PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP,pdcp_p),
 	  rb_idP);
     break;
@@ -1799,9 +1799,9 @@ rrc_pdcp_config_req (
         }
 
         pdcp_p->first_missing_pdu = -1;
-        LOG_I(PDCP,PROTOCOL_PDCP_CTXT_FMT" Inserting PDCP instance in collection key 0x%"PRIx64"\n",
+        LOG_D(PDCP,PROTOCOL_PDCP_CTXT_FMT" Inserting PDCP instance in collection key 0x%"PRIx64"\n",
               PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP,pdcp_p), key);
-        LOG_I(PDCP,PROTOCOL_PDCP_CTXT_FMT" Config request : Action ADD:  radio bearer id %d configured\n",
+        LOG_D(PDCP,PROTOCOL_PDCP_CTXT_FMT" Config request : Action ADD:  radio bearer id %d configured\n",
               PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP,pdcp_p),
               rb_idP);
       }
diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c
index 582fb0cb4e4da98dfd18466a5db13663fa321a8d..4733e247c0c69846a4b3fc23368ae303dc4e4bad 100644
--- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c
+++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c
@@ -686,12 +686,16 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const  ctxt_pP)
                     ctxt.module_id, ctxt.rnti, ctxt.enb_flag);
                 key = PDCP_COLL_KEY_DEFAULT_DRB_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag);
                 h_rc = hashtable_get(pdcp_coll_p, key, (void**)&pdcp_p);
+		LOG_I(PDCP,"request key %x : (%d,%x,%d,%d)\n",
+		      key,ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id);
               } else {
                 rab_id = rab_id % maxDRB;
                 LOG_I(PDCP, "PDCP_COLL_KEY_VALUE(module_id=%d, rnti=%x, enb_flag=%d, rab_id=%d, SRB_FLAG=%d)\n",
                     ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id, SRB_FLAG_NO);
                 key = PDCP_COLL_KEY_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id, SRB_FLAG_NO);
                 h_rc = hashtable_get(pdcp_coll_p, key, (void**)&pdcp_p);
+		LOG_I(PDCP,"request key %x : (%d,%x,%d,%d)\n",
+		      key,ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id);
               }
 
               if (h_rc == HASH_TABLE_OK) {
diff --git a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.c b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.c
index 2e1629f8c882b58d17a11579f03f017d1b93a8a9..7a9c0d38b51e331e43ecaa77f0d71b50597bd649 100644
--- a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.c
+++ b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.c
@@ -21,6 +21,7 @@
 
 #define RLC_UM_MODULE 1
 #define RLC_UM_C 1
+//#define TRACE_RLC_UM_PDU 1
 //-----------------------------------------------------------------------------
 //#include "rtos_header.h"
 #include "platform_types.h"
@@ -105,6 +106,7 @@ rlc_um_get_pdus (const protocol_ctxt_t* const ctxt_pP, void *argP)
     // establishment, the RLC entity:
     //   - is created; and
     //   - enters the DATA_TRANSFER_READY state.
+    LOG_D(RLC,"RLC-UM in RLC_NULL_STATE\n");
     break;
 
   case RLC_DATA_TRANSFER_READY_STATE:
@@ -125,6 +127,8 @@ rlc_um_get_pdus (const protocol_ctxt_t* const ctxt_pP, void *argP)
     // entity:
     // - enters the LOCAL_SUSPEND state.
 
+    LOG_D(RLC,"RLC-UM in RLC_DATA_TRANSFER_READY_STATE\n");
+
     // SEND DATA TO MAC
     if (rlc_p->tx_sn_length == 10) {
       rlc_um_segment_10 (ctxt_pP, rlc_p);
@@ -155,6 +159,9 @@ rlc_um_get_pdus (const protocol_ctxt_t* const ctxt_pP, void *argP)
     //   upper layers.
 
     // TO DO TAKE CARE OF SN : THE IMPLEMENTATION OF THIS FUNCTIONNALITY IS NOT CRITICAL
+
+    LOG_D(RLC,"RLC-UM in RLC_LOCAL_SUSPEND_STATE\n");
+
     break;
 
   default:
@@ -656,7 +663,6 @@ rlc_um_mac_data_request (const protocol_ctxt_t* const ctxt_pP, void *rlc_pP,cons
       memcpy(&msg_p->ittiMsg.rlc_um_data_pdu_req.text, message_string, message_string_size);
 
       itti_send_msg_to_task(TASK_UNKNOWN, ctxt_pP->instance, msg_p);
-
 # else
       LOG_T(RLC, "%s", message_string);
 # endif
@@ -776,7 +782,6 @@ rlc_um_data_req (const protocol_ctxt_t* const ctxt_pP, void *rlc_pP, mem_block_t
   memcpy(&msg_p->ittiMsg.rlc_um_sdu_req.text, message_string, message_string_size);
 
   itti_send_msg_to_task(TASK_UNKNOWN, ctxt_pP->instance, msg_p);
-
 #else
   LOG_T(RLC, "%s", message_string);
 #endif
@@ -785,7 +790,7 @@ rlc_um_data_req (const protocol_ctxt_t* const ctxt_pP, void *rlc_pP, mem_block_t
   rlc_p->buffer_occupancy += ((struct rlc_um_tx_sdu_management *) (sdu_pP->data))->sdu_size;
   list_add_tail_eurecom(sdu_pP, &rlc_p->input_sdus);
   RLC_UM_MUTEX_UNLOCK(&rlc_p->lock_input_sdus);
-#if DEBUG_RLC_CONGESTION
+#if 1//DEBUG_RLC_CONGESTION
 #if MESSAGE_CHART_GENERATOR
   if (rlc_p->buffer_occupancy > 4096) {
       MSC_LOG_EVENT((ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_RLC_ENB:MSC_RLC_UE,\
diff --git a/openair2/LAYER2/RLC/rlc_mac.c b/openair2/LAYER2/RLC/rlc_mac.c
index 904a714f5a2d5922b2ed8ab457f13a056d476e6b..642661c3f40b2d04b7a5d6cea9cfb4a71ab77662 100644
--- a/openair2/LAYER2/RLC/rlc_mac.c
+++ b/openair2/LAYER2/RLC/rlc_mac.c
@@ -37,7 +37,7 @@
 #include "assertions.h"
 #include "UTIL/LOG/vcd_signal_dumper.h"
 
-#define DEBUG_MAC_INTERFACE 1
+//#define DEBUG_MAC_INTERFACE 1
 
 //-----------------------------------------------------------------------------
 struct mac_data_ind mac_rlc_deserialize_tb (
@@ -143,7 +143,7 @@ tbs_size_t mac_rlc_data_req(
 
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_MAC_RLC_DATA_REQ,VCD_FUNCTION_IN);
 #ifdef DEBUG_MAC_INTERFACE
-  LOG_I(RLC, PROTOCOL_CTXT_FMT" MAC_RLC_DATA_REQ channel %d (%d) MAX RB %d, Num_tb %d\n",
+  LOG_D(RLC, PROTOCOL_CTXT_FMT" MAC_RLC_DATA_REQ channel %d (%d) MAX RB %d\n",
         PROTOCOL_CTXT_ARGS((&ctxt)),
         channel_idP,
         RLC_MAX_LC,
diff --git a/openair2/PHY_INTERFACE/phy_stub_UE.c b/openair2/PHY_INTERFACE/phy_stub_UE.c
index 2ea8bdaa6814e5ee9761d6653ba8c6ff4cefcccf..6d4b8034d4a0e3230c750f38006144a87d2ca69d 100644
--- a/openair2/PHY_INTERFACE/phy_stub_UE.c
+++ b/openair2/PHY_INTERFACE/phy_stub_UE.c
@@ -160,19 +160,30 @@ void fill_crc_indication_UE_MAC(int Mod_id,int frame,int subframe, UL_IND_t *UL_
 
 void fill_rach_indication_UE_MAC(int Mod_id,int frame,int subframe, UL_IND_t *UL_INFO, uint8_t ra_PreambleIndex, uint16_t ra_RNTI) {
 
+	//LOG_I(MAC, "Panos-D: fill_rach_indication_UE_MAC 1 \n");
 	pthread_mutex_lock(&UE_mac_inst[Mod_id].UL_INFO_mutex);
+	UL_INFO = (UL_IND_t*)malloc(sizeof(UL_IND_t));
 
+
+
+	//LOG_I(MAC, "Panos-D: fill_rach_indication_UE_MAC 2 \n");
 	    UL_INFO->rach_ind.rach_indication_body.number_of_preambles                 = 1;
+
 	    //eNB->UL_INFO.rach_ind.preamble_list                       = &eNB->preamble_list[0];
+	    UL_INFO->rach_ind.header.message_id                         = NFAPI_RACH_INDICATION;
+	    UL_INFO->rach_ind.sfn_sf                                    = frame<<4 | subframe;
+
 	    UL_INFO->rach_ind.rach_indication_body.tl.tag                              = NFAPI_RACH_INDICATION_BODY_TAG;
 
+
+	    UL_INFO->rach_ind.rach_indication_body.preamble_list = (nfapi_preamble_pdu_t*)malloc(UL_INFO->rach_ind.rach_indication_body.number_of_preambles*sizeof(nfapi_preamble_pdu_t));
 	    UL_INFO->rach_ind.rach_indication_body.preamble_list[0].preamble_rel8.tl.tag   		= NFAPI_PREAMBLE_REL8_TAG;
 	    UL_INFO->rach_ind.rach_indication_body.preamble_list[0].preamble_rel8.timing_advance = 0; //Panos: Not sure about that
 
 	    //Panos: The two following should get extracted from the call to get_prach_resources().
 	    UL_INFO->rach_ind.rach_indication_body.preamble_list[0].preamble_rel8.preamble = ra_PreambleIndex;
 	    UL_INFO->rach_ind.rach_indication_body.preamble_list[0].preamble_rel8.rnti 	  = ra_RNTI;
-	    UL_INFO->rach_ind.rach_indication_body.number_of_preambles++;
+	    //UL_INFO->rach_ind.rach_indication_body.number_of_preambles++;
 
 
 	    UL_INFO->rach_ind.rach_indication_body.preamble_list[0].preamble_rel13.rach_resource_type = 0;
@@ -200,8 +211,9 @@ void fill_rach_indication_UE_MAC(int Mod_id,int frame,int subframe, UL_IND_t *UL
 
 	          //Panos: This function is currently defined only in the nfapi-RU-RAU-split so we should call it when we merge
 	          // with that branch.
-	          //oai_nfapi_rach_ind(&rach_ind);
-
+	          oai_nfapi_rach_ind(&UL_INFO->rach_ind);
+	          free(UL_INFO->rach_ind.rach_indication_body.preamble_list);
+	          free(UL_INFO);
 
 	        //}
 	      pthread_mutex_unlock(&UE_mac_inst[Mod_id].UL_INFO_mutex);
@@ -477,12 +489,14 @@ void handle_nfapi_ul_pdu_UE_MAC(module_id_t Mod_id,
                          uint16_t frame,uint8_t subframe,uint8_t srs_present)
 {
   nfapi_ul_config_ulsch_pdu_rel8_t *rel8 = &ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8;
+  LOG_I(MAC, "Panos-D: handle_nfapi_ul_pdu_UE_MAC 1 \n");
 
   //int8_t UE_id;
 
   // check if we have received a dci for this ue and ulsch descriptor is configured
 
   if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_PDU_TYPE) {
+	  LOG_I(MAC, "Panos-D: handle_nfapi_ul_pdu_UE_MAC 2.1 \n");
     //AssertFatal((UE_id = find_ulsch(ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.rnti,eNB,SEARCH_EXIST_OR_FREE))>=0,
     //            "No existing UE ULSCH for rnti %x\n",rel8->rnti);
     LOG_D(PHY,"Applying UL config for UE, rnti %x for frame %d, subframe %d\n",
@@ -494,7 +508,8 @@ void handle_nfapi_ul_pdu_UE_MAC(module_id_t Mod_id,
     uint8_t access_mode=SCHEDULED_ACCESS;
     if(buflen>0){
     	if(UE_mac_inst[Mod_id].first_ULSCH_Tx == 1){ // Msg3 case
-    		fill_crc_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, 0);
+    		LOG_I(MAC, "Panos-D: handle_nfapi_ul_pdu_UE_MAC 2.2 \n");
+    		//fill_crc_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, 0);
     		fill_rx_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, UE_mac_inst[Mod_id].RA_prach_resources.Msg3,buflen, rnti);
     		Msg3_transmitted(Mod_id, 0, frame, 0);
 
@@ -502,14 +517,16 @@ void handle_nfapi_ul_pdu_UE_MAC(module_id_t Mod_id,
     		//UE_mac_inst[Mod_id].first_ULSCH_Tx = 0;
     	}
     	else {
+    		LOG_I(MAC, "Panos-D: handle_nfapi_ul_pdu_UE_MAC 2.3 \n");
     		ue_get_sdu( Mod_id, 0, frame, subframe, 0, ulsch_buffer, buflen, &access_mode);
-    		fill_crc_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, 0);
+    		//fill_crc_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, 0);
     		fill_rx_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, ulsch_buffer,buflen, rnti);
     	}
     }
   }
 
   else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE) {
+	  LOG_I(MAC, "Panos-D: handle_nfapi_ul_pdu_UE_MAC 3 \n");
     //AssertFatal((UE_id = find_ulsch(ul_config_pdu->ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti,eNB,SEARCH_EXIST_OR_FREE))>=0,
     //            "No available UE ULSCH for rnti %x\n",ul_config_pdu->ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti);
 	  uint8_t ulsch_buffer[5477] __attribute__ ((aligned(32)));
@@ -537,6 +554,7 @@ void handle_nfapi_ul_pdu_UE_MAC(module_id_t Mod_id,
 
   }
   else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE) {
+	  LOG_I(MAC, "Panos-D: handle_nfapi_ul_pdu_UE_MAC 4 \n");
     //AssertFatal((UE_id = find_ulsch(ul_config_pdu->ulsch_cqi_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti,
     //                                eNB,SEARCH_EXIST_OR_FREE))>=0,
     //            "No available UE ULSCH for rnti %x\n",ul_config_pdu->ulsch_cqi_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti);
@@ -562,6 +580,7 @@ void handle_nfapi_ul_pdu_UE_MAC(module_id_t Mod_id,
 
   }
   else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE) {
+	  LOG_I(MAC, "Panos-D: handle_nfapi_ul_pdu_UE_MAC 5 \n");
     //AssertFatal((UE_id = find_ulsch(ul_config_pdu->ulsch_cqi_harq_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti,
     //                                eNB,SEARCH_EXIST_OR_FREE))>=0,
     //            "No available UE ULSCH for rnti %x\n",ul_config_pdu->ulsch_cqi_harq_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti);
@@ -592,6 +611,7 @@ void handle_nfapi_ul_pdu_UE_MAC(module_id_t Mod_id,
 
   }
   else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE) {
+	  LOG_I(MAC, "Panos-D: handle_nfapi_ul_pdu_UE_MAC 6 \n");
   //  AssertFatal((UE_id = find_uci(ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.rnti,
   //                                proc->frame_tx,proc->subframe_tx,eNB,SEARCH_EXIST_OR_FREE))>=0,
   //              "No available UE UCI for rnti %x\n",ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.rnti);
@@ -612,6 +632,7 @@ void handle_nfapi_ul_pdu_UE_MAC(module_id_t Mod_id,
     AssertFatal(1==0,"NFAPI_UL_CONFIG_UCI_CQI_SR_PDU_TYPE not handled yet\n");
   }
   else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE) {
+	  LOG_I(MAC, "Panos-D: handle_nfapi_ul_pdu_UE_MAC 7 \n");
     //AssertFatal((UE_id = find_uci(ul_config_pdu->uci_sr_pdu.ue_information.ue_information_rel8.rnti,
     //                              proc->frame_tx,proc->subframe_tx,eNB,SEARCH_EXIST_OR_FREE))>=0,
     //            "No available UE UCI for rnti %x\n",ul_config_pdu->uci_sr_pdu.ue_information.ue_information_rel8.rnti);
@@ -621,6 +642,7 @@ void handle_nfapi_ul_pdu_UE_MAC(module_id_t Mod_id,
 
   }
   else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE) {
+	  LOG_I(MAC, "Panos-D: handle_nfapi_ul_pdu_UE_MAC 8 \n");
     //AssertFatal((UE_id = find_uci(rel8->rnti,proc->frame_tx,proc->subframe_tx,eNB,SEARCH_EXIST_OR_FREE))>=0,
     //            "No available UE UCI for rnti %x\n",ul_config_pdu->uci_sr_harq_pdu.ue_information.ue_information_rel8.rnti);
 
@@ -683,18 +705,20 @@ int ul_config_req_UE_MAC(nfapi_ul_config_request_t* req)
 
   module_id_t Mod_id = 0; //Panos: Currently static (only for one UE) but this should change.
   nfapi_ul_config_request_pdu_t* ul_config_pdu_list = req->ul_config_request_body.ul_config_pdu_list;
+  LOG_I(MAC, "Panos-D: ul_config_req_UE_MAC 1 \n");
 
   //Panos: Not sure whether we should put the memory allocation here.
   //*** Note we should find the right place to call free(UL_INFO).
   UL_INFO = (UL_IND_t*)malloc(sizeof(UL_IND_t));
 
   //Panos: Additional checks needed here to check if the UE is in PRACH mode.
-  uint8_t is_rach = req->ul_config_request_body.rach_prach_frequency_resources;
+
+  /*uint8_t is_rach = req->ul_config_request_body.rach_prach_frequency_resources;
   if(is_rach && UE_mac_inst[Mod_id].UE_mode[0] == PRACH) {
 	  PRACH_RESOURCES_t *prach_resources = ue_get_rach(Mod_id, 0, sfn, 0, sf);
 	  fill_rach_indication_UE_MAC(Mod_id, sfn ,sf, UL_INFO, prach_resources->ra_PreambleIndex, prach_resources->ra_RNTI);
 	  Msg1_transmitted(Mod_id, 0, sfn, 0);
-  }
+  }*/
 
 
   // subframe works off TX SFN/SF which is 4 ahead, need to put it back to RX SFN/SF
@@ -705,31 +729,34 @@ int ul_config_req_UE_MAC(nfapi_ul_config_request_t* req)
   //subtract_subframe(&sfn, &sf, 4);
 
 
+
   for (int i=0;i<req->ul_config_request_body.number_of_pdus;i++)
   {
     //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() sfn/sf:%d PDU[%d] size:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(req->sfn_sf), i, ul_config_pdu_list[i].pdu_size);
 
+	LOG_I(MAC, "Panos-D: ul_config_req_UE_MAC 2.0 \n");
     if (
-        ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_PDU_TYPE ||
-        ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE ||
-        ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE ||
-        ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE ||
-        ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE ||
-        ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE ||
-        ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE
+    		req->ul_config_request_body.ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_PDU_TYPE ||
+    		req->ul_config_request_body.ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE ||
+    		req->ul_config_request_body.ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE ||
+    		req->ul_config_request_body.ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE ||
+    		req->ul_config_request_body.ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE ||
+    		req->ul_config_request_body.ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE ||
+    		req->ul_config_request_body.ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE
        )
     {
       //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() handle_nfapi_ul_pdu() for PDU:%d\n", __FUNCTION__, i);
 
-
-      handle_nfapi_ul_pdu_UE_MAC(Mod_id,&ul_config_pdu_list[i],sfn,sf,req->ul_config_request_body.srs_present);
-      free(UL_INFO);
+    	LOG_I(MAC, "Panos-D: ul_config_req_UE_MAC 2.1 \n");
+      handle_nfapi_ul_pdu_UE_MAC(Mod_id,&req->ul_config_request_body.ul_config_pdu_list[i],sfn,sf,req->ul_config_request_body.srs_present);
+      LOG_I(MAC, "Panos-D: ul_config_req_UE_MAC 3 \n");
     }
     else
     {
       //NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() PDU:%i UNKNOWN type :%d\n", __FUNCTION__, i, ul_config_pdu_list[i].pdu_type);
     }
   }
+  free(UL_INFO);
 
   return 0;
 }
@@ -746,7 +773,7 @@ int tx_req_UE_MAC(nfapi_tx_request_t* req)
 
   LOG_D(PHY,"%s() SFN/SF:%d/%d PDUs:%d\n", __FUNCTION__, sfn, sf, req->tx_request_body.number_of_pdus);
 
-  LOG_I(MAC, "Panos-D: tx_req_UE_MAC 1 \n");
+  //LOG_I(MAC, "Panos-D: tx_req_UE_MAC 1 \n");
   //printf("Panos-D: tx_req_UE_MAC 1 \n");
   //if (req->tx_request_body.tl.tag==NFAPI_TX_REQUEST_BODY_TAG)
   //{
@@ -774,7 +801,8 @@ int tx_req_UE_MAC(nfapi_tx_request_t* req)
 
 int dl_config_req_UE_MAC(nfapi_dl_config_request_t* req)
 {
-	LOG_I(MAC, "Panos-D: dl_config_req_UE_MAC 1 \n");
+	if (req!=NULL && tx_request_pdu_list!=NULL){
+	//LOG_I(MAC, "Panos-D: dl_config_req_UE_MAC 1 \n");
   int sfn = NFAPI_SFNSF2SFN(req->sfn_sf);
   int sf = NFAPI_SFNSF2SF(req->sfn_sf);
   module_id_t Mod_id = 0; //Panos: Currently static (only for one UE) but this should change.
@@ -799,7 +827,8 @@ int dl_config_req_UE_MAC(nfapi_dl_config_request_t* req)
   for (int i=0;i<req->dl_config_request_body.number_pdu;i++)
   {
     //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() sfn/sf:%d PDU[%d] size:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(req->sfn_sf), i, dl_config_pdu_list[i].pdu_size);
-	  LOG_E(MAC, "%s() sfn/sf:%d PDU[%d] size:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(req->sfn_sf), i, dl_config_pdu_list[i].pdu_size);
+	  LOG_E(MAC, "dl_config_req_UE_MAC 2 Received real ones: sfn/sf:%d.%d PDU[%d] size:%d\n", sfn, sf, i, dl_config_pdu_list[i].pdu_size);
+
     if (dl_config_pdu_list[i].pdu_type == NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE)
     {
 		if (dl_config_pdu_list[i].dci_dl_pdu.dci_dl_pdu_rel8.rnti_type == 1) {
@@ -807,6 +836,7 @@ int dl_config_req_UE_MAC(nfapi_dl_config_request_t* req)
 			dl_config_pdu_tmp = &dl_config_pdu_list[i+1];
 			if (dl_config_pdu_tmp->pdu_type == NFAPI_DL_CONFIG_DLSCH_PDU_TYPE){
 				if(tx_request_pdu_list + dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index!= NULL){
+					LOG_E(MAC, "dl_config_req_UE_MAC 2 Received data: sfn/sf:%d PDU[%d] size:%d\n", NFAPI_SFNSF2DEC(req->sfn_sf), i, dl_config_pdu_list[i].pdu_size);
 					ue_send_sdu(Mod_id, 0, sfn, sf,
 							tx_request_pdu_list[dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index].segments[0].segment_data,
 							tx_request_pdu_list[dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index].segments[0].segment_length,
@@ -822,8 +852,8 @@ int dl_config_req_UE_MAC(nfapi_dl_config_request_t* req)
 			dl_config_pdu_tmp = &dl_config_pdu_list[i+1];
 			if(dl_config_pdu_tmp->pdu_type == NFAPI_DL_CONFIG_DLSCH_PDU_TYPE && dl_config_pdu_list[i].dci_dl_pdu.dci_dl_pdu_rel8.rnti == 0xFFFF){
 				//pdu = Tx_req->tx_request_body.tx_pdu_list[dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index].segments[0].segment_data;
-				LOG_D(PHY,"%s() [PDU:%d] NFAPI_DL_CONFIG_DLSCH_PDU_TYPE TX:%d/%d RX:%d/%d transport_blocks:%d pdu_index:%d sdu:%p\n",
-				            __FUNCTION__, i, sfn, sf, sfn, sf, dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.transport_blocks, dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index, tx_request_pdu_list[dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index].segments[0].segment_data);
+				LOG_E(MAC,"dl_config_req_UE_MAC 3 Received SI: [PDU:%d] NFAPI_DL_CONFIG_DLSCH_PDU_TYPE TX:%d/%d RX:%d/%d transport_blocks:%d pdu_index:%d sdu:%p\n",
+				            i, sfn, sf, sfn, sf, dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.transport_blocks, dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index, tx_request_pdu_list[dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index].segments[0].segment_data);
 				if(tx_request_pdu_list + dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index!= NULL){
 					ue_decode_si(Mod_id, 0, sfn, 0,
 							tx_request_pdu_list[dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index].segments[0].segment_data,
@@ -843,7 +873,7 @@ int dl_config_req_UE_MAC(nfapi_dl_config_request_t* req)
 			}
 			else if(dl_config_pdu_tmp->pdu_type == NFAPI_DL_CONFIG_DLSCH_PDU_TYPE) {
 				// RA-RNTI case
-
+				LOG_E(MAC,"dl_config_req_UE_MAC 4 Received RAR? \n");
 				// RNTI parameter not actually used. Provided only to comply with existing function definition.
 				// Not sure about parameters to fill the preamble index.
 				//rnti_t c_rnti = UE_mac_inst[Mod_id].crnti;
@@ -851,7 +881,7 @@ int dl_config_req_UE_MAC(nfapi_dl_config_request_t* req)
 				if ((UE_mac_inst[Mod_id].UE_mode[0] != PUSCH) &&
 				  (UE_mac_inst[Mod_id].RA_prach_resources.Msg3!=NULL) &&
 				  (tx_request_pdu_list + dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index!= NULL)) {
-
+					LOG_E(MAC,"dl_config_req_UE_MAC 5 Received RAR \n");
 					ue_process_rar(Mod_id, 0, sfn,
 							ra_rnti, //RA-RNTI
 							tx_request_pdu_list[dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index].segments[0].segment_data,
@@ -873,7 +903,12 @@ int dl_config_req_UE_MAC(nfapi_dl_config_request_t* req)
     	// BCH case
     	// Last parameter is 1 if first time synchronization and zero otherwise. Not sure which value to put
     	// for our case.
+    	LOG_E(MAC,"dl_config_req_UE_MAC 4 Received MIB: sfn/sf: %d.%d \n", sfn, sf);
     	dl_phy_sync_success(Mod_id,sfn,0, 0);
+    	if(UE_mac_inst[Mod_id].UE_mode[0] == NOT_SYNCHED){
+    		LOG_E(MAC,"dl_config_req_UE_MAC 5 Received MIB: UE_mode: %d\n", UE_mac_inst[Mod_id].UE_mode[0]);
+    		UE_mac_inst[Mod_id].UE_mode[0]=PRACH;
+    	}
 
     }
 
@@ -887,11 +922,26 @@ int dl_config_req_UE_MAC(nfapi_dl_config_request_t* req)
   if(req->vendor_extension)
     free(req->vendor_extension);
 
-  /*if(tx_request_pdu_list)
-	  free(tx_request_pdu_list);
-  free(req);*/
+  /*if(req->vendor_extension!=NULL){
+    free(req->vendor_extension);
+    req->vendor_extension = NULL;
+  }*/
 
+  if(tx_request_pdu_list!=NULL){
+	  free(tx_request_pdu_list);
+  	  tx_request_pdu_list = NULL;
+  }
+  free(req);
+  req = NULL;
   return 0;
+	}
+	else {
+		return -1;
+	}
+
+
+
+
 }
 
 
@@ -957,12 +1007,16 @@ int memcpy_dl_config_req (nfapi_pnf_p7_config_t* pnf_p7, nfapi_dl_config_request
 	UE_mac_inst[Mod_id].dl_config_req = (nfapi_dl_config_request_t*)malloc(sizeof(nfapi_dl_config_request_t));
 	LOG_I(MAC, "Panos-D: memcpy_dl_config_req 1 \n");
 
-	/*if(req->header!=NULL){
-		UE_mac_inst[Mod_id].dl_config_req->header = req->header;
-	}*/
 
+	//UE_mac_inst[Mod_id].dl_config_req->header = req->header;
 	UE_mac_inst[Mod_id].dl_config_req->sfn_sf = req->sfn_sf;
+	//vendor_extension = &UE_mac_inst[Mod_id].dl_config_req->vendor_extension;
+	//vendor_extension->tag = req->vendor_extension.tag;
+	//vendor_extension->length = req->vendor_extension.length;
+
 	UE_mac_inst[Mod_id].dl_config_req->vendor_extension = req->vendor_extension;
+	//UE_mac_inst[Mod_id].dl_config_req->vendor_extension.tag = req->vendor_extension.tag;
+	//UE_mac_inst[Mod_id].dl_config_req->vendor_extension.length = req->vendor_extension.length;
 
 	UE_mac_inst[Mod_id].dl_config_req->dl_config_request_body.number_dci = req->dl_config_request_body.number_dci;
 	UE_mac_inst[Mod_id].dl_config_req->dl_config_request_body.number_pdcch_ofdm_symbols = req->dl_config_request_body.number_pdcch_ofdm_symbols;
@@ -982,25 +1036,53 @@ int memcpy_dl_config_req (nfapi_pnf_p7_config_t* pnf_p7, nfapi_dl_config_request
 
 int memcpy_ul_config_req (nfapi_pnf_p7_config_t* pnf_p7, nfapi_ul_config_request_t* req)
 {
+	LOG_I(MAC, "Panos-D: memcpy_ul_config_req 1 \n");
+
 	module_id_t Mod_id = 0; //Panos: Currently static (only for one UE) but this should change.
-	UE_mac_inst[Mod_id].ul_config_req = req;
+
+	UE_mac_inst[Mod_id].ul_config_req = (nfapi_ul_config_request_t*)malloc(sizeof(nfapi_ul_config_request_t));
+	//UE_mac_inst[Mod_id].ul_config_req->header = req->header;
+	UE_mac_inst[Mod_id].ul_config_req->sfn_sf = req->sfn_sf;
+	UE_mac_inst[Mod_id].ul_config_req->vendor_extension = req->vendor_extension;
+	//UE_mac_inst[Mod_id].ul_config_req->vendor_extension->tag = req->vendor_extension.tag;
+	//UE_mac_inst[Mod_id].ul_config_req->vendor_extension->length = req->vendor_extension.length;
+
+	LOG_I(MAC, "Panos-D: memcpy_ul_config_req SFN_SF: MINE: %d \n", UE_mac_inst[Mod_id].ul_config_req->sfn_sf);
+	LOG_I(MAC, "Panos-D: memcpy_ul_config_req SFN_SF: REQ: %d \n", req->sfn_sf);
+
+	UE_mac_inst[Mod_id].ul_config_req->ul_config_request_body.number_of_pdus = req->ul_config_request_body.number_of_pdus;
+	UE_mac_inst[Mod_id].ul_config_req->ul_config_request_body.rach_prach_frequency_resources = req->ul_config_request_body.rach_prach_frequency_resources;
+	UE_mac_inst[Mod_id].ul_config_req->ul_config_request_body.srs_present = req->ul_config_request_body.srs_present;
+	UE_mac_inst[Mod_id].ul_config_req->ul_config_request_body.tl = req->ul_config_request_body.tl;
+
+	LOG_I(MAC, "Panos-D: memcpy_ul_config_req 1 #ofULPDUs: %d \n", UE_mac_inst[Mod_id].ul_config_req->ul_config_request_body.number_of_pdus); //req->ul_config_request_body.number_of_pdus);
+	UE_mac_inst[Mod_id].ul_config_req->ul_config_request_body.ul_config_pdu_list = (nfapi_ul_config_request_pdu_t*) malloc(req->ul_config_request_body.number_of_pdus*sizeof(nfapi_ul_config_request_pdu_t));
+	for(int i=0; i<UE_mac_inst[Mod_id].ul_config_req->ul_config_request_body.number_of_pdus; i++) {
+			UE_mac_inst[Mod_id].ul_config_req->ul_config_request_body.ul_config_pdu_list[i] = req->ul_config_request_body.ul_config_pdu_list[i];
+			LOG_I(MAC, "Panos-D: memcpy_ul_config_req TAG MINE: %d \n", UE_mac_inst[Mod_id].ul_config_req->ul_config_request_body.ul_config_pdu_list[i].pdu_type);
+			LOG_I(MAC, "Panos-D: memcpy_ul_config_req TAG REQ: %d \n", req->ul_config_request_body.ul_config_pdu_list[i].pdu_type);
+		}
+
+
+	//UE_mac_inst[Mod_id].ul_config_req = req;
 	return 0;
 }
 
 int memcpy_tx_req (nfapi_pnf_p7_config_t* pnf_p7, nfapi_tx_request_t* req)
 {
-	LOG_I(MAC, "Panos-D: memcpy_tx_req 1, req->tx_request_body.number_of_pdus: %d \n", req->tx_request_body.number_of_pdus);
-	LOG_I(MAC, "Panos-D: memcpy_tx_req 1, req->tx_request_body.tx_pdu_list[i].pdu_length: %d \n", req->tx_request_body.tx_pdu_list[0].pdu_length);
-	LOG_I(MAC, "Panos-D: memcpy_tx_req 1, req->tx_request_body.tx_pdu_list[i].pdu_index: %d \n", req->tx_request_body.tx_pdu_list[0].pdu_index);
-	LOG_I(MAC, "Panos-D: memcpy_tx_req 1, req->tx_request_body.tx_pdu_list[i].num_segments: %d \n", req->tx_request_body.tx_pdu_list[0].num_segments);
-	LOG_I(MAC, "Panos-D: memcpy_tx_req 1, req->tx_request_body.tx_pdu_list[i].segments[j].segment_data: %d \n", *req->tx_request_body.tx_pdu_list[0].segments[0].segment_data);
+	module_id_t Mod_id = 0; //Panos: Currently static (only for one UE) but this should change.
+	//LOG_I(MAC, "Panos-D: memcpy_tx_req 1, req->tx_request_body.number_of_pdus: %d \n", req->tx_request_body.number_of_pdus);
+	//LOG_I(MAC, "Panos-D: memcpy_tx_req 1, req->tx_request_body.tx_pdu_list[i].pdu_length: %d \n", req->tx_request_body.tx_pdu_list[0].pdu_length);
+	//LOG_I(MAC, "Panos-D: memcpy_tx_req 1, req->tx_request_body.tx_pdu_list[i].pdu_index: %d \n", req->tx_request_body.tx_pdu_list[0].pdu_index);
+	//LOG_I(MAC, "Panos-D: memcpy_tx_req 1, req->tx_request_body.tx_pdu_list[i].num_segments: %d \n", req->tx_request_body.tx_pdu_list[0].num_segments);
+	//LOG_I(MAC, "Panos-D: memcpy_tx_req 1, req->tx_request_body.tx_pdu_list[i].segments[j].segment_data: %d \n", *req->tx_request_body.tx_pdu_list[0].segments[0].segment_data);
 	//printf("Panos-D: memcpy_tx_req 1, req->tx_request_body.number_of_pdus: %d \n", req->tx_request_body.number_of_pdus);
 	//printf("Panos-D: memcpy_tx_req 1, req->tx_request_body.tx_pdu_list[i].pdu_length: %d \n", req->tx_request_body.tx_pdu_list[0].pdu_length);
 	//printf("Panos-D: memcpy_tx_req 1, req->tx_request_body.tx_pdu_list[i].pdu_index: %d \n", req->tx_request_body.tx_pdu_list[0].pdu_index);
 	//printf("Panos-D: memcpy_tx_req 1, req->tx_request_body.tx_pdu_list[i].num_segments: %d \n", req->tx_request_body.tx_pdu_list[0].num_segments);
 	//printf("Panos-D: memcpy_tx_req 1, req->tx_request_body.tx_pdu_list[i].segments[j].segment_data: %d \n", *req->tx_request_body.tx_pdu_list[0].segments[0].segment_data);
 
-	module_id_t Mod_id = 0; //Panos: Currently static (only for one UE) but this should change.
+
 
 	int num_elem = req->tx_request_body.number_of_pdus;
 	tx_request_pdu_list = (nfapi_tx_request_pdu_t*) malloc(num_elem*sizeof(nfapi_tx_request_pdu_t));
diff --git a/openair2/RRC/LITE/defs.h b/openair2/RRC/LITE/defs.h
index e7806df03869644fded19edcad1bb5c8d982a0f8..18defaec825f2dcb2b3a28d06d9d52689e19c8db 100644
--- a/openair2/RRC/LITE/defs.h
+++ b/openair2/RRC/LITE/defs.h
@@ -746,6 +746,11 @@ typedef struct UE_RRC_INST_s {
   /* Used integrity/ciphering algorithms */
   CipheringAlgorithm_r12_t                          ciphering_algorithm;
   e_SecurityAlgorithmConfig__integrityProtAlgorithm integrity_algorithm;
+
+#ifdef Rel14
+  /// Used for Sidelink Preconfiguration
+  DRB_ToAddModList_t *DRB_configList;
+#endif
 } UE_RRC_INST;
 
 #include "proto.h"
diff --git a/openair2/RRC/LITE/rrc_UE.c b/openair2/RRC/LITE/rrc_UE.c
index de9bc7bcb4a90a0e234d1464c9091fb02c03e88e..3a44791f1d2f00fea2a7ff9c9e33142118a329ae 100644
--- a/openair2/RRC/LITE/rrc_UE.c
+++ b/openair2/RRC/LITE/rrc_UE.c
@@ -360,23 +360,86 @@ void init_SL_preconfig(UE_RRC_INST *UE, const uint8_t eNB_index )
   // Rel13 extensions
   UE->SL_Preconfiguration[eNB_index]->ext1 = NULL;
 
-  // Establish a SLRB (using DRB for now)
+  // Establish a SLRB (using DRB 3 for now)
   protocol_ctxt_t ctxt;
   PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, ENB_FLAG_NO, 0x1234, 0, 0,0);
 
-  rrc_pdcp_config_req (&ctxt,SRB_FLAG_NO, CONFIG_ACTION_ADD,
-                       3, UNDEF_SECURITY_MODE);
+  UE->DRB_config[0][0] = CALLOC(1,sizeof(struct DRB_ToAddMod));
+  UE->DRB_config[0][0]->eps_BearerIdentity = CALLOC(1, sizeof(long));
+  UE->DRB_config[0][0]->drb_Identity =  3;
+  UE->DRB_config[0][0]->eps_BearerIdentity = CALLOC(1, sizeof(long));
+  // allowed value 5..15, value : x+4
+  *(UE->DRB_config[0][0]->eps_BearerIdentity) = 3;
+  UE->DRB_config[0][0]->logicalChannelIdentity = CALLOC(1, sizeof(long));
+  *(UE->DRB_config[0][0]->logicalChannelIdentity) = UE->DRB_config[0][0]->drb_Identity; //(long) (ue_context_pP->ue_context.e_rab[i].param.e_rab_id + 2); // value : x+2
+  
+
+
+
+  struct RLC_Config                  *DRB_rlc_config                   = CALLOC(1,sizeof(struct RLC_Config));
+  struct PDCP_Config                 *DRB_pdcp_config                  = CALLOC(1,sizeof(struct PDCP_Config));
+  struct PDCP_Config__rlc_UM         *PDCP_rlc_UM                      = CALLOC(1,sizeof(struct PDCP_Config__rlc_UM));
+  struct LogicalChannelConfig        *DRB_lchan_config                 = CALLOC(1,sizeof(struct LogicalChannelConfig));
+  struct LogicalChannelConfig__ul_SpecificParameters
+    *DRB_ul_SpecificParameters                                         = CALLOC(1, sizeof(struct LogicalChannelConfig__ul_SpecificParameters));
+  long                               *logicalchannelgroup_drb          = CALLOC(1, sizeof(long));
+
+  DRB_rlc_config->present = RLC_Config_PR_um_Bi_Directional;
+  DRB_rlc_config->choice.um_Bi_Directional.ul_UM_RLC.sn_FieldLength = SN_FieldLength_size10;
+  DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.sn_FieldLength = SN_FieldLength_size10;
+  DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.t_Reordering = T_Reordering_ms35;
+  UE->DRB_config[0][0]->rlc_Config = DRB_rlc_config;
+
+  DRB_pdcp_config = CALLOC(1, sizeof(*DRB_pdcp_config));
+  UE->DRB_config[0][0]->pdcp_Config = DRB_pdcp_config;
+  DRB_pdcp_config->discardTimer = CALLOC(1, sizeof(long));
+  *DRB_pdcp_config->discardTimer = PDCP_Config__discardTimer_infinity;
+  DRB_pdcp_config->rlc_AM = NULL;
+  DRB_pdcp_config->rlc_UM = NULL;
+
+  /* avoid gcc warnings */
+  (void)PDCP_rlc_UM;
+
+  DRB_pdcp_config->rlc_UM = PDCP_rlc_UM;
+  PDCP_rlc_UM->pdcp_SN_Size = PDCP_Config__rlc_UM__pdcp_SN_Size_len12bits;
+  DRB_pdcp_config->headerCompression.present = PDCP_Config__headerCompression_PR_notUsed;
+
+  UE->DRB_config[0][0]->logicalChannelConfig = DRB_lchan_config;
+  DRB_ul_SpecificParameters = CALLOC(1, sizeof(*DRB_ul_SpecificParameters));
+  DRB_lchan_config->ul_SpecificParameters = DRB_ul_SpecificParameters;
 
-  rlc_info_t rlc_info;
+  DRB_ul_SpecificParameters->priority = 12;    // lower priority than srb1, srb2 and other dedicated bearer
+  DRB_ul_SpecificParameters->prioritisedBitRate =LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps8 ;
+    //LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity;
+  DRB_ul_SpecificParameters->bucketSizeDuration =
+    LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50;
 
-  rlc_info.rlc_mode = RLC_MODE_UM;
-  rlc_info.rlc.rlc_um_info.timer_reordering = 5;
-  rlc_info.rlc.rlc_um_info.sn_field_length = 10;
-  rlc_info.rlc.rlc_um_info.is_mXch = 0;
+  // LCG for DTCH can take the value from 1 to 3 as defined in 36331: normally controlled by upper layers (like RRM)
 
-  rrc_rlc_config_req(&ctxt,SRB_FLAG_NO,MBMS_FLAG_NO,CONFIG_ACTION_ADD,
-		     3,
-		     rlc_info);
+  *logicalchannelgroup_drb = 1;
+  DRB_ul_SpecificParameters->logicalChannelGroup = logicalchannelgroup_drb;
+
+  UE->DRB_configList = CALLOC(1,sizeof(DRB_ToAddModList_t));
+  ASN_SEQUENCE_ADD(&UE->DRB_configList->list,UE->DRB_config[0][0]);
+
+  rrc_pdcp_config_asn1_req(&ctxt,
+			   (SRB_ToAddModList_t *) NULL,
+			   UE->DRB_configList,
+			   (DRB_ToReleaseList_t*) NULL,
+			   0xff, NULL, NULL, NULL
+#if defined(Rel10) || defined(Rel14)
+                           , (PMCH_InfoList_r9_t *) NULL
+#endif
+                           ,NULL);	   
+  
+  rrc_rlc_config_asn1_req(&ctxt,
+			  (SRB_ToAddModList_t*)NULL,
+			  UE->DRB_configList,
+			  (DRB_ToReleaseList_t*)NULL
+#if defined(Rel10) || defined(Rel14)
+			  ,(PMCH_InfoList_r9_t *)NULL
+#endif
+			  );
 }
 
 #endif
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/oaiL1.nfapi.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/oaiL1.nfapi.usrpb210.conf
index 801f43908444b531294d13fea33cf2575687d4c1..b13962aee90335a968e72b594dc5b02b20edbaf6 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/oaiL1.nfapi.usrpb210.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/oaiL1.nfapi.usrpb210.conf
@@ -35,9 +35,12 @@ L1s = (
     	{
 	num_cc = 1;
 	tr_n_preference = "nfapi";
-      	local_n_if_name  = "enp0s31f6";
-      	remote_n_address = "10.0.0.2";
-    	local_n_address  = "10.0.0.1";
+      	#local_n_if_name  = "enp0s31f6";
+      	#remote_n_address = "10.0.0.2";
+    	#local_n_address  = "10.0.0.1";
+    	local_n_if_name  = "lo";
+      	remote_n_address = "127.0.0.2";
+    	local_n_address  = "127.0.0.1";
     	local_n_portc    = 50000;
     	remote_n_portc   = 50001;
     	local_n_portd    = 50010;
diff --git a/targets/RT/USER/lte-softmodem-stub.c b/targets/RT/USER/lte-softmodem-stub.c
index 467e3c00cffe0daf5b6478383abaa72fedc57aa1..3e62bc68f9578c111a2b53cc6f59fe9c37f573cd 100644
--- a/targets/RT/USER/lte-softmodem-stub.c
+++ b/targets/RT/USER/lte-softmodem-stub.c
@@ -992,9 +992,9 @@ int main( int argc, char **argv )
 
     set_comp_log(HW,      LOG_INFO,  LOG_HIGH, 1);
     set_comp_log(PHY,     LOG_INFO,   LOG_HIGH, 1);
-    set_comp_log(MAC,     LOG_TRACE,   LOG_HIGH, 1);
-    set_comp_log(RLC,     LOG_TRACE,   LOG_HIGH | FLAG_THREAD, 1);
-    set_comp_log(PDCP,    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_DEBUG,   LOG_HIGH, 1);
     set_comp_log(OTG,     LOG_INFO,   LOG_HIGH, 1);
     set_comp_log(RRC,     LOG_INFO,   LOG_HIGH, 1);
 #if defined(ENABLE_ITTI)
@@ -1356,6 +1356,8 @@ int main( int argc, char **argv )
     	}
     // Panos: Call init_UE_stub instead of init_UE as we are always on nfapi_mode=3
     //phy_stub_ticking = (SF_ticking*)malloc(sizeof(SF_ticking));
+
+
     init_timer_thread();
     init_UE_stub(1,eMBMS_active,uecap_xer_in);
 
diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c
index 5e64b01426b29347e209a1a5569741148402d8ed..0c14d93e76bb53d75becc695bfad18dfabda1539 100644
--- a/targets/RT/USER/lte-ue.c
+++ b/targets/RT/USER/lte-ue.c
@@ -81,6 +81,8 @@ void init_UE_stub(int nb_inst,int,int);
 extern void oai_subframe_ind(uint16_t sfn, uint16_t sf);
 //extern int tx_req_UE_MAC1();
 
+void ue_stub_rx_handler(unsigned int, char *);
+
 int32_t **rxdata;
 int32_t **txdata;
 
@@ -270,9 +272,7 @@ void init_UE(int nb_inst,int eMBMS_active, int uecap_xer_in) {
 
 void init_UE_stub(int nb_inst,int eMBMS_active, int uecap_xer_in) {
 
-  PHY_VARS_UE *UE;
   int         inst;
-  //int         ret;
 
   LOG_I(PHY,"UE : Calling Layer 2 for initialization\n");
 
@@ -287,33 +287,13 @@ void init_UE_stub(int nb_inst,int eMBMS_active, int uecap_xer_in) {
 
     LOG_I(PHY,"Intializing UE Threads for instance %d (%p,%p)...\n",inst,PHY_vars_UE_g[inst],PHY_vars_UE_g[inst][0]);
     init_UE_threads_stub(inst);
-    UE = PHY_vars_UE_g[inst][0];
-
-    /*if (oaisim_flag == 0) {
-      ret = openair0_device_load(&(UE->rfdevice), &openair0_cfg[0]);
-      if (ret !=0){
-      exit_fun("Error loading device library");
-      }
-      }*/
-    //UE->rfdevice.host_type = RAU_HOST;
-    //    UE->rfdevice.type      = NONE_DEV;
-
-    /*PHY_VARS_UE *UE = PHY_vars_UE_g[inst][0];
-      AssertFatal(0 == pthread_create(&UE->proc.pthread_ue,
-      &UE->proc.attr_ue,
-      UE_thread,
-      (void*)UE), "");*/
   }
 
   printf("UE threads created \n");
-#if 0
-#if defined(ENABLE_USE_MME)
-  extern volatile int start_UE;
-  while (start_UE == 0) {
-    sleep(1);
-  }
-#endif
-#endif
+
+  multicast_link_start(ue_stub_rx_handler,0,"lo");
+
+
 }
 
 
@@ -772,7 +752,24 @@ static void *UE_thread_rxn_txnp4(void *arg) {
 
 
 
+unsigned int emulator_absSF;
+
+void ue_stub_rx_handler(unsigned int num_bytes, char *rx_buffer) {
+
+  PHY_VARS_UE *UE;
+  UE = PHY_vars_UE_g[0][0];
+
+  LOG_I(PHY,"Received %d bytes on UE-UE link, packet type %d\n",num_bytes,((UE_tport_header_t*)rx_buffer)->packet_type);
 
+  switch (((UE_tport_header_t*)rx_buffer)->packet_type) {
+  case TTI_SYNC:
+    emulator_absSF = ((UE_tport_header_t*)rx_buffer)->absSF;
+    wakeup_thread(&UE->timer_mutex,&UE->timer_cond,&UE->instance_cnt_timer,"timer_thread");
+    break;
+  case SLSCH:
+    break;
+  }
+}
 
 /*!
  * \brief This is the UE thread for RX subframe n and TX subframe n+4.
@@ -783,12 +780,17 @@ static void *UE_thread_rxn_txnp4(void *arg) {
  */
 
 static void *UE_phy_stub_thread_rxn_txnp4(void *arg) {
+
   module_id_t Mod_id = 0;
   static __thread int UE_thread_rxtx_retval;
   struct rx_tx_thread_data *rtd = arg;
   UE_rxtx_proc_t *proc = rtd->proc;
   PHY_VARS_UE    *UE   = rtd->UE;
   int ret;
+  //  double t_diff;
+
+  char threadname[256];
+  sprintf(threadname,"UE_%d_proc", UE->Mod_id);
 
   // Panos: Call (Sched_Rsp_t) get_nfapi_sched_response(UE->Mod_ID) to get all
   //sched_response config messages which concern the specific UE. Inside this
@@ -799,41 +801,32 @@ static void *UE_phy_stub_thread_rxn_txnp4(void *arg) {
   phy_stub_ticking->ticking_var = -1;
   proc->subframe_rx=proc->sub_frame_start;
 
-  char threadname[256];
-  sprintf(threadname,"UE_%d_proc_%d", UE->Mod_id, proc->sub_frame_start);
-  cpu_set_t cpuset;
-  CPU_ZERO(&cpuset);
-
-  if ( (proc->sub_frame_start+1)%RX_NB_TH == 0 && threads.one != -1 )
-    CPU_SET(threads.one, &cpuset);
-  if ( (proc->sub_frame_start+1)%RX_NB_TH == 1 && threads.two != -1 )
-    CPU_SET(threads.two, &cpuset);
-  if ( (proc->sub_frame_start+1)%RX_NB_TH == 2 && threads.three != -1 )
-    CPU_SET(threads.three, &cpuset);
-  //CPU_SET(threads.three, &cpuset);
-  init_thread(900000,1000000 , FIFO_PRIORITY-1, &cpuset,
-	      threadname);
-  wait_sync("UE_phy_stub_thread_rxn_txnp4");
-
   while (!oai_exit) {
+
     if (pthread_mutex_lock(&phy_stub_ticking->mutex_ticking) != 0) {
-      LOG_E( PHY, "[SCHED][UE] error locking mutex for UE RXTX\n" );
+      LOG_E( MAC, "[SCHED][UE] error locking mutex for UE RXTX\n" );
       exit_fun("nothing to add");
     }
     while (phy_stub_ticking->ticking_var < 0) {
       // most of the time, the thread is waiting here
-      //pthread_cond_wait( &proc->cond_rxtx, &proc->mutex_rxtx );
+      //pthread_cond_wait( &proc->cond_rxtx, &proc->mutex_rxtx )
+      LOG_D(MAC,"Waiting for ticking_var\n",phy_stub_ticking->ticking_var);
       pthread_cond_wait( &phy_stub_ticking->cond_ticking, &phy_stub_ticking->mutex_ticking);
     }
+    phy_stub_ticking->ticking_var--;
     if (pthread_mutex_unlock(&phy_stub_ticking->mutex_ticking) != 0) {
-      LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE RXn_TXnp4\n" );
+      LOG_E( MAC, "[SCHED][UE] error unlocking mutex for UE RXn_TXnp4\n" );
       exit_fun("nothing to add");
     }
+    LOG_D(MAC," Panos-D [UE_phy_stub_thread_rxn_txnp4 1] Frame: %d, Subframe: %d \n" "\n" "\n", timer_frame, timer_subframe);
+
 
     proc->subframe_rx=timer_subframe;
     proc->frame_rx = timer_frame;
     proc->subframe_tx=(timer_subframe+2)%10;
-    proc->frame_tx = proc->frame_rx + (proc->subframe_rx>5?1:0);
+    proc->frame_tx = proc->frame_rx + (proc->subframe_rx>7?1:0);
+    //oai_subframe_ind(proc->frame_rx, proc->subframe_rx);
+
 
 
     // Panos: Guessing that the next 4 lines are not needed for the phy_stub mode.
@@ -866,7 +859,9 @@ static void *UE_phy_stub_thread_rxn_txnp4(void *arg) {
 		(sf_type==SF_S ? "SF_S"  : "UNKNOWN_SF_TYPE"))));
       }
 
+
       phy_procedures_UE_SL_RX(UE,proc);
+
       /*
 	#ifdef UE_SLOT_PARALLELISATION
 	phy_procedures_slot_parallelization_UE_RX( UE, proc, 0, 0, 1, UE->mode, no_relay, NULL );
@@ -877,26 +872,35 @@ static void *UE_phy_stub_thread_rxn_txnp4(void *arg) {
       // Hardcode Mod_id for now. Will be changed later.
 
       // Panos: is this the right place to call oai_subframe_indication to invoke p7 nfapi callbacks here?
-      oai_subframe_ind(proc->frame_rx, proc->subframe_rx);
-      LOG_D( MAC, "Panos-D: UE_phy_stub_thread_rxn_txnp4 after oai_subframe_ind \n");
+
+      //oai_subframe_ind(proc->frame_rx, proc->subframe_rx);
+      //oai_subframe_ind(timer_frame, timer_subframe);
+
+      //start_meas(&UE->timer_stats);
+      //oai_subframe_ind(proc->frame_tx, proc->subframe_tx);
+      oai_subframe_ind(timer_frame, timer_subframe);
+      //LOG_I( MAC, "Panos-D: UE_phy_stub_thread_rxn_txnp4 after oai_subframe_ind \n");
       //printf("Panos-D: UE_phy_stub_thread_rxn_txnp4 after oai_subframe_ind \n");
       /*if(UE_mac_inst[Mod_id].tx_req!= NULL){
 	printf("Panos-D: UE_phy_stub_thread_rxn_txnp4 after oai_subframe_ind 2\n");
 	tx_req_UE_MAC(UE_mac_inst[Mod_id].tx_req);
 	}*/
       if(UE_mac_inst[Mod_id].dl_config_req!= NULL) {
-	LOG_D( MAC, "Panos-D: UE_phy_stub_thread_rxn_txnp4 after oai_subframe_ind 3 \n");
+	LOG_I( MAC, "Panos-D: UE_phy_stub_thread_rxn_txnp4 after oai_subframe_ind 3 \n");
 	dl_config_req_UE_MAC(UE_mac_inst[Mod_id].dl_config_req);
       }
       if(UE_mac_inst[Mod_id].hi_dci0_req!= NULL){
-	LOG_D( MAC, "Panos-D: UE_phy_stub_thread_rxn_txnp4 after oai_subframe_ind 4 \n");
+	LOG_I( MAC, "Panos-D: UE_phy_stub_thread_rxn_txnp4 after oai_subframe_ind 4 \n");
 	hi_dci0_req_UE_MAC(UE_mac_inst[Mod_id].hi_dci0_req);
       }
-
+      //stop_meas(&UE->timer_stats);
+      //t_diff = get_time_meas_us(&UE->timer_stats);
+      //LOG_E(MAC," Panos-D Absolute time: %f\n", t_diff);
       phy_procedures_UE_SL_TX(UE,proc);
       //#endif
     }
 
+
 #if UE_TIMING_TRACE
     start_meas(&UE->generic_stat);
 #endif
@@ -933,8 +937,46 @@ static void *UE_phy_stub_thread_rxn_txnp4(void *arg) {
     stop_meas(&UE->generic_stat);
 #endif
 
-
+	
     // Prepare the future Tx data
+	
+    if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_UL) ||
+	(UE->frame_parms.frame_type == FDD) )
+      if (UE->mode != loop_through_memory){
+
+	if ((UE_mac_inst[Mod_id].UE_mode[0] == PRACH) ) {
+	  LOG_I(MAC, "Panos-D: UE_phy_stub_thread_rxn_txnp4 before RACH \n");
+
+	  // check if we have PRACH opportunity
+
+	  if (is_prach_subframe(&UE->frame_parms,proc->frame_tx, proc->subframe_tx)) {
+	    LOG_I(MAC, "Panos-D: UE_phy_stub_thread_rxn_txnp4 before RACH 2 \n");
+	    PRACH_RESOURCES_t *prach_resources = ue_get_rach(Mod_id, 0, proc->frame_tx, 0, proc->subframe_tx);
+	    if(prach_resources!=NULL) {
+	      LOG_I(MAC, "Panos-D: UE_phy_stub_thread_rxn_txnp4 before RACH 3 \n");
+	      fill_rach_indication_UE_MAC(Mod_id, proc->frame_tx ,proc->subframe_tx, UL_INFO, prach_resources->ra_PreambleIndex, prach_resources->ra_RNTI);
+	      Msg1_transmitted(Mod_id, 0, proc->frame_tx, 0);
+	      UE_mac_inst[Mod_id].UE_mode[0] = RA_RESPONSE;
+	    }
+
+	    //ue_prach_procedures(ue,proc,eNB_id,abstraction_flag,mode);
+	  }
+	} // mode is PRACH
+
+	// Panos: Substitute call to phy_procedures Tx with call to phy_stub functions in order to trigger
+	// UE Tx procedures directly at the MAC layer, based on the received ul_config requests from the vnf (eNB).
+	// Generate UL_indications which corresponf to UL traffic.
+	if(UE_mac_inst[Mod_id].ul_config_req!= NULL){
+	  LOG_I(MAC, "Panos-D: UE_phy_stub_thread_rxn_txnp4 ul_config_req is not NULL \n");
+	  ul_config_req_UE_MAC(UE_mac_inst[Mod_id].ul_config_req);
+	  //UL_indication(UL_INFO);
+	}
+	/*else{
+	  AssertFatal(UE_mac_inst[Mod_id].ul_config_req!= NULL, "Panos-D: Copy of ul_config_req is NULL");
+	  }*/
+
+      }
+
 
     if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_UL) ||
 	(UE->frame_parms.frame_type == FDD) )
@@ -964,14 +1006,13 @@ static void *UE_phy_stub_thread_rxn_txnp4(void *arg) {
     }
 
     //proc->instance_cnt_rxtx--;
-    phy_stub_ticking->ticking_var--;
+
     //if (pthread_mutex_unlock(&proc->mutex_rxtx) != 0) {
     if (pthread_mutex_unlock(&phy_stub_ticking->mutex_ticking) != 0) {
       LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE RXTX\n" );
       exit_fun("noting to add");
     }
   }
-
   // thread finished
   free(arg);
   return &UE_thread_rxtx_retval;
@@ -1344,50 +1385,50 @@ void init_UE_threads_stub(int inst) {
       #endif*/
 
   }
-    // Panos: Remove thread for UE_sync in phy_stub_UE mode.
-    //pthread_create(&UE->proc.pthread_synch,NULL,UE_thread_synch,(void*)UE);
-  }
+  // Panos: Remove thread for UE_sync in phy_stub_UE mode.
+  //pthread_create(&UE->proc.pthread_synch,NULL,UE_thread_synch,(void*)UE);
+}
 
 
 
 
 #ifdef OPENAIR2
-    void fill_ue_band_info(void) {
+void fill_ue_band_info(void) {
 
-    UE_EUTRA_Capability_t *UE_EUTRA_Capability = UE_rrc_inst[0].UECap->UE_EUTRA_Capability;
-    int i,j;
+  UE_EUTRA_Capability_t *UE_EUTRA_Capability = UE_rrc_inst[0].UECap->UE_EUTRA_Capability;
+  int i,j;
 
-    bands_to_scan.nbands = UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list.count;
+  bands_to_scan.nbands = UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list.count;
 
-    for (i=0; i<bands_to_scan.nbands; i++) {
+  for (i=0; i<bands_to_scan.nbands; i++) {
 
     for (j=0; j<sizeof (eutra_bands) / sizeof (eutra_bands[0]); j++)
       if (eutra_bands[j].band == UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list.array[i]->bandEUTRA) {
-    memcpy(&bands_to_scan.band_info[i],
-      &eutra_bands[j],
-      sizeof(eutra_band_t));
-
-    printf("Band %d (%lu) : DL %u..%u Hz, UL %u..%u Hz, Duplex %s \n",
-      bands_to_scan.band_info[i].band,
-      UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list.array[i]->bandEUTRA,
-      bands_to_scan.band_info[i].dl_min,
-      bands_to_scan.band_info[i].dl_max,
-      bands_to_scan.band_info[i].ul_min,
-      bands_to_scan.band_info[i].ul_max,
-      (bands_to_scan.band_info[i].frame_type==FDD) ? "FDD" : "TDD");
-    break;
-  }
-  }
+	memcpy(&bands_to_scan.band_info[i],
+	       &eutra_bands[j],
+	       sizeof(eutra_band_t));
+
+	printf("Band %d (%lu) : DL %u..%u Hz, UL %u..%u Hz, Duplex %s \n",
+	       bands_to_scan.band_info[i].band,
+	       UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list.array[i]->bandEUTRA,
+	       bands_to_scan.band_info[i].dl_min,
+	       bands_to_scan.band_info[i].dl_max,
+	       bands_to_scan.band_info[i].ul_min,
+	       bands_to_scan.band_info[i].ul_max,
+	       (bands_to_scan.band_info[i].frame_type==FDD) ? "FDD" : "TDD");
+	break;
+      }
   }
+}
 #endif
 
-    int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue, openair0_config_t *openair0_cfg) {
+int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue, openair0_config_t *openair0_cfg) {
 
-    int i, CC_id;
-    LTE_DL_FRAME_PARMS *frame_parms;
-    openair0_rf_map *rf_map;
+  int i, CC_id;
+  LTE_DL_FRAME_PARMS *frame_parms;
+  openair0_rf_map *rf_map;
 
-    for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
+  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
     rf_map = &phy_vars_ue[CC_id]->rf_map;
       
     AssertFatal( phy_vars_ue[CC_id] !=0, "");
@@ -1398,61 +1439,79 @@ void init_UE_threads_stub(int inst) {
     txdata = (int32_t**)malloc16( frame_parms->nb_antennas_tx*sizeof(int32_t*) );
       
     for (i=0; i<frame_parms->nb_antennas_rx; i++) {
-    LOG_I(PHY, "Mapping UE CC_id %d, rx_ant %d, freq %u on card %d, chain %d\n",
-      CC_id, i, downlink_frequency[CC_id][i], rf_map->card, rf_map->chain+i );
-    free( phy_vars_ue[CC_id]->common_vars.rxdata[i] );
-    rxdata[i] = (int32_t*)malloc16_clear( 307200*sizeof(int32_t) );
-    phy_vars_ue[CC_id]->common_vars.rxdata[i] = rxdata[i]; // what about the "-N_TA_offset" ? // N_TA offset for TDD
-  }
+      LOG_I(PHY, "Mapping UE CC_id %d, rx_ant %d, freq %u on card %d, chain %d\n",
+	    CC_id, i, downlink_frequency[CC_id][i], rf_map->card, rf_map->chain+i );
+      free( phy_vars_ue[CC_id]->common_vars.rxdata[i] );
+      rxdata[i] = (int32_t*)malloc16_clear( 307200*sizeof(int32_t) );
+      phy_vars_ue[CC_id]->common_vars.rxdata[i] = rxdata[i]; // what about the "-N_TA_offset" ? // N_TA offset for TDD
+    }
 		
     for (i=0; i<frame_parms->nb_antennas_tx; i++) {
-    LOG_I(PHY, "Mapping UE CC_id %d, tx_ant %d, freq %u on card %d, chain %d\n",
-      CC_id, i, downlink_frequency[CC_id][i], rf_map->card, rf_map->chain+i );
-    free( phy_vars_ue[CC_id]->common_vars.txdata[i] );
-    txdata[i] = (int32_t*)malloc16_clear( 307200*sizeof(int32_t) );
-    phy_vars_ue[CC_id]->common_vars.txdata[i] = txdata[i];
-  }
+      LOG_I(PHY, "Mapping UE CC_id %d, tx_ant %d, freq %u on card %d, chain %d\n",
+	    CC_id, i, downlink_frequency[CC_id][i], rf_map->card, rf_map->chain+i );
+      free( phy_vars_ue[CC_id]->common_vars.txdata[i] );
+      txdata[i] = (int32_t*)malloc16_clear( 307200*sizeof(int32_t) );
+      phy_vars_ue[CC_id]->common_vars.txdata[i] = txdata[i];
+    }
       
     // rxdata[x] points now to the same memory region as phy_vars_ue[CC_id]->common_vars.rxdata[x]
     // txdata[x] points now to the same memory region as phy_vars_ue[CC_id]->common_vars.txdata[x]
     // be careful when releasing memory!
     // because no "release_ue_buffers"-function is available, at least rxdata and txdata memory will leak (only some bytes)
   }
-    return 0;
-  }
+  return 0;
+}
 
 
-    // Panos: This timer thread is used only in the phy_sub mode as an independent timer
-    // which will be ticking and provide the SFN/SF values that will be used from the UE threads
-    // playing the role of nfapi-pnf.
-    static void* timer_thread( void* param ) {
-    thread_top_init("timer_thread",1,870000L,1000000L,1000000L);
-    timer_subframe =9;
-    timer_frame    =1023;
-    //phy_stub_ticking = (SF_ticking*)malloc(sizeof(SF_ticking));
-    phy_stub_ticking->ticking_var = -1;
-    PHY_VARS_UE *UE;
-    UE = PHY_vars_UE_g[0][0];
-    double t_diff;
-    wait_sync("timer_thread");
-    //pthread_mutex_init(&phy_stub_ticking->mutex_ticking,NULL);
-    //pthread_cond_init(&phy_stub_ticking->cond_ticking,NULL);
-
-    struct timespec start = {0};
-    struct timespec end = {0};
-    //sleepValue.tv_nsec = 1000000;
-    opp_enabled = 1;
-    while (!oai_exit) {
+// Panos: This timer thread is used only in the phy_sub mode as an independent timer
+// which will be ticking and provide the SFN/SF values that will be used from the UE threads
+// playing the role of nfapi-pnf.
+static void* timer_thread( void* param ) {
+
+  thread_top_init("timer_thread",1,870000L,1000000L,1000000L);
+  timer_subframe =9;
+  timer_frame    =1023;
+  //phy_stub_ticking = (SF_ticking*)malloc(sizeof(SF_ticking));
+  phy_stub_ticking->ticking_var = -1;
+  PHY_VARS_UE *UE;
+  UE = PHY_vars_UE_g[0][0];
+  double t_diff;
+  int external_timer = 0;
+  
+  wait_sync("timer_thread");
+
+  //pthread_mutex_init(&phy_stub_ticking->mutex_ticking,NULL);
+  //pthread_cond_init(&phy_stub_ticking->cond_ticking,NULL);
+
+  //  struct timespec start = {0};
+  //  struct timespec end = {0};
+  //sleepValue.tv_nsec = 1000000;
+  opp_enabled = 1;
+
+  // first check if we are receiving timing indications
+  usleep(10000);
+  if (UE->instance_cnt_timer > 0) {
+    external_timer = 1;
+    int absSFm1 = ((emulator_absSF+10239)%10240);
+    timer_frame = absSFm1/10;
+    timer_subframe = absSFm1%10;
+    pthread_mutex_lock(&UE->timer_mutex);
+    UE->instance_cnt_timer = -1;
+    LOG_I(PHY,"Running with external timer\n");
+  }
+  else LOG_I(PHY,"Running with internal timer\n");
+
+  while (!oai_exit) {
 
     // these are local subframe/frame counters to check that we are in synch with the fronthaul timing.
     // They are set on the first rx/tx in the underly FH routines.
     if (timer_subframe==9) {
-    timer_subframe=0;
-    timer_frame++;
-    timer_frame&=1023;
-  } else {
-    timer_subframe++;
-  }
+      timer_subframe=0;
+      timer_frame++;
+      timer_frame&=1023;
+    } else {
+      timer_subframe++;
+    }
     //printf("[timer_thread] Frame: %d, Subframe: %d \n", timer_frame, timer_subframe);
     LOG_D(MAC," Panos-D [timer_thread] Frame: %d, Subframe: %d \n", timer_frame, timer_subframe);
     //AssertFatal( 0 == pthread_cond_signal(&phy_stub_ticking->cond_ticking), "");
@@ -1460,22 +1519,34 @@ void init_UE_threads_stub(int inst) {
     phy_stub_ticking->ticking_var++;
     // This should probably be a call to pthread_cond_broadcast when we introduce support for multiple UEs (threads)
     if(phy_stub_ticking->ticking_var == 0){
-    //AssertFatal(phy_stub_ticking->ticking_var == 0,"phy_stub_ticking->ticking_var = %d",
-    //		phy_stub_ticking->ticking_var);
-    if (pthread_cond_signal(&phy_stub_ticking->cond_ticking) != 0) {
-    //LOG_E( PHY, "[SCHED][UE %d] ERROR pthread_cond_signal for UE RX thread\n", UE->Mod_id);
-    LOG_E( PHY, "timer_thread ERROR pthread_cond_signal for UE_thread\n");
-    exit_fun("nothing to add");
-  }
-  }
+      //AssertFatal(phy_stub_ticking->ticking_var == 0,"phy_stub_ticking->ticking_var = %d",
+      //		phy_stub_ticking->ticking_var);
+      if (pthread_cond_signal(&phy_stub_ticking->cond_ticking) != 0) {
+	//LOG_E( PHY, "[SCHED][UE %d] ERROR pthread_cond_signal for UE RX thread\n", UE->Mod_id);
+	LOG_E( PHY, "timer_thread ERROR pthread_cond_signal for UE_thread\n");
+	exit_fun("nothing to add");
+      }
+    }
 
     AssertFatal(pthread_mutex_unlock(&phy_stub_ticking->mutex_ticking) ==0,"");
     start_meas(&UE->timer_stats);
 
 
     //clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start); // get initial time-stamp
-    usleep(1000);
-
+    if (external_timer == 0) {
+      usleep(1000);
+      UE_tport_t pdu;
+      pdu.header.packet_type = TTI_SYNC;
+      pdu.header.absSF = (timer_frame*10)+timer_subframe;
+      multicast_link_write_sock(0, 
+				&pdu, 
+				sizeof(UE_tport_header_t));
+    
+    }
+    else { 
+      wait_on_condition(&UE->timer_mutex,&UE->timer_cond,&UE->instance_cnt_timer,"timer_thread");
+      release_thread(&UE->timer_mutex,&UE->instance_cnt_timer,"timer_thread");
+    }
     //clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end);   // get final time-stamp
 
     //double t_ns = (double)(end.tv_sec - start.tv_sec) * 1.0e9 +
@@ -1483,7 +1554,18 @@ void init_UE_threads_stub(int inst) {
     //printf("Panos-D: [timer_thread] REAL TIME difference: %f", t_ns);
 
 
-    //nanosleep(&sleepValue, NULL);
+    stop_meas(&UE->timer_stats);
+    t_diff = get_time_meas_us(&UE->timer_stats);
+
+    //printf("Panos-D: Absolute time: %lld, diff: %lld, diff_now: %lld \n",UE->timer_stats.p_time, UE->timer_stats.diff, UE->timer_stats.diff_now);
+    //LOG_I(MAC,"[UE%d] Applying default macMainConfig\n",module_idP);
+    //if (t_diff > 1100)
+
+
+    //    LOG_E(MAC," Panos-D Absolute time: %f\n", t_diff);
+
+    //printf("Panos-D: Absolute time: %f", t_diff);
+
 
     stop_meas(&UE->timer_stats);
     t_diff = get_time_meas_us(&UE->timer_stats);
@@ -1496,20 +1578,20 @@ void init_UE_threads_stub(int inst) {
     // pthread_cond_signal() //Send signal to ue_thread()?
     // We also need to somehow pass the information of SFN/SF
   }
-    free(phy_stub_ticking);
-    pthread_cond_destroy(&phy_stub_ticking->cond_ticking);
-    pthread_mutex_destroy(&phy_stub_ticking->mutex_ticking);
-    return 0;
+  free(phy_stub_ticking);
+  pthread_cond_destroy(&phy_stub_ticking->cond_ticking);
+  pthread_mutex_destroy(&phy_stub_ticking->mutex_ticking);
+  return 0;
 
-  }
+}
 
-    int init_timer_thread(void) {
-    phy_stub_ticking = (SF_ticking*)malloc(sizeof(SF_ticking));
-    pthread_mutex_init(&phy_stub_ticking->mutex_ticking,NULL);
-    pthread_cond_init(&phy_stub_ticking->cond_ticking,NULL);
-    pthread_create(phy_stub_ticking->pthread_timer, NULL, &timer_thread, NULL);
-    return 0;
-  }
+int init_timer_thread(void) {
+  phy_stub_ticking = (SF_ticking*)malloc(sizeof(SF_ticking));
+  pthread_mutex_init(&phy_stub_ticking->mutex_ticking,NULL);
+  pthread_cond_init(&phy_stub_ticking->cond_ticking,NULL);
+  pthread_create(&phy_stub_ticking->pthread_timer, NULL, &timer_thread, NULL);
+  return 0;
+}