diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index f7bf468b08edf46d7e17981f9080bb5a58c13e05..a349e2a091934a78569b4ee2ea312970f3d32e10 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1123,6 +1123,7 @@ set(L2_SRC ${RRC_DIR}/L2_interface.c ) set (MAC_SRC + ${PHY_INTERFACE_DIR}/phy_stub_UE.c ${PHY_INTERFACE_DIR}/IF_Module.c ${MAC_DIR}/main.c ${MAC_DIR}/ue_procedures.c diff --git a/openair1/PHY/defs.h b/openair1/PHY/defs.h index 00d5605cfba11a8f10020f7b649779c5bf6600b8..8a65a54dfa7463bccbd39e7eb01c2c2272645535 100644 --- a/openair1/PHY/defs.h +++ b/openair1/PHY/defs.h @@ -1282,6 +1282,12 @@ typedef struct { /// N0 (used for abstraction) double N0; + /// Panos: Pointer to IF_Module_UE instance of the UE. + IF_Module_UE_t *if_inst_ue; + + /// Panos: Pointer to DL.indication structure of the UE. + UE_DL_IND_t UE_DL_INFO; + /// PDSCH Varaibles PDSCH_CONFIG_DEDICATED pdsch_config_dedicated[NUMBER_OF_CONNECTED_eNB_MAX]; diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c index 21b8ae98435f418ae19449eaef997da76f6d4ca8..28398ad00d9ca34e004a75df97cf36eb59742dd0 100644 --- a/openair1/SCHED/phy_procedures_lte_ue.c +++ b/openair1/SCHED/phy_procedures_lte_ue.c @@ -1339,7 +1339,7 @@ void ue_prach_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin // ask L2 for RACH transport if ((mode != rx_calib_ue) && (mode != rx_calib_ue_med) && (mode != rx_calib_ue_byp) && (mode != no_L2_connect) ) { LOG_D(PHY,"Getting PRACH resources\n"); - // Panos: Substitute the call to ue_get_rach with ue->prach_resources[eNB_id] = ue_rach_config, assuming that + // Panos: Substitute the call to ue_get_rach with ue->prach_resources[eNB_id] = UE_MAC_interface::ue_rach_config, assuming that // ue_get_rach() will have been called from the MAC layer. ue->prach_resources[eNB_id] = ue_get_rach(ue->Mod_id, ue->CC_id, diff --git a/openair2/LAYER2/MAC/defs.h b/openair2/LAYER2/MAC/defs.h index 2c8b613b1d2125da385099465fff3211423c4628..5b80ad71e2eee8b1619a8aeefc876fd3b6116b93 100644 --- a/openair2/LAYER2/MAC/defs.h +++ b/openair2/LAYER2/MAC/defs.h @@ -235,6 +235,33 @@ typedef struct { uint8_t R:2; } __attribute__((__packed__))SCH_SUBHEADER_FIXED; + +// Panos: +/*!\brief MAC subheader long with 24bit DST field */ +typedef struct { + uint8_t V:4; //Version number: Possible values "0001", "0010", "0011" based on TS36.321 section 6.2.3. + uint32_t SRC:24; //Prose UE source ID. Size 24 bits. + uint32_t DST:24; //Prose UE destination ID. Size 16 or 24 bits. + uint8_t LCID:5; + uint8_t L:7; // Length field indicating the size of the corresponding SDU in byes. Not sure about the size of this field (7). + uint8_t F:1; + uint8_t E:1; + uint8_t R:1; +}__attribute__((__packed__))SLSCH_SUBHEADER_24_Bit_DST; + +/*!\brief MAC subheader long with 16bit DST field */ +typedef struct { + uint8_t V:4; //Version number: Possible values "0001", "0010", "0011" based on TS36.321 section 6.2.3. + uint32_t SRC:24; //Prose UE source ID. Size 24 bits. + uint32_t DST:16; //Prose UE destination ID. Size 16 or 24 bits. + uint8_t LCID:5; + uint8_t L:7; // Length field indicating the size of the corresponding SDU in byes. Not sure about the size of this field (7). + uint8_t F:1; + uint8_t E:1; + uint8_t R:1; +}__attribute__((__packed__))SLSCH_SUBHEADER_16_Bit_DST; + + /*!\brief mac control element: short buffer status report for a specific logical channel group ID*/ typedef struct { uint8_t Buffer_size:6; // octet 1 LSB @@ -250,6 +277,30 @@ typedef struct { uint8_t Buffer_size0:6; } __attribute__((__packed__))BSR_LONG; +// Panos: +/*!\brief mac control element: sidelink buffer status report */ +typedef struct { + uint8_t DST_1:4; + uint8_t LCGID_1: 2; + uint8_t Buffer_size_1:6; + uint8_t DST_2:4; + uint8_t LCGID_2: 2; + uint8_t Buffer_size_2:6; +}__attribute__((__packed__))SL_BSR; + +/*!\brief mac control element: truncated sidelink buffer status report */ +typedef struct { + uint8_t DST:4; + uint8_t LCGID: 2; + uint8_t Buffer_size:6; + uint8_t R1:1; + uint8_t R2:1; + uint8_t R3:1; + uint8_t R4:1; +}__attribute__((__packed__))SL_BSR_Truncated; + + + #define BSR_LONG_SIZE (sizeof(BSR_LONG)) /*!\brief mac control element: timing advance */ typedef struct { @@ -1162,6 +1213,17 @@ typedef struct { MeasGapConfig_t *measGapConfig; /// Pointers to LogicalChannelConfig indexed by LogicalChannelIdentity. Note NULL means LCHAN is inactive. LogicalChannelConfig_t *logicalChannelConfig[MAX_NUM_LCID]; + + /// Panos: Pointer to IF_Module_UE instance of the UE + IF_Module_UE_t *if_inst_ue; + /// Panos: UE_MAC interface: Config request structure. + UE_PHY_Config_t UE_config; + /// Panos: UE_MAC interface: UL Config Request Structure + UE_MAC_ul_config_request_t UL_req_ue[MAX_NUM_CCs]; + /// Panos: UE_MAC interface: UL Transmission request structure. + UE_MAC_tx_request_t UL_TX_req[MAX_NUM_CCs]; + + /// Scheduling Information UE_SCHEDULING_INFO scheduling_info; /// Outgoing CCCH pdu for PHY diff --git a/openair2/PHY_INTERFACE/IF_Module_UE.c b/openair2/PHY_INTERFACE/IF_Module_UE.c index cb04b554321057fd49f3f438af876e2f1389fc7c..3951f95e33bb184e1af5a9f1c58a3f8e06bb20ee 100644 --- a/openair2/PHY_INTERFACE/IF_Module_UE.c +++ b/openair2/PHY_INTERFACE/IF_Module_UE.c @@ -6,6 +6,8 @@ #include "LAYER2/MAC/proto.h" #include "common/ran_context.h" +IF_Module_UE_t *if_inst_ue; + void handle_bch(UE_DL_IND_t *UE_DL_INFO) @@ -51,6 +53,8 @@ void UE_DL_indication(UE_DL_IND_t *UE_DL_INFO) /*Call handle functions to forward PDUs or control indications to the upper layers. handle_bch(UE_DL_INFO); handle_dlsch (UE_DL_INFO); + + Trigger ue_scheduler() ? */ } @@ -71,7 +75,24 @@ void UE_Tx_indication(UE_Tx_IND_t *UE_Tx_INFO) } } +/// Panos: Not sure about the implementation of this function. +IF_Module_UE_t *IF_Module_ue_init(int Mod_id){ + + AssertFatal(Mod_id<MAX_MODULES,"Asking for Module %d > %d\n",Mod_id,MAX_IF_MODULES); + if (if_inst_ue[Mod_id]==NULL) { + if_inst_ue[Mod_id] = (IF_Module_t*)malloc(sizeof(IF_Module_t)); + memset((void*)if_inst_ue[Mod_id],0,sizeof(IF_Module_t)); + //if_inst_ue[Mod_id]->CC_mask=0; + if_inst_ue[Mod_id]->UE_DL_indication = UE_DL_indication; + if_inst_ue[Mod_id]->UE_Tx_indication = UE_Tx_indication; + + // Panos: Have to check about this. + /*AssertFatal(pthread_mutex_init(&if_inst_ue[Mod_id]->if_mutex,NULL)==0, + "allocation of if_inst[%d]->if_mutex fails\n",Mod_id);*/ + } + return if_inst[Mod_id]; +} diff --git a/openair2/PHY_INTERFACE/IF_Module_UE.h b/openair2/PHY_INTERFACE/IF_Module_UE.h index 77046bcae62ba58df2af462ac9fc481a2ee63134..9cd246906b073fe67d82f8330bf82d7e71234b1b 100644 --- a/openair2/PHY_INTERFACE/IF_Module_UE.h +++ b/openair2/PHY_INTERFACE/IF_Module_UE.h @@ -126,6 +126,8 @@ typedef struct{ frame_t frame; /// subframe sub_frame_t subframe; + /// UE_Mode to be filled only after + UE_MODE_t UE_mode[NUMBER_OF_CONNECTED_eNB_MAX]; /// MAC IFace UL Config Request UE_MAC_ul_config_request_t *UE_UL_req; /// MAC IFace SL Transmission Config Request @@ -149,11 +151,11 @@ typedef struct IF_Module_UE_s{ //define the function pointer void (*UE_DL_indication)(UE_DL_IND_t *UE_DL_INFO); void (*UE_SL_indication)(UE_SL_IND_t *UE_SL_INFO); - void (*UE_Tx1_indication)(UE_Tx_IND_t *UE_Tx_INFO); + void (*UE_Tx_indication)(UE_Tx_IND_t *UE_Tx_INFO); void (*UE_sched_response)(UE_Sched_Rsp_t *UE_Sched_INFO); void (*UE_config_req)(UE_PHY_Config_t* UE_config_INFO); //P: Perhaps an additional separate function for dedicated PHY configuration is needed. - uint32_t CC_mask; + //uint32_t CC_mask_ue; uint16_t current_frame; uint8_t current_subframe; pthread_mutex_t if_mutex; diff --git a/openair2/PHY_INTERFACE/UE_MAC_interface.h b/openair2/PHY_INTERFACE/UE_MAC_interface.h index 0ed5e221840fafee0465c3c8f39e5dda2b1349ee..c697089b071aded0ae2157e0285006892f2005d4 100644 --- a/openair2/PHY_INTERFACE/UE_MAC_interface.h +++ b/openair2/PHY_INTERFACE/UE_MAC_interface.h @@ -281,7 +281,7 @@ typedef struct { typedef struct { int8_t referenceSignalPower; uint8_t p_b; -}UE_PHY_pdcch_config_t; +}UE_PHY_pdsch_config_t; typedef struct { @@ -335,8 +335,8 @@ typedef struct { UE_PHY_tdd_frame_structure_t ue_tdd_frame_structure_config; UE_PHY_prach_config_t ue_prach_config; UE_PHY_pucch_config_t ue_pucch_config; - UE_PHY_pdcch_config_t ue_pdcch_config; - UE_PHY_pusch_config_t ue_pdsch_config; + UE_PHY_pdsch_config_t ue_pdsch_config; + UE_PHY_pusch_config_t ue_pusch_config; UE_PHY_SRS_config_t ue_srs_config; UE_PHY_UL_power_control_config_t ue_ul_pow_cntl_config; UE_PHY_HARQ_Msg3_config_t ue_harq_msg3_config; diff --git a/openair2/PHY_INTERFACE/phy_stub_UE.c b/openair2/PHY_INTERFACE/phy_stub_UE.c new file mode 100644 index 0000000000000000000000000000000000000000..8c81d019a40f242f5bc3b718f2e02328cafe0213 --- /dev/null +++ b/openair2/PHY_INTERFACE/phy_stub_UE.c @@ -0,0 +1,97 @@ + +//#include "openair1/PHY/defs.h" +//#include "openair2/PHY_INTERFACE/IF_Module.h" +//#include "openair1/PHY/extern.h" +#include "LAYER2/MAC/extern.h" +//#include "LAYER2/MAC/proto.h" +//#include "common/ran_context.h" +#include "openair2/PHY_INTERFACE/phy_stub_UE.h" + + +void handle_nfapi_UE_Rx(uint8_t Mod_id, Sched_Rsp_t *Sched_INFO, int eNB_id){ + // copy data from eNB L2 interface to UE L2 interface + + int CC_id = Sched_INFO->CC_id; + nfapi_dl_config_request_t *DL_req = Sched_INFO->DL_req; + nfapi_tx_request_t *Tx_req = Sched_INFO->TX_req; + frame_t frame = Sched_INFO->frame; + sub_frame_t subframe = Sched_INFO->subframe; + + uint8_t number_dl_pdu = DL_req->dl_config_request_body.number_pdu; + nfapi_dl_config_request_pdu_t *dl_config_pdu; + nfapi_dl_config_request_pdu_t *dl_config_pdu_tmp; + int i = 0; + + for (i=0; i<number_dl_pdu; i++) + { + dl_config_pdu = &DL_req->dl_config_request_body.dl_config_pdu_list[i]; + switch (dl_config_pdu->pdu_type) { + case NFAPI_DL_CONFIG_BCH_PDU_TYPE: + // BCH case + // Last parameter is 1 if first time synchronization and zero otherwise. Not sure which value to put + // for our case. + dl_phy_sync_success(Mod_id,frame,eNB_id, 0); + break; + + case NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE: + if (dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type == 1) { + // C-RNTI (Normal DLSCH case) + dl_config_pdu_tmp = &DL_req->dl_config_request_body.dl_config_pdu_list[i+1]; + if (dl_config_pdu_tmp->pdu_type == NFAPI_DL_CONFIG_DLSCH_PDU_TYPE){ + ue_send_sdu(Mod_id, CC_id, frame, subframe, + Tx_req->tx_request_body.tx_pdu_list[dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index].segments[0].segment_data, + Tx_req->tx_request_body.tx_pdu_list[dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index].segments[0].segment_length, + eNB_id); + i++; + } + else { + LOG_E(MAC,"[UE %d] CCid %d Frame %d, subframe %d : Cannot extract DLSCH PDU from NFAPI\n",Mod_id, CC_id,frame,subframe); + } + } + else if (dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type == 2) { + dl_config_pdu_tmp = &DL_req->dl_config_request_body.dl_config_pdu_list[i+1]; + if(dl_config_pdu_tmp->pdu_type == NFAPI_DL_CONFIG_DLSCH_PDU_TYPE && dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti == 0xFFFF){ + //pdu = Tx_req->tx_request_body.tx_pdu_list[dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index].segments[0].segment_data; + // Question about eNB_index here. How do we obtain it? + ue_decode_si(Mod_id, CC_id, frame, eNB_id, + Tx_req->tx_request_body.tx_pdu_list[dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index].segments[0].segment_data, + Tx_req->tx_request_body.tx_pdu_list[dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index].segments[0].segment_length); + i++; + } + else if(dl_config_pdu_tmp->pdu_type == NFAPI_DL_CONFIG_DLSCH_PDU_TYPE && dl_config_pdu->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; + // Question about eNB_index here. How do we obtain it? + ue_decode_p(Mod_id, CC_id, frame, eNB_id, + Tx_req->tx_request_body.tx_pdu_list[dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index].segments[0].segment_data, + Tx_req->tx_request_body.tx_pdu_list[dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index].segments[0].segment_length); + i++; + } + else if(dl_config_pdu_tmp->pdu_type == NFAPI_DL_CONFIG_DLSCH_PDU_TYPE) { + // RA-RNTI case + // ue_process_rar should be called but the problem is that this function currently uses PHY_VARS_UE + // elements. + + // C-RNTI parameter not actually used. Provided only to comply with existing function definition. + // Not sure about parameters to fill the preamble index. Originally it comes from PHY. + const rnti_t c_rnti; + ue_process_rar(Mod_id, CC_id, frame, + dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.rnti, //RA-RNTI + Tx_req->tx_request_body.tx_pdu_list[dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index].segments[0].segment_data, + c_rnti, + UE_mac_inst[Mod_id].RA_prach_resources.ra_PreambleIndex, + Tx_req->tx_request_body.tx_pdu_list[dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index].segments[0].segment_data); + } + else { + LOG_E(MAC,"[UE %d] CCid %d Frame %d, subframe %d : Cannot extract DLSCH PDU from NFAPI\n",Mod_id, CC_id,frame,subframe); + } + + } + break; + } + + } + + +} + diff --git a/openair2/PHY_INTERFACE/phy_stub_UE.h b/openair2/PHY_INTERFACE/phy_stub_UE.h new file mode 100644 index 0000000000000000000000000000000000000000..09afecb6f62e9c0834a71f0c96747427d5b4ee65 --- /dev/null +++ b/openair2/PHY_INTERFACE/phy_stub_UE.h @@ -0,0 +1,37 @@ +/* + * phy_stub_UE.h + * + * Created on: Sep 14, 2017 + * Author: montre + */ + + +#ifndef __PHY_STUB_UE__H__ +#define __PHY_STUB_UE__H__ + +#include <stdint.h> +#include "openair2/PHY_INTERFACE/IF_Module.h" +//#include "openair1/PHY/LTE_TRANSPORT/defs.h" +//#include "openair1/PHY/defs.h" +//#include "openair1/PHY/LTE_TRANSPORT/defs.h" + + +// Panos: This function should return all the sched_response config messages which concern a specific UE. Inside this +// function we should somehow make the translation of config message's rnti to Mod_ID. +Sched_Rsp_t get_nfapi_sched_response(uint8_t Mod_id); + +// This function will be processing DL_config and Tx.requests and trigger all the MAC Rx related calls at the UE side, +// namely:ue_send_sdu(), or ue_decode_si(), or ue_decode_p(), or ue_process_rar() based on the rnti type. +void handle_nfapi_UE_Rx(uint8_t Mod_id, Sched_Rsp_t *Sched_INFO, int eNB_id); + +// This function will be processing UL and HI_DCI0 config requests to trigger all the MAC Tx related calls +// at the UE side, namely: ue_get_SR(), ue_get_rach(), ue_get_sdu() based on the pdu configuration type. +// The output of these calls will be put to an UL_IND_t structure which will then be the input to +// send_nfapi_UL_indications(). +UL_IND_t generate_nfapi_UL_indications(Sched_Rsp_t sched_response); + +// This function should pass the UL indication messages to the eNB side through the socket interface. +void send_nfapi_UL_indications(UL_IND_t UL_INFO); + + +#endif /* PHY_STUB_UE_H_ */ diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index a95342e8b6ae45ad04d49cc8b5281c3736c6648d..7729b6cb882d1356d25365a21f02d81806933e8d 100644 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -163,6 +163,7 @@ static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_nam #endif } // UE-specific RX processing for subframe n + // Panos: Substitute with call to get_nfapi_indications() from the socket. phy_procedures_eNB_uespec_RX(eNB, proc, no_relay ); pthread_mutex_lock(&eNB->UL_INFO_mutex); @@ -183,6 +184,7 @@ static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_nam if (oai_exit) return(-1); + // Panos: Substitute with call to send_nfapi_sched_response() to the UE through the socket. phy_procedures_eNB_TX(eNB, proc, no_relay, NULL, 1); if (release_thread(&proc->mutex_rxtx,&proc->instance_cnt_rxtx,thread_name)<0) return(-1); diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c index fdeeaea9a527d71d8e609fc718d31981a24cb106..eb99f9a97f20b577f6de720303645176045a2346 100644 --- a/targets/RT/USER/lte-ue.c +++ b/targets/RT/USER/lte-ue.c @@ -569,6 +569,10 @@ static void *UE_thread_rxn_txnp4(void *arg) { PHY_VARS_UE *UE = rtd->UE; int ret; + // 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; proc->subframe_rx=proc->sub_frame_start; @@ -624,6 +628,7 @@ static void *UE_thread_rxn_txnp4(void *arg) { (sf_type==SF_UL? "SF_UL" : (sf_type==SF_S ? "SF_S" : "UNKNOWN_SF_TYPE")))); } + // Panos: Substitute with call to handle_nfapi_UE_Rx(Sched_Resp). phy_procedures_UE_RX( UE, proc, 0, 0, UE->mode, no_relay, NULL ); } @@ -666,8 +671,11 @@ static void *UE_thread_rxn_txnp4(void *arg) { if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_UL) || (UE->frame_parms.frame_type == FDD) ) - if (UE->mode != loop_through_memory) - phy_procedures_UE_TX(UE,proc,0,0,UE->mode,no_relay); + if (UE->mode != loop_through_memory){ + // Panos: Substitute with call to generate_nfapi_UL_indications and then send_nfapi_UL_indications() + phy_procedures_UE_TX(UE,proc,0,0,UE->mode,no_relay); + } +