From 24fed617b51029361c62990f2c2edeb76a471090 Mon Sep 17 00:00:00 2001 From: francescomani Date: Fri, 29 Nov 2024 11:54:46 +0100 Subject: [PATCH] reworking prach scheduler to use new rach occasion information --- openair2/LAYER2/NR_MAC_UE/mac_defs.h | 4 +- openair2/LAYER2/NR_MAC_UE/main_ue_nr.c | 1 - openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c | 22 +-- openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c | 160 ++++--------------- 4 files changed, 46 insertions(+), 141 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index 4dc295acf3..d305b0246c 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -320,7 +320,7 @@ typedef struct { int Pc_max; } NR_PRACH_RESOURCES_t; -typedef struct{ +typedef struct { float ssb_per_ro; int preambles_per_ssb; } ssb_ro_preambles_t; @@ -362,8 +362,6 @@ typedef struct { bool RA_active; /// Random-access preamble index 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; // selected SSB for RACH (not the SSB-Index but the cumulative index, excluding not trasmitted SSBs) diff --git a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c index 1b865a78eb..95cc1b12ac 100644 --- a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c +++ b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c @@ -302,4 +302,3 @@ void release_mac_configuration(NR_UE_MAC_INST_t *mac, NR_UE_MAC_reset_cause_t ca for (int i = mac->TAG_list.count; i > 0 ; i--) asn_sequence_del(&mac->TAG_list, i - 1, 1); } - diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c index 039788b62e..d162168575 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c @@ -403,7 +403,7 @@ static void ra_resource_selection(NR_UE_MAC_INST_t *mac) ssb = mac->mib_ssb; // set the PREAMBLE_INDEX to a ra-PreambleIndex corresponding to the selected SSB ra->ra_PreambleIndex = res->ra_PreambleIndex; - ra->ro_mask_index = cfra->resourcesTwoStep_r16.ra_ssb_OccasionMaskIndex; + ra->ro_mask_index = cfra->resourcesTwoStep_r16.ra_ssb_OccasionMaskIndex; break; } } @@ -454,7 +454,7 @@ static void select_prach_occasion(RA_config_t *ra, int idx_ssb = 0; int temp_idx = 0; if (ra->ssb_ro_config.ssb_per_ro < 1) { - num_ros_per_ssb = (int) (1 / ra->ssb_ro_config.ssb_per_ro); + num_ros_per_ssb = (int)(1 / ra->ssb_ro_config.ssb_per_ro); idx_ssb = (rand_r(&seed) % num_ros_per_ssb); temp_idx = ra->ra_ssb * num_ros_per_ssb + idx_ssb; } else { @@ -508,13 +508,13 @@ static void configure_prach_occasions(NR_UE_MAC_INST_t *mac, int prach_config_in if (fs->frame_type == TDD && !check_mixed_slot_prach(fs, slot, start_symbol, end_symbol)) continue; for (int f = 0; f < num_fd_occasions; f++) { // fd occasions - ra_occasions_period[num_ra_occasions_period] = (prach_occasion_info_t) { - .slot = slot, - .frame_info[0] = prach_info.x, - .frame_info[1] = n == 0 ? prach_info.y : prach_info.y2, - .start_symbol = start_symbol, - .fdm = f, - .format = prach_info.format}; + ra_occasions_period[num_ra_occasions_period] = + (prach_occasion_info_t){.slot = slot, + .frame_info[0] = prach_info.x, + .frame_info[1] = n == 0 ? prach_info.y : prach_info.y2, + .start_symbol = start_symbol, + .fdm = f, + .format = prach_info.format}; LOG_D(NR_MAC, "RA occasion %d: slot %d start symbol %d fd occasion %d\n", num_ra_occasions_period, @@ -533,10 +533,10 @@ static void configure_prach_occasions(NR_UE_MAC_INST_t *mac, int prach_config_in ra->association_periods = 1; int nb_eq_ssb = mac->ssb_list.nb_tx_ssb; if (ra->ssb_ro_config.ssb_per_ro < 1) - nb_eq_ssb *= (int) (1 / ra->ssb_ro_config.ssb_per_ro); + nb_eq_ssb *= (int)(1 / ra->ssb_ro_config.ssb_per_ro); int nb_eq_ro = num_ra_occasions_period; if (ra->ssb_ro_config.ssb_per_ro > 1) - nb_eq_ro *= (int) ra->ssb_ro_config.ssb_per_ro; + nb_eq_ro *= (int)ra->ssb_ro_config.ssb_per_ro; while (nb_eq_ssb > nb_eq_ro) { // not enough PRACH occasions -> need to increase association period ra->association_periods <<= 1; diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index b2e1edd19e..bfdac6474e 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -1939,91 +1939,6 @@ static void map_ssb_to_ro(NR_UE_MAC_INST_t *mac) } } -// Returns a RACH occasion if any matches the SSB idx, the frame and the slot -static int get_nr_prach_info_from_ssb_index(prach_association_pattern_t *prach_assoc_pattern, - int ssb_idx, - int frame, - int slot, - ssb_list_info_t *ssb_list, - prach_occasion_info_t **prach_occasion_info_pp) -{ - prach_occasion_slot_t *prach_occasion_slot_p = NULL; - - *prach_occasion_info_pp = NULL; - - // Search for a matching RO slot in the SSB_to_RO map - // A valid RO slot will match: - // - ssb_idx mapped to one of the ROs in that RO slot - // - exact slot number - // - frame offset - int idx_list = ssb_list->nb_ssb_per_index[ssb_idx]; - ssb_info_t *ssb_info_p = &ssb_list->tx_ssb[idx_list]; - LOG_D(NR_MAC, "checking for prach : ssb_info_p->nb_mapped_ro %d\n", ssb_info_p->nb_mapped_ro); - for (int n_mapped_ro = 0; n_mapped_ro < ssb_info_p->nb_mapped_ro; n_mapped_ro++) { - LOG_D(NR_MAC, - "%d.%d: mapped_ro[%d]->frame.slot %d.%d, prach_assoc_pattern->nb_of_frame %d\n", - frame, - slot, - n_mapped_ro, - ssb_info_p->mapped_ro[n_mapped_ro]->frame, - ssb_info_p->mapped_ro[n_mapped_ro]->slot, - prach_assoc_pattern->nb_of_frame); - if ((slot == ssb_info_p->mapped_ro[n_mapped_ro]->slot) && prach_assoc_pattern->prach_conf_period_list[0].nb_of_frame != 0 && - (ssb_info_p->mapped_ro[n_mapped_ro]->frame == (frame % prach_assoc_pattern->nb_of_frame))) { - uint8_t prach_config_period_nb = ssb_info_p->mapped_ro[n_mapped_ro]->frame / prach_assoc_pattern->prach_conf_period_list[0].nb_of_frame; - uint8_t frame_nb_in_prach_config_period = ssb_info_p->mapped_ro[n_mapped_ro]->frame % prach_assoc_pattern->prach_conf_period_list[0].nb_of_frame; - prach_occasion_slot_p = &prach_assoc_pattern->prach_conf_period_list[prach_config_period_nb].prach_occasion_slot_map[frame_nb_in_prach_config_period][slot]; - } - } - - // If there is a matching RO slot in the SSB_to_RO map - if (NULL != prach_occasion_slot_p) { - // A random RO mapped to the SSB index should be selected in the slot - - // First count the number of times the SSB index is found in that RO - uint8_t nb_mapped_ssb = 0; - - for (int ro_in_time = 0; ro_in_time < prach_occasion_slot_p->nb_of_prach_occasion_in_time; ro_in_time++) { - for (int ro_in_freq = 0; ro_in_freq < prach_occasion_slot_p->nb_of_prach_occasion_in_freq; ro_in_freq++) { - prach_occasion_info_t *ro_p = - prach_occasion_slot_p->prach_occasion + ro_in_time * prach_occasion_slot_p->nb_of_prach_occasion_in_freq + ro_in_freq; - for (uint8_t ssb_nb = 0; ssb_nb < ro_p->nb_mapped_ssb; ssb_nb++) { - if (ro_p->mapped_ssb_idx[ssb_nb] == ssb_idx) { - nb_mapped_ssb++; - } - } - } - } - - // Choose a random SSB nb - uint8_t random_ssb_nb = 0; - - random_ssb_nb = ((taus()) % nb_mapped_ssb); - - // Select the RO according to the chosen random SSB nb - nb_mapped_ssb=0; - for (int ro_in_time=0; ro_in_time < prach_occasion_slot_p->nb_of_prach_occasion_in_time; ro_in_time++) { - for (int ro_in_freq=0; ro_in_freq < prach_occasion_slot_p->nb_of_prach_occasion_in_freq; ro_in_freq++) { - prach_occasion_info_t *ro_p = - prach_occasion_slot_p->prach_occasion + ro_in_time * prach_occasion_slot_p->nb_of_prach_occasion_in_freq + ro_in_freq; - for (uint8_t ssb_nb = 0; ssb_nb < ro_p->nb_mapped_ssb; ssb_nb++) { - if (ro_p->mapped_ssb_idx[ssb_nb] == ssb_idx) { - if (nb_mapped_ssb == random_ssb_nb) { - *prach_occasion_info_pp = ro_p; - return 1; - } - else { - nb_mapped_ssb++; - } - } - } - } - } - } - - return 0; -} - // Build the SSB to RO mapping upon RRC configuration update void build_ssb_to_ro_map(NR_UE_MAC_INST_t *mac) { @@ -2522,6 +2437,23 @@ void nr_schedule_csirs_reception(NR_UE_MAC_INST_t *mac, int frame, int slot) } } +static bool is_prach_frame(frame_t frame, prach_occasion_info_t *prach_occasion_info, int association_periods) +{ + int config_period = prach_occasion_info->frame_info[0]; + int frame_period = config_period * association_periods; + int frame_in_period = frame % frame_period; + if (association_periods > 1) { + int current_assoc_period = frame_in_period / config_period; + if (current_assoc_period != prach_occasion_info->association_period_idx) + return false; + frame_in_period %= config_period; + } + if (frame_in_period == prach_occasion_info->frame_info[1]) // SFN % x == y (see Tables in Table 6.3.3.2 of 38.211) + return true; + else + return false; +} + // This function schedules the PRACH according to prach_ConfigurationIndex and TS 38.211, tables 6.3.3.2.x // PRACH formats 9, 10, 11 are corresponding to dual PRACH format configurations A1/B1, A2/B2, A3/B3. // - todo: @@ -2533,49 +2465,36 @@ static void nr_ue_prach_scheduler(NR_UE_MAC_INST_t *mac, frame_t frameP, slot_t if (ra->ra_state != nrRA_GENERATE_PREAMBLE) return; - fapi_nr_config_request_t *cfg = &mac->phy_config.config_req; - fapi_nr_prach_config_t *prach_config = &cfg->prach_config; + // Get any valid PRACH occasion in the current slot for the selected SSB index + prach_occasion_info_t *prach_occasion_info = &ra->sched_ro_info; - const int bwp_id = mac->current_UL_BWP->bwp_id; + if (!is_prach_frame(frameP, prach_occasion_info, ra->association_periods)) + return; if (is_ul_slot(slotP, &mac->frame_structure)) { - // WIP Need to get the proper selected ssb_idx - // Initial beam selection functionality is not available yet - uint8_t selected_gnb_ssb_idx = mac->mib_ssb; - - // Get any valid PRACH occasion in the current slot for the selected SSB index - prach_occasion_info_t *prach_occasion_info_p; - int is_nr_prach_slot = get_nr_prach_info_from_ssb_index(&mac->prach_assoc_pattern[bwp_id], - selected_gnb_ssb_idx, - (int)frameP, - (int)slotP, - &mac->ssb_list, - &prach_occasion_info_p); - - if (is_nr_prach_slot) { - AssertFatal(NULL != prach_occasion_info_p,"PRACH Occasion Info not returned in a valid NR Prach Slot\n"); - + if (slotP == prach_occasion_info->slot) { nr_get_RA_window(mac); - - uint16_t format = prach_occasion_info_p->format; - uint16_t format0 = format & 0xff; // single PRACH format - uint16_t format1 = (format >> 8) & 0xff; // dual PRACH format - fapi_nr_ul_config_request_pdu_t *pdu = lockGet_ul_config(mac, frameP, slotP, FAPI_NR_UL_CONFIG_TYPE_PRACH); if (!pdu) { LOG_E(NR_MAC, "Error in PRACH allocation\n"); return; } + + uint16_t format = prach_occasion_info->format; + uint16_t format0 = format & 0xff; // single PRACH format + uint16_t format1 = (format >> 8) & 0xff; // dual PRACH format + + fapi_nr_prach_config_t *prach_config = &mac->phy_config.config_req.prach_config; 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, + .prach_slot = prach_occasion_info->slot, + .prach_start_symbol = prach_occasion_info->start_symbol, + .num_ra = prach_occasion_info->fdm, .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, + .root_seq_id = prach_config->num_prach_fd_occasions_list[prach_occasion_info->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}; + .freq_msg1 = prach_config->num_prach_fd_occasions_list[prach_occasion_info->fdm].k1}; LOG_I(NR_MAC, "PRACH scheduler: Selected RO Frame %u, Slot %u, Symbol %u, Fdm %u\n", @@ -2584,15 +2503,6 @@ static void nr_ue_prach_scheduler(NR_UE_MAC_INST_t *mac, frame_t frameP, slot_t pdu->prach_config_pdu.prach_start_symbol, pdu->prach_config_pdu.num_ra); - // Search which SSB is mapped in the RO (among all the SSBs mapped to this RO) - for (int ssb_nb_in_ro=0; ssb_nb_in_ronb_mapped_ssb; ssb_nb_in_ro++) { - if (prach_occasion_info_p->mapped_ssb_idx[ssb_nb_in_ro] == selected_gnb_ssb_idx) { - ra->ssb_nb_in_ro = ssb_nb_in_ro; - break; - } - } - AssertFatal(ra->ssb_nb_in_ronb_mapped_ssb, "%u not found in the mapped SSBs to the PRACH occasion", selected_gnb_ssb_idx); - if (format1 != 0xff) { switch (format0) { // dual PRACH format case 0xa1: @@ -2706,7 +2616,7 @@ static void nr_ue_prach_scheduler(NR_UE_MAC_INST_t *mac, frame_t frameP, slot_t // Compute MsgB RNTI ra->MsgB_rnti = - nr_get_MsgB_rnti(prach_occasion_info_p->start_symbol, slot_RA, prach_occasion_info_p->fdm, 0); + nr_get_MsgB_rnti(prach_occasion_info->start_symbol, slot_RA, prach_occasion_info->fdm, 0); LOG_D(NR_MAC, "ra->ra_state %s\n", nrra_ue_text[ra->ra_state]); ra->ra_state = nrRA_WAIT_MSGB; ra->t_crnti = 0; @@ -2715,8 +2625,6 @@ static void nr_ue_prach_scheduler(NR_UE_MAC_INST_t *mac, frame_t frameP, slot_t } else { AssertFatal(false, "RA type %d not implemented!\n", ra->ra_type); } - - // rnti = ra->t_crnti; } // is_nr_prach_slot } // if is_nr_UL_slot }