Commit e689e4b2 authored by ndomingues's avatar ndomingues

Baseline implementation of RA 2-Step MsgA procedures at gNB

parent da922910
...@@ -258,6 +258,118 @@ void find_SSB_and_RO_available(gNB_MAC_INST *nrmac) ...@@ -258,6 +258,118 @@ void find_SSB_and_RO_available(gNB_MAC_INST *nrmac)
cc->total_prach_occasions_per_config_period); cc->total_prach_occasions_per_config_period);
} }
static void schedule_nr_MsgA_pusch(NR_ServingCellConfigCommon_t *scc,
gNB_MAC_INST *nr_mac,
module_id_t module_idP,
frame_t frameP,
sub_frame_t slotP,
nfapi_nr_prach_pdu_t *prach_pdu)
{
NR_SCHED_ENSURE_LOCKED(&nr_mac->sched_lock);
NR_MsgA_PUSCH_Resource_r16_t *msgA_PUSCH_Resource = scc->uplinkConfigCommon->initialUplinkBWP->ext1->msgA_ConfigCommon_r16->choice
.setup->msgA_PUSCH_Config_r16->msgA_PUSCH_ResourceGroupA_r16;
int mu;
if (scc->uplinkConfigCommon->initialUplinkBWP->ext1->msgA_ConfigCommon_r16->choice.setup->rach_ConfigCommonTwoStepRA_r16
.msgA_SubcarrierSpacing_r16)
mu = (int)*scc->uplinkConfigCommon->initialUplinkBWP->ext1->msgA_ConfigCommon_r16->choice.setup->rach_ConfigCommonTwoStepRA_r16
.msgA_SubcarrierSpacing_r16;
else
mu = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
const int n_slots_frame = nr_slots_per_frame[mu];
slot_t msgA_pusch_slot = (slotP + msgA_PUSCH_Resource->msgA_PUSCH_TimeDomainOffset_r16) % n_slots_frame;
frame_t msgA_pusch_frame = (frameP + ((slotP + msgA_PUSCH_Resource->msgA_PUSCH_TimeDomainOffset_r16) / n_slots_frame)) % 1024;
int index = ul_buffer_index((int)msgA_pusch_frame, (int)msgA_pusch_slot, mu, nr_mac->UL_tti_req_ahead_size);
nfapi_nr_ul_tti_request_t *UL_tti_req = &nr_mac[module_idP].UL_tti_req_ahead[0][index];
UL_tti_req->SFN = msgA_pusch_frame;
UL_tti_req->Slot = msgA_pusch_slot;
AssertFatal(is_xlsch_in_slot(nr_mac->ulsch_slot_bitmap[msgA_pusch_slot / 64], msgA_pusch_slot),
"Slot %d is not an Uplink slot, invalid msgA_PUSCH_TimeDomainOffset_r16 %ld\n",
msgA_pusch_slot,
msgA_PUSCH_Resource->msgA_PUSCH_TimeDomainOffset_r16);
UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE;
UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_pusch_pdu_t);
nfapi_nr_pusch_pdu_t *pusch_pdu = &UL_tti_req->pdus_list[UL_tti_req->n_pdus].pusch_pdu;
memset(pusch_pdu, 0, sizeof(nfapi_nr_pusch_pdu_t));
rnti_t ra_rnti = nr_get_ra_rnti(prach_pdu->prach_start_symbol, slotP, prach_pdu->num_ra, 0);
// Fill PUSCH PDU
pusch_pdu->pdu_bit_map = PUSCH_PDU_BITMAP_PUSCH_DATA;
pusch_pdu->rnti = ra_rnti;
pusch_pdu->handle = 0;
pusch_pdu->rb_size = msgA_PUSCH_Resource->nrofPRBs_PerMsgA_PO_r16;
pusch_pdu->mcs_table = 0;
pusch_pdu->frequency_hopping =
msgA_PUSCH_Resource->msgA_IntraSlotFrequencyHopping_r16 ? *msgA_PUSCH_Resource->msgA_IntraSlotFrequencyHopping_r16 : 0;
pusch_pdu->dmrs_ports = 1; // 6.2.2 in 38.214 only port 0 to be used
AssertFatal(msgA_PUSCH_Resource->startSymbolAndLengthMsgA_PO_r16,
"Only SLIV based on startSymbolAndLengthMsgA_PO_r16 implemented\n");
int S = 0;
int L = 0;
SLIV2SL(*msgA_PUSCH_Resource->startSymbolAndLengthMsgA_PO_r16, &S, &L);
pusch_pdu->start_symbol_index = S;
pusch_pdu->nr_of_symbols = L;
pusch_pdu->pusch_data.new_data_indicator = 1;
pusch_pdu->nrOfLayers = 1;
pusch_pdu->num_dmrs_cdm_grps_no_data = 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, scc->dmrs_TypeA_Position);
pusch_pdu->transform_precoding = 0;
pusch_pdu->rb_bitmap[0] = 0;
pusch_pdu->rb_start = msgA_PUSCH_Resource->frequencyStartMsgA_PUSCH_r16; // rb_start depends on the RO
pusch_pdu->bwp_size = NRRIV2BW(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
pusch_pdu->bwp_start =
NRRIV2PRBOFFSET(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
pusch_pdu->subcarrier_spacing = 0;
pusch_pdu->cyclic_prefix = 0;
pusch_pdu->uplink_frequency_shift_7p5khz = 0;
pusch_pdu->vrb_to_prb_mapping = 0;
pusch_pdu->dmrs_config_type = 0;
pusch_pdu->data_scrambling_id = 0;
if (msgA_PUSCH_Resource->msgA_DMRS_Config_r16.msgA_ScramblingID0_r16) {
pusch_pdu->ul_dmrs_scrambling_id = *msgA_PUSCH_Resource->msgA_DMRS_Config_r16.msgA_ScramblingID0_r16;
} else {
pusch_pdu->ul_dmrs_scrambling_id = *scc->physCellId;
}
pusch_pdu->scid =
0; // DMRS sequence initialization [TS38.211, sec 6.4.1.1.1]. Should match what is sent in DCI 0_1, otherwise set to 0.
pusch_pdu->pusch_identity = 0;
pusch_pdu->resource_alloc = 1; // type 1
pusch_pdu->tx_direct_current_location = 0;
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 = 0;
for (int i = 10; i < 10 + 3; i++)
num_dmrs_symb += (pusch_pdu->ul_dmrs_symb_pos >> i) & 1;
int TBS = 0;
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;
pusch_pdu->qam_mod_order = nr_get_Qm_ul(pusch_pdu->mcs_index, pusch_pdu->mcs_table);
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;
pusch_pdu->pusch_data.tb_size = TBS;
pusch_pdu->maintenance_parms_v3.ldpcBaseGraph = get_BG(TBS << 3, R);
LOG_D(NR_MAC, "Scheduling MsgA PUSCH in %d.%d\n", msgA_pusch_frame, msgA_pusch_slot);
UL_tti_req->n_pdus += 1;
}
void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP)
{ {
gNB_MAC_INST *gNB = RC.nrmac[module_idP]; gNB_MAC_INST *gNB = RC.nrmac[module_idP];
...@@ -411,7 +523,7 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP ...@@ -411,7 +523,7 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP
} }
if (scc->uplinkConfigCommon->initialUplinkBWP->ext1 if (scc->uplinkConfigCommon->initialUplinkBWP->ext1
&& scc->uplinkConfigCommon->initialUplinkBWP->ext1->msgA_ConfigCommon_r16) { && scc->uplinkConfigCommon->initialUplinkBWP->ext1->msgA_ConfigCommon_r16) {
schedule_nr_MsgA_pusch(module_idP, frameP, slotP, prach_pdu); schedule_nr_MsgA_pusch(scc, gNB, module_idP, frameP, slotP, prach_pdu);
} }
} }
} }
...@@ -429,125 +541,74 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP ...@@ -429,125 +541,74 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP
} }
} }
void schedule_nr_MsgA_pusch(module_id_t module_idP, frame_t frameP, sub_frame_t slotP, nfapi_nr_prach_pdu_t *prach_pdu) int nr_fill_successrar(const NR_UE_sched_ctrl_t *ue_sched_ctl,
rnti_t crnti,
const unsigned char *ue_cont_res_id,
uint8_t resource_indicator,
uint8_t timing_indicator,
unsigned char *mac_pdu,
int mac_pdu_length)
{ {
gNB_MAC_INST *gNB = RC.nrmac[module_idP]; LOG_D(NR_MAC, "mac_pdu_length = %d\n", mac_pdu_length);
int timing_advance_cmd = ue_sched_ctl->ta_update;
// TS 38.321 - Figure 6.1.5a-1: BI MAC subheader
NR_RA_HEADER_BI_MSGB *bi = (NR_RA_HEADER_BI_MSGB *)&mac_pdu[mac_pdu_length];
mac_pdu_length += sizeof(NR_RA_HEADER_BI_MSGB);
bi->E = 1;
bi->T1 = 0;
bi->T2 = 0;
bi->R = 0;
bi->BI = 0; // BI = 0, 5ms
// TS 38.321 - Figure 6.1.5a-3: SuccessRAR MAC subheader
NR_RA_HEADER_SUCCESS_RAR_MSGB *SUCESS_RAR_header = (NR_RA_HEADER_SUCCESS_RAR_MSGB *)&mac_pdu[mac_pdu_length];
mac_pdu_length += sizeof(NR_RA_HEADER_SUCCESS_RAR_MSGB);
SUCESS_RAR_header->E = 0;
SUCESS_RAR_header->T1 = 0;
SUCESS_RAR_header->T2 = 1;
SUCESS_RAR_header->S = 0;
SUCESS_RAR_header->R = 0;
// TS 38.321 - Figure 6.2.3a-2: successRAR
NR_MAC_SUCCESS_RAR *successRAR = (NR_MAC_SUCCESS_RAR *)&mac_pdu[mac_pdu_length];
mac_pdu_length += sizeof(NR_MAC_SUCCESS_RAR);
successRAR->CONT_RES_1 = ue_cont_res_id[0];
successRAR->CONT_RES_2 = ue_cont_res_id[1];
successRAR->CONT_RES_3 = ue_cont_res_id[2];
successRAR->CONT_RES_4 = ue_cont_res_id[3];
successRAR->CONT_RES_5 = ue_cont_res_id[4];
successRAR->CONT_RES_6 = ue_cont_res_id[5];
successRAR->R = 0;
successRAR->CH_ACESS_CPEXT = 1;
successRAR->TPC = ue_sched_ctl->tpc0;
successRAR->HARQ_FTI = timing_indicator;
successRAR->PUCCH_RI = resource_indicator;
successRAR->TA1 = (uint8_t)(timing_advance_cmd >> 8); // 4 MSBs of timing advance;
successRAR->TA2 = (uint8_t)(timing_advance_cmd & 0xff); // 8 LSBs of timing advance;
successRAR->CRNTI_1 = (uint8_t)(crnti >> 8); // 8 MSBs of rnti
successRAR->CRNTI_2 = (uint8_t)(crnti & 0xff); // 8 LSBs of rnti
/* already mutex protected: held in gNB_dlsch_ulsch_scheduler() */ LOG_D(NR_MAC,
NR_SCHED_ENSURE_LOCKED(&gNB->sched_lock); "successRAR: Contention Resolution ID 0x%02x%02x%02x%02x%02x%02x R 0x%01x CH_ACESS_CPEXT 0x%02x TPC 0x%02x HARQ_FTI 0x%03x "
"PUCCH_RI 0x%04x TA 0x%012x CRNTI 0x%04x\n",
NR_COMMON_channels_t *cc = gNB->common_channels; successRAR->CONT_RES_1,
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; successRAR->CONT_RES_2,
successRAR->CONT_RES_3,
NR_MsgA_PUSCH_Resource_r16_t *msgA_PUSCH_Resource = scc->uplinkConfigCommon->initialUplinkBWP->ext1->msgA_ConfigCommon_r16->choice successRAR->CONT_RES_4,
.setup->msgA_PUSCH_Config_r16->msgA_PUSCH_ResourceGroupA_r16; successRAR->CONT_RES_5,
successRAR->CONT_RES_6,
int mu; successRAR->R,
if (scc->uplinkConfigCommon->initialUplinkBWP->ext1->msgA_ConfigCommon_r16->choice.setup->rach_ConfigCommonTwoStepRA_r16 successRAR->CH_ACESS_CPEXT,
.msgA_SubcarrierSpacing_r16) successRAR->TPC,
mu = (int)*scc->uplinkConfigCommon->initialUplinkBWP->ext1->msgA_ConfigCommon_r16->choice.setup->rach_ConfigCommonTwoStepRA_r16 successRAR->HARQ_FTI,
.msgA_SubcarrierSpacing_r16; successRAR->PUCCH_RI,
else timing_advance_cmd,
mu = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing; crnti);
LOG_D(NR_MAC, "mac_pdu_length = %d\n", mac_pdu_length);
const int n_slots_frame = nr_slots_per_frame[mu]; return mac_pdu_length;
slot_t msgA_pusch_slot = (slotP + msgA_PUSCH_Resource->msgA_PUSCH_TimeDomainOffset_r16) % n_slots_frame;
frame_t msgA_pusch_frame = (frameP + ((slotP + msgA_PUSCH_Resource->msgA_PUSCH_TimeDomainOffset_r16) / n_slots_frame)) % 1024;
int index = ul_buffer_index((int)msgA_pusch_frame, (int)msgA_pusch_slot, mu, gNB->UL_tti_req_ahead_size);
nfapi_nr_ul_tti_request_t *UL_tti_req = &RC.nrmac[module_idP]->UL_tti_req_ahead[0][index];
UL_tti_req->SFN = msgA_pusch_frame;
UL_tti_req->Slot = msgA_pusch_slot;
// printf("msgA_pusch_frame = %d\n", msgA_pusch_frame);
// printf("msgA_pusch_slot = %d\n", msgA_pusch_slot);
AssertFatal(is_xlsch_in_slot(gNB->ulsch_slot_bitmap[msgA_pusch_slot / 64], msgA_pusch_slot),
"Slot %d is not an Uplink slot, invalid msgA_PUSCH_TimeDomainOffset_r16 %ld\n",
msgA_pusch_slot,
msgA_PUSCH_Resource->msgA_PUSCH_TimeDomainOffset_r16);
UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE;
UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_pusch_pdu_t);
nfapi_nr_pusch_pdu_t *pusch_pdu = &UL_tti_req->pdus_list[UL_tti_req->n_pdus].pusch_pdu;
memset(pusch_pdu, 0, sizeof(nfapi_nr_pusch_pdu_t));
rnti_t ra_rnti = nr_get_ra_rnti(prach_pdu->prach_start_symbol, slotP, prach_pdu->num_ra, 0);
// Fill PUSCH PDU
pusch_pdu->pdu_bit_map = PUSCH_PDU_BITMAP_PUSCH_DATA;
pusch_pdu->rnti = ra_rnti;
pusch_pdu->handle = 0;
pusch_pdu->rb_size = msgA_PUSCH_Resource->nrofPRBs_PerMsgA_PO_r16;
pusch_pdu->mcs_table = 0;
pusch_pdu->frequency_hopping =
msgA_PUSCH_Resource->msgA_IntraSlotFrequencyHopping_r16 ? *msgA_PUSCH_Resource->msgA_IntraSlotFrequencyHopping_r16 : 0;
pusch_pdu->dmrs_ports = 1; // 6.2.2 in 38.214 only port 0 to be used
int S = 0;
int L = 0;
if (msgA_PUSCH_Resource->startSymbolAndLengthMsgA_PO_r16) {
SLIV2SL((int)*msgA_PUSCH_Resource->startSymbolAndLengthMsgA_PO_r16, &S, &L);
} else if (msgA_PUSCH_Resource->msgA_PUSCH_TimeDomainAllocation_r16) {
AssertFatal(false, "Not implemented\n");
} else {
AssertFatal(false, "Either startSymbolAndLengthMsgA_PO_r16 or msgA_PUSCH_TimeDomainAllocation_r16 must be configured\n");
}
pusch_pdu->start_symbol_index = S;
pusch_pdu->nr_of_symbols = L;
pusch_pdu->pusch_data.new_data_indicator = 1;
pusch_pdu->nrOfLayers = 1;
pusch_pdu->num_dmrs_cdm_grps_no_data = 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, scc->dmrs_TypeA_Position);
pusch_pdu->transform_precoding = 0;
pusch_pdu->rb_bitmap[0] = 0;
pusch_pdu->rb_start = msgA_PUSCH_Resource->frequencyStartMsgA_PUSCH_r16; // rb_start depends on the RO
pusch_pdu->bwp_size = NRRIV2BW(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
pusch_pdu->bwp_start =
NRRIV2PRBOFFSET(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
pusch_pdu->subcarrier_spacing = 0;
pusch_pdu->cyclic_prefix = 0;
pusch_pdu->uplink_frequency_shift_7p5khz = 0;
pusch_pdu->vrb_to_prb_mapping = 0;
pusch_pdu->dmrs_config_type = 0;
pusch_pdu->data_scrambling_id = 0;
if (msgA_PUSCH_Resource->msgA_DMRS_Config_r16.msgA_ScramblingID0_r16) {
pusch_pdu->ul_dmrs_scrambling_id = *msgA_PUSCH_Resource->msgA_DMRS_Config_r16.msgA_ScramblingID0_r16;
} else {
pusch_pdu->ul_dmrs_scrambling_id = *scc->physCellId;
}
pusch_pdu->scid =
0; // DMRS sequence initialization [TS38.211, sec 6.4.1.1.1]. Should match what is sent in DCI 0_1, otherwise set to 0.
pusch_pdu->pusch_identity = 0;
pusch_pdu->resource_alloc = 1; // type 1
pusch_pdu->tx_direct_current_location = 0;
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 = 0;
for (int i = 10; i < 10 + 3; i++)
num_dmrs_symb += (pusch_pdu->ul_dmrs_symb_pos >> i) & 1;
int TBS = 0;
AssertFatal(0 < 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;
pusch_pdu->qam_mod_order = nr_get_Qm_ul(pusch_pdu->mcs_index, pusch_pdu->mcs_table);
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;
pusch_pdu->pusch_data.tb_size = TBS;
pusch_pdu->maintenance_parms_v3.ldpcBaseGraph = get_BG(TBS << 3, R);
// pusch_pdu->dmrs_config_type = msgA_PUSCH_Resource->msgA_DMRS_Config_r16;
LOG_D(NR_MAC, "Scheduling MsgA PUSCH in %d.%d\n", msgA_pusch_frame, msgA_pusch_slot);
UL_tti_req->n_pdus += 1;
} }
static bool ra_contains_preamble(const NR_RA_t *ra, uint16_t preamble_index) static bool ra_contains_preamble(const NR_RA_t *ra, uint16_t preamble_index)
...@@ -639,18 +700,27 @@ void nr_initiate_ra_proc(module_id_t module_idP, ...@@ -639,18 +700,27 @@ void nr_initiate_ra_proc(module_id_t module_idP,
ra->rnti = trial; ra->rnti = trial;
} }
ra->ra_state = nrRA_Msg2;
ra->preamble_frame = frameP; ra->preamble_frame = frameP;
ra->preamble_slot = slotP; ra->preamble_slot = slotP;
ra->preamble_index = preamble_index; ra->preamble_index = preamble_index;
ra->timing_offset = timing_offset; ra->timing_offset = timing_offset;
uint8_t ul_carrier_id = 0; // 0 for NUL 1 for SUL 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); ra->RA_rnti = nr_get_ra_rnti(symbol, slotP, freq_index, ul_carrier_id);
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
if (scc->uplinkConfigCommon->initialUplinkBWP->ext1 && scc->uplinkConfigCommon->initialUplinkBWP->ext1->msgA_ConfigCommon_r16) {
ra->ra_type = RA_2_STEP;
ra->ra_state = nrRA_WAIT_MsgA_PUSCH;
ra->MsgB_rnti = nr_get_MsgB_rnti(symbol, slotP, freq_index, ul_carrier_id);
} else {
ra->ra_type = RA_4_STEP;
ra->ra_state = nrRA_Msg2;
}
int index = ra - cc->ra; int index = ra - cc->ra;
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); 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 // Configure RA BWP
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
configure_UE_BWP(nr_mac, scc, NULL, ra, NULL, -1, -1); 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); uint8_t beam_index = ssb_index_from_prach(module_idP, frameP, slotP, preamble_index, freq_index, symbol);
...@@ -1835,7 +1905,7 @@ static void prepare_dl_pdus(gNB_MAC_INST *nr_mac, ...@@ -1835,7 +1905,7 @@ static void prepare_dl_pdus(gNB_MAC_INST *nr_mac,
LOG_D(NR_MAC, "numDlDci: %i\n", pdcch_pdu_rel15->numDlDci); LOG_D(NR_MAC, "numDlDci: %i\n", pdcch_pdu_rel15->numDlDci);
} }
static void nr_generate_Msg4(module_id_t module_idP, static void nr_generate_Msg4_MsgB(module_id_t module_idP,
int CC_id, int CC_id,
frame_t frameP, frame_t frameP,
sub_frame_t slotP, sub_frame_t slotP,
...@@ -1849,18 +1919,17 @@ static void nr_generate_Msg4(module_id_t module_idP, ...@@ -1849,18 +1919,17 @@ static void nr_generate_Msg4(module_id_t module_idP,
// if it is a DL slot, if the RA is in MSG4 state // if it is a DL slot, if the RA is in MSG4 state
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)) {
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
NR_SearchSpace_t *ss = ra->ra_ss; NR_SearchSpace_t *ss = ra->ra_ss;
const char *ra_type_str = ra->ra_type == RA_2_STEP ? "MsgB" : "Msg4";
NR_ControlResourceSet_t *coreset = ra->coreset; NR_ControlResourceSet_t *coreset = ra->coreset;
AssertFatal(coreset!=NULL,"Coreset cannot be null for RA-Msg4\n"); AssertFatal(coreset != NULL, "Coreset cannot be null for RA %s\n", ra_type_str);
uint16_t mac_sdu_length = 0; uint16_t mac_sdu_length = 0;
NR_UE_info_t *UE = find_nr_UE(&nr_mac->UE_info, ra->rnti); NR_UE_info_t *UE = find_nr_UE(&nr_mac->UE_info, ra->rnti);
if (!UE) { if (!UE) {
LOG_E(NR_MAC, "want to generate Msg4, but rnti %04x not in the table\n", ra->rnti); LOG_E(NR_MAC, "want to generate %s, but rnti %04x not in the table\n", ra_type_str, ra->rnti);
return; return;
} }
...@@ -1949,7 +2018,8 @@ static void nr_generate_Msg4(module_id_t module_idP, ...@@ -1949,7 +2018,8 @@ static void nr_generate_Msg4(module_id_t module_idP,
} }
else { else {
uint8_t subheader_len = (mac_sdu_length < 256) ? sizeof(NR_MAC_SUBHEADER_SHORT) : sizeof(NR_MAC_SUBHEADER_LONG); uint8_t subheader_len = (mac_sdu_length < 256) ? sizeof(NR_MAC_SUBHEADER_SHORT) : sizeof(NR_MAC_SUBHEADER_LONG);
pdu_length = mac_sdu_length + subheader_len + 7; //7 is contetion resolution length pdu_length = mac_sdu_length + subheader_len + 13; // 13 is contention resolution length of msgB. It is divided into 3 parts:
// BI MAC subheader (1 Oct) + SuccessRAR MAC subheader (1 Oct) + SuccessRAR (11 Oct)
} }
// increase PRBs until we get to BWPSize or TBS is bigger than MAC PDU size // increase PRBs until we get to BWPSize or TBS is bigger than MAC PDU size
...@@ -1964,7 +2034,7 @@ static void nr_generate_Msg4(module_id_t module_idP, ...@@ -1964,7 +2034,7 @@ static void nr_generate_Msg4(module_id_t module_idP,
rbSize, msg4_tda.nrOfSymbols, dmrs_info.N_PRB_DMRS * dmrs_info.N_DMRS_SLOT, 0, tb_scaling,1) >> 3; rbSize, msg4_tda.nrOfSymbols, dmrs_info.N_PRB_DMRS * dmrs_info.N_DMRS_SLOT, 0, tb_scaling,1) >> 3;
} while (tb_size < pdu_length && mcsIndex<=28); } while (tb_size < pdu_length && mcsIndex<=28);
AssertFatal(tb_size >= pdu_length,"Cannot allocate Msg4\n"); AssertFatal(tb_size >= pdu_length, "Cannot allocate %s\n", ra_type_str);
int i = 0; int i = 0;
uint16_t *vrb_map = cc[CC_id].vrb_map; uint16_t *vrb_map = cc[CC_id].vrb_map;
...@@ -1989,7 +2059,7 @@ static void nr_generate_Msg4(module_id_t module_idP, ...@@ -1989,7 +2059,7 @@ static void nr_generate_Msg4(module_id_t module_idP,
int alloc = nr_acknack_scheduling(nr_mac, UE, frameP, slotP, r_pucch, 1); int alloc = nr_acknack_scheduling(nr_mac, UE, frameP, slotP, r_pucch, 1);
if (alloc < 0) { if (alloc < 0) {
LOG_D(NR_MAC,"Couldn't find a pucch allocation for ack nack (msg4) in frame %d slot %d\n",frameP,slotP); LOG_D(NR_MAC, "Couldn't find a pucch allocation for ack nack (%s) in frame %d slot %d\n", ra_type_str, frameP, slotP);
return; return;
} }
...@@ -2015,9 +2085,22 @@ static void nr_generate_Msg4(module_id_t module_idP, ...@@ -2015,9 +2085,22 @@ static void nr_generate_Msg4(module_id_t module_idP,
uint8_t *buf = (uint8_t *) harq->transportBlock; uint8_t *buf = (uint8_t *) harq->transportBlock;
// Bytes to be transmitted // Bytes to be transmitted
if (harq->round == 0) { if (harq->round == 0) {
uint16_t mac_pdu_length = 0;
if (ra->ra_type == RA_4_STEP) {
// UE Contention Resolution Identity MAC CE // UE Contention Resolution Identity MAC CE
uint16_t mac_pdu_length = nr_write_ce_dlsch_pdu(module_idP, nr_mac->sched_ctrlCommon, buf, 255, ra->cont_res_id); mac_pdu_length = nr_write_ce_dlsch_pdu(module_idP, nr_mac->sched_ctrlCommon, buf, 255, ra->cont_res_id);
LOG_D(NR_MAC,"Encoded contention resolution mac_pdu_length %d\n",mac_pdu_length); } else if (ra->ra_type == RA_2_STEP) {
mac_pdu_length = nr_fill_successrar(nr_mac->sched_ctrlCommon,
ra->rnti,
ra->cont_res_id,
pucch->resource_indicator,
pucch->timing_indicator,
buf,
mac_pdu_length);
} else {
AssertFatal(false, "RA type %d not implemented!\n", ra->ra_type);
}
uint8_t buffer[CCCH_SDU_SIZE]; uint8_t buffer[CCCH_SDU_SIZE];
uint8_t mac_subheader_len = sizeof(NR_MAC_SUBHEADER_SHORT); uint8_t mac_subheader_len = sizeof(NR_MAC_SUBHEADER_SHORT);
// Get RLC data on the SRB (RRCSetup, RRCReestablishment) // Get RLC data on the SRB (RRCSetup, RRCReestablishment)
...@@ -2050,9 +2133,20 @@ static void nr_generate_Msg4(module_id_t module_idP, ...@@ -2050,9 +2133,20 @@ static void nr_generate_Msg4(module_id_t module_idP,
memcpy(&buf[mac_pdu_length + mac_subheader_len], buffer, mac_sdu_length); memcpy(&buf[mac_pdu_length + mac_subheader_len], buffer, mac_sdu_length);
} }
rnti_t rnti = ra->ra_type == RA_4_STEP ? ra->rnti : ra->MsgB_rnti;
const int pduindex = nr_mac->pdu_index[CC_id]++; const int pduindex = nr_mac->pdu_index[CC_id]++;
prepare_dl_pdus(nr_mac, ra, dl_bwp, dl_req, pucch, dmrs_info, msg4_tda, aggregation_level, CCEIndex, tb_size, harq->ndi, sched_ctrl->tpc1, delta_PRI, prepare_dl_pdus(nr_mac, ra, dl_bwp, dl_req, pucch, dmrs_info, msg4_tda, aggregation_level, CCEIndex, tb_size, harq->ndi, sched_ctrl->tpc1, delta_PRI,
current_harq_pid, time_domain_assignment, CC_id, ra->rnti, harq->round, mcsIndex, tb_scaling, pduindex, rbStart, rbSize); current_harq_pid,
time_domain_assignment,
CC_id,
rnti,
harq->round,
mcsIndex,
tb_scaling,
pduindex,
rbStart,
rbSize);
// Add padding header and zero rest out if there is space left // Add padding header and zero rest out if there is space left
if (ra->mac_pdu_length < harq->tb_size) { if (ra->mac_pdu_length < harq->tb_size) {
...@@ -2088,16 +2182,25 @@ static void nr_generate_Msg4(module_id_t module_idP, ...@@ -2088,16 +2182,25 @@ static void nr_generate_Msg4(module_id_t module_idP,
vrb_map[BWPStart + rb + rbStart] |= SL_to_bitmap(msg4_tda.startSymbolIndex, msg4_tda.nrOfSymbols); vrb_map[BWPStart + rb + rbStart] |= SL_to_bitmap(msg4_tda.startSymbolIndex, msg4_tda.nrOfSymbols);
} }
ra->ra_state = nrRA_WAIT_Msg4_ACK; ra->ra_state = nrRA_WAIT_Msg4_MsgB_ACK;
LOG_I(NR_MAC,"UE %04x Generate msg4: feedback at %4d.%2d, payload %d bytes, next state WAIT_Msg4_ACK\n", ra->rnti, pucch->frame, pucch->ul_slot, harq->tb_size); LOG_I(NR_MAC,
"(%d.%d) UE %04x Generate %s: feedback at %4d.%2d, payload %d bytes, next state nrRA_WAIT_Msg4_MsgB_ACK\n",
frameP,
slotP,
ra->rnti,
ra_type_str,
pucch->frame,
pucch->ul_slot,
harq->tb_size);
} }
} }
static void nr_check_Msg4_Ack(module_id_t module_id, int CC_id, frame_t frame, sub_frame_t slot, NR_RA_t *ra) static void nr_check_Msg4_MsgB_Ack(module_id_t module_id, int CC_id, frame_t frame, sub_frame_t slot, NR_RA_t *ra)
{ {
const char *ra_type_str = ra->ra_type == RA_2_STEP ? "MsgB" : "Msg4";
NR_UE_info_t *UE = find_nr_UE(&RC.nrmac[module_id]->UE_info, ra->rnti); NR_UE_info_t *UE = find_nr_UE(&RC.nrmac[module_id]->UE_info, ra->rnti);
if (!UE) { if (!UE) {
LOG_E(NR_MAC, "Cannot check Msg4 ACK/NACK, rnti %04x not in the table\n", ra->rnti); LOG_E(NR_MAC, "Cannot check %s ACK/NACK, rnti %04x not in the table\n", ra_type_str, ra->rnti);
return; return;
} }
const int current_harq_pid = ra->harq_pid; const int current_harq_pid = ra->harq_pid;
...@@ -2109,10 +2212,14 @@ static void nr_check_Msg4_Ack(module_id_t module_id, int CC_id, frame_t frame, s ...@@ -2109,10 +2212,14 @@ static void nr_check_Msg4_Ack(module_id_t module_id, int CC_id, frame_t frame, s
if (harq->is_waiting == 0) { if (harq->is_waiting == 0) {
if (harq->round == 0) { if (harq->round == 0) {
if (UE->Msg4_ACKed) { if (UE->Msg4_MsgB_ACKed) {
LOG_A(NR_MAC, "(UE RNTI 0x%04x) Received Ack of RA-Msg4. CBRA procedure succeeded!\n", ra->rnti); LOG_A(NR_MAC,
"%4d.%2d UE %04x: Received Ack of %s. CBRA procedure succeeded!\n",
frame, slot, ra->rnti, ra_type_str);
} else { } else {
LOG_I(NR_MAC, "%4d.%2d UE %04x: RA Procedure failed at Msg4!\n", frame, slot, ra->rnti); LOG_I(NR_MAC,
"%4d.%2d UE %04x: RA Procedure failed at %s!\n",
frame, slot, ra->rnti, ra_type_str);
nr_mac_trigger_ul_failure(sched_ctrl, UE->current_DL_BWP.scs); nr_mac_trigger_ul_failure(sched_ctrl, UE->current_DL_BWP.scs);
} }
...@@ -2127,9 +2234,12 @@ static void nr_check_Msg4_Ack(module_id_t module_id, int CC_id, frame_t frame, s ...@@ -2127,9 +2234,12 @@ static void nr_check_Msg4_Ack(module_id_t module_id, int CC_id, frame_t frame, s
if (sched_ctrl->retrans_dl_harq.head >= 0) { if (sched_ctrl->retrans_dl_harq.head >= 0) {
remove_nr_list(&sched_ctrl->retrans_dl_harq, current_harq_pid); remove_nr_list(&sched_ctrl->retrans_dl_harq, current_harq_pid);
} }
} else { } else if (ra->ra_type == RA_4_STEP) {
LOG_I(NR_MAC, "(UE %04x) Received Nack of RA-Msg4. Preparing retransmission!\n", ra->rnti); LOG_I(NR_MAC, "(UE %04x) Received Nack of RA-Msg4. Preparing retransmission!\n", ra->rnti);
ra->ra_state = nrRA_Msg4; ra->ra_state = nrRA_Msg4;
} else if (ra->ra_type == RA_2_STEP) {
LOG_I(NR_MAC, "(UE %04x) Received Nack of RA-MsgB. Preparing retransmission!\n", ra->rnti);
ra->ra_state = nrRA_MsgB;
} }
} }
} }
...@@ -2281,7 +2391,7 @@ void nr_schedule_RA(module_id_t module_idP, ...@@ -2281,7 +2391,7 @@ void nr_schedule_RA(module_id_t module_idP,
LOG_D(NR_MAC, "RA[state:%d]\n", ra->ra_state); LOG_D(NR_MAC, "RA[state:%d]\n", ra->ra_state);
// Check RA Contention Resolution timer // Check RA Contention Resolution timer
if (ra->ra_state >= nrRA_WAIT_Msg3) { if (ra->ra_type == RA_4_STEP && ra->ra_state >= nrRA_WAIT_Msg3) {
ra->contention_resolution_timer--; ra->contention_resolution_timer--;
if (ra->contention_resolution_timer < 0) { 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); LOG_W(NR_MAC, "(%d.%d) RA Contention Resolution timer expired for UE 0x%04x, RA procedure failed...\n", frameP, slotP, ra->rnti);
...@@ -2299,10 +2409,11 @@ void nr_schedule_RA(module_id_t module_idP, ...@@ -2299,10 +2409,11 @@ void nr_schedule_RA(module_id_t module_idP,
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_Msg4: case nrRA_Msg4:
nr_generate_Msg4(module_idP, CC_id, frameP, slotP, ra, DL_req, TX_req); case nrRA_MsgB:
nr_generate_Msg4_MsgB(module_idP, CC_id, frameP, slotP, ra, DL_req, TX_req);
break; break;
case nrRA_WAIT_Msg4_ACK: case nrRA_WAIT_Msg4_MsgB_ACK:
nr_check_Msg4_Ack(module_idP, CC_id, frameP, slotP, ra); nr_check_Msg4_MsgB_Ack(module_idP, CC_id, frameP, slotP, ra);
break; break;
default: default:
break; break;
......
...@@ -557,7 +557,7 @@ void handle_nr_ul_harq(const int CC_idP, ...@@ -557,7 +557,7 @@ void handle_nr_ul_harq(const int CC_idP,
} }
} }
NR_SCHED_UNLOCK(&nrmac->sched_lock); NR_SCHED_UNLOCK(&nrmac->sched_lock);
LOG_E(NR_MAC, "no RA proc for RNTI 0x%04x in Msg3/PUSCH\n", crc_pdu->rnti); LOG_E(NR_MAC, "no RA proc for RNTI 0x%04x in Msg3/MsgA-PUSCH\n", crc_pdu->rnti);
return; return;
} }
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
...@@ -770,7 +770,7 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP, ...@@ -770,7 +770,7 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP,
* it. */ * it. */
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 = &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_type == RA_4_STEP && ra->ra_state != nrRA_WAIT_Msg3)
continue; continue;
if (no_sig) { if (no_sig) {
...@@ -778,10 +778,16 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP, ...@@ -778,10 +778,16 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP,
nr_clear_ra_proc(ra); nr_clear_ra_proc(ra);
continue; continue;
} }
if (ra->ra_type == RA_2_STEP) {
// random access pusch with RA-RNTI
if (ra->RA_rnti != current_rnti) {
LOG_E(NR_MAC, "expected TC_RNTI %04x to match current RNTI %04x\n", ra->RA_rnti, current_rnti);
continue;
}
} else {
// 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, "expected TC_RNTI %04x to match current RNTI %04x\n", ra->rnti, current_rnti); LOG_E(NR_MAC, "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_W(NR_MAC, LOG_W(NR_MAC,
...@@ -795,6 +801,7 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP, ...@@ -795,6 +801,7 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP,
continue; continue;
} }
}
UE = UE ? UE : add_new_nr_ue(gNB_mac, ra->rnti, ra->CellGroup); UE = UE ? UE : add_new_nr_ue(gNB_mac, ra->rnti, ra->CellGroup);
if (!UE) { if (!UE) {
...@@ -838,8 +845,13 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP, ...@@ -838,8 +845,13 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP,
nr_clear_ra_proc(ra); nr_clear_ra_proc(ra);
process_addmod_bearers_cellGroupConfig(&UE->UE_sched_ctrl, ra->CellGroup->rlc_BearerToAddModList); process_addmod_bearers_cellGroupConfig(&UE->UE_sched_ctrl, ra->CellGroup->rlc_BearerToAddModList);
} else { } else {
LOG_A(NR_MAC, "[RAPROC] RA-Msg3 received (sdu_lenP %d)\n", sdu_lenP); LOG_A(NR_MAC,
LOG_D(NR_MAC, "[RAPROC] Received Msg3:\n"); "[RAPROC][%d.%d] RA %s received (sdu_lenP %d)\n",
frameP,
slotP,
ra->ra_type == RA_2_STEP ? "MsgA-PUSCH" : "Msg3",
sdu_lenP);
LOG_D(NR_MAC, "[RAPROC] Received %s:\n", ra->ra_type == RA_2_STEP ? "MsgA-PUSCH" : "Msg3");
for (int k = 0; k < sdu_lenP; k++) { for (int k = 0; k < sdu_lenP; k++) {
LOG_D(NR_MAC, "(%i): 0x%x\n", k, sduP[k]); LOG_D(NR_MAC, "(%i): 0x%x\n", k, sduP[k]);
} }
...@@ -925,7 +937,7 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP, ...@@ -925,7 +937,7 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP,
return; return;
} }
LOG_D(NR_MAC, "Random Access %i Msg3 CRC did not pass)\n", i); LOG_D(NR_MAC, "Random Access %i Msg3 CRC did not pass\n", i);
ra->msg3_round++; ra->msg3_round++;
ra->ra_state = nrRA_Msg3_retransmission; ra->ra_state = nrRA_Msg3_retransmission;
......
...@@ -122,8 +122,6 @@ int nr_allocate_CCEs(int module_idP, int CC_idP, frame_t frameP, sub_frame_t slo ...@@ -122,8 +122,6 @@ int nr_allocate_CCEs(int module_idP, int CC_idP, frame_t frameP, sub_frame_t slo
void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP); void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP);
void schedule_nr_MsgA_pusch(module_id_t module_idP, frame_t frameP, sub_frame_t slotP, nfapi_nr_prach_pdu_t *prach_pdu);
uint16_t nr_mac_compute_RIV(uint16_t N_RB_DL, uint16_t RBstart, uint16_t Lcrbs); uint16_t nr_mac_compute_RIV(uint16_t N_RB_DL, uint16_t RBstart, uint16_t Lcrbs);
/////// Phy test scheduler /////// /////// Phy test scheduler ///////
......
...@@ -113,15 +113,17 @@ typedef struct { ...@@ -113,15 +113,17 @@ typedef struct {
} NR_list_t; } NR_list_t;
typedef enum { typedef enum {
nrRA_gNB_IDLE = 0, nrRA_gNB_IDLE,
nrRA_Msg2 = 1, nrRA_Msg2,
nrRA_WAIT_Msg3 = 2, nrRA_WAIT_MsgA_PUSCH,
nrRA_Msg3_retransmission = 3, nrRA_WAIT_Msg3,
nrRA_Msg4 = 4, nrRA_Msg3_retransmission,
nrRA_WAIT_Msg4_ACK = 5, nrRA_Msg4,
nrRA_MsgB,
nrRA_WAIT_Msg4_MsgB_ACK,
} 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_MsgA_PUSCH", "WAIT_Msg3", "Msg3_retransmission", "Msg3_dcch_dtch", "Msg4", "MsgB", "WAIT_Msg4_ACK"};
typedef struct nr_pdsch_AntennaPorts_t { typedef struct nr_pdsch_AntennaPorts_t {
int N1; int N1;
int N2; int N2;
...@@ -206,6 +208,8 @@ typedef struct { ...@@ -206,6 +208,8 @@ typedef struct {
rnti_t rnti; rnti_t rnti;
/// RA RNTI allocated from received PRACH /// RA RNTI allocated from received PRACH
uint16_t RA_rnti; uint16_t RA_rnti;
/// MsgB RNTI allocated from received MsgA
uint16_t MsgB_rnti;
/// Received UE Contention Resolution Identifier /// Received UE Contention Resolution Identifier
uint8_t cont_res_id[6]; uint8_t cont_res_id[6];
/// Msg3 first RB /// Msg3 first RB
...@@ -234,6 +238,7 @@ typedef struct { ...@@ -234,6 +238,7 @@ typedef struct {
/// Preambles for contention-free access /// Preambles for contention-free access
NR_preamble_ue_t preambles; NR_preamble_ue_t preambles;
int contention_resolution_timer; int contention_resolution_timer;
nr_ra_type_t ra_type;
/// CFRA flag /// CFRA flag
bool cfra; bool cfra;
// BWP for RA // BWP for RA
......
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