Commit cc154da5 authored by francescomani's avatar francescomani

Procedures for Random Access Response reception

parent 108fdae1
......@@ -283,8 +283,6 @@ typedef struct {
int ra_preamble_rx_target_power;
/// RA Preamble Power Ramping Step in dB
uint32_t preamble_power_ramping_step;
uint8_t preamble_backoff;
uint8_t scaling_factor_bi;
/// UE configured maximum output power
int Pc_max;
} NR_PRACH_RESOURCES_t;
......@@ -310,8 +308,6 @@ typedef struct {
bool cfra;
/// RA type
nr_ra_type_t ra_type;
/// RA rx frame offset: compensate RA rx offset introduced by OAI gNB.
uint8_t RA_offset;
/// MsgB SuccessRAR MAC subheader
int8_t MsgB_R;
int8_t MsgB_CH_ACESS_CPEXT;
......@@ -333,18 +329,15 @@ typedef struct {
int restricted_set_config;
// selected SSB for RACH (not the SSB-Index but the cumulative index, excluding not trasmitted SSBs)
int ra_ssb;
/// Random-access window counter
int16_t RA_window_cnt;
/// Flag to monitor if matching RAPID was received in RAR
uint8_t RA_RAPID_found;
/// Flag to monitor if BI was received in RAR
uint8_t RA_BI_found;
/// Random-access backoff counter
int16_t RA_backoff_indicator;
/// Random-access response window timer
NR_timer_t response_window_timer;
bool start_response_window;
/// Random-access backoff timer
NR_timer_t RA_backoff_timer;
int RA_backoff_limit;
uint8_t scaling_factor_bi;
/// Flag to indicate whether preambles Group A is selected
bool RA_GroupA;
/// RA backoff counter
int16_t RA_backoff_cnt;
/// RA max number of preamble transmissions
int preambleTransMax;
/// Received TPC command (in dB) from RAR
......
......@@ -212,7 +212,6 @@ void set_harq_status(NR_UE_MAC_INST_t *mac,
bool get_downlink_ack(NR_UE_MAC_INST_t *mac, frame_t frame, int slot, PUCCH_sched_t *pucch);
initial_pucch_resource_t get_initial_pucch_resource(const int idx);
void multiplex_pucch_resource(NR_UE_MAC_INST_t *mac, PUCCH_sched_t *pucch, int num_res);
uint32_t get_backoff_indicator(int idx);
int16_t get_pucch_tx_power_ue(NR_UE_MAC_INST_t *mac,
int scs,
NR_PUCCH_Config_t *pucch_Config,
......@@ -307,10 +306,6 @@ 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);
/*@mac pointer to MAC instance
......@@ -336,6 +331,8 @@ NR_UE_L2_STATE_t nr_ue_get_sync_state(module_id_t mod_id);
int16_t get_prach_tx_power(NR_UE_MAC_INST_t *mac);
void schedule_RA_after_SR_failure(NR_UE_MAC_INST_t *mac);
void nr_rar_not_successful(NR_UE_MAC_INST_t *mac);
void ra_resource_selection(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, dci_pdu_rel15_t *pdcch_order);
void nr_get_Msg3_MsgA_PUSCH_payload(NR_UE_MAC_INST_t *mac, uint8_t *buf, int TBS_max);
......
......@@ -412,30 +412,6 @@ static const uint8_t table_7_3_2_3_3_4_twoCodeword[6][14] = {
{2,1,1,1,1,0,0,1,1,1,1,0,0,2},
};
// table 7.2-1 TS 38.321
static const uint32_t table_7_2_1[16] = {
5, // row index 0
10, // row index 1
20, // row index 2
30, // row index 3
40, // row index 4
60, // row index 5
80, // row index 6
120, // row index 7
160, // row index 8
240, // row index 9
320, // row index 10
480, // row index 11
960, // row index 12
1920, // row index 13
};
uint32_t get_backoff_indicator(int idx)
{
AssertFatal(idx < 16, "Backoff indicator index %d exeeding table size\n", idx);
return table_7_2_1[idx];
}
static inline uint16_t packBits(const uint8_t *toPack, const int nb)
{
int res = 0;
......
......@@ -450,7 +450,7 @@ static void select_prach_occasion(RA_config_t *ra,
seed = 1;
} else {
// & to truncate the int64_t and keep only the LSB bits, up to sizeof(int)
seed = (unsigned int) (rdtsc_oai() & ~0);
seed = (unsigned int)(rdtsc_oai() & ~0);
}
int num_ros_per_ssb = 0;
......@@ -630,7 +630,7 @@ static void ra_preamble_msga_transmission(RA_config_t *ra, int scs)
}
// 38.321 Section 5.1.2 Random Access Resource selection
static void ra_resource_selection(NR_UE_MAC_INST_t *mac)
void ra_resource_selection(NR_UE_MAC_INST_t *mac)
{
configure_ra_preamble(mac);
const NR_UE_UL_BWP_t *current_UL_BWP = mac->current_UL_BWP;
......@@ -640,6 +640,189 @@ static void ra_resource_selection(NR_UE_MAC_INST_t *mac)
ra_preamble_msga_transmission(&mac->ra, mu);
}
static int nr_get_RA_window_2Step_v17(long msgB_ResponseWindow)
{
switch (msgB_ResponseWindow) {
case NR_RACH_ConfigGenericTwoStepRA_r16__ext1__msgB_ResponseWindow_v1700_sl240:
return 240;
break;
case NR_RACH_ConfigGenericTwoStepRA_r16__ext1__msgB_ResponseWindow_v1700_sl640:
return 640;
break;
case NR_RACH_ConfigGenericTwoStepRA_r16__ext1__msgB_ResponseWindow_v1700_sl960:
return 960;
break;
case NR_RACH_ConfigGenericTwoStepRA_r16__ext1__msgB_ResponseWindow_v1700_sl1280:
return 1280;
break;
case NR_RACH_ConfigGenericTwoStepRA_r16__ext1__msgB_ResponseWindow_v1700_sl1920:
return 1920;
break;
case NR_RACH_ConfigGenericTwoStepRA_r16__ext1__msgB_ResponseWindow_v1700_sl2560:
return 2590;
default:
AssertFatal(false, "illegal msgB_responseWindow value %ld\n", msgB_ResponseWindow);
break;
}
return 0;
}
static int nr_get_RA_window_2Step_v16(long msgB_ResponseWindow)
{
switch (msgB_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 %ld\n", msgB_ResponseWindow);
break;
}
return 0;
}
static int nr_get_RA_window_4Step_v16(long ra_ResponseWindow)
{
switch (ra_ResponseWindow) {
case NR_RACH_ConfigGeneric__ext1__ra_ResponseWindow_v1610_sl60:
return 60;
case NR_RACH_ConfigGeneric__ext1__ra_ResponseWindow_v1610_sl160:
return 160;
default:
AssertFatal(false, "illegal ra_ResponseWindow value %ld\n", ra_ResponseWindow);
}
return 0;
}
static int nr_get_RA_window_4Step_v17(long ra_ResponseWindow)
{
switch (ra_ResponseWindow) {
case NR_RACH_ConfigGeneric__ext2__ra_ResponseWindow_v1700_sl240:
return 240;
case NR_RACH_ConfigGeneric__ext2__ra_ResponseWindow_v1700_sl320:
return 320;
case NR_RACH_ConfigGeneric__ext2__ra_ResponseWindow_v1700_sl640:
return 640;
case NR_RACH_ConfigGeneric__ext2__ra_ResponseWindow_v1700_sl960:
return 960;
case NR_RACH_ConfigGeneric__ext2__ra_ResponseWindow_v1700_sl1280:
return 1280;
case NR_RACH_ConfigGeneric__ext2__ra_ResponseWindow_v1700_sl1920:
return 1920;
case NR_RACH_ConfigGeneric__ext2__ra_ResponseWindow_v1700_sl2560:
return 2590;
default:
AssertFatal(false, "illegal msgB_responseWindow value %ld\n", ra_ResponseWindow);
}
return 0;
}
static int nr_get_RA_window_4Step(long ra_ResponseWindow)
{
switch (ra_ResponseWindow) {
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl1:
return 1;
break;
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl2:
return 2;
break;
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl4:
return 4;
break;
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl8:
return 8;
break;
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl10:
return 10;
break;
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl20:
return 20;
break;
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl40:
return 40;
break;
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl80:
return 80;
break;
default:
AssertFatal(false, "illegal ra_ResponseWindow value %ld\n", ra_ResponseWindow);
break;
}
return 0;
}
static void setup_ra_response_window(RA_config_t *ra,
int slots_per_frame,
NR_NTN_Config_r17_t *ntn_Config_r17,
NR_RACH_ConfigGeneric_t *configGeneric,
NR_RACH_ConfigGenericTwoStepRA_r16_t *twostep,
ntn_timing_advance_componets_t *ntn_ta)
{
int respwind_value = 0;
if (ra->ra_type == RA_2_STEP) {
long *msgB_ResponseWindow = twostep->msgB_ResponseWindow_r16;
if (msgB_ResponseWindow)
respwind_value = nr_get_RA_window_2Step_v16(*msgB_ResponseWindow);
if (twostep->ext1 && twostep->ext1->msgB_ResponseWindow_v1700) {
AssertFatal(msgB_ResponseWindow == NULL,
"The network does not configure msgB-ResponseWindow-r16 simultaneously with msgB-ResponseWindow-v1700\n");
msgB_ResponseWindow = twostep->ext1->msgB_ResponseWindow_v1700;
if (msgB_ResponseWindow)
respwind_value = nr_get_RA_window_2Step_v17(*msgB_ResponseWindow);
}
// The network configures a value lower than or equal to 40ms
int slots_40ms = 4 * slots_per_frame;
AssertFatal(respwind_value != 0 && respwind_value <= slots_40ms, "Invalid MSGB response window value\n");
} else {
AssertFatal(ra->ra_type == RA_4_STEP, "Invalid RA type\n");
long *response_window = NULL;
if (configGeneric->ext1 && configGeneric->ext1->ra_ResponseWindow_v1610)
respwind_value = nr_get_RA_window_4Step_v16(*configGeneric->ext1->ra_ResponseWindow_v1610);
if (configGeneric->ext2 && configGeneric->ext2->ra_ResponseWindow_v1700) {
AssertFatal(response_window == NULL, "ra_ResponseWindow_v1610 and ra_ResponseWindow_v1700 are mutually exclusive\n");
respwind_value = nr_get_RA_window_4Step_v17(*configGeneric->ext2->ra_ResponseWindow_v1700);
}
if (!response_window)
respwind_value = nr_get_RA_window_4Step(configGeneric->ra_ResponseWindow);
// The network configures a value lower than or equal to 10ms
AssertFatal(respwind_value != 0 && respwind_value <= slots_per_frame, "Invalid RAR response window value\n");
}
int ta_Common_slots = 0;
if (ntn_Config_r17) {
const double ta_Common_ms = GET_COMPLETE_TIME_ADVANCE_MS(ntn_ta);
ta_Common_slots = (int)ceil(ta_Common_ms * slots_per_frame / 10);
}
nr_timer_setup(&ra->response_window_timer, respwind_value + ta_Common_slots, 1);
}
// Random Access procedure initialization as per 5.1.1 and initialization of variables specific
// to Random Access type as specified in clause 5.1.1a (3GPP TS 38.321 version 16.2.1 Release 16)
bool init_RA(NR_UE_MAC_INST_t *mac, int frame)
......@@ -704,8 +887,6 @@ bool init_RA(NR_UE_MAC_INST_t *mac, int frame)
prach_resources->preamble_tx_counter = 1;
// set the PREAMBLE_POWER_RAMPING_COUNTER to 1
prach_resources->preamble_power_ramping_cnt = 1;
// set the PREAMBLE_BACKOFF to 0 ms TODO to be set as a timer?
prach_resources->preamble_backoff = 0;
// set POWER_OFFSET_2STEP_RA to 0 dB
prach_resources->power_offset_2step = 0;
......@@ -826,7 +1007,7 @@ bool init_RA(NR_UE_MAC_INST_t *mac, int frame)
else
prach_resources->preamble_power_ramping_step = rach_ConfigGeneric->powerRampingStep << 1;
prach_resources->scaling_factor_bi = 1;
ra->scaling_factor_bi = 1;
if (ra->ra_type == RA_2_STEP && twostep_generic && twostep_generic->msgA_PreambleReceivedTargetPower_r16)
ra->preambleReceivedTargetPower_config = *twostep_generic->msgA_PreambleReceivedTargetPower_r16;
......@@ -863,9 +1044,6 @@ bool init_RA(NR_UE_MAC_INST_t *mac, int frame)
else
ra->msg3_deltaPreamble = mac->current_UL_BWP->msg3_DeltaPreamble ? *mac->current_UL_BWP->msg3_DeltaPreamble << 1 : 0;
ra->RA_RAPID_found = 0;
ra->RA_backoff_cnt = 0;
ra->RA_window_cnt = -1;
ra->new_ssb = false;
if (ra->ra_type == RA_2_STEP && twostep_generic && twostep_generic->msgA_PRACH_ConfigurationIndex_r16)
......@@ -882,18 +1060,16 @@ bool init_RA(NR_UE_MAC_INST_t *mac, int frame)
else
ra->num_fd_occasions = 1 << rach_ConfigGeneric->msg1_FDM;
setup_ra_response_window(ra,
mac->frame_structure.numb_slots_frame,
mac->sc_info.ntn_Config_r17,
rach_ConfigGeneric,
twostep_generic,
&mac->ntn_ta);
ra->start_response_window = false;
return true;
}
static void nr_get_prach_resources(NR_UE_MAC_INST_t *mac, NR_PRACH_RESOURCES_t *prach_resources)
{
const int ul_mu = mac->current_UL_BWP->scs;
const int mu = nr_get_prach_or_ul_mu(mac->current_UL_BWP->msgA_ConfigCommon_r16, mac->current_UL_BWP->rach_ConfigCommon, ul_mu);
if (prach_resources->preamble_tx_counter > 1)
prach_resources->preamble_power_ramping_cnt++;
prach_resources->ra_preamble_rx_target_power = get_ra_preamble_rx_target_power(&mac->ra, mu);
}
void nr_Msg3_transmitted(NR_UE_MAC_INST_t *mac, uint8_t CC_id, frame_t frameP, slot_t slotP, uint8_t gNB_id)
{
RA_config_t *ra = &mac->ra;
......@@ -1012,48 +1188,15 @@ void nr_ue_manage_ra_procedure(NR_UE_MAC_INST_t *mac, int CC_id, frame_t frame,
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);
if (ra->ra_state < nrRA_SUCCEEDED) {
if (ra->RA_window_cnt != -1) { // RACH is active
LOG_D(MAC, "[%d.%d] RA is active: RA window count %d, RA backoff count %d\n", frame, nr_slot_tx, ra->RA_window_cnt, ra->RA_backoff_cnt);
if (ra->RA_BI_found){
prach_resources->preamble_backoff = prach_resources->scaling_factor_bi * ra->RA_backoff_indicator;
} else {
prach_resources->preamble_backoff = 0;
}
if (ra->RA_window_cnt >= 0 && ra->RA_RAPID_found == 1) {
if(ra->cfra) {
// Reset RA_active flag: it disables Msg3 retransmission (8.3 of TS 38.213)
nr_ra_succeeded(mac, gNB_id, frame, nr_slot_tx);
}
} 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);
} else if (ra->RA_window_cnt > 0) {
LOG_D(MAC, "[UE %d][%d.%d]: RAR not received yet (RA window count %d) \n", mac->ue_id, frame, nr_slot_tx, ra->RA_window_cnt);
// Fill in preamble and PRACH resources
ra->RA_window_cnt--;
if (ra->ra_state == nrRA_GENERATE_PREAMBLE) {
nr_get_prach_resources(mac, prach_resources);
}
} else if (ra->RA_backoff_cnt > 0) {
LOG_D(MAC, "[UE %d][%d.%d]: RAR not received yet (RA backoff count %d) \n", mac->ue_id, frame, nr_slot_tx, ra->RA_backoff_cnt);
ra->RA_backoff_cnt--;
if ((ra->RA_backoff_cnt > 0 && ra->ra_state == nrRA_GENERATE_PREAMBLE) || ra->RA_backoff_cnt == 0) {
nr_get_prach_resources(mac, prach_resources);
}
}
if (nr_timer_is_active(&ra->RA_backoff_timer)) {
// if the criteria (as defined in clause 5.1.2) to select contention-free Random Access Resources
// is met during the backoff time
// TODO verify what does this mean
if (ra->cfra) {
// perform the Random Access Resource selection procedure
nr_timer_stop(&ra->RA_backoff_timer);
mac->ra.ra_state = nrRA_GENERATE_PREAMBLE;
ra_resource_selection(mac);
}
}
......@@ -1062,102 +1205,6 @@ void nr_ue_manage_ra_procedure(NR_UE_MAC_INST_t *mac, int CC_id, frame_t frame,
}
}
int16_t nr_get_RA_window_2Step(const NR_MsgA_ConfigCommon_r16_t *msgA_ConfigCommon_r16)
{
int16_t ra_ResponseWindow = *msgA_ConfigCommon_r16->rach_ConfigCommonTwoStepRA_r16
.rach_ConfigGenericTwoStepRA_r16.msgB_ResponseWindow_r16;
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;
}
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:
return 1;
break;
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl2:
return 2;
break;
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl4:
return 4;
break;
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl8:
return 8;
break;
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl10:
return 10;
break;
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl20:
return 20;
break;
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl40:
return 40;
break;
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl80:
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_COMPLETE_TIME_ADVANCE_MS(&mac->ntn_ta);
int slots_per_frame = mac->frame_structure.numb_slots_frame;
const int slots_per_ms = slots_per_frame / 10;
const int ra_Offset_slots = ra->RA_offset * slots_per_frame;
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);
}
////////////////////////////////////////////////////////////////////////////
/////////* Random Access Contention Resolution (5.1.35 TS 38.321) */////////
////////////////////////////////////////////////////////////////////////////
......@@ -1188,7 +1235,6 @@ void nr_ra_succeeded(NR_UE_MAC_INST_t *mac, const uint8_t gNB_index, const frame
if (ra->cfra) {
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",
......@@ -1210,7 +1256,6 @@ void nr_ra_succeeded(NR_UE_MAC_INST_t *mac, const uint8_t gNB_index, const frame
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);
ra->RA_active = false;
ra->msg3_C_RNTI = false;
ra->ra_state = nrRA_SUCCEEDED;
......@@ -1219,6 +1264,35 @@ void nr_ra_succeeded(NR_UE_MAC_INST_t *mac, const uint8_t gNB_index, const frame
nr_mac_rrc_ra_ind(mac->ue_id, frame, true);
}
void nr_rar_not_successful(NR_UE_MAC_INST_t *mac)
{
LOG_W(MAC, "[UE %d] RAR reception failed\n", mac->ue_id);
RA_config_t *ra = &mac->ra;
NR_PRACH_RESOURCES_t *prach_resources = &ra->prach_resources;
prach_resources->preamble_tx_counter++;
bool ra_completed = false;
if (prach_resources->preamble_tx_counter == ra->preambleTransMax + 1) {
// if the Random Access Preamble is transmitted on the SpCell
// TODO to be verified, this means SA if I'm not mistaken
if (IS_SA_MODE(get_softmodem_params())) {
// TODO indicate a Random Access problem to upper layers
} else {
// if the Random Access Preamble is transmitted on an SCell:
// consider the Random Access procedure unsuccessfully completed.
ra_completed = true;
ra->ra_state = nrRA_UE_IDLE;
}
}
if (!ra_completed) {
// select a random backoff time according to a uniform distribution
// between 0 and the PREAMBLE_BACKOFF
uint32_t seed = (unsigned int)(rdtsc_oai() & ~0);
uint32_t random_backoff = rand_r(&seed) % ra->RA_backoff_limit; // in slots
nr_timer_setup(&ra->RA_backoff_timer, random_backoff, 1);
nr_timer_start(&ra->RA_backoff_timer);
}
}
// Handling failure of RA procedure @ MAC layer
// according to section 5 of 3GPP TS 38.321 version 16.2.1 Release 16
// todo:
......@@ -1226,17 +1300,6 @@ void nr_ra_succeeded(NR_UE_MAC_INST_t *mac, const uint8_t gNB_index, const frame
void nr_ra_failed(NR_UE_MAC_INST_t *mac, uint8_t CC_id, NR_PRACH_RESOURCES_t *prach_resources, frame_t frame, int slot)
{
RA_config_t *ra = &mac->ra;
// Random seed generation
unsigned int seed;
if (IS_SOFTMODEM_IQPLAYER || IS_SOFTMODEM_IQRECORDER) {
// Overwrite seed with non-random seed for IQ player/recorder
seed = 1;
} else {
// & to truncate the int64_t and keep only the LSB bits, up to sizeof(int)
seed = (unsigned int)(rdtsc_oai() & ~0);
}
ra->ra_PreambleIndex = -1;
ra->ra_state = nrRA_UE_IDLE;
......@@ -1255,13 +1318,10 @@ void nr_ra_failed(NR_UE_MAC_INST_t *mac, uint8_t CC_id, NR_PRACH_RESOURCES_t *pr
slot,
ra->preambleTransMax);
ra->RA_backoff_cnt = rand_r(&seed) % (prach_resources->preamble_backoff + 1);
prach_resources->preamble_tx_counter = 1;
prach_resources->preamble_power_ramping_step += 2; // 2 dB increment
prach_resources->ra_preamble_rx_target_power = get_ra_preamble_rx_target_power(ra, mac->current_UL_BWP->scs);
} else {
nr_get_RA_window(mac);
}
}
......
......@@ -563,6 +563,12 @@ void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl
if (mac->state == UE_PERFORMING_RA && mac->ra.ra_state >= nrRA_WAIT_RAR) {
// if RA is ongoing use RA search space
if (is_ss_monitor_occasion(frame, slot, slots_per_frame, pdcch_config->ra_SS)) {
// The RA response window starts at the first symbol of the earliest CORESET
// the UE is configured to receive PDCCH for Type1-PDCCH CSS set
if (mac->ra.start_response_window) {
nr_timer_start(&mac->ra.response_window_timer);
mac->ra.start_response_window = false;
}
nr_rnti_type_t rnti_type = 0;
if (mac->ra.ra_type == RA_4_STEP) {
rnti_type = mac->ra.ra_state == nrRA_WAIT_RAR ? TYPE_RA_RNTI_ : TYPE_TC_RNTI_;
......
......@@ -492,9 +492,7 @@ int get_pusch_tx_power_ue(NR_UE_MAC_INST_t *mac,
if (current_UL_BWP->msg3_DeltaPreamble) {
DELTA_PREAMBLE_MSG3 = *current_UL_BWP->msg3_DeltaPreamble;
}
NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = current_UL_BWP->rach_ConfigCommon;
long preambleReceivedTargetPower = nr_rach_ConfigCommon->rach_ConfigGeneric.preambleReceivedTargetPower;
int P_O_PRE = preambleReceivedTargetPower;
int P_O_PRE = mac->ra.prach_resources.ra_preamble_rx_target_power;
P_O_NOMINAL_PUSCH = P_O_PRE + DELTA_PREAMBLE_MSG3;
if (has_pusch_power_control_config && pusch_Config->pusch_PowerControl->msg3_Alpha) {
......
......@@ -59,6 +59,25 @@
// #define DEBUG_MIB
// #define ENABLE_MAC_PAYLOAD_DEBUG 1
// #define DEBUG_RAR
// table 7.2-1 TS 38.321
const uint16_t table_7_2_1[16] = {
5, // row index 0
10, // row index 1
20, // row index 2
30, // row index 3
40, // row index 4
60, // row index 5
80, // row index 6
120, // row index 7
160, // row index 8
240, // row index 9
320, // row index 10
480, // row index 11
960, // row index 12
1920, // row index 13
};
/* TS 36.213 Table 9.2.3-3: Mapping of values for one HARQ-ACK bit to sequences */
static const int sequence_cyclic_shift_1_harq_ack_bit[2]
/* HARQ-ACK Value 0 1 */
......@@ -701,7 +720,7 @@ static int nr_ue_process_dci_dl_10(NR_UE_MAC_INST_t *mac,
dlsch_pdu->SubcarrierSpacing = mac->mib->subCarrierSpacingCommon + 2;
} else {
dlsch_pdu->SubcarrierSpacing = current_DL_BWP->scs;
if (mac->ra.RA_window_cnt >= 0 && rnti_type == TYPE_RA_RNTI_) {
if (nr_timer_is_active(&mac->ra.response_window_timer) && rnti_type == TYPE_RA_RNTI_) {
dl_conf_req->pdu_type = FAPI_NR_DL_CONFIG_TYPE_RA_DLSCH;
} else {
dl_conf_req->pdu_type = FAPI_NR_DL_CONFIG_TYPE_DLSCH;
......@@ -3414,11 +3433,11 @@ static bool check_ra_contention_resolution(const uint8_t *pdu, const uint8_t *co
}
static int nr_ue_validate_successrar(uint8_t *pduP,
int32_t pdu_len,
NR_UE_MAC_INST_t *mac,
uint8_t gNB_index,
frame_t frameP,
int slot)
int32_t pdu_len,
NR_UE_MAC_INST_t *mac,
uint8_t gNB_index,
frame_t frameP,
int slot)
{
// TS 38.321 - Figure 6.1.5a-1: BI MAC subheader
// TS 38.321 - Figure 6.1.5a-3: SuccessRAR MAC subheader
......@@ -3426,6 +3445,7 @@ static int nr_ue_validate_successrar(uint8_t *pduP,
uint8_t E = 1;
uint8_t cont_res_id[6];
RA_config_t *ra = &mac->ra;
ra->RA_backoff_limit = 0;
while (n < pdu_len && E) {
E = (pduP[n] >> 7) & 0x1;
......@@ -3433,7 +3453,9 @@ static int nr_ue_validate_successrar(uint8_t *pduP,
if (SUCESS_RAR_header_T1 == 0) { // T2 exist
int SUCESS_RAR_header_T2 = (pduP[n] >> 5) & 0x1;
if (SUCESS_RAR_header_T2 == 0) { // BI
ra->RA_backoff_indicator = pduP[n] & 0x0F;
int bi_ms = table_7_2_1[(pduP[n] & 0x0F)] * ra->scaling_factor_bi;
int slots_per_ms = mac->frame_structure.numb_slots_frame / 10;
ra->RA_backoff_limit = bi_ms * slots_per_ms;
n++;
} else { // S
n++;
......@@ -3476,6 +3498,7 @@ static int nr_ue_validate_successrar(uint8_t *pduP,
bool ra_success = check_ra_contention_resolution(cont_res_id, ra->cont_res_id);
if (ra->RA_active && ra_success) {
nr_timer_stop(&ra->response_window_timer);
nr_ra_succeeded(mac, gNB_index, frameP, slot);
} else if (!ra_success) {
// nr_ra_failed(mac, CC_id, &ra->prach_resources, frameP, slot);
......@@ -3841,6 +3864,115 @@ int nr_write_ce_ulsch_pdu(uint8_t *mac_ce,
return mac_ce - pdu;
}
static void handle_rar_reception(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *dlinfo, NR_MAC_RAR *rar, frame_t frame, int slot)
{
RAR_grant_t rar_grant;
RA_config_t *ra = &mac->ra;
#ifdef DEBUG_RAR
// CSI
unsigned char csi_req = (unsigned char)(rar->UL_GRANT_4 & 0x01);
#endif
// TPC
unsigned char tpc_command = (unsigned char)((rar->UL_GRANT_4 >> 1) & 0x07);
ra->Msg3_TPC = (tpc_command << 1) - 6;
// MCS
rar_grant.mcs = (unsigned char)(rar->UL_GRANT_4 >> 4);
// time alloc
rar_grant.Msg3_t_alloc = (unsigned char)(rar->UL_GRANT_3 & 0x0f);
// frequency alloc
rar_grant.Msg3_f_alloc = (uint16_t)((rar->UL_GRANT_3 >> 4) | (rar->UL_GRANT_2 << 4) | ((rar->UL_GRANT_1 & 0x03) << 12));
// frequency hopping
rar_grant.freq_hopping = (unsigned char)(rar->UL_GRANT_1 >> 2);
// Schedule Msg3
const NR_UE_UL_BWP_t *current_UL_BWP = mac->current_UL_BWP;
const NR_UE_DL_BWP_t *current_DL_BWP = mac->current_DL_BWP;
const NR_BWP_PDCCH_t *pdcch_config = &mac->config_BWP_PDCCH[current_DL_BWP->bwp_id];
NR_tda_info_t tda_info = get_ul_tda_info(current_UL_BWP,
*pdcch_config->ra_SS->controlResourceSetId,
pdcch_config->ra_SS->searchSpaceType->present,
TYPE_RA_RNTI_,
rar_grant.Msg3_t_alloc);
if (!tda_info.valid_tda || tda_info.nrOfSymbols == 0) {
LOG_E(MAC, "Cannot schedule Msg3. Something wrong in TDA information\n");
return;
}
frame_t frame_tx = 0;
int slot_tx = 0;
const int ntn_ue_koffset = GET_NTN_UE_K_OFFSET(&mac->ntn_ta, mac->current_UL_BWP->scs);
int ret = nr_ue_pusch_scheduler(mac, 1, frame, slot, &frame_tx, &slot_tx, tda_info.k2 + ntn_ue_koffset);
// TA command
// if the timeAlignmentTimer associated with this TAG is not running
if (!nr_timer_is_active(&mac->time_alignment_timer)) {
const int ta = rar->TA2 + (rar->TA1 << 5);
set_time_alignment(mac, ta, rar_ta, frame_tx, slot_tx);
LOG_W(MAC, "received TA command %d\n", 31 + ta);
}
// else ignore the received Timing Advance Command
#ifdef DEBUG_RAR
LOG_I(NR_MAC, "rarh->E = 0x%x\n", rarh->E);
LOG_I(NR_MAC, "rarh->T = 0x%x\n", rarh->T);
LOG_I(NR_MAC, "rarh->RAPID = 0x%x (%i)\n", rarh->RAPID, rarh->RAPID);
LOG_I(NR_MAC, "rar->R = 0x%x\n", rar->R);
LOG_I(NR_MAC, "rar->TA1 = 0x%x\n", rar->TA1);
LOG_I(NR_MAC, "rar->TA2 = 0x%x\n", rar->TA2);
LOG_I(NR_MAC, "rar->UL_GRANT_1 = 0x%x\n", rar->UL_GRANT_1);
LOG_I(NR_MAC, "rar->UL_GRANT_2 = 0x%x\n", rar->UL_GRANT_2);
LOG_I(NR_MAC, "rar->UL_GRANT_3 = 0x%x\n", rar->UL_GRANT_3);
LOG_I(NR_MAC, "rar->UL_GRANT_4 = 0x%x\n", rar->UL_GRANT_4);
LOG_I(NR_MAC, "rar->TCRNTI_1 = 0x%x\n", rar->TCRNTI_1);
LOG_I(NR_MAC, "rar->TCRNTI_2 = 0x%x\n", rar->TCRNTI_2);
LOG_I(NR_MAC,
"[%d.%d]: [UE %d] Received RAR with t_alloc %d f_alloc %d ta_command %d mcs %d freq_hopping %d tpc_command %d\n",
frame,
slot,
mac->ue_id,
rar_grant.Msg3_t_alloc,
rar_grant.Msg3_f_alloc,
ta_command,
rar_grant.mcs,
rar_grant.freq_hopping,
tpc_command);
#endif
if (ret != -1) {
uint16_t rnti = mac->crnti;
// Upon successful reception, set the T-CRNTI to the RAR value
// if the RA preamble is selected among the contention-based RA Preambles
if (!ra->cfra) {
ra->t_crnti = rar->TCRNTI_2 + (rar->TCRNTI_1 << 8);
rnti = ra->t_crnti;
if (!ra->msg3_C_RNTI)
nr_mac_rrc_msg3_ind(mac->ue_id, rnti, dlinfo->gNB_index);
}
fapi_nr_ul_config_request_pdu_t *pdu = lockGet_ul_config(mac, frame_tx, slot_tx, FAPI_NR_UL_CONFIG_TYPE_PUSCH);
if (!pdu)
return;
// Config Msg3 PDU
int ret = nr_config_pusch_pdu(mac,
&tda_info,
&pdu->pusch_config_pdu,
NULL,
NULL,
&rar_grant,
rnti,
NR_SearchSpace__searchSpaceType_PR_common,
NR_DCI_NONE);
if (ret != 0)
remove_ul_config_last_item(pdu);
release_ul_config(pdu, false);
}
}
/////////////////////////////////////
// Random Access Response PDU //
// TS 38.213 ch 8.2 //
......@@ -3885,13 +4017,10 @@ static void nr_ue_process_rar(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *d
}
RA_config_t *ra = &mac->ra;
ra->t_crnti = 0;
uint8_t n_subPDUs = 0; // number of RAR payloads
uint8_t n_subheaders = 0; // number of MAC RAR subheaders
uint8_t *dlsch_buffer = dl_info->rx_ind->rx_indication_body[pdu_id].pdsch_pdu.pdu;
uint8_t is_Msg3 = 1;
frame_t frame_tx = 0;
int slot_tx = 0;
int ret = 0;
NR_RA_HEADER_RAPID *rarh = (NR_RA_HEADER_RAPID *) dlsch_buffer; // RAR subheader pointer
NR_MAC_RAR *rar = (NR_MAC_RAR *) (dlsch_buffer + 1); // RAR subPDU pointer
uint8_t preamble_index = ra->ra_PreambleIndex;
......@@ -3900,7 +4029,8 @@ static void nr_ue_process_rar(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *d
T(T_NRUE_MAC_DL_RAR_PDU_WITH_DATA, T_INT(rnti), T_INT(frame), T_INT(slot),
T_BUFFER(dlsch_buffer, dl_info->rx_ind->rx_indication_body[pdu_id].pdsch_pdu.pdu_length));
LOG_D(NR_MAC, "[%d.%d]: [UE %d][RAPROC] invoking MAC for received RAR (current preamble %d)\n", frame, slot, mac->ue_id, preamble_index);
ra->RA_backoff_limit = 0;
LOG_D(NR_MAC, "[%d.%d]: [UE %d][RAPROC] MAC received RAR (current preamble %d)\n", frame, slot, mac->ue_id, preamble_index);
while (1) {
n_subheaders++;
......@@ -3908,10 +4038,11 @@ static void nr_ue_process_rar(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *d
n_subPDUs++;
LOG_I(NR_MAC, "[UE %d][RAPROC][RA-RNTI %04x] Got RAPID RAR subPDU\n", mac->ue_id, rnti);
} else {
ra->RA_backoff_indicator = get_backoff_indicator(((NR_RA_HEADER_BI *)rarh)->BI);
ra->RA_BI_found = 1;
LOG_I(NR_MAC, "[UE %d][RAPROC][RA-RNTI %04x] Got BI RAR subPDU %d ms\n", mac->ue_id, ra->RA_backoff_indicator, rnti);
if ( ((NR_RA_HEADER_BI *)rarh)->E == 1) {
int bi_ms = table_7_2_1[((NR_RA_HEADER_BI *)rarh)->BI] * ra->scaling_factor_bi;
int slots_per_ms = mac->frame_structure.numb_slots_frame / 10;
ra->RA_backoff_limit = bi_ms * slots_per_ms;
LOG_I(NR_MAC, "[UE %d][RAPROC][RA-RNTI %04x] Got BI RAR subPDU %d ms\n", mac->ue_id, rnti, bi_ms);
if (((NR_RA_HEADER_BI *)rarh)->E == 1) {
rarh += sizeof(NR_RA_HEADER_BI);
continue;
} else {
......@@ -3919,9 +4050,15 @@ static void nr_ue_process_rar(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *d
}
}
if (rarh->RAPID == preamble_index) {
// The MAC entity may stop ra-ResponseWindow (and hence monitoring for Random Access Response(s)) after
// successful reception of a Random Access Response containing Random Access Preamble identifiers
// that matches the transmitted PREAMBLE_INDEX.
nr_timer_stop(&ra->response_window_timer);
LOG_A(NR_MAC, "[UE %d][RAPROC][%d.%d] Found RAR with the intended RAPID %d\n", mac->ue_id, frame, slot, rarh->RAPID);
rar = (NR_MAC_RAR *) (dlsch_buffer + n_subheaders + (n_subPDUs - 1) * sizeof(NR_MAC_RAR));
ra->RA_RAPID_found = 1;
handle_rar_reception(mac, dl_info, rar, frame, slot);
if (ra->cfra)
nr_ra_succeeded(mac, dl_info->gNB_index, frame, slot);
if (get_softmodem_params()->emulate_l1) {
/* When we are emulating L1 with multiple UEs, the rx_indication will have
multiple RAR PDUs. The code would previously handle each of these PDUs,
......@@ -3971,142 +4108,6 @@ static void nr_ue_process_rar(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *d
rarh->RAPID,
preamble_index);
#endif
if (ra->RA_RAPID_found) {
RAR_grant_t rar_grant;
#ifdef DEBUG_RAR
// CSI
unsigned char csi_req = (unsigned char) (rar->UL_GRANT_4 & 0x01);
#endif
// TPC
unsigned char tpc_command = (unsigned char) ((rar->UL_GRANT_4 >> 1) & 0x07);
switch (tpc_command){
case 0:
ra->Msg3_TPC = -6;
break;
case 1:
ra->Msg3_TPC = -4;
break;
case 2:
ra->Msg3_TPC = -2;
break;
case 3:
ra->Msg3_TPC = 0;
break;
case 4:
ra->Msg3_TPC = 2;
break;
case 5:
ra->Msg3_TPC = 4;
break;
case 6:
ra->Msg3_TPC = 6;
break;
case 7:
ra->Msg3_TPC = 8;
break;
default:
LOG_E(NR_PHY, "RAR impossible msg3 TPC\n");
}
// MCS
rar_grant.mcs = (unsigned char) (rar->UL_GRANT_4 >> 4);
// time alloc
rar_grant.Msg3_t_alloc = (unsigned char) (rar->UL_GRANT_3 & 0x0f);
// frequency alloc
rar_grant.Msg3_f_alloc = (uint16_t) ((rar->UL_GRANT_3 >> 4) | (rar->UL_GRANT_2 << 4) | ((rar->UL_GRANT_1 & 0x03) << 12));
// frequency hopping
rar_grant.freq_hopping = (unsigned char) (rar->UL_GRANT_1 >> 2);
// Schedule Msg3
const NR_UE_UL_BWP_t *current_UL_BWP = mac->current_UL_BWP;
const NR_UE_DL_BWP_t *current_DL_BWP = mac->current_DL_BWP;
const NR_BWP_PDCCH_t *pdcch_config = &mac->config_BWP_PDCCH[current_DL_BWP->bwp_id];
NR_tda_info_t tda_info = get_ul_tda_info(current_UL_BWP,
*pdcch_config->ra_SS->controlResourceSetId,
pdcch_config->ra_SS->searchSpaceType->present,
TYPE_RA_RNTI_,
rar_grant.Msg3_t_alloc);
if (!tda_info.valid_tda || tda_info.nrOfSymbols == 0) {
LOG_E(MAC, "Cannot schedule Msg3. Something wrong in TDA information\n");
return;
}
const int ntn_ue_koffset = GET_NTN_UE_K_OFFSET(&mac->ntn_ta, mac->current_UL_BWP->scs);
ret = nr_ue_pusch_scheduler(mac, is_Msg3, frame, slot, &frame_tx, &slot_tx, tda_info.k2 + ntn_ue_koffset);
// TA command
// if the timeAlignmentTimer associated with this TAG is not running
if (!nr_timer_is_active(&mac->time_alignment_timer)) {
const int ta = rar->TA2 + (rar->TA1 << 5);
set_time_alignment(mac, ta, rar_ta, frame_tx, slot_tx);
LOG_W(MAC, "received TA command %d\n", 31 + ta);
}
// else ignore the received Timing Advance Command
#ifdef DEBUG_RAR
LOG_I(NR_MAC, "rarh->E = 0x%x\n", rarh->E);
LOG_I(NR_MAC, "rarh->T = 0x%x\n", rarh->T);
LOG_I(NR_MAC, "rarh->RAPID = 0x%x (%i)\n", rarh->RAPID, rarh->RAPID);
LOG_I(NR_MAC, "rar->R = 0x%x\n", rar->R);
LOG_I(NR_MAC, "rar->TA1 = 0x%x\n", rar->TA1);
LOG_I(NR_MAC, "rar->TA2 = 0x%x\n", rar->TA2);
LOG_I(NR_MAC, "rar->UL_GRANT_1 = 0x%x\n", rar->UL_GRANT_1);
LOG_I(NR_MAC, "rar->UL_GRANT_2 = 0x%x\n", rar->UL_GRANT_2);
LOG_I(NR_MAC, "rar->UL_GRANT_3 = 0x%x\n", rar->UL_GRANT_3);
LOG_I(NR_MAC, "rar->UL_GRANT_4 = 0x%x\n", rar->UL_GRANT_4);
LOG_I(NR_MAC, "rar->TCRNTI_1 = 0x%x\n", rar->TCRNTI_1);
LOG_I(NR_MAC, "rar->TCRNTI_2 = 0x%x\n", rar->TCRNTI_2);
LOG_I(NR_MAC, "[%d.%d]: [UE %d] Received RAR with t_alloc %d f_alloc %d ta_command %d mcs %d freq_hopping %d tpc_command %d\n",
frame,
slot,
mac->ue_id,
rar_grant.Msg3_t_alloc,
rar_grant.Msg3_f_alloc,
ta_command,
rar_grant.mcs,
rar_grant.freq_hopping,
tpc_command);
#endif
if (ret != -1) {
uint16_t rnti = mac->crnti;
// Upon successful reception, set the T-CRNTI to the RAR value if the RA preamble is selected among the contention-based RA Preambles
if (!ra->cfra) {
ra->t_crnti = rar->TCRNTI_2 + (rar->TCRNTI_1 << 8);
rnti = ra->t_crnti;
if (!ra->msg3_C_RNTI)
nr_mac_rrc_msg3_ind(mac->ue_id, rnti, dl_info->gNB_index);
}
fapi_nr_ul_config_request_pdu_t *pdu = lockGet_ul_config(mac, frame_tx, slot_tx, FAPI_NR_UL_CONFIG_TYPE_PUSCH);
if (!pdu)
return;
// Config Msg3 PDU
int ret = nr_config_pusch_pdu(mac,
&tda_info,
&pdu->pusch_config_pdu,
NULL,
NULL,
&rar_grant,
rnti,
NR_SearchSpace__searchSpaceType_PR_common,
NR_DCI_NONE);
if (ret != 0)
remove_ul_config_last_item(pdu);
release_ul_config(pdu, false);
}
} else {
ra->t_crnti = 0;
// TODO if the Random Access Preamble was not selected by the MAC entity
// among the contention-based Random Access Preamble
// apply the Timing Advance Command and start or restart the timeAlignmentTimer
}
return;
}
......@@ -236,6 +236,15 @@ void update_mac_timers(NR_UE_MAC_INST_t *mac)
phr_info->phr_reporting |= (1 << phr_cause_periodic_timer);
}
}
bool ra_window_expired = nr_timer_tick(&mac->ra.response_window_timer);
if (ra_window_expired) // consider the Random Access Response reception not successful
nr_rar_not_successful(mac);
bool ra_backoff_expired = nr_timer_tick(&mac->ra.RA_backoff_timer);
if (ra_backoff_expired) {
// perform the Random Access Resource selection procedure after the backoff time
mac->ra.ra_state = nrRA_GENERATE_PREAMBLE;
ra_resource_selection(mac);
}
}
void remove_ul_config_last_item(fapi_nr_ul_config_request_pdu_t *pdu)
......@@ -2064,7 +2073,6 @@ static bool is_prach_frame(frame_t frame, prach_occasion_info_t *prach_occasion_
static void nr_ue_prach_scheduler(NR_UE_MAC_INST_t *mac, frame_t frameP, slot_t slotP)
{
RA_config_t *ra = &mac->ra;
ra->RA_offset = 2; // to compensate the rx frame offset at the gNB
if (ra->ra_state != nrRA_GENERATE_PREAMBLE)
return;
......@@ -2076,7 +2084,6 @@ static void nr_ue_prach_scheduler(NR_UE_MAC_INST_t *mac, frame_t frameP, slot_t
if (is_ul_slot(slotP, &mac->frame_structure)) {
if (slotP == prach_occasion_info->slot) {
nr_get_RA_window(mac);
fapi_nr_ul_config_request_pdu_t *pdu = lockGet_ul_config(mac, frameP, slotP, FAPI_NR_UL_CONFIG_TYPE_PRACH);
if (!pdu) {
LOG_E(NR_MAC, "Error in PRACH allocation\n");
......@@ -2156,6 +2163,7 @@ static void nr_ue_prach_scheduler(NR_UE_MAC_INST_t *mac, frame_t frameP, slot_t
if (ra->ra_type == RA_4_STEP) {
ra->ra_state = nrRA_WAIT_RAR;
ra->start_response_window = true;
} else if (ra->ra_type == RA_2_STEP) {
NR_MsgA_PUSCH_Resource_r16_t *msgA_PUSCH_Resource =
mac->current_UL_BWP->msgA_ConfigCommon_r16->msgA_PUSCH_Config_r16->msgA_PUSCH_ResourceGroupA_r16;
......
......@@ -192,8 +192,6 @@ TEST(pusch_power_control, pusch_power_control_msg3)
current_UL_BWP.BWPSize = 106;
current_UL_BWP.channel_bandwidth = 40;
mac.current_UL_BWP = &current_UL_BWP;
NR_RACH_ConfigCommon_t nr_rach_ConfigCommon = {0};
current_UL_BWP.rach_ConfigCommon = &nr_rach_ConfigCommon;
mac.nr_band = 78;
NR_PUSCH_Config_t pusch_Config = {0};
current_UL_BWP.pusch_Config = &pusch_Config;
......@@ -229,8 +227,8 @@ TEST(pusch_power_control, pusch_power_control_msg3)
num_rb,
start_prb);
long preambleReceivedTargetPower = -96;
nr_rach_ConfigCommon.rach_ConfigGeneric.preambleReceivedTargetPower = preambleReceivedTargetPower;
int preambleReceivedTargetPower = -96;
mac.ra.prach_resources.ra_preamble_rx_target_power = preambleReceivedTargetPower;
int power = get_pusch_tx_power_ue(&mac,
num_rb,
......@@ -247,7 +245,7 @@ TEST(pusch_power_control, pusch_power_control_msg3)
false);
EXPECT_EQ(power, -84);
EXPECT_LT(power, P_CMAX);
nr_rach_ConfigCommon.rach_ConfigGeneric.preambleReceivedTargetPower -= 2;
mac.ra.prach_resources.ra_preamble_rx_target_power -= 2;
int reduced_power = get_pusch_tx_power_ue(&mac,
num_rb,
......@@ -372,8 +370,6 @@ TEST(pusch_power_control, pusch_power_control_state_initialization)
current_UL_BWP.BWPSize = 106;
current_UL_BWP.channel_bandwidth = 40;
mac.current_UL_BWP = &current_UL_BWP;
NR_RACH_ConfigCommon_t nr_rach_ConfigCommon = {0};
current_UL_BWP.rach_ConfigCommon = &nr_rach_ConfigCommon;
mac.nr_band = 78;
NR_PUSCH_Config_t pusch_Config = {0};
current_UL_BWP.pusch_Config = &pusch_Config;
......@@ -393,8 +389,8 @@ TEST(pusch_power_control, pusch_power_control_state_initialization)
uint32_t sum_bits_in_codeblocks = 56;
int delta_pusch = 0;
bool is_rar_tx_retx = true;
long preambleReceivedTargetPower = -96;
nr_rach_ConfigCommon.rach_ConfigGeneric.preambleReceivedTargetPower = preambleReceivedTargetPower;
int preambleReceivedTargetPower = -96;
mac.ra.prach_resources.ra_preamble_rx_target_power = preambleReceivedTargetPower;
get_pusch_tx_power_ue(&mac,
num_rb,
......
......@@ -101,6 +101,7 @@ TEST(test_init_ra, four_step_cbra)
mac.p_Max = 23;
mac.nr_band = 78;
mac.frame_structure.frame_type = TDD;
mac.frame_structure.numb_slots_frame = 20;
mac.frequency_range = FR1;
mac.first_sync_frame = 0;
int frame = 151;
......@@ -135,6 +136,7 @@ TEST(test_init_ra, four_step_cfra)
mac.p_Max = 23;
mac.nr_band = 78;
mac.frame_structure.frame_type = TDD;
mac.frame_structure.numb_slots_frame = 20;
mac.frequency_range = FR1;
mac.first_sync_frame = 0;
int frame = 151;
......
......@@ -390,8 +390,7 @@ static bool is_my_dci(NR_UE_MAC_INST_t *mac, nfapi_nr_dl_dci_pdu_t *received_pdu
already. Only once the RA procedure succeeds is the CRNTI value updated
to the TC_RNTI. */
if (get_softmodem_params()->nsa) {
if (received_pdu->RNTI != mac->crnti &&
(received_pdu->RNTI != mac->ra.ra_rnti || mac->ra.RA_RAPID_found))
if (received_pdu->RNTI != mac->crnti && (received_pdu->RNTI != mac->ra.ra_rnti))
return false;
}
if (IS_SA_MODE(get_softmodem_params())) {
......@@ -1292,11 +1291,11 @@ static uint32_t nr_ue_dl_processing(NR_UE_MAC_INST_t *mac, nr_downlink_indicatio
ret_mask |= (handle_dlsch(mac, dl_info, i)) << FAPI_NR_RX_PDU_TYPE_DLSCH;
break;
case FAPI_NR_RX_PDU_TYPE_RAR:
ret_mask |= (handle_dlsch(mac, dl_info, i)) << FAPI_NR_RX_PDU_TYPE_RAR;
if (!dl_info->rx_ind->rx_indication_body[i].pdsch_pdu.ack_nack)
LOG_W(PHY, "Received a RAR-Msg2 but LDPC decode failed\n");
else
LOG_I(PHY, "RAR-Msg2 decoded\n");
ret_mask |= (handle_dlsch(mac, dl_info, i)) << FAPI_NR_RX_PDU_TYPE_RAR;
break;
case FAPI_NR_CSIRS_IND:
ret_mask |= (handle_csirs_measurements(mac,
......
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