diff --git a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h index 62e514cf3f..37337e82d3 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h @@ -706,7 +706,6 @@ typedef struct uint8_t restricted_set_config;//PRACH restricted set config Value: 0: unrestricted 1: restricted set type A 2: restricted set type B uint8_t num_prach_fd_occasions;//Corresponds to the parameter 𝑀 in [38.211, sec 6.3.3.2] which equals the higher layer parameter msg1FDM Value: 1,2,4,8 fapi_nr_num_prach_fd_occasions_t* num_prach_fd_occasions_list; - uint8_t ssb_per_rach;//SSB-per-RACH-occasion Value: 0: 1/8 1:1/4, 2:1/2 3:1 4:2 5:4, 6:8 7:16 uint8_t prach_multiple_carriers_in_a_band;//0 = disabled 1 = enabled uint8_t root_seq_computed; // flag set and used only in PHY to indicate if table is computed with this config diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index 6b656e5242..8a89765e21 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -964,7 +964,7 @@ int main(int argc, char **argv) //Configure UE NR_BCCH_BCH_Message_t *mib = get_new_MIB_NR(scc); - nr_rrc_mac_config_req_mib(0, 0, mib->message.choice.mib, false, false); + nr_rrc_mac_config_req_mib(0, 0, mib->message.choice.mib, false); nr_rrc_mac_config_req_cg(0, 0, 0, 0, UE_CellGroup, UE_Capability_nr); asn1cFreeStruc(asn_DEF_NR_CellGroupConfig, UE_CellGroup); diff --git a/openair2/COMMON/mac_messages_types.h b/openair2/COMMON/mac_messages_types.h index d0d38c5938..a0314484eb 100644 --- a/openair2/COMMON/mac_messages_types.h +++ b/openair2/COMMON/mac_messages_types.h @@ -78,6 +78,7 @@ typedef struct NRRrcMacRaInd_s { bool RA_succeeded; + int gnb_index; } NRRrcMacRaInd; typedef struct NRRrcMacMsg3Ind_s { diff --git a/openair2/COMMON/rrc_messages_types.h b/openair2/COMMON/rrc_messages_types.h index ab8f93763e..cfc6914f4b 100644 --- a/openair2/COMMON/rrc_messages_types.h +++ b/openair2/COMMON/rrc_messages_types.h @@ -481,7 +481,6 @@ typedef struct { } nr_mac_rrc_config_cg_t; typedef struct { NR_BCCH_BCH_Message_t *bcch; - int get_sib; bool access_barred; } nr_mac_rrc_config_mib_t; typedef struct { @@ -494,6 +493,10 @@ typedef struct { int frame; bool can_start_ra; } nr_mac_rrc_config_other_sib_t; +typedef struct { + int get_sib; +} nr_mac_rrc_sched_sib_t; + enum payload_type { NR_MAC_RRC_CONFIG_RESET, @@ -501,6 +504,7 @@ enum payload_type { NR_MAC_RRC_CONFIG_MIB, NR_MAC_RRC_CONFIG_SIB1, NR_MAC_RRC_CONFIG_OTHER_SIB, + NR_MAC_RRC_SCHED_SIB, NR_MAC_RRC_RESUME_RB }; @@ -511,6 +515,7 @@ typedef struct { nr_mac_rrc_config_cg_t config_cg; nr_mac_rrc_config_mib_t config_mib; nr_mac_rrc_config_sib1_t config_sib1; + nr_mac_rrc_sched_sib_t sched_sib; nr_mac_rrc_config_other_sib_t config_other_sib; nr_mac_rrc_resume_rb_t resume_rb; } payload; diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index 997d0b6c23..c92c8225f6 100644 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -260,8 +260,6 @@ static void config_common_ue_sa(NR_UE_MAC_INST_t *mac, NR_ServingCellConfigCommo mac->frequency_range); //prach_fd_occasion->num_unused_root_sequences = ??? } - cfg->prach_config.ssb_per_rach = rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present-1; - } // prepare data for orbit propagation based on SIB19 ephemeris data to be able to compute the round-trip-time between ue and sat @@ -548,7 +546,6 @@ static void config_common_ue(NR_UE_MAC_INST_t *mac, NR_ServingCellConfigCommon_t prach_fd_occasion->num_root_sequences = compute_nr_root_seq(rach_ConfigCommon, nb_preambles, frame_type, mac->frequency_range); - cfg->prach_config.ssb_per_rach = rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present - 1; // prach_fd_occasion->num_unused_root_sequences = ??? } } @@ -887,7 +884,8 @@ static void nr_configure_lc_config(NR_UE_MAC_INST_t *mac, nr_lcid_rb_t rb) { NR_LC_SCHEDULING_INFO *lc_sched_info = get_scheduling_info_from_lcid(mac, lc_info->lcid); - lc_info->rb = rb; + if (rb.type != NR_LCID_NONE) + lc_info->rb = rb; lc_info->rb_suspended = false; if (rb.type == NR_LCID_SRB && !mac_lc_config->ul_SpecificParameters) { // release configuration and reset to default @@ -915,6 +913,12 @@ static void nr_configure_lc_config(NR_UE_MAC_INST_t *mac, static nr_lcid_rb_t configure_lcid_rb(NR_RLC_BearerConfig_t *rlc_bearer) { nr_lcid_rb_t rb; + if (!rlc_bearer->servedRadioBearer) { + LOG_W(NR_MAC, "RLC bearer config does not contain servedRadioBearer.\n"); + rb.type = NR_LCID_NONE; + return rb; + } + if (rlc_bearer->servedRadioBearer->present == NR_RLC_BearerConfig__servedRadioBearer_PR_srb_Identity) { rb.type = NR_LCID_SRB; rb.choice.srb_id = rlc_bearer->servedRadioBearer->choice.srb_Identity; @@ -954,8 +958,6 @@ static void configure_logicalChannelBearer(NR_UE_MAC_INST_t *mac, for (int i = 0; i < rlc_toadd_list->list.count; i++) { NR_RLC_BearerConfig_t *rlc_bearer = rlc_toadd_list->list.array[i]; nr_lcid_rb_t rb = configure_lcid_rb(rlc_bearer); - if (rb.type == NR_LCID_NONE) - continue; int lc_identity = rlc_bearer->logicalChannelIdentity; NR_LogicalChannelConfig_t *mac_lc_config = rlc_bearer->mac_LogicalChannelConfig; int j; @@ -1023,7 +1025,21 @@ static bool is_cset0_present(frequency_range_t const fr, uint8_t const kssb) return (fr == FR1) ? (kssb < 24) : (kssb < 12); } -void nr_rrc_mac_config_req_mib(module_id_t module_id, int cc_idP, NR_MIB_t *mib, int sched_sib, bool barred) +void nr_rrc_mac_sched_sib(module_id_t module_id, int sched_sib) +{ + NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); + if (sched_sib == 1) { + bool const is_c0 = is_cset0_present(mac->frequency_range, mac->ssb_subcarrier_offset); + mac->get_sib1 = is_c0; + AssertFatal(is_c0, "RRC scheduling SIB1 reception but MIB indicates no SIB1 present in current cell\n"); + } else if (sched_sib > 1) + mac->get_otherSI[sched_sib - 2] = true; + + if (mac->state == UE_NOT_SYNC && mac->get_sib1) + mac->state = UE_RECEIVING_SIB; +} + +void nr_rrc_mac_config_req_mib(module_id_t module_id, int cc_idP, NR_MIB_t *mib, bool barred) { NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); int ret = pthread_mutex_lock(&mac->if_mutex); @@ -1043,22 +1059,10 @@ void nr_rrc_mac_config_req_mib(module_id_t module_id, int cc_idP, NR_MIB_t *mib, mac->phy_config.CC_id = cc_idP; nr_ue_decode_mib(mac, cc_idP); - - if (sched_sib == 1) { - bool const is_c0 = is_cset0_present(mac->frequency_range, mac->ssb_subcarrier_offset); - mac->get_sib1 = is_c0; - AssertFatal(is_c0, "RRC scheduling SIB1 reception but MIB indicates no SIB1 present in current cell\n"); - } else if (sched_sib > 1) - mac->get_otherSI[sched_sib - 2] = true; - if (get_softmodem_params()->phy_test) mac->state = UE_CONNECTED; - else if (mac->state == UE_NOT_SYNC) { - if (IS_SA_MODE(get_softmodem_params()) && mac->get_sib1) - mac->state = UE_RECEIVING_SIB; - else - mac->state = UE_PERFORMING_RA; - } + else if (mac->state == UE_NOT_SYNC_RECONF) + mac->state = UE_PERFORMING_RA; ret = pthread_mutex_unlock(&mac->if_mutex); AssertFatal(!ret, "mutex failed %d\n", ret); @@ -1714,10 +1718,13 @@ static void configure_common_BWP_ul(NR_UE_MAC_INST_t *mac, int bwp_id, NR_BWP_Up mac->sc_info.initial_ul_BWPStart = bwp->BWPStart; } if (ul_common->rach_ConfigCommon) { - HANDLE_SETUPRELEASE_DIRECT(bwp->rach_ConfigCommon, - ul_common->rach_ConfigCommon, - NR_RACH_ConfigCommon_t, - asn_DEF_NR_RACH_ConfigCommon); + // ssb_perRACH_OccasionAndCB_PreamblesPerSSB is need M + // if NULL we need to maintain the information + NR_SetupRelease_RACH_ConfigCommon_t *rachcommon = ul_common->rach_ConfigCommon; + if (rachcommon->present == NR_SetupRelease_RACH_ConfigCommon_PR_setup + && rachcommon->choice.setup->ssb_perRACH_OccasionAndCB_PreamblesPerSSB) + mac->ssb_ro_preambles = get_ssb_ro_preambles_4step(rachcommon->choice.setup->ssb_perRACH_OccasionAndCB_PreamblesPerSSB); + HANDLE_SETUPRELEASE_DIRECT(bwp->rach_ConfigCommon, rachcommon, NR_RACH_ConfigCommon_t, asn_DEF_NR_RACH_ConfigCommon); } if (ul_common->ext1 && ul_common->ext1->msgA_ConfigCommon_r16) { HANDLE_SETUPRELEASE_DIRECT(bwp->msgA_ConfigCommon_r16, @@ -1805,7 +1812,7 @@ void nr_rrc_mac_config_req_reset(module_id_t module_id, NR_UE_MAC_reset_cause_t LOG_A(NR_MAC, "Received detach indication\n"); reset_ra(mac, true); reset_mac_inst(mac); - nr_ue_reset_sync_state(mac); + nr_ue_reset_sync_state(mac, false); release_mac_configuration(mac, cause); mac->state = UE_DETACHING; break; @@ -1822,7 +1829,7 @@ void nr_rrc_mac_config_req_reset(module_id_t module_id, NR_UE_MAC_reset_cause_t case RE_ESTABLISHMENT: reset_mac_inst(mac); nr_ue_mac_default_configs(mac); - nr_ue_reset_sync_state(mac); + nr_ue_reset_sync_state(mac, true); release_mac_configuration(mac, cause); // suspend all RBs except SRB0 for (int j = 0; j < mac->lc_ordered_list.count; j++) { @@ -1976,12 +1983,23 @@ static void handle_reconfiguration_with_sync(NR_UE_MAC_INST_t *mac, LOG_I(NR_MAC, "Configuring CRNTI %x\n", mac->crnti); RA_config_t *ra = &mac->ra; + bool is_cfra = false; if (reconfWithSync->rach_ConfigDedicated) { AssertFatal(reconfWithSync->rach_ConfigDedicated->present == NR_ReconfigurationWithSync__rach_ConfigDedicated_PR_uplink, "RACH on supplementaryUplink not supported\n"); + NR_RACH_ConfigDedicated_t *rach_ConfigDedicated = reconfWithSync->rach_ConfigDedicated->choice.uplink; + if (rach_ConfigDedicated->cfra) + is_cfra = true; + if (rach_ConfigDedicated->ext1 && rach_ConfigDedicated->ext1->cfra_TwoStep_r16) + is_cfra = true; UPDATE_IE(ra->rach_ConfigDedicated, reconfWithSync->rach_ConfigDedicated->choice.uplink, NR_RACH_ConfigDedicated_t); } + // in case of CBRA and reconfiguration with sync (handover) + // the UE sends MSG3 with C-RNTI to identify itself + if (!is_cfra) + mac->msg3_C_RNTI = true; + if (reconfWithSync->spCellConfigCommon) { NR_ServingCellConfigCommon_t *scc = reconfWithSync->spCellConfigCommon; if (scc->physCellId) @@ -2000,7 +2018,7 @@ static void handle_reconfiguration_with_sync(NR_UE_MAC_INST_t *mac, configure_common_BWP_ul(mac, bwp_id, scc->uplinkConfigCommon->initialUplinkBWP); } - mac->state = UE_NOT_SYNC; + mac->state = UE_NOT_SYNC_RECONF; ra->ra_state = nrRA_UE_IDLE; nr_ue_mac_default_configs(mac); diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index 8a8d9e4ebb..7fda4a4b6c 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -150,6 +150,7 @@ // Define the UE L2 states with X-Macro #define NR_UE_L2_STATES \ UE_STATE(UE_NOT_SYNC) \ + UE_STATE(UE_NOT_SYNC_RECONF) \ UE_STATE(UE_BARRED) \ UE_STATE(UE_RECEIVING_SIB) \ UE_STATE(UE_PERFORMING_RA) \ @@ -644,6 +645,7 @@ typedef struct NR_UE_MAC_INST_s { NR_SSB_meas_t ssb_measurements[MAX_NB_SSB]; NR_CSIRS_meas_t csirs_measurements; + ssb_ro_preambles_t ssb_ro_preambles; dci_pdu_rel15_t def_dci_pdu_rel15[NR_MAX_SLOTS_PER_FRAME][8]; diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index 52cb38e4de..5ee8a62625 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -88,8 +88,8 @@ void nr_rrc_mac_config_req_cg(module_id_t module_id, NR_CellGroupConfig_t *cell_group_config, NR_UE_NR_Capability_t *ue_Capability); -void nr_rrc_mac_config_req_mib(module_id_t module_id, int cc_idP, NR_MIB_t *mibP, int sched_sib1, bool barred); - +void nr_rrc_mac_config_req_mib(module_id_t module_id, int cc_idP, NR_MIB_t *mibP, bool barred); +void nr_rrc_mac_sched_sib(module_id_t module_id, int sched_sib); void nr_rrc_mac_config_req_sib1(module_id_t module_id, int cc_idP, NR_SIB1_t *sib1, bool can_start_ra); struct position; /* forward declaration */ @@ -255,7 +255,7 @@ void nr_get_RA_window(NR_UE_MAC_INST_t *mac); void prepare_msg4_msgb_feedback(NR_UE_MAC_INST_t *mac, int pid, int ack_nack); void configure_initial_pucch(PUCCH_sched_t *pucch, int res_ind); void release_PUCCH_SRS(NR_UE_MAC_INST_t *mac); -void nr_ue_reset_sync_state(NR_UE_MAC_INST_t *mac); +void nr_ue_reset_sync_state(NR_UE_MAC_INST_t *mac, bool reconf); void nr_ue_send_synch_request(NR_UE_MAC_INST_t *mac, module_id_t module_id, int cc_id, const fapi_nr_synch_request_t *sync_req); bool is_ss_monitor_occasion(const int frame, const int slot, const int slots_per_frame, const NR_SearchSpace_t *ss); @@ -363,5 +363,5 @@ int sl_nr_ue_slot_select(const sl_nr_phy_config_request_t *cfg, int nr_slot, uin void nr_ue_sidelink_scheduler(nr_sidelink_indication_t *sl_ind, NR_UE_MAC_INST_t *mac); NR_SearchSpace_t *get_common_search_space(const NR_UE_MAC_INST_t *mac, const NR_SearchSpaceId_t ss_id); - +ssb_ro_preambles_t get_ssb_ro_preambles_4step(struct NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB *config); #endif diff --git a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c index c78d2217b4..4cf96b46bc 100644 --- a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c +++ b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c @@ -54,7 +54,7 @@ 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); - nr_ue_reset_sync_state(mac); + nr_ue_reset_sync_state(mac, false); mac->get_sib1 = false; for (int i = 0; i < MAX_SI_GROUPS; i++) mac->get_otherSI[i] = false; @@ -117,10 +117,10 @@ void nr_ue_send_synch_request(NR_UE_MAC_INST_t *mac, module_id_t module_id, int mac->if_module->synch_request(&mac->synch_request); } -void nr_ue_reset_sync_state(NR_UE_MAC_INST_t *mac) +void nr_ue_reset_sync_state(NR_UE_MAC_INST_t *mac, bool reconf) { // reset synchornization status - mac->state = UE_NOT_SYNC; + mac->state = reconf ? UE_NOT_SYNC_RECONF : UE_NOT_SYNC; mac->ra.ra_state = nrRA_UE_IDLE; } diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c index b5eeedca3f..ecf8edb022 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c @@ -190,7 +190,7 @@ static void select_preamble_group(NR_UE_MAC_INST_t *mac) // else if Msg3 is being retransmitted, we keep what used in first transmission of Msg3 } -static ssb_ro_preambles_t get_ssb_ro_preambles_4step(struct NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB *config) +ssb_ro_preambles_t get_ssb_ro_preambles_4step(struct NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB *config) { ssb_ro_preambles_t ret = {0}; switch (config->present) { @@ -293,9 +293,7 @@ static void config_preamble_index(NR_UE_MAC_INST_t *mac) bool groupBconfigured = false; int preamb_ga = 0; if (ra->ra_type == RA_4_STEP) { - AssertFatal(nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB, - "Not expeting ssb_perRACH_OccasionAndCB_PreamblesPerSSB to be NULL here\n"); - ra->ssb_ro_config = get_ssb_ro_preambles_4step(nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB); + ra->ssb_ro_config = mac->ssb_ro_preambles; if (nr_rach_ConfigCommon->totalNumberOfRA_Preambles) nb_of_preambles = *nr_rach_ConfigCommon->totalNumberOfRA_Preambles; // Amongst the contention-based Random Access Preambles associated with an SSB the first numberOfRA-PreamblesGroupA @@ -321,7 +319,7 @@ static void config_preamble_index(NR_UE_MAC_INST_t *mac) if (twostep->msgA_SSB_PerRACH_OccasionAndCB_PreamblesPerSSB_r16) ra->ssb_ro_config = get_ssb_ro_preambles_2step(twostep->msgA_SSB_PerRACH_OccasionAndCB_PreamblesPerSSB_r16); else - ra->ssb_ro_config = get_ssb_ro_preambles_4step(nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB); + ra->ssb_ro_config = mac->ssb_ro_preambles; if (twostep->msgA_TotalNumberOfRA_Preambles_r16) nb_of_preambles = *twostep->msgA_TotalNumberOfRA_Preambles_r16; } 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 7d630c3002..1f84b11a48 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c @@ -480,6 +480,15 @@ void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl } config_dci_pdu(mac, dl_config, rnti_type, slot, ra_SS); } + // If Msg3 has C-RNTI MAC CE, also monitor dedicated search spaces during contention resolution + // according to TS 38.321 section 5.1.5 + if (ra->ra_state == nrRA_WAIT_CONTENTION_RESOLUTION && mac->msg3_C_RNTI) { + for (int i = 0; i < pdcch_config->list_SS.count; i++) { + NR_SearchSpace_t *ss = pdcch_config->list_SS.array[i]; + if (is_ss_monitor_occasion(frame, slot, slots_per_frame, ss)) + config_dci_pdu(mac, dl_config, TYPE_C_RNTI_, slot, ss); + } + } } else if (mac->state == UE_CONNECTED) { /* In RRC Connected state, the UE monitors for fallback DCI with C-RNTI in common and UE-specific SS. diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index 6387d9b516..c8d40e7f11 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -1145,7 +1145,7 @@ void nr_ue_dl_scheduler(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *dl_info dl_config->slot = rx_slot; dl_config->number_pdus = 0; - if (mac->state == UE_NOT_SYNC || mac->state == UE_DETACHING) + if (mac->state == UE_NOT_SYNC || mac->state == UE_NOT_SYNC_RECONF || mac->state == UE_DETACHING) return; if (mac->state == UE_CONNECTED) { diff --git a/openair2/RRC/NR_UE/L2_interface_ue.c b/openair2/RRC/NR_UE/L2_interface_ue.c index 12ed0953dd..a1af257282 100644 --- a/openair2/RRC/NR_UE/L2_interface_ue.c +++ b/openair2/RRC/NR_UE/L2_interface_ue.c @@ -154,7 +154,6 @@ void process_msg_rcc_to_mac(nr_mac_rrc_message_t *msg, int instance_id) nr_rrc_mac_config_req_mib(instance_id, 0, msg->payload.config_mib.bcch->message.choice.mib, - msg->payload.config_mib.get_sib, msg->payload.config_mib.access_barred); ASN_STRUCT_FREE(asn_DEF_NR_BCCH_BCH_Message, msg->payload.config_mib.bcch); break; @@ -171,6 +170,9 @@ void process_msg_rcc_to_mac(nr_mac_rrc_message_t *msg, int instance_id) msg->payload.config_other_sib.frame, msg->payload.config_other_sib.can_start_ra); } break; + case NR_MAC_RRC_SCHED_SIB: + nr_rrc_mac_sched_sib(instance_id, msg->payload.sched_sib.get_sib); + break; case NR_MAC_RRC_RESUME_RB: nr_rrc_mac_resume_rb(instance_id, msg->payload.resume_rb.is_srb, msg->payload.resume_rb.rb_id); break; diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index bc2efb84b0..8487619092 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -750,6 +750,189 @@ static void nr_rrc_ue_process_RadioBearerConfig(NR_UE_RRC_INST_t *ue_rrc, NR_Rad LOG_I(NR_RRC, "State = NR_RRC_CONNECTED\n"); } +static void nr_rrc_signal_maxrtxindication(int ue_id) +{ + MessageDef *msg = itti_alloc_new_message(TASK_RLC_UE, ue_id, NR_RRC_RLC_MAXRTX); + NR_RRC_RLC_MAXRTX(msg).ue_id = ue_id; + itti_send_msg_to_task(TASK_RRC_NRUE, ue_id, msg); +} + +/** @brief Release all active RLC entities for a UE and set to inactive. + * This is typically used when tearing down all DRBs at UE side, + * such as after a PDU session release or full reconfiguration. + * @param rrc Pointer to NR_UE_RRC_INST_t structure + * @param id Logical Channel ID (must be in range [0, NR_MAX_NUM_LCID-1]) */ +static void nr_rrc_release_rlc_entity(NR_UE_RRC_INST_t *rrc, int id) +{ + DevAssert(rrc); + DevAssert(id >= 0 && id < NR_MAX_NUM_LCID); + if (rrc->active_RLC_entity[id]) { + rrc->active_RLC_entity[id] = false; + nr_rlc_release_entity(rrc->ue_id, id); + LOG_I(RLC, "Released RLC entity: ue_id=%ld, lc_id=%d\n", rrc->ue_id, id); + } +} + +static void nr_rrc_manage_rlc_bearers(NR_UE_RRC_INST_t *rrc, const NR_CellGroupConfig_t *cellGroupConfig) +{ + if (cellGroupConfig->rlc_BearerToReleaseList != NULL) { + for (int i = 0; i < cellGroupConfig->rlc_BearerToReleaseList->list.count; i++) { + NR_LogicalChannelIdentity_t *lcid = cellGroupConfig->rlc_BearerToReleaseList->list.array[i]; + AssertFatal(lcid, "LogicalChannelIdentity shouldn't be null here\n"); + nr_rrc_release_rlc_entity(rrc, *lcid); + } + } + + if (cellGroupConfig->rlc_BearerToAddModList != NULL) { + for (int i = 0; i < cellGroupConfig->rlc_BearerToAddModList->list.count; i++) { + NR_RLC_BearerConfig_t *rlc_bearer = cellGroupConfig->rlc_BearerToAddModList->list.array[i]; + NR_LogicalChannelIdentity_t lcid = rlc_bearer->logicalChannelIdentity; + if (rrc->active_RLC_entity[lcid]) { + if (rlc_bearer->reestablishRLC) + nr_rlc_reestablish_entity(rrc->ue_id, lcid); + if (rlc_bearer->rlc_Config) + nr_rlc_reconfigure_entity(rrc->ue_id, lcid, rlc_bearer->rlc_Config); + } else { + rrc->active_RLC_entity[lcid] = true; + AssertFatal(rlc_bearer->servedRadioBearer, "servedRadioBearer mandatory in case of setup\n"); + AssertFatal(rlc_bearer->servedRadioBearer->present != NR_RLC_BearerConfig__servedRadioBearer_PR_NOTHING, + "Invalid RB for RLC configuration\n"); + if (rlc_bearer->servedRadioBearer->present == NR_RLC_BearerConfig__servedRadioBearer_PR_srb_Identity) { + NR_SRB_Identity_t srb_id = rlc_bearer->servedRadioBearer->choice.srb_Identity; + nr_rlc_add_srb(rrc->ue_id, srb_id, rlc_bearer); + nr_rlc_set_rlf_handler(rrc->ue_id, nr_rrc_signal_maxrtxindication); + } else { // DRB + NR_DRB_Identity_t drb_id = rlc_bearer->servedRadioBearer->choice.drb_Identity; + if (!rlc_bearer->rlc_Config) { + LOG_E(RLC, "RLC-Config not present but is mandatory for setup\n"); + rrc->active_RLC_entity[lcid] = false; + } else { + nr_rlc_add_drb(rrc->ue_id, drb_id, rlc_bearer); + nr_rlc_set_rlf_handler(rrc->ue_id, nr_rrc_signal_maxrtxindication); + } + } + } + } + } +} + +static void nr_rrc_process_reconfigurationWithSync(NR_UE_RRC_INST_t *rrc, + NR_ReconfigurationWithSync_t *reconfigurationWithSync, + int gNB_index) +{ + // perform Reconfiguration with sync according to 5.3.5.5.2 + if (!rrc->as_security_activated && !(get_softmodem_params()->phy_test || get_softmodem_params()->do_ra)) { + // if the AS security is not activated, perform the actions upon going to RRC_IDLE as specified in 5.3.11 + // with the release cause 'other' upon which the procedure ends + NR_Release_Cause_t release_cause = OTHER; + nr_rrc_going_to_IDLE(rrc, release_cause, NULL); + return; + } + + if (reconfigurationWithSync->spCellConfigCommon) { + /* if the frequencyInfoDL is included, consider the target SpCell + to be one on the SSB frequency indicated by the frequencyInfoDL */ + const NR_DownlinkConfigCommon_t *dcc = reconfigurationWithSync->spCellConfigCommon->downlinkConfigCommon; + if (dcc && dcc->frequencyInfoDL && dcc->frequencyInfoDL->absoluteFrequencySSB) + rrc->arfcn_ssb = *dcc->frequencyInfoDL->absoluteFrequencySSB; + + // consider the target SpCell to be one with a physical cell identity indicated by the physCellId + if (!reconfigurationWithSync->spCellConfigCommon->physCellId) + LOG_E(NR_RRC, "physCellId absent but should be mandatory present upon cell change and cell addition\n"); + else + rrc->phyCellID = *reconfigurationWithSync->spCellConfigCommon->physCellId; + } + + NR_UE_Timers_Constants_t *tac = &rrc->timers_and_constants; + nr_timer_stop(&tac->T310); + if (!get_softmodem_params()->phy_test) { + // T304 is stopped upon completion of RA procedure which is not done in phy-test mode + int t304_value = nr_rrc_get_T304(reconfigurationWithSync->t304); + nr_timer_setup(&tac->T304, t304_value, 10); // 10ms step + nr_timer_start(&tac->T304); + } + rrc->rnti = reconfigurationWithSync->newUE_Identity; + // reset the MAC entity of this cell group (done at MAC in handle_reconfiguration_with_sync) + + // 3GPP TS38.331 section 5.3.5.5.2 + nr_timer_stop(&tac->T430); + + if (rrc->target_ntncfg) { + ASN_STRUCT_FREE(asn_DEF_NR_NTN_Config_r17, rrc->target_ntncfg); + rrc->target_ntncfg = NULL; + rrc->process_target_ntncfg = false; + } + if (reconfigurationWithSync->spCellConfigCommon && + reconfigurationWithSync->spCellConfigCommon->ext2 && + reconfigurationWithSync->spCellConfigCommon->ext2->ntn_Config_r17) { + NR_NTN_Config_r17_t *ntncfg = reconfigurationWithSync->spCellConfigCommon->ext2->ntn_Config_r17; + // EPOCH time is always sent if NTN config is sent through DCCH + AssertFatal(ntncfg->epochTime_r17, "NTN-CONFIG sent in dedicated mode should have EPOCHTIME\n"); + const int copy_result = asn_copy(&asn_DEF_NR_NTN_Config_r17, (void **)&rrc->target_ntncfg, ntncfg); + AssertFatal(copy_result == 0, "unable to copy NR_NTN_Config_r17_t\n"); + } +} + +static void nr_rrc_cellgroup_configuration(NR_UE_RRC_INST_t *rrc, NR_CellGroupConfig_t *cgConfig, int gNB_index, bool dedicatedsib1) +{ + NR_SpCellConfig_t *spCellConfig = cgConfig->spCellConfig; + if(spCellConfig) { + NR_ServingCellConfig_t *spCellConfigDedicated = spCellConfig->spCellConfigDedicated; + if (spCellConfigDedicated) { + if (spCellConfigDedicated->firstActiveDownlinkBWP_Id) + rrc->dl_bwp_id = *spCellConfigDedicated->firstActiveDownlinkBWP_Id; + if (spCellConfigDedicated->uplinkConfig && spCellConfigDedicated->uplinkConfig->firstActiveUplinkBWP_Id) + rrc->ul_bwp_id = *spCellConfigDedicated->uplinkConfig->firstActiveUplinkBWP_Id; + } + NR_ReconfigurationWithSync_t *reconfigurationWithSync = spCellConfig->reconfigurationWithSync; + if (reconfigurationWithSync) { + LOG_I(NR_RRC, "Processing reconfigurationWithSync\n"); + nr_rrc_process_reconfigurationWithSync(rrc, reconfigurationWithSync, gNB_index); + // if RRCReconfiguration does not include dedicatedSIB1-Delivery + // if the active downlink BWP, which is indicated by the firstActiveDownlinkBWP-Id for the target SpCell of the MCG, + // has a common search space configured by searchSpaceSIB1 + // acquire the SIB1, which is scheduled as specified in TS 38.213 [13], of the target SpCell of the MCG + if (!dedicatedsib1 && IS_SA_MODE(get_softmodem_params())) { + if (rrc->dl_bwp_id == 0) { + // Check initial DL BWP for searchSpaceSIB1 + NR_ServingCellConfigCommon_t *spCellConfigCommon = reconfigurationWithSync->spCellConfigCommon; + if (spCellConfigCommon) { + NR_DownlinkConfigCommon_t *downlinkConfig = spCellConfigCommon->downlinkConfigCommon; + if (downlinkConfig + && downlinkConfig->initialDownlinkBWP + && downlinkConfig->initialDownlinkBWP->pdcch_ConfigCommon + && downlinkConfig->initialDownlinkBWP->pdcch_ConfigCommon->present == NR_SetupRelease_PDCCH_ConfigCommon_PR_setup + && downlinkConfig->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->searchSpaceSIB1) { + rrc->sched_reconfsync_sib1 = true; + } + } + } else { + // Check dedicated DL BWP for searchSpaceSIB1 + if (spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList) { + for (int i = 0; i < spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count; i++) { + NR_BWP_Downlink_t *bwp = spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[i]; + if (bwp->bwp_Id == rrc->dl_bwp_id && bwp->bwp_Common && bwp->bwp_Common->pdcch_ConfigCommon + && bwp->bwp_Common->pdcch_ConfigCommon->present == NR_SetupRelease_PDCCH_ConfigCommon_PR_setup + && bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->searchSpaceSIB1) { + rrc->sched_reconfsync_sib1 = true; + break; + } + } + } + } + } + } + nr_rrc_handle_SetupRelease_RLF_TimersAndConstants(rrc, spCellConfig->rlf_TimersAndConstants); + } + + nr_rrc_manage_rlc_bearers(rrc, cgConfig); + + if (cgConfig->ext1) + AssertFatal(cgConfig->ext1->reportUplinkTxDirectCurrent == NULL, "Reporting of UplinkTxDirectCurrent not implemented\n"); + AssertFatal(cgConfig->sCellToReleaseList == NULL, "Secondary serving cell release not implemented\n"); + AssertFatal(cgConfig->sCellToAddModList == NULL, "Secondary serving cell addition not implemented\n"); +} + static void nr_rrc_ue_process_masterCellGroup(NR_UE_RRC_INST_t *rrc, OCTET_STRING_t *masterCellGroup, long *fullConfig, @@ -770,7 +953,7 @@ static void nr_rrc_ue_process_masterCellGroup(NR_UE_RRC_INST_t *rrc, xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void *) cellGroupConfig); } - nr_rrc_cellgroup_configuration(rrc, cellGroupConfig, gNB_index); + nr_rrc_cellgroup_configuration(rrc, cellGroupConfig, gNB_index, false); LOG_D(RRC, "Sending CellGroupConfig to MAC the pointer will be managed by mac\n"); nr_mac_rrc_message_t rrc_msg = {0}; @@ -783,7 +966,7 @@ static void nr_rrc_ue_process_masterCellGroup(NR_UE_RRC_INST_t *rrc, nr_rrc_send_msg_to_mac(rrc, &rrc_msg); } -static void nr_rrc_process_reconfiguration_v1530(NR_UE_RRC_INST_t *rrc, NR_RRCReconfiguration_v1530_IEs_t *rec_1530, int gNB_index) +static bool nr_rrc_process_reconfiguration_v1530(NR_UE_RRC_INST_t *rrc, NR_RRCReconfiguration_v1530_IEs_t *rec_1530, int gNB_index) { if (rec_1530->fullConfig) { // TODO perform the full configuration procedure as specified in 5.3.5.11 of 331 @@ -797,7 +980,9 @@ static void nr_rrc_process_reconfiguration_v1530(NR_UE_RRC_INST_t *rrc, NR_RRCRe nr_pdcp_config_set_security(rrc->ue_id, 1, true, &sp); } NR_UE_RRC_SI_INFO *SI_info = &rrc->perNB[gNB_index].SInfo; + bool dedicatedsib1 = false; if (rec_1530->dedicatedSIB1_Delivery) { + dedicatedsib1 = true; NR_SIB1_t *sib1 = NULL; asn_dec_rval_t dec_rval = uper_decode(NULL, &asn_DEF_NR_SIB1, @@ -864,6 +1049,7 @@ static void nr_rrc_process_reconfiguration_v1530(NR_UE_RRC_INST_t *rrc, NR_RRCRe } } } + return dedicatedsib1; } static void handle_meas_reporting_remove(rrcPerNB_t *rrc, int id, NR_UE_Timers_Constants_t *timers) @@ -1142,8 +1328,9 @@ static void nr_rrc_ue_process_rrcReconfiguration(NR_UE_RRC_INST_t *rrc, int gNB_ case NR_RRCReconfiguration__criticalExtensions_PR_rrcReconfiguration: { NR_RRCReconfiguration_IEs_t *ie = reconfiguration->criticalExtensions.choice.rrcReconfiguration; + bool dedicatedsib1 = false; if (ie->nonCriticalExtension) - nr_rrc_process_reconfiguration_v1530(rrc, ie->nonCriticalExtension, gNB_index); + dedicatedsib1 = nr_rrc_process_reconfiguration_v1530(rrc, ie->nonCriticalExtension, gNB_index); if (ie->radioBearerConfig) { LOG_I(NR_RRC, "RRCReconfiguration includes radio Bearer Configuration\n"); @@ -1179,7 +1366,7 @@ static void nr_rrc_ue_process_rrcReconfiguration(NR_UE_RRC_INST_t *rrc, int gNB_ if (LOG_DEBUGFLAG(DEBUG_ASN1)) xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void *) cellGroupConfig); - nr_rrc_cellgroup_configuration(rrc, cellGroupConfig, gNB_index); + nr_rrc_cellgroup_configuration(rrc, cellGroupConfig, gNB_index, dedicatedsib1); AssertFatal(!IS_SA_MODE(get_softmodem_params()), "secondaryCellGroup only used in NSA for now\n"); nr_mac_rrc_message_t rrc_msg = {0}; rrc_msg.payload_type = NR_MAC_RRC_CONFIG_CG; @@ -1284,6 +1471,7 @@ NR_UE_RRC_INST_t* nr_rrc_init_ue(char* uecap_file, int instance_id, int num_ant_ rrc->dl_bwp_id = 0; rrc->ul_bwp_id = 0; rrc->as_security_activated = false; + rrc->sched_reconfsync_sib1 = false; rrc->detach_after_release = false; rrc->reconfig_after_reestab = false; /* 5G-S-TMSI */ @@ -1513,17 +1701,21 @@ static void nr_rrc_ue_decode_NR_BCCH_BCH_Message(NR_UE_RRC_INST_t *rrc, && rrc->nrRrcState != RRC_STATE_DETACH_NR) { // to schedule MAC to get SI if required get_sib = check_si_status(SI_info); - if (get_sib) - SI_info->sib_pending = true; } if (bcch_message->message.present == NR_BCCH_BCH_MessageType_PR_mib) { nr_mac_rrc_message_t rrc_msg = {0}; rrc_msg.payload_type = NR_MAC_RRC_CONFIG_MIB; nr_mac_rrc_config_mib_t *config_mib = &rrc_msg.payload.config_mib; config_mib->bcch = bcch_message; - config_mib->get_sib = get_sib; config_mib->access_barred = barred; nr_rrc_send_msg_to_mac(rrc, &rrc_msg); + if (get_sib) { + SI_info->sib_pending = true; + nr_mac_rrc_message_t sib_msg = {0}; + sib_msg.payload_type = NR_MAC_RRC_SCHED_SIB; + sib_msg.payload.sched_sib.get_sib = get_sib; + nr_rrc_send_msg_to_mac(rrc, &sib_msg); + } } else { LOG_E(NR_RRC, "RRC-received BCCH message is not a MIB\n"); ASN_STRUCT_FREE(asn_DEF_NR_BCCH_BCH_Message, bcch_message); @@ -1668,155 +1860,6 @@ static void nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(NR_UE_RRC_INST_t *rrc, VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_BCCH, VCD_FUNCTION_OUT ); } -static void nr_rrc_signal_maxrtxindication(int ue_id) -{ - MessageDef *msg = itti_alloc_new_message(TASK_RLC_UE, ue_id, NR_RRC_RLC_MAXRTX); - NR_RRC_RLC_MAXRTX(msg).ue_id = ue_id; - itti_send_msg_to_task(TASK_RRC_NRUE, ue_id, msg); -} - -/** @brief Release all active RLC entities for a UE and set to inactive. - * This is typically used when tearing down all DRBs at UE side, - * such as after a PDU session release or full reconfiguration. - * @param rrc Pointer to NR_UE_RRC_INST_t structure - * @param id Logical Channel ID (must be in range [0, NR_MAX_NUM_LCID-1]) */ -static void nr_rrc_release_rlc_entity(NR_UE_RRC_INST_t *rrc, int id) -{ - DevAssert(rrc); - DevAssert(id >= 0 && id < NR_MAX_NUM_LCID); - if (rrc->active_RLC_entity[id]) { - rrc->active_RLC_entity[id] = false; - nr_rlc_release_entity(rrc->ue_id, id); - LOG_I(RLC, "Released RLC entity: ue_id=%ld, lc_id=%d\n", rrc->ue_id, id); - } -} - -static void nr_rrc_manage_rlc_bearers(NR_UE_RRC_INST_t *rrc, const NR_CellGroupConfig_t *cellGroupConfig) -{ - if (cellGroupConfig->rlc_BearerToReleaseList != NULL) { - for (int i = 0; i < cellGroupConfig->rlc_BearerToReleaseList->list.count; i++) { - NR_LogicalChannelIdentity_t *lcid = cellGroupConfig->rlc_BearerToReleaseList->list.array[i]; - AssertFatal(lcid, "LogicalChannelIdentity shouldn't be null here\n"); - nr_rrc_release_rlc_entity(rrc, *lcid); - } - } - - if (cellGroupConfig->rlc_BearerToAddModList != NULL) { - for (int i = 0; i < cellGroupConfig->rlc_BearerToAddModList->list.count; i++) { - NR_RLC_BearerConfig_t *rlc_bearer = cellGroupConfig->rlc_BearerToAddModList->list.array[i]; - NR_LogicalChannelIdentity_t lcid = rlc_bearer->logicalChannelIdentity; - if (rrc->active_RLC_entity[lcid]) { - if (rlc_bearer->reestablishRLC) - nr_rlc_reestablish_entity(rrc->ue_id, lcid); - if (rlc_bearer->rlc_Config) - nr_rlc_reconfigure_entity(rrc->ue_id, lcid, rlc_bearer->rlc_Config); - } else { - rrc->active_RLC_entity[lcid] = true; - AssertFatal(rlc_bearer->servedRadioBearer, "servedRadioBearer mandatory in case of setup\n"); - AssertFatal(rlc_bearer->servedRadioBearer->present != NR_RLC_BearerConfig__servedRadioBearer_PR_NOTHING, - "Invalid RB for RLC configuration\n"); - if (rlc_bearer->servedRadioBearer->present == NR_RLC_BearerConfig__servedRadioBearer_PR_srb_Identity) { - NR_SRB_Identity_t srb_id = rlc_bearer->servedRadioBearer->choice.srb_Identity; - nr_rlc_add_srb(rrc->ue_id, srb_id, rlc_bearer); - nr_rlc_set_rlf_handler(rrc->ue_id, nr_rrc_signal_maxrtxindication); - } else { // DRB - NR_DRB_Identity_t drb_id = rlc_bearer->servedRadioBearer->choice.drb_Identity; - if (!rlc_bearer->rlc_Config) { - LOG_E(RLC, "RLC-Config not present but is mandatory for setup\n"); - rrc->active_RLC_entity[lcid] = false; - } else { - nr_rlc_add_drb(rrc->ue_id, drb_id, rlc_bearer); - nr_rlc_set_rlf_handler(rrc->ue_id, nr_rrc_signal_maxrtxindication); - } - } - } - } - } -} - -static void nr_rrc_process_reconfigurationWithSync(NR_UE_RRC_INST_t *rrc, - NR_ReconfigurationWithSync_t *reconfigurationWithSync, - int gNB_index) -{ - // perform Reconfiguration with sync according to 5.3.5.5.2 - if (!rrc->as_security_activated && !(get_softmodem_params()->phy_test || get_softmodem_params()->do_ra)) { - // if the AS security is not activated, perform the actions upon going to RRC_IDLE as specified in 5.3.11 - // with the release cause 'other' upon which the procedure ends - NR_Release_Cause_t release_cause = OTHER; - nr_rrc_going_to_IDLE(rrc, release_cause, NULL); - return; - } - - if (reconfigurationWithSync->spCellConfigCommon) { - /* if the frequencyInfoDL is included, consider the target SpCell - to be one on the SSB frequency indicated by the frequencyInfoDL */ - const NR_DownlinkConfigCommon_t *dcc = reconfigurationWithSync->spCellConfigCommon->downlinkConfigCommon; - if (dcc && dcc->frequencyInfoDL && dcc->frequencyInfoDL->absoluteFrequencySSB) - rrc->arfcn_ssb = *dcc->frequencyInfoDL->absoluteFrequencySSB; - - // consider the target SpCell to be one with a physical cell identity indicated by the physCellId - if (!reconfigurationWithSync->spCellConfigCommon->physCellId) - LOG_E(NR_RRC, "physCellId absent but should be mandatory present upon cell change and cell addition\n"); - else - rrc->phyCellID = *reconfigurationWithSync->spCellConfigCommon->physCellId; - } - - NR_UE_Timers_Constants_t *tac = &rrc->timers_and_constants; - nr_timer_stop(&tac->T310); - if (!get_softmodem_params()->phy_test) { - // T304 is stopped upon completion of RA procedure which is not done in phy-test mode - int t304_value = nr_rrc_get_T304(reconfigurationWithSync->t304); - nr_timer_setup(&tac->T304, t304_value, 10); // 10ms step - nr_timer_start(&tac->T304); - } - rrc->rnti = reconfigurationWithSync->newUE_Identity; - // reset the MAC entity of this cell group (done at MAC in handle_reconfiguration_with_sync) - - // 3GPP TS38.331 section 5.3.5.5.2 - nr_timer_stop(&tac->T430); - - if (rrc->target_ntncfg) { - ASN_STRUCT_FREE(asn_DEF_NR_NTN_Config_r17, rrc->target_ntncfg); - rrc->target_ntncfg = NULL; - rrc->process_target_ntncfg = false; - } - if (reconfigurationWithSync->spCellConfigCommon && - reconfigurationWithSync->spCellConfigCommon->ext2 && - reconfigurationWithSync->spCellConfigCommon->ext2->ntn_Config_r17) { - NR_NTN_Config_r17_t *ntncfg = reconfigurationWithSync->spCellConfigCommon->ext2->ntn_Config_r17; - // EPOCH time is always sent if NTN config is sent through DCCH - AssertFatal(ntncfg->epochTime_r17, "NTN-CONFIG sent in dedicated mode should have EPOCHTIME\n"); - const int copy_result = asn_copy(&asn_DEF_NR_NTN_Config_r17, (void **)&rrc->target_ntncfg, ntncfg); - AssertFatal(copy_result == 0, "unable to copy NR_NTN_Config_r17_t\n"); - } -} - -void nr_rrc_cellgroup_configuration(NR_UE_RRC_INST_t *rrc, NR_CellGroupConfig_t *cellGroupConfig, int gNB_index) -{ - NR_SpCellConfig_t *spCellConfig = cellGroupConfig->spCellConfig; - if(spCellConfig) { - if (spCellConfig->reconfigurationWithSync) { - LOG_I(NR_RRC, "Processing reconfigurationWithSync\n"); - nr_rrc_process_reconfigurationWithSync(rrc, spCellConfig->reconfigurationWithSync, gNB_index); - } - nr_rrc_handle_SetupRelease_RLF_TimersAndConstants(rrc, spCellConfig->rlf_TimersAndConstants); - if (spCellConfig->spCellConfigDedicated) { - if (spCellConfig->spCellConfigDedicated->firstActiveDownlinkBWP_Id) - rrc->dl_bwp_id = *spCellConfig->spCellConfigDedicated->firstActiveDownlinkBWP_Id; - if (spCellConfig->spCellConfigDedicated->uplinkConfig && - spCellConfig->spCellConfigDedicated->uplinkConfig->firstActiveUplinkBWP_Id) - rrc->dl_bwp_id = *spCellConfig->spCellConfigDedicated->uplinkConfig->firstActiveUplinkBWP_Id; - } - } - - nr_rrc_manage_rlc_bearers(rrc, cellGroupConfig); - - if (cellGroupConfig->ext1) - AssertFatal(cellGroupConfig->ext1->reportUplinkTxDirectCurrent == NULL, "Reporting of UplinkTxDirectCurrent not implemented\n"); - AssertFatal(cellGroupConfig->sCellToReleaseList == NULL, "Secondary serving cell release not implemented\n"); - AssertFatal(cellGroupConfig->sCellToAddModList == NULL, "Secondary serving cell addition not implemented\n"); -} - static void rrc_ue_generate_RRCSetupComplete(const NR_UE_RRC_INST_t *rrc, const uint8_t Transaction_id) { uint8_t buffer[100]; @@ -2592,14 +2635,37 @@ static void nr_ue_check_meas_report(NR_UE_RRC_INST_t *rrc, const uint8_t gnb_ind } } -void nr_rrc_handle_ra_indication(NR_UE_RRC_INST_t *rrc, bool ra_succeeded) +static void nr_rrc_handle_ra_indication(NR_UE_RRC_INST_t *rrc, bool ra_succeeded, int gNB_index) { NR_UE_Timers_Constants_t *timers = &rrc->timers_and_constants; if (ra_succeeded && nr_timer_is_active(&timers->T304)) { // successful Random Access procedure triggered by reconfigurationWithSync - nr_timer_stop(&timers->T304); - // TODO handle the rest of procedures as described in 5.3.5.3 for when + // procedures described in 5.3.5.3 of 38.331 when // reconfigurationWithSync is included in spCellConfig + nr_timer_stop(&timers->T304); + + // TODO apply the parts of the CQI reporting configuration, + // the scheduling request configuration and the sounding RS + // configuration that do not require the UE to know the SFN of the respective target SpCell + // TODO apply the parts of the measurement and the radio resource configuration + // that require the UE to know the SFN of the respective target SpCell + // (not sure what to do for these two points, probably not relevant for our implementation) + + // if T390 is running stop timer T390 for all access categories + if (nr_timer_is_active(&timers->T390)) { + nr_timer_stop(&timers->T390); + // TODO perform the actions as specified in 5.3.14.4. + } + + if (rrc->sched_reconfsync_sib1) { + rrc->sched_reconfsync_sib1 = false; + NR_UE_RRC_SI_INFO *SI_info = &rrc->perNB[gNB_index].SInfo; + SI_info->sib_pending = true; + nr_mac_rrc_message_t sib_msg = {0}; + sib_msg.payload_type = NR_MAC_RRC_SCHED_SIB; + sib_msg.payload.sched_sib.get_sib = 1; + nr_rrc_send_msg_to_mac(rrc, &sib_msg); + } } else if (!ra_succeeded) { // upon random access problem indication from MCG MAC // while neither T300, T301, T304, T311 nor T319 are running @@ -2691,7 +2757,7 @@ void *rrc_nrue(void *notUsed) rrc->ue_id, ITTI_MSG_NAME(msg_p), NR_RRC_MAC_RA_IND(msg_p).RA_succeeded ? "successful" : "failed"); - nr_rrc_handle_ra_indication(rrc, NR_RRC_MAC_RA_IND(msg_p).RA_succeeded); + nr_rrc_handle_ra_indication(rrc, NR_RRC_MAC_RA_IND(msg_p).RA_succeeded, NR_RRC_MAC_RA_IND(msg_p).gnb_index); break; case NR_RRC_MAC_BCCH_DATA_IND: diff --git a/openair2/RRC/NR_UE/rrc_defs.h b/openair2/RRC/NR_UE/rrc_defs.h index e7f9cec43b..336afcc63a 100644 --- a/openair2/RRC/NR_UE/rrc_defs.h +++ b/openair2/RRC/NR_UE/rrc_defs.h @@ -264,7 +264,7 @@ typedef struct NR_UE_RRC_INST_s { // Frame timing received from MAC int current_hfn; int current_frame; - + bool sched_reconfsync_sib1; //Sidelink params NR_SL_PreconfigurationNR_r16_t *sl_preconfig; // NTN params diff --git a/openair2/RRC/NR_UE/rrc_proto.h b/openair2/RRC/NR_UE/rrc_proto.h index 28bdeb6e51..d8f2c0f23f 100644 --- a/openair2/RRC/NR_UE/rrc_proto.h +++ b/openair2/RRC/NR_UE/rrc_proto.h @@ -46,9 +46,6 @@ NR_UE_RRC_INST_t* get_NR_UE_rrc_inst(int instance); void init_nsa_message (NR_UE_RRC_INST_t *rrc, char* reconfig_file, char* rbconfig_file); void process_nsa_message(NR_UE_RRC_INST_t *rrc, nsa_message_t nsa_message_type, void *message, int msg_len); - -void nr_rrc_cellgroup_configuration(NR_UE_RRC_INST_t *rrc, NR_CellGroupConfig_t *cellGroupConfig, int gNB_index); - void nr_rrc_going_to_IDLE(NR_UE_RRC_INST_t *rrc, NR_Release_Cause_t release_cause, NR_RRCRelease_t *RRCRelease);