From 796c2a61a3546129624b7ef8aa2c0189c928a67b Mon Sep 17 00:00:00 2001 From: francescomani Date: Thu, 17 Oct 2024 10:14:44 +0200 Subject: [PATCH] improvements in RA init procedures according to 5.1.1 in 38.321 --- openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c | 19 +- openair2/LAYER2/NR_MAC_UE/config_ue.c | 4 +- openair2/LAYER2/NR_MAC_UE/mac_defs.h | 23 +- openair2/LAYER2/NR_MAC_UE/mac_proto.h | 5 + openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c | 349 ++++++++++-------- .../LAYER2/NR_MAC_UE/nr_ue_power_procedures.c | 13 +- openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c | 5 +- .../tests/test_nr_ue_ra_procedures.cpp | 44 ++- 8 files changed, 257 insertions(+), 205 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c index f3693e2791..29c5e2bfa1 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c @@ -571,34 +571,33 @@ NR_tda_info_t get_dl_tda_info(const NR_UE_DL_BWP_t *dl_BWP, return tda_info; } -uint16_t get_NCS(uint8_t index, uint16_t format0, uint8_t restricted_set_config) { - - LOG_D(MAC,"get_NCS: indx %d,format0 %d, restriced_set_config %d\n", - index,format0,restricted_set_config); +uint16_t get_NCS(uint8_t index, uint16_t format0, uint8_t restricted_set_config) +{ + LOG_D(NR_MAC, "get_NCS: indx %d,format0 %d, restriced_set_config %d\n", index, format0, restricted_set_config); if (format0 < 3) { - switch(restricted_set_config){ + switch (restricted_set_config) { case 0: return(NCS_unrestricted_delta_f_RA_125[index]); case 1: return(NCS_restricted_TypeA_delta_f_RA_125[index]); case 2: return(NCS_restricted_TypeB_delta_f_RA_125[index]); - default: - AssertFatal(1==0,"Invalid restricted set config value %d",restricted_set_config); + default: + AssertFatal(false, "Invalid restricted set config value %d", restricted_set_config); } } else { if (format0 == 3) { - switch(restricted_set_config){ + switch (restricted_set_config) { case 0: return(NCS_unrestricted_delta_f_RA_5[index]); case 1: return(NCS_restricted_TypeA_delta_f_RA_5[index]); case 2: return(NCS_restricted_TypeB_delta_f_RA_5[index]); - default: - AssertFatal(1==0,"Invalid restricted set config value %d",restricted_set_config); + default: + AssertFatal(false, "Invalid restricted set config value %d", restricted_set_config); } } else diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index 09d0eb2928..552f0676f6 100644 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -1399,7 +1399,7 @@ static void setup_srsconfig(NR_UE_UL_BWP_t *bwp, NR_SRS_Config_t *source, NR_SRS } } -static NR_UE_DL_BWP_t *get_dl_bwp_structure(NR_UE_MAC_INST_t *mac, int bwp_id, bool setup) +NR_UE_DL_BWP_t *get_dl_bwp_structure(NR_UE_MAC_INST_t *mac, int bwp_id, bool setup) { NR_UE_DL_BWP_t *bwp = NULL; for (int i = 0; i < mac->dl_BWPs.count; i++) { @@ -1423,7 +1423,7 @@ static NR_UE_DL_BWP_t *get_dl_bwp_structure(NR_UE_MAC_INST_t *mac, int bwp_id, b return bwp; } -static NR_UE_UL_BWP_t *get_ul_bwp_structure(NR_UE_MAC_INST_t *mac, int bwp_id, bool setup) +NR_UE_UL_BWP_t *get_ul_bwp_structure(NR_UE_MAC_INST_t *mac, int bwp_id, bool setup) { NR_UE_UL_BWP_t *bwp = NULL; for (int i = 0; i < mac->ul_BWPs.count; i++) { diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index fbd96532f9..d80a279952 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -275,25 +275,21 @@ typedef struct { /// PRACH format retrieved from prach_ConfigIndex uint16_t prach_format; /// Preamble Tx Counter - uint8_t RA_PREAMBLE_TRANSMISSION_COUNTER; + uint8_t preamble_tx_counter; /// Preamble Power Ramping Counter - uint8_t RA_PREAMBLE_POWER_RAMPING_COUNTER; + uint8_t preamble_power_ramping_cnt; /// 2-step RA power offset - int POWER_OFFSET_2STEP_RA; + int power_offset_2step; /// Target received power at gNB. Baseline is range -202..-60 dBm. Depends on delta preamble, power ramping counter and step. int ra_PREAMBLE_RECEIVED_TARGET_POWER; /// PRACH index for TDD (0 ... 6) depending on TDD configuration and prachConfigIndex uint8_t ra_TDD_map_index; /// RA Preamble Power Ramping Step in dB - uint32_t RA_PREAMBLE_POWER_RAMPING_STEP; - /// - uint8_t RA_PREAMBLE_BACKOFF; - /// - uint8_t RA_SCALING_FACTOR_BI; - /// Indicating whether it is 2-step or 4-step RA - nr_ra_type_t RA_TYPE; + uint32_t preamble_power_ramping_step; + uint8_t preamble_backoff; + uint8_t scaling_factor_bi; /// UE configured maximum output power - int RA_PCMAX; + int Pc_max; } NR_PRACH_RESOURCES_t; typedef struct { @@ -303,7 +299,7 @@ typedef struct { /// state of RA procedure nrRA_UE_state_t ra_state; /// RA contention type - uint8_t cfra; + bool cfra; /// RA type nr_ra_type_t ra_type; /// RA rx frame offset: compensate RA rx offset introduced by OAI gNB. @@ -329,7 +325,8 @@ typedef struct { int ra_PreambleIndex; // When multiple SSBs per RO is configured, this indicates which one is selected in this RO -> this is used to properly compute the PRACH preamble uint8_t ssb_nb_in_ro; - + int zeroCorrelationZoneConfig; + int restricted_set_config; /// Random-access window counter int16_t RA_window_cnt; /// Flag to monitor if matching RAPID was received in RAR diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index 3f3ae2a141..22f0cbaf84 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -45,6 +45,9 @@ \param mac MAC pointer */ void nr_ue_init_mac(NR_UE_MAC_INST_t *mac); +NR_UE_DL_BWP_t *get_dl_bwp_structure(NR_UE_MAC_INST_t *mac, int bwp_id, bool setup); +NR_UE_UL_BWP_t *get_ul_bwp_structure(NR_UE_MAC_INST_t *mac, int bwp_id, bool setup); + void send_srb0_rrc(int ue_id, const uint8_t *sdu, sdu_size_t sdu_len, void *data); void update_mac_timers(NR_UE_MAC_INST_t *mac); NR_LC_SCHEDULING_INFO *get_scheduling_info_from_lcid(NR_UE_MAC_INST_t *mac, NR_LogicalChannelIdentity_t lcid); @@ -274,6 +277,8 @@ void ul_ports_config(NR_UE_MAC_INST_t *mac, dci_pdu_rel15_t *dci, nr_dci_format_t dci_format); +bool init_RA(NR_UE_MAC_INST_t *mac, int frame); + /* Random Access */ /* \brief This function schedules the PRACH according to prach_ConfigurationIndex and TS 38.211 tables 6.3.3.2.x and fills the PRACH PDU per each FD occasion. diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c index ada5c9e0ba..b16def686f 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c @@ -46,18 +46,55 @@ int16_t get_prach_tx_power(NR_UE_MAC_INST_t *mac) RA_config_t *ra = &mac->ra; int16_t pathloss = compute_nr_SSB_PL(mac, mac->ssb_measurements.ssb_rsrp_dBm); int16_t ra_preamble_rx_power = (int16_t)(ra->prach_resources.ra_PREAMBLE_RECEIVED_TARGET_POWER + pathloss); - return min(ra->prach_resources.RA_PCMAX, ra_preamble_rx_power); + return min(ra->prach_resources.Pc_max, ra_preamble_rx_power); +} + +static void set_preambleTransMax(RA_config_t *ra, long preambleTransMax) +{ + switch (preambleTransMax) { + case 0: + ra->preambleTransMax = 3; + break; + case 1: + ra->preambleTransMax = 4; + break; + case 2: + ra->preambleTransMax = 5; + break; + case 3: + ra->preambleTransMax = 6; + break; + case 4: + ra->preambleTransMax = 7; + break; + case 5: + ra->preambleTransMax = 8; + break; + case 6: + ra->preambleTransMax = 10; + break; + case 7: + ra->preambleTransMax = 20; + break; + case 8: + ra->preambleTransMax = 50; + break; + case 9: + ra->preambleTransMax = 100; + break; + case 10: + ra->preambleTransMax = 200; + break; + default: + AssertFatal(false, "Invalid preambleTransMax\n"); + } } // Random Access procedure initialization as per 5.1.1 and initialization of variables specific // to Random Access type as specified in clause 5.1.1a (3GPP TS 38.321 version 16.2.1 Release 16) // todo: // - check if carrier to use is explicitly signalled then do (1) RA CARRIER SELECTION (SUL, NUL) (2) set PCMAX (currently hardcoded to 0) -static bool init_RA(NR_UE_MAC_INST_t *mac, - int frame, - NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon, - NR_RACH_ConfigGeneric_t *rach_ConfigGeneric, - NR_RACH_ConfigDedicated_t *rach_ConfigDedicated) +bool init_RA(NR_UE_MAC_INST_t *mac, int frame) { RA_config_t *ra = &mac->ra; // Delay init RA procedure to allow the convergence of the IIR filter on PRACH noise measurements at gNB side @@ -111,23 +148,50 @@ static bool init_RA(NR_UE_MAC_INST_t *mac, ra->Msg3_size = size_sdu; } + // Random acces procedure initialization mac->state = UE_PERFORMING_RA; ra->RA_active = true; - ra->ra_PreambleIndex = -1; - ra->RA_usedGroupA = 1; - ra->RA_RAPID_found = 0; - ra->preambleTransMax = 0; - ra->first_Msg3 = true; - ra->starting_preamble_nb = 0; - ra->RA_backoff_cnt = 0; - ra->RA_window_cnt = -1; - - fapi_nr_config_request_t *cfg = &mac->phy_config.config_req; NR_PRACH_RESOURCES_t *prach_resources = &ra->prach_resources; - prach_resources->RA_PREAMBLE_BACKOFF = 0; + fapi_nr_config_request_t *cfg = &mac->phy_config.config_req; + // flush MSG3 buffer + free_and_zero(ra->Msg3_buffer); + // set the PREAMBLE_TRANSMISSION_COUNTER to 1 + prach_resources->preamble_tx_counter = 1; + // set the PREAMBLE_POWER_RAMPING_COUNTER to 1 + prach_resources->preamble_power_ramping_cnt = 1; + // set the PREAMBLE_BACKOFF to 0 ms TODO to be set as a timer? + prach_resources->preamble_backoff = 0; + // set POWER_OFFSET_2STEP_RA to 0 dB + prach_resources->power_offset_2step = 0; + + const NR_UE_UL_BWP_t *current_UL_BWP = mac->current_UL_BWP; + // perform the BWP operation as specified in clause 5.15 + // if PRACH occasions are not configured for the active UL BWP + if (!current_UL_BWP->rach_ConfigCommon) { + // switch the active UL BWP to BWP indicated by initialUplinkBWP + current_UL_BWP = get_ul_bwp_structure(mac, 0, false); + // if the Serving Cell is an SpCell + // switch the active DL BWP to BWP indicated by initialDownlinkBWP + mac->current_DL_BWP = get_dl_bwp_structure(mac, 0, false); + } else { + // if the active DL BWP does not have the same bwp-Id as the active UL BWP + if (current_UL_BWP->bwp_id != mac->current_DL_BWP->bwp_id) { + // switch the active DL BWP to the DL BWP with the same bwp-Id as the active UL BWP + mac->current_DL_BWP = get_dl_bwp_structure(mac, 0, false); + } + } + + NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = current_UL_BWP->rach_ConfigCommon; + AssertFatal(nr_rach_ConfigCommon, "rach-ConfigCommon should be configured here\n"); + // stop the bwp-InactivityTimer associated with the active DL BWP of this Serving Cell, if running + // TODO bwp-InactivityTimer not implemented + + // if the carrier to use for the Random Access procedure is explicitly signalled (always the case for us) + // PRACH shall be as specified for QPSK modulated DFT-s-OFDM of equivalent RB allocation (38.101-1) NR_SubcarrierSpacing_t prach_scs; int scs_for_pcmax; // for long prach the UL BWP SCS is used for calculating RA_PCMAX - if (nr_rach_ConfigCommon && nr_rach_ConfigCommon->msg1_SubcarrierSpacing) { + NR_RACH_ConfigGeneric_t *rach_ConfigGeneric = &nr_rach_ConfigCommon->rach_ConfigGeneric; + if (nr_rach_ConfigCommon->msg1_SubcarrierSpacing) { prach_scs = *nr_rach_ConfigCommon->msg1_SubcarrierSpacing; scs_for_pcmax = prach_scs; } else { @@ -137,136 +201,111 @@ static bool init_RA(NR_UE_MAC_INST_t *mac, prach_scs = get_delta_f_RA_long(format); scs_for_pcmax = mac->current_UL_BWP->scs; } - int n_prbs = get_N_RA_RB(prach_scs, mac->current_UL_BWP->scs); - int start_prb = rach_ConfigGeneric->msg1_FrequencyStart + mac->current_UL_BWP->BWPStart; - // PRACH shall be as specified for QPSK modulated DFT-s-OFDM of equivalent RB allocation (38.101-1) - prach_resources->RA_PCMAX = nr_get_Pcmax(mac->p_Max, - mac->nr_band, - mac->frame_structure.frame_type, - mac->frequency_range, - mac->current_UL_BWP->channel_bandwidth, - 2, - false, - scs_for_pcmax, - cfg->carrier_config.dl_grid_size[scs_for_pcmax], - true, - n_prbs, - start_prb); - prach_resources->RA_PREAMBLE_TRANSMISSION_COUNTER = 1; - prach_resources->RA_PREAMBLE_POWER_RAMPING_COUNTER = 1; - prach_resources->POWER_OFFSET_2STEP_RA = 0; - prach_resources->RA_SCALING_FACTOR_BI = 1; + int n_prbs = get_N_RA_RB(prach_scs, current_UL_BWP->scs); + int start_prb = rach_ConfigGeneric->msg1_FrequencyStart + current_UL_BWP->BWPStart; + prach_resources->Pc_max = nr_get_Pcmax(mac->p_Max, + mac->nr_band, + mac->frame_structure.frame_type, + mac->frequency_range, + current_UL_BWP->channel_bandwidth, + 2, + false, + scs_for_pcmax, + cfg->carrier_config.dl_grid_size[scs_for_pcmax], + true, + n_prbs, + start_prb); + // TODO if the Random Access procedure is initiated by PDCCH order + // and if the ra-PreambleIndex explicitly provided by PDCCH is not 0b000000 - // Contention Free - if (rach_ConfigDedicated) { - if (rach_ConfigDedicated->cfra){ - LOG_I(MAC, "Initialization of 4-Step CFRA procedure\n"); - prach_resources->RA_TYPE = RA_4_STEP; - ra->ra_type = RA_4_STEP; - ra->cfra = 1; - } else if (rach_ConfigDedicated->ext1){ - if (rach_ConfigDedicated->ext1->cfra_TwoStep_r16) { - LOG_I(MAC, "Initialization of 2-Step CFRA procedure\n"); - prach_resources->RA_TYPE = RA_2_STEP; - ra->ra_type = RA_2_STEP; - ra->cfra = 1; - } else { - LOG_E(NR_MAC, "Config not handled\n"); - } - } else { - LOG_E(NR_MAC, "Config not handled\n"); - } - // Contention Based - } else if (mac->current_UL_BWP->msgA_ConfigCommon_r16) { - LOG_I(MAC, "Initialization of 2-Step CBRA procedure\n"); - prach_resources->RA_TYPE = RA_2_STEP; - ra->ra_type = RA_2_STEP; - ra->cfra = 0; - } else if (nr_rach_ConfigCommon) { - LOG_I(MAC, "Initialization of 4-Step CBRA procedure\n"); - prach_resources->RA_TYPE = RA_4_STEP; + // TODO if the Random Access procedure was initiated for SI request + // and the Random Access Resources for SI request have been explicitly provided by RRC + + // TODO if the Random Access procedure was initiated for SpCell beam failure recovery + // and if the contention-free Random Access Resources for beam failure recovery request for 4-step RA type + // have been explicitly provided by RRC for the BWP selected for Random Access procedure + + NR_RACH_ConfigCommonTwoStepRA_r16_t *twostep_conf = NULL; + NR_RACH_ConfigDedicated_t *rach_Dedicated = ra->rach_ConfigDedicated; + if (rach_Dedicated && rach_Dedicated->cfra) { + // if the Random Access procedure was initiated for reconfiguration with sync and + // if the contention-free Random Access Resources for 4-step RA type have been explicitly provided + // in rach-ConfigDedicated for the BWP selected for Random Access procedure + LOG_I(MAC, "Initialization of 4-Step CFRA procedure\n"); ra->ra_type = RA_4_STEP; - ra->cfra = 0; + ra->cfra = true; } else { - LOG_E(MAC, "Config not handled\n"); - AssertFatal(false, "In %s: config not handled\n", __FUNCTION__); - } - - switch (rach_ConfigGeneric->powerRampingStep){ // in dB - case 0: - prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP = 0; - break; - case 1: - prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP = 2; - break; - case 2: - prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP = 4; - break; - case 3: - prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP = 6; - break; - } - - switch (rach_ConfigGeneric->preambleTransMax) { - case 0: - ra->preambleTransMax = 3; - break; - case 1: - ra->preambleTransMax = 4; - break; - case 2: - ra->preambleTransMax = 5; - break; - case 3: - ra->preambleTransMax = 6; - break; - case 4: - ra->preambleTransMax = 7; - break; - case 5: - ra->preambleTransMax = 8; - break; - case 6: - ra->preambleTransMax = 10; - break; - case 7: - ra->preambleTransMax = 20; - break; - case 8: - ra->preambleTransMax = 50; - break; - case 9: - ra->preambleTransMax = 100; - break; - case 10: - ra->preambleTransMax = 200; - break; - } - - if (ra->ra_type == RA_2_STEP) { - if (nr_rach_ConfigCommon->ext1 && nr_rach_ConfigCommon->ext1->ra_PrioritizationForAccessIdentity_r16) { - LOG_D(MAC, "Missing implementation for Access Identity initialization procedures\n"); - } - // Perform initialization of variables specific to Random Access type as specified in clause 5.1.1a of TS 38.321 - NR_RACH_ConfigGenericTwoStepRA_r16_t nr_ra_ConfigGenericTwoStepRA_r16 = - mac->current_UL_BWP->msgA_ConfigCommon_r16->rach_ConfigCommonTwoStepRA_r16.rach_ConfigGenericTwoStepRA_r16; - // Takes the value of 2-Step RA variable - if (nr_ra_ConfigGenericTwoStepRA_r16.msgA_PreamblePowerRampingStep_r16) { - prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP = *nr_ra_ConfigGenericTwoStepRA_r16.msgA_PreamblePowerRampingStep_r16; + bool twostep_cfra = (rach_Dedicated && rach_Dedicated->ext1) ? (rach_Dedicated->ext1->cfra_TwoStep_r16 ? true : false) : false; + if (twostep_cfra) { + // if the Random Access procedure was initiated for reconfiguration with sync and + // if the contention-free Random Access Resources for 2-step RA type have been explicitly provided in rach-ConfigDedicated + LOG_I(MAC, "Initialization of 2-Step CFRA procedure\n"); + ra->ra_type = RA_2_STEP; + ra->cfra = true; } else { - // If 2-Step variable does not exist, it takes the value of 4-Step RA variable - prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP = nr_rach_ConfigCommon->rach_ConfigGeneric.powerRampingStep; - } - prach_resources->RA_SCALING_FACTOR_BI = 1; - // Takes the value of 2-Step RA variable - if (nr_ra_ConfigGenericTwoStepRA_r16.preambleTransMax_r16) { - ra->preambleTransMax = (int)*nr_ra_ConfigGenericTwoStepRA_r16.preambleTransMax_r16; - } else { - // If 2-Step variable does not exist, it takes the value of 4-Step RA variable - ra->preambleTransMax = (int)nr_rach_ConfigCommon->rach_ConfigGeneric.preambleTransMax; + bool twostep = false; + if (current_UL_BWP->msgA_ConfigCommon_r16) { + twostep_conf = ¤t_UL_BWP->msgA_ConfigCommon_r16->rach_ConfigCommonTwoStepRA_r16; + if (nr_rach_ConfigCommon) { + // if the BWP selected for Random Access procedure is configured with both 2- and 4-step RA type Random Access Resources + // and the RSRP of the downlink pathloss reference is above msgA-RSRP-Threshold + AssertFatal(twostep_conf->msgA_RSRP_Threshold_r16, + "msgA_RSRP_Threshold_r16 is mandatory present if both 2-step and 4-step random access types are configured\n"); + // For thresholds the RSRP value is (IE value – 156) dBm except for the IE 127 in which case the actual value is infinity + int rsrp_msga_thr = *twostep_conf->msgA_RSRP_Threshold_r16 - 156; + if (*twostep_conf->msgA_RSRP_Threshold_r16 != 127 && mac->ssb_measurements.ssb_rsrp_dBm > rsrp_msga_thr) + twostep = true; + } else { + // if the BWP selected for Random Access procedure is only configured with 2-step RA type Random Access + twostep = true; + } + } + if (twostep) { + LOG_I(MAC, "Initialization of 2-Step CBRA procedure\n"); + ra->ra_type = RA_2_STEP; + ra->cfra = false; + } else { + LOG_I(MAC, "Initialization of 4-Step CBRA procedure\n"); + ra->ra_type = RA_4_STEP; + ra->cfra = false; + } } } + + NR_RACH_ConfigGenericTwoStepRA_r16_t *twostep_generic = twostep_conf ? &twostep_conf->rach_ConfigGenericTwoStepRA_r16 : NULL; + if (ra->ra_type == RA_2_STEP && twostep_generic && twostep_generic->msgA_PreamblePowerRampingStep_r16) + prach_resources->preamble_power_ramping_step = *twostep_generic->msgA_PreamblePowerRampingStep_r16 << 1; + else + prach_resources->preamble_power_ramping_step = rach_ConfigGeneric->powerRampingStep << 1; + + prach_resources->scaling_factor_bi = 1; + + if (ra->ra_type == RA_2_STEP && twostep_generic && twostep_generic->preambleTransMax_r16) + set_preambleTransMax(ra, *twostep_generic->preambleTransMax_r16); + else + set_preambleTransMax(ra, rach_ConfigGeneric->preambleTransMax); + + if (ra->ra_type == RA_2_STEP && twostep_generic && twostep_generic->msgA_ZeroCorrelationZoneConfig_r16) + ra->zeroCorrelationZoneConfig = *twostep_generic->msgA_ZeroCorrelationZoneConfig_r16; + else + ra->zeroCorrelationZoneConfig = rach_ConfigGeneric->zeroCorrelationZoneConfig; + if (ra->ra_type == RA_2_STEP && twostep_conf && twostep_conf->msgA_RestrictedSetConfig_r16) + ra->restricted_set_config = *twostep_conf->msgA_RestrictedSetConfig_r16; + else + ra->restricted_set_config = nr_rach_ConfigCommon->restrictedSetConfig; + + // TODO msgA-TransMax not implemented + // TODO ra-Prioritization not implemented + + ra->ra_PreambleIndex = -1; + ra->RA_usedGroupA = 1; + ra->RA_RAPID_found = 0; + ra->first_Msg3 = true; + ra->starting_preamble_nb = 0; + ra->RA_backoff_cnt = 0; + ra->RA_window_cnt = -1; + return true; } @@ -359,8 +398,8 @@ static int nr_get_Po_NOMINAL_PUSCH(NR_UE_MAC_INST_t *mac, NR_PRACH_RESOURCES_t * receivedTargerPower = preambleReceivedTargetPower + delta_preamble + - (prach_resources->RA_PREAMBLE_POWER_RAMPING_COUNTER - 1) * prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP + - prach_resources->POWER_OFFSET_2STEP_RA; + (prach_resources->preamble_power_ramping_cnt - 1) * prach_resources->preamble_power_ramping_step + + prach_resources->power_offset_2step; LOG_D(MAC, "ReceivedTargerPower is %d dBm \n", receivedTargerPower); return receivedTargerPower; @@ -545,7 +584,7 @@ void ra_preambles_config(NR_PRACH_RESOURCES_t *prach_resources, NR_UE_MAC_INST_t AssertFatal(1 == 0,"Unknown messagePowerOffsetGroupB %lu\n", setup->groupBconfigured->messagePowerOffsetGroupB); } - PLThreshold = prach_resources->RA_PCMAX - rach_ConfigGeneric->preambleReceivedTargetPower - deltaPreamble_Msg3 - messagePowerOffsetGroupB; + PLThreshold = prach_resources->Pc_max - rach_ConfigGeneric->preambleReceivedTargetPower - deltaPreamble_Msg3 - messagePowerOffsetGroupB; } @@ -629,8 +668,8 @@ void nr_get_prach_resources(NR_UE_MAC_INST_t *mac, LOG_D(MAC, "[RAPROC] - Selected RA preamble index %d for contention-based random access procedure... \n", ra->ra_PreambleIndex); } - if (prach_resources->RA_PREAMBLE_TRANSMISSION_COUNTER > 1) - prach_resources->RA_PREAMBLE_POWER_RAMPING_COUNTER++; + if (prach_resources->preamble_tx_counter > 1) + prach_resources->preamble_power_ramping_cnt++; prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER = nr_get_Po_NOMINAL_PUSCH(mac, prach_resources, CC_id); } @@ -748,10 +787,8 @@ void nr_ue_manage_ra_procedure(NR_UE_MAC_INST_t *mac, int CC_id, frame_t frame, RA_config_t *ra = &mac->ra; NR_RACH_ConfigDedicated_t *rach_ConfigDedicated = ra->rach_ConfigDedicated; NR_PRACH_RESOURCES_t *prach_resources = &ra->prach_resources; - NR_RACH_ConfigCommon_t *setup = mac->current_UL_BWP->rach_ConfigCommon; - NR_RACH_ConfigGeneric_t *rach_ConfigGeneric = &setup->rach_ConfigGeneric; if (ra->ra_state == nrRA_UE_IDLE) { - bool init_success = init_RA(mac, frame, setup, rach_ConfigGeneric, rach_ConfigDedicated); + bool init_success = init_RA(mac, frame); if (!init_success) return; } @@ -764,9 +801,9 @@ void nr_ue_manage_ra_procedure(NR_UE_MAC_INST_t *mac, int CC_id, frame_t frame, LOG_D(MAC, "[%d.%d] RA is active: RA window count %d, RA backoff count %d\n", frame, nr_slot_tx, ra->RA_window_cnt, ra->RA_backoff_cnt); if (ra->RA_BI_found){ - prach_resources->RA_PREAMBLE_BACKOFF = prach_resources->RA_SCALING_FACTOR_BI * ra->RA_backoff_indicator; + prach_resources->preamble_backoff = prach_resources->scaling_factor_bi * ra->RA_backoff_indicator; } else { - prach_resources->RA_PREAMBLE_BACKOFF = 0; + prach_resources->preamble_backoff = 0; } if (ra->RA_window_cnt >= 0 && ra->RA_RAPID_found == 1) { @@ -987,13 +1024,13 @@ void nr_ra_failed(NR_UE_MAC_INST_t *mac, uint8_t CC_id, NR_PRACH_RESOURCES_t *pr ra->ra_PreambleIndex = -1; ra->ra_state = nrRA_UE_IDLE; - prach_resources->RA_PREAMBLE_TRANSMISSION_COUNTER++; + prach_resources->preamble_tx_counter++; // when the Contention Resolution is considered not successful // stop timeAlignmentTimer nr_timer_stop(&mac->time_alignment_timer); - if (prach_resources->RA_PREAMBLE_TRANSMISSION_COUNTER == ra->preambleTransMax + 1) { + if (prach_resources->preamble_tx_counter == ra->preambleTransMax + 1) { LOG_D(NR_MAC, "[UE %d][%d.%d] Maximum number of RACH attempts (%d) reached, selecting backoff time...\n", @@ -1002,9 +1039,9 @@ void nr_ra_failed(NR_UE_MAC_INST_t *mac, uint8_t CC_id, NR_PRACH_RESOURCES_t *pr slot, ra->preambleTransMax); - ra->RA_backoff_cnt = rand_r(&seed) % (prach_resources->RA_PREAMBLE_BACKOFF + 1); - prach_resources->RA_PREAMBLE_TRANSMISSION_COUNTER = 1; - prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP += 2; // 2 dB increment + ra->RA_backoff_cnt = rand_r(&seed) % (prach_resources->preamble_backoff + 1); + prach_resources->preamble_tx_counter = 1; + prach_resources->preamble_power_ramping_step += 2; // 2 dB increment prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER = nr_get_Po_NOMINAL_PUSCH(mac, prach_resources, CC_id); } else { diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_power_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_power_procedures.c index 7083b4a141..0c024560d7 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_power_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_power_procedures.c @@ -372,8 +372,8 @@ int16_t get_pucch_tx_power_ue(NR_UE_MAC_INST_t *mac, if (mac->pucch_power_control_initialized == false) { // Initialize power control state // Assuming only sending on PCell - NR_PRACH_RESOURCES_t* prach_resources = &mac->ra.prach_resources; - float DELTA_P_rampup_requested = (prach_resources->RA_PREAMBLE_POWER_RAMPING_COUNTER - 1) * prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP; + NR_PRACH_RESOURCES_t *prach_res = &mac->ra.prach_resources; + float DELTA_P_rampup_requested = (prach_res->preamble_power_ramping_cnt - 1) * prach_res->preamble_power_ramping_step; float DELTA_P_rampup = P_CMAX - (P_O_PUCCH + pathloss + delta_F_PUCCH + DELTA_TF + sum_delta_pucch); DELTA_P_rampup = max(min(0, DELTA_P_rampup), DELTA_P_rampup_requested); mac->G_b_f_c = DELTA_P_rampup + sum_delta_pucch; @@ -572,8 +572,8 @@ int get_pusch_tx_power_ue(NR_UE_MAC_INST_t *mac, f_b_f_c = delta_pusch; } else { if (!mac->pusch_power_control_initialized && is_rar_tx_retx) { - NR_PRACH_RESOURCES_t* prach_resources = &mac->ra.prach_resources; - float DELTA_P_rampup_requested = (prach_resources->RA_PREAMBLE_POWER_RAMPING_COUNTER - 1) * prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP; + NR_PRACH_RESOURCES_t *prach_res = &mac->ra.prach_resources; + float DELTA_P_rampup_requested = (prach_res->preamble_power_ramping_cnt - 1) * prach_res->preamble_power_ramping_step; float DELTA_P_rampup = P_CMAX - (P_O_PUSCH + M_pusch_component + alpha * pathloss + DELTA_TF + delta_pusch); DELTA_P_rampup = min(DELTA_P_rampup_requested, max(0, DELTA_P_rampup)); mac->f_b_f_c = DELTA_P_rampup + delta_pusch; @@ -654,9 +654,8 @@ int get_srs_tx_power_ue(NR_UE_MAC_INST_t *mac, if (!is_tpc_accumulation_provided && (!is_configured_for_pusch_on_current_bwp || separate_pc_adjustment_state)) { if (!current_UL_BWP->srs_power_control_initialized) { - NR_PRACH_RESOURCES_t *prach_resources = &mac->ra.prach_resources; - float DELTA_P_rampup_requested = - (prach_resources->RA_PREAMBLE_POWER_RAMPING_COUNTER - 1) * prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP; + NR_PRACH_RESOURCES_t *prach = &mac->ra.prach_resources; + float DELTA_P_rampup_requested = (prach->preamble_power_ramping_cnt - 1) * prach->preamble_power_ramping_step; float DELTA_P_rampup = P_CMAX - (P_0_SRS + m_srs_component + alpha * pathloss); DELTA_P_rampup = min(DELTA_P_rampup_requested, max(0, DELTA_P_rampup)); current_UL_BWP->srs_power_control_initialized = true; diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index fc85583ad2..94f9c80277 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -2595,8 +2595,6 @@ static void nr_ue_prach_scheduler(NR_UE_MAC_INST_t *mac, frame_t frameP, slot_t fapi_nr_config_request_t *cfg = &mac->phy_config.config_req; fapi_nr_prach_config_t *prach_config = &cfg->prach_config; - NR_RACH_ConfigCommon_t *setup = mac->current_UL_BWP->rach_ConfigCommon; - NR_RACH_ConfigGeneric_t *rach_ConfigGeneric = &setup->rach_ConfigGeneric; const int bwp_id = mac->current_UL_BWP->bwp_id; if (is_ul_slot(slotP, &mac->frame_structure)) { @@ -2627,14 +2625,13 @@ static void nr_ue_prach_scheduler(NR_UE_MAC_INST_t *mac, frame_t frameP, slot_t LOG_E(NR_MAC, "Error in PRACH allocation\n"); return; } - uint16_t ncs = get_NCS(rach_ConfigGeneric->zeroCorrelationZoneConfig, format0, setup->restrictedSetConfig); pdu->prach_config_pdu = (fapi_nr_ul_config_prach_pdu){ .phys_cell_id = mac->physCellId, .num_prach_ocas = 1, .prach_slot = prach_occasion_info_p->slot, .prach_start_symbol = prach_occasion_info_p->start_symbol, .num_ra = prach_occasion_info_p->fdm, - .num_cs = ncs, + .num_cs = get_NCS(ra->zeroCorrelationZoneConfig, format0, ra->restricted_set_config), .root_seq_id = prach_config->num_prach_fd_occasions_list[prach_occasion_info_p->fdm].prach_root_sequence_index, .restricted_set = prach_config->restricted_set_config, .freq_msg1 = prach_config->num_prach_fd_occasions_list[prach_occasion_info_p->fdm].k1}; diff --git a/openair2/LAYER2/NR_MAC_UE/tests/test_nr_ue_ra_procedures.cpp b/openair2/LAYER2/NR_MAC_UE/tests/test_nr_ue_ra_procedures.cpp index f5a402c467..8b74a4a725 100644 --- a/openair2/LAYER2/NR_MAC_UE/tests/test_nr_ue_ra_procedures.cpp +++ b/openair2/LAYER2/NR_MAC_UE/tests/test_nr_ue_ra_procedures.cpp @@ -32,14 +32,6 @@ softmodem_params_t *get_softmodem_params(void) void nr_mac_rrc_ra_ind(const module_id_t mod_id, int frame, bool success) { } -int nr_write_ce_ulsch_pdu(uint8_t *mac_ce, - NR_UE_MAC_INST_t *mac, - NR_SINGLE_ENTRY_PHR_MAC_CE *power_headroom, - const type_bsr_t *bsr, - uint8_t *mac_ce_end) -{ - return 0; -} int nr_write_ce_msg3_pdu(uint8_t *mac_ce, NR_UE_MAC_INST_t *mac, rnti_t crnti, uint8_t *mac_ce_end) { return 0; @@ -77,6 +69,14 @@ int nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac, { return 0; } +NR_UE_DL_BWP_t *get_dl_bwp_structure(NR_UE_MAC_INST_t *mac, int bwp_id, bool setup) +{ + return NULL; +} +NR_UE_UL_BWP_t *get_ul_bwp_structure(NR_UE_MAC_INST_t *mac, int bwp_id, bool setup) +{ + return NULL; +} } #include #include "common/utils/LOG/log.h" @@ -84,22 +84,31 @@ int nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac, TEST(test_init_ra, four_step_cbra) { NR_UE_MAC_INST_t mac = {0}; - NR_PRACH_RESOURCES_t prach_resources = {0}; + RA_config_t *ra = &mac.ra; NR_RACH_ConfigCommon_t nr_rach_ConfigCommon = {0}; NR_RACH_ConfigGeneric_t rach_ConfigGeneric = {0}; - NR_RACH_ConfigDedicated_t *rach_ConfigDedicated = nullptr; + NR_RACH_ConfigDedicated_t rach_ConfigDedicated = {0}; NR_UE_UL_BWP_t current_bwp; + NR_UE_DL_BWP_t dl_bwp; mac.current_UL_BWP = ¤t_bwp; + mac.current_DL_BWP = &dl_bwp; long scs = 1; current_bwp.scs = scs; + current_bwp.bwp_id = 0; + dl_bwp.bwp_id = 0; current_bwp.channel_bandwidth = 40; nr_rach_ConfigCommon.msg1_SubcarrierSpacing = &scs; + nr_rach_ConfigCommon.rach_ConfigGeneric = rach_ConfigGeneric; + current_bwp.rach_ConfigCommon = &nr_rach_ConfigCommon; + ra->rach_ConfigDedicated = &rach_ConfigDedicated; mac.p_Max = 23; mac.nr_band = 78; mac.frame_structure.frame_type = TDD; mac.frequency_range = FR1; + mac.first_sync_frame = 0; + int frame = 151; - init_RA(&mac, &prach_resources, &nr_rach_ConfigCommon, &rach_ConfigGeneric, rach_ConfigDedicated); + init_RA(&mac, frame); EXPECT_EQ(mac.ra.ra_type, RA_4_STEP); EXPECT_EQ(mac.state, UE_PERFORMING_RA); @@ -110,25 +119,34 @@ TEST(test_init_ra, four_step_cbra) TEST(test_init_ra, four_step_cfra) { NR_UE_MAC_INST_t mac = {0}; - NR_PRACH_RESOURCES_t prach_resources = {0}; + RA_config_t *ra = &mac.ra; NR_RACH_ConfigCommon_t nr_rach_ConfigCommon = {0}; NR_RACH_ConfigGeneric_t rach_ConfigGeneric = {0}; NR_UE_UL_BWP_t current_bwp; + NR_UE_DL_BWP_t dl_bwp; mac.current_UL_BWP = ¤t_bwp; + mac.current_DL_BWP = &dl_bwp; long scs = 1; current_bwp.scs = scs; + current_bwp.bwp_id = 0; + dl_bwp.bwp_id = 0; current_bwp.channel_bandwidth = 40; nr_rach_ConfigCommon.msg1_SubcarrierSpacing = &scs; + nr_rach_ConfigCommon.rach_ConfigGeneric = rach_ConfigGeneric; + current_bwp.rach_ConfigCommon = &nr_rach_ConfigCommon; mac.p_Max = 23; mac.nr_band = 78; mac.frame_structure.frame_type = TDD; mac.frequency_range = FR1; + mac.first_sync_frame = 0; + int frame = 151; NR_RACH_ConfigDedicated_t rach_ConfigDedicated = {0}; struct NR_CFRA cfra; rach_ConfigDedicated.cfra = &cfra; + ra->rach_ConfigDedicated = &rach_ConfigDedicated; - init_RA(&mac, &prach_resources, &nr_rach_ConfigCommon, &rach_ConfigGeneric, &rach_ConfigDedicated); + init_RA(&mac, frame); EXPECT_EQ(mac.ra.ra_type, RA_4_STEP); EXPECT_EQ(mac.state, UE_PERFORMING_RA);