From 5dc306ec1dfe05b41ebd42ee763c25d9d01d639b Mon Sep 17 00:00:00 2001
From: matzakos <panagiotis.matzakos@eurecom.fr>
Date: Wed, 24 Jan 2018 11:12:53 +0100
Subject: [PATCH] Works up to the reception of HI_DCI0.request at the UE-PNF.
 Sometimes Msg3 arrives later than expected at the eNB-VNF.

---
 cmake_targets/CMakeLists.txt         |  49 ++++++
 cmake_targets/build_oai              |   2 +-
 nfapi/nfapi_pnf.c                    |   4 +
 nfapi/nfapi_vnf.c                    |   1 +
 openair2/LAYER2/MAC/ra_procedures.c  |   2 +-
 openair2/PHY_INTERFACE/IF_Module.c   |   2 +-
 openair2/PHY_INTERFACE/phy_stub_UE.c | 171 ++++++++++++++++----
 openair2/PHY_INTERFACE/phy_stub_UE.h |   8 +-
 targets/RT/USER/lte-softmodem-stub.c |  12 +-
 targets/RT/USER/lte-ue.c             | 230 +++++++++++++++++++++++++--
 10 files changed, 425 insertions(+), 56 deletions(-)

diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt
index 1e5f71b8ae7..1574f5366a5 100644
--- a/cmake_targets/CMakeLists.txt
+++ b/cmake_targets/CMakeLists.txt
@@ -1933,6 +1933,55 @@ target_link_libraries (lte-softmodem-nos1  ${LIB_LMS_LIBRARIES})
 target_link_libraries (lte-softmodem-nos1 ${T_LIB})
 
 
