diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index 068890f620..ceea8f71c6 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -162,7 +162,6 @@ typedef enum { UE_NOT_SYNC = 0, UE_SYNC, UE_PERFORMING_RA, - UE_WAIT_TX_ACK_MSG4, UE_CONNECTED } NR_UE_L2_STATE_t; diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index 60c64ead12..f638ea789f 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -364,6 +364,9 @@ void nr_get_prach_resources(module_id_t mod_id, NR_PRACH_RESOURCES_t *prach_resources, NR_RACH_ConfigDedicated_t * rach_ConfigDedicated); +void prepare_msg4_feedback(NR_UE_MAC_INST_t *mac, NR_UE_HARQ_STATUS_t *current_harq, int ack_nack); +void configure_initial_pucch(PUCCH_sched_t *pucch, int res_ind); + void init_RA(module_id_t mod_id, NR_PRACH_RESOURCES_t *prach_resources, NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon, diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c index 19c9919f6a..07907addc5 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c @@ -894,7 +894,6 @@ void nr_ra_succeeded(const module_id_t mod_id, const uint8_t gNB_index, const fr if (ra->cfra) { LOG_I(MAC, "[UE %d][%d.%d][RAPROC] RA procedure succeeded. CF-RA: RAR successfully received.\n", mod_id, frame, slot); - mac->state = UE_CONNECTED; ra->RA_window_cnt = -1; } else { LOG_A(MAC, "[UE %d][%d.%d][RAPROC] RA procedure succeeded. CB-RA: Contention Resolution is successful.\n", mod_id, frame, slot); @@ -902,12 +901,12 @@ void nr_ra_succeeded(const module_id_t mod_id, const uint8_t gNB_index, const fr mac->crnti = ra->t_crnti; ra->t_crnti = 0; LOG_D(MAC, "In %s: [UE %d][%d.%d] CB-RA: cleared contention resolution timer...\n", __FUNCTION__, mod_id, frame, slot); - mac->state = UE_WAIT_TX_ACK_MSG4; } LOG_D(MAC, "In %s: [UE %d] clearing RA_active flag...\n", __FUNCTION__, mod_id); ra->RA_active = 0; ra->ra_state = RA_SUCCEEDED; + mac->state = UE_CONNECTED; nr_mac_rrc_ra_ind(mod_id, frame, true); } @@ -915,8 +914,8 @@ void nr_ra_succeeded(const module_id_t mod_id, const uint8_t gNB_index, const fr // according to section 5 of 3GPP TS 38.321 version 16.2.1 Release 16 // todo: // - complete handling of received contention-based RA preamble -void nr_ra_failed(uint8_t mod_id, uint8_t CC_id, NR_PRACH_RESOURCES_t *prach_resources, frame_t frame, int slot) { - +void nr_ra_failed(uint8_t mod_id, uint8_t CC_id, NR_PRACH_RESOURCES_t *prach_resources, frame_t frame, int slot) +{ NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); RA_config_t *ra = &mac->ra; // Random seed generation @@ -950,5 +949,32 @@ void nr_ra_failed(uint8_t mod_id, uint8_t CC_id, NR_PRACH_RESOURCES_t *prach_res // Resetting RA window nr_get_RA_window(mac); } +} +void prepare_msg4_feedback(NR_UE_MAC_INST_t *mac, NR_UE_HARQ_STATUS_t *current_harq, int ack_nack) +{ + int sched_slot = current_harq->ul_slot; + int sched_frame = current_harq->ul_frame; + fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, sched_slot, 0); + pthread_mutex_lock(&ul_config->mutex_ul_config); + mac->nr_ue_emul_l1.num_harqs = 1; + AssertFatal(ul_config->number_pdus < FAPI_NR_UL_CONFIG_LIST_NUM, + "ul_config->number_pdus %d out of bounds\n", + ul_config->number_pdus); + fapi_nr_ul_config_pucch_pdu *pucch_pdu = &ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu; + PUCCH_sched_t pucch = {0}; + pucch.n_CCE = current_harq->n_CCE; + pucch.N_CCE = current_harq->N_CCE; + pucch.delta_pucch = current_harq->delta_pucch; + pucch.ack_payload = ack_nack; + pucch.n_harq = 1; + current_harq->active = false; + current_harq->ack_received = false; + nr_ue_configure_pucch(mac, + sched_slot, + mac->ra.t_crnti, + &pucch, + pucch_pdu); + fill_ul_config(ul_config, sched_frame, sched_slot, FAPI_NR_UL_CONFIG_TYPE_PUCCH); + pthread_mutex_unlock(&ul_config->mutex_ul_config); } diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index f5902bed27..9a33dd842d 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -1262,7 +1262,6 @@ void set_harq_status(NR_UE_MAC_INST_t *mac, int slot) { NR_UE_HARQ_STATUS_t *current_harq = &mac->dl_harq_info[harq_id]; - current_harq->active = true; current_harq->ack_received = false; current_harq->pucch_resource_indicator = pucch_id; @@ -2172,6 +2171,19 @@ void multiplex_pucch_resource(NR_UE_MAC_INST_t *mac, PUCCH_sched_t *pucch, int n } } +void configure_initial_pucch(PUCCH_sched_t *pucch, int res_ind) +{ + /* see TS 38.213 9.2.1 PUCCH Resource Sets */ + int delta_PRI = res_ind; + int n_CCE_0 = pucch->n_CCE; + int N_CCE_0 = pucch->N_CCE; + if (N_CCE_0 == 0) + AssertFatal(1 == 0, "PUCCH No compatible pucch format found\n"); + int r_PUCCH = ((2 * n_CCE_0) / N_CCE_0) + (2 * delta_PRI); + pucch->initial_pucch_id = r_PUCCH; + pucch->pucch_resource = NULL; +} + /******************************************************************* * * NAME : get_downlink_ack @@ -2356,18 +2368,10 @@ bool get_downlink_ack(NR_UE_MAC_INST_t *mac, frame_t frame, int slot, PUCCH_sche } NR_PUCCH_Config_t *pucch_Config = current_UL_BWP->pucch_Config; - if (mac->state == UE_WAIT_TX_ACK_MSG4 || !pucch_Config || !pucch_Config->resourceSetToAddModList - || pucch_Config->resourceSetToAddModList->list.array[0] == NULL) { - /* see TS 38.213 9.2.1 PUCCH Resource Sets */ - int delta_PRI = res_ind; - int n_CCE_0 = pucch->n_CCE; - int N_CCE_0 = pucch->N_CCE; - if (N_CCE_0 == 0) - AssertFatal(1 == 0, "PUCCH No compatible pucch format found\n"); - int r_PUCCH = ((2 * n_CCE_0) / N_CCE_0) + (2 * delta_PRI); - pucch->initial_pucch_id = r_PUCCH; - pucch->pucch_resource = NULL; - } else { + if (!pucch_Config || !pucch_Config->resourceSetToAddModList + || pucch_Config->resourceSetToAddModList->list.array[0] == NULL) + configure_initial_pucch(pucch, res_ind); + else { int resource_set_id = find_pucch_resource_set(mac, O_ACK); int n_list = pucch_Config->resourceSetToAddModList->list.count; AssertFatal(resource_set_id < n_list, "Invalid PUCCH resource set id %d\n", resource_set_id); @@ -2381,7 +2385,7 @@ bool get_downlink_ack(NR_UE_MAC_INST_t *mac, frame_t frame, int slot, PUCCH_sche pucch->pucch_resource = acknack_resource; LOG_D(MAC, "frame %d slot %d pucch acknack payload %d\n", frame, slot, o_ACK); } - reverse_n_bits(&o_ACK,number_harq_feedback); + reverse_n_bits(&o_ACK, number_harq_feedback); pucch->ack_payload = o_ACK; pucch->n_harq = number_harq_feedback; @@ -2833,7 +2837,8 @@ void nr_ue_send_sdu(nr_downlink_indication_t *dl_info, int pdu_id) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_SDU, VCD_FUNCTION_IN); - LOG_D(MAC, "In %s [%d.%d] Handling DLSCH PDU...\n", __FUNCTION__, dl_info->frame, dl_info->slot); + LOG_D(MAC, "In [%d.%d] Handling DLSCH PDU type %d\n", + dl_info->frame, dl_info->slot, dl_info->rx_ind->rx_indication_body[pdu_id].pdu_type); // Processing MAC PDU // it parses MAC CEs subheaders, MAC CEs, SDU subheaderds and SDUs diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index e5ecba5efc..404b6a76b4 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -60,8 +60,8 @@ static prach_association_pattern_t prach_assoc_pattern; static void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t slotP); -void fill_ul_config(fapi_nr_ul_config_request_t *ul_config, frame_t frame_tx, int slot_tx, uint8_t pdu_type){ - +void fill_ul_config(fapi_nr_ul_config_request_t *ul_config, frame_t frame_tx, int slot_tx, uint8_t pdu_type) +{ AssertFatal(ul_config->number_pdus < sizeof(ul_config->ul_config_list) / sizeof(ul_config->ul_config_list[0]), "Number of PDUS in ul_config = %d > ul_config_list num elements", ul_config->number_pdus); // clear ul_config for new frame/slot @@ -91,8 +91,8 @@ void fill_scheduled_response(nr_scheduled_response_t *scheduled_response, int cc_id, frame_t frame, int slot, - void *phy_data){ - + void *phy_data) +{ scheduled_response->dl_config = dl_config; scheduled_response->ul_config = ul_config; scheduled_response->tx_request = tx_request; @@ -2137,8 +2137,6 @@ void nr_ue_pucch_scheduler(module_id_t module_idP, frame_t frameP, int slotP, vo fill_scheduled_response(&scheduled_response, NULL, ul_config, NULL, module_idP, 0 /*TBR fix*/, frameP, slotP, phy_data); if (mac->if_module != NULL && mac->if_module->scheduled_response != NULL) mac->if_module->scheduled_response(&scheduled_response); - if (mac->state == UE_WAIT_TX_ACK_MSG4) - mac->state = UE_CONNECTED; } } } diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c index 5e77829680..0b655ab010 100644 --- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c @@ -1103,15 +1103,20 @@ int8_t handle_csirs_measurements(module_id_t module_id, frame_t frame, int slot, return nr_ue_process_csirs_measurements(module_id, frame, slot, csirs_measurements); } -void update_harq_status(module_id_t module_id, uint8_t harq_pid, uint8_t ack_nack) { - +void update_harq_status(module_id_t module_id, uint8_t harq_pid, uint8_t ack_nack) +{ NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); NR_UE_HARQ_STATUS_t *current_harq = &mac->dl_harq_info[harq_pid]; if (current_harq->active) { - current_harq->ack = ack_nack; - current_harq->ack_received = true; - LOG_T(PHY,"Updating harq_status for harq_id %d,ack/nak %d\n",harq_pid,current_harq->ack); + 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 == WAIT_CONTENTION_RESOLUTION) + prepare_msg4_feedback(mac, current_harq, ack_nack); + else { + current_harq->ack = ack_nack; + current_harq->ack_received = true; + } } else { //shouldn't get here