Commit 36195ec3 authored by cig's avatar cig

RA fixes and additions:

- RA resource selection and transmission
- MAC header structs for RA
- RA procedure msg1 fixes
- code cleanup
parent e01dd43b
......@@ -56,7 +56,7 @@ extern int64_t table_6_3_3_2_4_prachConfig_Index [256][10];
extern uint16_t nr_du[838];
extern int16_t nr_ru[2*839];
int32_t generate_nr_prach( PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t subframe, uint16_t Nf )
int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe)
{
//lte_frame_type_t frame_type = ue->frame_parms.frame_type;
......@@ -66,13 +66,13 @@ int32_t generate_nr_prach( PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t subframe,
uint8_t prach_ConfigIndex = fp->prach_config_common.prach_ConfigInfo.prach_ConfigIndex;
uint8_t Ncs_config = fp->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig;
uint8_t restricted_set = fp->prach_config_common.prach_ConfigInfo.highSpeedFlag;
uint8_t preamble_index = ue->prach_resources[eNB_id]->ra_PreambleIndex;
//uint8_t tdd_mapindex = ue->prach_resources[eNB_id]->ra_TDD_map_index;
int16_t *prachF = ue->prach_vars[eNB_id]->prachF;
uint8_t preamble_index = ue->prach_resources[gNB_id]->ra_PreambleIndex;
//uint8_t tdd_mapindex = ue->prach_resources[gNB_id]->ra_TDD_map_index;
int16_t *prachF = ue->prach_vars[gNB_id]->prachF;
int16_t prach_tmp[98304*2*4] __attribute__((aligned(32)));
int16_t *prach = prach_tmp;
int16_t *prach2;
int16_t amp = ue->prach_vars[eNB_id]->amp;
int16_t amp = ue->prach_vars[gNB_id]->amp;
int16_t Ncp;
uint16_t NCS=0;
uint16_t *prach_root_sequence_map;
......
......@@ -1755,9 +1755,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
uint8_t is_crnti,
uint8_t llr8_flag);
int32_t generate_nr_prach( PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t subframe, uint16_t Nf );
int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe);
void *dlsch_thread(void *arg);
/**@}*/
......
......@@ -210,9 +210,12 @@ void nr_dump_dlsch_SI(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id,
exit(-1);
}
#endif
#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706)
//unsigned int gain_table[31] = {100,112,126,141,158,178,200,224,251,282,316,359,398,447,501,562,631,708,794,891,1000,1122,1258,1412,1585,1778,1995,2239,2512,2818,3162};
/*
unsigned int gain_table[31] = {100,112,126,141,158,178,200,224,251,282,316,359,398,447,501,562,631,708,794,891,1000,1122,1258,1412,1585,1778,1995,2239,2512,2818,3162};
#endif
unsigned int get_tx_amp_prach(int power_dBm, int power_max_dBm, int N_RB_UL)
{
......@@ -250,9 +253,10 @@ void nr_dump_dlsch_SI(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id,
else
return(amp_x_100/gain_table[-gain_dB]); // 245 corresponds to the factor sqrt(25/6)
}
*/
unsigned int get_tx_amp(int power_dBm, int power_max_dBm, int N_RB_UL, int nb_rb)
#if 0
unsigned int get_tx_amp(int power_dBm, int power_max_dBm, int N_RB_UL, int nb_rb) // TbD
{
int gain_dB = power_dBm - power_max_dBm;
......@@ -269,8 +273,6 @@ unsigned int get_tx_amp(int power_dBm, int power_max_dBm, int N_RB_UL, int nb_rb
return(0);
}
#endif
void nr_dump_dlsch_ra(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t nr_tti_rx)
{
unsigned int coded_bits_per_codeword;
......@@ -4480,11 +4482,11 @@ uint8_t nr_is_ri_TXOp(PHY_VARS_NR_UE *ue,
return(0);
}
void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t gNB_id, runmode_t mode) {
void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t gNB_id, runmode_t runmode) {
/* TBR
// here params are hardcoded */
int frame_tx = proc->frame_tx, nr_tti_tx = proc->nr_tti_tx, prach_power;
uint16_t preamble_tx=ue->prach_resources[0]->ra_PreambleIndex; //uint16_t preamble_tx=50; // TBR
uint16_t preamble_tx = 50, pathloss;
NR_PRACH_RESOURCES_t prach_resources;
uint8_t mod_id = ue->Mod_id;
NR_UE_MAC_INST_t *nr_UE_mac_inst = get_mac_inst(mod_id);
......@@ -4497,72 +4499,52 @@ void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t
ue->prach_resources[gNB_id] = &prach_resources; // TBR double check pointer
ue->prach_resources[gNB_id]->ra_PreambleIndex = preamble_tx;
ue->prach_resources[gNB_id]->ra_TDD_map_index = 0;
// ue->prach_resources[gNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER = 10; // TBR
// ue->prach_resources[gNB_id]->ra_RNTI = 93; // TBR
ue->prach_resources[gNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER = 10; // TBR
ue->prach_resources[gNB_id]->ra_RNTI = 93; // TBR NR_UE_MAC_INST_t
} else {
// ask L2 for RACH transport
/* TBR
// check if these modes are active */
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. Frame %d Slot %d \n", frame_tx, nr_tti_tx);
if ((runmode != rx_calib_ue) && (runmode != rx_calib_ue_med) && (runmode != rx_calib_ue_byp) && (runmode != no_L2_connect) ) {
LOG_D(PHY, "Getting PRACH resources. Frame %d Slot %d \n", frame_tx, nr_tti_tx);
ue->prach_resources[gNB_id] = nr_ue_get_rach(mod_id, ue->CC_id, UE_mode, frame_tx, gNB_id, nr_tti_tx);
// LOG_D(PHY,"Got prach_resources for gNB %d address %p, RRCCommon %p\n", gNB_id, ue->prach_resources[gNB_id], UE_mac_inst[ue->Mod_id].radioResourceConfigCommon); // TBR update this
}
}
if (ue->prach_resources[gNB_id]!=NULL) {
if (ue->prach_resources[gNB_id] != NULL) {
ue->generate_nr_prach = 1;
ue->prach_cnt = 0;
pathloss = get_nr_PL(ue, gNB_id);
LOG_I(PHY,"runmode %d\n",runmode);
#ifdef SMBV // TBR
ue->prach_resources[gNB_id]->ra_PreambleIndex = preamble_tx;
#endif
#ifdef OAI_EMU // TBR
ue->prach_PreambleIndex=ue->prach_resources[gNB_id]->ra_PreambleIndex;
#endif
// if (abstraction_flag == 0) { // TBR
LOG_I(PHY,"mode %d\n",mode);
if ((ue->mac_enabled==1) && (mode != calib_prach_tx)) {
/* TODO TBR
// check if ra_PREAMBLE_RECEIVED_TARGET_POWER is filled id */
ue->tx_power_dBm[nr_tti_tx] = ue->prach_resources[gNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER + get_nr_PL(ue,gNB_id);
/* TODO TBR
DEBUG ONLY */
printf("ue->tx_power_dBm[nr_tti_tx] %d ue->prach_resources[gNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER %d get_nr_PL(ue,gNB_id) %d\n", ue->tx_power_dBm[nr_tti_tx], ue->prach_resources[gNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER, get_nr_PL(ue,gNB_id));
} else {
if ((ue->mac_enabled == 1) && (runmode != calib_prach_tx)) {
// todo power control as per 38.213 ch 7.4
ue->tx_power_dBm[nr_tti_tx] = ue->prach_resources[gNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER + pathloss;
ue->tx_power_dBm[nr_tti_tx] = ue->tx_power_max_dBm;
ue->prach_resources[gNB_id]->ra_PreambleIndex = preamble_tx; /* TODO TBR this is hardcoded */
ue->prach_resources[gNB_id]->ra_PreambleIndex = preamble_tx;
}
LOG_I(PHY,"[UE %d][RAPROC] Frame %d, nr_tti_rx %d : Generating PRACH, preamble %d,PL %d, P0_PRACH %d, TARGET_RECEIVED_POWER %d dBm, PRACH TDD Resource index %d, RA-RNTI %d\n", ue->Mod_id,
LOG_D(PHY,"[UE %d][RAPROC] Frame %d, nr_tti_rx %d : Generating PRACH, preamble %d, PL %d, P0_PRACH %d, TARGET_RECEIVED_POWER %d dBm, RA-RNTI %d\n",
ue->Mod_id,
frame_tx,
nr_tti_tx,
ue->prach_resources[gNB_id]->ra_PreambleIndex,
get_nr_PL(ue,gNB_id),
pathloss,
ue->tx_power_dBm[nr_tti_tx],
ue->prach_resources[gNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER,
ue->prach_resources[gNB_id]->ra_TDD_map_index,
ue->prach_resources[gNB_id]->ra_RNTI);
ue->tx_total_RE[nr_tti_tx] = 96; /* TODO TBR this is hardcoded */
ue->tx_total_RE[nr_tti_tx] = 96; /* todo TBR double check */
#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706)
ue->prach_vars[gNB_id]->amp = get_tx_amp(ue->tx_power_dBm[nr_tti_tx], /* TODO TBR get_tx_amp is still valid for NR ? */
ue->prach_vars[gNB_id]->amp = get_tx_amp_prach(ue->tx_power_dBm[nr_tti_tx],
ue->tx_power_max_dBm,
ue->frame_parms.N_RB_UL,
6); /* TODO TBR why 6 ? */
ue->frame_parms.N_RB_UL);
#else
ue->prach_vars[gNB_id]->amp = AMP; /* TODO TBR where does this come from ? */
ue->prach_vars[gNB_id]->amp = AMP;
#endif
if ((mode == calib_prach_tx) && (((proc->frame_tx&0xfffe)%100)==0)) /* TODO TBR double check where calibration prach tx is handled */
LOG_D(PHY,"[UE %d][RAPROC] Frame %d, nr_tti_rx %d : PRACH TX power %d dBm, amp %d\n",
ue->Mod_id,
if ((runmode == calib_prach_tx) && (((proc->frame_tx&0xfffe)%100)==0))
LOG_D(PHY,"[UE %d][RAPROC] Frame %d, nr_tti_rx %d : PRACH TX power %d dBm, amp %d\n", ue->Mod_id,
proc->frame_rx,
proc->nr_tti_tx,
ue->tx_power_dBm[nr_tti_tx],
......@@ -4571,38 +4553,35 @@ void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t
// start_meas(&ue->tx_prach);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GENERATE_PRACH, VCD_FUNCTION_IN);
// prach_power = generate_nr_prach(ue,gNB_id,nr_tti_tx,frame_tx);
prach_power = generate_nr_prach(ue,0,9,0); //subframe number hardcoded according to the simulator /* TODO TBR this is hardcoded */
prach_power = generate_nr_prach(ue, gNB_id, nr_tti_tx);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GENERATE_PRACH, VCD_FUNCTION_OUT);
// stop_meas(&ue->tx_prach);
LOG_D(PHY,"[UE %d][RAPROC] PRACH PL %d dB, power %d dBm, digital power %d dB (amp %d)\n",
ue->Mod_id,
get_nr_PL(ue,gNB_id),
ue->tx_power_dBm[nr_tti_tx],
dB_fixed(prach_power),
ue->prach_vars[gNB_id]->amp);
// } else {
// UE_transport_info[ue->Mod_id][ue->CC_id].cntl.prach_flag=1;
// UE_transport_info[ue->Mod_id][ue->CC_id].cntl.prach_id=ue->prach_resources[eNB_id]->ra_PreambleIndex;
// } // commented for compiling as abstraction flag is 0
if (ue->mac_enabled == 1)
// nr_Msg1_transmitted(ue->Mod_id, ue->CC_id, frame_tx, gNB_id); TBR
nr_Msg1_transmitted(ue->Mod_id, ue->CC_id, frame_tx, gNB_id);
LOG_I(PHY,"[UE %d][RAPROC] Frame %d, nr_tti_rx %d: Generating PRACH (eNB %d) preamble index %d for UL, TX power %d dBm (PL %d dB), l3msg \n",
ue->Mod_id,frame_tx,nr_tti_tx,gNB_id,
LOG_I(PHY,"[UE %d][RAPROC] Frame %d, nr_tti_rx %d: Generating PRACH (gNB %d) preamble index %d for UL, TX power %d dBm (PL %d dB) \n",
ue->Mod_id,
frame_tx,
nr_tti_tx,
gNB_id,
ue->prach_resources[gNB_id]->ra_PreambleIndex,
ue->prach_resources[gNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER+get_nr_PL(ue,gNB_id),
get_nr_PL(ue,gNB_id));
ue->tx_power_dBm[nr_tti_tx],
pathloss);
}
// if we're calibrating the PRACH kill the pointer to its resources so that the RA protocol doesn't continue
if (mode == calib_prach_tx)
if (runmode == calib_prach_tx)
ue->prach_resources[gNB_id]=NULL;
LOG_D(PHY,"[UE %d] frame %d nr_tti_rx %d : generate_nr_prach %d, prach_cnt %d\n", ue->Mod_id,frame_tx,nr_tti_tx,ue->generate_nr_prach,ue->prach_cnt);
LOG_D(PHY,"[UE %d] frame %d nr_tti_rx %d : generate_nr_prach %d, prach_cnt %d\n", ue->Mod_id,frame_tx,nr_tti_tx, ue->generate_nr_prach, ue->prach_cnt);
ue->prach_cnt++;
......
......@@ -514,8 +514,7 @@ int main(int argc, char **argv)
/*tx_lev = generate_nr_prach(UE,
0, //gNB_id,
subframe,
0); //Nf */ //commented for testing purpose
subframe); */ //commented for testing purpose
UE_nr_rxtx_proc_t proc={0};
nr_ue_prach_procedures(UE,&proc,0,0);
......
......@@ -96,12 +96,53 @@ typedef struct {
uint8_t R:2; // octet 1 [7:6]
} __attribute__ ((__packed__)) NR_MAC_SUBHEADER_FIXED;
// BSR MAC CEs
// TS 38.321 ch. 6.1.3.1
// Short BSR for a specific logical channel group ID
typedef struct {
uint8_t Buffer_size:5; // octet 1 LSB
uint8_t LcgID:3; // octet 1 MSB
} __attribute__ ((__packed__)) NR_BSR_SHORT;
typedef NR_BSR_SHORT NR_BSR_SHORT_TRUNCATED;
// Long BSR for all logical channel group ID
typedef struct {
uint8_t Buffer_size7:8;
uint8_t Buffer_size6:8;
uint8_t Buffer_size5:8;
uint8_t Buffer_size4:8;
uint8_t Buffer_size3:8;
uint8_t Buffer_size2:8;
uint8_t Buffer_size1:8;
uint8_t Buffer_size0:8;
uint8_t LcgID0:1;
uint8_t LcgID1:1;
uint8_t LcgID2:1;
uint8_t LcgID3:1;
uint8_t LcgID4:1;
uint8_t LcgID5:1;
uint8_t LcgID6:1;
uint8_t LcgID7:1;
} __attribute__ ((__packed__)) NR_BSR_LONG;
typedef NR_BSR_LONG NR_BSR_LONG_TRUNCATED;
// 38.321 ch. 6.1.3.4
typedef struct {
uint8_t TA_COMMAND:6; // octet 1 [5:0]
uint8_t TAGID:2; // octet 1 [7:6]
} __attribute__ ((__packed__)) NR_MAC_CE_TA;
// single Entry PHR MAC CE
// TS 38.321 ch. 6.1.3.8
typedef struct {
uint8_t PH:6;
uint8_t R1:2;
uint8_t PCMAX:6;
uint8_t R2:6;
} __attribute__ ((__packed__)) NR_SINGLE_ENTRY_PHR_MAC_CE;
// /*! \brief CCCH payload */ // TBR
// typedef struct {
// uint8_t payload[CCCH_PAYLOAD_SIZE_MAX];
......@@ -154,6 +195,7 @@ typedef struct {
#define UL_SCH_LCID_SRB1 0x01
#define UL_SCH_LCID_SRB2 0x02
#define UL_SCH_LCID_SRB3 0x03
#define UL_SCH_LCID_DTCH 0x04
#define UL_SCH_LCID_CCCH_MSG3 0x21
#define UL_SCH_LCID_RECOMMENDED_BITRATE_QUERY 0x35
#define UL_SCH_LCID_MULTI_ENTRY_PHR_4_OCT 0x36
......
......@@ -100,10 +100,12 @@ typedef struct {
SFN_C_TYPE type0_pdcch_ss_sfn_c;
uint32_t type0_pdcch_ss_n_c;
uint32_t type0_pdcch_consecutive_slots;
int rnti_type;
/* PDUs */
/// Outgoing CCCH pdu for PHY
CCCH_PDU CCCH_pdu;
ULSCH_PDU ulsch_pdu;
/* Random Access parameters */
/// state of RA procedure
......
......@@ -152,6 +152,19 @@ void nr_ue_process_mac_pdu(module_id_t module_idP,
uint8_t gNB_index,
NR_UL_TIME_ALIGNMENT_t *ul_time_alignment);
unsigned char nr_generate_ulsch_pdu(uint8_t *sdus_payload,
uint8_t *pdu,
uint8_t num_sdus,
uint16_t *sdu_lengths,
uint8_t *sdu_lcids,
uint8_t power_headroom,
uint16_t crnti,
uint16_t truncated_bsr,
uint16_t short_bsr,
uint16_t long_bsr,
unsigned short post_padding);
int8_t nr_ue_process_dlsch(module_id_t module_id, int cc_id, uint8_t gNB_index, fapi_nr_dci_indication_t *dci_ind, void *pduP, uint32_t pdu_len);
void ue_dci_configuration(NR_UE_MAC_INST_t *mac,fapi_nr_dl_config_request_t *dl_config,int frame,int slot);
......
......@@ -35,7 +35,7 @@
#include "mac_defs.h"
#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
/* 38.321 subclause 7.3 - return values are in dB */
/* TS 38.321 subclause 7.3 - return DELTA_PREAMBLE values in dB */
int8_t nr_get_DELTA_PREAMBLE(module_id_t mod_id, int CC_id){
NR_UE_MAC_INST_t *nrUE_mac_inst = get_mac_inst(mod_id);
......@@ -43,13 +43,15 @@ int8_t nr_get_DELTA_PREAMBLE(module_id_t mod_id, int CC_id){
AssertFatal(CC_id == 0, "Transmission on secondary CCs is not supported yet\n");
NR_SubcarrierSpacing_t scs = nr_rach_ConfigCommon->msg1_SubcarrierSpacing;
uint8_t preambleFormat, prachConfigIndex;
lte_frame_type_t frame_type = TDD; // TODO TBR retrieve frame type. Currently hardcoded to TDD.
// was nr_UE_mac_inst[mod_id].tdd_Config
nr_frequency_range_e fr = nr_FR1; // TODO TBR retrieve frame type. Currently hardcoded to FR1.
int mu;
// SCS configuration from msg1_SubcarrierSpacing and table 4.2-1 in TS 38.211
NR_SubcarrierSpacing_t scs = nr_rach_ConfigCommon->msg1_SubcarrierSpacing;
switch (scs){
case NR_SubcarrierSpacing_kHz15:
mu = 0;
......@@ -87,6 +89,8 @@ int8_t nr_get_DELTA_PREAMBLE(module_id_t mod_id, int CC_id){
AssertFatal(1 == 0,"Unknown msg1_SubcarrierSpacing %d\n", scs);
}
// Preamble formats given by prach_ConfigurationIndex and tables 6.3.3.2-2 and 6.3.3.2-2 in TS 38.211
prachConfigIndex = nr_rach_ConfigCommon->rach_ConfigGeneric.prach_ConfigurationIndex;
preambleFormat = get_nr_prach_fmt(prachConfigIndex,frame_type,fr);
......@@ -128,28 +132,16 @@ int8_t nr_get_DELTA_PREAMBLE(module_id_t mod_id, int CC_id){
return;
}
/* TS 38.321 subclause 5.1.3 - RA preamble transmission - ra_PREAMBLE_RECEIVED_TARGET_POWER configuration */
int8_t nr_get_Po_NOMINAL_PUSCH(module_id_t mod_id, uint8_t CC_id){
NR_UE_MAC_INST_t *nr_UE_mac_inst = get_mac_inst(mod_id);
NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = nr_UE_mac_inst->nr_rach_ConfigCommon;
NR_PRACH_RESOURCES_t *prach_resources = &nr_UE_mac_inst->RA_prach_resources;
//AssertFatal(CC_id == 0, "Transmission on secondary CCs is not supported yet\n");
AssertFatal(nr_rach_ConfigCommon != NULL, "[UE %d] CCid %d FATAL nr_rach_ConfigCommon is NULL !!!\n", mod_id, CC_id);
int8_t receivedTargerPower = nr_rach_ConfigCommon->rach_ConfigGeneric.preambleReceivedTargetPower + nr_get_DELTA_PREAMBLE(mod_id, CC_id) + (nr_UE_mac_inst->RA_PREAMBLE_POWER_RAMPING_COUNTER - 1) * prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP;
return receivedTargerPower;
//return (-120 + (nr_rach_ConfigCommon->rach_ConfigGeneric.preambleReceivedTargetPower << 1) + nr_get_DELTA_PREAMBLE(mod_id, CC_id) );
}
\ No newline at end of file
/*int8_t get_deltaP_rampup(module_id_t module_idP, uint8_t CC_id){ // TBR
AssertFatal(CC_id == 0,
"Transmission on secondary CCs is not supported yet\n");
LOG_D(MAC, "[PUSCH]%d dB\n",
nrUE_mac_inst->RA_PREAMBLE_TRANSMISSION_COUNTER << 1);
return ((int8_t)
(nrUE_mac_inst->RA_PREAMBLE_TRANSMISSION_COUNTER << 1));
}*/
\ No newline at end of file
......@@ -67,7 +67,7 @@ extern UE_MODE_t get_nrUE_mode(uint8_t Mod_id, uint8_t CC_id, uint8_t gNB_id);
extern int64_t table_6_3_3_2_2_prachConfig_Index [256][9];
extern int64_t table_6_3_3_2_3_prachConfig_Index [256][9];
//extern uint8_t nfapi_mode; // TBR
//extern uint8_t nfapi_mode;
// This routine implements Section 5.1.2 (UE Random Access Resource Selection)
// and Section 5.1.3 (Random Access Preamble Transmission) from 3GPP TS 38.321
......@@ -80,43 +80,27 @@ void nr_get_prach_resources(module_id_t mod_id,
NR_UE_MAC_INST_t *nr_UE_mac_inst = get_mac_inst(mod_id);
NR_PRACH_RESOURCES_t *prach_resources = &nr_UE_mac_inst->RA_prach_resources;
NR_BeamFailureRecoveryConfig_t *beam_failure_recovery_config = &nr_UE_mac_inst->RA_BeamFailureRecoveryConfig;
NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = nr_UE_mac_inst->nr_rach_ConfigCommon;
// NR_BeamFailureRecoveryConfig_t *beam_failure_recovery_config = &nr_UE_mac_inst->RA_BeamFailureRecoveryConfig; // todo
int messagePowerOffsetGroupB, messageSizeGroupA, PLThreshold, sizeOfRA_PreamblesGroupA, numberOfRA_Preambles, frequencyStart, i, deltaPreamble_Msg3;
uint8_t noGroupB = 0, s_id, f_id, ul_carrier_id, msg1_FDM, prach_ConfigIndex, SFN_nbr, Msg3_size;
NR_RSRP_Range_t rsrp_ThresholdSSB;
/* TBR retrieve following params
// currently hardcoded */
prach_resources->ra_PreambleIndex = 51;
/*uint8_t Msg3_size = nr_UE_mac_inst->RA_Msg3_size;
uint8_t f_id = 0, num_prach = 0;*/
/*AssertFatal(CC_id == 0,
"Transmission on secondary CCs is not supported yet\n");
AssertFatal(nr_UE_mac_inst->nr_rach_ConfigCommon != NULL,
"[UE %d] FATAL nr_rach_ConfigCommon is NULL !!!\n",
mod_id);*/
// NR_RSRP_Range_t rsrp_ThresholdSSB; // TBR todo
///////////////////////////////////////////////////////////
//////////* UE Random Access Resource Selection *//////////
///////////////////////////////////////////////////////////
//numberOfRA_Preambles = (1 + nr_rach_ConfigCommon->preambleInfo.numberOfRA_Preambles) << 2;
numberOfRA_Preambles = nr_rach_ConfigCommon->totalNumberOfRA_Preambles;
rsrp_ThresholdSSB = *nr_rach_ConfigCommon->rsrp_ThresholdSSB;
nr_UE_mac_inst->nr_rach_ConfigCommon->rach_ConfigGeneric.prach_ConfigurationIndex;
/* TBR switch initialisation cases
- RA initiated by beam failure recovery operation (subclause 5.17 TS 38.321)
- SSB selection, set prach_resources->ra_PreambleIndex
- RA initiated by PDCCH: ra_PreambleIndex provided by PDCCH && ra_PreambleIndex != 0b000000
- set REAMBLE_INDEX to ra_PreambleIndex
- select the SSB signalled by PDCCH
- RA initiated for SI request:
- SSB selection, set prach_resources->ra_PreambleIndex */
// todo: switch initialisation cases
// - RA initiated by beam failure recovery operation (subclause 5.17 TS 38.321)
// -- SSB selection, set prach_resources->ra_PreambleIndex
// - RA initiated by PDCCH: ra_preamble_index provided by PDCCH && ra_PreambleIndex != 0b000000
// -- TBR coming from dci_pdu_rel15[0].ra_preamble_index
// -- set PREAMBLE_INDEX to ra_preamble_index
// -- select the SSB signalled by PDCCH
// - RA initiated for SI request:
// -- SSB selection, set prach_resources->ra_PreambleIndex
// if (rach_ConfigDedicated) { // This is for network controlled Mobility
// // TBR operation for contention-free RA resources when:
......@@ -126,14 +110,19 @@ void nr_get_prach_resources(module_id_t mod_id,
// return;
// }
/* Contention-based RA preamble selection:
- TBR selection of SSB with SS-RSRP above rsrp-ThresholdSSB else select any SSB */
//////////* Contention-based RA preamble selection *//////////
// todo: selection of SSB with SS-RSRP above rsrp-ThresholdSSB else select any SSB
// rsrp_ThresholdSSB = *nr_rach_ConfigCommon->rsrp_ThresholdSSB; // TBR
Msg3_size = nr_UE_mac_inst->RA_Msg3_size;
numberOfRA_Preambles = nr_rach_ConfigCommon->totalNumberOfRA_Preambles;
if (!nr_rach_ConfigCommon->groupBconfigured) {
noGroupB = 1;
} else {
/* RA preambles group B is configured
// RA preambles group B is configured
// - Defining the number of RA preambles in RA Preamble Group A for each SSB */
//sizeOfRA_PreamblesGroupA = (nr_rach_ConfigCommon->preambleInfo.preamblesGroupAConfig->sizeOfRA_PreamblesGroupA + 1) << 2;
sizeOfRA_PreamblesGroupA = nr_rach_ConfigCommon->groupBconfigured->numberOfRA_PreamblesGroupA;
switch (nr_rach_ConfigCommon->groupBconfigured->ra_Msg3SizeGroupA){
/* - Threshold to determine the groups of RA preambles */
......@@ -169,11 +158,11 @@ void nr_get_prach_resources(module_id_t mod_id,
break;
default:
AssertFatal(1 == 0,"Unknown ra_Msg3SizeGroupA %d\n", nr_rach_ConfigCommon->groupBconfigured->ra_Msg3SizeGroupA);
/* TBR cases 10 -15*/
/* todo cases 10 -15*/
}
/* - Power offset for preamble selection */
/* TBR: what value to use as default? */
/* Power offset for preamble selection in dB */
/* TBR: what value to use as default? Shall it be converted ? */
messagePowerOffsetGroupB = -9999;
switch (nr_rach_ConfigCommon->groupBconfigured->messagePowerOffsetGroupB){
case 0:
......@@ -204,84 +193,58 @@ void nr_get_prach_resources(module_id_t mod_id,
AssertFatal(1 == 0,"Unknown messagePowerOffsetGroupB %d\n", nr_rach_ConfigCommon->groupBconfigured->messagePowerOffsetGroupB);
}
// TBR Msg3-DeltaPreamble should be provided from higher layers, otherwise is 0
// todo Msg3-DeltaPreamble should be provided from higher layers, otherwise is 0
nr_UE_mac_inst->deltaPreamble_Msg3 = 0;
deltaPreamble_Msg3 = nr_UE_mac_inst->deltaPreamble_Msg3;
}
PLThreshold = prach_resources->RA_PCMAX - nr_rach_ConfigCommon->rach_ConfigGeneric.preambleReceivedTargetPower - deltaPreamble_Msg3 - messagePowerOffsetGroupB;
// PLThreshold = prach_resources->RA_PCMAX - nr_get_DELTA_PREAMBLE(mod_id, CC_id) - nr_get_Po_NOMINAL_PUSCH(mod_id, CC_id) - messagePowerOffsetGroupB;
// TBR Note Pcmax is set to 0 here, we have to fix this
/* Msg3 has not been transmitted yet */
if (first_Msg3 == 1) {
if (noGroupB == 1) {
// use Group A preamble
prach_resources->ra_PreambleIndex = (taus()) % numberOfRA_Preambles;
prach_resources->ra_RACH_MaskIndex = 0;
nr_UE_mac_inst->RA_usedGroupA = 1;
} else if ((Msg3_size < messageSizeGroupA) && (get_PL(mod_id, 0, gNB_id) > PLThreshold)) {
// TBR update get_PL to NR
// TBR add condition for initiation by CCCH
// Group B is configured and RA preamble Group A is used
// - todo TBR update get_PL to NR get_nr_PL (needs PHY_VARS_NR_UE)
// - todo add condition on CCCH_sdu_size for initiation by CCCH
prach_resources->ra_PreambleIndex = (taus()) % sizeOfRA_PreamblesGroupA;
prach_resources->ra_RACH_MaskIndex = 0;
nr_UE_mac_inst->RA_usedGroupA = 1;
} else {
// Group B preamble is configured and used
// the first sizeOfRA_PreamblesGroupA RA preambles belong to RA Preambles Group A
// the remaining belong to RA Preambles Group B
prach_resources->ra_PreambleIndex = sizeOfRA_PreamblesGroupA
+ (taus()) % (numberOfRA_Preambles - sizeOfRA_PreamblesGroupA);
prach_resources->ra_RACH_MaskIndex = 0;
prach_resources->ra_PreambleIndex = sizeOfRA_PreamblesGroupA + (taus()) % (numberOfRA_Preambles - sizeOfRA_PreamblesGroupA);
nr_UE_mac_inst->RA_usedGroupA = 0;
}
//TBR check why this is here
// prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER = nr_get_Po_NOMINAL_PUSCH(mod_id, CC_id);
} else {
// Msg3 is being retransmitted
} else { // Msg3 is being retransmitted
if (nr_UE_mac_inst->RA_usedGroupA == 1) {
if (nr_rach_ConfigCommon->groupBconfigured){
prach_resources->ra_PreambleIndex = (taus()) % sizeOfRA_PreamblesGroupA;
} else {
prach_resources->ra_PreambleIndex = (taus()) & 0x3f; // TBR check this
prach_resources->ra_RACH_MaskIndex = 0;
}
} else {
// TBR FIXME nr_rach_ConfigCommon->preambleInfo.preamblesGroupAConfig may be zero
prach_resources->ra_PreambleIndex =
sizeOfRA_PreamblesGroupA + (taus()) % (numberOfRA_Preambles - sizeOfRA_PreamblesGroupA);
prach_resources->ra_RACH_MaskIndex = 0;
prach_resources->ra_PreambleIndex = sizeOfRA_PreamblesGroupA + (taus()) % (numberOfRA_Preambles - sizeOfRA_PreamblesGroupA);
}
}
// TBR determine next available PRACH occasion
// todo determine next available PRACH occasion
// - if RA initiated for SI request and ra_AssociationPeriodIndex and si-RequestPeriod are configured
// - else if SSB is selected above
// - else if CSI-RS is selected above
/* // choose random PRACH resource in TDD
if (nr_UE_mac_inst->tdd_Config) {
num_prach = get_num_prach_tdd(mod_id);
if ((num_prach > 0) && (num_prach < 6))
prach_resources->ra_TDD_map_index = (taus() % num_prach);
f_id = get_fid_prach_tdd(mod_id, nr_UE_mac_inst [mod_id].RA_prach_resources->ra_TDD_map_index);
}*/
/////////////////////////////////////////////////////////////////////////////
//////////* Random Access Preamble Transmission (5.1.3 TS 38.321) *//////////
/////////////////////////////////////////////////////////////////////////////
// TBR condition on notification of suspending power ramping counter from lower layer (5.1.3 TS 38.321)
// TBR check if SSB or CSI-RS have not changed since the selection in the last RA Preamble tranmission
if (nr_UE_mac_inst->RA_PREAMBLE_TRANSMISSION_COUNTER >1)
// todo condition on notification of suspending power ramping counter from lower layer (5.1.3 TS 38.321) // TBR
// todo check if SSB or CSI-RS have not changed since the selection in the last RA Preamble tranmission
if (nr_UE_mac_inst->RA_PREAMBLE_TRANSMISSION_COUNTER > 1)
nr_UE_mac_inst->RA_PREAMBLE_TRANSMISSION_COUNTER++;
//prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER = nr_rach_ConfigCommon->rach_ConfigGeneric.preambleReceivedTargetPower +
// nr_get_DELTA_PREAMBLE(mod_id, CC_id) + (nr_UE_mac_inst->RA_PREAMBLE_POWER_RAMPING_COUNTER - 1) * prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP; // TBR
prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER = nr_get_Po_NOMINAL_PUSCH(mod_id, CC_id);
/* RA-RNTI computation (associated to PRACH occasion in which the RA Preamble is transmitted)
......@@ -289,11 +252,7 @@ void nr_get_prach_resources(module_id_t mod_id,
// 2) getting star_symb, SFN_nbr from table 6.3.3.2-3 (TDD and FR1 scenario)
// 3) TBR extend this (e.g. f_id selection, ul_carrier_id are hardcoded) */
ul_carrier_id = 0; // UL carrier used for RA preamble transmission, hardcoded for NUL carrier
f_id = 0;
//frequencyStart = nr_rach_ConfigCommon->rach_ConfigGeneric.msg1_FrequencyStart;
switch (nr_rach_ConfigCommon->rach_ConfigGeneric.msg1_FDM){
switch (nr_rach_ConfigCommon->rach_ConfigGeneric.msg1_FDM){ // todo this is not used
case 0:
msg1_FDM = 1;
break;
......@@ -312,36 +271,41 @@ void nr_get_prach_resources(module_id_t mod_id,
prach_ConfigIndex = nr_rach_ConfigCommon->rach_ConfigGeneric.prach_ConfigurationIndex;
// TBR this is for TDD FR1 only
// ra_RNTI computation
// - todo: this is for TDD FR1 only
// - ul_carrier_id: UL carrier used for RA preamble transmission, hardcoded for NUL carrier
// - f_id: index of the PRACH occasion in the frequency domain
// - s_id is starting symbol of the PRACH occasion [0...14]
// - t_id is the first slot of the PRACH occasion in a system frame [0...80]
ul_carrier_id = 0; // todo SUL
f_id = nr_rach_ConfigCommon->rach_ConfigGeneric.msg1_FrequencyStart;
SFN_nbr = table_6_3_3_2_3_prachConfig_Index[prach_ConfigIndex][4];
s_id = table_6_3_3_2_3_prachConfig_Index[prach_ConfigIndex][5]; // starting symbol of the PRACH occasion
s_id = table_6_3_3_2_3_prachConfig_Index[prach_ConfigIndex][5];
// pick the first slot of the PRACH occasion in a system frame (0 <= t_id <= 80)
// Pick the first slot of the PRACH occasion in a system frame
for (i = 0; i < 10; i++){
if (((SFN_nbr & (1 << i)) >> i) == 1){
t_id = 2*i;
break;
}
}
prach_resources->ra_RNTI = 1 + s_id + 14 * t_id + 1120 * f_id + 8960 * ul_carrier_id;
LOG_D(MAC, "Computed ra_RNTI is %d", prach_resources->ra_RNTI);
}
void nr_Msg1_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint8_t gNB_id){
#if 0 //TBR
NR_UE_MAC_INST_t *nr_UE_mac_inst = get_mac_inst(mod_id);
AssertFatal(CC_id == 0, "Transmission on secondary CCs is not supported yet\n");
// start contention resolution timer
nr_UE_mac_inst->RA_attempt_number++;
// Start contention resolution timer
nr_UE_mac_inst->RA_attempt_number++; // todo this is not used
if (opt_enabled) {
trace_pdu(DIRECTION_UPLINK, NULL, 0, mod_id, WS_NO_RNTI, nr_UE_mac_inst->RA_prach_resources->ra_PreambleIndex, nr_UE_mac_inst->txFrame, nr_UE_mac_inst->txSubframe, 0, nr_UE_mac_inst->RA_attempt_number);
LOG_D(OPT, "[UE %d][RAPROC] TX MSG1 Frame %d trace pdu for rnti %x with size %d\n", mod_id, frameP, 1, nr_UE_mac_inst->RA_Msg3_size);
}
#endif
}
void nr_Msg3_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint8_t gNB_id){
#if 0 // TBR
AssertFatal(CC_id == 0, "Transmission on secondary CCs is not supported yet\n");
......@@ -352,10 +316,6 @@ void nr_Msg3_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint
nr_UE_mac_inst->RA_contention_resolution_cnt = 0;
nr_UE_mac_inst->RA_contention_resolution_timer_active = 1;
if (opt_enabled) {
trace_pdu(DIRECTION_UPLINK, &nr_UE_mac_inst->CCCH_pdu.payload[0], nr_UE_mac_inst->RA_Msg3_size, mod_id, WS_C_RNTI, nr_UE_mac_inst->crnti, nr_UE_mac_inst->txFrame, nr_UE_mac_inst->txSubframe, 0, 0);
LOG_D(OPT, "[UE %d][RAPROC] MSG3 Frame %d trace pdu Preamble %d with size %d\n", mod_id, frameP, nr_UE_mac_inst->crnti /*nr_UE_mac_inst->RA_prach_resources->ra_PreambleIndex */, nr_UE_mac_inst->RA_Msg3_size);
}
#endif
}
......@@ -374,42 +334,33 @@ NR_PRACH_RESOURCES_t *nr_ue_get_rach(module_id_t mod_id,
int nr_tti_tx){
NR_UE_MAC_INST_t *nr_UE_mac_inst = get_mac_inst(mod_id);
uint8_t size_sdu = 0, Nb_tb = 1, lcid = CCCH, dcch_header_len = 0, ulsch_buff[MAX_ULSCH_PAYLOAD_BYTES];
// UE_MODE_t UE_mode;
uint16_t Size16, sdu_lengths;
uint8_t lcid = CCCH, dcch_header_len = 0, mac_sdus[MAX_NR_ULSCH_PAYLOAD_BYTES], * payload;
uint16_t size_sdu = 0;
unsigned short post_padding;
NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = (struct NR_RACH_ConfigCommon_t *) NULL;
NR_PRACH_RESOURCES_t *prach_resources = &nr_UE_mac_inst->RA_prach_resources;
int32_t frame_diff = 0;
// Modification for phy_stub_ue operation // TBR
// if(nfapi_mode == 3) { // phy_stub_ue mode
// UE_mode = nr_UE_mac_inst->UE_mode[CC_id];
// LOG_D(MAC, "ue_get_rach, UE_mode: %d", UE_mode);
// }
// else // Full stack mode
// UE_mode = get_nrUE_mode(mod_id, CC_id, gNB_id); // TBR
uint8_t sdu_lcids[NB_RB_MAX] = {0}; // TBR
uint16_t sdu_lengths[NB_RB_MAX] = {0}; // TBR
int TBS_bytes = 848, header_length_total, num_sdus, offset; // TBR
AssertFatal(CC_id == 0,"Transmission on secondary CCs is not supported yet\n");
if (UE_mode == PRACH) {
LOG_D(MAC, "ue_get_rach, RA_active value: %d", nr_UE_mac_inst->RA_active);
if (nr_UE_mac_inst->nr_rach_ConfigCommon) {
LOG_D(MAC, "nr_ue_get_rach, RA_active value: %d", nr_UE_mac_inst->RA_active);
AssertFatal(nr_UE_mac_inst->nr_rach_ConfigCommon != NULL, "[UE %d] FATAL nr_rach_ConfigCommon is NULL !!!\n", mod_id);
if (nr_UE_mac_inst->nr_rach_ConfigCommon) { // TBR check the condition
nr_rach_ConfigCommon = nr_UE_mac_inst->nr_rach_ConfigCommon;
printf("nr_rach_ConfigCommon from MAC nr_UE_mac_inst\n"); /* TBR DEBUG only */
} else return NULL;
/* TBR moved below
size_sdu = mac_rrc_nr_data_req(mod_id,
CC_id,
frame,
CCCH,
1,
&nr_UE_mac_inst->CCCH_pdu.payload[sizeof(SCH_SUBHEADER_SHORT) + 1], gNB_id, 0);*/
if (nr_UE_mac_inst->RA_active == 0) {
/* RA not active - checking if RRC is ready to initiate the RA procedure */
LOG_I(MAC, "RA not active\n");
LOG_I(MAC, "RA not active. Starting RA preamble initialization.\n");
/* TBR flush Msg3 Buffer
this was done like this but at PHY level
......@@ -420,14 +371,7 @@ NR_PRACH_RESOURCES_t *nr_ue_get_rach(module_id_t mod_id,
}
*/
nr_UE_mac_inst->RA_PREAMBLE_TRANSMISSION_COUNTER = 1;
nr_UE_mac_inst->RA_PREAMBLE_POWER_RAMPING_COUNTER = 1;
prach_resources->RA_PREAMBLE_BACKOFF = 0;
/* TBR: if carrier to use is explicitly signalled do RA CARRIER SELECTION (SUL, NUL) this will set PCMAX */
prach_resources->RA_PCMAX = 0;
/* TBR: BWP operation (subclause 5.15 TS 38.321) */
nr_UE_mac_inst->RA_RAPID_found = 0;
/* Set RA_PREAMBLE_POWER_RAMPING_STEP */
switch (nr_rach_ConfigCommon->rach_ConfigGeneric.powerRampingStep){ // in dB
......@@ -445,187 +389,113 @@ NR_PRACH_RESOURCES_t *nr_ue_get_rach(module_id_t mod_id,
break;
}
prach_resources->RA_PREAMBLE_BACKOFF = 0;
prach_resources->RA_SCALING_FACTOR_BI = 1;
/* TBR: initialization by beam failure recovery */
/* TBR: initialization by handover */
/* size_sdu = mac_rrc_nr_data_req(mod_id,
prach_resources->RA_PCMAX = 0; // currently hardcoded to 0
// todo:
// - check if carrier to use is explicitly signalled then do (1) RA CARRIER SELECTION (SUL, NUL) (2) set PCMAX
// - BWP operation (subclause 5.15 TS 38.321)
// - handle initialization by beam failure recovery
// - handle initialization by handover
if (!IS_SOFTMODEM_NOS1){
// todo mac_rrc_nr_data_req_ue
payload = &nr_UE_mac_inst->CCCH_pdu.payload;
size_sdu = (uint16_t) mac_rrc_nr_data_req_ue(mod_id,
CC_id,
frame,
CCCH,
Nb_tb,
&nr_UE_mac_inst->CCCH_pdu.payload[sizeof(NR_MAC_SUBHEADER_SHORT) + 1]); */
// TBR mac_rrc_nr_data_req is a GNB func
// use nr_mac_rrc_data_ind_ue instead
payload[sizeof(NR_MAC_SUBHEADER_SHORT) + 1]);
// TBR fix CCCH PDU payload
Size16 = (uint16_t) size_sdu;
LOG_D(MAC,"[UE %d] Frame %d: Requested RRCConnectionRequest, got %d bytes\n", mod_id,frame, size_sdu);
/* TBR FIX THIS
// todo: else triggers a transmission on DCCH using PRACH (during handover, or sending SR for example)
// LOG_D(MAC,"[UE %d] Frame %d: Requested RRCConnectionRequest, got %d bytes\n",mod_id,frame,size_sdu);
LOG_I(RRC,
"[MSC_MSG][FRAME %05d][RRC_UE][MOD %02d][][--- MAC_DATA_REQ (RRCConnectionRequest gNB %d) --->][MAC_UE][MOD %02d][]\n",
frame, mod_id, gNB_id, mod_id);
LOG_I(MAC,
"[UE %d] Frame %d: Requested RRCConnectionRequest, got %d bytes\n",
mod_id, frame, size_sdu);
} else {
// fill ulsch_buffer with random data
payload = (uint8_t *)nr_UE_mac_inst->ulsch_pdu.payload[0];
for (int i = 0; i < TBS_bytes; i++){
mac_sdus[i] = (unsigned char) (lrand48()&0xff);
}
//Sending SDUs with size 1
//Initialize elements of sdu_lcids and sdu_lengths
sdu_lcids[0] = UL_SCH_LCID_DTCH;
sdu_lengths[0] = TBS_bytes - 3;
header_length_total += 2 + (sdu_lengths[0] >= 128);
size_sdu += sdu_lengths[0];
num_sdus +=1;
}
nr_UE_mac_inst->RA_RAPID_found = 0;
// TBR which frame and slot ?
nr_UE_mac_inst->RA_tx_frame = frame;
nr_UE_mac_inst->RA_tx_subframe = nr_tti_tx;
nr_UE_mac_inst->RA_backoff_frame = frame;
nr_UE_mac_inst->RA_backoff_subframe = nr_tti_tx;*/
nr_UE_mac_inst->RA_backoff_subframe = nr_tti_tx;
/*if (size_sdu > 0) { */
if (size_sdu > 0) { // TBR size_sdu + MAC_Header_len + mac_ce_len
/* TBR initialisation by RRC
// PDU from CCCH */
LOG_I(MAC, "[UE %d] Frame %d: Initialisation Random Access Procedure\n", mod_id, frame);
// TBR
/*nr_UE_mac_inst->RA_Msg3_size = size_sdu + sizeof(SCH_SUBHEADER_SHORT) + sizeof(SCH_SUBHEADER_SHORT);
nr_UE_mac_inst->RA_PREAMBLE_TRANSMISSION_COUNTER = 1;
nr_UE_mac_inst->RA_PREAMBLE_POWER_RAMPING_COUNTER = 1;
nr_UE_mac_inst->RA_Msg3_size = size_sdu + sizeof(NR_MAC_SUBHEADER_SHORT) + sizeof(NR_MAC_SUBHEADER_SHORT); // TBR size_sdu + MAC_Header_len + mac_ce_len
nr_UE_mac_inst->RA_prachMaskIndex = 0;
prach_resources->Msg3 = nr_UE_mac_inst->CCCH_pdu.payload;
nr_UE_mac_inst->RA_backoff_cnt = 0; // add the backoff condition here if we have it from a previous RA reponse which failed (i.e. backoff indicator)
AssertFatal(nr_rach_ConfigCommon != NULL,
"[UE %d] FATAL Frame %d: nr_rach_ConfigCommon is NULL !!!\n",
mod_id, frame);
nr_UE_mac_inst->RA_window_cnt = 2 + nr_rach_ConfigCommon->ra_SupervisionInfo.ra_ResponseWindowSize;
// TBR todo: add the backoff condition here if we have it from a previous RA reponse which failed (i.e. backoff indicator)
nr_UE_mac_inst->RA_backoff_cnt = 0;
nr_UE_mac_inst->RA_active = 1;
prach_resources->Msg3 = payload;
if (nr_UE_mac_inst->RA_window_cnt == 9) {
nr_UE_mac_inst->RA_window_cnt = 10; // Note: 9 subframe window doesn't exist, after 8 is 10!
}*/
// TBR todo double check window count
// nr_UE_mac_inst->RA_window_cnt = 2 + nr_rach_ConfigCommon->ra_SupervisionInfo.ra_ResponseWindowSize;
// if (nr_UE_mac_inst->RA_window_cnt == 9) {
// nr_UE_mac_inst->RA_window_cnt = 10; // Note: 9 subframe window doesn't exist, after 8 is 10!
// }
// Fill in preamble and PRACH resources
nr_get_prach_resources(mod_id, CC_id, gNB_id, nr_tti_tx, 1, NULL);
/*generate_ulsch_header((uint8_t *) & nr_UE_mac_inst->CCCH_pdu.payload[0], // mac header
1, // num sdus
0, // short pading
&Size16, // sdu length
&lcid, // sdu lcid
NULL, // power headroom
NULL, // crnti
NULL, // truncated bsr
NULL, // short bsr
NULL, // long_bsr
1); //post_padding*/
return (&nr_UE_mac_inst->RA_prach_resources);
/*} else if (nr_UE_mac_inst->scheduling_info.
BSR_bytes[nr_UE_mac_inst->scheduling_info.LCGID[DCCH]] > 0) {
// This is for triggering a transmission on DCCH using PRACH (during handover,
// or sending SR for example)
dcch_header_len = 2 + 2; /// SHORT Subheader + C-RNTI control element
LOG_USEDINLOG_VAR(mac_rlc_status_resp_t,rlc_status)=mac_rlc_status_ind(mod_id,
nr_UE_mac_inst->crnti,
gNB_id, frame, nr_tti_tx,
ENB_FLAG_NO, MBMS_FLAG_NO, DCCH, 6
#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
,0, 0
#endif
);
if (nr_UE_mac_inst->crnti_before_ho)
LOG_D(MAC,
"[UE %d] Frame %d : UL-DCCH -> ULSCH, HO RRCConnectionReconfigurationComplete (%x, %x), RRC message has %d bytes to send throug PRACH (mac header len %d)\n",
mod_id, frame,
nr_UE_mac_inst->crnti,
nr_UE_mac_inst->crnti_before_ho,
rlc_status.bytes_in_buffer, dcch_header_len);
else
LOG_D(MAC,
"[UE %d] Frame %d : UL-DCCH -> ULSCH, RRC message has %d bytes to send through PRACH(mac header len %d)\n",
mod_id, frame, rlc_status.bytes_in_buffer,
dcch_header_len);
sdu_lengths = mac_rlc_data_req(mod_id, nr_UE_mac_inst->crnti,
gNB_id, frame, ENB_FLAG_NO, MBMS_FLAG_NO, DCCH, 6, //not used
(char *) &ulsch_buff[0]
#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
,0,0
#endif
);
if(sdu_lengths > 0)
LOG_D(MAC, "[UE %d] TX Got %d bytes for DCCH\n", mod_id, sdu_lengths);
else
LOG_E(MAC, "[UE %d] TX DCCH error\n", mod_id );
update_bsr(mod_id, frame, nr_tti_tx, gNB_id);
nr_UE_mac_inst->scheduling_info.BSR[nr_UE_mac_inst->
scheduling_info.LCGID[DCCH]] = locate_BsrIndexByBufferSize(BSR_TABLE, BSR_TABLE_SIZE,
nr_UE_mac_inst
[mod_id].scheduling_info.BSR_bytes
[nr_UE_mac_inst
[mod_id].scheduling_info.LCGID
[DCCH]]);
//TBR: fill BSR infos in UL TBS
//header_len +=2;
nr_UE_mac_inst->RA_active = 1;
nr_UE_mac_inst->RA_PREAMBLE_TRANSMISSION_COUNTER =
1;
nr_UE_mac_inst->RA_Msg3_size =
size_sdu + dcch_header_len;
nr_UE_mac_inst->RA_prachMaskIndex = 0;
prach_resources->Msg3 =
ulsch_buff;
nr_UE_mac_inst->RA_backoff_cnt = 0; // add the backoff condition here if we have it from a previous RA reponse which failed (i.e. backoff indicator)
AssertFatal(nr_rach_ConfigCommon != NULL,
"[UE %d] FATAL Frame %d: nr_rach_ConfigCommon is NULL !!!\n",
mod_id, frame);
nr_UE_mac_inst->RA_window_cnt =
2 +
nr_rach_ConfigCommon->ra_SupervisionInfo.
ra_ResponseWindowSize;
if (nr_UE_mac_inst->RA_window_cnt == 9) {
nr_UE_mac_inst->RA_window_cnt = 10; // Note: 9 subframe window doesn't exist, after 8 is 10!
offset = nr_generate_ulsch_pdu((uint8_t *) mac_sdus, // sdus buffer
(uint8_t *) payload, // logical channel payload
num_sdus, // num sdus
sdu_lengths, // sdu length
sdu_lcids, // sdu lcid
0, // power headroom
0, // crnti
0, // truncated bsr
0, // short bsr
0, // long_bsr
1); // post_padding
// Padding: fill remainder of DLSCH with 0
if (post_padding > 0){
for (int j = 0; j < (TBS_bytes - offset); j++)
payload[offset + j] = 0; // mac_pdu[offset + j] = 0;
}
nr_UE_mac_inst->RA_tx_frame = frame;
nr_UE_mac_inst->RA_tx_subframe = nr_tti_tx;
nr_UE_mac_inst->RA_backoff_frame = frame;
nr_UE_mac_inst->RA_backoff_subframe = nr_tti_tx;
// Fill in preamble and PRACH resource
nr_get_prach_resources(mod_id, CC_id, gNB_id,
nr_tti_tx, 1, NULL);
generate_ulsch_header((uint8_t *) ulsch_buff, // mac header
1, // num sdus
0, // short pading
&Size16, // sdu length
&lcid, // sdu lcid
NULL, // power headroom
&nr_UE_mac_inst->crnti, // crnti
NULL, // truncated bsr
NULL, // short bsr
NULL, // long_bsr
0); //post_padding
return (&nr_UE_mac_inst->RA_prach_resources);
}*/
return (prach_resources);
}
} else { // RACH is active
////////////////////////////////////////////////////////////////
/////* Random Access Response reception (5.1.4 TS 38.321) */////
////////////////////////////////////////////////////////////////
/// Handling ra_responseWindow, RA_PREAMBLE_TRANSMISSION_COUNTER
/// and RA_backoff_cnt
// Handling ra_responseWindow, RA_PREAMBLE_TRANSMISSION_COUNTER
// and RA_backoff_cnt
// todo:
// - handle beam failure recovery request
// - handle DL assignment on PDCCH for RA-RNTI
LOG_D(MAC, "[MAC][UE %d][RAPROC] frame %d, subframe %d: RA Active, window cnt %d (RA_tx_frame %d, RA_tx_subframe %d)\n",
mod_id, frame, nr_tti_tx, nr_UE_mac_inst->RA_window_cnt, nr_UE_mac_inst->RA_tx_frame, nr_UE_mac_inst->RA_tx_subframe);
// - TBR check
if (nr_UE_mac_inst->rnti_type = NR_RNTI_RA){ // add condition on BI
// TBR todo
} else {
prach_resources->RA_PREAMBLE_BACKOFF = 0;
}
// compute backoff parameters
if (nr_UE_mac_inst->RA_backoff_cnt > 0){
frame_diff = (sframe_t) frame - nr_UE_mac_inst->RA_backoff_frame;
......
......@@ -114,7 +114,7 @@ void ue_dci_configuration(NR_UE_MAC_INST_t *mac,fapi_nr_dl_config_request_t *dl_
if (mac->ra_state == WAIT_RAR) {
// check for RAR
rel15 = &dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15;
rel15->rnti = 2;//get_RA_RNTI(mac,frame,slot);
rel15->rnti = 2;//get_RA_RNTI(mac,frame,slot); // TBR
dl_config->number_pdus = dl_config->number_pdus + 1;
}
else if (mac->ra_state == WAIT_CONTENTION_RESOLUTION) {
......
......@@ -2753,6 +2753,8 @@ void nr_extract_dci_info(NR_UE_MAC_INST_t *mac,
#endif
break;
mac->rnti_type = rnti_type;
case NR_RNTI_C:
// indicating a DL DCI format 1bit
......@@ -3280,3 +3282,169 @@ void nr_ue_process_mac_pdu(module_id_t module_idP,
AssertFatal(pdu_len >= 0, "[MAC] nr_ue_process_mac_pdu, residual mac pdu length < 0!\n");
}
}
////////////////////////////////////////////////////////
/////* ULSCH MAC PDU generation (6.1.2 TS 38.321) */////
////////////////////////////////////////////////////////
unsigned char nr_generate_ulsch_pdu(uint8_t *sdus_payload,
uint8_t *pdu,
uint8_t num_sdus,
uint16_t *sdu_lengths,
uint8_t *sdu_lcids,
uint8_t power_headroom,
uint16_t crnti,
uint16_t truncated_bsr,
uint16_t short_bsr,
uint16_t long_bsr,
unsigned short post_padding) {
NR_MAC_SUBHEADER_FIXED *mac_pdu_ptr = (NR_MAC_SUBHEADER_FIXED *) pdu;
unsigned char first_element = 0, last_size = 0, i, mac_header_control_elements[16], *ce_ptr, bsr = 0;
int mac_ce_size, offset;
LOG_D(MAC, "[UE] Generating ULSCH PDU : num_sdus %d\n", num_sdus);
#ifdef DEBUG_HEADER_PARSING
for (i = 0; i < num_sdus; i++)
LOG_D(MAC, "[UE] MAC subPDU %d (lcid %d length %d bytes \n", i, sdu_lcids[i], sdu_lengths[i]);
#endif
// Generating UL MAC subPDUs including MAC SDU and subheader
for (i = 0; i < num_sdus; i++) {
LOG_D(MAC, "[UE] Generating UL MAC subPDUs for SDU with lenght %d ( num_sdus %d )\n", sdu_lengths[i], num_sdus);
if (sdu_lcids[i] != UL_SCH_LCID_CCCH){
if (sdu_lengths[i] < 128) {
((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->R = 0;
((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->F = 0;
((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->LCID = sdu_lcids[i];
((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->L = (unsigned char) sdu_lengths[i];
last_size = 2;
} else {
((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->R = 0;
((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->F = 1;
((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->LCID = sdu_lcids[i];
((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->L1 = ((unsigned short) sdu_lengths[i] >> 8) & 0x7f;
((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->L2 = (unsigned short) sdu_lengths[i] & 0xff;
last_size = 3;
}
} else { // UL CCCH SDU
mac_pdu_ptr->R = 0;
mac_pdu_ptr->LCID = sdu_lcids[i];
}
mac_pdu_ptr += last_size;
// cycle through SDUs, compute each relevant and place ulsch_buffer in
memcpy((void *) mac_pdu_ptr, (void *) sdus_payload, sdu_lengths[i]);
sdus_payload += sdu_lengths[i];
mac_pdu_ptr += sdu_lengths[i];
}
// Generating UL MAC subPDUs including MAC CEs (MAC CE and subheader)
ce_ptr = &mac_header_control_elements[0];
if (power_headroom) {
// MAC CE fixed subheader
mac_pdu_ptr->R = 0;
mac_pdu_ptr->LCID = UL_SCH_LCID_SINGLE_ENTRY_PHR;
mac_pdu_ptr++;
// PHR MAC CE (1 octet)
((NR_SINGLE_ENTRY_PHR_MAC_CE *) ce_ptr)->PH = power_headroom;
((NR_SINGLE_ENTRY_PHR_MAC_CE *) ce_ptr)->R1 = 0;
((NR_SINGLE_ENTRY_PHR_MAC_CE *) ce_ptr)->PCMAX = 0; // todo
((NR_SINGLE_ENTRY_PHR_MAC_CE *) ce_ptr)->R2 = 0;
mac_ce_size = sizeof(NR_SINGLE_ENTRY_PHR_MAC_CE);
// Copying bytes for PHR MAC CEs to the mac pdu pointer
memcpy((void *) mac_pdu_ptr, (void *) ce_ptr, mac_ce_size);
ce_ptr += mac_ce_size;
mac_pdu_ptr += (unsigned char) mac_ce_size;
}
if (crnti) {
// MAC CE fixed subheader
mac_pdu_ptr->R = 0;
mac_pdu_ptr->LCID = CRNTI;
mac_pdu_ptr++;
// C-RNTI MAC CE (2 octets)
* (uint16_t *) ce_ptr = crnti;
mac_ce_size = sizeof(uint16_t);
// Copying bytes for CRNTI MAC CE to the mac pdu pointer
memcpy((void *) mac_pdu_ptr, (void *) ce_ptr, mac_ce_size);
ce_ptr += mac_ce_size;
mac_pdu_ptr += (unsigned char) mac_ce_size;
}
if (truncated_bsr) {
// MAC CE fixed subheader
mac_pdu_ptr->R = 0;
mac_pdu_ptr->LCID = UL_SCH_LCID_S_TRUNCATED_BSR;
mac_pdu_ptr++;
// Short truncated BSR MAC CE (1 octet)
((NR_BSR_SHORT_TRUNCATED *) ce_ptr)-> Buffer_size = truncated_bsr;
((NR_BSR_SHORT_TRUNCATED *) ce_ptr)-> LcgID = 0; // todo
mac_ce_size = sizeof(NR_BSR_SHORT_TRUNCATED);
bsr = 1 ;
} else if (short_bsr) {
// MAC CE fixed subheader
mac_pdu_ptr->R = 0;
mac_pdu_ptr->LCID = UL_SCH_LCID_S_BSR;
mac_pdu_ptr++;
// Short truncated BSR MAC CE (1 octet)
((NR_BSR_SHORT *) ce_ptr)->Buffer_size = short_bsr;
((NR_BSR_SHORT *) ce_ptr)->LcgID = 0; // todo
mac_ce_size = sizeof(NR_BSR_SHORT);
bsr = 1 ;
} else if (long_bsr) {
// MAC CE variable subheader
// todo ch 6.1.3.1. TS 38.321
// ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->R = 0;
// ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->F = 0;
// ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->LCID = UL_SCH_LCID_L_BSR;
// ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->L = 0;
// last_size = 2;
// mac_pdu_ptr += last_size;
// Short truncated BSR MAC CE (1 octet)
// ((NR_BSR_LONG *) ce_ptr)->Buffer_size0 = short_bsr;
// ((NR_BSR_LONG *) ce_ptr)->LCGID0 = 0;
// mac_ce_size = sizeof(NR_BSR_LONG); // size is variable
}
if (bsr){
// Copying bytes for BSR MAC CE to the mac pdu pointer
memcpy((void *) mac_pdu_ptr, (void *) ce_ptr, mac_ce_size);
ce_ptr += mac_ce_size;
mac_pdu_ptr += (unsigned char) mac_ce_size;
}
// Compute final offset for padding
if (post_padding > 0) {
((NR_MAC_SUBHEADER_FIXED *) mac_pdu_ptr)->R = 0;
((NR_MAC_SUBHEADER_FIXED *) mac_pdu_ptr)->LCID = UL_SCH_LCID_PADDING;
mac_pdu_ptr++;
} else {
// no MAC subPDU with padding
}
// compute final offset
offset = ((unsigned char *) mac_pdu_ptr - pdu);
//printf("Offset %d \n", ((unsigned char *) mac_pdu_ptr - mac_pdu));
return offset;
}
\ No newline at end of file
......@@ -57,3 +57,14 @@ nr_mac_rrc_data_ind_ue(
return(0);
}
int8_t mac_rrc_nr_data_req_ue(const module_id_t Mod_idP,
const int CC_id,
const frame_t frameP,
const rb_id_t Srb_id,
uint8_t *const buffer_pP ){
// todo
return 0;
}
\ No newline at end of file
......@@ -102,6 +102,18 @@ int8_t nr_rrc_ue_decode_NR_DL_DCCH_Message(const module_id_t module_id, const ui
\param pdu_len data length of pdu*/
int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, const int CC_id, const uint8_t gNB_index, const channel_t channel, const uint8_t* pduP, const sdu_size_t pdu_len);
/**\brief
\param module_id module id
\param CC_id component carrier id
\param frame_t frameP
\param rb_id_t SRB id
\param buffer_pP pointer to buffer*/
int8_t mac_rrc_nr_data_req_ue(const module_id_t Mod_idP,
const int CC_id,
const frame_t frameP,
const rb_id_t Srb_id,
uint8_t *const buffer_pP);
/** @}*/
#endif
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