+
+
+# lte-softmodem-stub-nos1 is both eNB and UE implementation
+###################################################
+
+add_executable(lte-softmodem-stub-nos1
+  ${rrc_h}
+  ${s1ap_h}
+  ${OPENAIR_BIN_DIR}/messages_xml.h
+  ${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-softmodem-stub.c
+  ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c
+  ${OPENAIR_TARGETS}/SIMU/USER/init_lte.c
+  ${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
+  #${GTPU_need_ITTI}
+  ${RTAI_SOURCE}
+  ${XFORMS_SOURCE}
+  ${XFORMS_SOURCE_SOFTMODEM}
+  ${T_SOURCE}
+  ${CONFIG_SOURCES}
+  ${SHLIB_LOADER_SOURCES}
+  )
+
+target_link_libraries (lte-softmodem-stub-nos1
+  -Wl,--start-group
+  RRC_LIB SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB PHY LFDS L2 ${MSC_LIB} ${RAL_LIB} ${ITTI_LIB} ${MIH_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7
+  NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB
+  NFAPI_USER_LIB
+  -Wl,--end-group z dl)
+
+target_link_libraries (lte-softmodem-stub-nos1 ${LIBXML2_LIBRARIES})
+target_link_libraries (lte-softmodem-stub-nos1 pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp  ${XFORMS_LIBRARIES} ${PROTOBUF_LIB}  ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES})
+target_link_libraries (lte-softmodem-stub-nos1 ${LIB_LMS_LIBRARIES})
+target_link_libraries (lte-softmodem-stub-nos1 ${T_LIB})
+
+
+
+
+
+
 # lte-softmodem-stub is both eNB and UE implementation
 ###################################################
 
diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai
index 052a32f3208..45ff89e2adf 100755
--- a/cmake_targets/build_oai
+++ b/cmake_targets/build_oai
@@ -503,7 +503,7 @@ function main() {
   if [ "$NOS1" =  "1" ] ; then
       lte_build_dir=lte_noS1_build_oai
       #lte_exec=lte-softmodem-nos1
-      lte_exec=lte-softmodem-stub
+      lte_exec=lte-softmodem-stub-nos1
   else
       lte_build_dir=lte_build_oai
       #lte_exec=lte-softmodem
diff --git a/nfapi/nfapi_pnf.c b/nfapi/nfapi_pnf.c
index 7699440db85..9bf3d710bc4 100644
--- a/nfapi/nfapi_pnf.c
+++ b/nfapi/nfapi_pnf.c
@@ -51,6 +51,9 @@ extern void handle_nfapi_bch_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, nfapi_
 
 extern uint8_t  nfapi_mode;
 
+extern int timer_subframe;
+extern int timer_frame;
+
 nfapi_tx_request_pdu_t* tx_request_pdu[1023][10][10]; // [frame][subframe][max_num_pdus]
 
 
@@ -1921,6 +1924,7 @@ int oai_nfapi_rx_ind(nfapi_rx_indication_t *ind)
   ind->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!!
   ind->header.message_id = NFAPI_RX_ULSCH_INDICATION;
 
+  LOG_I(MAC, "Panos-D: oai_nfapi_rx_ind 1 TIMER SFN/SF:%d.%d \n", timer_frame, timer_subframe);
   int retval = nfapi_pnf_p7_rx_ind(p7_config_g, ind);
 
   //LOG_D(PHY,"%s() SFN/SF:%d pdus:%d retval:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(ind->sfn_sf), ind->rx_indication_body.number_of_pdus, retval);
diff --git a/nfapi/nfapi_vnf.c b/nfapi/nfapi_vnf.c
index e694b6e609b..316a9d713fb 100644
--- a/nfapi/nfapi_vnf.c
+++ b/nfapi/nfapi_vnf.c
@@ -1362,6 +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;
+  // Panos:
   vnf.p7_vnfs[0].aperiodic_timing_enabled = 1;
   vnf.p7_vnfs[0].periodic_timing_period = 10;
 
diff --git a/openair2/LAYER2/MAC/ra_procedures.c b/openair2/LAYER2/MAC/ra_procedures.c
index b8d09180085..cec5f8420a3 100644
--- a/openair2/LAYER2/MAC/ra_procedures.c
+++ b/openair2/LAYER2/MAC/ra_procedures.c
@@ -321,7 +321,7 @@ 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");
+	  LOG_I(MAC, "Panos-D: ue_get_rach 3, RA_active value: %d", UE_mac_inst[module_idP].RA_active);
     if (UE_mac_inst[module_idP].radioResourceConfigCommon) {
       rach_ConfigCommon = &UE_mac_inst[module_idP].radioResourceConfigCommon->rach_ConfigCommon;
     } else {
diff --git a/openair2/PHY_INTERFACE/IF_Module.c b/openair2/PHY_INTERFACE/IF_Module.c
index 8f4720024b5..282e77faeb6 100644
--- a/openair2/PHY_INTERFACE/IF_Module.c
+++ b/openair2/PHY_INTERFACE/IF_Module.c
@@ -547,7 +547,7 @@ void UL_indication(UL_IND_t *UL_info)
   IF_Module_t  *ifi        = if_inst[module_id];
   eNB_MAC_INST *mac        = RC.mac[module_id];
 
-  LOG_D(PHY,"SFN/SF:%d%d module_id:%d CC_id:%d UL_info[rx_ind:%d harqs:%d crcs:%d cqis:%d preambles:%d sr_ind:%d]\n", 
+  LOG_D(PHY,"SFN/SF:%d%d module_id:%d CC_id:%d UL_info[rx_ind:%d harqs:%d crcs:%d cqis:%d preambles:%d sr_ind:%d]\n",
       UL_info->frame,UL_info->subframe,
       module_id,CC_id,
       UL_info->rx_ind.rx_indication_body.number_of_pdus, UL_info->harq_ind.harq_indication_body.number_of_harqs, UL_info->crc_ind.crc_indication_body.number_of_crcs, UL_info->cqi_ind.number_of_cqis, UL_info->rach_ind.rach_indication_body.number_of_preambles, UL_info->sr_ind.sr_indication_body.number_of_srs);
diff --git a/openair2/PHY_INTERFACE/phy_stub_UE.c b/openair2/PHY_INTERFACE/phy_stub_UE.c
index 6d4b8034d4a..03384bc464b 100644
--- a/openair2/PHY_INTERFACE/phy_stub_UE.c
+++ b/openair2/PHY_INTERFACE/phy_stub_UE.c
@@ -7,6 +7,7 @@
 #include "openair2/LAYER2/MAC/proto.h"
 //#include "openair2/LAYER2/MAC/vars.h"
 #include "openair1/SCHED/defs.h"
+#include "nfapi/nfapi_interface.h"
 //#include "common/ran_context.h"
 #include "openair2/PHY_INTERFACE/phy_stub_UE.h"
 
@@ -16,19 +17,24 @@
 //#include "nfapi.h"
 //#include "nfapi_pnf.h"
 
+extern int oai_nfapi_crc_indication(nfapi_crc_indication_t *crc_ind);
+extern int oai_nfapi_rx_ind(nfapi_rx_indication_t *ind);
+
 
 
 
 //extern uint8_t nfapi_pnf;
 //UL_IND_t *UL_INFO;
 extern nfapi_tx_request_pdu_t* tx_request_pdu[1023][10][10];
+//extern int timer_subframe;
+//extern int timer_frame;
 
 void Msg1_transmitted(module_id_t module_idP,uint8_t CC_id,frame_t frameP, uint8_t eNB_id);
 void Msg3_transmitted(module_id_t module_idP,uint8_t CC_id,frame_t frameP, uint8_t eNB_id);
 
 
 
-void fill_rx_indication_UE_MAC(module_id_t Mod_id,int frame,int subframe, UL_IND_t* UL_INFO, uint8_t *ulsch_buffer, uint16_t buflen, uint16_t rnti)
+void fill_rx_indication_UE_MAC(module_id_t Mod_id,int frame,int subframe, UL_IND_t* UL_INFO, uint8_t *ulsch_buffer, uint16_t buflen, uint16_t rnti, int index)
 {
 	  nfapi_rx_indication_pdu_t *pdu;
 
@@ -46,7 +52,15 @@ void fill_rx_indication_UE_MAC(module_id_t Mod_id,int frame,int subframe, UL_IND
 	  //eNB->UL_INFO.rx_ind.sfn_sf                    = frame<<4| subframe;
 	  //eNB->UL_INFO.rx_ind.rx_indication_body.tl.tag = NFAPI_RX_INDICATION_BODY_TAG;
 
-	  pdu                                    = &UL_INFO->rx_ind.rx_indication_body.rx_pdu_list[UL_INFO->rx_ind.rx_indication_body.number_of_pdus];
+	  UL_INFO->rx_ind.sfn_sf                    = frame<<4| subframe;
+	  UL_INFO->rx_ind.header.message_id			= NFAPI_RX_ULSCH_INDICATION;
+	  UL_INFO->rx_ind.rx_indication_body.tl.tag = NFAPI_RX_INDICATION_BODY_TAG;
+
+	  // Panos: Remove
+	  //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));
+
+	  //pdu                                    = &UL_INFO->rx_ind.rx_indication_body.rx_pdu_list[UL_INFO->rx_ind.rx_indication_body.number_of_pdus];
+	  pdu                                    = &UL_INFO->rx_ind.rx_indication_body.rx_pdu_list[index];
 
 	  //  pdu->rx_ue_information.handle          = eNB->ulsch[UE_id]->handle;
 	  pdu->rx_ue_information.tl.tag          = NFAPI_RX_UE_INFORMATION_TAG;
@@ -136,18 +150,26 @@ void fill_sr_indication_UE_MAC(int Mod_id,int frame,int subframe, UL_IND_t *UL_I
 }
 
 
-void fill_crc_indication_UE_MAC(int Mod_id,int frame,int subframe, UL_IND_t *UL_INFO, uint8_t crc_flag) {
+void fill_crc_indication_UE_MAC(int Mod_id,int frame,int subframe, UL_IND_t *UL_INFO, uint8_t crc_flag, int index, uint16_t rnti) {
 
   pthread_mutex_lock(&UE_mac_inst[Mod_id].UL_INFO_mutex);
-  nfapi_crc_indication_pdu_t *pdu =   &UL_INFO->crc_ind.crc_indication_body.crc_pdu_list[UL_INFO->crc_ind.crc_indication_body.number_of_crcs];
+
+  //nfapi_crc_indication_pdu_t *pdu =   &UL_INFO->crc_ind.crc_indication_body.crc_pdu_list[UL_INFO->crc_ind.crc_indication_body.number_of_crcs];
+  nfapi_crc_indication_pdu_t *pdu =   &UL_INFO->crc_ind.crc_indication_body.crc_pdu_list[index];
 
   //eNB->UL_INFO.crc_ind.sfn_sf                         = frame<<4 | subframe;
   //eNB->UL_INFO.crc_ind.crc_indication_body.tl.tag     = NFAPI_CRC_INDICATION_BODY_TAG;
 
+  UL_INFO->crc_ind.sfn_sf                    = frame<<4| subframe;
+  UL_INFO->crc_ind.header.message_id              = NFAPI_CRC_INDICATION;
+  UL_INFO->crc_ind.crc_indication_body.tl.tag = NFAPI_CRC_INDICATION_BODY_TAG;
+
   pdu->instance_length                                = 0; // don't know what to do with this
   //  pdu->rx_ue_information.handle                       = handle;
   pdu->rx_ue_information.tl.tag                       = NFAPI_RX_UE_INFORMATION_TAG;
-  pdu->rx_ue_information.rnti                         = UE_mac_inst[Mod_id].crnti;
+
+  //pdu->rx_ue_information.rnti                         = UE_mac_inst[Mod_id].crnti;
+  pdu->rx_ue_information.rnti                         = rnti;
   pdu->crc_indication_rel8.tl.tag                     = NFAPI_CRC_INDICATION_REL8_TAG;
   pdu->crc_indication_rel8.crc_flag                   = crc_flag;
 
@@ -486,7 +508,7 @@ void fill_uci_harq_indication_UE_MAC(int Mod_id,
 
 void handle_nfapi_ul_pdu_UE_MAC(module_id_t Mod_id,
                          nfapi_ul_config_request_pdu_t *ul_config_pdu,
-                         uint16_t frame,uint8_t subframe,uint8_t srs_present)
+                         uint16_t frame,uint8_t subframe,uint8_t srs_present, int index)
 {
   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");
@@ -509,8 +531,8 @@ void handle_nfapi_ul_pdu_UE_MAC(module_id_t Mod_id,
     if(buflen>0){
     	if(UE_mac_inst[Mod_id].first_ULSCH_Tx == 1){ // Msg3 case
     		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);
+    		fill_crc_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, 0, index, rnti);
+    		fill_rx_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, UE_mac_inst[Mod_id].RA_prach_resources.Msg3,buflen, rnti, index);
     		Msg3_transmitted(Mod_id, 0, frame, 0);
 
     		// Panos: This should be done after the reception of the respective hi_dci0
@@ -519,8 +541,8 @@ void handle_nfapi_ul_pdu_UE_MAC(module_id_t Mod_id,
     	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_rx_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, ulsch_buffer,buflen, rnti);
+    		fill_crc_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, 0, index, rnti);
+    		fill_rx_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, ulsch_buffer,buflen, rnti, index);
     	}
     }
   }
@@ -536,15 +558,15 @@ 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);
-			  fill_rx_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, UE_mac_inst[Mod_id].RA_prach_resources.Msg3,buflen, rnti);
+			  fill_crc_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, 0, index, rnti);
+			  fill_rx_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, UE_mac_inst[Mod_id].RA_prach_resources.Msg3,buflen, rnti, index);
 			  Msg3_transmitted(Mod_id, 0, frame, 0);
 			  //UE_mac_inst[Mod_id].first_ULSCH_Tx = 0;
 		  }
 		  else {
 			  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_rx_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, ulsch_buffer,buflen, rnti);
