diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index 26ee87bacf..f2527e1e8c 100644 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -1355,21 +1355,40 @@ static void configure_common_BWP_ul(NR_UE_MAC_INST_t *mac, int bwp_id, NR_BWP_Up } void nr_rrc_mac_config_req_reset(module_id_t module_id, - NR_UE_MAC_reset_cause_t reset_cause) + NR_UE_MAC_reset_cause_t cause) { NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); - reset_mac_inst(mac); - reset_ra(&mac->ra); - release_mac_configuration(mac); - nr_ue_init_mac(mac); - // Sending to PHY a request to resync - // with no target cell ID - if (reset_cause != DETACH) { - mac->synch_request.Mod_id = module_id; - mac->synch_request.CC_id = 0; - mac->synch_request.synch_req.target_Nid_cell = -1; - mac->if_module->synch_request(&mac->synch_request); + switch (cause) { + case GO_TO_IDLE: + reset_ra(&mac->ra); + release_mac_configuration(mac, cause); + nr_ue_init_mac(mac); + nr_ue_mac_default_configs(mac); + // new sync but no target cell id -> -1 + nr_ue_send_synch_request(mac, module_id, 0, -1); + break; + case DETACH: + reset_ra(&mac->ra); + reset_mac_inst(mac); + nr_ue_reset_sync_state(mac); + release_mac_configuration(mac, cause); + break; + case T300_EXPIRY: + reset_mac_inst(mac); + reset_ra(&mac->ra); + mac->state = UE_SYNC; // still in sync but need to restart RA + break; + case RE_ESTABLISHMENT: + reset_mac_inst(mac); + nr_ue_mac_default_configs(mac); + nr_ue_reset_sync_state(mac); + release_mac_configuration(mac, cause); + // new sync with old cell ID (re-establishment on the same cell) + nr_ue_send_synch_request(mac, module_id, 0, mac->physCellId); + break; + default: + AssertFatal(false, "Invalid MAC reset cause %d\n", cause); } } diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index 86ce0c348a..ec3a0d608f 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -205,7 +205,8 @@ NR_UE_MAC_INST_t *get_mac_inst(module_id_t module_id); void reset_mac_inst(NR_UE_MAC_INST_t *nr_mac); void reset_ra(RA_config_t *ra); -void release_mac_configuration(NR_UE_MAC_INST_t *mac); +void release_mac_configuration(NR_UE_MAC_INST_t *mac, + NR_UE_MAC_reset_cause_t cause); /**\brief called at each slot, slot length based on numerology. now use u=0, scs=15kHz, slot=1ms performs BSR/SR/PHR procedures, random access procedure handler and DLSCH/ULSCH procedures. @@ -450,6 +451,9 @@ void nr_get_prach_resources(NR_UE_MAC_INST_t *mac, void prepare_msg4_feedback(NR_UE_MAC_INST_t *mac, int pid, int ack_nack); void configure_initial_pucch(PUCCH_sched_t *pucch, int res_ind); +void nr_ue_reset_sync_state(NR_UE_MAC_INST_t *mac); +void nr_ue_send_synch_request(NR_UE_MAC_INST_t *mac, module_id_t module_id, int cc_id, int cell_id); + void init_RA(NR_UE_MAC_INST_t *mac, NR_PRACH_RESOURCES_t *prach_resources, NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon, diff --git a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c index c7e43e50f8..968f948631 100644 --- a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c +++ b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c @@ -56,12 +56,11 @@ void send_srb0_rrc(int ue_id, const uint8_t *sdu, sdu_size_t sdu_len, void *data void nr_ue_init_mac(NR_UE_MAC_INST_t *mac) { LOG_I(NR_MAC, "[UE%d] Initializing MAC\n", mac->ue_id); - mac->first_sync_frame = -1; + nr_ue_reset_sync_state(mac); mac->get_sib1 = false; mac->get_otherSI = false; mac->phy_config_request_sent = false; memset(&mac->phy_config, 0, sizeof(mac->phy_config)); - mac->state = UE_NOT_SYNC; mac->si_window_start = -1; mac->servCellIndex = 0; mac->harq_ACK_SpatialBundlingPUCCH = false; @@ -69,6 +68,9 @@ void nr_ue_init_mac(NR_UE_MAC_INST_t *mac) mac->uecap_maxMIMO_PDSCH_layers = 0; mac->uecap_maxMIMO_PUSCH_layers_cb = 0; mac->uecap_maxMIMO_PUSCH_layers_nocb = 0; + mac->p_Max = INT_MIN; + mac->p_Max_alt = INT_MIN; + reset_mac_inst(mac); memset(&mac->ssb_measurements, 0, sizeof(mac->ssb_measurements)); memset(&mac->ul_time_alignment, 0, sizeof(mac->ul_time_alignment)); @@ -76,35 +78,32 @@ void nr_ue_init_mac(NR_UE_MAC_INST_t *mac) memset(&mac->ssb_list[i], 0, sizeof(mac->ssb_list[i])); memset(&mac->prach_assoc_pattern[i], 0, sizeof(mac->prach_assoc_pattern[i])); } - for (int k = 0; k < NR_MAX_HARQ_PROCESSES; k++) { - mac->ul_harq_info[k].last_ndi = -1; // initialize to invalid value - mac->dl_harq_info[k].last_ndi = -1; // initialize to invalid value - } } void nr_ue_mac_default_configs(NR_UE_MAC_INST_t *mac) { // default values as defined in 38.331 sec 9.2.2 - mac->scheduling_info.retxBSR_Timer = NR_BSR_Config__retxBSR_Timer_sf10240; - mac->scheduling_info.periodicBSR_Timer = NR_BSR_Config__periodicBSR_Timer_infinity; - mac->scheduling_info.SR_COUNTER = 0; - mac->scheduling_info.SR_pending = 0; - mac->scheduling_info.sr_ProhibitTimer = 0; - mac->scheduling_info.sr_ProhibitTimer_Running = 0; - mac->scheduling_info.sr_id = -1; // invalid init value + mac->scheduling_info.retxBSR_Timer = NR_BSR_Config__retxBSR_Timer_sf80; + mac->scheduling_info.periodicBSR_Timer = NR_BSR_Config__periodicBSR_Timer_sf10; + mac->scheduling_info.periodicPHR_Timer = NR_PHR_Config__phr_PeriodicTimer_sf10; + mac->scheduling_info.prohibitPHR_Timer = NR_PHR_Config__phr_ProhibitTimer_sf10; +} - // set init value 0xFFFF, make sure periodic timer and retx time counters are NOT active, after bsr transmission set the value - // configured by the NW. - mac->scheduling_info.periodicBSR_SF = NR_MAC_UE_BSR_TIMER_NOT_RUNNING; - mac->scheduling_info.retxBSR_SF = NR_MAC_UE_BSR_TIMER_NOT_RUNNING; - mac->BSR_reporting_active = NR_BSR_TRIGGER_NONE; +void nr_ue_send_synch_request(NR_UE_MAC_INST_t *mac, module_id_t module_id, int cc_id, int cell_id) +{ + // Sending to PHY a request to resync + mac->synch_request.Mod_id = module_id; + mac->synch_request.CC_id = cc_id; + mac->synch_request.synch_req.target_Nid_cell = cell_id; + mac->if_module->synch_request(&mac->synch_request); +} - for (int i = 0; i < NR_MAX_NUM_LCID; i++) { - LOG_D(NR_MAC, "Applying default logical channel config for LCGID %d\n", i); - mac->scheduling_info.lc_sched_info[i].LCID_buffer_with_data = false; - mac->scheduling_info.lc_sched_info[i].LCID_buffer_remain = 0; - mac->scheduling_info.lc_sched_info[i].Bj = 0; - } +void nr_ue_reset_sync_state(NR_UE_MAC_INST_t *mac) +{ + // reset synchornization status + mac->first_sync_frame = -1; + mac->state = UE_NOT_SYNC; + mac->ra.ra_state = RA_UE_IDLE; } NR_UE_MAC_INST_t *nr_l2_init_ue(int nb_inst) @@ -144,14 +143,16 @@ void reset_mac_inst(NR_UE_MAC_INST_t *nr_mac) { // MAC reset according to 38.321 Section 5.12 - nr_ue_mac_default_configs(nr_mac); - // initialize Bj for each logical channel to zero - for (int i = 0; i < NR_MAX_NUM_LCID; i++) + // TODO reset also other status variables of LC, is this ok? + for (int i = 0; i < NR_MAX_NUM_LCID; i++) { nr_mac->scheduling_info.lc_sched_info[i].Bj = 0; + nr_mac->scheduling_info.lc_sched_info[i].LCID_buffer_with_data = false; + nr_mac->scheduling_info.lc_sched_info[i].LCID_buffer_remain = 0; + } - // stop all running timers - // TODO + // TODO stop all running timers + nr_timer_stop(&nr_mac->ra.contention_resolution_timer); // consider all timeAlignmentTimers as expired and perform the corresponding actions in clause 5.2 // TODO @@ -171,10 +172,16 @@ void reset_mac_inst(NR_UE_MAC_INST_t *nr_mac) free_and_zero(nr_mac->ra.Msg3_buffer); // cancel any triggered Scheduling Request procedure - // Done in default config + nr_mac->scheduling_info.SR_COUNTER = 0; + nr_mac->scheduling_info.SR_pending = 0; + nr_mac->scheduling_info.sr_ProhibitTimer = 0; + nr_mac->scheduling_info.sr_ProhibitTimer_Running = 0; + nr_mac->scheduling_info.sr_id = -1; // invalid init value // cancel any triggered Buffer Status Reporting procedure - // Done in default config + nr_mac->scheduling_info.periodicBSR_SF = NR_MAC_UE_BSR_TIMER_NOT_RUNNING; + nr_mac->scheduling_info.retxBSR_SF = NR_MAC_UE_BSR_TIMER_NOT_RUNNING; + nr_mac->BSR_reporting_active = NR_BSR_TRIGGER_NONE; // cancel any triggered Power Headroom Reporting procedure // TODO PHR not implemented yet @@ -194,12 +201,24 @@ void reset_mac_inst(NR_UE_MAC_INST_t *nr_mac) // TODO beam failure procedure not implemented } -void release_mac_configuration(NR_UE_MAC_INST_t *mac) +void release_mac_configuration(NR_UE_MAC_INST_t *mac, + NR_UE_MAC_reset_cause_t cause) { - asn1cFreeStruc(asn_DEF_NR_MIB, mac->mib); - asn1cFreeStruc(asn_DEF_NR_SI_SchedulingInfo, mac->si_SchedulingInfo); - asn1cFreeStruc(asn_DEF_NR_TDD_UL_DL_ConfigCommon, mac->tdd_UL_DL_ConfigurationCommon); NR_UE_ServingCell_Info_t *sc = &mac->sc_info; + // if cause is Re-establishment, release spCellConfig only + if (cause == GO_TO_IDLE) { + asn1cFreeStruc(asn_DEF_NR_MIB, mac->mib); + asn1cFreeStruc(asn_DEF_NR_SearchSpace, mac->search_space_zero); + asn1cFreeStruc(asn_DEF_NR_ControlResourceSet, mac->coreset0); + asn1cFreeStruc(asn_DEF_NR_SI_SchedulingInfo, mac->si_SchedulingInfo); + asn1cFreeStruc(asn_DEF_NR_TDD_UL_DL_ConfigCommon, mac->tdd_UL_DL_ConfigurationCommon); + for (int i = 0; i < mac->lc_ordered_list.count; i++) { + nr_lcordered_info_t *lc_info = mac->lc_ordered_list.array[i]; + asn_sequence_del(&mac->lc_ordered_list, i, 0); + free(lc_info); + } + } + asn1cFreeStruc(asn_DEF_NR_CrossCarrierSchedulingConfig, sc->crossCarrierSchedulingConfig); asn1cFreeStruc(asn_DEF_NR_SRS_CarrierSwitching, sc->carrierSwitching); asn1cFreeStruc(asn_DEF_NR_UplinkConfig, sc->supplementaryUplink); @@ -218,20 +237,35 @@ void release_mac_configuration(NR_UE_MAC_INST_t *mac) mac->current_DL_BWP = NULL; mac->current_UL_BWP = NULL; - for (int i = 0; i < mac->dl_BWPs.count; i++) - release_dl_BWP(mac, i); - for (int i = 0; i < mac->ul_BWPs.count; i++) - release_ul_BWP(mac, i); - - asn1cFreeStruc(asn_DEF_NR_SearchSpace, mac->search_space_zero); - asn1cFreeStruc(asn_DEF_NR_ControlResourceSet, mac->coreset0); - - for (int i = 0; i < mac->lc_ordered_list.count; i++) { - nr_lcordered_info_t *lc_info = mac->lc_ordered_list.array[i]; - asn_sequence_del(&mac->lc_ordered_list, i, 0); - free(lc_info); + // in case of re-establishment we don't need to release initial BWP config common + int first_bwp_rel = 0; // first BWP to release + if (cause == RE_ESTABLISHMENT) { + first_bwp_rel = 1; + // release dedicated BWP0 config + NR_UE_DL_BWP_t *bwp = mac->dl_BWPs.array[0]; + NR_BWP_PDCCH_t *pdcch = &mac->config_BWP_PDCCH[0]; + for (int i = 0; pdcch->list_Coreset.count; i++) + asn_sequence_del(&pdcch->list_Coreset, i, 1); + for (int i = 0; pdcch->list_SS.count; i++) + asn_sequence_del(&pdcch->list_SS, i, 1); + asn1cFreeStruc(asn_DEF_NR_PDSCH_Config, bwp->pdsch_Config); + NR_UE_UL_BWP_t *ubwp = mac->ul_BWPs.array[0]; + asn1cFreeStruc(asn_DEF_NR_PUCCH_Config, ubwp->pucch_Config); + asn1cFreeStruc(asn_DEF_NR_SRS_Config, ubwp->srs_Config); + asn1cFreeStruc(asn_DEF_NR_PUSCH_Config, ubwp->pusch_Config); + mac->current_DL_BWP = bwp; + mac->current_UL_BWP = ubwp; + mac->sc_info.initial_dl_BWPSize = bwp->BWPSize; + mac->sc_info.initial_dl_BWPStart = bwp->BWPStart; + mac->sc_info.initial_ul_BWPSize = ubwp->BWPSize; + mac->sc_info.initial_ul_BWPStart = ubwp->BWPStart; } + for (int i = first_bwp_rel; i < mac->dl_BWPs.count; i++) + release_dl_BWP(mac, i); + for (int i = first_bwp_rel; i < mac->ul_BWPs.count; i++) + release_ul_BWP(mac, i); + memset(&mac->ssb_measurements, 0, sizeof(mac->ssb_measurements)); memset(&mac->csirs_measurements, 0, sizeof(mac->csirs_measurements)); memset(&mac->ul_time_alignment, 0, sizeof(mac->ul_time_alignment)); diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 941eda1352..75f7e40fce 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -1601,6 +1601,45 @@ static void nr_rrc_ue_process_ueCapabilityEnquiry(NR_UE_RRC_INST_t *rrc, NR_UECa } } +void nr_rrc_initiate_rrcReestablishment(NR_UE_RRC_INST_t *rrc, + const int gnb_id) +{ + NR_UE_Timers_Constants_t *timers = &rrc->timers_and_constants; + rrcPerNB_t *rrcNB = rrc->perNB + gnb_id; + + // reset timers to SIB1 as part of release of spCellConfig + // it needs to be done before handling timers + set_rlf_sib1_timers_and_constants(timers, rrcNB->SInfo.sib1); + + // stop timer T310, if running + nr_timer_stop(&timers->T310); + // stop timer T304, if running + nr_timer_stop(&timers->T304); + // start timer T311 + nr_timer_start(&timers->T311); + // suspend all RBs, except SRB0 + for (int i = 1; i < 4; i++) { + if (rrc->Srb[i] == RB_ESTABLISHED) { + rrc->Srb[i] = RB_SUSPENDED; + nr_pdcp_suspend_srb(rrc->ue_id, i); + } + } + for (int i = 1; i <= MAX_DRBS_PER_UE; i++) { + if (get_DRB_status(rrc, i) == RB_ESTABLISHED) { + set_DRB_status(rrc, i, RB_SUSPENDED); + nr_pdcp_suspend_drb(rrc->ue_id, i); + } + } + // release the MCG SCell(s), if configured + // no SCell configured in our implementation + rrc->nrRrcState = RRC_STATE_REESTABLISHMENT; + + // reset MAC + // release spCellConfig, if configured + // perform cell selection in accordance with the cell selection process + nr_rrc_mac_config_req_reset(rrc->ue_id, RE_ESTABLISHMENT); +} + static void nr_rrc_ue_generate_rrcReestablishmentComplete(NR_RRCReestablishment_t *rrcReestablishment) { uint8_t buffer[RRC_BUFFER_SIZE] = {0}; diff --git a/openair2/RRC/NR_UE/rrc_defs.h b/openair2/RRC/NR_UE/rrc_defs.h index 4ce65ef036..448978a7d0 100644 --- a/openair2/RRC/NR_UE/rrc_defs.h +++ b/openair2/RRC/NR_UE/rrc_defs.h @@ -85,8 +85,7 @@ typedef enum Rrc_State_NR_e { RRC_STATE_INACTIVE_NR, RRC_STATE_CONNECTED_NR, RRC_STATE_DETACH_NR, - RRC_STATE_FIRST_NR = RRC_STATE_IDLE_NR, - RRC_STATE_LAST_NR = RRC_STATE_CONNECTED_NR, + RRC_STATE_REESTABLISHMENT } Rrc_State_NR_t; typedef enum requested_SI_List_e { diff --git a/openair2/RRC/NR_UE/rrc_proto.h b/openair2/RRC/NR_UE/rrc_proto.h index 1bb3fda06f..9ce17336d2 100644 --- a/openair2/RRC/NR_UE/rrc_proto.h +++ b/openair2/RRC/NR_UE/rrc_proto.h @@ -87,6 +87,7 @@ void nr_rrc_going_to_IDLE(NR_UE_RRC_INST_t *rrc, void nr_mac_rrc_ra_ind(const module_id_t mod_id, int frame, bool success); void nr_mac_rrc_msg3_ind(const module_id_t mod_id, const int rnti); +void set_rlf_sib1_timers_and_constants(NR_UE_Timers_Constants_t *tac, NR_SIB1_t *sib1); /**\brief RRC UE task. \param void *args_p Pointer on arguments to start the task. */