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);
......
......@@ -191,10 +191,28 @@ void init_RA(NR_UE_MAC_INST_t *mac,
break;
}
if (nr_rach_ConfigCommon->ext1) {
if (nr_rach_ConfigCommon->ext1->ra_PrioritizationForAccessIdentity_r16){
if (ra->ra_type == RA_2_STEP) {
if (nr_rach_ConfigCommon->ext1 && nr_rach_ConfigCommon->ext1->ra_PrioritizationForAccessIdentity_r16) {
LOG_D(MAC, "Missing implementation for Access Identity initialization procedures\n");
}
// Perform initialization of variables specific to Random Access type as specified in clause 5.1.1a of TS 38.321
NR_RACH_ConfigGenericTwoStepRA_r16_t nr_ra_ConfigGenericTwoStepRA_r16 =
mac->current_UL_BWP->msgA_ConfigCommon_r16->rach_ConfigCommonTwoStepRA_r16.rach_ConfigGenericTwoStepRA_r16;
// Takes the value of 2-Step RA variable
if (nr_ra_ConfigGenericTwoStepRA_r16.msgA_PreamblePowerRampingStep_r16) {
prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP = *nr_ra_ConfigGenericTwoStepRA_r16.msgA_PreamblePowerRampingStep_r16;
} else {
// If 2-Step variable does not exist, it takes the value of 4-Step RA variable
prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP = nr_rach_ConfigCommon->rach_ConfigGeneric.powerRampingStep;
}
prach_resources->RA_SCALING_FACTOR_BI = 1;
// Takes the value of 2-Step RA variable
if (nr_ra_ConfigGenericTwoStepRA_r16.preambleTransMax_r16) {
ra->preambleTransMax = (int)*nr_ra_ConfigGenericTwoStepRA_r16.preambleTransMax_r16;
} else {
// If 2-Step variable does not exist, it takes the value of 4-Step RA variable
ra->preambleTransMax = (int)nr_rach_ConfigCommon->rach_ConfigGeneric.preambleTransMax;
}
}
}
......@@ -637,7 +655,7 @@ static uint8_t *fill_msg3_crnti_pdu(RA_config_t *ra, uint8_t *pdu, uint16_t crnt
static uint8_t *fill_msg3_pdu_from_rlc(NR_UE_MAC_INST_t *mac, uint8_t *pdu, int TBS_max)
{
RA_config_t *ra = &mac->ra;
// regular MSG3 with PDU coming from higher layers
// regular Msg3/MsgA_PUSCH with PDU coming from higher layers
*(NR_MAC_SUBHEADER_FIXED *)pdu = (NR_MAC_SUBHEADER_FIXED){.LCID = UL_SCH_LCID_CCCH};
pdu += sizeof(NR_MAC_SUBHEADER_FIXED);
tbs_size_t len = mac_rlc_data_req(mac->ue_id,
......@@ -651,7 +669,7 @@ static uint8_t *fill_msg3_pdu_from_rlc(NR_UE_MAC_INST_t *mac, uint8_t *pdu, int
(char *)pdu,
0,
0);
AssertFatal(len > 0, "no data for Msg.3\n");
AssertFatal(len > 0, "no data for Msg3/MsgA_PUSCH\n");
// UE Contention Resolution Identity
// Store the first 48 bits belonging to the uplink CCCH SDU within Msg3 to determine whether or not the
// Random Access Procedure has been successful after reception of Msg4
......@@ -661,7 +679,7 @@ static uint8_t *fill_msg3_pdu_from_rlc(NR_UE_MAC_INST_t *mac, uint8_t *pdu, int
return pdu;
}
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)
{
RA_config_t *ra = &mac->ra;
......@@ -674,10 +692,10 @@ void nr_get_msg3_payload(NR_UE_MAC_INST_t *mac, uint8_t *buf, int TBS_max)
uint8_t *pdu = buf;
if (ra->msg3_C_RNTI)
pdu = fill_msg3_crnti_pdu(ra, pdu, mac->crnti);
else
else
pdu = fill_msg3_pdu_from_rlc(mac, pdu, TBS_max);
AssertFatal(TBS_max >= pdu - buf, "Allocated resources are not enough for Msg3!\n");
AssertFatal(TBS_max >= pdu - buf, "Allocated resources are not enough for Msg3/MsgA_PUSCH!\n");
// Padding: fill remainder with 0
LOG_D(NR_MAC, "Remaining %ld bytes, filling with padding\n", pdu - buf);
while (pdu < buf + TBS_max - sizeof(NR_MAC_SUBHEADER_FIXED)) {
......@@ -709,13 +727,24 @@ void nr_ue_get_rach(NR_UE_MAC_INST_t *mac, int CC_id, frame_t frame, uint8_t gNB
// Delay init RA procedure to allow the convergence of the IIR filter on PRACH noise measurements at gNB side
if (ra->ra_state == nrRA_UE_IDLE) {
if ((mac->first_sync_frame > -1 || get_softmodem_params()->do_ra || get_softmodem_params()->nsa) &&
((MAX_FRAME_NUMBER + frame - mac->first_sync_frame) % MAX_FRAME_NUMBER) > 150) {
ra->ra_state = nrRA_GENERATE_PREAMBLE;
} else {
LOG_D(NR_MAC,"PRACH Condition not met: ra state %d, frame %d, sync_frame %d\n", ra->ra_state, frame, mac->first_sync_frame);
return;
}
LOG_D(NR_MAC,
"ra->ra_state %d frame %d mac->first_sync_frame %d xxx %d",
ra->ra_state,
frame,
mac->first_sync_frame,
((MAX_FRAME_NUMBER + frame - mac->first_sync_frame) % MAX_FRAME_NUMBER) > 10);
if ((mac->first_sync_frame > -1 || get_softmodem_params()->do_ra || get_softmodem_params()->nsa)
&& ((MAX_FRAME_NUMBER + frame - mac->first_sync_frame) % MAX_FRAME_NUMBER) > 150) {
ra->ra_state = nrRA_GENERATE_PREAMBLE;
LOG_D(NR_MAC, "PRACH Condition met: ra state %d, frame %d, sync_frame %d\n", ra->ra_state, frame, mac->first_sync_frame);
} else {
LOG_D(NR_MAC,
"PRACH Condition not met: ra state %d, frame %d, sync_frame %d\n",
ra->ra_state,
frame,
mac->first_sync_frame);
return;
}
}
LOG_D(NR_MAC, "[UE %d][%d.%d]: ra_state %d, RA_active %d\n", mac->ue_id, frame, nr_slot_tx, ra->ra_state, ra->RA_active);
......@@ -776,8 +805,7 @@ void nr_ue_get_rach(NR_UE_MAC_INST_t *mac, int CC_id, frame_t frame, uint8_t gNB
nr_ra_succeeded(mac, gNB_id, frame, nr_slot_tx);
}
} else if (ra->RA_window_cnt == 0 && !ra->RA_RAPID_found) {
} else if (ra->RA_window_cnt == 0 && !ra->RA_RAPID_found && ra->ra_state != nrRA_WAIT_MSGB) {
LOG_W(MAC, "[UE %d][%d:%d] RAR reception failed \n", mac->ue_id, frame, nr_slot_tx);
nr_ra_failed(mac, CC_id, prach_resources, frame, nr_slot_tx);
......@@ -809,49 +837,102 @@ void nr_ue_get_rach(NR_UE_MAC_INST_t *mac, int CC_id, frame_t frame, uint8_t gNB
}
}
void nr_get_RA_window(NR_UE_MAC_INST_t *mac)
int16_t nr_get_RA_window_2Step(const NR_MsgA_ConfigCommon_r16_t *msgA_ConfigCommon_r16)
{
RA_config_t *ra = &mac->ra;
NR_RACH_ConfigCommon_t *setup = mac->current_UL_BWP->rach_ConfigCommon;
AssertFatal(&setup->rach_ConfigGeneric != NULL, "In %s: FATAL! rach_ConfigGeneric is NULL...\n", __FUNCTION__);
NR_RACH_ConfigGeneric_t *rach_ConfigGeneric = &setup->rach_ConfigGeneric;
const double ta_Common_ms = get_ta_Common_ms(mac->sc_info.ntn_Config_r17);
const int mu = mac->current_DL_BWP->scs;
const int slots_per_ms = nr_slots_per_frame[mu] / 10;
const int ra_Offset_slots = ra->RA_offset * nr_slots_per_frame[mu];
const int ta_Common_slots = (int)ceil(ta_Common_ms * slots_per_ms);
int16_t ra_ResponseWindow = *msgA_ConfigCommon_r16->rach_ConfigCommonTwoStepRA_r16
.rach_ConfigGenericTwoStepRA_r16.msgB_ResponseWindow_r16;
ra->RA_window_cnt = ra_Offset_slots + ta_Common_slots; // taking into account the 2 frames gap introduced by OAI gNB
switch (ra_ResponseWindow) {
case NR_RACH_ConfigGenericTwoStepRA_r16__msgB_ResponseWindow_r16_sl1:
return 1;
break;
case NR_RACH_ConfigGenericTwoStepRA_r16__msgB_ResponseWindow_r16_sl2:
return 2;
break;
case NR_RACH_ConfigGenericTwoStepRA_r16__msgB_ResponseWindow_r16_sl4:
return 4;
break;
case NR_RACH_ConfigGenericTwoStepRA_r16__msgB_ResponseWindow_r16_sl8:
return 8;
break;
case NR_RACH_ConfigGenericTwoStepRA_r16__msgB_ResponseWindow_r16_sl10:
return 10;
break;
case NR_RACH_ConfigGenericTwoStepRA_r16__msgB_ResponseWindow_r16_sl20:
return 20;
break;
case NR_RACH_ConfigGenericTwoStepRA_r16__msgB_ResponseWindow_r16_sl40:
return 40;
break;
case NR_RACH_ConfigGenericTwoStepRA_r16__msgB_ResponseWindow_r16_sl80:
return 80;
break;
case NR_RACH_ConfigGenericTwoStepRA_r16__msgB_ResponseWindow_r16_sl160:
return 160;
break;
case NR_RACH_ConfigGenericTwoStepRA_r16__msgB_ResponseWindow_r16_sl320:
return 360;
break;
default:
AssertFatal(false, "illegal msgB_responseWindow value %d\n", ra_ResponseWindow);
break;
}
return 0;
}
int ra_ResponseWindow = rach_ConfigGeneric->ra_ResponseWindow;
int16_t nr_get_RA_window_4Step(const NR_RACH_ConfigCommon_t *rach_ConfigCommon)
{
int16_t ra_ResponseWindow = rach_ConfigCommon->rach_ConfigGeneric.ra_ResponseWindow;
switch (ra_ResponseWindow) {
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl1:
ra->RA_window_cnt += 1;
return 1;
break;
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl2:
ra->RA_window_cnt += 2;
return 2;
break;
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl4:
ra->RA_window_cnt += 4;
return 4;
break;
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl8:
ra->RA_window_cnt += 8;
return 8;
break;
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl10:
ra->RA_window_cnt += 10;
return 10;
break;
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl20:
ra->RA_window_cnt += 20;
return 20;
break;
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl40:
ra->RA_window_cnt += 40;
return 40;
break;
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl80:
ra->RA_window_cnt += 80;
return 80;
break;
default:
AssertFatal(false, "illegal ra_ResponseWindow value %d\n", ra_ResponseWindow);
break;
}
return 0;
}
void nr_get_RA_window(NR_UE_MAC_INST_t *mac)
{
RA_config_t *ra = &mac->ra;
NR_RACH_ConfigCommon_t *setup = mac->current_UL_BWP->rach_ConfigCommon;
AssertFatal(&setup->rach_ConfigGeneric != NULL, "In %s: FATAL! rach_ConfigGeneric is NULL...\n", __FUNCTION__);
const double ta_Common_ms = get_ta_Common_ms(mac->sc_info.ntn_Config_r17);
const int mu = mac->current_DL_BWP->scs;
const int slots_per_ms = nr_slots_per_frame[mu] / 10;
const int ra_Offset_slots = ra->RA_offset * nr_slots_per_frame[mu];
const int ta_Common_slots = (int)ceil(ta_Common_ms * slots_per_ms);
ra->RA_window_cnt = ra_Offset_slots + ta_Common_slots; // taking into account the 2 frames gap introduced by OAI gNB
ra->RA_window_cnt += ra->ra_type == RA_2_STEP ? nr_get_RA_window_2Step(mac->current_UL_BWP->msgA_ConfigCommon_r16)
: nr_get_RA_window_4Step(mac->current_UL_BWP->rach_ConfigCommon);
}
////////////////////////////////////////////////////////////////////////////
......@@ -869,7 +950,7 @@ void nr_ue_contention_resolution(NR_UE_MAC_INST_t *mac, int cc_id, frame_t frame
ra->t_crnti = 0;
nr_timer_stop(&ra->contention_resolution_timer);
// Signal PHY to quit RA procedure
LOG_E(MAC, "[UE %d] CB-RA: Contention resolution timer has expired, RA procedure has failed...\n", mac->ue_id);
LOG_E(MAC, "[UE %d] 4-Step CBRA: Contention resolution timer has expired, RA procedure has failed...\n", mac->ue_id);
nr_ra_failed(mac, cc_id, prach_resources, frame, slot);
}
}
......@@ -883,14 +964,27 @@ void nr_ra_succeeded(NR_UE_MAC_INST_t *mac, const uint8_t gNB_index, const frame
RA_config_t *ra = &mac->ra;
if (ra->cfra) {
LOG_I(MAC, "[UE %d][%d.%d][RAPROC] RA procedure succeeded. CF-RA: RAR successfully received.\n", mac->ue_id, frame, slot);
LOG_I(MAC, "[UE %d][%d.%d][RAPROC] RA procedure succeeded. CFRA: RAR successfully received.\n", mac->ue_id, frame, slot);
ra->RA_window_cnt = -1;
} else if (ra->ra_type == RA_2_STEP) {
LOG_A(MAC,
"[UE %d][%d.%d][RAPROC] 2-Step RA procedure succeeded. CBRA: Contention Resolution is successful.\n",
mac->ue_id,
frame,
slot);
mac->crnti = ra->t_crnti;
ra->t_crnti = 0;
LOG_D(MAC, "[UE %d][%d.%d] CBRA: cleared response window timer...\n", mac->ue_id, frame, slot);
} else {
LOG_A(MAC, "[UE %d][%d.%d][RAPROC] RA procedure succeeded. CB-RA: Contention Resolution is successful.\n", mac->ue_id, frame, slot);
LOG_A(MAC,
"[UE %d][%d.%d][RAPROC] 4-Step RA procedure succeeded. CBRA: Contention Resolution is successful.\n",
mac->ue_id,
frame,
slot);
nr_timer_stop(&ra->contention_resolution_timer);
mac->crnti = ra->t_crnti;
ra->t_crnti = 0;
LOG_D(MAC, "[UE %d][%d.%d] CB-RA: cleared contention resolution timer...\n", mac->ue_id, frame, slot);
LOG_D(MAC, "[UE %d][%d.%d] CBRA: cleared contention resolution timer...\n", mac->ue_id, frame, slot);
}
LOG_D(MAC, "[UE %d] clearing RA_active flag...\n", mac->ue_id);
......@@ -945,7 +1039,6 @@ void nr_ra_failed(NR_UE_MAC_INST_t *mac, uint8_t CC_id, NR_PRACH_RESOURCES_t *pr
prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER = nr_get_Po_NOMINAL_PUSCH(mac, prach_resources, CC_id);
} else {
// Resetting RA window
nr_get_RA_window(mac);
}
}
......@@ -958,7 +1051,7 @@ void trigger_MAC_UE_RA(NR_UE_MAC_INST_t *mac)
mac->ra.msg3_C_RNTI = true;
}
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)
{
NR_UE_HARQ_STATUS_t *current_harq = &mac->dl_harq_info[pid];
int sched_slot = current_harq->ul_slot;
......
......@@ -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