+			  fill_crc_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, 0, index, rnti);
+			  fill_rx_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, ulsch_buffer,buflen, rnti, index);
 		  }
 
 	  }
@@ -565,15 +587,15 @@ 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);
-			  fill_rx_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, UE_mac_inst[Mod_id].RA_prach_resources.Msg3,buflen, rnti);
+			  fill_crc_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, 0, index, rnti);
+			  fill_rx_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, UE_mac_inst[Mod_id].RA_prach_resources.Msg3,buflen, rnti, index);
 			  Msg3_transmitted(Mod_id, 0, frame, 0);
 			  //UE_mac_inst[Mod_id].first_ULSCH_Tx = 0;
 		  }
 		  else {
 			  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_rx_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, ulsch_buffer,buflen, rnti);
+			  fill_crc_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, 0, index, rnti);
+			  fill_rx_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, ulsch_buffer,buflen, rnti, index);
 		  }
 	  }
 	  fill_ulsch_cqi_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, rnti);
@@ -593,15 +615,15 @@ 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);
-			  fill_rx_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, UE_mac_inst[Mod_id].RA_prach_resources.Msg3,buflen, rnti);
+			  fill_crc_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, 0, index, rnti);
+			  fill_rx_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, UE_mac_inst[Mod_id].RA_prach_resources.Msg3,buflen, rnti, index);
 			  Msg3_transmitted(Mod_id, 0, frame, 0);
 			  //UE_mac_inst[Mod_id].first_ULSCH_Tx = 0;
 		  }
 		  else {
 			  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_rx_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, ulsch_buffer,buflen, rnti);
