diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index ddb522dfb5..95df46fb72 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -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 diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index 6d2c7a1efd..2157a6c1c8 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -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); diff --git a/openair2/LAYER2/NR_MAC_UE/mac_tables.c b/openair2/LAYER2/NR_MAC_UE/mac_tables.c index bd4cc6d8f3..a313600609 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_tables.c +++ b/openair2/LAYER2/NR_MAC_UE/mac_tables.c @@ -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; diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c index 9a4caa7038..02afecec81 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c @@ -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); } } diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c index b2fcab87c3..237838e4dc 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c @@ -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_; diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_power_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_power_procedures.c index 0c024560d7..9db464f015 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_power_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_power_procedures.c @@ -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) { diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 54f047f46d..a77067395f 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -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; } diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index d4d4aa3a4d..a5f129e312 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -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; diff --git a/openair2/LAYER2/NR_MAC_UE/tests/test_nr_ue_power_procedures.cpp b/openair2/LAYER2/NR_MAC_UE/tests/test_nr_ue_power_procedures.cpp index bcbec989c2..7dc0b43ec3 100644 --- a/openair2/LAYER2/NR_MAC_UE/tests/test_nr_ue_power_procedures.cpp +++ b/openair2/LAYER2/NR_MAC_UE/tests/test_nr_ue_power_procedures.cpp @@ -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 = ¤t_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 = ¤t_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, diff --git a/openair2/LAYER2/NR_MAC_UE/tests/test_nr_ue_ra_procedures.cpp b/openair2/LAYER2/NR_MAC_UE/tests/test_nr_ue_ra_procedures.cpp index 6e8916f6f0..504abae957 100644 --- a/openair2/LAYER2/NR_MAC_UE/tests/test_nr_ue_ra_procedures.cpp +++ b/openair2/LAYER2/NR_MAC_UE/tests/test_nr_ue_ra_procedures.cpp @@ -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; diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c index 9e7310cf40..d3e7a5a9aa 100644 --- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c @@ -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,