From 514d6ac121d78c55a2e5d17e4f24bf533d2c3016 Mon Sep 17 00:00:00 2001 From: ndomingues Date: Tue, 23 Sep 2025 10:34:41 +0100 Subject: [PATCH 01/10] Improve find_ra_UE function to return UE identified by RA-RNTI required for MsgA-PUSCH Signed-off-by: Nuno Domingues --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index d4fad33723..41b0191c4d 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -2535,9 +2535,13 @@ NR_UE_info_t *find_nr_UE(NR_UEs_t *UEs, rnti_t rntiP) NR_UE_info_t *find_ra_UE(NR_UEs_t *UEs, rnti_t rntiP) { - UE_iterator(UEs->access_ue_list, UE) { + UE_iterator (UEs->access_ue_list, UE) { + if (UE->ra->ra_type == RA_2_STEP && UE->ra->RA_rnti == rntiP) { + LOG_D(NR_MAC, "Search and found RA 2-Step RA_rnti: %04x\n", rntiP); + return UE; + } if (UE->rnti == rntiP) { - LOG_D(NR_MAC,"Search and found rnti: %04x\n", rntiP); + LOG_D(NR_MAC, "Search and found rnti: %04x\n", rntiP); return UE; } } From 2cf87108f4971907d2e2672cbc3b133172680aee Mon Sep 17 00:00:00 2001 From: ndomingues Date: Fri, 24 Apr 2026 18:47:39 +0100 Subject: [PATCH 02/10] Increase RA frame buffer size for 2-step RA to avoid MsgA-PUSCH and ACK/NACK collision Signed-off-by: Nuno Domingues --- openair2/LAYER2/NR_MAC_gNB/config.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c index 06b6972379..06a2974533 100644 --- a/openair2/LAYER2/NR_MAC_gNB/config.c +++ b/openair2/LAYER2/NR_MAC_gNB/config.c @@ -941,7 +941,19 @@ void nr_mac_config_scc(gNB_MAC_INST *nrmac, NR_ServingCellConfigCommon_t *scc, c const int NTN_gNB_Koffset = get_NTN_Koffset(scc); const int n = get_slots_per_frame_from_scs(*scc->ssbSubcarrierSpacing); - const int size = n << (int)ceil(log2((NTN_gNB_Koffset + 13) / n + 1)); // 13 is upper limit for max_fb_time + int size = n << (int)ceil(log2((NTN_gNB_Koffset + 13) / n + 1)); // 13 is upper limit for max_fb_time + + // If the RA is configured as 2-step, the size must be increased to accommodate more frames. This allows MsgA-PUSCH and the + // ACK/NACK to be scheduled within the same slot, as they reside in different frames. Consequently, multiple MsgA-PUSCH + // transmissions can be scheduled without overriding the ACK/NACK. + if (scc->uplinkConfigCommon->initialUplinkBWP->ext1 + && scc->uplinkConfigCommon->initialUplinkBWP->ext1->msgA_ConfigCommon_r16->choice.setup->msgA_PUSCH_Config_r16 + ->msgA_PUSCH_ResourceGroupA_r16->msgA_PUSCH_TimeDomainOffset_r16) { + NR_MsgA_ConfigCommon_r16_t *msgacc = scc->uplinkConfigCommon->initialUplinkBWP->ext1->msgA_ConfigCommon_r16->choice.setup; + int msgA_PUSCH_TimeDomainOffset = msgacc->msgA_PUSCH_Config_r16->msgA_PUSCH_ResourceGroupA_r16->msgA_PUSCH_TimeDomainOffset_r16; + size *= (n + msgA_PUSCH_TimeDomainOffset + (n - 1)) / n; + } + nrmac->vrb_map_UL_size = size; int num_beams = 1; From d58e618116bf29f41a599fa64506d8f88d26e6bc Mon Sep 17 00:00:00 2001 From: ndomingues Date: Thu, 30 Apr 2026 15:56:00 +0100 Subject: [PATCH 03/10] Schedule MsgA-PUSCH even if there are UEs connected Signed-off-by: Nuno Domingues --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index f5c753ea87..8de7ca5df8 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -476,15 +476,14 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, slot_t slotP) } } if (initialUplinkBWP->ext1 && initialUplinkBWP->ext1->msgA_ConfigCommon_r16) { - if (gNB->UE_info.connected_ue_list[0] == NULL) - schedule_nr_MsgA_pusch(scc->uplinkConfigCommon, - gNB, - module_idP, - frameP, - slotP, - prach_pdu, - scc->dmrs_TypeA_Position, - *scc->physCellId); + schedule_nr_MsgA_pusch(scc->uplinkConfigCommon, + gNB, + module_idP, + frameP, + slotP, + prach_pdu, + scc->dmrs_TypeA_Position, + *scc->physCellId); } } prach_pdu->num_prach_ocas = num_td_occ; From 143ee8ff25d3eddd3851fc299353cbc38e70fe5f Mon Sep 17 00:00:00 2001 From: ndomingues Date: Fri, 26 Sep 2025 15:37:36 +0100 Subject: [PATCH 04/10] Minor adjustments to RA 2-Step configuration file Signed-off-by: Nuno Domingues --- .../CONF/gnb.sa.band78.106PRB.usrpb210.RA_2-Step.conf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.106PRB.usrpb210.RA_2-Step.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.106PRB.usrpb210.RA_2-Step.conf index aae6375cab..a27425c4c8 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.106PRB.usrpb210.RA_2-Step.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.106PRB.usrpb210.RA_2-Step.conf @@ -70,7 +70,7 @@ gNBs = initialULBWPsubcarrierSpacing = 1; #rach-ConfigCommon #rach-ConfigGeneric - prach_ConfigurationIndex = 98; + prach_ConfigurationIndex = 148; #prach_msg1_FDM #0 = one, 1=two, 2=four, 3=eight prach_msg1_FDM = 0; @@ -117,7 +117,7 @@ gNBs = nrofMsgA_PO_PerSlot_r16 = 0; msgA_PUSCH_TimeDomainOffset_r16 = 8; startSymbolAndLengthMsgA_PO_r16 = 38; - mappingTypeMsgA_PUSCH_r16 = 0; + mappingTypeMsgA_PUSCH_r16 = 1; guardBandMsgA_PUSCH_r16 = 0; frequencyStartMsgA_PUSCH_r16 = 0; nrofPRBs_PerMsgA_PO_r16 = 8; From f1c2a64636c57a6238d6c1ee81de4fbb3dfe7e95 Mon Sep 17 00:00:00 2001 From: ndomingues Date: Tue, 5 May 2026 18:19:10 +0100 Subject: [PATCH 05/10] Implementation of the response window timer for 2-Step RA Signed-off-by: Nuno Domingues --- openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c | 7 +++++-- openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c | 17 +++++++++++++++++ ...gnb.sa.band78.106PRB.usrpb210.RA_2-Step.conf | 2 +- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c index 730b0fbef3..f5a733bbc2 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c @@ -679,7 +679,7 @@ static int nr_get_RA_window_2Step_v16(long msgB_ResponseWindow) return 160; break; case NR_RACH_ConfigGenericTwoStepRA_r16__msgB_ResponseWindow_r16_sl320: - return 360; + return 320; break; default: AssertFatal(false, "illegal msgB_responseWindow value %ld\n", msgB_ResponseWindow); @@ -1157,12 +1157,15 @@ void nr_ra_contention_resolution_failed(NR_UE_MAC_INST_t *mac) void nr_rar_not_successful(NR_UE_MAC_INST_t *mac) { - LOG_W(MAC, "[UE %d] RAR reception failed\n", mac->ue_id); RA_config_t *ra = &mac->ra; + LOG_W(MAC, "[UE %d] Response window timer expired, %s reception failed\n", mac->ue_id, ra->ra_type == RA_2_STEP ? "MsgB" : "RAR"); NR_PRACH_RESOURCES_t *prach_resources = &ra->prach_resources; prach_resources->preamble_tx_counter++; bool ra_completed = false; if (prach_resources->preamble_tx_counter == ra->preambleTransMax + 1) { + if (ra->ra_type == RA_2_STEP) { + AssertFatal(false, "Fallback to 4-Step RA not implemented\n"); + } // if the Random Access Preamble is transmitted on the SpCell // TODO to be verified, this means SA if I'm not mistaken if (IS_SA_MODE(get_softmodem_params())) { diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index 26ce0e5037..7f0da2b3b0 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -1677,6 +1677,23 @@ static void nr_ue_prach_scheduler(NR_UE_MAC_INST_t *mac, frame_t frameP, slot_t ra->t_crnti = 0; mac->crnti = 0; ra->ra_rnti = 0; + + // start MsgB response window timer + int next_slot = (slotP + 1) % n_slots_frame; + int next_frame = (frameP + (next_slot < slotP)) % MAX_FRAME_NUMBER; + int add_slots = 1; + NR_BWP_PDCCH_t *pdcch_config = &mac->config_BWP_PDCCH[mac->current_DL_BWP->bwp_id]; + const NR_SearchSpace_t *ra_SS = get_common_search_space(mac, pdcch_config->ra_SS_id); + while (!is_dl_slot(next_slot, &mac->frame_structure) + || !is_ss_monitor_occasion(next_frame, next_slot, n_slots_frame, ra_SS)) { + int temp_slot = (next_slot + 1) % n_slots_frame; + next_frame = (next_frame + (temp_slot < next_slot)) % MAX_FRAME_NUMBER; + next_slot = temp_slot; + add_slots++; + } + add_slots += GET_DURATION_RX_TO_TX(&mac->phy_config.config_req.ntn_config, mac->current_DL_BWP->scs); + nr_timer_setup(&ra->response_window_timer, ra->response_window_setup_time + add_slots, 1); + nr_timer_start(&ra->response_window_timer); } else { AssertFatal(false, "RA type %d not implemented!\n", ra->ra_type); } diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.106PRB.usrpb210.RA_2-Step.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.106PRB.usrpb210.RA_2-Step.conf index a27425c4c8..c349d82248 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.106PRB.usrpb210.RA_2-Step.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.106PRB.usrpb210.RA_2-Step.conf @@ -106,7 +106,7 @@ gNBs = p0_NominalWithGrant =-90; # 0=sl1, 1=sl2, 2=sl4, 3=sl8, 4=sl10, 5=sl20, 6=sl40, 7=sl80, 8=sl160, 9=sl320 - msgB_ResponseWindow_r16 = 2; + msgB_ResponseWindow_r16 = 7; msgA_RSRP_Threshold_r16 = 19; msgA_CB_PreamblesPerSSB_PerSharedRO_r16 = 1; From 11ae2f8308e5e9544be9bdf2366c5385d3ef0333 Mon Sep 17 00:00:00 2001 From: ndomingues Date: Fri, 26 Sep 2025 15:40:53 +0100 Subject: [PATCH 06/10] For RA 2-Step consider RA failed if MsgA-PUSCH not detected Signed-off-by: Nuno Domingues --- .../LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 27 ++++++++++++++----- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 96d2f2c063..b230789bc2 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -702,6 +702,18 @@ static void handle_nr_ul_harq(gNB_MAC_INST *nrmac, NR_UE_info_t *UE, rnti_t rnti static void handle_msg3_failed_rx(gNB_MAC_INST *mac, NR_RA_t *ra, rnti_t rnti, int harq_round_max) { + // for CFRA (NSA) do not schedule retransmission of msg3 + // For RA 2-Step consider RA failed if MsgA-PUSCH not detected + if (ra->cfra || ra->ra_type == RA_2_STEP) { + LOG_W(NR_MAC, + "UE %04x RA failed at state %s (%s reception failed)\n", + rnti, + nrra_text[ra->ra_state], + ra->ra_type == RA_2_STEP ? "MsgA-PUSCH" : "NSA Msg3"); + nr_release_ra_UE(mac, rnti); + return; + } + if (ra->msg3_round >= harq_round_max - 1) { LOG_W(NR_MAC, "UE %04x RA failed at state %s (Reached msg3 max harq rounds)\n", rnti, nrra_text[ra->ra_state]); nr_release_ra_UE(mac, rnti); @@ -729,7 +741,7 @@ static void nr_rx_ra_sdu(const module_id_t mod_id, NR_ServingCellConfigCommon_t *scc = mac->common_channels[0].ServingCellConfigCommon; NR_UE_info_t *UE = find_ra_UE(&mac->UE_info, rnti); if (!UE) { - LOG_E(NR_MAC, "UL SDU discarded. Couldn't finde UE with RNTI %04x \n", rnti); + LOG_D(NR_MAC, "UL SDU discarded. Couldn't find UE with RNTI %04x \n", rnti); return; } @@ -773,16 +785,19 @@ static void nr_rx_ra_sdu(const module_id_t mod_id, if (cfra) // no Msg3 on CFRA, no problem return; - if (ra->ra_state != nrRA_WAIT_Msg3) + if (ra->ra_type == RA_4_STEP && ra->ra_state != nrRA_WAIT_Msg3) + return; + + if (ra->ra_type == RA_2_STEP && ra->ra_state != nrRA_WAIT_MsgA_PUSCH) return; - if((frame!=ra->Msg3_frame) || (slot!=ra->Msg3_slot)) + if (ra->ra_type == RA_4_STEP && ((frame != ra->Msg3_frame) || (slot != ra->Msg3_slot))) return; if (ul_cqi != 0xff) ra->msg3_TPC = nr_mac_get_tpc(&UE->UE_sched_ctrl.pusch_pc); - handle_msg3_failed_rx(mac, ra, rnti, mac->ul_bler.harq_round_max); + handle_msg3_failed_rx(mac, ra, UE->rnti, mac->ul_bler.harq_round_max); return; } @@ -801,9 +816,9 @@ static void nr_rx_ra_sdu(const module_id_t mod_id, if (no_sig) { - LOG_W(NR_MAC, "MSG3 ULSCH with no signal\n"); + LOG_W(NR_MAC, "%s ULSCH with no signal\n", ra->ra_type == RA_2_STEP ? "MsgA-PUSCH" : "MSG3"); if (!cfra) - handle_msg3_failed_rx(mac, ra, rnti, mac->ul_bler.harq_round_max); + handle_msg3_failed_rx(mac, ra, UE->rnti, mac->ul_bler.harq_round_max); return; } if (!cfra && ra->ra_type == RA_2_STEP) { From 31aa512c5b922b8bd3411a1fc4b44925c7963c09 Mon Sep 17 00:00:00 2001 From: ndomingues Date: Tue, 23 Sep 2025 10:36:57 +0100 Subject: [PATCH 07/10] Improve LOGs to better handle RA 2-Step Signed-off-by: Nuno Domingues --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index b230789bc2..66b9b448bf 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -824,7 +824,7 @@ static void nr_rx_ra_sdu(const module_id_t mod_id, if (!cfra && ra->ra_type == RA_2_STEP) { // random access pusch with RA-RNTI if (ra->RA_rnti != rnti) { - LOG_E(NR_MAC, "expected TC_RNTI %04x to match current RNTI %04x\n", ra->RA_rnti, rnti); + LOG_E(NR_MAC, "expected RA_RNTI %04x to match current RNTI %04x\n", ra->RA_rnti, rnti); return; } } @@ -832,7 +832,12 @@ static void nr_rx_ra_sdu(const module_id_t mod_id, // re-initialize ta update variables after RA procedure completion UE->UE_sched_ctrl.ta_frame = (frame + 100) % MAX_FRAME_NUMBER; - LOG_A(NR_MAC, "%4d.%2d PUSCH with TC_RNTI 0x%04x received correctly\n", frame, slot, rnti); + LOG_A(NR_MAC, + "%4d.%2d PUSCH with %s 0x%04x received correctly\n", + frame, + slot, + ra->ra_type == RA_2_STEP ? "RA_RNTI" : "TC_RNTI", + rnti); NR_UE_sched_ctrl_t *UE_scheduling_control = &UE->UE_sched_ctrl; DevAssert(harq_pid >= 0 && harq_pid < 8); @@ -899,9 +904,10 @@ static void nr_rx_ra_sdu(const module_id_t mod_id, nr_process_mac_pdu(mod_id, UE, frame, slot, sdu, sdu_len, harq_pid); LOG_I(NR_MAC, - "Activating scheduling %s for TC_RNTI 0x%04x (state %s)\n", + "Activating scheduling %s for %s 0x%04x (state %s)\n", ra->ra_type == RA_2_STEP ? "MsgB" : "Msg4", - UE->rnti, + ra->ra_type == RA_2_STEP ? "MsgB_rnti" : "TC_RNTI", + ra->ra_type == RA_2_STEP ? UE->ra->MsgB_rnti : UE->rnti, nrra_text[ra->ra_state]); ra->ra_state = ra->ra_type == RA_2_STEP ? nrRA_MsgB : nrRA_Msg4; LOG_D(NR_MAC, "TC_RNTI 0x%04x next RA state %s\n", UE->rnti, nrra_text[ra->ra_state]); From 2f27ec15ee459c7768daf5fec3f6b327a07ac82b Mon Sep 17 00:00:00 2001 From: ndomingues Date: Tue, 23 Sep 2025 10:39:50 +0100 Subject: [PATCH 08/10] Demote sharedROs Assert Fatal to LOG_E to get RA 2-Step working sharedROs feature to be implemented in the future Signed-off-by: Nuno Domingues --- openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c index f5a733bbc2..f1f014c2bc 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c @@ -287,7 +287,8 @@ static void config_preamble_index(NR_UE_MAC_INST_t *mac) // The field is mandatory present if the 2-step random access type occasions are shared with 4-step random access type, // otherwise the field is not present bool sharedROs = twostep->msgA_CB_PreamblesPerSSB_PerSharedRO_r16 != NULL; - AssertFatal(sharedROs == false, "Shared ROs between 2- and 4-step RA not supported\n"); + if (!sharedROs) + LOG_E(NR_MAC, "Shared ROs between 2- and 4-step RA not supported\n"); // For Type-2 random access procedure with separate configuration of PRACH occasions with Type-1 random access procedure // configuration by msgA-SSB-PerRACH-OccasionAndCB-PreamblesPerSSB when provided; From 642fe0e5fe1c7c9ebae04d412f41374b25623b5a Mon Sep 17 00:00:00 2001 From: Nuno Domingues Date: Mon, 15 Jun 2026 12:41:38 +0100 Subject: [PATCH 09/10] Improve PUSCH message both in gNB and UE Signed-off-by: Nuno Domingues --- openair2/GNB_APP/gnb_config.c | 1 + openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c | 54 ++++++++++------- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 58 ++++++++++++++----- 3 files changed, 80 insertions(+), 33 deletions(-) diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index f9ca5709f3..079a04f8e2 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -195,6 +195,7 @@ void prepare_msgA_scc(NR_ServingCellConfigCommon_t *scc) { NR_MsgA_PUSCH_Resource_r16_t *msgA_PUSCH_Resource = msgA_PUSCH_Config_r16->msgA_PUSCH_ResourceGroupA_r16; msgA_PUSCH_Resource->startSymbolAndLengthMsgA_PO_r16 = calloc(1, sizeof(long)); msgA_PUSCH_Config_r16->msgA_TransformPrecoder_r16 = calloc(1, sizeof(long)); + msgA_PUSCH_Resource->mappingTypeMsgA_PUSCH_r16 = calloc(1, sizeof(long)); } // Section 4.1 in 38.213 diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index 7f0da2b3b0..cd7933bce7 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -378,29 +378,19 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, int dmrslength = 1; NR_PUSCH_Config_t *pusch_Config = current_UL_BWP->pusch_Config; - AssertFatal(!((mac->ra.ra_state < nrRA_SUCCEEDED && mac->ra.ra_type == RA_2_STEP) && rar_grant), "logic error: Is not possible to have both msgA_pusch_resource and rar_grant\n"); + AssertFatal(!((mac->ra.ra_state < nrRA_SUCCEEDED && mac->ra.ra_type == RA_2_STEP) && rar_grant), + "logic error: Is not possible to have both msgA_pusch_resource and rar_grant\n"); if (mac->ra.ra_state < nrRA_SUCCEEDED && mac->ra.ra_type == RA_2_STEP) { NR_MsgA_PUSCH_Resource_r16_t *msgA_PUSCH_Resource = current_UL_BWP->msgA_ConfigCommon_r16->msgA_PUSCH_Config_r16->msgA_PUSCH_ResourceGroupA_r16; + int mapping_type = *msgA_PUSCH_Resource->mappingTypeMsgA_PUSCH_r16; int S = 0; int L = 0; SLIV2SL(*msgA_PUSCH_Resource->startSymbolAndLengthMsgA_PO_r16, &S, &L); tda_info->k2 = msgA_PUSCH_Resource->msgA_PUSCH_TimeDomainOffset_r16; - tda_info->startSymbolIndex = S; - tda_info->nrOfSymbols = L; - l_prime_mask = get_l_prime(tda_info->nrOfSymbols, - tda_info->mapping_type, - add_pos, - dmrslength, - tda_info->startSymbolIndex, - mac->dmrs_TypeA_Position); - LOG_I(NR_MAC, - "MSGA PUSCH start_sym:%d NR Symb:%d mappingtype:%d, DMRS_MASK:%x\n", - pusch_config_pdu->start_symbol_index, - pusch_config_pdu->nr_of_symbols, - tda_info->mapping_type, - l_prime_mask); + l_prime_mask = get_l_prime(L, mapping_type, add_pos, dmrslength, S, 0); + LOG_I(NR_MAC, "MSGA PUSCH start_sym:%d NR Symb:%d mappingtype:%d, DMRS_MASK:%x\n", S, L, mapping_type, l_prime_mask); LOG_D(NR_MAC, "sc_info->initial_ul_BWPStart = %d sc_info->initial_ul_BWPSize = %d\n", @@ -409,12 +399,12 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, pusch_config_pdu->handle = 0; pusch_config_pdu->rb_size = msgA_PUSCH_Resource->nrofPRBs_PerMsgA_PO_r16; pusch_config_pdu->mcs_table = 0; - pusch_config_pdu->frequency_hopping = msgA_PUSCH_Resource->msgA_IntraSlotFrequencyHopping_r16 ? *msgA_PUSCH_Resource->msgA_IntraSlotFrequencyHopping_r16 : 0; + pusch_config_pdu->frequency_hopping = + msgA_PUSCH_Resource->msgA_IntraSlotFrequencyHopping_r16 ? *msgA_PUSCH_Resource->msgA_IntraSlotFrequencyHopping_r16 : 0; pusch_config_pdu->pusch_data.new_data_indicator = 1; // new data pusch_config_pdu->num_dmrs_cdm_grps_no_data = 2; - pusch_config_pdu->ul_dmrs_symb_pos = get_l_prime(3, 0, pusch_dmrs_pos2, pusch_len1, 10, mac->dmrs_TypeA_Position); pusch_config_pdu->transform_precoding = - *mac->current_UL_BWP->msgA_ConfigCommon_r16->msgA_PUSCH_Config_r16->msgA_TransformPrecoder_r16; + *mac->current_UL_BWP->msgA_ConfigCommon_r16->msgA_PUSCH_Config_r16->msgA_TransformPrecoder_r16; pusch_config_pdu->rb_bitmap[0] = 0; pusch_config_pdu->rb_start = msgA_PUSCH_Resource->frequencyStartMsgA_PUSCH_r16; // rb_start depends on the RO pusch_config_pdu->bwp_size = sc_info->initial_ul_BWPSize; @@ -430,14 +420,38 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, pusch_config_pdu->resource_alloc = 1; pusch_config_pdu->tx_direct_current_location = 0; pusch_config_pdu->mcs_index = msgA_PUSCH_Resource->msgA_MCS_r16; - pusch_config_pdu->qam_mod_order = nr_get_Qm_dl(pusch_config_pdu->mcs_index, 0); pusch_config_pdu->start_symbol_index = S; pusch_config_pdu->nr_of_symbols = L; pusch_config_pdu->pusch_data.rv_index = 0; // 8.3 in 38.213 pusch_config_pdu->pusch_data.harq_process_id = 0; pusch_config_pdu->pusch_data.num_cb = 0; pusch_config_pdu->tbslbrm = 0; - pusch_config_pdu->target_code_rate = nr_get_code_rate_ul(pusch_config_pdu->mcs_index, 0); + + LOG_D(NR_MAC, + "pdu_bit_map %d rnti %d handle %d rb_size %d mcs_table %d frequency_hopping %d dmrs_ports %d start_symbol_index %d " + "nr_of_symbols %d new_data_indicator %d num_dmrs_cdm_grps_no_data %d ul_dmrs_symb_pos %d transform_precoding %d rb_start " + "%d bwp_size %d bwp_start %d ul_dmrs_scrambling_id %d mcs_index %d qam_mod_order %d target_code_rate %d tb_size %d\n", + pusch_config_pdu->pdu_bit_map, + pusch_config_pdu->rnti, + pusch_config_pdu->handle, + pusch_config_pdu->rb_size, + pusch_config_pdu->mcs_table, + pusch_config_pdu->frequency_hopping, + pusch_config_pdu->dmrs_ports, + pusch_config_pdu->start_symbol_index, + pusch_config_pdu->nr_of_symbols, + pusch_config_pdu->pusch_data.new_data_indicator, + pusch_config_pdu->num_dmrs_cdm_grps_no_data, + pusch_config_pdu->ul_dmrs_symb_pos, + pusch_config_pdu->transform_precoding, + pusch_config_pdu->rb_start, + pusch_config_pdu->bwp_size, + pusch_config_pdu->bwp_start, + pusch_config_pdu->ul_dmrs_scrambling_id, + pusch_config_pdu->mcs_index, + pusch_config_pdu->qam_mod_order, + pusch_config_pdu->target_code_rate, + pusch_config_pdu->pusch_data.tb_size); } else if (rar_grant) { // Note: for Msg3 or MsgA PUSCH transmission the N_PRB_oh is always set to 0 diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index 8de7ca5df8..0fd3ae2080 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -206,8 +206,8 @@ static void schedule_nr_MsgA_pusch(NR_UplinkConfigCommon_t *uplinkConfigCommon, { NR_SCHED_ENSURE_LOCKED(&nr_mac->sched_lock); - NR_MsgA_PUSCH_Resource_r16_t *msgA_PUSCH_Resource = uplinkConfigCommon->initialUplinkBWP->ext1->msgA_ConfigCommon_r16->choice - .setup->msgA_PUSCH_Config_r16->msgA_PUSCH_ResourceGroupA_r16; + NR_MsgA_ConfigCommon_r16_t *msgacc = uplinkConfigCommon->initialUplinkBWP->ext1->msgA_ConfigCommon_r16->choice.setup; + NR_MsgA_PUSCH_Resource_r16_t *msgA_PUSCH_Resource = msgacc->msgA_PUSCH_Config_r16->msgA_PUSCH_ResourceGroupA_r16; const int n_slots_frame = nr_mac->frame_structure.numb_slots_frame; slot_t msgA_pusch_slot = (slotP + msgA_PUSCH_Resource->msgA_PUSCH_TimeDomainOffset_r16) % n_slots_frame; @@ -249,8 +249,9 @@ static void schedule_nr_MsgA_pusch(NR_UplinkConfigCommon_t *uplinkConfigCommon, pusch_pdu->pusch_data.new_data_indicator = 1; pusch_pdu->nrOfLayers = 1; pusch_pdu->num_dmrs_cdm_grps_no_data = L <= 2 ? 1 : 2; // no data in dmrs symbols as in 6.2.2 in 38.214 - pusch_pdu->ul_dmrs_symb_pos = get_l_prime(3, 0, pusch_dmrs_pos2, pusch_len1, 10, dmrs_TypeA_Position); - pusch_pdu->transform_precoding = *uplinkConfigCommon->initialUplinkBWP->ext1->msgA_ConfigCommon_r16->choice.setup->msgA_PUSCH_Config_r16->msgA_TransformPrecoder_r16; + pusch_pdu->ul_dmrs_symb_pos = + get_l_prime(L, *msgA_PUSCH_Resource->mappingTypeMsgA_PUSCH_r16, pusch_dmrs_pos2, pusch_len1, S, dmrs_TypeA_Position); + pusch_pdu->transform_precoding = *msgacc->msgA_PUSCH_Config_r16->msgA_TransformPrecoder_r16; pusch_pdu->rb_bitmap[0] = 0; pusch_pdu->rb_start = msgA_PUSCH_Resource->frequencyStartMsgA_PUSCH_r16; // rb_start depends on the RO int locationAndBandwidth = uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth; @@ -275,25 +276,56 @@ static void schedule_nr_MsgA_pusch(NR_UplinkConfigCommon_t *uplinkConfigCommon, pusch_pdu->mcs_index = msgA_PUSCH_Resource->msgA_MCS_r16; pusch_pdu->qam_mod_order = nr_get_Qm_dl(pusch_pdu->mcs_index, pusch_pdu->mcs_table); - int num_dmrs_symb = count_bits64_with_mask(pusch_pdu->ul_dmrs_symb_pos, 10, 3); + int num_dmrs_symb = count_bits64_with_mask(pusch_pdu->ul_dmrs_symb_pos, S, L); AssertFatal(pusch_pdu->mcs_index <= 28, "Exceeding MCS limit for MsgA PUSCH\n"); int R = nr_get_code_rate_ul(pusch_pdu->mcs_index, pusch_pdu->mcs_table); pusch_pdu->target_code_rate = R; int TBS = nr_compute_tbs(pusch_pdu->qam_mod_order, - R, - pusch_pdu->rb_size, - pusch_pdu->nr_of_symbols, - num_dmrs_symb * 12, // nb dmrs set for no data in dmrs symbol - 0, // nb_rb_oh - 0, // to verify tb scaling - pusch_pdu->nrOfLayers) - >> 3; + R, + pusch_pdu->rb_size, + pusch_pdu->nr_of_symbols, + num_dmrs_symb * 12, // nb dmrs set for no data in dmrs symbol + 0, // nb_rb_oh + 0, // to verify tb scaling + pusch_pdu->nrOfLayers) + >> 3; pusch_pdu->pusch_data.tb_size = TBS; pusch_pdu->maintenance_parms_v3.ldpcBaseGraph = get_BG(TBS << 3, R); + pusch_pdu->param_v4.numSpatialStreamIndices = nr_mac->radio_config.pusch_AntennaPorts; + LOG_D(NR_MAC, "Scheduling MsgA PUSCH in %d.%d\n", msgA_pusch_frame, msgA_pusch_slot); + LOG_D(NR_MAC, + "pdu_bit_map %d rnti %d handle %d rb_size %d mcs_table %d frequency_hopping %d dmrs_ports %d start_symbol_index %d " + "nr_of_symbols %d new_data_indicator %d num_dmrs_cdm_grps_no_data %d ul_dmrs_symb_pos %d transform_precoding %d rb_start " + "%d bwp_size %d bwp_start %d ul_dmrs_scrambling_id %d mcs_index %d qam_mod_order %d target_code_rate %d tb_size %d " + "ldpcBaseGraph %d numSpatialStreamIndices %d\n", + pusch_pdu->pdu_bit_map, + pusch_pdu->rnti, + pusch_pdu->handle, + pusch_pdu->rb_size, + pusch_pdu->mcs_table, + pusch_pdu->frequency_hopping, + pusch_pdu->dmrs_ports, + pusch_pdu->start_symbol_index, + pusch_pdu->nr_of_symbols, + pusch_pdu->pusch_data.new_data_indicator, + pusch_pdu->num_dmrs_cdm_grps_no_data, + pusch_pdu->ul_dmrs_symb_pos, + pusch_pdu->transform_precoding, + pusch_pdu->rb_start, + pusch_pdu->bwp_size, + pusch_pdu->bwp_start, + pusch_pdu->ul_dmrs_scrambling_id, + pusch_pdu->mcs_index, + pusch_pdu->qam_mod_order, + pusch_pdu->target_code_rate, + pusch_pdu->pusch_data.tb_size, + pusch_pdu->maintenance_parms_v3.ldpcBaseGraph, + pusch_pdu->param_v4.numSpatialStreamIndices); + UL_tti_req->n_pdus += 1; } From 5355cea93a44aafee7c9dd0823b1bf9bc4dc4dce Mon Sep 17 00:00:00 2001 From: Nuno Domingues Date: Mon, 29 Jun 2026 17:42:47 +0100 Subject: [PATCH 10/10] Add RA 2-Step variables for the CI test Signed-off-by: Nuno Domingues --- .../gnb-du.sa.band78.106prb.rfsim.conf | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/ci-scripts/conf_files/gnb-du.sa.band78.106prb.rfsim.conf b/ci-scripts/conf_files/gnb-du.sa.band78.106prb.rfsim.conf index d31988f1f1..e2a252ba52 100644 --- a/ci-scripts/conf_files/gnb-du.sa.band78.106prb.rfsim.conf +++ b/ci-scripts/conf_files/gnb-du.sa.band78.106prb.rfsim.conf @@ -109,6 +109,29 @@ gNBs = msg3_DeltaPreamble = 1; p0_NominalWithGrant =-90; + # 0=sl1, 1=sl2, 2=sl4, 3=sl8, 4=sl10, 5=sl20, 6=sl40, 7=sl80, 8=sl160, 9=sl320 + msgB_ResponseWindow_r16 = 6; + msgA_RSRP_Threshold_r16 = 19; + + msgA_CB_PreamblesPerSSB_PerSharedRO_r16 = 1; + + msgA_MCS_r16 = 2; + nrofSlotsMsgA_PUSCH_r16 = 1; + # 0=one, 1=two, 2=three, 3=six + nrofMsgA_PO_PerSlot_r16 = 0; + msgA_PUSCH_TimeDomainOffset_r16 = 8; + startSymbolAndLengthMsgA_PO_r16 = 38; + mappingTypeMsgA_PUSCH_r16 = 1; + guardBandMsgA_PUSCH_r16 = 0; + frequencyStartMsgA_PUSCH_r16 = 0; + nrofPRBs_PerMsgA_PO_r16 = 8; + # 0=one, 1=two, 2=four, 3=eight + nrofMsgA_PO_FDM_r16 = 0; + msgA_PUSCH_NrofPorts_r16 = 1; + nrofDMRS_Sequences_r16 = 1; + # 0=enabled, 1=disabled + msgA_TransformPrecoder_r16 = 1; + # pucch-ConfigCommon setup : # pucchGroupHopping # 0 = neither, 1= group hopping, 2=sequence hopping