+			  fill_crc_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, 0, index, rnti);
+			  fill_rx_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, ulsch_buffer,buflen, rnti, index);
 		  }
 	  }
 
@@ -666,8 +688,9 @@ void handle_nfapi_ul_pdu_UE_MAC(module_id_t Mod_id,
 
 
 
-int ul_config_req_UE_MAC(nfapi_ul_config_request_t* req)
+int ul_config_req_UE_MAC(nfapi_ul_config_request_t* req, int timer_frame, int timer_subframe)
 {
+	if (req!=NULL && req->ul_config_request_body.ul_config_pdu_list !=NULL){
   LOG_D(PHY,"[PNF] UL_CONFIG_REQ %s() sfn_sf:%d pdu:%d rach_prach_frequency_resources:%d srs_present:%u\n",
       __FUNCTION__,
       NFAPI_SFNSF2DEC(req->sfn_sf),
@@ -700,6 +723,11 @@ int ul_config_req_UE_MAC(nfapi_ul_config_request_t* req)
   int sfn = NFAPI_SFNSF2SFN(req->sfn_sf);
   int sf = NFAPI_SFNSF2SF(req->sfn_sf);
 
+  //int sfn = timer_frame;
+  //int sf = timer_subframe;
+
+  LOG_I(MAC, "Panos-D: ul_config_req_UE_MAC 1, SFN/SF in REQ:%d.%d, SFN/SF of PNF counter:%d.%d \n", sfn, sf, timer_frame, timer_subframe);
+
   //struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0];
   //eNB_rxtx_proc_t *proc = &eNB->proc.proc_rxtx[0];
 
@@ -710,7 +738,10 @@ int ul_config_req_UE_MAC(nfapi_ul_config_request_t* req)
   //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));
+  //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->rx_ind.rx_indication_body.rx_pdu_list = (nfapi_rx_indication_pdu_t*)malloc(req->ul_config_request_body.number_of_pdus*sizeof(nfapi_rx_indication_pdu_t));
+  UL_INFO->crc_ind.crc_indication_body.crc_pdu_list = (nfapi_crc_indication_pdu_t*)malloc(req->ul_config_request_body.number_of_pdus*sizeof(nfapi_crc_indication_pdu_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;
@@ -734,7 +765,7 @@ int ul_config_req_UE_MAC(nfapi_ul_config_request_t* req)
   {
     //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");
+	LOG_I(MAC, "Panos-D: ul_config_req_UE_MAC 2.0 #PDUs: %d \n", i<req->ul_config_request_body.number_of_pdus);
     if (
     		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 ||
@@ -748,15 +779,80 @@ int ul_config_req_UE_MAC(nfapi_ul_config_request_t* req)
       //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() handle_nfapi_ul_pdu() for PDU:%d\n", __FUNCTION__, i);
 
     	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);
+      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, i);
+
+      /*if (UL_INFO->crc_ind.crc_indication_body.number_of_crcs>0)
+      {
+            //LOG_D(PHY,"UL_info->crc_ind.crc_indication_body.number_of_crcs:%d CRC_IND:SFN/SF:%d\n", UL_info->crc_ind.crc_indication_body.number_of_crcs, NFAPI_SFNSF2DEC(UL_info->crc_ind.sfn_sf));
+    	  oai_nfapi_crc_indication(&UL_INFO->crc_ind);
+    	  LOG_I(MAC, "Panos-D: ul_config_req_UE_MAC 2.2 \n");
+    	  UL_INFO->crc_ind.crc_indication_body.number_of_crcs = 0;
+      }
+      if (UL_INFO->rx_ind.rx_indication_body.number_of_pdus>0)
+      {
+    	  //LOG_D(PHY,"UL_info->rx_ind.number_of_pdus:%d RX_IND:SFN/SF:%d\n", UL_info->rx_ind.rx_indication_body.number_of_pdus, NFAPI_SFNSF2DEC(UL_info->rx_ind.sfn_sf));
+    	  LOG_I(MAC, "Panos-D: ul_config_req_UE_MAC 2.3 \n");
+    	  oai_nfapi_rx_ind(&UL_INFO->rx_ind);
+    	  LOG_I(MAC, "Panos-D: ul_config_req_UE_MAC 2.4 \n");
+    	  UL_INFO->rx_ind.rx_indication_body.number_of_pdus = 0;
+      }*/
+
+
+
+      /*if (UL_INFO->rx_ind.rx_indication_body.number_of_pdus>0)
+      {
+    	  //LOG_D(PHY,"UL_info->rx_ind.number_of_pdus:%d RX_IND:SFN/SF:%d\n", UL_info->rx_ind.rx_indication_body.number_of_pdus, NFAPI_SFNSF2DEC(UL_info->rx_ind.sfn_sf));
+    	  oai_nfapi_rx_ind(&UL_INFO->rx_ind);
+    	  oai_nfapi_crc_indication(&UL_INFO->crc_ind);
+    	  //UL_INFO->rx_ind.rx_indication_body.number_of_pdus = 0;
+      }*/
       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);
     }
   }
+  if (UL_INFO->crc_ind.crc_indication_body.number_of_crcs>0)
+        {
+              //LOG_D(PHY,"UL_info->crc_ind.crc_indication_body.number_of_crcs:%d CRC_IND:SFN/SF:%d\n", UL_info->crc_ind.crc_indication_body.number_of_crcs, NFAPI_SFNSF2DEC(UL_info->crc_ind.sfn_sf));
+	  LOG_I(MAC, "Panos-D: ul_config_req_UE_MAC 2.2, SFN/SF in REQ:%d.%d, SFN/SF of PNF counter:%d.%d \n", sfn, sf, timer_frame, timer_subframe);
+	  	  oai_nfapi_crc_indication(&UL_INFO->crc_ind);
+      	  //LOG_I(MAC, "Panos-D: ul_config_req_UE_MAC 2.2 \n");
+      	  UL_INFO->crc_ind.crc_indication_body.number_of_crcs = 0;
+        }
+        if (UL_INFO->rx_ind.rx_indication_body.number_of_pdus>0)
+        {
+      	  //LOG_D(PHY,"UL_info->rx_ind.number_of_pdus:%d RX_IND:SFN/SF:%d\n", UL_info->rx_ind.rx_indication_body.number_of_pdus, NFAPI_SFNSF2DEC(UL_info->rx_ind.sfn_sf));
+          LOG_I(MAC, "Panos-D: ul_config_req_UE_MAC 2.3, SFN/SF in REQ:%d.%d, SFN/SF of PNF counter:%d.%d \n", sfn, sf, timer_frame, timer_subframe);
+          //LOG_I(MAC, "Panos-D: ul_config_req_UE_MAC 2.3 \n");
+      	  oai_nfapi_rx_ind(&UL_INFO->rx_ind);
+      	  LOG_I(MAC, "Panos-D: ul_config_req_UE_MAC 2.4 \n");
+      	  UL_INFO->rx_ind.rx_indication_body.number_of_pdus = 0;
+        }
+
+  // Free ul_config_request
+  /*if(req->ul_config_request_body.ul_config_pdu_list != NULL){
+	  free(req->ul_config_request_body.ul_config_pdu_list);
+	  req->ul_config_request_body.ul_config_pdu_list = NULL;
+  }
+  free(req);
+  req = NULL;*/
+
+
+  // Free UL_INFO messages
+  if(UL_INFO->crc_ind.crc_indication_body.crc_pdu_list != NULL){
+	  free(UL_INFO->crc_ind.crc_indication_body.crc_pdu_list);
+	  UL_INFO->crc_ind.crc_indication_body.crc_pdu_list = NULL;
+  }
+  if(UL_INFO->rx_ind.rx_indication_body.rx_pdu_list != NULL){
+	  free(UL_INFO->rx_ind.rx_indication_body.rx_pdu_list);
+	  UL_INFO->rx_ind.rx_indication_body.rx_pdu_list = NULL;
+  }
   free(UL_INFO);
+  UL_INFO = NULL;
+	}
 
   return 0;
 }
@@ -935,7 +1031,10 @@ int dl_config_req_UE_MAC(nfapi_dl_config_request_t* req)
   req = NULL;
   return 0;
 	}
-	else {
+	else if(req!=NULL){
+		//LOG_I(MAC, "Panos-D: dl_config_req_UE_MAC probably dummy DL_Config \n");
+		//free(req);
+		//req = NULL;
 		return -1;
 	}
 
@@ -1005,7 +1104,7 @@ int memcpy_dl_config_req (nfapi_pnf_p7_config_t* pnf_p7, nfapi_dl_config_request
 
 	module_id_t Mod_id = 0; //Panos: Currently static (only for one UE) but this should change.
 	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");
+	//LOG_I(MAC, "Panos-D: memcpy_dl_config_req 1 \n");
 
 
 	//UE_mac_inst[Mod_id].dl_config_req->header = req->header;
@@ -1114,7 +1213,23 @@ int memcpy_tx_req (nfapi_pnf_p7_config_t* pnf_p7, nfapi_tx_request_t* req)
 int memcpy_hi_dci0_req (nfapi_pnf_p7_config_t* pnf_p7, nfapi_hi_dci0_request_t* req)
 {
 	module_id_t Mod_id = 0; //Panos: Currently static (only for one UE) but this should change.
-	UE_mac_inst[Mod_id].hi_dci0_req = req;
+	UE_mac_inst[Mod_id].hi_dci0_req = (nfapi_hi_dci0_request_t*)malloc(sizeof(nfapi_hi_dci0_request_t));
+
+	UE_mac_inst[Mod_id].hi_dci0_req->sfn_sf = req->sfn_sf;
+	UE_mac_inst[Mod_id].hi_dci0_req->vendor_extension = req->vendor_extension;
+
+	UE_mac_inst[Mod_id].hi_dci0_req->hi_dci0_request_body.number_of_dci = req->hi_dci0_request_body.number_of_dci;
+	UE_mac_inst[Mod_id].hi_dci0_req->hi_dci0_request_body.number_of_hi = req->hi_dci0_request_body.number_of_hi;
+	UE_mac_inst[Mod_id].hi_dci0_req->hi_dci0_request_body.sfnsf = req->hi_dci0_request_body.sfnsf;
+	UE_mac_inst[Mod_id].hi_dci0_req->hi_dci0_request_body.tl = req->hi_dci0_request_body.tl;
+	int total_pdus = UE_mac_inst[Mod_id].hi_dci0_req->hi_dci0_request_body.number_of_dci + UE_mac_inst[Mod_id].hi_dci0_req->hi_dci0_request_body.number_of_dci;
+
+	//(nfapi_ul_config_request_pdu_t*) malloc(req->ul_config_request_body.number_of_pdus*sizeof(nfapi_ul_config_request_pdu_t));
+	UE_mac_inst[Mod_id].hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list = (nfapi_hi_dci0_request_pdu_t*) malloc(total_pdus*sizeof(nfapi_hi_dci0_request_pdu_t));
+
+	LOG_I(MAC, "Panos-D: memcpy_hi_dci0_req 2 \n");
+	//module_id_t Mod_id = 0; //Panos: Currently static (only for one UE) but this should change.
+	//UE_mac_inst[Mod_id].hi_dci0_req = req;
 	return 0;
 }
 
diff --git a/openair2/PHY_INTERFACE/phy_stub_UE.h b/openair2/PHY_INTERFACE/phy_stub_UE.h
index 4cb56d02237..02ca2b14976 100644
--- a/openair2/PHY_INTERFACE/phy_stub_UE.h
+++ b/openair2/PHY_INTERFACE/phy_stub_UE.h
@@ -47,7 +47,7 @@ void send_nfapi_UL_indications(UL_IND_t UL_INFO);
 
 //void fill_rx_indication_UE_MAC(module_id_t Mod_id,int frame,int subframe);
 
-void fill_rx_indication_UE_MAC(module_id_t Mod_id,int frame,int subframe, UL_IND_t *UL_INFO, uint8_t *ulsch_buffer, uint16_t buflen, uint16_t rnti);
+void fill_rx_indication_UE_MAC(module_id_t Mod_id,int frame,int subframe, UL_IND_t *UL_INFO, uint8_t *ulsch_buffer, uint16_t buflen, uint16_t rnti, int index);
 
 
 // This function should be indicating directly to the eNB when there is a planned scheduling request at the MAC layer
@@ -56,7 +56,7 @@ void fill_sr_indication_UE_MAC(int Mod_id,int frame,int subframe, UL_IND_t *UL_I
 
 // In our case the this function will be always indicating ACK to the MAC of the eNB (i.e. always assuming)
 // successful decoding.
-void fill_crc_indication_UE_MAC(int Mod_id,int frame,int subframe, UL_IND_t *UL_INFO, uint8_t crc_flag);
+void fill_crc_indication_UE_MAC(int Mod_id,int frame,int subframe, UL_IND_t *UL_INFO, uint8_t crc_flag, int index, uint16_t rnti);
 
 
 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);
@@ -71,11 +71,11 @@ void fill_uci_harq_indication_UE_MAC(int Mod_id, int frame, int subframe, UL_IND
 			      /*uint8_t tdd_mapping_mode,
 			      uint16_t tdd_multiplexing_mask*/);
 
-int ul_config_req_UE_MAC(nfapi_ul_config_request_t* req);
+int ul_config_req_UE_MAC(nfapi_ul_config_request_t* req, int frame, int subframe);
 
 void handle_nfapi_ul_pdu_UE_MAC(module_id_t Mod_id,
                          nfapi_ul_config_request_pdu_t *ul_config_pdu,
-                         uint16_t frame,uint8_t subframe,uint8_t srs_present);
+                         uint16_t frame,uint8_t subframe,uint8_t srs_present, int index);
 
 int dl_config_req_UE_MAC(nfapi_dl_config_request_t* req);
 
diff --git a/targets/RT/USER/lte-softmodem-stub.c b/targets/RT/USER/lte-softmodem-stub.c
index 3fe1f851822..13b15808da4 100644
--- a/targets/RT/USER/lte-softmodem-stub.c
+++ b/targets/RT/USER/lte-softmodem-stub.c
@@ -128,7 +128,7 @@ int nfapi_sync_var=-1; //!< protected by mutex \ref nfapi_sync_mutex
 
 uint8_t nfapi_mode = 3;
 
-uint16_t sf_ahead=4;
+uint16_t sf_ahead=2;
 
 char *emul_iface;
 
@@ -1228,7 +1228,9 @@ int main( int argc, char **argv )
       printf("cannot create ITTI tasks\n");
       exit(-1); // need a softer mode
     }
