Commit 6fe7581e authored by Robert Schmidt's avatar Robert Schmidt

Merge remote-tracking branch 'origin/cfra-no-msg3' into integration_2025_w48

CFRA: mark RA complete when sending Msg2

The current contention-free random access forces a "Msg3" (which does
not exist in CFRA) to be received by a UE. Sometimes, this "Msg3" is not
received (for whatever reason), and the MAC declare that RA failed.

This is problematic, as the spec says that RA is complete once Msg2 is
received by the UE. Since the gNB cannot know when this is, simply mark
it as complete once we sent Msg2.

We still send Msg3 in CFRA, which is explained further in the commits.

Also, improve logging and stabilize an RFsim test by reducing sl_ahead.
parents 2ff7a56b 1368bb5a
...@@ -195,6 +195,7 @@ RUs = ( ...@@ -195,6 +195,7 @@ RUs = (
max_pdschReferenceSignalPower = -27; max_pdschReferenceSignalPower = -27;
max_rxgain = 50; max_rxgain = 50;
eNB_instances = [0]; eNB_instances = [0];
sl_ahead = 3;
sdr_addrs = "addr=192.168.10.2,second_addr=192.168.20.2"; sdr_addrs = "addr=192.168.10.2,second_addr=192.168.20.2";
} }
); );
......
...@@ -1148,14 +1148,23 @@ void nr_mac_prepare_ra_ue(gNB_MAC_INST *nrmac, NR_UE_info_t *UE) ...@@ -1148,14 +1148,23 @@ void nr_mac_prepare_ra_ue(gNB_MAC_INST *nrmac, NR_UE_info_t *UE)
uint8_t num_preamble = cfra->resources.choice.ssb->ssb_ResourceList.list.count; uint8_t num_preamble = cfra->resources.choice.ssb->ssb_ResourceList.list.count;
ra->preambles.num_preambles = num_preamble; ra->preambles.num_preambles = num_preamble;
NR_COMMON_channels_t *cc = &nrmac->common_channels[0]; NR_COMMON_channels_t *cc = &nrmac->common_channels[0];
char buf[200];
int idx = 0;
for (int i = 0; i < cc->num_active_ssb; i++) { for (int i = 0; i < cc->num_active_ssb; i++) {
for (int j = 0; j < num_preamble; j++) { for (int j = 0; j < num_preamble; j++) {
if (cc->ssb_index[i] == cfra->resources.choice.ssb->ssb_ResourceList.list.array[j]->ssb) { if (cc->ssb_index[i] == cfra->resources.choice.ssb->ssb_ResourceList.list.array[j]->ssb) {
// one dedicated preamble for each beam // one dedicated preamble for each beam
ra->preambles.preamble_list[i] = cfra->resources.choice.ssb->ssb_ResourceList.list.array[j]->ra_PreambleIndex; ra->preambles.preamble_list[i] = cfra->resources.choice.ssb->ssb_ResourceList.list.array[j]->ra_PreambleIndex;
if (idx < sizeof(buf) - 1)
idx += snprintf(buf + idx, sizeof(buf) - idx, " %d", ra->preambles.preamble_list[i]);
break; break;
} }
} }
} }
LOG_I(NR_MAC, "Added new %s process for UE RNTI %04x with initial CellGroup\n", ra->cfra ? "CFRA" : "CBRA", UE->rnti); LOG_I(NR_MAC,
"Added new %s process for UE RNTI %04x with initial CellGroup and %d preamble(s): %s\n",
ra->cfra ? "CFRA" : "CBRA",
UE->rnti,
num_preamble,
buf);
} }
...@@ -785,6 +785,7 @@ static void nr_generate_Msg3_retransmission(module_id_t module_idP, ...@@ -785,6 +785,7 @@ static void nr_generate_Msg3_retransmission(module_id_t module_idP,
{ {
gNB_MAC_INST *nr_mac = RC.nrmac[module_idP]; gNB_MAC_INST *nr_mac = RC.nrmac[module_idP];
NR_RA_t *ra = UE->ra; NR_RA_t *ra = UE->ra;
DevAssert(!ra->cfra);
NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id]; NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id];
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP; NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP;
...@@ -1451,6 +1452,11 @@ static void nr_generate_Msg2(module_id_t module_idP, ...@@ -1451,6 +1452,11 @@ static void nr_generate_Msg2(module_id_t module_idP,
return; return;
const NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP; const NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP;
// check the feasibility of Msg3, the actual Msg3 allocation
// is further below. In the case of CFRA, we don't need Msg3, but 38.321
// §5.1.4 does not clearly exclude Msg3, and UL TA might still be useful.
// Before the change in this commit, we used CFRA but required Msg3, which
// COTS UE would often (but not always) send.
bool ret = get_feasible_msg3_tda(scc, bool ret = get_feasible_msg3_tda(scc,
get_delta_for_k2(ul_bwp->scs), get_delta_for_k2(ul_bwp->scs),
ul_bwp->tdaList_Common, ul_bwp->tdaList_Common,
...@@ -1523,6 +1529,7 @@ static void nr_generate_Msg2(module_id_t module_idP, ...@@ -1523,6 +1529,7 @@ static void nr_generate_Msg2(module_id_t module_idP,
return; return;
} }
// get an actual Msg3 allocation in CBRA
bool msg3_ret = nr_get_Msg3alloc(nr_mac, CC_id, slotP, frameP, UE); bool msg3_ret = nr_get_Msg3alloc(nr_mac, CC_id, slotP, frameP, UE);
if (!msg3_ret) { if (!msg3_ret) {
reset_beam_status(&nr_mac->beam_info, ra->Msg3_frame, ra->Msg3_slot, UE->UE_beam_index, n_slots_frame, ra->Msg3_beam.new_beam); reset_beam_status(&nr_mac->beam_info, ra->Msg3_frame, ra->Msg3_slot, UE->UE_beam_index, n_slots_frame, ra->Msg3_beam.new_beam);
...@@ -1609,27 +1616,31 @@ static void nr_generate_Msg2(module_id_t module_idP, ...@@ -1609,27 +1616,31 @@ static void nr_generate_Msg2(module_id_t module_idP,
// DL TX request // DL TX request
nfapi_nr_pdu_t *tx_req = &TX_req->pdu_list[TX_req->Number_of_PDUs]; nfapi_nr_pdu_t *tx_req = &TX_req->pdu_list[TX_req->Number_of_PDUs];
// Program UL processing for Msg3 // If CFRA: 38.321 §5.1.4 does not clearly say (to me) if UL grant should be
// dropped or not, and COTS UE would often send Msg3 if we configured CFRA
// but required Msg3. Also, "if RAR includes a MAC subPDU with RAPID: [...]
// indicate the reception of an acknowledgement for SI request to upper
// layers." which is not the case here.
nr_add_msg3(module_idP, CC_id, frameP, slotP, UE, (uint8_t *)&tx_req->TLVs[0].value.direct[0]); nr_add_msg3(module_idP, CC_id, frameP, slotP, UE, (uint8_t *)&tx_req->TLVs[0].value.direct[0]);
// Start RA contention resolution timer in Msg3 transmission slot (current slot + K2) if (!ra->cfra) {
// 3GPP TS 38.321 Section 5.1.5 Contention Resolution LOG_D(NR_MAC,
start_ra_contention_resolution_timer( "UE %04x: %d.%d: Setting RA-Msg3 reception for SFN.Slot %d.%d\n",
ra, UE->rnti,
scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->ra_ContentionResolutionTimer, frameP,
*ul_bwp->tdaList_Common->list.array[ra->Msg3_tda_id]->k2 + get_NTN_Koffset(scc), slotP,
ul_bwp->scs); ra->Msg3_frame,
ra->Msg3_slot);
LOG_D(NR_MAC, // Start RA contention resolution timer in Msg3 transmission slot (current slot + K2)
"UE %04x: %d.%d: Setting RA-Msg3 reception (%s) for SFN.Slot %d.%d\n", // 3GPP TS 38.321 Section 5.1.5 Contention Resolution
UE->rnti, start_ra_contention_resolution_timer(
frameP, ra,
slotP, scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->ra_ContentionResolutionTimer,
ra->cfra ? "CFRA" : "CBRA", *ul_bwp->tdaList_Common->list.array[ra->Msg3_tda_id]->k2 + get_NTN_Koffset(scc),
ra->Msg3_frame, ul_bwp->scs);
ra->Msg3_slot);
LOG_A(NR_MAC, "%d.%d Send RAR to RA-RNTI %04x\n", frameP, slotP, ra->RA_rnti); }
tx_req->PDU_index = pduindex; tx_req->PDU_index = pduindex;
tx_req->num_TLV = 1; tx_req->num_TLV = 1;
...@@ -1654,6 +1665,7 @@ static void nr_generate_Msg2(module_id_t module_idP, ...@@ -1654,6 +1665,7 @@ static void nr_generate_Msg2(module_id_t module_idP,
vrb_map[bwp_info.bwpStart + rb + rbStart] |= SL_to_bitmap(tda_info.startSymbolIndex, tda_info.nrOfSymbols); vrb_map[bwp_info.bwpStart + rb + rbStart] |= SL_to_bitmap(tda_info.startSymbolIndex, tda_info.nrOfSymbols);
} }
// In CFRA: in Msg3 handling, will unconditionally mark succeeded
ra->ra_state = nrRA_WAIT_Msg3; ra->ra_state = nrRA_WAIT_Msg3;
} }
...@@ -1675,6 +1687,7 @@ static void nr_generate_Msg4_MsgB(module_id_t module_idP, ...@@ -1675,6 +1687,7 @@ static void nr_generate_Msg4_MsgB(module_id_t module_idP,
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
NR_SearchSpace_t *ss = sched_ctrl->search_space; NR_SearchSpace_t *ss = sched_ctrl->search_space;
NR_RA_t *ra = UE->ra; NR_RA_t *ra = UE->ra;
DevAssert(!ra->cfra);
const char *ra_type_str = ra->ra_type == RA_2_STEP ? "MsgB" : "Msg4"; const char *ra_type_str = ra->ra_type == RA_2_STEP ? "MsgB" : "Msg4";
NR_ControlResourceSet_t *coreset = sched_ctrl->coreset; NR_ControlResourceSet_t *coreset = sched_ctrl->coreset;
AssertFatal(coreset != NULL, "Coreset cannot be null for RA %s\n", ra_type_str); AssertFatal(coreset != NULL, "Coreset cannot be null for RA %s\n", ra_type_str);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment