From 1ed57bbffca4e264bcd710fac03c7c01796a4db2 Mon Sep 17 00:00:00 2001
From: matzakos <panagiotis.matzakos@eurecom.fr>
Date: Tue, 20 Mar 2018 12:00:53 +0100
Subject: [PATCH] Extension to multiple UEs. Currently being tested with two
 UEs. Second UE doesn't always reach the RRC Connection Reconfiguration stage.

---
 nfapi/oai_integration/nfapi_vnf.c         |   1 +
 nfapi/open-nFAPI/nfapi/src/nfapi_p7.c     |   2 +-
 nfapi/open-nFAPI/pnf/src/pnf_p7.c         |   3 +
 nfapi/open-nFAPI/vnf/src/vnf_p7.c         |   5 +
 openair1/SCHED/fapi_l1.c                  |   2 +-
 openair2/LAYER2/MAC/defs.h                |   1 +
 openair2/LAYER2/MAC/eNB_scheduler_RA.c    |   8 +-
 openair2/LAYER2/MAC/eNB_scheduler_ulsch.c |  21 +-
 openair2/LAYER2/MAC/main_ue.c             |   2 +
 openair2/LAYER2/MAC/ra_procedures.c       |   2 +-
 openair2/LAYER2/MAC/rar_tools_ue.c        |   2 +-
 openair2/LAYER2/MAC/ue_procedures.c       |   4 +-
 openair2/LAYER2/PDCP_v10.1.0/pdcp.c       |   8 +-
 openair2/PHY_INTERFACE/phy_stub_UE.c      | 179 +++++++--
 openair2/PHY_INTERFACE/phy_stub_UE.h      |   8 +-
 openair2/RRC/LITE/L2_interface_ue.c       |   1 +
 openair2/RRC/LITE/rrc_UE.c                |  14 +-
 targets/RT/USER/lte-softmodem-stub.c      |  84 ++---
 targets/RT/USER/lte-ue.c                  | 432 +++++++++++++++++++++-
 19 files changed, 647 insertions(+), 132 deletions(-)

