From 3289189a2d78ca2ea517debcfb1e36c03f3b73c7 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 4 Apr 2024 09:37:21 +0200 Subject: [PATCH 01/19] Fix: Configure TDD beam association only in FR2; set to NULL otherwise Before this commit, there was data that was not initialized, resulting in Msg2 remaining unscheduled. --- openair2/LAYER2/NR_MAC_gNB/config.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c index 29b4434405..17fb37edba 100644 --- a/openair2/LAYER2/NR_MAC_gNB/config.c +++ b/openair2/LAYER2/NR_MAC_gNB/config.c @@ -654,11 +654,14 @@ static void config_common(gNB_MAC_INST *nrmac, nr_pdsch_AntennaPorts_t pdsch_Ant scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots, scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols); - if (periods_per_frame < 0) - LOG_E(NR_MAC, "TDD configuration can not be done\n"); - else { - LOG_I(NR_MAC, "TDD has been properly configurated\n"); - nrmac->tdd_beam_association = (int16_t *)malloc16(periods_per_frame * sizeof(int16_t)); + AssertFatal(periods_per_frame > 0, "TDD configuration cannot be configured\n"); + if (frequency_range == FR2) { + LOG_I(NR_MAC, "Configuring TDD beam association to default\n"); + nrmac->tdd_beam_association = malloc16(periods_per_frame * sizeof(int16_t)); + for (int i = 0; i < periods_per_frame; ++i) + nrmac->tdd_beam_association[i] = -1; /* default: beams not configured */ + } else { + nrmac->tdd_beam_association = NULL; /* default: no beams */ } } From 6658eb28f05c2d37d366bc18850480bf502c4e4a Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 19 Mar 2024 14:33:45 +0100 Subject: [PATCH 02/19] Simplify nr_clear_ra_proc() --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 12 +++++------- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 14 +++++++------- openair2/LAYER2/NR_MAC_gNB/mac_proto.h | 2 +- openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c | 2 +- openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h | 2 -- 5 files changed, 14 insertions(+), 18 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index 98d241388e..1b68465968 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -1281,7 +1281,7 @@ static void nr_generate_Msg2(module_id_t module_idP, if (CCEIndex < 0) { LOG_E(NR_MAC, "cannot find free CCE for Msg2 of RA RNTI 0x%04x!\n", ra->rnti); - nr_clear_ra_proc(module_idP, CC_id, frameP, ra); + nr_clear_ra_proc(ra); return; } @@ -1986,7 +1986,7 @@ static void nr_check_Msg4_Ack(module_id_t module_id, int CC_id, frame_t frame, s // UE->apply_cellgroup was already set when processing RRCReestablishment message nr_mac_enable_ue_rrc_processing_timer(RC.nrmac[module_id], UE, UE->apply_cellgroup); - nr_clear_ra_proc(module_id, CC_id, frame, ra); + nr_clear_ra_proc(ra); if (sched_ctrl->retrans_dl_harq.head >= 0) { remove_nr_list(&sched_ctrl->retrans_dl_harq, current_harq_pid); } @@ -1997,14 +1997,12 @@ static void nr_check_Msg4_Ack(module_id_t module_id, int CC_id, frame_t frame, s } } -void nr_clear_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP, NR_RA_t *ra) +void nr_clear_ra_proc(NR_RA_t *ra) { /* we assume that this function is mutex-protected from outside */ - NR_SCHED_ENSURE_LOCKED(&RC.nrmac[module_idP]->sched_lock); - LOG_D(NR_MAC,"[gNB %d][RAPROC] CC_id %d Frame %d Clear Random access information rnti %x\n", module_idP, CC_id, frameP, ra->rnti); + NR_SCHED_ENSURE_LOCKED(&RC.nrmac[0]->sched_lock); ra->ra_state = nrRA_gNB_IDLE; ra->timing_offset = 0; - ra->RRC_timer = 20; ra->msg3_round = 0; if(ra->cfra == false) { ra->rnti = 0; @@ -2151,7 +2149,7 @@ void nr_schedule_RA(module_id_t module_idP, if (ra->contention_resolution_timer < 0) { LOG_W(NR_MAC, "(%d.%d) RA Contention Resolution timer expired for UE 0x%04x, RA procedure failed...\n", frameP, slotP, ra->rnti); nr_mac_release_ue(mac, ra->rnti); - nr_clear_ra_proc(module_idP, CC_id, frameP, ra); + nr_clear_ra_proc(ra); continue; } } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 7ed78885ed..ada64a4189 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -717,7 +717,7 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP, if (no_sig) { LOG_D(NR_MAC, "Random Access %i failed at state %s (no signal)\n", i, nrra_text[ra->ra_state]); - nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra); + nr_clear_ra_proc(ra); continue; } @@ -732,7 +732,7 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP, nrra_text[ra->ra_state], ra->rnti, current_rnti); - nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra); + nr_clear_ra_proc(ra); } continue; @@ -747,7 +747,7 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP, ra->rnti, current_rnti); - nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra); + nr_clear_ra_proc(ra); return; } @@ -778,7 +778,7 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP, nr_mac_reset_ul_failure(UE_scheduling_control); reset_dl_harq_list(UE_scheduling_control); reset_ul_harq_list(UE_scheduling_control); - nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra); + nr_clear_ra_proc(ra); process_CellGroup(ra->CellGroup, UE); } else { @@ -809,7 +809,7 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP, // solution may be implemented LOG_W(NR_MAC, "No UE found with C-RNTI %04x, ignoring Msg3 to have UE come back with new RA attempt\n", ra->rnti); mac_remove_nr_ue(RC.nrmac[gnb_mod_idP], ra->rnti); - nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra); + nr_clear_ra_proc(ra); return; } @@ -859,13 +859,13 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP, // for CFRA (NSA) do not schedule retransmission of msg3 if (ra->cfra) { LOG_D(NR_MAC, "Random Access %i failed at state %s (NSA msg3 reception failed)\n", i, nrra_text[ra->ra_state]); - nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra); + nr_clear_ra_proc(ra); return; } if (ra->msg3_round >= gNB_mac->ul_bler.harq_round_max - 1) { LOG_W(NR_MAC, "Random Access %i failed at state %s (Reached msg3 max harq rounds)\n", i, nrra_text[ra->ra_state]); - nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra); + nr_clear_ra_proc(ra); return; } diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index 6e38f491f6..d156663bc9 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -115,7 +115,7 @@ void nr_schedule_RA(module_id_t module_idP, void nr_initiate_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP, uint16_t preamble_index, uint8_t freq_index, uint8_t symbol, int16_t timing_offset); -void nr_clear_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP, NR_RA_t *ra); +void nr_clear_ra_proc(NR_RA_t *ra); int nr_allocate_CCEs(int module_idP, int CC_idP, frame_t frameP, sub_frame_t slotP, int test_only); diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c index 6f4c832802..f0d5b7ce18 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c @@ -612,7 +612,7 @@ void ue_context_modification_refuse(const f1ap_ue_context_modif_refuse_t *refuse for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) { NR_RA_t *ra = &cc->ra[i]; if (ra->rnti == UE->rnti) - nr_clear_ra_proc(0, CC_id, 0 /* frame */, ra); + nr_clear_ra_proc(ra); } NR_SCHED_UNLOCK(&mac->sched_lock); diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 17c5134bcd..479dd9dffe 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -188,8 +188,6 @@ typedef struct { uint8_t cont_res_id[6]; /// Timing offset indicated by PHY int16_t timing_offset; - /// Timeout for RRC connection - int16_t RRC_timer; /// Msg3 first RB int msg3_first_rb; /// Msg3 number of RB From 8f747d7aa2b5f672b34c6477468a2372a63324d4 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 18 Mar 2024 11:52:45 +0100 Subject: [PATCH 03/19] Simplify nr_initiate_ra_proc() - create function to find free RA process - reorganize function to put Msg1 related processing first, Msg2 second --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 242 ++++++++---------- 1 file changed, 111 insertions(+), 131 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index 1b68465968..96613a252a 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -540,6 +540,40 @@ static void nr_schedule_msg2(uint16_t rach_frame, *msg2_frame = *msg2_frame % 1024; } +static bool ra_contains_preamble(const NR_RA_t *ra, uint16_t preamble_index) +{ + for (int j = 0; j < ra->preambles.num_preambles; j++) { + // check if the preamble received correspond to one of the listed or configured preambles + if (preamble_index == ra->preambles.preamble_list[j]) { + if (ra->rnti == 0 && get_softmodem_params()->nsa) + continue; + return true; + } + } + return false; +} + +static NR_RA_t *find_free_nr_RA(NR_RA_t *ra_base, int ra_count, uint16_t preamble_index) +{ + // for posteriority: in the past we checked the beam index, but only in CFRA + //if (ra->cfra && preamble_index != ra->preamble.preamble_list[beam_index]]) + // // then is not right RA + // + // that seems strange because: + // - we check preamble_index already + // - why only CFRA? + + for (int i = 0; i < ra_count; ++i) { + NR_RA_t *ra = &ra_base[i]; + if (ra->ra_state != nrRA_gNB_IDLE) + continue; + if (!ra_contains_preamble(ra, preamble_index)) + continue; + + return ra; + } + return NULL; +} void nr_initiate_ra_proc(module_id_t module_idP, int CC_id, @@ -550,147 +584,93 @@ void nr_initiate_ra_proc(module_id_t module_idP, uint8_t symbol, int16_t timing_offset) { + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 1); + gNB_MAC_INST *nr_mac = RC.nrmac[module_idP]; NR_SCHED_LOCK(&nr_mac->sched_lock); - uint8_t ul_carrier_id = 0; // 0 for NUL 1 for SUL - uint16_t msg2_frame, msg2_slot,monitoring_slot_period,monitoring_offset; NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id]; - NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; - frame_type_t frame_type = cc->frame_type; - - uint8_t total_RApreambles = MAX_NUM_NR_PRACH_PREAMBLES; - uint8_t num_ssb_per_RO = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present; - int pr_found; - - if( scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles != NULL) - total_RApreambles = *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles; - - if(num_ssb_per_RO > 3) { /*num of ssb per RO >= 1*/ - num_ssb_per_RO -= 3; - total_RApreambles = total_RApreambles/num_ssb_per_RO ; - } - - for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) { - - NR_RA_t *ra = &cc->ra[i]; - if (ra->ra_state != nrRA_gNB_IDLE) - continue; - - pr_found = 0; - - for(int j = 0; j < ra->preambles.num_preambles; j++) { - //check if the preamble received correspond to one of the listed or configured preambles - if (preamble_index == ra->preambles.preamble_list[j]) { - if (ra->rnti == 0 && get_softmodem_params()->nsa) - continue; - pr_found=1; - break; - } - } - if (pr_found == 0) { - continue; - } - - rnti_t ra_rnti = nr_get_ra_rnti(symbol, slotP, freq_index, ul_carrier_id); - - // Configure RA BWP - configure_UE_BWP(nr_mac, scc, NULL, ra, NULL, -1, -1); - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 1); - - LOG_D(NR_MAC, - "[gNB %d][RAPROC] CC_id %d Frame %d, Slot %d Initiating RA procedure for preamble index %d\n", - module_idP, - CC_id, - frameP, - slotP, - preamble_index); - - uint8_t beam_index = ssb_index_from_prach(module_idP, frameP, slotP, preamble_index, freq_index, symbol); - - // the UE sent a RACH either for starting RA procedure or RA procedure failed and UE retries - if (ra->cfra) { - // if the preamble received correspond to one of the listed - if (!(preamble_index == ra->preambles.preamble_list[beam_index])) { - LOG_E( - NR_MAC, - "[gNB %d][RAPROC] FAILURE: preamble %d does not correspond to any of the ones in rach_ConfigDedicated\n", - module_idP, - preamble_index); - continue; // if the PRACH preamble does not correspond to any of the ones sent through RRC abort RA proc - } - } - LOG_D(NR_MAC, "Frame %d, Slot %d: Activating RA process \n", frameP, slotP); - ra->timing_offset = timing_offset; - ra->preamble_slot = slotP; - - // retrieving ra pdcch monitoring period and offset - find_monitoring_periodicity_offset_common(ra->ra_ss, &monitoring_slot_period, &monitoring_offset); - - nr_schedule_msg2(frameP, - slotP, - &msg2_frame, - &msg2_slot, - ra->DL_BWP.scs, - scc, - frame_type, - monitoring_slot_period, - monitoring_offset, - beam_index, - cc->num_active_ssb, - nr_mac->tdd_beam_association, - nr_mac->if_inst->sl_ahead); - - ra->Msg2_frame = msg2_frame; - ra->Msg2_slot = msg2_slot; - - LOG_D(NR_MAC, "%s() Msg2[%04d%d] SFN/SF:%04d%d\n", __FUNCTION__, ra->Msg2_frame, ra->Msg2_slot, frameP, slotP); - - int loop = 0; - bool exist_connected_ue, exist_in_pending_ra_ue; - if (ra->rnti == 0) { // This condition allows for the usage of a preconfigured rnti for the CFRA - rnti_t trial = 0; - do { - // 3GPP TS 38.321 version 15.13.0 Section 7.1 Table 7.1-1: RNTI values - while (trial < 1 || trial > 0xffef) - trial = (taus() % 0xffef) + 1; - exist_connected_ue = find_nr_UE(&nr_mac->UE_info, trial) != NULL; - exist_in_pending_ra_ue = find_nr_RA_id(module_idP, CC_id, trial) != -1; - loop++; - } while (loop < 100 && (exist_connected_ue || exist_in_pending_ra_ue) ); - if (loop == 100) { - LOG_E(NR_MAC, "[RAPROC] initialisation random access: no more available RNTIs for new UE\n"); - NR_SCHED_UNLOCK(&nr_mac->sched_lock); - return; - } - ra->rnti = trial; - } - - ra->ra_state = nrRA_Msg2; - ra->RA_rnti = ra_rnti; - ra->preamble_index = preamble_index; - ra->beam_id = cc->ssb_index[beam_index]; - - LOG_I(NR_MAC, - "[gNB %d][RAPROC] CC_id %d Frame %d Activating Msg2 generation in frame %d, slot %d using RA rnti %x SSB, new rnti %04x " - "index %u RA index %d\n", - module_idP, - CC_id, - frameP, - ra->Msg2_frame, - ra->Msg2_slot, - ra->RA_rnti, - ra->rnti, - cc->ssb_index[beam_index], - i); + NR_RA_t *ra = find_free_nr_RA(cc->ra, sizeofArray(cc->ra), preamble_index); + if (ra == NULL) { + LOG_E(NR_MAC, "FAILURE: %4d.%2d initiating RA procedure for preamble index %d: no free RA process\n", frameP, slotP, preamble_index); NR_SCHED_UNLOCK(&nr_mac->sched_lock); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 0); return; } + if (ra->rnti == 0) { // This condition allows for the usage of a preconfigured rnti for the CFRA + int loop = 0; + bool exist_connected_ue, exist_in_pending_ra_ue; + rnti_t trial = 0; + do { + // 3GPP TS 38.321 version 15.13.0 Section 7.1 Table 7.1-1: RNTI values + while (trial < 1 || trial > 0xffef) + trial = (taus() % 0xffef) + 1; + exist_connected_ue = find_nr_UE(&nr_mac->UE_info, trial) != NULL; + exist_in_pending_ra_ue = find_nr_RA_id(module_idP, CC_id, trial) != -1; + loop++; + } while (loop < 100 && (exist_connected_ue || exist_in_pending_ra_ue) ); + if (loop == 100) { + LOG_E(NR_MAC, "[RAPROC] initialisation random access: no more available RNTIs for new UE\n"); + NR_SCHED_UNLOCK(&nr_mac->sched_lock); + return; + } + ra->rnti = trial; + } + + ra->ra_state = nrRA_Msg2; + ra->preamble_slot = slotP; + ra->preamble_index = preamble_index; + ra->timing_offset = timing_offset; + uint8_t ul_carrier_id = 0; // 0 for NUL 1 for SUL + ra->RA_rnti = nr_get_ra_rnti(symbol, slotP, freq_index, ul_carrier_id); + int index = ra - cc->ra; + LOG_I(NR_MAC, "%d.%d UE RA-RNTI %04x RNTI %04x: Activating RA process index %d\n", frameP, slotP, ra->RA_rnti, ra->rnti, index); + + // Configure RA BWP + NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; + configure_UE_BWP(nr_mac, scc, NULL, ra, NULL, -1, -1); + + // retrieving ra pdcch monitoring period and offset + uint16_t monitoring_slot_period, monitoring_offset; + find_monitoring_periodicity_offset_common(ra->ra_ss, &monitoring_slot_period, &monitoring_offset); + + uint8_t beam_index = ssb_index_from_prach(module_idP, frameP, slotP, preamble_index, freq_index, symbol); + ra->beam_id = cc->ssb_index[beam_index]; + uint16_t msg2_frame, msg2_slot; + nr_schedule_msg2(frameP, + slotP, + &msg2_frame, + &msg2_slot, + ra->DL_BWP.scs, + scc, + cc->frame_type, + monitoring_slot_period, + monitoring_offset, + beam_index, + cc->num_active_ssb, + nr_mac->tdd_beam_association, + nr_mac->if_inst->sl_ahead); + + ra->Msg2_frame = msg2_frame; + ra->Msg2_slot = msg2_slot; + + LOG_D(NR_MAC, "%s() Msg2[%04d%d] SFN/SF:%04d%d\n", __FUNCTION__, ra->Msg2_frame, ra->Msg2_slot, frameP, slotP); + + LOG_I(NR_MAC, + "[gNB %d][RAPROC] CC_id %d Frame %d Activating Msg2 generation in frame %d, slot %d using RA rnti %x SSB, new rnti %04x " + "index %u\n", + module_idP, + CC_id, + frameP, + ra->Msg2_frame, + ra->Msg2_slot, + ra->RA_rnti, + ra->rnti, + cc->ssb_index[beam_index]); + NR_SCHED_UNLOCK(&nr_mac->sched_lock); - LOG_E(NR_MAC, "[gNB %d][RAPROC] FAILURE: CC_id %d %4d.%2d initiating RA procedure for preamble index %d: no free RA process\n", module_idP, CC_id, frameP, slotP, preamble_index); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 0); } From 205cc66546ad098a60605e2b4677da51210ce1b8 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 19 Mar 2024 07:33:57 +0100 Subject: [PATCH 04/19] Refactor former find_nr_RA_id() to static function --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 12 +++++++++++- .../LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c | 14 -------------- openair2/LAYER2/NR_MAC_gNB/mac_proto.h | 2 -- 3 files changed, 11 insertions(+), 17 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index 96613a252a..7b6769cecf 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -575,6 +575,16 @@ static NR_RA_t *find_free_nr_RA(NR_RA_t *ra_base, int ra_count, uint16_t preambl return NULL; } +static const NR_RA_t *find_nr_RA_rnti(const NR_RA_t *ra_base, int ra_count, rnti_t rnti) +{ + for (int i = 0; i < ra_count; ++i) { + const NR_RA_t *ra = &ra_base[i]; + if (ra->ra_state != nrRA_gNB_IDLE && ra->rnti == rnti) + return ra; + } + return NULL; +} + void nr_initiate_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP, @@ -608,7 +618,7 @@ void nr_initiate_ra_proc(module_id_t module_idP, while (trial < 1 || trial > 0xffef) trial = (taus() % 0xffef) + 1; exist_connected_ue = find_nr_UE(&nr_mac->UE_info, trial) != NULL; - exist_in_pending_ra_ue = find_nr_RA_id(module_idP, CC_id, trial) != -1; + exist_in_pending_ra_ue = find_nr_RA_rnti(cc->ra, sizeofArray(cc->ra), ra->rnti) != NULL; loop++; } while (loop < 100 && (exist_connected_ue || exist_in_pending_ra_ue) ); if (loop == 100) { diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index 851b9e3faa..9a1be26024 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -2071,20 +2071,6 @@ NR_UE_info_t *find_nr_UE(NR_UEs_t *UEs, rnti_t rntiP) return NULL; } -int find_nr_RA_id(module_id_t mod_idP, int CC_idP, rnti_t rntiP) -{ - NR_RA_t *ra = RC.nrmac[mod_idP]->common_channels[CC_idP].ra; - - for (int RA_id = 0; RA_id < NR_NB_RA_PROC_MAX; RA_id++) { - LOG_D(NR_MAC, "Checking RA_id %d for %x : state %s\n", RA_id, rntiP, nrra_text[ra[RA_id].ra_state]); - - if (ra[RA_id].ra_state != nrRA_gNB_IDLE && ra[RA_id].rnti == rntiP) - return RA_id; - } - - return -1; -} - int get_nrofHARQ_ProcessesForPDSCH(e_NR_PDSCH_ServingCellConfig__nrofHARQ_ProcessesForPDSCH n) { switch (n) { diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index d156663bc9..639d126220 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -302,8 +302,6 @@ void remove_front_nr_list(NR_list_t *listP); NR_UE_info_t * find_nr_UE(NR_UEs_t* UEs, rnti_t rntiP); -int find_nr_RA_id(module_id_t mod_idP, int CC_idP, rnti_t rntiP); - void configure_UE_BWP(gNB_MAC_INST *nr_mac, NR_ServingCellConfigCommon_t *scc, NR_UE_sched_ctrl_t *sched_ctrl, From 7873292f28344d484acbea0b821bb7fd938fa16c Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 19 Mar 2024 16:41:07 +0100 Subject: [PATCH 05/19] Reduce indentation in nr_generate_msg2(): no functional changes --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 575 +++++++++--------- 1 file changed, 289 insertions(+), 286 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index 7b6769cecf..39940110f2 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -1204,296 +1204,299 @@ static void nr_generate_Msg2(module_id_t module_idP, NR_UE_DL_BWP_t *dl_bwp = &ra->DL_BWP; NR_UE_ServingCell_Info_t *sc_info = &ra->sc_info; - if ((ra->Msg2_frame == frameP) && (ra->Msg2_slot == slotP)) { + if (ra->Msg2_frame != frameP || ra->Msg2_slot != slotP) + return; - int mcsIndex = -1; // initialization value - int rbStart = 0; - int rbSize = 8; + int mcsIndex = -1; // initialization value + int rbStart = 0; + int rbSize = 8; - NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; - NR_SearchSpace_t *ss = ra->ra_ss; + NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; + NR_SearchSpace_t *ss = ra->ra_ss; - long BWPStart = 0; - long BWPSize = 0; - NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config = NULL; - if(*ss->controlResourceSetId != 0) { - BWPStart = dl_bwp->BWPStart; - BWPSize = sc_info->initial_dl_BWPSize; - } else { - type0_PDCCH_CSS_config = &nr_mac->type0_PDCCH_CSS_config[ra->beam_id]; - BWPStart = type0_PDCCH_CSS_config->cset_start_rb; - BWPSize = type0_PDCCH_CSS_config->num_rbs; - } - - NR_ControlResourceSet_t *coreset = ra->coreset; - AssertFatal(coreset != NULL,"Coreset cannot be null for RA-Msg2\n"); - const int coresetid = coreset->controlResourceSetId; - // Calculate number of symbols - int time_domain_assignment = get_dl_tda(nr_mac, scc, slotP); - int mux_pattern = type0_PDCCH_CSS_config ? type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern : 1; - NR_tda_info_t tda_info = get_dl_tda_info(dl_bwp, - ss->searchSpaceType->present, - time_domain_assignment, - scc->dmrs_TypeA_Position, - mux_pattern, - TYPE_RA_RNTI_, - coresetid, - false); - - uint16_t *vrb_map = cc[CC_id].vrb_map; - for (int i = 0; (i < rbSize) && (rbStart <= (BWPSize - rbSize)); i++) { - if (vrb_map[BWPStart + rbStart + i]&SL_to_bitmap(tda_info.startSymbolIndex, tda_info.nrOfSymbols)) { - rbStart += i; - i = 0; - } - } - - if (rbStart > (BWPSize - rbSize)) { - LOG_E(NR_MAC, "%s(): cannot find free vrb_map for RA RNTI %04x!\n", __func__, ra->RA_rnti); - return; - } - - // Checking if the DCI allocation is feasible in current subframe - nfapi_nr_dl_tti_request_body_t *dl_req = &DL_req->dl_tti_request_body; - if (dl_req->nPDUs > NFAPI_NR_MAX_DL_TTI_PDUS - 2) { - LOG_I(NR_MAC, "[RAPROC] Subframe %d: FAPI DL structure is full, skip scheduling UE %d\n", slotP, ra->RA_rnti); - return; - } - - uint8_t aggregation_level; - int CCEIndex = get_cce_index(nr_mac, - CC_id, slotP, 0, - &aggregation_level, - ss, - coreset, - &ra->sched_pdcch, - true); - - if (CCEIndex < 0) { - LOG_E(NR_MAC, "cannot find free CCE for Msg2 of RA RNTI 0x%04x!\n", ra->rnti); - nr_clear_ra_proc(ra); - return; - } - - LOG_D(NR_MAC,"Msg2 startSymbolIndex.nrOfSymbols %d.%d\n",tda_info.startSymbolIndex,tda_info.nrOfSymbols); - - // look up the PDCCH PDU for this CC, BWP, and CORESET. If it does not exist, create it. This is especially - // important if we have multiple RAs, and the DLSCH has to reuse them, so we need to mark them - nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = nr_mac->pdcch_pdu_idx[CC_id][coresetid]; - if (!pdcch_pdu_rel15) { - nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdcch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs]; - memset(dl_tti_pdcch_pdu, 0, sizeof(nfapi_nr_dl_tti_request_pdu_t)); - dl_tti_pdcch_pdu->PDUType = NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE; - dl_tti_pdcch_pdu->PDUSize = (uint8_t)(2 + sizeof(nfapi_nr_dl_tti_pdcch_pdu)); - dl_req->nPDUs += 1; - pdcch_pdu_rel15 = &dl_tti_pdcch_pdu->pdcch_pdu.pdcch_pdu_rel15; - nr_configure_pdcch(pdcch_pdu_rel15, coreset, &ra->sched_pdcch); - nr_mac->pdcch_pdu_idx[CC_id][coresetid] = pdcch_pdu_rel15; - } - - nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdsch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs]; - memset((void *)dl_tti_pdsch_pdu,0,sizeof(nfapi_nr_dl_tti_request_pdu_t)); - dl_tti_pdsch_pdu->PDUType = NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE; - dl_tti_pdsch_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdsch_pdu)); - dl_req->nPDUs+=1; - nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15 = &dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15; - - pdsch_pdu_rel15->precodingAndBeamforming.num_prgs = 0; - pdsch_pdu_rel15->precodingAndBeamforming.prg_size = 0; - pdsch_pdu_rel15->precodingAndBeamforming.dig_bf_interfaces = 0; - pdsch_pdu_rel15->precodingAndBeamforming.prgs_list[0].pm_idx = 0; - pdsch_pdu_rel15->precodingAndBeamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = 0; - - LOG_A(NR_MAC, - "[gNB %d][RAPROC] CC_id %d Frame %d, slotP %d: Generating RA-Msg2 DCI, rnti 0x%x, state %d, CoreSetType %d\n", - module_idP, - CC_id, - frameP, - slotP, - ra->RA_rnti, - ra->ra_state, - pdcch_pdu_rel15->CoreSetType); - - // SCF222: PDU index incremented for each PDSCH PDU sent in TX control message. This is used to associate control - // information to data and is reset every slot. - const int pduindex = nr_mac->pdu_index[CC_id]++; - uint8_t mcsTableIdx = dl_bwp->mcsTableIdx; - - NR_pdsch_dmrs_t dmrs_parms = get_dl_dmrs_params(scc, - dl_bwp, - &tda_info, - 1); - - pdsch_pdu_rel15->pduBitmap = 0; - pdsch_pdu_rel15->rnti = ra->RA_rnti; - pdsch_pdu_rel15->pduIndex = pduindex; - pdsch_pdu_rel15->BWPSize = BWPSize; - pdsch_pdu_rel15->BWPStart = BWPStart; - pdsch_pdu_rel15->SubcarrierSpacing = dl_bwp->scs; - pdsch_pdu_rel15->CyclicPrefix = 0; - pdsch_pdu_rel15->NrOfCodewords = 1; - pdsch_pdu_rel15->mcsTable[0] = mcsTableIdx; - pdsch_pdu_rel15->rvIndex[0] = 0; - pdsch_pdu_rel15->dataScramblingId = *scc->physCellId; - pdsch_pdu_rel15->nrOfLayers = 1; - pdsch_pdu_rel15->transmissionScheme = 0; - pdsch_pdu_rel15->refPoint = 0; - pdsch_pdu_rel15->dmrsConfigType = dmrs_parms.dmrsConfigType; - pdsch_pdu_rel15->dlDmrsScramblingId = *scc->physCellId; - pdsch_pdu_rel15->SCID = 0; - pdsch_pdu_rel15->numDmrsCdmGrpsNoData = dmrs_parms.numDmrsCdmGrpsNoData; - pdsch_pdu_rel15->dmrsPorts = 1; - pdsch_pdu_rel15->resourceAlloc = 1; - pdsch_pdu_rel15->rbStart = rbStart; - pdsch_pdu_rel15->rbSize = rbSize; - pdsch_pdu_rel15->VRBtoPRBMapping = 0; - pdsch_pdu_rel15->StartSymbolIndex = tda_info.startSymbolIndex; - pdsch_pdu_rel15->NrOfSymbols = tda_info.nrOfSymbols; - pdsch_pdu_rel15->dlDmrsSymbPos = dmrs_parms.dl_dmrs_symb_pos; - - uint8_t tb_scaling = 0; - int R, Qm; - uint32_t TBS=0; - - while(TBS<9) { // min TBS for RAR is 9 bytes - mcsIndex++; - R = nr_get_code_rate_dl(mcsIndex, mcsTableIdx); - Qm = nr_get_Qm_dl(mcsIndex, mcsTableIdx); - TBS = nr_compute_tbs(Qm, - R, - rbSize, - tda_info.nrOfSymbols, - dmrs_parms.N_PRB_DMRS*dmrs_parms.N_DMRS_SLOT, - 0, // overhead - tb_scaling, // tb scaling - 1)>>3; // layers - - pdsch_pdu_rel15->targetCodeRate[0] = R; - pdsch_pdu_rel15->qamModOrder[0] = Qm; - pdsch_pdu_rel15->mcsIndex[0] = mcsIndex; - pdsch_pdu_rel15->TBSize[0] = TBS; - } - - pdsch_pdu_rel15->maintenance_parms_v3.tbSizeLbrmBytes = nr_compute_tbslbrm(mcsTableIdx, sc_info->dl_bw_tbslbrm, 1); - pdsch_pdu_rel15->maintenance_parms_v3.ldpcBaseGraph = get_BG(TBS<<3,R); - - // Fill PDCCH DL DCI PDU - nfapi_nr_dl_dci_pdu_t *dci_pdu = &pdcch_pdu_rel15->dci_pdu[pdcch_pdu_rel15->numDlDci]; - pdcch_pdu_rel15->numDlDci++; - dci_pdu->RNTI = ra->RA_rnti; - dci_pdu->ScramblingId = *scc->physCellId; - dci_pdu->ScramblingRNTI = 0; - dci_pdu->AggregationLevel = aggregation_level; - dci_pdu->CceIndex = CCEIndex; - dci_pdu->beta_PDCCH_1_0 = 0; - dci_pdu->powerControlOffsetSS = 1; - - dci_pdu_rel15_t dci_payload; - dci_payload.frequency_domain_assignment.val = PRBalloc_to_locationandbandwidth0(pdsch_pdu_rel15->rbSize, - pdsch_pdu_rel15->rbStart, - BWPSize); - - LOG_D(NR_MAC,"Msg2 rbSize.rbStart.BWPsize %d.%d.%ld\n",pdsch_pdu_rel15->rbSize, - pdsch_pdu_rel15->rbStart, - BWPSize); - - dci_payload.time_domain_assignment.val = time_domain_assignment; - dci_payload.vrb_to_prb_mapping.val = 0; - dci_payload.mcs = pdsch_pdu_rel15->mcsIndex[0]; - dci_payload.tb_scaling = tb_scaling; - - LOG_D(NR_MAC, - "[RAPROC] DCI type 1 payload: freq_alloc %d (%d,%d,%ld), time_alloc %d, vrb to prb %d, mcs %d tb_scaling %d \n", - dci_payload.frequency_domain_assignment.val, - pdsch_pdu_rel15->rbStart, - pdsch_pdu_rel15->rbSize, - BWPSize, - dci_payload.time_domain_assignment.val, - dci_payload.vrb_to_prb_mapping.val, - dci_payload.mcs, - dci_payload.tb_scaling); - - LOG_D(NR_MAC, - "[RAPROC] DCI params: rnti 0x%x, rnti_type %d, dci_format %d coreset params: FreqDomainResource %llx, start_symbol %d " - "n_symb %d\n", - pdcch_pdu_rel15->dci_pdu[0].RNTI, - TYPE_RA_RNTI_, - NR_DL_DCI_FORMAT_1_0, - *(unsigned long long *)pdcch_pdu_rel15->FreqDomainResource, - pdcch_pdu_rel15->StartSymbolIndex, - pdcch_pdu_rel15->DurationSymbols); - - fill_dci_pdu_rel15(sc_info, - dl_bwp, - &ra->UL_BWP, - &pdcch_pdu_rel15->dci_pdu[pdcch_pdu_rel15->numDlDci - 1], - &dci_payload, - NR_DL_DCI_FORMAT_1_0, - TYPE_RA_RNTI_, - dl_bwp->bwp_id, - ss, - coreset, - 0, // parameter not needed for DCI 1_0 - nr_mac->cset0_bwp_size); - - // DL TX request - nfapi_nr_pdu_t *tx_req = &TX_req->pdu_list[TX_req->Number_of_PDUs]; - - // Program UL processing for Msg3 - nr_get_Msg3alloc(module_idP, CC_id, scc, slotP, frameP, ra, nr_mac->tdd_beam_association); - nr_add_msg3(module_idP, CC_id, frameP, slotP, ra, (uint8_t *) &tx_req->TLVs[0].value.direct[0]); - - // Start RA contention resolution timer in Msg3 transmission slot (current slot + K2) - // 3GPP TS 38.321 Section 5.1.5 Contention Resolution - start_ra_contention_resolution_timer( - ra, - scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->ra_ContentionResolutionTimer, - *ra->UL_BWP.tdaList_Common->list.array[ra->Msg3_tda_id]->k2, - ra->UL_BWP.scs); - - if (ra->cfra) { - NR_UE_info_t *UE = find_nr_UE(&RC.nrmac[module_idP]->UE_info, ra->rnti); - if (UE) { - const NR_ServingCellConfig_t *servingCellConfig = UE->CellGroup ? UE->CellGroup->spCellConfig->spCellConfigDedicated : NULL; - uint32_t delay_ms = servingCellConfig && servingCellConfig->downlinkBWP_ToAddModList ? NR_RRC_SETUP_DELAY_MS + NR_RRC_BWP_SWITCHING_DELAY_MS : NR_RRC_SETUP_DELAY_MS; - NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; - sched_ctrl->rrc_processing_timer = (delay_ms << ra->DL_BWP.scs); - } - LOG_D(NR_MAC, "Frame %d, Subframe %d: Setting RA-Msg3 reception (CFRA) for SFN.Slot %d.%d\n", frameP, slotP, ra->Msg3_frame, ra->Msg3_slot); - } else { - LOG_D(NR_MAC, "Frame %d, Subframe %d: Setting RA-Msg3 reception (CBRA) for SFN.Slot %d.%d\n", frameP, slotP, ra->Msg3_frame, ra->Msg3_slot); - } - - T(T_GNB_MAC_DL_RAR_PDU_WITH_DATA, T_INT(module_idP), T_INT(CC_id), T_INT(ra->RA_rnti), T_INT(frameP), - T_INT(slotP), T_INT(0), T_BUFFER(&tx_req->TLVs[0].value.direct[0], tx_req->TLVs[0].length)); - - tx_req->PDU_index = pduindex; - tx_req->num_TLV = 1; - tx_req->TLVs[0].length = pdsch_pdu_rel15->TBSize[0]; - tx_req->PDU_length = compute_PDU_length(tx_req->num_TLV, pdsch_pdu_rel15->TBSize[0]); - TX_req->SFN = frameP; - TX_req->Number_of_PDUs++; - TX_req->Slot = slotP; - - // Mark the corresponding symbols RBs as used - fill_pdcch_vrb_map(nr_mac, - CC_id, - &ra->sched_pdcch, - CCEIndex, - aggregation_level); - for (int rb = 0; rb < rbSize; rb++) { - vrb_map[BWPStart + rb + rbStart] |= SL_to_bitmap(tda_info.startSymbolIndex, tda_info.nrOfSymbols); - } - - ra->ra_state = nrRA_WAIT_Msg3; - LOG_D(NR_MAC, - "[gNB %d][RAPROC] Frame %d, Subframe %d: rnti %04x RA state %s\n", - module_idP, - frameP, - slotP, - ra->rnti, - nrra_text[ra->ra_state]); + long BWPStart = 0; + long BWPSize = 0; + NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config = NULL; + if (*ss->controlResourceSetId != 0) { + BWPStart = dl_bwp->BWPStart; + BWPSize = sc_info->initial_dl_BWPSize; + } else { + type0_PDCCH_CSS_config = &nr_mac->type0_PDCCH_CSS_config[ra->beam_id]; + BWPStart = type0_PDCCH_CSS_config->cset_start_rb; + BWPSize = type0_PDCCH_CSS_config->num_rbs; } + + NR_ControlResourceSet_t *coreset = ra->coreset; + AssertFatal(coreset != NULL, "Coreset cannot be null for RA-Msg2\n"); + const int coresetid = coreset->controlResourceSetId; + // Calculate number of symbols + int time_domain_assignment = get_dl_tda(nr_mac, scc, slotP); + int mux_pattern = type0_PDCCH_CSS_config ? type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern : 1; + NR_tda_info_t tda_info = get_dl_tda_info(dl_bwp, + ss->searchSpaceType->present, + time_domain_assignment, + scc->dmrs_TypeA_Position, + mux_pattern, + TYPE_RA_RNTI_, + coresetid, + false); + + uint16_t *vrb_map = cc[CC_id].vrb_map; + for (int i = 0; (i < rbSize) && (rbStart <= (BWPSize - rbSize)); i++) { + if (vrb_map[BWPStart + rbStart + i] & SL_to_bitmap(tda_info.startSymbolIndex, tda_info.nrOfSymbols)) { + rbStart += i; + i = 0; + } + } + + if (rbStart > (BWPSize - rbSize)) { + LOG_E(NR_MAC, "%s(): cannot find free vrb_map for RA RNTI %04x!\n", __func__, ra->RA_rnti); + return; + } + + // Checking if the DCI allocation is feasible in current subframe + nfapi_nr_dl_tti_request_body_t *dl_req = &DL_req->dl_tti_request_body; + if (dl_req->nPDUs > NFAPI_NR_MAX_DL_TTI_PDUS - 2) { + LOG_I(NR_MAC, "[RAPROC] Subframe %d: FAPI DL structure is full, skip scheduling UE %d\n", slotP, ra->RA_rnti); + return; + } + + uint8_t aggregation_level; + int CCEIndex = get_cce_index(nr_mac, CC_id, slotP, 0, &aggregation_level, ss, coreset, &ra->sched_pdcch, true); + + if (CCEIndex < 0) { + LOG_E(NR_MAC, "cannot find free CCE for Msg2 of RA RNTI 0x%04x!\n", ra->rnti); + nr_clear_ra_proc(ra); + return; + } + + LOG_D(NR_MAC, "Msg2 startSymbolIndex.nrOfSymbols %d.%d\n", tda_info.startSymbolIndex, tda_info.nrOfSymbols); + + // look up the PDCCH PDU for this CC, BWP, and CORESET. If it does not exist, create it. This is especially + // important if we have multiple RAs, and the DLSCH has to reuse them, so we need to mark them + nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = nr_mac->pdcch_pdu_idx[CC_id][coresetid]; + if (!pdcch_pdu_rel15) { + nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdcch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs]; + memset(dl_tti_pdcch_pdu, 0, sizeof(nfapi_nr_dl_tti_request_pdu_t)); + dl_tti_pdcch_pdu->PDUType = NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE; + dl_tti_pdcch_pdu->PDUSize = (uint8_t)(2 + sizeof(nfapi_nr_dl_tti_pdcch_pdu)); + dl_req->nPDUs += 1; + pdcch_pdu_rel15 = &dl_tti_pdcch_pdu->pdcch_pdu.pdcch_pdu_rel15; + nr_configure_pdcch(pdcch_pdu_rel15, coreset, &ra->sched_pdcch); + nr_mac->pdcch_pdu_idx[CC_id][coresetid] = pdcch_pdu_rel15; + } + + nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdsch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs]; + memset((void *)dl_tti_pdsch_pdu, 0, sizeof(nfapi_nr_dl_tti_request_pdu_t)); + dl_tti_pdsch_pdu->PDUType = NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE; + dl_tti_pdsch_pdu->PDUSize = (uint8_t)(2 + sizeof(nfapi_nr_dl_tti_pdsch_pdu)); + dl_req->nPDUs += 1; + nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15 = &dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15; + + pdsch_pdu_rel15->precodingAndBeamforming.num_prgs = 0; + pdsch_pdu_rel15->precodingAndBeamforming.prg_size = 0; + pdsch_pdu_rel15->precodingAndBeamforming.dig_bf_interfaces = 0; + pdsch_pdu_rel15->precodingAndBeamforming.prgs_list[0].pm_idx = 0; + pdsch_pdu_rel15->precodingAndBeamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = 0; + + LOG_A(NR_MAC, + "[gNB %d][RAPROC] CC_id %d Frame %d, slotP %d: Generating RA-Msg2 DCI, rnti 0x%x, state %d, CoreSetType %d\n", + module_idP, + CC_id, + frameP, + slotP, + ra->RA_rnti, + ra->ra_state, + pdcch_pdu_rel15->CoreSetType); + + // SCF222: PDU index incremented for each PDSCH PDU sent in TX control message. This is used to associate control + // information to data and is reset every slot. + const int pduindex = nr_mac->pdu_index[CC_id]++; + uint8_t mcsTableIdx = dl_bwp->mcsTableIdx; + + NR_pdsch_dmrs_t dmrs_parms = get_dl_dmrs_params(scc, dl_bwp, &tda_info, 1); + + pdsch_pdu_rel15->pduBitmap = 0; + pdsch_pdu_rel15->rnti = ra->RA_rnti; + pdsch_pdu_rel15->pduIndex = pduindex; + pdsch_pdu_rel15->BWPSize = BWPSize; + pdsch_pdu_rel15->BWPStart = BWPStart; + pdsch_pdu_rel15->SubcarrierSpacing = dl_bwp->scs; + pdsch_pdu_rel15->CyclicPrefix = 0; + pdsch_pdu_rel15->NrOfCodewords = 1; + pdsch_pdu_rel15->mcsTable[0] = mcsTableIdx; + pdsch_pdu_rel15->rvIndex[0] = 0; + pdsch_pdu_rel15->dataScramblingId = *scc->physCellId; + pdsch_pdu_rel15->nrOfLayers = 1; + pdsch_pdu_rel15->transmissionScheme = 0; + pdsch_pdu_rel15->refPoint = 0; + pdsch_pdu_rel15->dmrsConfigType = dmrs_parms.dmrsConfigType; + pdsch_pdu_rel15->dlDmrsScramblingId = *scc->physCellId; + pdsch_pdu_rel15->SCID = 0; + pdsch_pdu_rel15->numDmrsCdmGrpsNoData = dmrs_parms.numDmrsCdmGrpsNoData; + pdsch_pdu_rel15->dmrsPorts = 1; + pdsch_pdu_rel15->resourceAlloc = 1; + pdsch_pdu_rel15->rbStart = rbStart; + pdsch_pdu_rel15->rbSize = rbSize; + pdsch_pdu_rel15->VRBtoPRBMapping = 0; + pdsch_pdu_rel15->StartSymbolIndex = tda_info.startSymbolIndex; + pdsch_pdu_rel15->NrOfSymbols = tda_info.nrOfSymbols; + pdsch_pdu_rel15->dlDmrsSymbPos = dmrs_parms.dl_dmrs_symb_pos; + + uint8_t tb_scaling = 0; + int R, Qm; + uint32_t TBS = 0; + + while (TBS < 9) { // min TBS for RAR is 9 bytes + mcsIndex++; + R = nr_get_code_rate_dl(mcsIndex, mcsTableIdx); + Qm = nr_get_Qm_dl(mcsIndex, mcsTableIdx); + TBS = nr_compute_tbs(Qm, + R, + rbSize, + tda_info.nrOfSymbols, + dmrs_parms.N_PRB_DMRS * dmrs_parms.N_DMRS_SLOT, + 0, // overhead + tb_scaling, // tb scaling + 1) + >> 3; // layers + + pdsch_pdu_rel15->targetCodeRate[0] = R; + pdsch_pdu_rel15->qamModOrder[0] = Qm; + pdsch_pdu_rel15->mcsIndex[0] = mcsIndex; + pdsch_pdu_rel15->TBSize[0] = TBS; + } + + pdsch_pdu_rel15->maintenance_parms_v3.tbSizeLbrmBytes = nr_compute_tbslbrm(mcsTableIdx, sc_info->dl_bw_tbslbrm, 1); + pdsch_pdu_rel15->maintenance_parms_v3.ldpcBaseGraph = get_BG(TBS << 3, R); + + // Fill PDCCH DL DCI PDU + nfapi_nr_dl_dci_pdu_t *dci_pdu = &pdcch_pdu_rel15->dci_pdu[pdcch_pdu_rel15->numDlDci]; + pdcch_pdu_rel15->numDlDci++; + dci_pdu->RNTI = ra->RA_rnti; + dci_pdu->ScramblingId = *scc->physCellId; + dci_pdu->ScramblingRNTI = 0; + dci_pdu->AggregationLevel = aggregation_level; + dci_pdu->CceIndex = CCEIndex; + dci_pdu->beta_PDCCH_1_0 = 0; + dci_pdu->powerControlOffsetSS = 1; + + dci_pdu_rel15_t dci_payload; + dci_payload.frequency_domain_assignment.val = + PRBalloc_to_locationandbandwidth0(pdsch_pdu_rel15->rbSize, pdsch_pdu_rel15->rbStart, BWPSize); + + LOG_D(NR_MAC, "Msg2 rbSize.rbStart.BWPsize %d.%d.%ld\n", pdsch_pdu_rel15->rbSize, pdsch_pdu_rel15->rbStart, BWPSize); + + dci_payload.time_domain_assignment.val = time_domain_assignment; + dci_payload.vrb_to_prb_mapping.val = 0; + dci_payload.mcs = pdsch_pdu_rel15->mcsIndex[0]; + dci_payload.tb_scaling = tb_scaling; + + LOG_D(NR_MAC, + "[RAPROC] DCI type 1 payload: freq_alloc %d (%d,%d,%ld), time_alloc %d, vrb to prb %d, mcs %d tb_scaling %d \n", + dci_payload.frequency_domain_assignment.val, + pdsch_pdu_rel15->rbStart, + pdsch_pdu_rel15->rbSize, + BWPSize, + dci_payload.time_domain_assignment.val, + dci_payload.vrb_to_prb_mapping.val, + dci_payload.mcs, + dci_payload.tb_scaling); + + LOG_D(NR_MAC, + "[RAPROC] DCI params: rnti 0x%x, rnti_type %d, dci_format %d coreset params: FreqDomainResource %llx, start_symbol %d " + "n_symb %d\n", + pdcch_pdu_rel15->dci_pdu[0].RNTI, + TYPE_RA_RNTI_, + NR_DL_DCI_FORMAT_1_0, + *(unsigned long long *)pdcch_pdu_rel15->FreqDomainResource, + pdcch_pdu_rel15->StartSymbolIndex, + pdcch_pdu_rel15->DurationSymbols); + + fill_dci_pdu_rel15(sc_info, + dl_bwp, + &ra->UL_BWP, + &pdcch_pdu_rel15->dci_pdu[pdcch_pdu_rel15->numDlDci - 1], + &dci_payload, + NR_DL_DCI_FORMAT_1_0, + TYPE_RA_RNTI_, + dl_bwp->bwp_id, + ss, + coreset, + 0, // parameter not needed for DCI 1_0 + nr_mac->cset0_bwp_size); + + // DL TX request + nfapi_nr_pdu_t *tx_req = &TX_req->pdu_list[TX_req->Number_of_PDUs]; + + // Program UL processing for Msg3 + nr_get_Msg3alloc(module_idP, CC_id, scc, slotP, frameP, ra, nr_mac->tdd_beam_association); + nr_add_msg3(module_idP, CC_id, frameP, slotP, ra, (uint8_t *)&tx_req->TLVs[0].value.direct[0]); + + // Start RA contention resolution timer in Msg3 transmission slot (current slot + K2) + // 3GPP TS 38.321 Section 5.1.5 Contention Resolution + start_ra_contention_resolution_timer( + ra, + scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->ra_ContentionResolutionTimer, + *ra->UL_BWP.tdaList_Common->list.array[ra->Msg3_tda_id]->k2, + ra->UL_BWP.scs); + + if (ra->cfra) { + NR_UE_info_t *UE = find_nr_UE(&RC.nrmac[module_idP]->UE_info, ra->rnti); + if (UE) { + const NR_ServingCellConfig_t *servingCellConfig = UE->CellGroup ? UE->CellGroup->spCellConfig->spCellConfigDedicated : NULL; + uint32_t delay_ms = servingCellConfig && servingCellConfig->downlinkBWP_ToAddModList + ? NR_RRC_SETUP_DELAY_MS + NR_RRC_BWP_SWITCHING_DELAY_MS + : NR_RRC_SETUP_DELAY_MS; + NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; + sched_ctrl->rrc_processing_timer = (delay_ms << ra->DL_BWP.scs); + } + LOG_D(NR_MAC, + "Frame %d, Subframe %d: Setting RA-Msg3 reception (CFRA) for SFN.Slot %d.%d\n", + frameP, + slotP, + ra->Msg3_frame, + ra->Msg3_slot); + } else { + LOG_D(NR_MAC, + "Frame %d, Subframe %d: Setting RA-Msg3 reception (CBRA) for SFN.Slot %d.%d\n", + frameP, + slotP, + ra->Msg3_frame, + ra->Msg3_slot); + } + + T(T_GNB_MAC_DL_RAR_PDU_WITH_DATA, + T_INT(module_idP), + T_INT(CC_id), + T_INT(ra->RA_rnti), + T_INT(frameP), + T_INT(slotP), + T_INT(0), + T_BUFFER(&tx_req->TLVs[0].value.direct[0], tx_req->TLVs[0].length)); + + tx_req->PDU_index = pduindex; + tx_req->num_TLV = 1; + tx_req->TLVs[0].length = pdsch_pdu_rel15->TBSize[0]; + tx_req->PDU_length = compute_PDU_length(tx_req->num_TLV, pdsch_pdu_rel15->TBSize[0]); + TX_req->SFN = frameP; + TX_req->Number_of_PDUs++; + TX_req->Slot = slotP; + + // Mark the corresponding symbols RBs as used + fill_pdcch_vrb_map(nr_mac, CC_id, &ra->sched_pdcch, CCEIndex, aggregation_level); + for (int rb = 0; rb < rbSize; rb++) { + vrb_map[BWPStart + rb + rbStart] |= SL_to_bitmap(tda_info.startSymbolIndex, tda_info.nrOfSymbols); + } + + ra->ra_state = nrRA_WAIT_Msg3; + LOG_D(NR_MAC, + "[gNB %d][RAPROC] Frame %d, Subframe %d: rnti %04x RA state %s\n", + module_idP, + frameP, + slotP, + ra->rnti, + nrra_text[ra->ra_state]); } static void prepare_dl_pdus(gNB_MAC_INST *nr_mac, From 7364d9bde71d5b55697c4c952aaf2c918514b095 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 19 Mar 2024 16:38:29 +0100 Subject: [PATCH 06/19] Move find_monitoring_periodicity_offset_common() to RA file --- openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c | 71 ------------------- openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h | 4 -- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 69 ++++++++++++++++++ 3 files changed, 69 insertions(+), 75 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c index 1980986144..176b5b8e7b 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c @@ -1676,77 +1676,6 @@ void set_monitoring_periodicity_offset(NR_SearchSpace_t *ss, } -void find_monitoring_periodicity_offset_common(NR_SearchSpace_t *ss, - uint16_t *slot_period, - uint16_t *offset) { - - switch(ss->monitoringSlotPeriodicityAndOffset->present) { - case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl1: - *slot_period = 1; - *offset = 0; - break; - case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl2: - *slot_period = 2; - *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl2; - break; - case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl4: - *slot_period = 4; - *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl4; - break; - case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl5: - *slot_period = 5; - *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl5; - break; - case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl8: - *slot_period = 8; - *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl8; - break; - case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl10: - *slot_period = 10; - *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl10; - break; - case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl16: - *slot_period = 16; - *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl16; - break; - case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl20: - *slot_period = 20; - *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl20; - break; - case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl40: - *slot_period = 40; - *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl40; - break; - case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl80: - *slot_period = 80; - *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl80; - break; - case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl160: - *slot_period = 160; - *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl160; - break; - case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl320: - *slot_period = 320; - *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl320; - break; - case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl640: - *slot_period = 640; - *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl640; - break; - case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl1280: - *slot_period = 1280; - *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl1280; - break; - case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl2560: - *slot_period = 2560; - *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl2560; - break; - default: - AssertFatal(1==0,"Invalid monitoring slot periodicity and offset value\n"); - break; - } -} - int get_nr_prach_occasion_info_from_index(uint8_t index, uint32_t pointa, uint8_t mu, diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h index 33077c6ce2..60af5706ae 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h @@ -133,10 +133,6 @@ void find_aggregation_candidates(uint8_t *aggregation_level, const NR_SearchSpace_t *ss, int maxL); -void find_monitoring_periodicity_offset_common(NR_SearchSpace_t *ss, - uint16_t *slot_period, - uint16_t *offset); - int get_nr_prach_info_from_index(uint8_t index, int frame, int slot, diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index 39940110f2..84d5bd2619 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -585,6 +585,75 @@ static const NR_RA_t *find_nr_RA_rnti(const NR_RA_t *ra_base, int ra_count, rnti return NULL; } +static void find_monitoring_periodicity_offset_common(const NR_SearchSpace_t *ss, uint16_t *slot_period, uint16_t *offset) +{ + switch (ss->monitoringSlotPeriodicityAndOffset->present) { + case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl1: + *slot_period = 1; + *offset = 0; + break; + case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl2: + *slot_period = 2; + *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl2; + break; + case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl4: + *slot_period = 4; + *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl4; + break; + case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl5: + *slot_period = 5; + *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl5; + break; + case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl8: + *slot_period = 8; + *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl8; + break; + case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl10: + *slot_period = 10; + *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl10; + break; + case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl16: + *slot_period = 16; + *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl16; + break; + case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl20: + *slot_period = 20; + *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl20; + break; + case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl40: + *slot_period = 40; + *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl40; + break; + case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl80: + *slot_period = 80; + *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl80; + break; + case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl160: + *slot_period = 160; + *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl160; + break; + case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl320: + *slot_period = 320; + *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl320; + break; + case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl640: + *slot_period = 640; + *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl640; + break; + case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl1280: + *slot_period = 1280; + *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl1280; + break; + case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl2560: + *slot_period = 2560; + *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl2560; + break; + default: + AssertFatal(1 == 0, "Invalid monitoring slot periodicity and offset value\n"); + break; + } +} + void nr_initiate_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP, From 8d37fde91fe808e8379343b6d2b75ec918e0bc94 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 19 Mar 2024 16:38:47 +0100 Subject: [PATCH 07/19] Refactor: store Msg.1 parameters in RA process - the preamble is needed to detect when we are outside of the RA window, so store it - store the rest of Msg1 variables together in struct --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 1 + openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h | 10 ++++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index 84d5bd2619..e5bca56fde 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -699,6 +699,7 @@ void nr_initiate_ra_proc(module_id_t module_idP, } ra->ra_state = nrRA_Msg2; + ra->preamble_frame = frameP; ra->preamble_slot = slotP; ra->preamble_index = preamble_index; ra->timing_offset = timing_offset; diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 479dd9dffe..e162ecbff5 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -164,8 +164,14 @@ typedef struct { RA_gNB_state_t ra_state; /// CORESET0 configured flag int coreset0_configured; + /// Frame where preamble was received + int preamble_frame; /// Slot where preamble was received uint8_t preamble_slot; + /// Received preamble_index + uint8_t preamble_index; + /// Timing offset indicated by PHY + int16_t timing_offset; /// Subframe where Msg2 is to be sent uint8_t Msg2_slot; /// Frame where Msg2 is to be sent @@ -182,12 +188,8 @@ typedef struct { rnti_t rnti; /// RA RNTI allocated from received PRACH uint16_t RA_rnti; - /// Received preamble_index - uint8_t preamble_index; /// Received UE Contention Resolution Identifier uint8_t cont_res_id[6]; - /// Timing offset indicated by PHY - int16_t timing_offset; /// Msg3 first RB int msg3_first_rb; /// Msg3 number of RB From defc97ec163b834f39e269058eea227940888bb9 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 19 Mar 2024 18:19:40 +0100 Subject: [PATCH 08/19] check Msg2 allocation frame/slot in DL scheduler Move decision of Msg2 allocation time instant from instance we receive RA indication (only containing preamble time information) to actual RA scheduler (containing current DL slot time). This has the advantage: - if Msg2 cannot be sent, we might try in a later slot - no timing-based problems were a RACH.indication FAPI message might come late, we calculate a Msg2 frame/slot, but this instant has already passed in the DL scheduler - no assumption about slot_ahead (an L1 constant) The previous code calculated and verified an SSB index; I am not sure this code is correct or used. I leave the function ssb_index_from_prach() (hence the gcc attribute), but remove any checks. Similarly, the beam association list might be wrong. I deleted the corresponding code. --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 388 +++++++----------- 1 file changed, 157 insertions(+), 231 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index e5bca56fde..68370fb8d0 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -70,6 +70,7 @@ static const uint8_t DELTA[4] = {2, 3, 4, 6}; static const float ssb_per_rach_occasion[8] = {0.125, 0.25, 0.5, 1, 2, 4, 8}; +__attribute__ ((unused)) static int16_t ssb_index_from_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP, @@ -422,124 +423,6 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP } } -static void nr_schedule_msg2(uint16_t rach_frame, - uint16_t rach_slot, - uint16_t *msg2_frame, - uint16_t *msg2_slot, - int mu, - NR_ServingCellConfigCommon_t *scc, - frame_type_t frame_type, - uint16_t monitoring_slot_period, - uint16_t monitoring_offset, - uint8_t beam_index, - uint8_t num_active_ssb, - int16_t *tdd_beam_association, - int sl_ahead) -{ - // preferentially we schedule the msg2 in the mixed slot or in the last dl slot - // if they are allowed by search space configuration - uint8_t response_window = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.ra_ResponseWindow; - uint8_t slot_window; - const int n_slots_frame = nr_slots_per_frame[mu]; - const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL; - // number of mixed slot or of last dl slot if there is no mixed slot - uint8_t last_dl_slot_period = n_slots_frame-1; - // lenght of tdd period in slots - uint8_t tdd_period_slot = n_slots_frame; - - if (tdd) { - last_dl_slot_period = tdd->nrofDownlinkSymbols == 0? (tdd->nrofDownlinkSlots-1) : tdd->nrofDownlinkSlots; - tdd_period_slot = n_slots_frame/get_nb_periods_per_frame(tdd->dl_UL_TransmissionPeriodicity); - } - else{ - if(frame_type == TDD) - AssertFatal(frame_type == FDD, "Dynamic TDD not handled yet\n"); - } - - - switch(response_window){ - case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl1: - slot_window = 1; - break; - case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl2: - slot_window = 2; - break; - case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl4: - slot_window = 4; - break; - case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl8: - slot_window = 8; - break; - case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl10: - slot_window = 10; - break; - case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl20: - slot_window = 20; - break; - case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl40: - slot_window = 40; - break; - case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl80: - slot_window = 80; - break; - default: - AssertFatal(1==0,"Invalid response window value %d\n",response_window); - } - AssertFatal(slot_window<=nr_slots_per_frame[mu],"Msg2 response window needs to be lower or equal to 10ms"); - - // slot and frame limit to transmit msg2 according to response window - uint8_t slot_limit = (rach_slot + slot_window)%nr_slots_per_frame[mu]; - uint16_t frame_limit = rach_frame + (rach_slot + slot_window)/nr_slots_per_frame[mu]; - - // computing start of next period - uint8_t start_next_period = rach_slot-(rach_slot%tdd_period_slot)+tdd_period_slot; - int eff_slot = start_next_period + last_dl_slot_period; // initializing scheduling of slot to next mixed (or last dl) slot - - // we can't schedule msg2 before sl_ahead since prach - while ((eff_slot-rach_slot)<=sl_ahead) { - eff_slot += tdd_period_slot; - } -#ifdef ENABLE_AERIAL - if (nfapi_mode > 0) { // Aerial needs slot_ahead = 0, requiring addition of another TDD period - eff_slot += tdd_period_slot; - } -#endif - int FR = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0] >= 257 ? nr_FR2 : nr_FR1; - if (FR==nr_FR2) { - int num_tdd_period = (eff_slot%nr_slots_per_frame[mu])/tdd_period_slot; - while((tdd_beam_association[num_tdd_period]!=-1)&&(tdd_beam_association[num_tdd_period]!=beam_index)) { - eff_slot += tdd_period_slot; - num_tdd_period = (eff_slot % nr_slots_per_frame[mu])/tdd_period_slot; - } - if(tdd_beam_association[num_tdd_period] == -1) - tdd_beam_association[num_tdd_period] = beam_index; - } - - *msg2_frame = rach_frame + eff_slot / nr_slots_per_frame[mu]; - *msg2_slot = eff_slot % nr_slots_per_frame[mu]; - - // go to previous slot if the current scheduled slot is beyond the response window - // and if the slot is not among the PDCCH monitored ones (38.213 10.1) - while (*msg2_frame > frame_limit - || (*msg2_frame == frame_limit && *msg2_slot > slot_limit) - || ((*msg2_frame * nr_slots_per_frame[mu] + *msg2_slot - monitoring_offset) % monitoring_slot_period != 0)) { - - if((frame_type == FDD) || ((*msg2_slot%tdd_period_slot) > 0)) { - if (*msg2_slot==0) { - (*msg2_frame)--; - *msg2_slot = nr_slots_per_frame[mu] - 1; - } - else - (*msg2_slot)--; - } - else - AssertFatal(1==0,"No available DL slot to schedule msg2 has been found"); - } - - // calculate frame number considering wrap-around - *msg2_frame = *msg2_frame % 1024; -} - static bool ra_contains_preamble(const NR_RA_t *ra, uint16_t preamble_index) { for (int j = 0; j < ra->preambles.num_preambles; j++) { @@ -585,75 +468,6 @@ static const NR_RA_t *find_nr_RA_rnti(const NR_RA_t *ra_base, int ra_count, rnti return NULL; } -static void find_monitoring_periodicity_offset_common(const NR_SearchSpace_t *ss, uint16_t *slot_period, uint16_t *offset) -{ - switch (ss->monitoringSlotPeriodicityAndOffset->present) { - case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl1: - *slot_period = 1; - *offset = 0; - break; - case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl2: - *slot_period = 2; - *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl2; - break; - case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl4: - *slot_period = 4; - *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl4; - break; - case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl5: - *slot_period = 5; - *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl5; - break; - case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl8: - *slot_period = 8; - *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl8; - break; - case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl10: - *slot_period = 10; - *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl10; - break; - case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl16: - *slot_period = 16; - *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl16; - break; - case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl20: - *slot_period = 20; - *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl20; - break; - case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl40: - *slot_period = 40; - *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl40; - break; - case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl80: - *slot_period = 80; - *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl80; - break; - case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl160: - *slot_period = 160; - *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl160; - break; - case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl320: - *slot_period = 320; - *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl320; - break; - case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl640: - *slot_period = 640; - *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl640; - break; - case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl1280: - *slot_period = 1280; - *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl1280; - break; - case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl2560: - *slot_period = 2560; - *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl2560; - break; - default: - AssertFatal(1 == 0, "Invalid monitoring slot periodicity and offset value\n"); - break; - } -} - void nr_initiate_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP, @@ -712,44 +526,6 @@ void nr_initiate_ra_proc(module_id_t module_idP, NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; configure_UE_BWP(nr_mac, scc, NULL, ra, NULL, -1, -1); - // retrieving ra pdcch monitoring period and offset - uint16_t monitoring_slot_period, monitoring_offset; - find_monitoring_periodicity_offset_common(ra->ra_ss, &monitoring_slot_period, &monitoring_offset); - - uint8_t beam_index = ssb_index_from_prach(module_idP, frameP, slotP, preamble_index, freq_index, symbol); - ra->beam_id = cc->ssb_index[beam_index]; - uint16_t msg2_frame, msg2_slot; - nr_schedule_msg2(frameP, - slotP, - &msg2_frame, - &msg2_slot, - ra->DL_BWP.scs, - scc, - cc->frame_type, - monitoring_slot_period, - monitoring_offset, - beam_index, - cc->num_active_ssb, - nr_mac->tdd_beam_association, - nr_mac->if_inst->sl_ahead); - - ra->Msg2_frame = msg2_frame; - ra->Msg2_slot = msg2_slot; - - LOG_D(NR_MAC, "%s() Msg2[%04d%d] SFN/SF:%04d%d\n", __FUNCTION__, ra->Msg2_frame, ra->Msg2_slot, frameP, slotP); - - LOG_I(NR_MAC, - "[gNB %d][RAPROC] CC_id %d Frame %d Activating Msg2 generation in frame %d, slot %d using RA rnti %x SSB, new rnti %04x " - "index %u\n", - module_idP, - CC_id, - frameP, - ra->Msg2_frame, - ra->Msg2_slot, - ra->RA_rnti, - ra->rnti, - cc->ssb_index[beam_index]); - NR_SCHED_UNLOCK(&nr_mac->sched_lock); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 0); @@ -1261,6 +1037,145 @@ static void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_f } +static void find_monitoring_periodicity_offset_common(const NR_SearchSpace_t *ss, uint16_t *slot_period, uint16_t *offset) +{ + switch (ss->monitoringSlotPeriodicityAndOffset->present) { + case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl1: + *slot_period = 1; + *offset = 0; + break; + case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl2: + *slot_period = 2; + *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl2; + break; + case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl4: + *slot_period = 4; + *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl4; + break; + case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl5: + *slot_period = 5; + *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl5; + break; + case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl8: + *slot_period = 8; + *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl8; + break; + case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl10: + *slot_period = 10; + *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl10; + break; + case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl16: + *slot_period = 16; + *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl16; + break; + case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl20: + *slot_period = 20; + *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl20; + break; + case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl40: + *slot_period = 40; + *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl40; + break; + case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl80: + *slot_period = 80; + *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl80; + break; + case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl160: + *slot_period = 160; + *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl160; + break; + case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl320: + *slot_period = 320; + *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl320; + break; + case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl640: + *slot_period = 640; + *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl640; + break; + case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl1280: + *slot_period = 1280; + *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl1280; + break; + case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl2560: + *slot_period = 2560; + *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl2560; + break; + default: + AssertFatal(1 == 0, "Invalid monitoring slot periodicity and offset value\n"); + break; + } +} + +static bool check_msg2_monitoring(const NR_RA_t *ra, int mu, int current_frame, int current_slot) +{ + int n = nr_slots_per_frame[mu]; + + // check if the slot is not among the PDCCH monitored ones (38.213 10.1) + uint16_t monitoring_slot_period, monitoring_offset; + find_monitoring_periodicity_offset_common(ra->ra_ss, &monitoring_slot_period, &monitoring_offset); + if ((current_frame * n + current_slot - monitoring_offset) % monitoring_slot_period != 0) + return false; + return true; +} + +static int get_response_window(e_NR_RACH_ConfigGeneric__ra_ResponseWindow response_window) +{ + int slots; + switch (response_window) { + case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl1: + slots = 1; + break; + case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl2: + slots = 2; + break; + case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl4: + slots = 4; + break; + case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl8: + slots = 8; + break; + case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl10: + slots = 10; + break; + case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl20: + slots = 20; + break; + case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl40: + slots = 40; + break; + case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl80: + slots = 80; + break; + default: + AssertFatal(false, "Invalid response window value %d\n", response_window); + } + return slots; +} + +static bool msg2_in_response_window(int rach_frame, int rach_slot, int mu, long rrc_ra_ResponseWindow, int current_frame, int current_slot) +{ + int window_slots = get_response_window(rrc_ra_ResponseWindow); + int n = nr_slots_per_frame[mu]; + + int abs_rach = n * rach_frame + rach_slot; + int abs_now = n * current_frame + current_slot; + int diff = (n * 1024 + abs_now - abs_rach) % (n * 1024); + + bool in_window = diff <= window_slots; + if (!in_window) { + LOG_W(NR_MAC, + "exceeded RA window: preamble at %d.%2d now %d.%d (diff %d), ra_ResponseWindow %ld/%d slots\n", + rach_frame, + rach_slot, + current_frame, + current_slot, + diff, + rrc_ra_ResponseWindow, + window_slots); + } + return in_window; +} + static void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, @@ -1270,18 +1185,30 @@ static void nr_generate_Msg2(module_id_t module_idP, nfapi_nr_tx_data_request_t *TX_req) { gNB_MAC_INST *nr_mac = RC.nrmac[module_idP]; + // no DL -> cannot send Msg2 + if (!is_xlsch_in_slot(nr_mac->dlsch_slot_bitmap[slotP / 64], slotP)) + return; + NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id]; NR_UE_DL_BWP_t *dl_bwp = &ra->DL_BWP; NR_UE_ServingCell_Info_t *sc_info = &ra->sc_info; + NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; - if (ra->Msg2_frame != frameP || ra->Msg2_slot != slotP) + long rrc_ra_ResponseWindow = + scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.ra_ResponseWindow; + if (!msg2_in_response_window(ra->preamble_frame, ra->preamble_slot, dl_bwp->scs, rrc_ra_ResponseWindow, frameP, slotP)) { + LOG_E(NR_MAC, "UE RA-RNTI %04x RNTI %04x: exceeded RA window, cannot schedule Msg2\n", ra->RA_rnti, ra->rnti); + nr_clear_ra_proc(ra); + return; + } + + if (!check_msg2_monitoring(ra, dl_bwp->scs, frameP, slotP)) return; int mcsIndex = -1; // initialization value int rbStart = 0; int rbSize = 8; - NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; NR_SearchSpace_t *ss = ra->ra_ss; long BWPStart = 0; @@ -1320,14 +1247,14 @@ static void nr_generate_Msg2(module_id_t module_idP, } if (rbStart > (BWPSize - rbSize)) { - LOG_E(NR_MAC, "%s(): cannot find free vrb_map for RA RNTI %04x!\n", __func__, ra->RA_rnti); + LOG_W(NR_MAC, "%s(): cannot find free vrb_map for RA RNTI %04x!\n", __func__, ra->RA_rnti); return; } // Checking if the DCI allocation is feasible in current subframe nfapi_nr_dl_tti_request_body_t *dl_req = &DL_req->dl_tti_request_body; if (dl_req->nPDUs > NFAPI_NR_MAX_DL_TTI_PDUS - 2) { - LOG_I(NR_MAC, "[RAPROC] Subframe %d: FAPI DL structure is full, skip scheduling UE %d\n", slotP, ra->RA_rnti); + LOG_W(NR_MAC, "[RAPROC] Subframe %d: FAPI DL structure is full, skip scheduling UE %d\n", slotP, ra->RA_rnti); return; } @@ -1335,8 +1262,7 @@ static void nr_generate_Msg2(module_id_t module_idP, int CCEIndex = get_cce_index(nr_mac, CC_id, slotP, 0, &aggregation_level, ss, coreset, &ra->sched_pdcch, true); if (CCEIndex < 0) { - LOG_E(NR_MAC, "cannot find free CCE for Msg2 of RA RNTI 0x%04x!\n", ra->rnti); - nr_clear_ra_proc(ra); + LOG_W(NR_MAC, "cannot find free CCE for Msg2 of RA RNTI 0x%04x!\n", ra->rnti); return; } From 876b2ce8f69b9aa82ac85ba77f30952345fc7373 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 20 Mar 2024 07:46:05 +0100 Subject: [PATCH 09/19] Refactor Msg3 TDA selection in own function --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 125 +++++++++--------- 1 file changed, 64 insertions(+), 61 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index 68370fb8d0..b237bfe298 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -735,6 +735,44 @@ static void nr_generate_Msg3_retransmission(module_id_t module_idP, } } +static int get_feasible_msg3_tda(frame_type_t frame_type, + int mu_delta, + uint64_t ulsch_slot_bitmap[3], + const NR_PUSCH_TimeDomainResourceAllocationList_t *tda_list, + int slots_per_frame, + int slot, + const NR_TDD_UL_DL_Pattern_t *tdd) +{ + DevAssert(tda_list != NULL); + + if (frame_type == FDD) { + int tda = 0; // the first occasion is good enough + return tda; + } + + // TDD + DevAssert(tdd != NULL); + for (int i = 0; i < tda_list->list.count; i++) { + // check if it is UL + long k2 = *tda_list->list.array[i]->k2; + int temp_slot = (slot + k2 + mu_delta) % slots_per_frame; // msg3 slot according to 8.3 in 38.213 + if (!is_xlsch_in_slot(ulsch_slot_bitmap[temp_slot / 64], temp_slot)) + continue; + + // check if enough symbols in case of mixed slot + bool has_mixed = tdd->nrofUplinkSymbols != 0 || tdd->nrofDownlinkSymbols != 0; + // is in mixed slot with less than 3 symbols? + if (has_mixed && temp_slot == tdd->nrofDownlinkSlots && tdd->nrofUplinkSymbols < 3) + continue; + + // is in mixed slot with more or equal than 3 symbols, or UL slot + int tda = i; + return tda; + } + + return -1; // invalid +} + static void nr_get_Msg3alloc(module_id_t module_id, int CC_id, NR_ServingCellConfigCommon_t *scc, @@ -752,66 +790,26 @@ static void nr_get_Msg3alloc(module_id_t module_id, NR_UE_UL_BWP_t *ul_bwp = &ra->UL_BWP; NR_UE_ServingCell_Info_t *sc_info = &ra->sc_info; - int mu = ul_bwp->scs; - int StartSymbolIndex = 0; - int NrOfSymbols = 0; - int startSymbolAndLength = 0; - int abs_slot = 0; - int Msg3maxsymb = 14, Msg3start = 0; - ra->Msg3_tda_id = 16; // initialization to a value above limit - - NR_PUSCH_TimeDomainResourceAllocationList_t *pusch_TimeDomainAllocationList = ul_bwp->tdaList_Common; - + const NR_PUSCH_TimeDomainResourceAllocationList_t *pusch_TimeDomainAllocationList = ul_bwp->tdaList_Common; const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL; + int mu = ul_bwp->scs; const int n_slots_frame = nr_slots_per_frame[mu]; - uint8_t k2 = 0; - if (frame_type == TDD) { - int msg3_slot = get_first_ul_slot(tdd->nrofDownlinkSlots, tdd->nrofDownlinkSymbols, tdd->nrofUplinkSymbols); - if (tdd->nrofUplinkSymbols != 0) { - if (tdd->nrofUplinkSymbols < 3) - msg3_slot++; // we can't trasmit msg3 in mixed slot if there are less than 3 symbols - else { - Msg3maxsymb = tdd->nrofUplinkSymbols; - Msg3start = 14 - tdd->nrofUplinkSymbols; - } - } - const int nb_periods_per_frame = get_nb_periods_per_frame(tdd->dl_UL_TransmissionPeriodicity); - const int nb_slots_per_period = ((1<list.count; i++) { - startSymbolAndLength = pusch_TimeDomainAllocationList->list.array[i]->startSymbolAndLength; - SLIV2SL(startSymbolAndLength, &StartSymbolIndex, &NrOfSymbols); - k2 = *pusch_TimeDomainAllocationList->list.array[i]->k2; - LOG_D(NR_MAC,"Checking Msg3 TDA %d for Msg3_slot %d Msg3_start %d Msg3_nsymb %d: k2 %d, sliv %d,S %d L %d\n", - i, msg3_slot, Msg3start, Msg3maxsymb, (int)k2, (int)pusch_TimeDomainAllocationList->list.array[i]->startSymbolAndLength, StartSymbolIndex, NrOfSymbols); - // we want to transmit in the uplink symbols of mixed slot or the first uplink slot - abs_slot = (current_slot + k2 + DELTA[mu]); - int temp_slot = abs_slot % nr_slots_per_frame[mu]; // msg3 slot according to 8.3 in 38.213 - if ((temp_slot % nb_slots_per_period) == msg3_slot && - is_xlsch_in_slot(mac->ulsch_slot_bitmap[temp_slot / 64], temp_slot) && - StartSymbolIndex == Msg3start && - NrOfSymbols <= Msg3maxsymb) { - ra->Msg3_tda_id = i; - ra->msg3_startsymb = StartSymbolIndex; - ra->msg3_nbSymb = NrOfSymbols; - ra->Msg3_slot = temp_slot; - break; - } - } - AssertFatal(ra->Msg3_tda_id < 16, "Couldn't find an appropriate TD allocation for Msg3\n"); - } - else { - ra->Msg3_tda_id = 0; - k2 = *pusch_TimeDomainAllocationList->list.array[0]->k2; - abs_slot = current_slot + k2 + DELTA[mu]; // msg3 slot according to 8.3 in 38.213 - ra->Msg3_slot = abs_slot % nr_slots_per_frame[mu]; - } + ra->Msg3_tda_id = get_feasible_msg3_tda(frame_type, + DELTA[mu], + mac->ulsch_slot_bitmap, + pusch_TimeDomainAllocationList, + n_slots_frame, + current_slot, + tdd); + DevAssert(ra->Msg3_tda_id >= 0 && ra->Msg3_tda_id < 16); - AssertFatal(ra->Msg3_tda_id<16,"Unable to find Msg3 time domain allocation in list\n"); + int startSymbolAndLength = pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->startSymbolAndLength; + SLIV2SL(startSymbolAndLength, &ra->msg3_startsymb, &ra->msg3_nbSymb); - if (n_slots_frame > abs_slot) - ra->Msg3_frame = current_frame; - else - ra->Msg3_frame = (current_frame + (abs_slot / n_slots_frame)) % 1024; + long k2 = *pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->k2; + int abs_slot = current_slot + k2 + DELTA[mu]; + ra->Msg3_slot = abs_slot % n_slots_frame; + ra->Msg3_frame = (current_frame + (abs_slot / n_slots_frame)) % 1024; // beam association for FR2 if (*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0] >= 257) { @@ -824,7 +822,14 @@ static void nr_get_Msg3alloc(module_id_t module_id, tdd_beam_association[num_tdd_period] = ra->beam_id; } - LOG_I(NR_MAC, "[RAPROC] Msg3 slot %d: current slot %u Msg3 frame %u k2 %u Msg3_tda_id %u\n", ra->Msg3_slot, current_slot, ra->Msg3_frame, k2,ra->Msg3_tda_id); + LOG_I(NR_MAC, + "[RAPROC] Msg3 scheduled at %d.%d (%d.%d k2 %ld TDA %u)\n", + ra->Msg3_frame, + ra->Msg3_slot, + current_frame, + current_slot, + k2, + ra->Msg3_tda_id); const int buffer_index = ul_buffer_index(ra->Msg3_frame, ra->Msg3_slot, mu, mac->vrb_map_UL_size); uint16_t *vrb_map_UL = &mac->common_channels[CC_id].vrb_map_UL[buffer_index * MAX_BWP_SIZE]; @@ -843,13 +848,11 @@ static void nr_get_Msg3alloc(module_id_t module_id, while (rbSize < msg3_nb_rb) { rbStart += rbSize; /* last iteration rbSize was not enough, skip it */ rbSize = 0; - while (rbStart < bwpSize && - (vrb_map_UL[rbStart + bwpStart]&SL_to_bitmap(StartSymbolIndex, NrOfSymbols))) + while (rbStart < bwpSize && (vrb_map_UL[rbStart + bwpStart] & SL_to_bitmap(ra->msg3_startsymb, ra->msg3_nbSymb))) rbStart++; AssertFatal(rbStart < bwpSize - msg3_nb_rb, "no space to allocate Msg 3 for RA!\n"); while (rbStart + rbSize < bwpSize - && !(vrb_map_UL[rbStart + bwpStart + rbSize]&SL_to_bitmap(StartSymbolIndex, NrOfSymbols)) - && rbSize < msg3_nb_rb) + && !(vrb_map_UL[rbStart + bwpStart + rbSize] & SL_to_bitmap(ra->msg3_startsymb, ra->msg3_nbSymb)) && rbSize < msg3_nb_rb) rbSize++; } ra->msg3_nb_rb = msg3_nb_rb; From d534e444f0094bb922b165b9091b23224778d718 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 20 Mar 2024 10:07:31 +0100 Subject: [PATCH 10/19] Check Msg3 TDA before committing to Msg2 allocation --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index b237bfe298..87adc21112 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -782,26 +782,17 @@ static void nr_get_Msg3alloc(module_id_t module_id, int16_t *tdd_beam_association) { // msg3 is scheduled in mixed slot in the following TDD period + DevAssert(ra->Msg3_tda_id >= 0 && ra->Msg3_tda_id < 16); uint16_t msg3_nb_rb = 8; // sdu has 6 or 8 bytes gNB_MAC_INST *mac = RC.nrmac[module_id]; - frame_type_t frame_type = mac->common_channels->frame_type; NR_UE_UL_BWP_t *ul_bwp = &ra->UL_BWP; NR_UE_ServingCell_Info_t *sc_info = &ra->sc_info; const NR_PUSCH_TimeDomainResourceAllocationList_t *pusch_TimeDomainAllocationList = ul_bwp->tdaList_Common; - const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL; int mu = ul_bwp->scs; const int n_slots_frame = nr_slots_per_frame[mu]; - ra->Msg3_tda_id = get_feasible_msg3_tda(frame_type, - DELTA[mu], - mac->ulsch_slot_bitmap, - pusch_TimeDomainAllocationList, - n_slots_frame, - current_slot, - tdd); - DevAssert(ra->Msg3_tda_id >= 0 && ra->Msg3_tda_id < 16); int startSymbolAndLength = pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->startSymbolAndLength; SLIV2SL(startSymbolAndLength, &ra->msg3_startsymb, &ra->msg3_nbSymb); @@ -813,6 +804,7 @@ static void nr_get_Msg3alloc(module_id_t module_id, // beam association for FR2 if (*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0] >= 257) { + const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL; AssertFatal(tdd,"Dynamic TDD not handled yet\n"); uint8_t tdd_period_slot = n_slots_frame/get_nb_periods_per_frame(tdd->dl_UL_TransmissionPeriodicity); int num_tdd_period = ra->Msg3_slot/tdd_period_slot; @@ -1208,6 +1200,20 @@ static void nr_generate_Msg2(module_id_t module_idP, if (!check_msg2_monitoring(ra, dl_bwp->scs, frameP, slotP)) return; + const NR_UE_UL_BWP_t *ul_bwp = &ra->UL_BWP; + const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL; + ra->Msg3_tda_id = get_feasible_msg3_tda(cc->frame_type, + DELTA[ul_bwp->scs], + nr_mac->ulsch_slot_bitmap, + ul_bwp->tdaList_Common, + nr_slots_per_frame[ul_bwp->scs], + slotP, + tdd); + if (ra->Msg3_tda_id < 0 || ra->Msg3_tda_id > 15) { + LOG_W(NR_MAC, "UE RNTI %04x %d.%d: infeasible Msg3 TDA\n", ra->rnti, frameP, slotP); + return; + } + int mcsIndex = -1; // initialization value int rbStart = 0; int rbSize = 8; From ca1ca5f5afa256eabe9c0b23b3d6bd6e7caca4fb Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 27 Mar 2024 17:14:55 +0100 Subject: [PATCH 11/19] Check beam before allocating Msg2/harmonize with Msg3 retx --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 46 +++++++++---------- 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index 87adc21112..7c3d6eae3e 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -70,7 +70,6 @@ static const uint8_t DELTA[4] = {2, 3, 4, 6}; static const float ssb_per_rach_occasion[8] = {0.125, 0.25, 0.5, 1, 2, 4, 8}; -__attribute__ ((unused)) static int16_t ssb_index_from_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP, @@ -526,6 +525,9 @@ void nr_initiate_ra_proc(module_id_t module_idP, NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; configure_UE_BWP(nr_mac, scc, NULL, ra, NULL, -1, -1); + uint8_t beam_index = ssb_index_from_prach(module_idP, frameP, slotP, preamble_index, freq_index, symbol); + ra->beam_id = cc->ssb_index[beam_index]; + NR_SCHED_UNLOCK(&nr_mac->sched_lock); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 0); @@ -546,6 +548,20 @@ static void start_ra_contention_resolution_timer(NR_RA_t *ra, const long ra_Cont ra->contention_resolution_timer); } +static bool beam_is_active(const NR_TDD_UL_DL_Pattern_t *tdd, int mu, const int16_t *tdd_beam_association, int slot, int16_t ra_beam) +{ + if (tdd_beam_association == NULL) // no beams configured + return true; + DevAssert(tdd != NULL); + + const int n_slots_frame = nr_slots_per_frame[mu]; + uint8_t tdd_period_slot = n_slots_frame/get_nb_periods_per_frame(tdd->dl_UL_TransmissionPeriodicity); + int num_tdd_period = slot / tdd_period_slot; + int16_t current_beam = tdd_beam_association[num_tdd_period]; + return current_beam == -1 /* no beams */ + || current_beam == ra_beam; +} + static void nr_generate_Msg3_retransmission(module_id_t module_idP, int CC_id, frame_t frame, @@ -567,19 +583,11 @@ static void nr_generate_Msg3_retransmission(module_id_t module_idP, if (is_xlsch_in_slot(nr_mac->ulsch_slot_bitmap[sched_slot / 64], sched_slot)) { // beam association for FR2 - int16_t *tdd_beam_association = nr_mac->tdd_beam_association; if (*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0] >= 257) { // FR2 - const int n_slots_frame = nr_slots_per_frame[mu]; const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL; - AssertFatal(tdd,"Dynamic TDD not handled yet\n"); - uint8_t tdd_period_slot = n_slots_frame/get_nb_periods_per_frame(tdd->dl_UL_TransmissionPeriodicity); - int num_tdd_period = sched_slot/tdd_period_slot; - - if((tdd_beam_association[num_tdd_period]!=-1)&&(tdd_beam_association[num_tdd_period]!=ra->beam_id)) - return; // can't schedule retransmission in this slot - else - tdd_beam_association[num_tdd_period] = ra->beam_id; + if (!beam_is_active(tdd, mu, nr_mac->tdd_beam_association, sched_slot, ra->beam_id)) + return; } int fh = 0; @@ -802,18 +810,6 @@ static void nr_get_Msg3alloc(module_id_t module_id, ra->Msg3_slot = abs_slot % n_slots_frame; ra->Msg3_frame = (current_frame + (abs_slot / n_slots_frame)) % 1024; - // beam association for FR2 - if (*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0] >= 257) { - const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL; - AssertFatal(tdd,"Dynamic TDD not handled yet\n"); - uint8_t tdd_period_slot = n_slots_frame/get_nb_periods_per_frame(tdd->dl_UL_TransmissionPeriodicity); - int num_tdd_period = ra->Msg3_slot/tdd_period_slot; - if((tdd_beam_association[num_tdd_period]!=-1)&&(tdd_beam_association[num_tdd_period]!=ra->beam_id)) - AssertFatal(1==0,"Cannot schedule MSG3\n"); - else - tdd_beam_association[num_tdd_period] = ra->beam_id; - } - LOG_I(NR_MAC, "[RAPROC] Msg3 scheduled at %d.%d (%d.%d k2 %ld TDA %u)\n", ra->Msg3_frame, @@ -1199,9 +1195,11 @@ static void nr_generate_Msg2(module_id_t module_idP, if (!check_msg2_monitoring(ra, dl_bwp->scs, frameP, slotP)) return; - const NR_UE_UL_BWP_t *ul_bwp = &ra->UL_BWP; const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL; + if (!beam_is_active(tdd, ul_bwp->scs, nr_mac->tdd_beam_association, slotP, ra->beam_id)) + return; + ra->Msg3_tda_id = get_feasible_msg3_tda(cc->frame_type, DELTA[ul_bwp->scs], nr_mac->ulsch_slot_bitmap, From b63762f9fef87384f0146682884c82ba02bf54f4 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 20 Mar 2024 10:42:59 +0100 Subject: [PATCH 12/19] Improve RA logs --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 94 +++++++++---------- 1 file changed, 45 insertions(+), 49 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index 7c3d6eae3e..fd8f837c85 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -504,7 +504,7 @@ void nr_initiate_ra_proc(module_id_t module_idP, loop++; } while (loop < 100 && (exist_connected_ue || exist_in_pending_ra_ue) ); if (loop == 100) { - LOG_E(NR_MAC, "[RAPROC] initialisation random access: no more available RNTIs for new UE\n"); + LOG_E(NR_MAC, "initialisation random access: no more available RNTIs for new UE\n"); NR_SCHED_UNLOCK(&nr_mac->sched_lock); return; } @@ -519,7 +519,7 @@ void nr_initiate_ra_proc(module_id_t module_idP, uint8_t ul_carrier_id = 0; // 0 for NUL 1 for SUL ra->RA_rnti = nr_get_ra_rnti(symbol, slotP, freq_index, ul_carrier_id); int index = ra - cc->ra; - LOG_I(NR_MAC, "%d.%d UE RA-RNTI %04x RNTI %04x: Activating RA process index %d\n", frameP, slotP, ra->RA_rnti, ra->rnti, index); + LOG_I(NR_MAC, "%d.%d UE RA-RNTI %04x TC-RNTI %04x: Activating RA process index %d\n", frameP, slotP, ra->RA_rnti, ra->rnti, index); // Configure RA BWP NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; @@ -676,7 +676,7 @@ static void nr_generate_Msg3_retransmission(module_id_t module_idP, &ra->sched_pdcch, true); if (CCEIndex < 0) { - LOG_E(NR_MAC, "%s(): cannot find free CCE for RA RNTI 0x%04x!\n", __func__, ra->rnti); + LOG_E(NR_MAC, "UE %04x cannot find free CCE!\n", ra->rnti); return; } @@ -811,7 +811,8 @@ static void nr_get_Msg3alloc(module_id_t module_id, ra->Msg3_frame = (current_frame + (abs_slot / n_slots_frame)) % 1024; LOG_I(NR_MAC, - "[RAPROC] Msg3 scheduled at %d.%d (%d.%d k2 %ld TDA %u)\n", + "UE %04x: Msg3 scheduled at %d.%d (%d.%d k2 %ld TDA %u)\n", + ra->rnti, ra->Msg3_frame, ra->Msg3_slot, current_frame, @@ -984,7 +985,7 @@ static void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_f vrb_map_UL[i + ra->msg3_first_rb + ra->msg3_bwp_start] |= mask; } - LOG_D(NR_MAC, "[gNB %d][RAPROC] Frame %d, Slot %d : CC_id %d RA is active, Msg3 in (%d,%d)\n", module_idP, frameP, slotP, CC_id, ra->Msg3_frame, ra->Msg3_slot); + LOG_D(NR_MAC, "UE %04x: %d.%d RA is active, Msg3 in (%d,%d)\n", ra->rnti, frameP, slotP, ra->Msg3_frame, ra->Msg3_slot); buffer_index = ul_buffer_index(ra->Msg3_frame, ra->Msg3_slot, scs, mac->UL_tti_req_ahead_size); nfapi_nr_ul_tti_request_t *future_ul_tti_req = &RC.nrmac[module_idP]->UL_tti_req_ahead[CC_id][buffer_index]; AssertFatal(future_ul_tti_req->SFN == ra->Msg3_frame @@ -1004,15 +1005,16 @@ static void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_f const int startSymbolAndLength = ul_bwp->tdaList_Common->list.array[ra->Msg3_tda_id]->startSymbolAndLength; const int mappingtype = ul_bwp->tdaList_Common->list.array[ra->Msg3_tda_id]->mappingType; - LOG_D(NR_MAC, "Frame %d, Slot %d Adding Msg3 UL Config Request for (%d,%d) : (%d,%d,%d) for rnti: %d\n", - frameP, - slotP, - ra->Msg3_frame, - ra->Msg3_slot, - ra->msg3_nb_rb, - ra->msg3_first_rb, - ra->msg3_round, - ra->rnti); + LOG_D(NR_MAC, + "UE %04x: %d.%d Adding Msg3 UL Config Request for (%d,%d) : (%d,%d,%d)\n", + ra->rnti, + frameP, + slotP, + ra->Msg3_frame, + ra->Msg3_slot, + ra->msg3_nb_rb, + ra->msg3_first_rb, + ra->msg3_round); fill_msg3_pusch_pdu(pusch_pdu,scc, ra->msg3_round, @@ -1176,9 +1178,11 @@ static void nr_generate_Msg2(module_id_t module_idP, nfapi_nr_tx_data_request_t *TX_req) { gNB_MAC_INST *nr_mac = RC.nrmac[module_idP]; + // no DL -> cannot send Msg2 - if (!is_xlsch_in_slot(nr_mac->dlsch_slot_bitmap[slotP / 64], slotP)) + if (!is_xlsch_in_slot(nr_mac->dlsch_slot_bitmap[slotP / 64], slotP)) { return; + } NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id]; NR_UE_DL_BWP_t *dl_bwp = &ra->DL_BWP; @@ -1188,17 +1192,21 @@ static void nr_generate_Msg2(module_id_t module_idP, long rrc_ra_ResponseWindow = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.ra_ResponseWindow; if (!msg2_in_response_window(ra->preamble_frame, ra->preamble_slot, dl_bwp->scs, rrc_ra_ResponseWindow, frameP, slotP)) { - LOG_E(NR_MAC, "UE RA-RNTI %04x RNTI %04x: exceeded RA window, cannot schedule Msg2\n", ra->RA_rnti, ra->rnti); + LOG_E(NR_MAC, "UE RA-RNTI %04x TC-RNTI %04x: exceeded RA window, cannot schedule Msg2\n", ra->RA_rnti, ra->rnti); nr_clear_ra_proc(ra); return; } - if (!check_msg2_monitoring(ra, dl_bwp->scs, frameP, slotP)) + if (!check_msg2_monitoring(ra, dl_bwp->scs, frameP, slotP)) { + LOG_E(NR_MAC, "UE RA-RNTI %04x TC-RNTI %04x: Msg2 not monitored by UE\n", ra->RA_rnti, ra->rnti); return; + } const NR_UE_UL_BWP_t *ul_bwp = &ra->UL_BWP; const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL; - if (!beam_is_active(tdd, ul_bwp->scs, nr_mac->tdd_beam_association, slotP, ra->beam_id)) + if (!beam_is_active(tdd, ul_bwp->scs, nr_mac->tdd_beam_association, slotP, ra->beam_id)) { + LOG_I(NR_MAC, "UE RA-RNTI %04x TC-RNTI %04x: beam %d inactive\n", ra->RA_rnti, ra->rnti, ra->beam_id); return; + } ra->Msg3_tda_id = get_feasible_msg3_tda(cc->frame_type, DELTA[ul_bwp->scs], @@ -1261,7 +1269,7 @@ static void nr_generate_Msg2(module_id_t module_idP, // Checking if the DCI allocation is feasible in current subframe nfapi_nr_dl_tti_request_body_t *dl_req = &DL_req->dl_tti_request_body; if (dl_req->nPDUs > NFAPI_NR_MAX_DL_TTI_PDUS - 2) { - LOG_W(NR_MAC, "[RAPROC] Subframe %d: FAPI DL structure is full, skip scheduling UE %d\n", slotP, ra->RA_rnti); + LOG_W(NR_MAC, "UE %04x: %d.%d FAPI DL structure is full\n", ra->rnti, frameP, slotP); return; } @@ -1269,7 +1277,7 @@ static void nr_generate_Msg2(module_id_t module_idP, int CCEIndex = get_cce_index(nr_mac, CC_id, slotP, 0, &aggregation_level, ss, coreset, &ra->sched_pdcch, true); if (CCEIndex < 0) { - LOG_W(NR_MAC, "cannot find free CCE for Msg2 of RA RNTI 0x%04x!\n", ra->rnti); + LOG_W(NR_MAC, "UE %04x: %d.%d cannot find free CCE for Msg2!\n", ra->rnti, frameP, slotP); return; } @@ -1303,9 +1311,8 @@ static void nr_generate_Msg2(module_id_t module_idP, pdsch_pdu_rel15->precodingAndBeamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = 0; LOG_A(NR_MAC, - "[gNB %d][RAPROC] CC_id %d Frame %d, slotP %d: Generating RA-Msg2 DCI, rnti 0x%x, state %d, CoreSetType %d\n", - module_idP, - CC_id, + "UE %04x: %d.%d Generating RA-Msg2 DCI, RA RNTI 0x%x, state %d, CoreSetType %d\n", + ra->rnti, frameP, slotP, ra->RA_rnti, @@ -1396,7 +1403,7 @@ static void nr_generate_Msg2(module_id_t module_idP, dci_payload.tb_scaling = tb_scaling; LOG_D(NR_MAC, - "[RAPROC] DCI type 1 payload: freq_alloc %d (%d,%d,%ld), time_alloc %d, vrb to prb %d, mcs %d tb_scaling %d \n", + "DCI type 1 payload: freq_alloc %d (%d,%d,%ld), time_alloc %d, vrb to prb %d, mcs %d tb_scaling %d \n", dci_payload.frequency_domain_assignment.val, pdsch_pdu_rel15->rbStart, pdsch_pdu_rel15->rbSize, @@ -1407,7 +1414,7 @@ static void nr_generate_Msg2(module_id_t module_idP, dci_payload.tb_scaling); LOG_D(NR_MAC, - "[RAPROC] DCI params: rnti 0x%x, rnti_type %d, dci_format %d coreset params: FreqDomainResource %llx, start_symbol %d " + "DCI params: rnti 0x%x, rnti_type %d, dci_format %d coreset params: FreqDomainResource %llx, start_symbol %d " "n_symb %d\n", pdcch_pdu_rel15->dci_pdu[0].RNTI, TYPE_RA_RNTI_, @@ -1454,21 +1461,17 @@ static void nr_generate_Msg2(module_id_t module_idP, NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; sched_ctrl->rrc_processing_timer = (delay_ms << ra->DL_BWP.scs); } - LOG_D(NR_MAC, - "Frame %d, Subframe %d: Setting RA-Msg3 reception (CFRA) for SFN.Slot %d.%d\n", - frameP, - slotP, - ra->Msg3_frame, - ra->Msg3_slot); - } else { - LOG_D(NR_MAC, - "Frame %d, Subframe %d: Setting RA-Msg3 reception (CBRA) for SFN.Slot %d.%d\n", - frameP, - slotP, - ra->Msg3_frame, - ra->Msg3_slot); } + LOG_D(NR_MAC, + "UE %04x: %d.%d: Setting RA-Msg3 reception (%s) for SFN.Slot %d.%d\n", + ra->rnti, + frameP, + slotP, + ra->cfra ? "CFRA" : "CBRA", + ra->Msg3_frame, + ra->Msg3_slot); + T(T_GNB_MAC_DL_RAR_PDU_WITH_DATA, T_INT(module_idP), T_INT(CC_id), @@ -1493,13 +1496,6 @@ static void nr_generate_Msg2(module_id_t module_idP, } ra->ra_state = nrRA_WAIT_Msg3; - LOG_D(NR_MAC, - "[gNB %d][RAPROC] Frame %d, Subframe %d: rnti %04x RA state %s\n", - module_idP, - frameP, - slotP, - ra->rnti, - nrra_text[ra->ra_state]); } static void prepare_dl_pdus(gNB_MAC_INST *nr_mac, @@ -1641,7 +1637,7 @@ static void prepare_dl_pdus(gNB_MAC_INST *nr_mac, dci_payload.pdsch_to_harq_feedback_timing_indicator.val = pucch ? pucch->timing_indicator : 0; LOG_D(NR_MAC, - "[RAPROC] DCI 1_0 payload: freq_alloc %d (%d,%d,%d), time_alloc %d, vrb to prb %d, mcs %d tb_scaling %d pucchres %d harqtiming %d\n", + "DCI 1_0 payload: freq_alloc %d (%d,%d,%d), time_alloc %d, vrb to prb %d, mcs %d tb_scaling %d pucchres %d harqtiming %d\n", dci_payload.frequency_domain_assignment.val, pdsch_pdu_rel15->rbStart, pdsch_pdu_rel15->rbSize, @@ -1654,7 +1650,7 @@ static void prepare_dl_pdus(gNB_MAC_INST *nr_mac, dci_payload.pdsch_to_harq_feedback_timing_indicator.val); LOG_D(NR_MAC, - "[RAPROC] DCI params: rnti 0x%x, rnti_type %d, dci_format %d coreset params: FreqDomainResource %llx, start_symbol %d " + "DCI params: rnti 0x%x, rnti_type %d, dci_format %d coreset params: FreqDomainResource %llx, start_symbol %d " "n_symb %d, BWPsize %d\n", pdcch_pdu_rel15->dci_pdu[0].RNTI, TYPE_TC_RNTI_, @@ -1774,7 +1770,7 @@ static void nr_generate_Msg4(module_id_t module_idP, // Checking if the DCI allocation is feasible in current subframe nfapi_nr_dl_tti_request_body_t *dl_req = &DL_req->dl_tti_request_body; if (dl_req->nPDUs > NFAPI_NR_MAX_DL_TTI_PDUS - 2) { - LOG_I(NR_MAC, "[RAPROC] Subframe %d: FAPI DL structure is full, skip scheduling UE %d\n", slotP, ra->rnti); + LOG_I(NR_MAC, "UE %04x: %d.%d FAPI DL structure is full\n", ra->rnti, frameP, slotP); return; } @@ -1844,7 +1840,7 @@ static void nr_generate_Msg4(module_id_t module_idP, const int delta_PRI = 0; int r_pucch = nr_get_pucch_resource(coreset, ra->UL_BWP.pucch_Config, CCEIndex); - LOG_D(NR_MAC,"[RAPROC] Msg4 r_pucch %d (CCEIndex %d, delta_PRI %d)\n", r_pucch, CCEIndex, delta_PRI); + LOG_D(NR_MAC, "Msg4 r_pucch %d (CCEIndex %d, delta_PRI %d)\n", r_pucch, CCEIndex, delta_PRI); int alloc = nr_acknack_scheduling(nr_mac, UE, frameP, slotP, r_pucch, 1); if (alloc < 0) { From 0716d1d6c04ef39a71b043aa09f896632b150320 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 28 Mar 2024 19:31:06 +0100 Subject: [PATCH 13/19] gNB: Msg2: print used RAPID --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index fd8f837c85..0799dcf7a3 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -1311,13 +1311,14 @@ static void nr_generate_Msg2(module_id_t module_idP, pdsch_pdu_rel15->precodingAndBeamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = 0; LOG_A(NR_MAC, - "UE %04x: %d.%d Generating RA-Msg2 DCI, RA RNTI 0x%x, state %d, CoreSetType %d\n", + "UE %04x: %d.%d Generating RA-Msg2 DCI, RA RNTI 0x%x, state %d, CoreSetType %d, RAPID %d\n", ra->rnti, frameP, slotP, ra->RA_rnti, ra->ra_state, - pdcch_pdu_rel15->CoreSetType); + pdcch_pdu_rel15->CoreSetType, + ra->preamble_index); // SCF222: PDU index incremented for each PDSCH PDU sent in TX control message. This is used to associate control // information to data and is reset every slot. From c9f58179e4f2a97334592f141bb5c516766fc248 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 20 Mar 2024 10:46:53 +0100 Subject: [PATCH 14/19] Improve Preamble detection log and reformat code --- openair1/SCHED_NR/nr_prach_procedures.c | 70 ++++++++++++++----------- 1 file changed, 38 insertions(+), 32 deletions(-) diff --git a/openair1/SCHED_NR/nr_prach_procedures.c b/openair1/SCHED_NR/nr_prach_procedures.c index ce79cec448..f1d09f0b18 100644 --- a/openair1/SCHED_NR/nr_prach_procedures.c +++ b/openair1/SCHED_NR/nr_prach_procedures.c @@ -152,38 +152,44 @@ void L1_nr_prach_procedures(PHY_VARS_gNB *gNB,int frame,int slot) { gNB->prach_energy_counter); if ((gNB->prach_energy_counter == 100) && (max_preamble_energy[0] > gNB->measurements.prach_I0+gNB->prach_thres)) { - - LOG_I(NR_PHY,"[gNB %d][RAPROC] Frame %d, slot %d Initiating RA procedure with preamble %d, energy %d.%d dB (I0 %d, thres %d), delay %d start symbol %u freq index %u\n", - gNB->Mod_id, - frame, - slot, - max_preamble[0], - max_preamble_energy[0]/10, - max_preamble_energy[0]%10, - gNB->measurements.prach_I0,gNB->prach_thres, - max_preamble_delay[0], - prachStartSymbol, - prach_pdu->num_ra); - - T(T_ENB_PHY_INITIATE_RA_PROCEDURE, T_INT(gNB->Mod_id), T_INT(frame), T_INT(slot), - T_INT(max_preamble[0]), T_INT(max_preamble_energy[0]), T_INT(max_preamble_delay[0])); - - - gNB->UL_INFO.rach_ind.number_of_pdus += 1; - - gNB->prach_pdu_indication_list[pdu_index].phy_cell_id = gNB->gNB_config.cell_config.phy_cell_id.value; - gNB->prach_pdu_indication_list[pdu_index].symbol_index = prachStartSymbol; - gNB->prach_pdu_indication_list[pdu_index].slot_index = slot; - gNB->prach_pdu_indication_list[pdu_index].freq_index = prach_pdu->num_ra; - gNB->prach_pdu_indication_list[pdu_index].avg_rssi = (max_preamble_energy[0]<631) ? (128+(max_preamble_energy[0]/5)) : 254; - gNB->prach_pdu_indication_list[pdu_index].avg_snr = 0xff; // invalid for now - - gNB->prach_pdu_indication_list[pdu_index].num_preamble = 1; - gNB->prach_pdu_indication_list[pdu_index].preamble_list = gNB->preamble_list; - gNB->prach_pdu_indication_list[pdu_index].preamble_list[0].preamble_index = max_preamble[0]; - gNB->prach_pdu_indication_list[pdu_index].preamble_list[0].timing_advance = max_preamble_delay[0]; - gNB->prach_pdu_indication_list[pdu_index].preamble_list[0].preamble_pwr = 0xffffffff; - pdu_index++; + LOG_I(NR_PHY, + "[RAPROC] %d.%d Initiating RA procedure with preamble %d, energy %d.%d dB (I0 %d, thres %d), delay %d start symbol " + "%u freq index %u\n", + frame, + slot, + max_preamble[0], + max_preamble_energy[0] / 10, + max_preamble_energy[0] % 10, + gNB->measurements.prach_I0, + gNB->prach_thres, + max_preamble_delay[0], + prachStartSymbol, + prach_pdu->num_ra); + + T(T_ENB_PHY_INITIATE_RA_PROCEDURE, + T_INT(gNB->Mod_id), + T_INT(frame), + T_INT(slot), + T_INT(max_preamble[0]), + T_INT(max_preamble_energy[0]), + T_INT(max_preamble_delay[0])); + + gNB->UL_INFO.rach_ind.number_of_pdus += 1; + + nfapi_nr_prach_indication_pdu_t *ind = &gNB->prach_pdu_indication_list[pdu_index]; + ind->phy_cell_id = gNB->gNB_config.cell_config.phy_cell_id.value; + ind->symbol_index = prachStartSymbol; + ind->slot_index = slot; + ind->freq_index = prach_pdu->num_ra; + ind->avg_rssi = (max_preamble_energy[0] < 631) ? (128 + (max_preamble_energy[0] / 5)) : 254; + ind->avg_snr = 0xff; // invalid for now + + ind->num_preamble = 1; + ind->preamble_list = gNB->preamble_list; + ind->preamble_list[0].preamble_index = max_preamble[0]; + ind->preamble_list[0].timing_advance = max_preamble_delay[0]; + ind->preamble_list[0].preamble_pwr = 0xffffffff; + pdu_index++; } gNB->measurements.prach_I0 = ((gNB->measurements.prach_I0*900)>>10) + ((max_preamble_energy[0]*124)>>10); if (frame==0) LOG_I(PHY,"prach_I0 = %d.%d dB\n",gNB->measurements.prach_I0/10,gNB->measurements.prach_I0%10); From 0e2c9e8ebb848f0199ca45c45a56a651f77e834b Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 28 Mar 2024 17:20:48 +0100 Subject: [PATCH 15/19] Do not reduce RACH.ind count in loop if we reduce, we will never do all rach indications. Go one-by-one instead. --- openair2/NR_PHY_INTERFACE/NR_IF_Module.c | 1 - 1 file changed, 1 deletion(-) diff --git a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c index b3bc9d05ff..e7a3ec7fe8 100644 --- a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c @@ -80,7 +80,6 @@ void handle_nr_rach(NR_UL_IND_t *UL_info) LOG_D(MAC,"UL_info[Frame %d, Slot %d] Calling initiate_ra_proc RACH:SFN/SLOT:%d/%d\n", UL_info->frame, UL_info->slot, UL_info->rach_ind.sfn, UL_info->rach_ind.slot); for (int i = 0; i < UL_info->rach_ind.number_of_pdus; i++) { - UL_info->rach_ind.number_of_pdus--; AssertFatal(UL_info->rach_ind.pdu_list[i].num_preamble == 1, "More than 1 preamble not supported\n"); nr_initiate_ra_proc(UL_info->module_id, UL_info->CC_id, From 087480084b921dda44a453c4994f4dd2f8740578 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 28 Mar 2024 19:30:34 +0100 Subject: [PATCH 16/19] increase response_window in multi-UE test --- ci-scripts/conf_files/gnb.sa.band78.106prb.rfsim.2x2.conf | 2 +- ci-scripts/conf_files/gnb.sa.band78.106prb.rfsim.conf | 2 +- ci-scripts/conf_files/gnb.sa.band78.24prb.rfsim.conf | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ci-scripts/conf_files/gnb.sa.band78.106prb.rfsim.2x2.conf b/ci-scripts/conf_files/gnb.sa.band78.106prb.rfsim.2x2.conf index f59ce1bd4c..c6899c04c9 100644 --- a/ci-scripts/conf_files/gnb.sa.band78.106prb.rfsim.2x2.conf +++ b/ci-scripts/conf_files/gnb.sa.band78.106prb.rfsim.2x2.conf @@ -85,7 +85,7 @@ gNBs = powerRampingStep = 1; #ra_ReponseWindow #1,2,4,8,10,20,40,80 - ra_ResponseWindow = 4; + ra_ResponseWindow = 5; #ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR #1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 3; diff --git a/ci-scripts/conf_files/gnb.sa.band78.106prb.rfsim.conf b/ci-scripts/conf_files/gnb.sa.band78.106prb.rfsim.conf index e69f351fe0..a11f6d5634 100644 --- a/ci-scripts/conf_files/gnb.sa.band78.106prb.rfsim.conf +++ b/ci-scripts/conf_files/gnb.sa.band78.106prb.rfsim.conf @@ -88,7 +88,7 @@ gNBs = powerRampingStep = 1; #ra_ReponseWindow #1,2,4,8,10,20,40,80 - ra_ResponseWindow = 4; + ra_ResponseWindow = 5; #ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR #1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 3; diff --git a/ci-scripts/conf_files/gnb.sa.band78.24prb.rfsim.conf b/ci-scripts/conf_files/gnb.sa.band78.24prb.rfsim.conf index 2c9300a2a2..4b891d1789 100644 --- a/ci-scripts/conf_files/gnb.sa.band78.24prb.rfsim.conf +++ b/ci-scripts/conf_files/gnb.sa.band78.24prb.rfsim.conf @@ -82,7 +82,7 @@ gNBs = powerRampingStep = 1; #ra_ReponseWindow #1,2,4,8,10,20,40,80 - ra_ResponseWindow = 4; + ra_ResponseWindow = 5; #ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR #1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4; From 0f1f76878efe3ec76f5366ab99a53cbcb660ce2b Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 28 Mar 2024 19:30:52 +0100 Subject: [PATCH 17/19] NRUE: print RA RNTI when receiving RAPID --- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 5520c49315..625f120778 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -3800,6 +3800,7 @@ static void nr_ue_process_rar(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *d NR_RA_HEADER_RAPID *rarh = (NR_RA_HEADER_RAPID *) dlsch_buffer; // RAR subheader pointer NR_MAC_RAR *rar = (NR_MAC_RAR *) (dlsch_buffer + 1); // RAR subPDU pointer uint8_t preamble_index = ra->ra_PreambleIndex; + uint16_t rnti = mac->ra.ra_rnti; LOG_D(NR_MAC, "[%d.%d]: [UE %d][RAPROC] invoking MAC for received RAR (current preamble %d)\n", frame, slot, mac->ue_id, preamble_index); @@ -3807,11 +3808,11 @@ static void nr_ue_process_rar(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *d n_subheaders++; if (rarh->T == 1) { n_subPDUs++; - LOG_I(NR_MAC, "[UE %d][RAPROC] Got RAPID RAR subPDU\n", mac->ue_id); + LOG_I(NR_MAC, "[UE %d][RAPROC][RA-RNTI %04x] Got RAPID RAR subPDU\n", mac->ue_id, rnti); } else { ra->RA_backoff_indicator = table_7_2_1[((NR_RA_HEADER_BI *)rarh)->BI]; ra->RA_BI_found = 1; - LOG_I(NR_MAC, "[UE %d][RAPROC] Got BI RAR subPDU %d ms\n", mac->ue_id, ra->RA_backoff_indicator); + LOG_I(NR_MAC, "[UE %d][RAPROC][RA-RNTI %04x] Got BI RAR subPDU %d ms\n", mac->ue_id, ra->RA_backoff_indicator, rnti); if ( ((NR_RA_HEADER_BI *)rarh)->E == 1) { rarh += sizeof(NR_RA_HEADER_BI); continue; From e6e25275edb6cd86666406458c17b44a32f7c15d Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 29 Mar 2024 15:08:44 +0100 Subject: [PATCH 18/19] Bugfix: make preamble_list an array - It is only a couple of bytes - It hid a bug: if two preambles, L1_nr_prach_procedures() overwrote the preamble of the first with the second one --- executables/nr-ue.c | 4 ---- nfapi/oai_integration/aerial/fapi_vnf_p7.c | 3 --- nfapi/oai_integration/nfapi_vnf.c | 5 ----- .../nfapi/public_inc/nfapi_nr_interface_scf.h | 2 +- nfapi/open-nFAPI/nfapi/src/nfapi_p7.c | 13 +++++-------- openair1/PHY/defs_gNB.h | 3 --- openair1/SCHED_NR/nr_prach_procedures.c | 1 - openair1/SCHED_NR_UE/fapi_nr_ue_l1.c | 6 ++---- openair2/NR_PHY_INTERFACE/NR_IF_Module.c | 4 ---- 9 files changed, 8 insertions(+), 33 deletions(-) diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 37b61db343..221e97e475 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -213,10 +213,6 @@ static void process_queued_nr_nfapi_msgs(NR_UE_MAC_INST_t *mac, int sfn_slot) .rach_ind = *rach_ind, }; send_nsa_standalone_msg(&UL_INFO, rach_ind->header.message_id); - for (int i = 0; i < rach_ind->number_of_pdus; i++) - { - free_and_zero(rach_ind->pdu_list[i].preamble_list); - } free_and_zero(rach_ind->pdu_list); free_and_zero(rach_ind); } diff --git a/nfapi/oai_integration/aerial/fapi_vnf_p7.c b/nfapi/oai_integration/aerial/fapi_vnf_p7.c index 3e54b75375..f2046aa456 100644 --- a/nfapi/oai_integration/aerial/fapi_vnf_p7.c +++ b/nfapi/oai_integration/aerial/fapi_vnf_p7.c @@ -397,9 +397,6 @@ int aerial_phy_nr_rach_indication(nfapi_nr_rach_indication_t *ind) rach_ind->pdu_list[i].avg_rssi = ind->pdu_list[i].avg_rssi; rach_ind->pdu_list[i].avg_snr = ind->pdu_list[i].avg_snr; rach_ind->pdu_list[i].num_preamble = ind->pdu_list[i].num_preamble; - rach_ind->pdu_list[i].preamble_list = CALLOC(ind->pdu_list[i].num_preamble, sizeof(nfapi_nr_prach_indication_preamble_t)); - AssertFatal(rach_ind->pdu_list[i].preamble_list != NULL, - "Memory not allocated for rach_ind->pdu_list[i].preamble_list in phy_nr_rach_indication."); for (int j = 0; j < ind->pdu_list[i].num_preamble; j++) { rach_ind->pdu_list[i].preamble_list[j].preamble_index = ind->pdu_list[i].preamble_list[j].preamble_index; rach_ind->pdu_list[i].preamble_list[j].timing_advance = ind->pdu_list[i].preamble_list[j].timing_advance; diff --git a/nfapi/oai_integration/nfapi_vnf.c b/nfapi/oai_integration/nfapi_vnf.c index 93666157d3..b3e34ee1b7 100644 --- a/nfapi/oai_integration/nfapi_vnf.c +++ b/nfapi/oai_integration/nfapi_vnf.c @@ -731,7 +731,6 @@ int phy_nr_rach_indication(nfapi_nr_rach_indication_t *ind) rach_ind->pdu_list[i].num_preamble = ind->pdu_list[i].num_preamble; rach_ind->pdu_list[i].freq_index = ind->pdu_list[i].freq_index; rach_ind->pdu_list[i].symbol_index = ind->pdu_list[i].symbol_index; - rach_ind->pdu_list[i].preamble_list = CALLOC(ind->pdu_list[i].num_preamble, sizeof(nfapi_nr_prach_indication_preamble_t)); AssertFatal(rach_ind->pdu_list[i].preamble_list != NULL, "Memory not allocated for rach_ind->pdu_list[i].preamble_list in phy_nr_rach_indication."); for (int j = 0; j < ind->number_of_pdus; j++) { @@ -742,10 +741,6 @@ int phy_nr_rach_indication(nfapi_nr_rach_indication_t *ind) if (!put_queue(&gnb_rach_ind_queue, rach_ind)) { LOG_E(NR_MAC, "Put_queue failed for rach_ind\n"); - for (int i = 0; i < ind->number_of_pdus; i++) - { - free(rach_ind->pdu_list[i].preamble_list); - } free(rach_ind->pdu_list); free(rach_ind); } diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h index f3f0775ccc..d3452a4212 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h @@ -1759,7 +1759,7 @@ typedef struct{ uint8_t avg_rssi; uint8_t avg_snr; uint8_t num_preamble; - nfapi_nr_prach_indication_preamble_t* preamble_list; + nfapi_nr_prach_indication_preamble_t preamble_list[64]; }nfapi_nr_prach_indication_pdu_t; diff --git a/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c b/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c index e11e2a1d16..7cbf2c41fd 100644 --- a/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c +++ b/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c @@ -6302,14 +6302,11 @@ static uint8_t unpack_nr_rach_indication_body(nfapi_nr_prach_indication_pdu_t *v return 0; } - if (value->num_preamble > 0) { - value->preamble_list = nfapi_p7_allocate(sizeof(*value->preamble_list) * value->num_preamble, config); - for (int i = 0; i < value->num_preamble; i++) { - nfapi_nr_prach_indication_preamble_t *preamble = &(value->preamble_list[i]); - if (!(pull8(ppReadPackedMsg, &preamble->preamble_index, end) && pull16(ppReadPackedMsg, &preamble->timing_advance, end) - && pull32(ppReadPackedMsg, &preamble->preamble_pwr, end))) { - return 0; - } + for (int i = 0; i < value->num_preamble; i++) { + nfapi_nr_prach_indication_preamble_t *preamble = &(value->preamble_list[i]); + if (!(pull8(ppReadPackedMsg, &preamble->preamble_index, end) && pull16(ppReadPackedMsg, &preamble->timing_advance, end) + && pull32(ppReadPackedMsg, &preamble->preamble_pwr, end))) { + return 0; } } return 1; diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index c4ef28bc0b..abc0ac2a2a 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -531,7 +531,6 @@ typedef struct { #define MAX_NUM_NR_RX_RACH_PDUS 4 -#define MAX_NUM_NR_RX_PRACH_PREAMBLES 4 #define MAX_UL_PDUS_PER_SLOT 8 #define MAX_NUM_NR_SRS_PDUS 8 // the current RRC resource allocation is that each UE gets its @@ -573,8 +572,6 @@ typedef struct PHY_VARS_gNB_s { nfapi_nr_uci_t uci_pdu_list[MAX_NUM_NR_UCI_PDUS]; /// NFAPI PRACH information nfapi_nr_prach_indication_pdu_t prach_pdu_indication_list[MAX_NUM_NR_RX_RACH_PDUS]; - /// NFAPI PRACH information - nfapi_nr_prach_indication_preamble_t preamble_list[MAX_NUM_NR_RX_PRACH_PREAMBLES]; nfapi_nr_ul_tti_request_t UL_tti_req; nfapi_nr_uci_indication_t uci_indication; diff --git a/openair1/SCHED_NR/nr_prach_procedures.c b/openair1/SCHED_NR/nr_prach_procedures.c index f1d09f0b18..dd77115817 100644 --- a/openair1/SCHED_NR/nr_prach_procedures.c +++ b/openair1/SCHED_NR/nr_prach_procedures.c @@ -185,7 +185,6 @@ void L1_nr_prach_procedures(PHY_VARS_gNB *gNB,int frame,int slot) { ind->avg_snr = 0xff; // invalid for now ind->num_preamble = 1; - ind->preamble_list = gNB->preamble_list; ind->preamble_list[0].preamble_index = max_preamble[0]; ind->preamble_list[0].timing_advance = max_preamble_delay[0]; ind->preamble_list[0].preamble_pwr = 0xffffffff; diff --git a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c index cd8835d57e..fe36aa3425 100644 --- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c +++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c @@ -125,16 +125,14 @@ int8_t nr_ue_scheduled_response_stub(nr_scheduled_response_t *scheduled_response rach_ind->pdu_list[pdu_index].freq_index = prach_pdu->num_ra; rach_ind->pdu_list[pdu_index].avg_rssi = 128; rach_ind->pdu_list[pdu_index].avg_snr = 0xff; // invalid for now - rach_ind->pdu_list[pdu_index].num_preamble = 1; const int num_p = rach_ind->pdu_list[pdu_index].num_preamble; - rach_ind->pdu_list[pdu_index].preamble_list = calloc(num_p, sizeof(nfapi_nr_prach_indication_preamble_t)); + AssertFatal(num_p == 1, "can handle only one preamble in preamble_list\n"); + rach_ind->pdu_list[pdu_index].num_preamble = 1; rach_ind->pdu_list[pdu_index].preamble_list[0].preamble_index = prach_pdu->ra_PreambleIndex; rach_ind->pdu_list[pdu_index].preamble_list[0].timing_advance = 0; rach_ind->pdu_list[pdu_index].preamble_list[0].preamble_pwr = 0xffffffff; if (!put_queue(&nr_rach_ind_queue, rach_ind)) { - for (int pdu_index = 0; pdu_index < rach_ind->number_of_pdus; pdu_index++) - free(rach_ind->pdu_list[pdu_index].preamble_list); free(rach_ind->pdu_list); free(rach_ind); } diff --git a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c index e7a3ec7fe8..6f3cd0a744 100644 --- a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c @@ -255,10 +255,6 @@ static void free_unqueued_nfapi_indications(nfapi_nr_rach_indication_t *rach_ind nfapi_nr_crc_indication_t *crc_ind) { if (rach_ind && rach_ind->number_of_pdus > 0) { - for(int i = 0; i < rach_ind->number_of_pdus; i++) - { - free_and_zero(rach_ind->pdu_list[i].preamble_list); - } free_and_zero(rach_ind->pdu_list); free_and_zero(rach_ind); } From e3747ab5928b030fb2b9136ed021360f44a97a86 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 8 Apr 2024 16:08:35 +0200 Subject: [PATCH 19/19] Check if Msg3 start&length can be accommodated in mixed slot Prior to this commit, it might happen that the gNB used TDA 0 (Start 0 len 13) for mixed slot, in which case the UE could not send msg3 (because a mixed slot has less than 13 symbols). --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index 0799dcf7a3..4c84d88680 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -760,6 +760,7 @@ static int get_feasible_msg3_tda(frame_type_t frame_type, // TDD DevAssert(tdd != NULL); + uint8_t tdd_period_slot = slots_per_frame / get_nb_periods_per_frame(tdd->dl_UL_TransmissionPeriodicity); for (int i = 0; i < tda_list->list.count; i++) { // check if it is UL long k2 = *tda_list->list.array[i]->k2; @@ -769,8 +770,19 @@ static int get_feasible_msg3_tda(frame_type_t frame_type, // check if enough symbols in case of mixed slot bool has_mixed = tdd->nrofUplinkSymbols != 0 || tdd->nrofDownlinkSymbols != 0; - // is in mixed slot with less than 3 symbols? - if (has_mixed && temp_slot == tdd->nrofDownlinkSlots && tdd->nrofUplinkSymbols < 3) + bool is_mixed = has_mixed && ((temp_slot % tdd_period_slot) == tdd->nrofDownlinkSlots); + // if the mixed slot has not enough symbols, skip + if (is_mixed && tdd->nrofUplinkSymbols < 3) + continue; + + uint16_t slot_mask = is_mixed ? SL_to_bitmap(14 - tdd->nrofUplinkSymbols, tdd->nrofUplinkSymbols) : 0x3fff; + long startSymbolAndLength = tda_list->list.array[i]->startSymbolAndLength; + int start, nr; + SLIV2SL(startSymbolAndLength, &start, &nr); + uint16_t msg3_mask = SL_to_bitmap(start, nr); + LOG_D(NR_MAC, "Check Msg3 TDA %d for slot %d: k2 %ld, S %d L %d\n", i, temp_slot, k2, start, nr); + /* if this start and length of this TDA cannot be fulfilled, skip */ + if ((slot_mask & msg3_mask) != msg3_mask) continue; // is in mixed slot with more or equal than 3 symbols, or UL slot