Merge remote-tracking branch 'origin/Fix_Msg3_RRCReestablishmentComplete_with_C-RNTI' into integration_2024_w13
This commit is contained in:
@@ -1112,7 +1112,7 @@ static void fill_msg3_pusch_pdu(nfapi_nr_pusch_pdu_t *pusch_pdu,
|
|||||||
int TBS = 0;
|
int TBS = 0;
|
||||||
while(TBS<7) { // TBS for msg3 is 7 bytes (except for RRCResumeRequest1 currently not implemented)
|
while(TBS<7) { // TBS for msg3 is 7 bytes (except for RRCResumeRequest1 currently not implemented)
|
||||||
mcsindex++;
|
mcsindex++;
|
||||||
AssertFatal(mcsindex<28,"Exceeding MCS limit for Msg3\n");
|
AssertFatal(mcsindex <= 28, "Exceeding MCS limit for Msg3\n");
|
||||||
int R = nr_get_code_rate_ul(mcsindex,pusch_pdu->mcs_table);
|
int R = nr_get_code_rate_ul(mcsindex,pusch_pdu->mcs_table);
|
||||||
pusch_pdu->target_code_rate = R;
|
pusch_pdu->target_code_rate = R;
|
||||||
pusch_pdu->qam_mod_order = nr_get_Qm_ul(mcsindex,pusch_pdu->mcs_table);
|
pusch_pdu->qam_mod_order = nr_get_Qm_ul(mcsindex,pusch_pdu->mcs_table);
|
||||||
@@ -1981,7 +1981,10 @@ static void nr_check_Msg4_Ack(module_id_t module_id, int CC_id, frame_t frame, s
|
|||||||
|
|
||||||
// Pause scheduling according to:
|
// Pause scheduling according to:
|
||||||
// 3GPP TS 38.331 Section 12 Table 12.1-1: UE performance requirements for RRC procedures for UEs
|
// 3GPP TS 38.331 Section 12 Table 12.1-1: UE performance requirements for RRC procedures for UEs
|
||||||
nr_mac_enable_ue_rrc_processing_timer(RC.nrmac[module_id], UE, false);
|
// Msg4 may transmit a RRCReconfiguration, for example when UE sends RRCReestablishmentComplete and MAC CE for C-RNTI in Msg3.
|
||||||
|
// In that case, gNB will generate a RRCReconfiguration that will be transmitted in Msg4, so we need to apply CellGroup after the Ack,
|
||||||
|
// 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(module_id, CC_id, frame, ra);
|
||||||
if (sched_ctrl->retrans_dl_harq.head >= 0) {
|
if (sched_ctrl->retrans_dl_harq.head >= 0) {
|
||||||
@@ -2160,8 +2163,6 @@ void nr_schedule_RA(module_id_t module_idP,
|
|||||||
case nrRA_Msg3_retransmission:
|
case nrRA_Msg3_retransmission:
|
||||||
nr_generate_Msg3_retransmission(module_idP, CC_id, frameP, slotP, ra, ul_dci_req);
|
nr_generate_Msg3_retransmission(module_idP, CC_id, frameP, slotP, ra, ul_dci_req);
|
||||||
break;
|
break;
|
||||||
case nrRA_Msg3_dcch_dtch:
|
|
||||||
/* fallthrough */
|
|
||||||
case nrRA_Msg4:
|
case nrRA_Msg4:
|
||||||
nr_generate_Msg4(module_idP, CC_id, frameP, slotP, ra, DL_req, TX_req);
|
nr_generate_Msg4(module_idP, CC_id, frameP, slotP, ra, DL_req, TX_req);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -40,6 +40,26 @@
|
|||||||
|
|
||||||
//#define SRS_IND_DEBUG
|
//#define SRS_IND_DEBUG
|
||||||
|
|
||||||
|
static rnti_t lcid_crnti_lookahead(uint8_t *pdu, int pdu_len)
|
||||||
|
{
|
||||||
|
uint16_t mac_len = 0;
|
||||||
|
uint16_t mac_subheader_len = 0;
|
||||||
|
while (pdu_len >= 3) {
|
||||||
|
if ((pdu[0] & 0x3F) == UL_SCH_LCID_C_RNTI) {
|
||||||
|
// Extract C-RNTI value
|
||||||
|
rnti_t crnti = ((pdu[1] & 0xFF) << 8) | (pdu[2] & 0xFF);
|
||||||
|
LOG_D(NR_MAC, "Received a MAC CE for C-RNTI with %04x\n", crnti);
|
||||||
|
return crnti;
|
||||||
|
}
|
||||||
|
if (!get_mac_len(pdu, pdu_len, &mac_len, &mac_subheader_len)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pdu += mac_len + mac_subheader_len;
|
||||||
|
pdu_len -= mac_len + mac_subheader_len;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int get_ul_tda(gNB_MAC_INST *nrmac, const NR_ServingCellConfigCommon_t *scc, int frame, int slot)
|
int get_ul_tda(gNB_MAC_INST *nrmac, const NR_ServingCellConfigCommon_t *scc, int frame, int slot)
|
||||||
{
|
{
|
||||||
/* we assume that this function is mutex-protected from outside */
|
/* we assume that this function is mutex-protected from outside */
|
||||||
@@ -220,26 +240,21 @@ static int nr_process_mac_pdu(instance_t module_idP,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case UL_SCH_LCID_C_RNTI:
|
case UL_SCH_LCID_C_RNTI:
|
||||||
|
|
||||||
for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) {
|
for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) {
|
||||||
NR_RA_t *ra = &RC.nrmac[module_idP]->common_channels[CC_id].ra[i];
|
NR_RA_t *ra = &RC.nrmac[module_idP]->common_channels[CC_id].ra[i];
|
||||||
if (ra->ra_state >= nrRA_WAIT_Msg3 && ra->rnti == UE->rnti) {
|
if (ra->ra_state == nrRA_gNB_IDLE && ra->rnti == UE->rnti) {
|
||||||
// remove UE context just created after Msg.3 in some milliseconds
|
// Extract C-RNTI value
|
||||||
// as the UE is one already known (not now, as the UE context is
|
rnti_t crnti = ((pduP[1] & 0xFF) << 8) | (pduP[2] & 0xFF);
|
||||||
// still needed for the moment)
|
AssertFatal(false,
|
||||||
nr_mac_trigger_release_timer(&UE->UE_sched_ctrl, UE->current_UL_BWP.scs);
|
"Received MAC CE for C-RNTI %04x without RA running, procedure exists? Or is it a bug while decoding the "
|
||||||
//mac_remove_nr_ue(RC.nrmac[module_idP], ra->rnti);
|
"MAC PDU?\n",
|
||||||
// this UE is the one identified by the RNTI in pduP
|
crnti);
|
||||||
ra->rnti = ((pduP[1]&0xFF)<<8)|(pduP[2]&0xFF);
|
|
||||||
ra->ra_state = nrRA_Msg3_dcch_dtch;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 38.321 section 6.1.3.2
|
||||||
//38.321 section 6.1.3.2
|
// fixed length
|
||||||
//fixed length
|
|
||||||
mac_len = 2;
|
mac_len = 2;
|
||||||
/* Extract CRNTI value */
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case UL_SCH_LCID_SINGLE_ENTRY_PHR:
|
case UL_SCH_LCID_SINGLE_ENTRY_PHR:
|
||||||
@@ -310,39 +325,28 @@ static int nr_process_mac_pdu(instance_t module_idP,
|
|||||||
LOG_E(NR_MAC, "pdu_len %d is invalid (shorter than MAC PDU header)\n", pdu_len);
|
LOG_E(NR_MAC, "pdu_len %d is invalid (shorter than MAC PDU header)\n", pdu_len);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
LOG_D(NR_MAC, "UE %04x %d.%d: Received LCID %d bytes %d\n", UE->rnti, frameP, slot, rx_lcid, mac_len);
|
||||||
|
|
||||||
rnti_t crnti = UE->rnti;
|
AssertFatal(UE->CellGroup,
|
||||||
NR_UE_info_t* UE_idx = UE;
|
"UE %04x %d.%d: Received LCID %d which is not configured (UE has no CellGroup)\n",
|
||||||
for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) {
|
UE->rnti,
|
||||||
NR_RA_t *ra = &RC.nrmac[module_idP]->common_channels[CC_id].ra[i];
|
frameP,
|
||||||
if (ra->ra_state >= nrRA_WAIT_Msg3 && ra->rnti == UE->rnti) {
|
slot,
|
||||||
uint8_t *next_subpduP = pduP + mac_subheader_len + mac_len;
|
rx_lcid);
|
||||||
if ((pduP[mac_subheader_len+mac_len] & 0x3F) == UL_SCH_LCID_C_RNTI) {
|
|
||||||
crnti = ((next_subpduP[1]&0xFF)<<8)|(next_subpduP[2]&0xFF);
|
|
||||||
LOG_W(NR_MAC, " UL_SCH_LCID_SRB for rnti %04x\n", crnti);
|
|
||||||
UE_idx = find_nr_UE(&RC.nrmac[module_idP]->UE_info, crnti);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (UE_idx->CellGroup) {
|
mac_rlc_data_ind(module_idP,
|
||||||
LOG_D(NR_MAC, "Frame %d : ULSCH -> UL-DCCH %d (gNB %ld, %d bytes), rnti: 0x%04x \n", frameP, rx_lcid, module_idP, mac_len, crnti);
|
UE->rnti,
|
||||||
UE->mac_stats.ul.total_sdu_bytes += mac_len;
|
module_idP,
|
||||||
mac_rlc_data_ind(module_idP,
|
frameP,
|
||||||
crnti,
|
ENB_FLAG_YES,
|
||||||
module_idP,
|
MBMS_FLAG_NO,
|
||||||
frameP,
|
rx_lcid,
|
||||||
ENB_FLAG_YES,
|
(char *)(pduP + mac_subheader_len),
|
||||||
MBMS_FLAG_NO,
|
mac_len,
|
||||||
rx_lcid,
|
1,
|
||||||
(char *) (pduP + mac_subheader_len),
|
NULL);
|
||||||
mac_len,
|
|
||||||
1,
|
UE->mac_stats.ul.total_sdu_bytes += mac_len;
|
||||||
NULL);
|
|
||||||
} else {
|
|
||||||
AssertFatal(1==0,"[UE %04x] Frame/Slot %d.%d : Received LCID %d which is not configured, dropping packet\n",UE->rnti,frameP,slot,rx_lcid);
|
|
||||||
}
|
|
||||||
UE->mac_stats.ul.lc_bytes[rx_lcid] += mac_len;
|
UE->mac_stats.ul.lc_bytes[rx_lcid] += mac_len;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -710,129 +714,136 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP,
|
|||||||
NR_RA_t *ra = &gNB_mac->common_channels[CC_idP].ra[i];
|
NR_RA_t *ra = &gNB_mac->common_channels[CC_idP].ra[i];
|
||||||
if (ra->ra_state != nrRA_WAIT_Msg3)
|
if (ra->ra_state != nrRA_WAIT_Msg3)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if(no_sig) {
|
if (no_sig) {
|
||||||
LOG_D(NR_MAC, "Random Access %i failed at state %s (no signal)\n", i, nrra_text[ra->ra_state]);
|
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(gnb_mod_idP, CC_idP, frameP, ra);
|
||||||
} else {
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// random access pusch with TC-RNTI
|
// random access pusch with TC-RNTI
|
||||||
if (ra->rnti != current_rnti) {
|
if (ra->rnti != current_rnti) {
|
||||||
LOG_D(NR_MAC,
|
LOG_D(NR_MAC, "expected TC_RNTI %04x to match current RNTI %04x\n", ra->rnti, current_rnti);
|
||||||
"expected TC_RNTI %04x to match current RNTI %04x\n",
|
|
||||||
ra->rnti,
|
|
||||||
current_rnti);
|
|
||||||
|
|
||||||
if( (frameP==ra->Msg3_frame) && (slotP==ra->Msg3_slot) ) {
|
if ((frameP == ra->Msg3_frame) && (slotP == ra->Msg3_slot)) {
|
||||||
LOG_D(NR_MAC,
|
|
||||||
"Random Access %i failed at state %s (TC_RNTI %04x RNTI %04x)\n",
|
|
||||||
i,
|
|
||||||
nrra_text[ra->ra_state],
|
|
||||||
ra->rnti,
|
|
||||||
current_rnti);
|
|
||||||
nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra);
|
|
||||||
}
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
NR_UE_info_t *UE_msg3_stage = UE ? UE : add_new_nr_ue(gNB_mac, ra->rnti, ra->CellGroup);
|
|
||||||
if (!UE_msg3_stage) {
|
|
||||||
LOG_W(NR_MAC,
|
LOG_W(NR_MAC,
|
||||||
"Random Access %i discarded at state %s (TC_RNTI %04x RNTI %04x): max number of users achieved!\n",
|
"Random Access %i failed at state %s (TC_RNTI %04x RNTI %04x)\n",
|
||||||
i,
|
i,
|
||||||
nrra_text[ra->ra_state],
|
nrra_text[ra->ra_state],
|
||||||
ra->rnti,
|
ra->rnti,
|
||||||
current_rnti);
|
current_rnti);
|
||||||
|
|
||||||
nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra);
|
nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UE_msg3_stage->UE_beam_index = ra->beam_id;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// re-initialize ta update variables after RA procedure completion
|
UE = UE ? UE : add_new_nr_ue(gNB_mac, ra->rnti, ra->CellGroup);
|
||||||
UE_msg3_stage->UE_sched_ctrl.ta_frame = frameP;
|
if (!UE) {
|
||||||
|
LOG_W(NR_MAC,
|
||||||
LOG_D(NR_MAC,
|
"Random Access %i discarded at state %s (TC_RNTI %04x RNTI %04x): max number of users achieved!\n",
|
||||||
"reset RA state information for RA-RNTI 0x%04x/index %d\n",
|
i,
|
||||||
|
nrra_text[ra->ra_state],
|
||||||
ra->rnti,
|
ra->rnti,
|
||||||
i);
|
current_rnti);
|
||||||
|
|
||||||
LOG_I(NR_MAC,
|
nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra);
|
||||||
"[gNB %d][RAPROC] PUSCH with TC_RNTI 0x%04x received correctly, "
|
return;
|
||||||
"adding UE MAC Context RNTI 0x%04x\n",
|
}
|
||||||
gnb_mod_idP,
|
|
||||||
current_rnti,
|
|
||||||
ra->rnti);
|
|
||||||
|
|
||||||
NR_UE_sched_ctrl_t *UE_scheduling_control = &UE_msg3_stage->UE_sched_ctrl;
|
UE->UE_beam_index = ra->beam_id;
|
||||||
|
|
||||||
if (ul_cqi != 0xff) {
|
// re-initialize ta update variables after RA procedure completion
|
||||||
UE_scheduling_control->pusch_snrx10 = ul_cqi * 5 - 640;
|
UE->UE_sched_ctrl.ta_frame = frameP;
|
||||||
UE_scheduling_control->tpc0 = nr_get_tpc(target_snrx10, UE_scheduling_control->pusch_snrx10, 30);
|
|
||||||
|
LOG_I(NR_MAC,
|
||||||
|
"[gNB %d][RAPROC] PUSCH with TC_RNTI 0x%04x received correctly, "
|
||||||
|
"adding UE MAC Context RNTI 0x%04x\n",
|
||||||
|
gnb_mod_idP,
|
||||||
|
current_rnti,
|
||||||
|
ra->rnti);
|
||||||
|
|
||||||
|
NR_UE_sched_ctrl_t *UE_scheduling_control = &UE->UE_sched_ctrl;
|
||||||
|
|
||||||
|
if (ul_cqi != 0xff) {
|
||||||
|
UE_scheduling_control->pusch_snrx10 = ul_cqi * 5 - 640;
|
||||||
|
UE_scheduling_control->tpc0 = nr_get_tpc(target_snrx10, UE_scheduling_control->pusch_snrx10, 30);
|
||||||
|
}
|
||||||
|
if (timing_advance != 0xffff)
|
||||||
|
UE_scheduling_control->ta_update = timing_advance;
|
||||||
|
UE_scheduling_control->raw_rssi = rssi;
|
||||||
|
LOG_D(NR_MAC, "[UE %04x] PUSCH TPC %d and TA %d\n", UE->rnti, UE_scheduling_control->tpc0, UE_scheduling_control->ta_update);
|
||||||
|
if (ra->cfra) {
|
||||||
|
LOG_A(NR_MAC, "(rnti 0x%04x) CFRA procedure succeeded!\n", ra->rnti);
|
||||||
|
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);
|
||||||
|
process_CellGroup(ra->CellGroup, UE);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
LOG_A(NR_MAC, "[RAPROC] RA-Msg3 received (sdu_lenP %d)\n", sdu_lenP);
|
||||||
|
LOG_D(NR_MAC, "[RAPROC] Received Msg3:\n");
|
||||||
|
for (int k = 0; k < sdu_lenP; k++) {
|
||||||
|
LOG_D(NR_MAC, "(%i): 0x%x\n", k, sduP[k]);
|
||||||
}
|
}
|
||||||
if (timing_advance != 0xffff)
|
|
||||||
UE_scheduling_control->ta_update = timing_advance;
|
|
||||||
UE_scheduling_control->raw_rssi = rssi;
|
|
||||||
LOG_D(NR_MAC, "[UE %04x] PUSCH TPC %d and TA %d\n", UE_msg3_stage->rnti, UE_scheduling_control->tpc0, UE_scheduling_control->ta_update);
|
|
||||||
if (ra->cfra) {
|
|
||||||
LOG_A(NR_MAC, "(rnti 0x%04x) CFRA procedure succeeded!\n", ra->rnti);
|
|
||||||
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);
|
|
||||||
process_CellGroup(ra->CellGroup, UE_msg3_stage);
|
|
||||||
|
|
||||||
} else {
|
// 3GPP TS 38.321 Section 5.4.3 Multiplexing and assembly
|
||||||
|
// Logical channels shall be prioritised in accordance with the following order (highest priority listed first):
|
||||||
|
// - MAC CE for C-RNTI, or data from UL-CCCH;
|
||||||
|
// This way, we need to process MAC CE for C-RNTI if RA is active and it is present in the MAC PDU
|
||||||
|
// Search for MAC CE for C-RNTI
|
||||||
|
rnti_t crnti = lcid_crnti_lookahead(sduP, sdu_lenP);
|
||||||
|
if (crnti != 0) { // 3GPP TS 38.321 Table 7.1-1: RNTI values, RNTI 0x0000: N/A
|
||||||
|
// this UE is the one identified by the RNTI in sduP
|
||||||
|
ra->rnti = crnti;
|
||||||
|
// Remove UE context just created after Msg.3 in some milliseconds as the UE is one already known (not now, as the UE
|
||||||
|
// context is still needed for the moment)
|
||||||
|
nr_mac_trigger_release_timer(&UE->UE_sched_ctrl, UE->current_UL_BWP.scs);
|
||||||
|
|
||||||
LOG_A(NR_MAC,"[RAPROC] RA-Msg3 received (sdu_lenP %d)\n",sdu_lenP);
|
// Replace the current UE by the UE identified by C-RNTI
|
||||||
LOG_D(NR_MAC,"[RAPROC] Received Msg3:\n");
|
UE = find_nr_UE(&RC.nrmac[gnb_mod_idP]->UE_info, crnti);
|
||||||
for (int k = 0; k < sdu_lenP; k++) {
|
if (!UE) {
|
||||||
LOG_D(NR_MAC,"(%i): 0x%x\n",k,sduP[k]);
|
// The UE identified by C-RNTI no longer exists at the gNB
|
||||||
|
// Let's abort the current RA, so the UE will trigger a new RA later but using RRCSetupRequest instead. A better
|
||||||
|
// 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);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The UE identified by C-RNTI still exists at the gNB
|
||||||
|
// Reset Msg4_ACKed to not schedule ULSCH and DLSCH before RRC Reconfiguration
|
||||||
|
UE->Msg4_ACKed = false;
|
||||||
|
nr_mac_reset_ul_failure(&UE->UE_sched_ctrl);
|
||||||
|
// Reset HARQ processes
|
||||||
|
reset_dl_harq_list(&UE->UE_sched_ctrl);
|
||||||
|
reset_ul_harq_list(&UE->UE_sched_ctrl);
|
||||||
|
|
||||||
|
if (UE->reconfigCellGroup) {
|
||||||
|
// Nothing to do
|
||||||
|
// A RRCReconfiguration message should be already pending (for example, an ongoing RRCReestablishment), and it will be
|
||||||
|
// transmitted in Msg4
|
||||||
|
} else {
|
||||||
|
// Trigger RRC Reconfiguration
|
||||||
|
LOG_I(NR_MAC, "Received UL_SCH_LCID_C_RNTI with C-RNTI 0x%04x, triggering RRC Reconfiguration\n", UE->rnti);
|
||||||
|
nr_mac_trigger_reconfiguration(RC.nrmac[gnb_mod_idP], UE);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
// UE Contention Resolution Identity
|
// UE Contention Resolution Identity
|
||||||
// Store the first 48 bits belonging to the uplink CCCH SDU within Msg3 to fill in Msg4
|
// Store the first 48 bits belonging to the uplink CCCH SDU within Msg3 to fill in Msg4
|
||||||
// First byte corresponds to R/LCID MAC sub-header
|
// First byte corresponds to R/LCID MAC sub-header
|
||||||
memcpy(ra->cont_res_id, &sduP[1], sizeof(uint8_t) * 6);
|
memcpy(ra->cont_res_id, &sduP[1], sizeof(uint8_t) * 6);
|
||||||
// harq_pid set a non valid value because it is not used in this call
|
|
||||||
// the function is only called to decode the contention resolution sub-header
|
|
||||||
if (nr_process_mac_pdu(gnb_mod_idP, UE_msg3_stage, CC_idP, frameP, slotP, sduP, sdu_lenP, -1) == 0) {
|
|
||||||
if (ra->ra_state == nrRA_Msg3_dcch_dtch) {
|
|
||||||
// Check if the UE identified by C-RNTI still exists at the gNB
|
|
||||||
NR_UE_info_t * UE_C = find_nr_UE(&gNB_mac->UE_info, ra->rnti);
|
|
||||||
if (!UE_C) {
|
|
||||||
// The UE identified by C-RNTI no longer exists at the gNB
|
|
||||||
// Let's abort the current RA, so the UE will trigger a new RA later but using RRCSetupRequest instead. A better solution may be implemented
|
|
||||||
mac_remove_nr_ue(gNB_mac, ra->rnti);
|
|
||||||
nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra);
|
|
||||||
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);
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
// Reset Msg4_ACKed to not schedule ULSCH and DLSCH before RRC Reconfiguration
|
|
||||||
UE_C->Msg4_ACKed = false;
|
|
||||||
|
|
||||||
// The UE identified by C-RNTI still exists at the gNB
|
|
||||||
nr_mac_reset_ul_failure(&UE_C->UE_sched_ctrl);
|
|
||||||
|
|
||||||
// Reset HARQ processes
|
|
||||||
reset_dl_harq_list(&UE_C->UE_sched_ctrl);
|
|
||||||
reset_ul_harq_list(&UE_C->UE_sched_ctrl);
|
|
||||||
|
|
||||||
// Trigger RRC Reconfiguration
|
|
||||||
LOG_I(NR_MAC, "Received UL_SCH_LCID_C_RNTI with C-RNTI 0x%04x, triggering RRC Reconfiguration\n", UE_C->rnti);
|
|
||||||
nr_mac_trigger_reconfiguration(RC.nrmac[gnb_mod_idP], UE_C);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
LOG_I(NR_MAC, "Activating scheduling RA-Msg4 for TC_RNTI 0x%04x (state %s)\n", ra->rnti, nrra_text[ra->ra_state]);
|
|
||||||
ra->ra_state = nrRA_Msg4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Decode MAC PDU for the correct UE, after checking for MAC CE for C-RNTI
|
||||||
|
// harq_pid set a non valid value because it is not used in this call
|
||||||
|
// the function is only called to decode the contention resolution sub-header
|
||||||
|
nr_process_mac_pdu(gnb_mod_idP, UE, CC_idP, frameP, slotP, sduP, sdu_lenP, -1);
|
||||||
|
|
||||||
|
LOG_I(NR_MAC, "Activating scheduling RA-Msg4 for TC_RNTI 0x%04x (state %s)\n", ra->rnti, nrra_text[ra->ra_state]);
|
||||||
|
ra->ra_state = nrRA_Msg4;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -116,9 +116,8 @@ typedef enum {
|
|||||||
nrRA_Msg2 = 1,
|
nrRA_Msg2 = 1,
|
||||||
nrRA_WAIT_Msg3 = 2,
|
nrRA_WAIT_Msg3 = 2,
|
||||||
nrRA_Msg3_retransmission = 3,
|
nrRA_Msg3_retransmission = 3,
|
||||||
nrRA_Msg3_dcch_dtch = 4,
|
nrRA_Msg4 = 4,
|
||||||
nrRA_Msg4 = 5,
|
nrRA_WAIT_Msg4_ACK = 5,
|
||||||
nrRA_WAIT_Msg4_ACK = 6
|
|
||||||
} RA_gNB_state_t;
|
} RA_gNB_state_t;
|
||||||
static const char *const nrra_text[] =
|
static const char *const nrra_text[] =
|
||||||
{"IDLE", "Msg2", "WAIT_Msg3", "Msg3_retransmission", "Msg3_dcch_dtch", "Msg4", "WAIT_Msg4_ACK"};
|
{"IDLE", "Msg2", "WAIT_Msg3", "Msg3_retransmission", "Msg3_dcch_dtch", "Msg4", "WAIT_Msg4_ACK"};
|
||||||
|
|||||||
Reference in New Issue
Block a user