-    //    UE_config_stub_pnf();
+    if(nfapi_mode==3){ //Panos: Here we should add another nfapi_mode for the case of Supervised LTE-D2D
+        UE_config_stub_pnf();
+    }
     printf("ITTI tasks created\n");
   }
   else {
@@ -1349,7 +1351,7 @@ int main( int argc, char **argv )
   if (nfapi_mode<3) // VNF
     wait_nfapi_init("main?");
 
-  printf("START MAIN THREADS\n");
+  printf("START MAIN THREADS, nfapi_mode:%d \n", nfapi_mode);
 
   // start the main threads
   if (UE_flag == 1) {
@@ -1366,9 +1368,11 @@ int main( int argc, char **argv )
     //phy_stub_ticking = (SF_ticking*)malloc(sizeof(SF_ticking));
 
 
-    init_timer_thread();
+    // Panos: CHANGE we call init_timer_thread() from inside init_UE_stub() now
+    //init_timer_thread();
     init_UE_stub(1,eMBMS_active,uecap_xer_in,emul_iface);
 
+
     /*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-ue.c b/targets/RT/USER/lte-ue.c
index d5a6b0eb65a..b8f2a722cfc 100644
--- a/targets/RT/USER/lte-ue.c
+++ b/targets/RT/USER/lte-ue.c
@@ -284,6 +284,10 @@ void init_UE_stub(int nb_inst,int eMBMS_active, int uecap_xer_in, char *emul_ifa
 
     LOG_I(PHY,"Initializing memory for UE instance %d (%p)\n",inst,PHY_vars_UE_g[inst]);
     PHY_vars_UE_g[inst][0] = init_ue_vars(NULL,inst,0);
+  }
+  init_timer_thread();
+
+  for (inst=0;inst<nb_inst;inst++) {
 
     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);
@@ -866,8 +870,8 @@ static void *UE_phy_stub_thread_rxn_txnp4(void *arg) {
 
     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>7?1:0);
+    proc->subframe_tx=(timer_subframe+4)%10;
+    proc->frame_tx = proc->frame_rx + (proc->subframe_rx>5?1:0);
     //oai_subframe_ind(proc->frame_rx, proc->subframe_rx);
 
 
@@ -929,7 +933,7 @@ static void *UE_phy_stub_thread_rxn_txnp4(void *arg) {
 	tx_req_UE_MAC(UE_mac_inst[Mod_id].tx_req);
 	}*/
       if(UE_mac_inst[Mod_id].dl_config_req!= NULL) {
-	LOG_I( 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){
@@ -943,6 +947,7 @@ static void *UE_phy_stub_thread_rxn_txnp4(void *arg) {
       //#endif
     }
 
+//>>>>>>> Stashed changes
 
 #if UE_TIMING_TRACE
     start_meas(&UE->generic_stat);
@@ -1005,23 +1010,33 @@ static void *UE_phy_stub_thread_rxn_txnp4(void *arg) {
 	    //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);
+	// Generate UL_indications which correspond to UL traffic.
+	if(UE_mac_inst[Mod_id].ul_config_req!= NULL && UE_mac_inst[Mod_id].ul_config_req->ul_config_request_body.ul_config_pdu_list != 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, timer_frame, timer_subframe);
+		//ul_config_req_UE_MAC(UE_mac_inst[Mod_id].ul_config_req, proc->frame_tx, proc->subframe_tx);
+		if(UE_mac_inst[Mod_id].ul_config_req->ul_config_request_body.ul_config_pdu_list != NULL){
+			free(UE_mac_inst[Mod_id].ul_config_req->ul_config_request_body.ul_config_pdu_list);
+			UE_mac_inst[Mod_id].ul_config_req->ul_config_request_body.ul_config_pdu_list = NULL;
+		}
+		free(UE_mac_inst[Mod_id].ul_config_req);
+		UE_mac_inst[Mod_id].ul_config_req = NULL;
+		//UL_indication(UL_INFO);
+	}
+	else if(UE_mac_inst[Mod_id].ul_config_req!=NULL){
+		free(UE_mac_inst[Mod_id].ul_config_req);
+		UE_mac_inst[Mod_id].ul_config_req = NULL;
 	}
-	/*else{
-	  AssertFatal(UE_mac_inst[Mod_id].ul_config_req!= NULL, "Panos-D: Copy of ul_config_req is NULL");
-	  }*/
-
       }
+            	/*else{
+            		AssertFatal(UE_mac_inst[Mod_id].ul_config_req!= NULL, "Panos-D: Copy of ul_config_req is NULL");
+            	}*/
+//>>>>>>> Stashed changes
 
 
-    if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_UL) ||
+    /*if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_UL) ||
 	(UE->frame_parms.frame_type == FDD) )
       if (UE->mode != loop_through_memory){
 	// Panos: Substitute call to phy_procedures Tx with call to phy_stub functions in order to trigger
@@ -1031,7 +1046,7 @@ static void *UE_phy_stub_thread_rxn_txnp4(void *arg) {
 	  ul_config_req_UE_MAC(UE_mac_inst[Mod_id].ul_config_req);
 	  UL_indication(UL_INFO);
 	}
-      }
+      }*/
 
     phy_procedures_UE_SL_RX(UE,proc);
 
@@ -1510,7 +1525,6 @@ int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue, openair0_config_t *openair0_cfg)
 // 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;
@@ -1532,6 +1546,7 @@ static void* timer_thread( void* param ) {
   opp_enabled = 1;
 
   // first check if we are receiving timing indications
+  if(nfapi_mode==4) {
   usleep(10000);
   if (UE->instance_cnt_timer > 0) {
     external_timer = 1;
@@ -1544,6 +1559,7 @@ static void* timer_thread( void* param ) {
     LOG_I(PHY,"Running with external timer\n");
   }
   else LOG_I(PHY,"Running with internal timer\n");
+  }
 
   while (!oai_exit) {
 
@@ -1607,6 +1623,7 @@ static void* timer_thread( void* param ) {
 
 
     //    LOG_E(MAC," Panos-D Absolute time: %f\n", t_diff);
+	    //LOG_E(MAC," Panos-D Absolute time: %f\n", t_diff);
 
     //printf("Panos-D: Absolute time: %f", t_diff);
 
@@ -1629,8 +1646,187 @@ static void* timer_thread( void* param ) {
 
 }
 
+
+
+
+
+
+/*static void* timer_thread( void* param ) {
+<<<<<<< Updated upstream
+=======
+	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) {
+
+	    // 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++;
+	    }
+	    //printf("[timer_thread] Frame: %d, Subframe: %d \n", timer_frame, timer_subframe);
+	    //LOG_I(MAC," Panos-D [timer_thread] Frame: %d, Subframe: %d \n", timer_frame, timer_subframe);
+	    //AssertFatal( 0 == pthread_cond_signal(&phy_stub_ticking->cond_ticking), "");
+	    AssertFatal(pthread_mutex_lock(&phy_stub_ticking->mutex_ticking) ==0,"");
+	    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");
+	    }
+	    }
+	    else{
+	    	LOG_I(MAC," Panos-D: Problemmm");
+	    }
+>>>>>>> Stashed changes
+
+  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;
+    pthread_mutex_unlock(&UE->timer_mutex);
+    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++;
+    }
+    //printf("[timer_thread] Frame: %d, Subframe: %d \n", timer_frame, timer_subframe);
+    //LOG_I(MAC," Panos-D [timer_thread] Frame: %d, Subframe: %d \n", timer_frame, timer_subframe);
+    //AssertFatal( 0 == pthread_cond_signal(&phy_stub_ticking->cond_ticking), "");
+    AssertFatal(pthread_mutex_lock(&phy_stub_ticking->mutex_ticking) ==0,"");
+    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(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
+    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 +
+    //              (double)(end.tv_nsec - start.tv_nsec);
+    //printf("Panos-D: [timer_thread] REAL TIME difference: %f", t_ns);
+
+
+    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)
+
+
+<<<<<<< Updated upstream
+    //    LOG_E(MAC," Panos-D Absolute time: %f\n", t_diff);
+=======
+	    //LOG_E(MAC," Panos-D Absolute time: %f\n", t_diff);
+>>>>>>> Stashed changes
+
+    //printf("Panos-D: Absolute time: %f", t_diff);
+
+
+    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);
+
+    //UE->proc.ticking_var++;
+    // 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;
+
+}*/
+
 int init_timer_thread(void) {
-  PHY_VARS_UE *UE=PHY_vars_UE_g[0];
+	// Panos: CAREFUL Originally this was set to PHY_VARS_UE *UE=PHY_vars_UE_g[0]
+  //PHY_VARS_UE *UE=PHY_vars_UE_g[0];
+	PHY_VARS_UE *UE=PHY_vars_UE_g[0][0];
   phy_stub_ticking = (SF_ticking*)malloc(sizeof(SF_ticking));
   pthread_mutex_init(&UE->timer_mutex,NULL);
   pthread_mutex_init(&UE->timer_cond,NULL);
-- 
GitLab