Commit d4e6d45c authored by matzakos's avatar matzakos

Definition of the UE<->eNB MAC to MAC interface based on nFAPI structures:...

Definition of the UE<->eNB MAC to MAC interface based on nFAPI structures: Currently supporting the triggering of MAC layer Rx operations at the UE side based on the reception of NFAPI DL messages. Partial definition of Sidelink MAC subheaders.
parent 0422bf8b
......@@ -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
......
......@@ -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];
......
......@@ -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,
......
......@@ -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
......
......@@ -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];
}
......@@ -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;
......
......@@ -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;
......
//#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;
}
}
}
/*
* 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_ */
......@@ -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);
......
......@@ -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);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment