Commit 160210eb authored by ndomingues's avatar ndomingues

Baseline implementation of RA 2-Step MsgA procedures at UE

parent cbbbeb80
......@@ -225,7 +225,9 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int frame, uint8_t
k += kbar;
k *= 2;
LOG_I(PHY, "PRACH [UE %d] in frame.slot %d.%d, placing PRACH in position %d, msg1 frequency start %d (k1 %d), preamble_offset %d, first_nonzero_root_idx %d\n",
LOG_I(PHY,
"PRACH [UE %d] in frame.slot %d.%d, placing PRACH in position %d, Msg1/MsgA-Preamble frequency start %d (k1 %d), "
"preamble_offset %d, first_nonzero_root_idx %d\n",
Mod_id,
frame,
slot,
......
......@@ -263,16 +263,17 @@ typedef struct {
} NR_UE_SCHEDULING_INFO;
typedef enum {
nrRA_UE_IDLE = 0,
nrRA_GENERATE_PREAMBLE = 1,
nrRA_WAIT_RAR = 2,
nrRA_WAIT_CONTENTION_RESOLUTION = 3,
nrRA_SUCCEEDED = 4,
nrRA_FAILED = 5
nrRA_UE_IDLE,
nrRA_GENERATE_PREAMBLE,
nrRA_WAIT_RAR,
nrRA_WAIT_MSGB,
nrRA_WAIT_CONTENTION_RESOLUTION,
nrRA_SUCCEEDED,
nrRA_FAILED,
} nrRA_UE_state_t;
static const char *const nrra_ue_text[] =
{"UE_IDLE", "GENERATE_PREAMBLE", "WAIT_RAR", "WAIT_CONTENTION_RESOLUTION", "RA_SUCCEEDED", "RA_FAILED"};
{"UE_IDLE", "GENERATE_PREAMBLE", "WAIT_RAR", "WAIT_MSGB", "WAIT_CONTENTION_RESOLUTION", "RA_SUCCEEDED", "RA_FAILED"};
typedef struct {
/// PRACH format retrieved from prach_ConfigIndex
......@@ -311,8 +312,10 @@ typedef struct {
nr_ra_type_t ra_type;
/// RA rx frame offset: compensate RA rx offset introduced by OAI gNB.
uint8_t RA_offset;
/// RA-rnti
uint16_t ra_rnti;
/// RA-RNTI
rnti_t ra_rnti;
/// MsgB-RNTI
rnti_t MsgB_rnti;
/// Temporary CRNTI
uint16_t t_crnti;
/// number of attempt for rach
......
......@@ -304,6 +304,10 @@ void nr_ra_failed(NR_UE_MAC_INST_t *mac, uint8_t CC_id, NR_PRACH_RESOURCES_t *pr
void nr_ra_succeeded(NR_UE_MAC_INST_t *mac, const uint8_t gNB_index, const frame_t frame, const int slot);
int16_t nr_get_RA_window_2Step(const NR_MsgA_ConfigCommon_r16_t *msgA_ConfigCommon_r16);
int16_t nr_get_RA_window_4Step(const NR_RACH_ConfigCommon_t *rach_ConfigCommon);
void nr_get_RA_window(NR_UE_MAC_INST_t *mac);
/* \brief Function called by PHY to retrieve information to be transmitted using the RA procedure.
......@@ -331,7 +335,7 @@ void nr_get_prach_resources(NR_UE_MAC_INST_t *mac,
NR_PRACH_RESOURCES_t *prach_resources,
NR_RACH_ConfigDedicated_t * rach_ConfigDedicated);
void prepare_msg4_feedback(NR_UE_MAC_INST_t *mac, int pid, int ack_nack);
void prepare_msg4_msgb_feedback(NR_UE_MAC_INST_t *mac, int pid, int ack_nack);
void configure_initial_pucch(PUCCH_sched_t *pucch, int res_ind);
void release_PUCCH_SRS(NR_UE_MAC_INST_t *mac);
void nr_ue_reset_sync_state(NR_UE_MAC_INST_t *mac);
......@@ -356,7 +360,7 @@ void schedule_RA_after_SR_failure(NR_UE_MAC_INST_t *mac);
void nr_Msg1_transmitted(NR_UE_MAC_INST_t *mac);
void nr_Msg3_transmitted(NR_UE_MAC_INST_t *mac, uint8_t CC_id, frame_t frameP, slot_t slotP, uint8_t gNB_id);
void trigger_MAC_UE_RA(NR_UE_MAC_INST_t *mac);
void nr_get_msg3_payload(NR_UE_MAC_INST_t *mac, uint8_t *buf, int TBS_max);
void nr_get_Msg3_MsgA_PUSCH_payload(NR_UE_MAC_INST_t *mac, uint8_t *buf, int TBS_max);
void handle_time_alignment_timer_expired(NR_UE_MAC_INST_t *mac);
int8_t nr_ue_process_dci_freq_dom_resource_assignment(nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu,
fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu,
......@@ -410,7 +414,7 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
dci_pdu_rel15_t *dci,
csi_payload_t *csi_report,
RAR_grant_t *rar_grant,
uint16_t rnti,
rnti_t rnti,
int ss_type,
const nr_dci_format_t dci_format);
......
......@@ -574,7 +574,7 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
dci_pdu_rel15_t *dci,
csi_payload_t *csi_report,
RAR_grant_t *rar_grant,
uint16_t rnti,
rnti_t rnti,
int ss_type,
const nr_dci_format_t dci_format)
{
......@@ -584,6 +584,7 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
int rnti_type = get_rnti_type(mac, rnti);
NR_UE_UL_BWP_t *current_UL_BWP = mac->current_UL_BWP;
NR_UE_ServingCell_Info_t *sc_info = &mac->sc_info;
int scs = current_UL_BWP->scs;
// Common configuration
pusch_config_pdu->dmrs_config_type = pusch_dmrs_type1;
......@@ -596,8 +597,69 @@ 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;
if (rar_grant) {
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 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);
LOG_D(NR_MAC,
"sc_info->initial_ul_BWPStart = %d sc_info->initial_ul_BWPSize = %d\n",
sc_info->initial_ul_BWPStart,
sc_info->initial_ul_BWPSize);
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->dmrs_ports = 1; // is in SIB1 nrofDMRS_Sequences_r16?
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;
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;
pusch_config_pdu->bwp_start = sc_info->initial_ul_BWPStart;
pusch_config_pdu->subcarrier_spacing = scs;
pusch_config_pdu->cyclic_prefix = 0;
pusch_config_pdu->uplink_frequency_shift_7p5khz = 0;
pusch_config_pdu->vrb_to_prb_mapping = 0;
pusch_config_pdu->dmrs_config_type = 0;
pusch_config_pdu->data_scrambling_id = mac->physCellId;
pusch_config_pdu->ul_dmrs_scrambling_id = mac->physCellId;
pusch_config_pdu->scid = 0;
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);
} else if (rar_grant) {
// Note: for Msg3 or MsgA PUSCH transmission the N_PRB_oh is always set to 0
int ibwp_start = sc_info->initial_ul_BWPStart;
int ibwp_size = sc_info->initial_ul_BWPSize;
......@@ -1501,8 +1563,8 @@ void nr_ue_ul_scheduler(NR_UE_MAC_INST_t *mac, nr_uplink_indication_t *ul_info)
TBS_bytes,
ra->ra_state);
ulcfg_pdu->pusch_config_pdu.tx_request_body.fapiTxPdu = NULL;
if (ra->ra_state == nrRA_WAIT_RAR && !ra->cfra) {
nr_get_msg3_payload(mac, ulsch_input_buffer, TBS_bytes);
if ((ra->ra_state == nrRA_WAIT_RAR || ra->ra_state == nrRA_WAIT_MSGB) && !ra->cfra) {
nr_get_Msg3_MsgA_PUSCH_payload(mac, ulsch_input_buffer, TBS_bytes);
for (int k = 0; k < TBS_bytes; k++) {
LOG_D(NR_MAC, "(%i): 0x%x\n", k, ulsch_input_buffer[k]);
}
......@@ -1553,6 +1615,9 @@ void nr_ue_ul_scheduler(NR_UE_MAC_INST_t *mac, nr_uplink_indication_t *ul_info)
LOG_A(NR_MAC, "[RAPROC][%d.%d] RA-Msg3 transmitted\n", frame_tx, slot_tx);
nr_Msg3_transmitted(mac, cc_id, frame_tx, slot_tx, gNB_index);
}
if (ra->ra_state == nrRA_WAIT_MSGB && !ra->cfra) {
LOG_A(NR_MAC, "[RAPROC][%d.%d] RA-MsgA-PUSCH transmitted\n", frame_tx, slot_tx);
}
}
ulcfg_pdu++;
}
......@@ -2867,7 +2932,57 @@ static void nr_ue_prach_scheduler(NR_UE_MAC_INST_t *mac, frame_t frameP, sub_fra
if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL)
mac->if_module->scheduled_response(&scheduled_response);
nr_Msg1_transmitted(mac);
if (ra->ra_type == RA_4_STEP) {
nr_Msg1_transmitted(mac);
} else if (ra->ra_type == RA_2_STEP) {
const NR_MsgA_ConfigCommon_r16_t *msgacc = mac->current_UL_BWP->msgA_ConfigCommon_r16;
int mu = (int)*msgacc->rach_ConfigCommonTwoStepRA_r16.msgA_SubcarrierSpacing_r16;
NR_MsgA_PUSCH_Resource_r16_t *msgA_PUSCH_Resource =
mac->current_UL_BWP->msgA_ConfigCommon_r16->msgA_PUSCH_Config_r16->msgA_PUSCH_ResourceGroupA_r16;
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;
fapi_nr_ul_config_request_pdu_t *pdu =
lockGet_ul_config(mac, msgA_pusch_frame, msgA_pusch_slot, FAPI_NR_UL_CONFIG_TYPE_PUSCH);
if (!pdu)
return;
// Config Msg3/MsgA-PUSCH PDU
NR_tda_info_t tda_info = {0};
AssertFatal(msgA_PUSCH_Resource->startSymbolAndLengthMsgA_PO_r16,
"Only SLIV based on startSymbolAndLengthMsgA_PO_r16 implemented\n");
int ret = nr_config_pusch_pdu(mac,
&tda_info,
&pdu->pusch_config_pdu,
NULL,
NULL,
NULL,
mac->ra.ra_rnti,
NR_SearchSpace__searchSpaceType_PR_common,
NR_DCI_NONE);
if (ret != 0)
remove_ul_config_last_item(pdu);
release_ul_config(pdu, false);
// Compute MsgB RNTI
ra->MsgB_rnti =
nr_get_MsgB_rnti(prach_occasion_info_p->start_symbol, prach_occasion_info_p->slot, prach_occasion_info_p->fdm, 0);
LOG_D(NR_MAC, "ra->ra_state %s\n", nrra_ue_text[ra->ra_state]);
ra->ra_state = nrRA_WAIT_MSGB;
ra->t_crnti = 0;
mac->crnti = 0;
ra->ra_rnti = 0;
} else {
AssertFatal(false, "RA type %d not implemented!\n", ra->ra_type);
}
// rnti = ra->t_crnti;
} // is_nr_prach_slot
} // if is_nr_UL_slot
}
......
......@@ -1127,7 +1127,7 @@ void update_harq_status(NR_UE_MAC_INST_t *mac, uint8_t harq_pid, uint8_t ack_nac
LOG_D(PHY,"Updating harq_status for harq_id %d, ack/nak %d\n", harq_pid, current_harq->ack);
// we can prepare feedback for MSG4 in advance
if (mac->ra.ra_state == nrRA_WAIT_CONTENTION_RESOLUTION)
prepare_msg4_feedback(mac, harq_pid, ack_nack);
prepare_msg4_msgb_feedback(mac, harq_pid, ack_nack);
else {
current_harq->ack = ack_nack;
current_harq->ack_received = true;
......
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