diff --git a/nfapi/oai_integration/nfapi_vnf.c b/nfapi/oai_integration/nfapi_vnf.c
index 07c3f1aa91f..8437c2afe3b 100644
--- a/nfapi/oai_integration/nfapi_vnf.c
+++ b/nfapi/oai_integration/nfapi_vnf.c
@@ -1199,6 +1199,7 @@ int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req) {
 
 int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req) {
 
+	//LOG_I(MAC, "Panos-D: oai_nfapi_ul_config_req 1 \n");
   nfapi_vnf_p7_config_t *p7_config = vnf.p7_vnfs[0].config;
 
   ul_config_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!!
diff --git a/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c b/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c
index fcca18241c3..6b41d4ead66 100644
--- a/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c
+++ b/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c
@@ -2763,7 +2763,7 @@ int nfapi_p7_message_pack(void *pMessageBuf, void *pPackedBuf, uint32_t packedBu
 
 	if(result == 0)
 	{
-		//printf( "Panos-D: P7 Pack failed to pack message\n");
+		printf( "Panos-D: P7 Pack failed to pack message\n");
 		NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 Pack failed to pack message\n");
 		return -1;
 	}
diff --git a/nfapi/open-nFAPI/pnf/src/pnf_p7.c b/nfapi/open-nFAPI/pnf/src/pnf_p7.c
index 52412084d38..8cbd84bd0b2 100644
--- a/nfapi/open-nFAPI/pnf/src/pnf_p7.c
+++ b/nfapi/open-nFAPI/pnf/src/pnf_p7.c
@@ -675,6 +675,8 @@ int pnf_p7_subframe_ind(pnf_p7_t* pnf_p7, uint16_t phy_id, uint16_t sfn_sf)
                 //printf("subframe_buffer->sfn_sf:%d sfn_sf:%d\n", subframe_buffer->sfn_sf, sfn_sf);
 		if(tx_subframe_buffer->sfn_sf == sfn_sf_tx)
 		{
+			//printf("Panos-D: pnf_p7_subframe_ind tx_subframe_buffer->sfn_sf == sfn_sf_tx satisfied, pnf_p7: %d MINE: %d.%d, REAL: %d.%d \n",
+				//	tx_subframe_buffer->sfn_sf, sfn_sf_tx>>4, sfn_sf_tx&0xf, tx_subframe_buffer->sfn_sf>>4, tx_subframe_buffer->sfn_sf&0xf);
 			if(tx_subframe_buffer->tx_req != 0)
 			{
 				if(pnf_p7->_public.tx_req)
@@ -1366,6 +1368,7 @@ void pnf_handle_dl_node_sync(void *pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7, u
 	// unpack the message
 	if (nfapi_p7_message_unpack(pRecvMsg, recvMsgLen, &dl_node_sync, sizeof(dl_node_sync), &pnf_p7->_public.codec_config) < 0)
 	{
+		printf("Panos-D: %s: Unpack message failed, ignoring\n", __FUNCTION__);
 		NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__);
 		return;
 	}
diff --git a/nfapi/open-nFAPI/vnf/src/vnf_p7.c b/nfapi/open-nFAPI/vnf/src/vnf_p7.c
index 13041767522..bcd06be6a22 100644
--- a/nfapi/open-nFAPI/vnf/src/vnf_p7.c
+++ b/nfapi/open-nFAPI/vnf/src/vnf_p7.c
@@ -1247,9 +1247,14 @@ void vnf_handle_timing_info(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7)
           int16_t vnf_pnf_sfnsf_delta = NFAPI_SFNSF2DEC(vnf_p7->p7_connections[0].sfn_sf) - NFAPI_SFNSF2DEC(ind.last_sfn_sf);
 
           //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() PNF:SFN/SF:%d VNF:SFN/SF:%d deltaSFNSF:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(ind.last_sfn_sf), NFAPI_SFNSF2DEC(vnf_p7->p7_connections[0].sfn_sf), vnf_pnf_sfnsf_delta);
+
+          // Panos: Careful here!!!
           if (vnf_pnf_sfnsf_delta>1 || vnf_pnf_sfnsf_delta < -1)
+          //if (vnf_pnf_sfnsf_delta>0 || vnf_pnf_sfnsf_delta < 0)
           {
             NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() LARGE SFN/SF DELTA between PNF and VNF delta:%d VNF:%d PNF:%d\n\n\n\n\n\n\n\n\n", __FUNCTION__, vnf_pnf_sfnsf_delta, NFAPI_SFNSF2DEC(vnf_p7->p7_connections[0].sfn_sf), NFAPI_SFNSF2DEC(ind.last_sfn_sf));
+            // Panos: Careful here!!!
+            //vnf_p7->p7_connections[0].sfn_sf = ind.last_sfn_sf;
           }
         }
 }
diff --git a/openair1/SCHED/fapi_l1.c b/openair1/SCHED/fapi_l1.c
index 59b36a18815..d98737b8550 100644
--- a/openair1/SCHED/fapi_l1.c
+++ b/openair1/SCHED/fapi_l1.c
@@ -816,7 +816,7 @@ void schedule_response(Sched_Rsp_t *Sched_INFO)
   if (nfapi_mode) {
     if (number_ul_pdu>0)
     {
-      //LOG_D(PHY, "UL_CONFIG to send to PNF\n");
+      //LOG_I(PHY, "UL_CONFIG to send to PNF\n");
       oai_nfapi_ul_config_req(UL_req);
       UL_req->ul_config_request_body.number_of_pdus=0;
       number_ul_pdu=0;
diff --git a/openair2/LAYER2/MAC/defs.h b/openair2/LAYER2/MAC/defs.h
index 6d61d8e92b4..1491a12411a 100644
--- a/openair2/LAYER2/MAC/defs.h
+++ b/openair2/LAYER2/MAC/defs.h
@@ -1484,6 +1484,7 @@ typedef struct {
   nfapi_dl_config_request_t* dl_config_req;
   nfapi_ul_config_request_t* ul_config_req;
   nfapi_hi_dci0_request_t* hi_dci0_req;
+  nfapi_tx_request_pdu_t* tx_request_pdu_list;
   nfapi_tx_request_t* tx_req;
 
   eth_params_t         eth_params_n;
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_RA.c b/openair2/LAYER2/MAC/eNB_scheduler_RA.c
index 394b3c7e9f1..db874c33ba4 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_RA.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_RA.c
@@ -186,10 +186,10 @@ add_msg3(module_id_t module_idP, int CC_id, RA_t * ra, frame_t frameP,
 	      module_idP, frameP, subframeP, CC_id, ra->Msg3_frame,
 	      ra->Msg3_subframe);
 
-	LOG_D(MAC,
-	      "Frame %d, Subframe %d Adding Msg3 UL Config Request for (%d,%d) : (%d,%d,%d)\n",
+	LOG_I(MAC,
+	      "Frame %d, Subframe %d Adding Msg3 UL Config Request for (%d,%d) : (%d,%d,%d) for rnti: %d\n",
 	      frameP, subframeP, ra->Msg3_frame, ra->Msg3_subframe,
-	      ra->msg3_nb_rb, ra->msg3_first_rb, ra->msg3_round);
+	      ra->msg3_nb_rb, ra->msg3_first_rb, ra->msg3_round, ra->rnti);
 
 	ul_config_pdu =
 	    &ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus];
@@ -693,7 +693,7 @@ generate_Msg2(module_id_t module_idP, int CC_idP, frame_t frameP,
 			 cc[CC_idP].RAR_pdu.payload, N_RB_DL, 7);
 		add_msg3(module_idP, CC_idP, ra, frameP, subframeP);
 		ra->state = WAITMSG3;
-                LOG_D(MAC,"[eNB %d][RAPROC] Frame %d, Subframe %d: state:WAITMSG3\n", module_idP, frameP, subframeP);
+                LOG_I(MAC,"[eNB %d][RAPROC] Frame %d, Subframe %d: state:WAITMSG3\n", module_idP, frameP, subframeP);
 
 		// DL request
 		mac->TX_req[CC_idP].sfn_sf = (frameP << 4) + subframeP;
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
index 0ee93f0cd6a..c597f38fd9a 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
@@ -87,6 +87,7 @@ rx_sdu(const module_id_t enb_mod_idP,
        const uint16_t sdu_lenP,
        const uint16_t timing_advance, const uint8_t ul_cqi)
 {
+	//LOG_I(MAC, "Panos-D: rx_sdu 1 \n");
     int current_rnti = rntiP;
     unsigned char rx_ces[MAX_NUM_CE], num_ce, num_sdu, i, *payload_ptr;
     unsigned char rx_lcids[NB_RB_MAX];
@@ -155,7 +156,7 @@ rx_sdu(const module_id_t enb_mod_idP,
 							  UE_id));
 	    }
 	} else {		// we've got an error
-	    LOG_D(MAC,
+	    LOG_I(MAC,
 		  "[eNB %d][PUSCH %d] CC_id %d ULSCH in error in round %d, ul_cqi %d\n",
 		  enb_mod_idP, harq_pid, CC_idP,
 		  UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid],
@@ -185,7 +186,7 @@ rx_sdu(const module_id_t enb_mod_idP,
 		    radioResourceConfigCommon->rach_ConfigCommon.
 		    maxHARQ_Msg3Tx);
 
-	LOG_D(MAC,
+	LOG_I(MAC,
 	      "[eNB %d][PUSCH %d] CC_id %d [RAPROC Msg3] Received ULSCH sdu round %d from PHY (rnti %x, RA_id %d) ul_cqi %d\n",
 	      enb_mod_idP, harq_pid, CC_idP, ra[RA_id].msg3_round,
 	      current_rnti, RA_id, ul_cqi);
@@ -217,10 +218,11 @@ rx_sdu(const module_id_t enb_mod_idP,
 		add_msg3(enb_mod_idP, CC_idP, &ra[RA_id], frameP,
 			 subframeP);
 	    }
+	    LOG_I(MAC, "Panos-D: rx_sdu() 2 before error returning \n");
 	    return;
 	}
     } else {
-	LOG_W(MAC,
+	LOG_I(MAC,
 	      "Cannot find UE or RA corresponding to ULSCH rnti %x, dropping it\n",
 	      current_rnti);
 	return;
@@ -1043,6 +1045,7 @@ schedule_ulsch(module_id_t module_idP, frame_t frameP,
 	for (i = 0; i < NB_RA_PROC_MAX; i++) {
 	    if ((cc->ra[i].state == WAITMSG3) &&
 		(cc->ra[i].Msg3_subframe == sched_subframe)) {
+	    	//LOG_I(MAC, "Panos-D: schedule_ulsch WAITMSG3 \n");
 		first_rb[CC_id]++;
 		//    cc->ray[i].Msg3_subframe = -1;
 		break;
@@ -1062,6 +1065,7 @@ schedule_ulsch_rnti(module_id_t module_idP,
 		    unsigned char sched_subframeP, uint16_t * first_rb)
 {
 
+	//LOG_I(MAC, "Panos-D: schedule_ulsch_rnti \n");
     int UE_id;
     uint8_t aggregation = 2;
     rnti_t rnti = -1;
@@ -1109,7 +1113,7 @@ schedule_ulsch_rnti(module_id_t module_idP,
 	// don't schedule if Msg4 is not received yet
 	if (UE_list->UE_template[UE_PCCID(module_idP, UE_id)][UE_id].
 	    configured == FALSE) {
-	    LOG_D(MAC,
+	    LOG_I(MAC,
 		  "[eNB %d] frame %d subfarme %d, UE %d: not configured, skipping UE scheduling \n",
 		  module_idP, frameP, subframeP, UE_id);
 	    continue;
@@ -1118,7 +1122,7 @@ schedule_ulsch_rnti(module_id_t module_idP,
 	rnti = UE_RNTI(module_idP, UE_id);
 
 	if (rnti == NOT_A_RNTI) {
-	    LOG_W(MAC, "[eNB %d] frame %d subfarme %d, UE %d: no RNTI \n",
+	    LOG_I(MAC, "[eNB %d] frame %d subfarme %d, UE %d: no RNTI \n",
 		  module_idP, frameP, subframeP, UE_id);
 	    continue;
 	}
@@ -1148,7 +1152,7 @@ schedule_ulsch_rnti(module_id_t module_idP,
 	     */
 	    if (UE_list->UE_sched_ctrl[UE_id].ul_failure_timer == 0 &&
 		UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 0) {
-		LOG_W(MAC,
+		LOG_I(MAC,
 		      "[eNB %d] frame %d subframe %d, UE %d/%x CC %d: UE in weird state, let's put it 'out of sync'\n",
 		      module_idP, frameP, subframeP, UE_id, rnti, CC_id);
 		// inform RRC of failure and clear timer
@@ -1173,7 +1177,7 @@ schedule_ulsch_rnti(module_id_t module_idP,
 
 	    if (CCE_allocation_infeasible
 		(module_idP, CC_id, 1, subframeP, aggregation, rnti)) {
-		LOG_W(MAC,
+		LOG_I(MAC,
 		      "[eNB %d] frame %d subframe %d, UE %d/%x CC %d: not enough nCCE\n",
 		      module_idP, frameP, subframeP, UE_id, rnti, CC_id);
 		continue;	// break;
@@ -1181,7 +1185,7 @@ schedule_ulsch_rnti(module_id_t module_idP,
 
 	    /* be sure that there are some free RBs */
 	    if (first_rb[CC_id] >= N_RB_UL - 1) {
-		LOG_W(MAC,
+		LOG_I(MAC,
 		      "[eNB %d] frame %d subframe %d, UE %d/%x CC %d: dropping, not enough RBs\n",
 		      module_idP, frameP, subframeP, UE_id, rnti, CC_id);
 		continue;
@@ -1463,6 +1467,7 @@ schedule_ulsch_rnti(module_id_t module_idP,
 		      T_INT(rb_table[rb_table_index]), T_INT(round));
 
 		    // fill in NAK information
+		    LOG_I(MAC, "schedule_ulsch_rnti() Retransmission case! \n");
 
 		    hi_dci0_pdu = &hi_dci0_req_body->hi_dci0_pdu_list[hi_dci0_req_body->number_of_dci + hi_dci0_req_body->number_of_hi];
 		    memset((void *) hi_dci0_pdu, 0,
diff --git a/openair2/LAYER2/MAC/main_ue.c b/openair2/LAYER2/MAC/main_ue.c
index 64326dec614..e9992dd665a 100644
--- a/openair2/LAYER2/MAC/main_ue.c
+++ b/openair2/LAYER2/MAC/main_ue.c
@@ -60,8 +60,10 @@ void dl_phy_sync_success(module_id_t module_idP, frame_t frameP, unsigned char e
 
     if (first_sync == 1 && !(mme_enabled == 1)) {
 	//layer2_init_UE(module_idP);
+    	LOG_I(MAC, "Panos-D: dl_phy_sync_success 1 \n");
 	openair_rrc_ue_init(module_idP, eNB_index);
     } else {
+    	LOG_I(MAC, "Panos-D: dl_phy_sync_success 2 \n");
 	rrc_in_sync_ind(module_idP, frameP, eNB_index);
     }
 }
diff --git a/openair2/LAYER2/MAC/ra_procedures.c b/openair2/LAYER2/MAC/ra_procedures.c
index ac18fe3e7cd..66932dfdeb0 100644
--- a/openair2/LAYER2/MAC/ra_procedures.c
+++ b/openair2/LAYER2/MAC/ra_procedures.c
@@ -327,7 +327,7 @@ Msg3_transmitted(module_id_t module_idP, uint8_t CC_id,
 		"Transmission on secondary CCs is not supported yet\n");
 
     // start contention resolution timer
-    LOG_D(MAC,
+    LOG_I(MAC,
 	  "[UE %d][RAPROC] Frame %d : Msg3_tx: Setting contention resolution timer\n",
 	  module_idP, frameP);
     UE_mac_inst[module_idP].RA_contention_resolution_cnt = 0;
diff --git a/openair2/LAYER2/MAC/rar_tools_ue.c b/openair2/LAYER2/MAC/rar_tools_ue.c
index ab193c7a66b..fc4ae29c1c1 100644
--- a/openair2/LAYER2/MAC/rar_tools_ue.c
+++ b/openair2/LAYER2/MAC/rar_tools_ue.c
@@ -63,7 +63,7 @@ uint16_t ue_process_rar(const module_id_t module_idP, const int CC_id, const fra
 	}
 
 	if (rarh->RAPID == preamble_index) {
-	    LOG_D(PHY, "Found RAR with the intended RAPID %d\n",
+	    LOG_I(PHY, "Found RAR with the intended RAPID %d\n",
 		  rarh->RAPID);
 	    rar = (uint8_t *) (dlsch_buffer + n_rarh + (n_rarpy - 1) * 6);
 	    break;
diff --git a/openair2/LAYER2/MAC/ue_procedures.c b/openair2/LAYER2/MAC/ue_procedures.c
index 336c183bd78..5219434df62 100644
--- a/openair2/LAYER2/MAC/ue_procedures.c
+++ b/openair2/LAYER2/MAC/ue_procedures.c
@@ -1625,7 +1625,7 @@ ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP,
 	   uint8_t * ulsch_buffer, uint16_t buflen, uint8_t * access_mode)
 {
 
-	LOG_I(MAC, "Panos-D: In ue_get_sdu() 1 \n");
+	LOG_I(MAC, "Panos-D: UE[%d] In ue_get_sdu() 1  \n", module_idP);
     uint8_t total_rlc_pdu_header_len = 0, rlc_pdu_header_len_last = 0;
     uint16_t buflen_remain = 0;
     uint8_t bsr_len = 0, bsr_ce_len = 0, bsr_header_len = 0;
@@ -2214,7 +2214,7 @@ ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP,
 	  buflen - sdu_length_total - payload_offset);
     // cycle through SDUs and place in ulsch_buffer
     if (sdu_length_total) {
-    	LOG_I(MAC, "Panos-D: ue_get_sdu() 2 before copying to ulsch_buffer");
+    	LOG_I(MAC, "Panos-D: [UE %d] ue_get_sdu() 2 before copying to ulsch_buffer, SFN/SF: %d/%d \n \n \n", module_idP, frameP, subframe);
 	memcpy(&ulsch_buffer[payload_offset], ulsch_buff,
 	       sdu_length_total);
     }
diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c
index 174db3bdfa7..f389c5d3f83 100644
--- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c
+++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c
@@ -372,22 +372,22 @@ boolean_t pdcp_data_req(
     break;
 
   case RLC_OP_STATUS_BAD_PARAMETER:
-    LOG_W(PDCP, "Data sending request over RLC failed with 'Bad Parameter' reason!\n");
+    LOG_D(PDCP, "Data sending request over RLC failed with 'Bad Parameter' reason!\n");
     ret= FALSE;
     break;
 
   case RLC_OP_STATUS_INTERNAL_ERROR:
-    LOG_W(PDCP, "Data sending request over RLC failed with 'Internal Error' reason!\n");
+    LOG_D(PDCP, "Data sending request over RLC failed with 'Internal Error' reason!\n");
     ret= FALSE;
     break;
 
   case RLC_OP_STATUS_OUT_OF_RESSOURCES:
-    LOG_W(PDCP, "Data sending request over RLC failed with 'Out of Resources' reason!\n");
+    LOG_D(PDCP, "Data sending request over RLC failed with 'Out of Resources' reason!\n");
     ret= FALSE;
     break;
 
   default:
-    LOG_W(PDCP, "RLC returned an unknown status code after PDCP placed the order to send some data (Status Code:%d)\n", rlc_status);
+    LOG_D(PDCP, "RLC returned an unknown status code after PDCP placed the order to send some data (Status Code:%d)\n", rlc_status);
     ret= FALSE;
     break;
   }
diff --git a/openair2/PHY_INTERFACE/phy_stub_UE.c b/openair2/PHY_INTERFACE/phy_stub_UE.c
index 77ccc280b6b..9c819e56cc3 100644
--- a/openair2/PHY_INTERFACE/phy_stub_UE.c
+++ b/openair2/PHY_INTERFACE/phy_stub_UE.c
@@ -217,6 +217,7 @@ void fill_rach_indication_UE_MAC(int Mod_id,int frame,int subframe, UL_IND_t *UL
 	    //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.vendor_extension							= NULL;
 
 	    UL_INFO->rach_ind.rach_indication_body.tl.tag                              = NFAPI_RACH_INDICATION_BODY_TAG;
 
@@ -592,6 +593,9 @@ void handle_nfapi_ul_pdu_UE_MAC(module_id_t Mod_id,
     		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: Modification
+    		UE_mac_inst[Mod_id].UE_mode[0] = PUSCH;
+    		UE_mac_inst[Mod_id].first_ULSCH_Tx = 0;
 
     		// Panos: This should be done after the reception of the respective hi_dci0
     		//UE_mac_inst[Mod_id].first_ULSCH_Tx = 0;
@@ -620,6 +624,9 @@ void handle_nfapi_ul_pdu_UE_MAC(module_id_t Mod_id,
 			  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;
+			  // Panos: Modification
+			  UE_mac_inst[Mod_id].UE_mode[0] = PUSCH;
+			  UE_mac_inst[Mod_id].first_ULSCH_Tx = 0;
 		  }
 		  else {
 			  LOG_I(MAC, "Panos-D: handle_nfapi_ul_pdu_UE_MAC 3.1 \n");
@@ -650,6 +657,9 @@ void handle_nfapi_ul_pdu_UE_MAC(module_id_t Mod_id,
 			  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;
+			  // Panos: Modification
+			  UE_mac_inst[Mod_id].UE_mode[0] = PUSCH;
+			  UE_mac_inst[Mod_id].first_ULSCH_Tx = 0;
 		  }
 		  else {
 			  ue_get_sdu( Mod_id, 0, frame, subframe, 0, ulsch_buffer, buflen, &access_mode);
@@ -678,6 +688,9 @@ void handle_nfapi_ul_pdu_UE_MAC(module_id_t Mod_id,
 			  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;
+			  // Panos: Modification
+			  UE_mac_inst[Mod_id].UE_mode[0] = PUSCH;
+			  UE_mac_inst[Mod_id].first_ULSCH_Tx = 0;
 		  }
 		  else {
 			  ue_get_sdu( Mod_id, 0, frame, subframe, 0, ulsch_buffer, buflen, &access_mode);
@@ -748,9 +761,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 timer_frame, int timer_subframe)
+int ul_config_req_UE_MAC(nfapi_ul_config_request_t* req, int timer_frame, int timer_subframe, module_id_t Mod_id)
 {
-	if (req!=NULL && req->ul_config_request_body.ul_config_pdu_list !=NULL){
+	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),
@@ -791,7 +804,8 @@ int ul_config_req_UE_MAC(nfapi_ul_config_request_t* req, int timer_frame, int ti
   //struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0];
   //eNB_rxtx_proc_t *proc = &eNB->proc.proc_rxtx[0];
 
-  module_id_t Mod_id = 0; //Panos: Currently static (only for one UE) but this should change.
+  //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_D(MAC, "Panos-D: ul_config_req_UE_MAC 1 \n");
 
@@ -849,7 +863,7 @@ int ul_config_req_UE_MAC(nfapi_ul_config_request_t* req, int timer_frame, int ti
   //subtract_subframe(&sfn, &sf, 4);
 
 
-  LOG_I(MAC, "Panos-D: ul_config_req_UE_MAC() TOTAL NUMBER OF UL_CONFIG PDUs: %d", req->ul_config_request_body.number_of_pdus);
+  LOG_I(MAC, "Panos-D: ul_config_req_UE_MAC() TOTAL NUMBER OF UL_CONFIG PDUs: %d, SFN/SF: %d/%d \n", req->ul_config_request_body.number_of_pdus, timer_frame, timer_subframe);
 
 
 
@@ -858,14 +872,15 @@ int ul_config_req_UE_MAC(nfapi_ul_config_request_t* req, int timer_frame, int ti
     //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_D(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 ||
-    		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
+    		(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].ulsch_pdu.ulsch_pdu_rel8.rnti == UE_mac_inst[Mod_id].crnti) ||
+    		(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].ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti == UE_mac_inst[Mod_id].crnti) ||
+    		(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].ulsch_cqi_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti == UE_mac_inst[Mod_id].crnti) ||
+    		(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].ulsch_cqi_harq_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti == UE_mac_inst[Mod_id].crnti) ||
+    		(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].uci_cqi_harq_pdu.ue_information.ue_information_rel8.rnti == UE_mac_inst[Mod_id].crnti) ||
+    		(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].uci_sr_pdu.ue_information.ue_information_rel8.rnti == UE_mac_inst[Mod_id].crnti) ||
+    		(req->ul_config_request_body.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].uci_cqi_sr_harq_pdu.ue_information.ue_information_rel8.rnti == UE_mac_inst[Mod_id].crnti)
        )
     {
     	/*switch (req->ul_config_request_body.ul_config_pdu_list[i].pdu_type){
@@ -1049,13 +1064,13 @@ int tx_req_UE_MAC(nfapi_tx_request_t* req)
 }
 
 
-int dl_config_req_UE_MAC(nfapi_dl_config_request_t* req)
+int dl_config_req_UE_MAC(nfapi_dl_config_request_t* req, module_id_t Mod_id) //, nfapi_tx_request_pdu_t* tx_request_pdu_list)
 {
 	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.
+  //Mod_id = 0; //Panos: Currently static (only for one UE) but this should change.
 
   /*struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0];
   eNB_rxtx_proc_t *proc = &eNB->proc.proc_rxtx[0];*/
@@ -1084,15 +1099,29 @@ int dl_config_req_UE_MAC(nfapi_dl_config_request_t* req)
 		if (dl_config_pdu_list[i].dci_dl_pdu.dci_dl_pdu_rel8.rnti_type == 1) {
 			// C-RNTI (Normal DLSCH case)
 			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);
+			if (dl_config_pdu_tmp->pdu_type == NFAPI_DL_CONFIG_DLSCH_PDU_TYPE && UE_mac_inst[Mod_id].crnti == dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.rnti){
+				// PANTEL
+				/*nfapi_tx_request_pdu_t *ptr = tx_request_pdu_list;
+				ptr += dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index*(sizeof(nfapi_tx_request_pdu_t));
+				nfapi_tx_request_pdu_t temp;
+				memset(&temp, 0, sizeof(nfapi_tx_request_pdu_t));
+				//if (!memcmp(&temp, ptr, sizeof(temp)) ...
+				if( *(char*)ptr != 0){
+				//if(tx_request_pdu_list[dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index].segments[0].segment_data!= NULL && tx_request_pdu_list[dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index].segments[0].segment_length >0){
+				*/
+
+				if(dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index <= tx_req_num_elems -1){
+				//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, TX_PDU index: %d, tx_req_num_elems: %d \n", NFAPI_SFNSF2DEC(req->sfn_sf), i, dl_config_pdu_list[i].pdu_size, dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index, tx_req_num_elems);
 					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,
 							0);
 					i++;
 				}
+				else{
+					LOG_E(MAC,"dl_config_req_UE_MAC 2: Problem with receiving data: sfn/sf:%d PDU[%d] size:%d, TX_PDU index: %d\n", NFAPI_SFNSF2DEC(req->sfn_sf), i, dl_config_pdu_list[i].pdu_size, dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index);
+				}
 			}
 			else {
 				LOG_E(MAC,"[UE %d] Frame %d, subframe %d : Cannot extract DLSCH PDU from NFAPI\n",Mod_id, sfn,sf);
@@ -1104,22 +1133,31 @@ int dl_config_req_UE_MAC(nfapi_dl_config_request_t* req)
 				//pdu = Tx_req->tx_request_body.tx_pdu_list[dl_config_pdu->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){
+				if(dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index <= tx_req_num_elems -1){
+				//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,
 							tx_request_pdu_list[dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index].segments[0].segment_length);
 					i++;
 				}
+				else{
+					LOG_E(MAC,"dl_config_req_UE_MAC 3: Problem with receiving SI: sfn/sf:%d PDU[%d] size:%d, TX_PDU index: %d\n", NFAPI_SFNSF2DEC(req->sfn_sf), i, dl_config_pdu_list[i].pdu_size, dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index);
+				}
 			}
 			else 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 == 0xFFFE){
 				// P_RNTI case
 				//pdu = Tx_req->tx_request_body.tx_pdu_list[dl_config_pdu->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){
+
+				if (dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index <= tx_req_num_elems -1){
+				//if(tx_request_pdu_list + dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index!= NULL){
 					ue_decode_p(Mod_id, 0, sfn, 0,
 							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);
 					i++;
 				}
+				else{
+					LOG_E(MAC,"dl_config_req_UE_MAC: Problem with receiving Paging: sfn/sf:%d PDU[%d] size:%d, TX_PDU index: %d\n", NFAPI_SFNSF2DEC(req->sfn_sf), i, dl_config_pdu_list[i].pdu_size, dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index);
+				}
 			}
 			else if(dl_config_pdu_tmp->pdu_type == NFAPI_DL_CONFIG_DLSCH_PDU_TYPE) {
 				// RA-RNTI case
@@ -1129,9 +1167,10 @@ int dl_config_req_UE_MAC(nfapi_dl_config_request_t* req)
 				//rnti_t c_rnti = UE_mac_inst[Mod_id].crnti;
 				rnti_t ra_rnti = UE_mac_inst[Mod_id].RA_prach_resources.ra_RNTI;
 				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_mac_inst[Mod_id].RA_prach_resources.Msg3!=NULL) && (ra_rnti== dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.rnti) &&
+				  //(tx_request_pdu_list + dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index!= NULL)) {
+				  (dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index <= tx_req_num_elems -1)) {
+					LOG_E(MAC,"dl_config_req_UE_MAC 5 Received RAR, PreambleIndex: %d \n", UE_mac_inst[Mod_id].RA_prach_resources.ra_PreambleIndex);
 					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,
@@ -1155,10 +1194,12 @@ int dl_config_req_UE_MAC(nfapi_dl_config_request_t* req)
     	// for our case.
     	LOG_E(MAC,"dl_config_req_UE_MAC 4 Received MIB: sfn/sf: %d.%d \n", sfn, sf);
     	if(UE_mac_inst[Mod_id].UE_mode[0] == NOT_SYNCHED){
-    		dl_phy_sync_success(Mod_id,sfn,0, 0);
+    		dl_phy_sync_success(Mod_id,sfn,0, 1);
     		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;
     	}
+    	else
+    		dl_phy_sync_success(Mod_id,sfn,0, 0);
 
     }
 
@@ -1177,10 +1218,13 @@ int dl_config_req_UE_MAC(nfapi_dl_config_request_t* req)
     req->vendor_extension = NULL;
   }*/
 
-  if(tx_request_pdu_list!=NULL){
+  // Panos: Modification here BRING THIS BACK!
+  /*if(tx_request_pdu_list!=NULL){
 	  free(tx_request_pdu_list);
   	  tx_request_pdu_list = NULL;
-  }
+  }*/
+
+
   if(req->dl_config_request_body.dl_config_pdu_list!=NULL){
 	  free(req->dl_config_request_body.dl_config_pdu_list);
 	  req->dl_config_request_body.dl_config_pdu_list = NULL;
@@ -1214,18 +1258,19 @@ int deallocate_mem_nfapi_dl(nfapi_dl_config_request_t* req, nfapi_tx_request_pdu
 
 
 
-int hi_dci0_req_UE_MAC(nfapi_hi_dci0_request_t* req)
+int hi_dci0_req_UE_MAC(nfapi_hi_dci0_request_t* req, module_id_t Mod_id)
 {
 	if (req!=NULL && req->hi_dci0_request_body.hi_dci0_pdu_list!=NULL){
   LOG_D(PHY,"[UE-PHY_STUB] hi dci0 request sfn_sf:%d number_of_dci:%d number_of_hi:%d\n", NFAPI_SFNSF2DEC(req->sfn_sf), req->hi_dci0_request_body.number_of_dci, req->hi_dci0_request_body.number_of_hi);
 
   //phy_info* phy = (phy_info*)(pnf_p7->user_data);
 
-  module_id_t Mod_id = 0; //Panos: Currently static (only for one UE) but this should change.
+  //Mod_id = 0; //Panos: Currently static (only for one UE) but this should change.
 
   /*struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0];
   eNB_rxtx_proc_t *proc = &eNB->proc.proc_rxtx[0];*/
 
+
   for (int i=0; i<req->hi_dci0_request_body.number_of_dci + req->hi_dci0_request_body.number_of_hi; i++)
   {
     LOG_D(PHY,"[UE-PHY_STUB] HI_DCI0_REQ sfn_sf:%d PDU[%d]\n", NFAPI_SFNSF2DEC(req->sfn_sf), i);
@@ -1255,14 +1300,7 @@ int hi_dci0_req_UE_MAC(nfapi_hi_dci0_request_t* req)
     }
   }
 
-  /*if(req->hi_dci0_request_body.hi_dci0_pdu_list!=NULL){
-	  free(req->hi_dci0_request_body.hi_dci0_pdu_list);
-	  req->hi_dci0_request_body.hi_dci0_pdu_list = NULL;
   }
-  free(req);
-  req = NULL;*/
-
-	}
 	/*else if(req!=NULL){
 		free(req);
 		req = NULL;
@@ -1281,9 +1319,13 @@ int memcpy_dl_config_req (nfapi_pnf_p7_config_t* pnf_p7, nfapi_dl_config_request
 {
 	//LOG_I(MAC, "Panos-D: memcpy_dl_config_req 1");
 
+
 	module_id_t Mod_id = 0; //Panos: Currently static (only for one UE) but this should change.
+
+	for (Mod_id=0; Mod_id<NB_UE_INST; Mod_id++){
+
 	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, Mod_id:%d \n", Mod_id);
 
 
 	//UE_mac_inst[Mod_id].dl_config_req->header = req->header;
@@ -1310,6 +1352,8 @@ int memcpy_dl_config_req (nfapi_pnf_p7_config_t* pnf_p7, nfapi_dl_config_request
 		UE_mac_inst[Mod_id].dl_config_req->dl_config_request_body.dl_config_pdu_list[i] = req->dl_config_request_body.dl_config_pdu_list[i];
 	}
 
+	}
+
 	//UE_mac_inst[Mod_id].dl_config_req = req;
 	return 0;
 
@@ -1321,7 +1365,10 @@ int memcpy_ul_config_req (nfapi_pnf_p7_config_t* pnf_p7, nfapi_ul_config_request
 
 	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 = (nfapi_ul_config_request_t*)malloc(sizeof(nfapi_ul_config_request_t));
+
+	for (Mod_id=0; Mod_id<NB_UE_INST; Mod_id++){
+
+		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;
@@ -1346,6 +1393,7 @@ int memcpy_ul_config_req (nfapi_pnf_p7_config_t* pnf_p7, nfapi_ul_config_request
 			//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);
 		}
+	}
 
 
 
@@ -1353,7 +1401,10 @@ int memcpy_ul_config_req (nfapi_pnf_p7_config_t* pnf_p7, nfapi_ul_config_request
 	return 0;
 }
 
-int memcpy_tx_req (nfapi_pnf_p7_config_t* pnf_p7, nfapi_tx_request_t* req)
+
+
+
+/*int memcpy_tx_req (nfapi_pnf_p7_config_t* pnf_p7, nfapi_tx_request_t* req)
 {
 	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);
@@ -1370,10 +1421,58 @@ int memcpy_tx_req (nfapi_pnf_p7_config_t* pnf_p7, nfapi_tx_request_t* req)
 
 
 	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));
+	UE_mac_inst[Mod_id].tx_request_pdu_list = (nfapi_tx_request_pdu_t*) malloc(num_elem*sizeof(nfapi_tx_request_pdu_t));
 	//UE_mac_inst[Mod_id].tx_req = (nfapi_tx_request_t*) malloc(sizeof(nfapi_tx_request_t));
 	//memcpy(UE_mac_inst[Mod_id].tx_req, req, sizeof(req));
 	for (int i=0; i<num_elem; i++) {
+		UE_mac_inst[Mod_id].tx_request_pdu_list[i].num_segments = req->tx_request_body.tx_pdu_list[i].num_segments;
+		UE_mac_inst[Mod_id].tx_request_pdu_list[i].pdu_index = req->tx_request_body.tx_pdu_list[i].pdu_index;
+		UE_mac_inst[Mod_id].tx_request_pdu_list[i].pdu_length = req->tx_request_body.tx_pdu_list[i].pdu_length;
+		for (int j=0; j<req->tx_request_body.tx_pdu_list[i].num_segments; j++){
+			//*tx_request_pdu_list[i].segments[j].segment_data = *req->tx_request_body.tx_pdu_list[i].segments[j].segment_data;
+			UE_mac_inst[Mod_id].tx_request_pdu_list[i].segments[j].segment_length = req->tx_request_body.tx_pdu_list[i].segments[j].segment_length;
+			if(UE_mac_inst[Mod_id].tx_request_pdu_list[i].segments[j].segment_length > 0){
+				UE_mac_inst[Mod_id].tx_request_pdu_list[i].segments[j].segment_data = (uint8_t*)malloc(UE_mac_inst[Mod_id].tx_request_pdu_list[i].segments[j].segment_length*sizeof (uint8_t));
+			memcpy(UE_mac_inst[Mod_id].tx_request_pdu_list[i].segments[j].segment_data, req->tx_request_body.tx_pdu_list[i].segments[j].segment_data, UE_mac_inst[Mod_id].tx_request_pdu_list[i].segments[j].segment_length);
+			}
+			//tx_request_pdu_list[i].segments[j].segment_length = req->tx_request_body.tx_pdu_list[i].segments[j].segment_length;
+		}
+
+		//tx_request_pdu_list[i].segments = req->tx_request_body.tx_pdu_list[i].segments;
+	}
+
+
+	// Panos: Old way. Not possible to use because by the time we call tx_req_UE_MAC tx_req memory has been deallocated within nfapi.
+	//UE_mac_inst[Mod_id].tx_req = req;
+	return 0;
+}*/
+
+
+
+
+
+int memcpy_tx_req (nfapi_pnf_p7_config_t* pnf_p7, nfapi_tx_request_t* req)
+{
+	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);
+
+
+
+	//int num_elem = req->tx_request_body.number_of_pdus;
+	tx_req_num_elems = req->tx_request_body.number_of_pdus;
+	tx_request_pdu_list = (nfapi_tx_request_pdu_t*) calloc(tx_req_num_elems, sizeof(nfapi_tx_request_pdu_t));
+	//UE_mac_inst[Mod_id].tx_req = (nfapi_tx_request_t*) malloc(sizeof(nfapi_tx_request_t));
+	//memcpy(UE_mac_inst[Mod_id].tx_req, req, sizeof(req));
+	for (int i=0; i<tx_req_num_elems; i++) {
 		tx_request_pdu_list[i].num_segments = req->tx_request_body.tx_pdu_list[i].num_segments;
 		tx_request_pdu_list[i].pdu_index = req->tx_request_body.tx_pdu_list[i].pdu_index;
 		tx_request_pdu_list[i].pdu_length = req->tx_request_body.tx_pdu_list[i].pdu_length;
@@ -1381,7 +1480,7 @@ int memcpy_tx_req (nfapi_pnf_p7_config_t* pnf_p7, nfapi_tx_request_t* req)
 			//*tx_request_pdu_list[i].segments[j].segment_data = *req->tx_request_body.tx_pdu_list[i].segments[j].segment_data;
 			tx_request_pdu_list[i].segments[j].segment_length = req->tx_request_body.tx_pdu_list[i].segments[j].segment_length;
 			if(tx_request_pdu_list[i].segments[j].segment_length > 0){
-			tx_request_pdu_list[i].segments[j].segment_data = (uint8_t*)malloc(tx_request_pdu_list[i].segments[j].segment_length*sizeof (uint8_t));
+				tx_request_pdu_list[i].segments[j].segment_data = (uint8_t*)malloc(tx_request_pdu_list[i].segments[j].segment_length*sizeof (uint8_t));
 			memcpy(tx_request_pdu_list[i].segments[j].segment_data, req->tx_request_body.tx_pdu_list[i].segments[j].segment_data, tx_request_pdu_list[i].segments[j].segment_length);
 			}
 			//tx_request_pdu_list[i].segments[j].segment_length = req->tx_request_body.tx_pdu_list[i].segments[j].segment_length;
@@ -1401,6 +1500,8 @@ int memcpy_hi_dci0_req (nfapi_pnf_p7_config_t* pnf_p7, nfapi_hi_dci0_request_t*
 
 	//if(req!=0){
 	module_id_t Mod_id = 0; //Panos: Currently static (only for one UE) but this should change.
+
+	for (Mod_id=0; Mod_id<NB_UE_INST; Mod_id++){
 	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;
@@ -1425,6 +1526,8 @@ int memcpy_hi_dci0_req (nfapi_pnf_p7_config_t* pnf_p7, nfapi_hi_dci0_request_t*
 		UE_mac_inst[Mod_id].hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list[i] = req->hi_dci0_request_body.hi_dci0_pdu_list[i];
 		//LOG_I(MAC, "Original hi_dci0 req. type:%d, Copy type: %d \n",req->hi_dci0_request_body.hi_dci0_pdu_list[i].pdu_type, UE_mac_inst[Mod_id].hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list[i].pdu_type);
 	}
+
+	}
 	//}
 	//else
 	//	LOG_I(MAC, "Panos-D: Dummy HI_DCI0");
diff --git a/openair2/PHY_INTERFACE/phy_stub_UE.h b/openair2/PHY_INTERFACE/phy_stub_UE.h
index 02ca2b14976..b6f8df57f8d 100644
--- a/openair2/PHY_INTERFACE/phy_stub_UE.h
+++ b/openair2/PHY_INTERFACE/phy_stub_UE.h
@@ -20,6 +20,7 @@
 UL_IND_t *UL_INFO;
 
 nfapi_tx_request_pdu_t* tx_request_pdu_list;
+int	tx_req_num_elems;
 
 
 
@@ -71,18 +72,19 @@ 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 frame, int subframe);
+int ul_config_req_UE_MAC(nfapi_ul_config_request_t* req, int frame, int subframe, module_id_t 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, int index);
 
-int dl_config_req_UE_MAC(nfapi_dl_config_request_t* req);
+//int dl_config_req_UE_MAC(nfapi_dl_config_request_t* req, nfapi_tx_request_pdu_t* tx_request_pdu_list);
+int dl_config_req_UE_MAC(nfapi_dl_config_request_t* req, module_id_t Mod_id);
 
 int tx_req_UE_MAC(nfapi_tx_request_t* req);
 
 
-int hi_dci0_req_UE_MAC(nfapi_hi_dci0_request_t* req);
+int hi_dci0_req_UE_MAC(nfapi_hi_dci0_request_t* req, module_id_t Mod_id);
 
 // The following set of memcpy functions should be getting called as callback functions from
 // pnf_p7_subframe_ind.
diff --git a/openair2/RRC/LITE/L2_interface_ue.c b/openair2/RRC/LITE/L2_interface_ue.c
index 3c46f7ff71b..00bb731b6f4 100644
--- a/openair2/RRC/LITE/L2_interface_ue.c
+++ b/openair2/RRC/LITE/L2_interface_ue.c
@@ -418,6 +418,7 @@ void rrc_in_sync_ind(module_id_t Mod_idP, frame_t frameP, uint16_t eNB_index)
   UE_rrc_inst[Mod_idP].Info[eNB_index].N310_cnt=0;
 
   if (UE_rrc_inst[Mod_idP].Info[eNB_index].T310_active==1) {
+	  LOG_I(RRC, "Panos-D: rrc_in_sync_ind 1 \n");
     UE_rrc_inst[Mod_idP].Info[eNB_index].N311_cnt++;
   }
 
diff --git a/openair2/RRC/LITE/rrc_UE.c b/openair2/RRC/LITE/rrc_UE.c
index 4eb364ece44..92579b7d8e2 100644
--- a/openair2/RRC/LITE/rrc_UE.c
+++ b/openair2/RRC/LITE/rrc_UE.c
@@ -1828,8 +1828,8 @@ rrc_ue_process_securityModeCommand(
   uint8_t buffer[200];
   int i, securityMode;
 
-  LOG_I(RRC,"[UE %d] Frame %d: Receiving from SRB1 (DL-DCCH), Processing securityModeCommand (eNB %d)\n",
-        ctxt_pP->module_id,ctxt_pP->frame,eNB_index);
+  LOG_I(RRC,"[UE %d] SFN/SF %d/%d: Receiving from SRB1 (DL-DCCH), Processing securityModeCommand (eNB %d)\n",
+        ctxt_pP->module_id,ctxt_pP->frame, ctxt_pP->subframe, eNB_index);
 
   switch (securityModeCommand->criticalExtensions.choice.c1.choice.securityModeCommand_r8.securityConfigSMC.securityAlgorithmConfig.cipheringAlgorithm) {
   case CipheringAlgorithm_r12_eea0:
@@ -1886,8 +1886,10 @@ rrc_ue_process_securityModeCommand(
   ul_dcch_msg.message.present           = UL_DCCH_MessageType_PR_c1;
 
   if (securityMode >= NO_SECURITY_MODE) {
+	  LOG_I(RRC, "rrc_ue_process_securityModeCommand, security mode complete case \n");
     ul_dcch_msg.message.choice.c1.present = UL_DCCH_MessageType__c1_PR_securityModeComplete;
   } else {
+	  LOG_I(RRC, "rrc_ue_process_securityModeCommand, security mode failure case \n");
     ul_dcch_msg.message.choice.c1.present = UL_DCCH_MessageType__c1_PR_securityModeFailure;
   }
 
@@ -1938,11 +1940,11 @@ rrc_ue_process_securityModeCommand(
               | (UE_rrc_inst[ctxt_pP->module_id].integrity_algorithm << 4),
           kRRCenc, kRRCint, kUPenc);
     } else {
-      LOG_W(RRC, "skipped pdcp_config_set_security() as securityMode == 0x%02x",
+      LOG_I(RRC, "skipped pdcp_config_set_security() as securityMode == 0x%02x",
           securityMode);
     }
   } else {
-    LOG_W(RRC, "Could not get PDCP instance where key=0x%ld\n", key);
+    LOG_I(RRC, "Could not get PDCP instance where key=0x%ld\n", key);
   }
 
 #endif //#if defined(ENABLE_SECURITY)
@@ -1957,8 +1959,8 @@ rrc_ue_process_securityModeCommand(
     ul_dcch_msg.message.choice.c1.choice.securityModeComplete.criticalExtensions.present = SecurityModeCommand__criticalExtensions_PR_c1;
     ul_dcch_msg.message.choice.c1.choice.securityModeComplete.criticalExtensions.choice.securityModeComplete_r8.nonCriticalExtension =NULL;
     
-    LOG_I(RRC,"[UE %d] Frame %d: Receiving from SRB1 (DL-DCCH), encoding securityModeComplete (eNB %d)\n",
-	  ctxt_pP->module_id,ctxt_pP->frame,eNB_index);
+    LOG_I(RRC,"[UE %d] SFN/SF %d/%d: Receiving from SRB1 (DL-DCCH), encoding securityModeComplete (eNB %d), rrc_TransactionIdentifier: %ld\n",
+	  ctxt_pP->module_id,ctxt_pP->frame, ctxt_pP->subframe, eNB_index, securityModeCommand->rrc_TransactionIdentifier);
     
     enc_rval = uper_encode_to_buffer(&asn_DEF_UL_DCCH_Message,
 				     (void*)&ul_dcch_msg,
diff --git a/targets/RT/USER/lte-softmodem-stub.c b/targets/RT/USER/lte-softmodem-stub.c
index 0c1be84c615..be8ef1fd005 100644
--- a/targets/RT/USER/lte-softmodem-stub.c
+++ b/targets/RT/USER/lte-softmodem-stub.c
@@ -1106,66 +1106,27 @@ int main( int argc, char **argv )
 
   printf("Before CC \n");
 
-  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
-
-
-    if (UE_flag==1) {
-      NB_UE_INST=1;
-      NB_INST=1;
-      PHY_vars_UE_g = malloc(sizeof(PHY_VARS_UE**));
-      PHY_vars_UE_g[0] = malloc(sizeof(PHY_VARS_UE*)*MAX_NUM_CCs);
-
-
 
-      PHY_vars_UE_g[0][CC_id] = init_ue_vars(frame_parms[CC_id], 0,abstraction_flag);
-      UE[CC_id] = PHY_vars_UE_g[0][CC_id];
-      printf("PHY_vars_UE_g[0][%d] = %p\n",CC_id,UE[CC_id]);
+  NB_UE_INST=2;
+  NB_INST=1;
 
-      if (phy_test==1)
-	UE[CC_id]->mac_enabled = 0;
-      else
-	UE[CC_id]->mac_enabled = 1;
-
-      /*if (UE[CC_id]->mac_enabled == 0) {  //set default UL parameters for testing mode
-	for (i=0; i<NUMBER_OF_CONNECTED_eNB_MAX; i++) {
-	  UE[CC_id]->pusch_config_dedicated[i].betaOffset_ACK_Index = beta_ACK;
-	  UE[CC_id]->pusch_config_dedicated[i].betaOffset_RI_Index  = beta_RI;
-	  UE[CC_id]->pusch_config_dedicated[i].betaOffset_CQI_Index = beta_CQI;
-
-	  UE[CC_id]->scheduling_request_config[i].sr_PUCCH_ResourceIndex = 0;
-	  UE[CC_id]->scheduling_request_config[i].sr_ConfigIndex = 7+(0%3);
-	  UE[CC_id]->scheduling_request_config[i].dsr_TransMax = sr_n4;
-	}
-      }
+  if (UE_flag==1) {
+	  PHY_vars_UE_g = malloc(sizeof(PHY_VARS_UE**)*NB_UE_INST);
+	  for (int i=0; i<NB_UE_INST; i++) {
+		  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
 
-      UE[CC_id]->UE_scan = UE_scan;
-      UE[CC_id]->UE_scan_carrier = UE_scan_carrier;
-      UE[CC_id]->mode    = mode;
-      printf("UE[%d]->mode = %d\n",CC_id,mode);
-
-      if (UE[CC_id]->mac_enabled == 1) {
-	UE[CC_id]->pdcch_vars[0][0]->crnti = 0x1234;
-	UE[CC_id]->pdcch_vars[1][0]->crnti = 0x1234;
-      }else {
-	UE[CC_id]->pdcch_vars[0][0]->crnti = 0x1235;
-	UE[CC_id]->pdcch_vars[1][0]->crnti = 0x1235;
-      }
-      UE[CC_id]->rx_total_gain_dB =  (int)rx_gain[CC_id][0] + rx_gain_off;
-      UE[CC_id]->tx_power_max_dBm = tx_max_power[CC_id];
+			  PHY_vars_UE_g[i] = malloc(sizeof(PHY_VARS_UE*)*MAX_NUM_CCs);
+			  PHY_vars_UE_g[i][CC_id] = init_ue_vars(frame_parms[CC_id], i,abstraction_flag);
 
-      if (frame_parms[CC_id]->frame_type==FDD) {
-	UE[CC_id]->N_TA_offset = 0;
-      }
-      else {
-	if (frame_parms[CC_id]->N_RB_DL == 100)
-	  UE[CC_id]->N_TA_offset = 624;
-	else if (frame_parms[CC_id]->N_RB_DL == 50)
-	  UE[CC_id]->N_TA_offset = 624/2;
-	else if (frame_parms[CC_id]->N_RB_DL == 25)
-	  UE[CC_id]->N_TA_offset = 624/4;
-      }*/
+			  UE[CC_id] = PHY_vars_UE_g[i][CC_id];
+			  printf("PHY_vars_UE_g[inst][%d] = %p\n",CC_id,UE[CC_id]);
 
-    }
+			  if (phy_test==1)
+				  UE[CC_id]->mac_enabled = 0;
+			  else
+				  UE[CC_id]->mac_enabled = 1;
+		  }
+	  }
   }
 
   // Panos: Probably don't need these lines for phy_stub
@@ -1374,7 +1335,10 @@ int main( int argc, char **argv )
 
     // 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);
+
+    // Panos: Temporarily we will be using single set of threads for multiple UEs.
+    //init_UE_stub(1,eMBMS_active,uecap_xer_in,emul_iface);
+    init_UE_stub_single_thread(NB_UE_INST,eMBMS_active,uecap_xer_in,emul_iface);
 
 
     /*for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
@@ -1444,7 +1408,7 @@ int main( int argc, char **argv )
   // connect the TX/RX buffers
   if (UE_flag==1) {
 
-    for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
+    /*for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
 
 
 #ifdef OAI_USRP
@@ -1452,7 +1416,11 @@ int main( int argc, char **argv )
 #else
       UE[CC_id]->hw_timing_advance = 160;
 #endif
-    }
+    }*/
+
+
+
+
     // Panos: No need to call setup_ue_buffers() for nfapi_mode=3
     /*if (setup_ue_buffers(UE,&openair0_cfg[0])!=0) {
       printf("Error setting up eNB buffer\n");
diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c
index cab7b92a1c7..82cb720fbb8 100644
--- a/targets/RT/USER/lte-ue.c
+++ b/targets/RT/USER/lte-ue.c
@@ -76,9 +76,11 @@ typedef enum {
 
 void init_UE_threads(int);
 void init_UE_threads_stub(int);
+void init_UE_single_thread_stub(int);
 void *UE_thread(void *arg);
 void init_UE(int nb_inst,int,int,int);
 void init_UE_stub(int nb_inst,int,int,char*);
+void init_UE_stub_single_thread(int nb_inst,int,int,char*);
 extern void oai_subframe_ind(uint16_t sfn, uint16_t sf);
 //extern int tx_req_UE_MAC1();
 
@@ -272,6 +274,44 @@ void init_UE(int nb_inst,int eMBMS_active, int uecap_xer_in, int timing_correcti
 #endif
 }
 
+// Panos: Initiating all UEs within a single set of threads for PHY_STUB. Future extensions -> multiple
+// set of threads for multiple UEs.
+void init_UE_stub_single_thread(int nb_inst,int eMBMS_active, int uecap_xer_in, char *emul_iface) {
+
+  int         inst;
+
+  LOG_I(PHY,"UE : Calling Layer 2 for initialization, nb_inst: %d \n", nb_inst);
+
+  l2_init_ue(eMBMS_active,(uecap_xer_in==1)?uecap_xer:NULL,
+	     0,// cba_group_active
+	     0); // HO flag
+
+  for (inst=0;inst<nb_inst;inst++) {
+
+    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();
+  init_UE_single_thread_stub(nb_inst);
+
+  /*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);
+  }*/
+
+  printf("UE threads created \n");
+
+  LOG_I(PHY,"Starting multicast link on %s\n",emul_iface);
+  if(nfapi_mode!=3)
+  multicast_link_start(ue_stub_rx_handler,0,emul_iface);
+
+
+}
+
+
+
+
 
 void init_UE_stub(int nb_inst,int eMBMS_active, int uecap_xer_in, char *emul_iface) {
 
@@ -824,6 +864,323 @@ void ue_stub_rx_handler(unsigned int num_bytes, char *rx_buffer) {
   }
 }
 
+
+/*!
+ * \brief This is the UE thread for RX subframe n and TX subframe n+4.
+ * This thread performs the phy_procedures_UE_RX() on every received slot.
+ * then, if TX is enabled it performs TX for n+4.
+ * \param arg is a pointer to a \ref PHY_VARS_UE structure.
+ * \returns a pointer to an int. The storage is not on the heap and must not be freed.
+ */
+
+static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg) {
+
+	thread_top_init("UE_phy_stub_thread_rxn_txnp4",1,870000L,1000000L,1000000L);
+
+	module_id_t Mod_id = 0;
+	int init_ra_UE = -1; // This counter is used to initiate the RA of each UE in different SFrames
+	int global_cnt = 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
+  //function we should somehow make the translation of rnti to Mod_ID.
+
+  //proc->instance_cnt_rxtx=-1;
+
+  phy_stub_ticking->ticking_var = -1;
+  proc->subframe_rx=proc->sub_frame_start;
+
+  // Initialize all nfapi structures to NULL
+  for (Mod_id=0; Mod_id<NB_UE_INST; Mod_id++) {
+      	UE_mac_inst[Mod_id].dl_config_req = NULL;
+      	UE_mac_inst[Mod_id].ul_config_req = NULL;
+      	UE_mac_inst[Mod_id].hi_dci0_req = NULL;
+      	tx_request_pdu_list = NULL;
+      	tx_req_num_elems = 0;
+      	UE_mac_inst[Mod_id].tx_req = NULL;
+      }
+
+  //PANOS: CAREFUL HERE!
+  wait_sync("UE_phy_stub_single_thread_rxn_txnp4");
+
+  while (!oai_exit) {
+
+    if (pthread_mutex_lock(&phy_stub_ticking->mutex_ticking) != 0) {
+      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 )
+      LOG_D(MAC,"Waiting for ticking_var\n");
+      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( 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+4)%10;
+    proc->frame_tx = proc->frame_rx + (proc->subframe_rx>5?1:0);
+    //oai_subframe_ind(proc->frame_rx, proc->subframe_rx);
+
+
+    oai_subframe_ind(timer_frame, timer_subframe);
+
+    // Panos: Guessing that the next 4 lines are not needed for the phy_stub mode.
+    /*initRefTimes(t2);
+      initRefTimes(t3);
+      pickTime(current);
+      updateTimes(proc->gotIQs, &t2, 10000, "Delay to wake up UE_Thread_Rx (case 2)");*/
+
+
+
+    // Process Rx data for one sub-frame
+
+    /*if(global_cnt == 0){
+    	init_ra_UE++;
+    	global_cnt++;
+    }*/
+
+    /*if(global_cnt>= 0 && global_cnt<15000)
+    	global_cnt++;
+    if(global_cnt == 10000 || global_cnt == 15000){
+    	LOG_I(MAC, "Panos-D: global_cnt: %d", global_cnt);
+    	global_cnt++;
+    	init_ra_UE++;
+    }*/
+
+
+    //if(timer_frame%5 == 0 && timer_subframe%10 == 0)
+    	init_ra_UE++;
+    for (Mod_id=0; Mod_id<NB_UE_INST; Mod_id++) {
+    	//LOG_I(MAC, "Panos-D: UE_phy_stub_single_thread_rxn_txnp4, NB_UE_INST:%d, Mod_id:%d \n", NB_UE_INST, Mod_id);
+    	UE = PHY_vars_UE_g[Mod_id][0];
+    lte_subframe_t sf_type = subframe_select( &UE->frame_parms, proc->subframe_rx);
+    if ((sf_type == SF_DL) ||
+	(UE->frame_parms.frame_type == FDD) ||
+	(sf_type == SF_S)) {
+
+      if (UE->frame_parms.frame_type == TDD) {
+	LOG_D(PHY, "%s,TDD%d,%s: calling UE_RX\n",
+	      threadname,
+	      UE->frame_parms.tdd_config,
+	      (sf_type==SF_DL? "SF_DL" :
+	       (sf_type==SF_UL? "SF_UL" :
+		(sf_type==SF_S ? "SF_S"  : "UNKNOWN_SF_TYPE"))));
+      } else {
+	LOG_D(PHY, "%s,%s,%s: calling UE_RX\n",
+	      threadname,
+	      (UE->frame_parms.frame_type==FDD? "FDD":
+	       (UE->frame_parms.frame_type==TDD? "TDD":"UNKNOWN_DUPLEX_MODE")),
+	      (sf_type==SF_DL? "SF_DL" :
+	       (sf_type==SF_UL? "SF_UL" :
+		(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 );
+	#else
+      */
+      // Panos: Substitute call to phy_procedures Rx with call to phy_stub functions in order to trigger
+      // UE Rx procedures directly at the MAC layer, based on the received nfapi requests from the vnf (eNB).
+      // 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);
+      //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_I( MAC, "Panos-D: UE_phy_stub_thread_rxn_txnp4 after oai_subframe_ind 3, NB_UE_INST:%d \n", NB_UE_INST);
+	dl_config_req_UE_MAC(UE_mac_inst[Mod_id].dl_config_req, Mod_id);
+      }
+      //if(UE_mac_inst[Mod_id].hi_dci0_req!= NULL){
+      if (UE_mac_inst[Mod_id].hi_dci0_req!=NULL && UE_mac_inst[Mod_id].hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list!=NULL){
+    	  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, Mod_id);
+    	  //if(UE_mac_inst[Mod_id].hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list!=NULL){
+    		  free(UE_mac_inst[Mod_id].hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list);
+    		  UE_mac_inst[Mod_id].hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list = NULL;
+    	  //}
+    	  free(UE_mac_inst[Mod_id].hi_dci0_req);
+    	  UE_mac_inst[Mod_id].hi_dci0_req = NULL;
+      }
+
+      else if(UE_mac_inst[Mod_id].hi_dci0_req!=NULL){
+      		free(UE_mac_inst[Mod_id].hi_dci0_req);
+      		UE_mac_inst[Mod_id].hi_dci0_req = NULL;
+      	}
+      //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);
+
+      if(nfapi_mode!=3)
+      phy_procedures_UE_SL_TX(UE,proc);
+
+      //#endif
+    }
+  //} //for (Mod_id=0; Mod_id<NB_UE_INST; Mod_id++)
+
+//>>>>>>> Stashed changes
+
+#if UE_TIMING_TRACE
+    start_meas(&UE->generic_stat);
+#endif
+
+    if (UE->mac_enabled==1) {
+
+      ret = ue_scheduler(UE->Mod_id,
+			 proc->frame_rx,
+			 proc->subframe_rx,
+			 proc->frame_tx,
+			 proc->subframe_tx,
+			 subframe_select(&UE->frame_parms,proc->subframe_tx),
+			 0,
+			 0/*FIXME CC_id*/);
+      if ( ret != CONNECTION_OK) {
+	char *txt;
+	switch (ret) {
+	case CONNECTION_LOST:
+	  txt="RRC Connection lost, returning to PRACH";
+	  break;
+	case PHY_RESYNCH:
+	  txt="RRC Connection lost, trying to resynch";
+	  break;
+	case RESYNCH:
+	  txt="return to PRACH and perform a contention-free access";
+	  break;
+	default:
+	  txt="UNKNOWN RETURN CODE";
+	};
+	LOG_E( PHY, "[UE %"PRIu8"] Frame %"PRIu32", subframe %u %s\n",
+	       UE->Mod_id, proc->frame_rx, proc->subframe_tx,txt );
+      }
+    }
+#if UE_TIMING_TRACE
+    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_D(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 && Mod_id == (module_id_t) init_ra_UE) ) { //&& Mod_id == init_ra_UE
+	    //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 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, Mod_id);
+		//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;
+	}
+      }
+
+    phy_procedures_UE_SL_RX(UE,proc);
+
+
+    /*if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_S) &&
+      (UE->frame_parms.frame_type == TDD))
+      if (UE->mode != loop_through_memory)
+      phy_procedures_UE_S_TX(UE,0,0,no_relay);
+      updateTimes(current, &t3, 10000, "Delay to process sub-frame (case 3)");*/
+
+    //if (pthread_mutex_lock(&proc->mutex_rxtx) != 0) {
+    /*if (pthread_mutex_lock(&phy_stub_ticking->mutex_ticking) != 0) {
+      LOG_E( PHY, "[SCHED][UE] error locking mutex for UE RXTX\n" );
+      exit_fun("noting to add");
+    }
+
+    //proc->instance_cnt_rxtx--;
+
+    //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");
+    }*/
+    } //for (Mod_id=0; Mod_id<NB_UE_INST; Mod_id++)
+
+    if(tx_request_pdu_list!=NULL){
+    	  free(tx_request_pdu_list);
+      	  tx_request_pdu_list = NULL;
+      }
+  }
+  // thread finished
+  free(arg);
+  return &UE_thread_rxtx_retval;
+}
+
+
+
+
 /*!
  * \brief This is the UE thread for RX subframe n and TX subframe n+4.
  * This thread performs the phy_procedures_UE_RX() on every received slot.
@@ -945,12 +1302,13 @@ static void *UE_phy_stub_thread_rxn_txnp4(void *arg) {
 	}*/
       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");
-	dl_config_req_UE_MAC(UE_mac_inst[Mod_id].dl_config_req);
+	dl_config_req_UE_MAC(UE_mac_inst[Mod_id].dl_config_req, Mod_id);
+      //dl_config_req_UE_MAC(UE_mac_inst[Mod_id].dl_config_req, UE_mac_inst[Mod_id].tx_request_pdu_list);
       }
       //if(UE_mac_inst[Mod_id].hi_dci0_req!= NULL){
       if (UE_mac_inst[Mod_id].hi_dci0_req!=NULL && UE_mac_inst[Mod_id].hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list!=NULL){
     	  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);
+    	  hi_dci0_req_UE_MAC(UE_mac_inst[Mod_id].hi_dci0_req, Mod_id);
     	  //if(UE_mac_inst[Mod_id].hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list!=NULL){
     		  free(UE_mac_inst[Mod_id].hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list);
     		  UE_mac_inst[Mod_id].hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list = NULL;
@@ -1039,7 +1397,7 @@ static void *UE_phy_stub_thread_rxn_txnp4(void *arg) {
 	// 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, timer_frame, timer_subframe, Mod_id);
 		//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);
@@ -1400,6 +1758,70 @@ void init_UE_threads(int inst) {
 
 
 
+/*!
+ * \brief Initialize the UE theads.
+ * Creates the UE threads:
+ * - UE_thread_rxtx0
+ * - UE_thread_synch
+ * - UE_thread_fep_slot0
+ * - UE_thread_fep_slot1
+ * - UE_thread_dlsch_proc_slot0
+ * - UE_thread_dlsch_proc_slot1
+ * and the locking between them.
+ */
+void init_UE_single_thread_stub(int nb_inst) {
+  struct rx_tx_thread_data *rtd;
+  PHY_VARS_UE *UE;
+
+  for (int i=0; i<nb_inst; i++){
+	  AssertFatal(PHY_vars_UE_g!=NULL,"PHY_vars_UE_g is NULL\n");
+	  AssertFatal(PHY_vars_UE_g[i]!=NULL,"PHY_vars_UE_g[inst] is NULL\n");
+	  AssertFatal(PHY_vars_UE_g[i][0]!=NULL,"PHY_vars_UE_g[inst][0] is NULL\n");
+  }
+  UE = PHY_vars_UE_g[0][0];
+
+  pthread_attr_init (&UE->proc.attr_ue);
+  pthread_attr_setstacksize(&UE->proc.attr_ue,8192);//5*PTHREAD_STACK_MIN);
+
+  // Panos: Don't need synch for phy_stub mode
+  //pthread_mutex_init(&UE->proc.mutex_synch,NULL);
+  //pthread_cond_init(&UE->proc.cond_synch,NULL);
+
+  // the threads are not yet active, therefore access is allowed without locking
+  // Panos: In phy_stub_UE mode due to less heavy processing operations we don't need two threads
+  //int nb_threads=RX_NB_TH;
+  int nb_threads=1;
+  for (int i=0; i<nb_threads; i++) {
+    rtd = calloc(1, sizeof(struct rx_tx_thread_data));
+    if (rtd == NULL) abort();
+    rtd->UE = UE;
+    rtd->proc = &UE->proc.proc_rxtx[i];
+
+    pthread_mutex_init(&UE->proc.proc_rxtx[i].mutex_rxtx,NULL);
+    pthread_cond_init(&UE->proc.proc_rxtx[i].cond_rxtx,NULL);
+    UE->proc.proc_rxtx[i].sub_frame_start=i;
+    UE->proc.proc_rxtx[i].sub_frame_step=nb_threads;
+    printf("Init_UE_threads rtd %d proc %d nb_threads %d i %d\n",rtd->proc->sub_frame_start, UE->proc.proc_rxtx[i].sub_frame_start,nb_threads, i);
+    pthread_create(&UE->proc.proc_rxtx[i].pthread_rxtx, NULL, UE_phy_stub_single_thread_rxn_txnp4, rtd);
+    /*
+      #ifdef UE_SLOT_PARALLELISATION
+      //pthread_mutex_init(&UE->proc.proc_rxtx[i].mutex_slot0_dl_processing,NULL);
+      //pthread_cond_init(&UE->proc.proc_rxtx[i].cond_slot0_dl_processing,NULL);
+      //pthread_create(&UE->proc.proc_rxtx[i].pthread_slot0_dl_processing,NULL,UE_thread_slot0_dl_processing, rtd);
+
+      pthread_mutex_init(&UE->proc.proc_rxtx[i].mutex_slot1_dl_processing,NULL);
+      pthread_cond_init(&UE->proc.proc_rxtx[i].cond_slot1_dl_processing,NULL);
+      pthread_create(&UE->proc.proc_rxtx[i].pthread_slot1_dl_processing,NULL,UE_thread_slot1_dl_processing, rtd);
+      #endif*/
+
+  }
+  // Panos: Remove thread for UE_sync in phy_stub_UE mode.
+  //pthread_create(&UE->proc.pthread_synch,NULL,UE_thread_synch,(void*)UE);
+}
+
+
+
+
 /*!
  * \brief Initialize the UE theads.
  * Creates the UE threads:
@@ -1537,8 +1959,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;
@@ -1644,9 +2064,11 @@ int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue, openair0_config_t *openair0_cfg)
       UE_tport_t pdu;
       pdu.header.packet_type = TTI_SYNC;
       pdu.header.absSF = (timer_frame*10)+timer_subframe;
+      if (nfapi_mode!=3){
       multicast_link_write_sock(0,
 	  			&pdu,
 				sizeof(UE_tport_header_t));
+				}
 
     }
     else {
-- 
GitLab