diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index 80e2255aa5..b430727955 100644 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -1676,6 +1676,32 @@ static int get_ta_offset(long *n_TimingAdvanceOffset) return -1; } +static void configure_si_schedulingInfo(NR_UE_MAC_INST_t *mac, + NR_SI_SchedulingInfo_t *si_SchedulingInfo, + NR_SI_SchedulingInfo_v1700_t *si_SchedulingInfo_v1700) +{ + asn_sequence_empty(&mac->si_SchedInfo.si_SchedInfo_list); + if (si_SchedulingInfo) { + mac->si_SchedInfo.si_WindowLength = si_SchedulingInfo->si_WindowLength; + for (int i = 0; i < si_SchedulingInfo->schedulingInfoList.list.count; i++) { + si_schedinfo_config_t *config = calloc_or_fail(1, sizeof(*config)); + config->type = NR_SI_INFO; + config->si_WindowPosition = i + 1; + config->si_Periodicity = si_SchedulingInfo->schedulingInfoList.list.array[i]->si_Periodicity; + ASN_SEQUENCE_ADD(&mac->si_SchedInfo.si_SchedInfo_list, config); + } + } + if (si_SchedulingInfo_v1700) { + for (int i = 0; i < si_SchedulingInfo_v1700->schedulingInfoList2_r17.list.count; i++) { + si_schedinfo_config_t *config = calloc_or_fail(1, sizeof(*config)); + config->type = NR_SI_INFO_v1700; + config->si_WindowPosition = si_SchedulingInfo_v1700->schedulingInfoList2_r17.list.array[i]->si_WindowPosition_r17; + config->si_Periodicity = si_SchedulingInfo_v1700->schedulingInfoList2_r17.list.array[i]->si_Periodicity_r17; + ASN_SEQUENCE_ADD(&mac->si_SchedInfo.si_SchedInfo_list, config); + } + } +} + void nr_rrc_mac_config_req_sib1(module_id_t module_id, int cc_idP, NR_SI_SchedulingInfo_t *si_SchedulingInfo, @@ -1688,8 +1714,7 @@ void nr_rrc_mac_config_req_sib1(module_id_t module_id, AssertFatal(scc, "SIB1 SCC should not be NULL\n"); UPDATE_IE(mac->tdd_UL_DL_ConfigurationCommon, scc->tdd_UL_DL_ConfigurationCommon, NR_TDD_UL_DL_ConfigCommon_t); - UPDATE_IE(mac->si_SchedulingInfo, si_SchedulingInfo, NR_SI_SchedulingInfo_t); - UPDATE_IE(mac->si_SchedulingInfo_v1700, si_SchedulingInfo_v1700, NR_SI_SchedulingInfo_v1700_t); + configure_si_schedulingInfo(mac, si_SchedulingInfo, si_SchedulingInfo_v1700); mac->n_ta_offset = get_ta_offset(scc->n_TimingAdvanceOffset); config_common_ue_sa(mac, scc, cc_idP); @@ -1734,35 +1759,32 @@ void nr_rrc_mac_config_req_sib19_r17(module_id_t module_id, static void handle_reconfiguration_with_sync(NR_UE_MAC_INST_t *mac, int cc_idP, - const NR_ReconfigurationWithSync_t *reconfigurationWithSync) + const NR_ReconfigurationWithSync_t *reconfWithSync) { - mac->crnti = reconfigurationWithSync->newUE_Identity; + reset_mac_inst(mac); + mac->crnti = reconfWithSync->newUE_Identity; LOG_I(NR_MAC, "Configuring CRNTI %x\n", mac->crnti); RA_config_t *ra = &mac->ra; - if (reconfigurationWithSync->rach_ConfigDedicated) { - AssertFatal( - reconfigurationWithSync->rach_ConfigDedicated->present == NR_ReconfigurationWithSync__rach_ConfigDedicated_PR_uplink, - "RACH on supplementaryUplink not supported\n"); - UPDATE_IE(ra->rach_ConfigDedicated, reconfigurationWithSync->rach_ConfigDedicated->choice.uplink, NR_RACH_ConfigDedicated_t); + if (reconfWithSync->rach_ConfigDedicated) { + AssertFatal(reconfWithSync->rach_ConfigDedicated->present == NR_ReconfigurationWithSync__rach_ConfigDedicated_PR_uplink, + "RACH on supplementaryUplink not supported\n"); + UPDATE_IE(ra->rach_ConfigDedicated, reconfWithSync->rach_ConfigDedicated->choice.uplink, NR_RACH_ConfigDedicated_t); } - if (reconfigurationWithSync->spCellConfigCommon) { - NR_ServingCellConfigCommon_t *scc = reconfigurationWithSync->spCellConfigCommon; + if (reconfWithSync->spCellConfigCommon) { + NR_ServingCellConfigCommon_t *scc = reconfWithSync->spCellConfigCommon; mac->n_ta_offset = get_ta_offset(scc->n_TimingAdvanceOffset); if (scc->physCellId) mac->physCellId = *scc->physCellId; mac->dmrs_TypeA_Position = scc->dmrs_TypeA_Position; UPDATE_IE(mac->tdd_UL_DL_ConfigurationCommon, scc->tdd_UL_DL_ConfigurationCommon, NR_TDD_UL_DL_ConfigCommon_t); config_common_ue(mac, scc, cc_idP); + const int bwp_id = 0; if (scc->downlinkConfigCommon) - configure_common_BWP_dl(mac, - 0, // bwp-id - scc->downlinkConfigCommon->initialDownlinkBWP); + configure_common_BWP_dl(mac, bwp_id, scc->downlinkConfigCommon->initialDownlinkBWP); if (scc->uplinkConfigCommon) - configure_common_BWP_ul(mac, - 0, // bwp-id - scc->uplinkConfigCommon->initialUplinkBWP); + configure_common_BWP_ul(mac, bwp_id, scc->uplinkConfigCommon->initialUplinkBWP); } mac->state = UE_NOT_SYNC; diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index ca60310b45..51b9c29058 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -537,6 +537,23 @@ typedef struct { int NPRB; } ue_mac_stats_t; +typedef enum { + NR_SI_INFO, + NR_SI_INFO_v1700 +} nr_si_info_type; + +typedef struct { + nr_si_info_type type; + long si_Periodicity; + long si_WindowPosition; +} si_schedinfo_config_t; + +typedef struct { + int si_window_start; + int si_WindowLength; + A_SEQUENCE_OF(si_schedinfo_config_t) si_SchedInfo_list; +} si_schedInfo_t; + /*!\brief Top level UE MAC structure */ typedef struct NR_UE_MAC_INST_s { module_id_t ue_id; @@ -547,9 +564,8 @@ typedef struct NR_UE_MAC_INST_s { bool get_sib1; bool get_otherSI; NR_MIB_t *mib; - struct NR_SI_SchedulingInfo *si_SchedulingInfo; - struct NR_SI_SchedulingInfo_v1700 *si_SchedulingInfo_v1700; - int si_window_start; + + si_schedInfo_t si_SchedInfo; ssb_list_info_t ssb_list[MAX_NUM_BWP_UE]; prach_association_pattern_t prach_assoc_pattern[MAX_NUM_BWP_UE]; diff --git a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c index 8ad8d673b8..76dd88d07d 100644 --- a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c +++ b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c @@ -60,7 +60,7 @@ void nr_ue_init_mac(NR_UE_MAC_INST_t *mac) mac->get_sib1 = false; mac->get_otherSI = false; memset(&mac->phy_config, 0, sizeof(mac->phy_config)); - mac->si_window_start = -1; + mac->si_SchedInfo.si_window_start = -1; mac->servCellIndex = 0; mac->harq_ACK_SpatialBundlingPUCCH = false; mac->harq_ACK_SpatialBundlingPUSCH = false; @@ -261,7 +261,7 @@ void release_mac_configuration(NR_UE_MAC_INST_t *mac, NR_UE_MAC_reset_cause_t ca 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); + asn_sequence_empty(&mac->si_SchedInfo.si_SchedInfo_list); asn1cFreeStruc(asn_DEF_NR_TDD_UL_DL_ConfigCommon, mac->tdd_UL_DL_ConfigurationCommon); for (int i = mac->lc_ordered_list.count; i > 0 ; i--) asn_sequence_del(&mac->lc_ordered_list, i - 1, 1); 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 1c01f84d4d..debd5226be 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c @@ -444,8 +444,8 @@ bool search_space_monitoring_ocasion_other_si(NR_UE_MAC_INST_t *mac, int K = mac->ssb_list->nb_ssb_per_index[mac->mib_ssb]; // numbering current frame and slot in terms of monitoring occasions in window - int current_monitor_occasion = - ((abs_slot - mac->si_window_start) % period) + (duration * (abs_slot - mac->si_window_start) / period); + int rel_slot = abs_slot - mac->si_SchedInfo.si_window_start; + int current_monitor_occasion = (rel_slot % period) + (duration * rel_slot / period); return current_monitor_occasion % N == K; } } @@ -455,12 +455,12 @@ bool search_space_monitoring_ocasion_other_si(NR_UE_MAC_INST_t *mac, bool is_window_valid(NR_UE_MAC_INST_t *mac, int window_slots, int abs_slot) { - if (mac->si_window_start == -1) { + if (mac->si_SchedInfo.si_window_start == -1) { // out of window return false; - } else if (abs_slot > mac->si_window_start + window_slots) { + } else if (abs_slot > mac->si_SchedInfo.si_window_start + window_slots) { // window expired - mac->si_window_start = -1; + mac->si_SchedInfo.si_window_start = -1; return false; } return true; @@ -472,56 +472,38 @@ bool monitor_dci_for_other_SI(NR_UE_MAC_INST_t *mac, const int frame, const int slot) { - const struct NR_SI_SchedulingInfo *si_SchedulingInfo = mac->si_SchedulingInfo; - const struct NR_SI_SchedulingInfo_v1700 *si_SchedulingInfo_v1700 = mac->si_SchedulingInfo_v1700; - // 5.2.2.3.2 in 331 - - if (!si_SchedulingInfo_v1700 && !si_SchedulingInfo) { - LOG_D(NR_MAC_DCI, "No scheduling info provided in SIB1\n"); - return false; - } - + // according to 5.2.2.3.2 in 331 const int abs_slot = frame * slots_per_frame + slot; const int bwp_id = mac->current_DL_BWP->bwp_id; - if (si_SchedulingInfo) { - const int si_window_slots = 5 << si_SchedulingInfo->si_WindowLength; - for (int n = 0; n < si_SchedulingInfo->schedulingInfoList.list.count; n++) { - struct NR_SchedulingInfo *sched_Info = si_SchedulingInfo->schedulingInfoList.list.array[n]; - if (mac->si_window_start == -1) { - int x = n * si_window_slots; - int T = 8 << sched_Info->si_Periodicity; // radio frame periodicity - if ((frame % T) == (x / slots_per_frame) && (x % slots_per_frame == 0)) - mac->si_window_start = abs_slot; // in terms of absolute slot number - } - bool check_valid = is_window_valid(mac, si_window_slots, abs_slot); - if (check_valid && search_space_monitoring_ocasion_other_si(mac, ss, abs_slot, frame, slot, slots_per_frame, bwp_id)) { - return true; - } - } - } - - if (si_SchedulingInfo_v1700) { - for (int n = 0; n < si_SchedulingInfo_v1700->schedulingInfoList2_r17.list.count; n++) { - struct NR_SchedulingInfo2_r17 *sched_Info = si_SchedulingInfo_v1700->schedulingInfoList2_r17.list.array[n]; - - const int T = 8 << sched_Info->si_Periodicity_r17; - const int window_slots = 5 << 1; // 10 slots - const int x = ((sched_Info->si_WindowPosition_r17 - 1) * window_slots); // currently window starts from slot 0, maybe + 1? - const int N = 10; // TS 38.211 - - if (mac->si_window_start == -1) { - // this condition will calculate where SI-window starts - // 5.2.2.3.2 - if ((frame % T == floor(x / N)) && (slot == x % N)) { - mac->si_window_start = abs_slot; + for (int i = 0; i < mac->si_SchedInfo.si_SchedInfo_list.count; i++) { + si_schedinfo_config_t *config = mac->si_SchedInfo.si_SchedInfo_list.array[i]; + int window_slots = 5 << mac->si_SchedInfo.si_WindowLength; + int x = (config->si_WindowPosition - 1) * window_slots; + int T = 8 << config->si_Periodicity; // radio frame periodicity + bool check_valid; + switch (config->type) { + case NR_SI_INFO : + if (mac->si_SchedInfo.si_window_start == -1) { + if ((frame % T) == (x / slots_per_frame) && (x % slots_per_frame == 0)) + mac->si_SchedInfo.si_window_start = abs_slot; // in terms of absolute slot number } - } - - bool check_valid = is_window_valid(mac, window_slots, abs_slot); - if (check_valid && (sched_Info->si_WindowPosition_r17 - 1) == slot) { - return search_space_monitoring_ocasion_other_si(mac, ss, abs_slot, frame, slot, slots_per_frame, bwp_id); - } + check_valid = is_window_valid(mac, window_slots, abs_slot); + if (check_valid && search_space_monitoring_ocasion_other_si(mac, ss, abs_slot, frame, slot, slots_per_frame, bwp_id)) + return true; + break; + case NR_SI_INFO_v1700 : + if (mac->si_SchedInfo.si_window_start == -1) { + if ((frame % T == floor(x / slots_per_frame)) && (slot == x % slots_per_frame)) + mac->si_SchedInfo.si_window_start = abs_slot; + } + window_slots = 10; // TODO window length hardcoded to 10 at gNB for NTN + check_valid = is_window_valid(mac, window_slots, abs_slot); + if (check_valid && (config->si_WindowPosition - 1) == slot) + return search_space_monitoring_ocasion_other_si(mac, ss, abs_slot, frame, slot, slots_per_frame, bwp_id); + break; + default : + AssertFatal(false, "Invalid SI-SchedulingInfo case\n"); } } return false; diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index d5106b41ab..e9d1f20fb3 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -141,10 +141,6 @@ static void nr_rrc_ue_process_RadioBearerConfig(NR_UE_RRC_INST_t *ue_rrc, NR_RadioBearerConfig_t *const radioBearerConfig); static void nr_rrc_ue_generate_rrcReestablishmentComplete(const NR_UE_RRC_INST_t *rrc, const NR_RRCReestablishment_t *rrcReestablishment); static void process_lte_nsa_msg(NR_UE_RRC_INST_t *rrc, nsa_msg_t *msg, int msg_len); -static void nr_rrc_ue_process_rrcReconfiguration(NR_UE_RRC_INST_t *rrc, - int gNB_index, - NR_RRCReconfiguration_t *rrcReconfiguration); - static void nr_rrc_ue_process_ueCapabilityEnquiry(NR_UE_RRC_INST_t *rrc, NR_UECapabilityEnquiry_t *UECapabilityEnquiry); static void nr_rrc_ue_process_masterCellGroup(NR_UE_RRC_INST_t *rrc, OCTET_STRING_t *masterCellGroup, @@ -169,43 +165,282 @@ static void set_DRB_status(NR_UE_RRC_INST_t *rrc, NR_DRB_Identity_t drb_id, NR_R rrc->status_DRBs[drb_id - 1] = status; } -static void nr_rrc_ue_process_rrcReconfiguration(NR_UE_RRC_INST_t *rrc, - int gNB_index, - NR_RRCReconfiguration_t *rrcReconfiguration) +static void nr_decode_SI(NR_UE_RRC_SI_INFO *SI_info, NR_SystemInformation_t *si) +{ + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_UE_DECODE_SI, VCD_FUNCTION_IN); + + // Dump contents + if (si->criticalExtensions.present == NR_SystemInformation__criticalExtensions_PR_systemInformation + || si->criticalExtensions.present == NR_SystemInformation__criticalExtensions_PR_criticalExtensionsFuture_r16) { + LOG_D(NR_RRC, + "[UE] si->criticalExtensions.choice.NR_SystemInformation_t->sib_TypeAndInfo.list.count %d\n", + si->criticalExtensions.choice.systemInformation->sib_TypeAndInfo.list.count); + } else { + LOG_D(NR_RRC, "[UE] Unknown criticalExtension version (not Rel16)\n"); + return; + } + + for (int i = 0; i < si->criticalExtensions.choice.systemInformation->sib_TypeAndInfo.list.count; i++) { + SystemInformation_IEs__sib_TypeAndInfo__Member *typeandinfo; + typeandinfo = si->criticalExtensions.choice.systemInformation->sib_TypeAndInfo.list.array[i]; + LOG_I(NR_RRC, "Found SIB%d\n", typeandinfo->present + 1); + switch(typeandinfo->present) { + case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib2: + SI_info->sib2_validity = true; + nr_timer_start(&SI_info->sib2_timer); + break; + case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib3: + SI_info->sib3_validity = true; + nr_timer_start(&SI_info->sib3_timer); + break; + case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib4: + SI_info->sib4_validity = true; + nr_timer_start(&SI_info->sib4_timer); + break; + case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib5: + SI_info->sib5_validity = true; + nr_timer_start(&SI_info->sib5_timer); + break; + case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib6: + SI_info->sib6_validity = true; + nr_timer_start(&SI_info->sib6_timer); + break; + case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib7: + SI_info->sib7_validity = true; + nr_timer_start(&SI_info->sib7_timer); + break; + case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib8: + SI_info->sib8_validity = true; + nr_timer_start(&SI_info->sib8_timer); + break; + case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib9: + SI_info->sib9_validity = true; + nr_timer_start(&SI_info->sib9_timer); + break; + case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib10_v1610: + SI_info->sib10_validity = true; + nr_timer_start(&SI_info->sib10_timer); + break; + case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib11_v1610: + SI_info->sib11_validity = true; + nr_timer_start(&SI_info->sib11_timer); + break; + case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib12_v1610: + SI_info->sib12_validity = true; + nr_timer_start(&SI_info->sib12_timer); + break; + case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib13_v1610: + SI_info->sib13_validity = true; + nr_timer_start(&SI_info->sib13_timer); + break; + case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib14_v1610: + SI_info->sib14_validity = true; + nr_timer_start(&SI_info->sib14_timer); + break; + case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib19_v1700: + SI_info->SInfo_r17.sib19_validity = true; + if (g_log->log_component[NR_RRC].level >= OAILOG_DEBUG) + xer_fprint(stdout, &asn_DEF_NR_SIB19_r17, (const void *)typeandinfo->choice.sib19_v1700); + nr_timer_start(&SI_info->SInfo_r17.sib19_timer); + break; + default: + break; + } + } + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_UE_DECODE_SI, VCD_FUNCTION_OUT); +} + +static void nr_rrc_ue_prepare_RRCSetupRequest(NR_UE_RRC_INST_t *rrc) +{ + LOG_D(NR_RRC, "Generation of RRCSetupRequest\n"); + uint8_t rv[6]; + // Get RRCConnectionRequest, fill random for now + // Generate random byte stream for contention resolution + for (int i = 0; i < 6; i++) { +#ifdef SMBV + // if SMBV is configured the contention resolution needs to be fix for the connection procedure to succeed + rv[i] = i; +#else + rv[i] = taus() & 0xff; +#endif + } + + uint8_t buf[1024]; + int len = do_RRCSetupRequest(buf, sizeof(buf), rv); + + nr_rlc_srb_recv_sdu(rrc->ue_id, 0, buf, len); +} + +static void nr_rrc_configure_default_SI(NR_UE_RRC_SI_INFO *SI_info, + struct NR_SI_SchedulingInfo *si_SchedulingInfo, + struct NR_SI_SchedulingInfo_v1700 *si_SchedulingInfo_v1700) +{ + if (si_SchedulingInfo) { + SI_info->default_otherSI_map = 0; + for (int i = 0; i < si_SchedulingInfo->schedulingInfoList.list.count; i++) { + struct NR_SchedulingInfo *schedulingInfo = si_SchedulingInfo->schedulingInfoList.list.array[i]; + for (int j = 0; j < schedulingInfo->sib_MappingInfo.list.count; j++) { + struct NR_SIB_TypeInfo *sib_Type = schedulingInfo->sib_MappingInfo.list.array[j]; + SI_info->default_otherSI_map |= 1 << sib_Type->type; + } + } + } + + if (si_SchedulingInfo_v1700) { + SI_info->SInfo_r17.default_otherSI_map_r17 = 0; + for (int i = 0; i < si_SchedulingInfo_v1700->schedulingInfoList2_r17.list.count; i++) { + struct NR_SchedulingInfo2_r17 *schedulingInfo2 = si_SchedulingInfo_v1700->schedulingInfoList2_r17.list.array[i]; + for (int j = 0; j < schedulingInfo2->sib_MappingInfo_r17.list.count; j++) { + struct NR_SIB_TypeInfo_v1700 *sib_TypeInfo_v1700 = schedulingInfo2->sib_MappingInfo_r17.list.array[j]; + if (sib_TypeInfo_v1700->sibType_r17.present == NR_SIB_TypeInfo_v1700__sibType_r17_PR_type1_r17) { + SI_info->SInfo_r17.default_otherSI_map_r17 |= 1 << sib_TypeInfo_v1700->sibType_r17.choice.type1_r17; + } + } + } + } +} + +static void nr_rrc_process_sib1(NR_UE_RRC_INST_t *rrc, NR_UE_RRC_SI_INFO *SI_info, NR_SIB1_t *sib1) +{ + if(g_log->log_component[NR_RRC].level >= OAILOG_DEBUG) + xer_fprint(stdout, &asn_DEF_NR_SIB1, (const void *) sib1); + LOG_A(NR_RRC, "SIB1 decoded\n"); + nr_timer_start(&SI_info->sib1_timer); + SI_info->sib1_validity = true; + if (rrc->nrRrcState == RRC_STATE_IDLE_NR) { + rrc->ra_trigger = RRC_CONNECTION_SETUP; + // preparing RRC setup request payload in advance + nr_rrc_ue_prepare_RRCSetupRequest(rrc); + } + + NR_SI_SchedulingInfo_v1700_t *si_SchedInfo_v1700 = NULL; + if (sib1->nonCriticalExtension + && sib1->nonCriticalExtension->nonCriticalExtension + && sib1->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension) { + si_SchedInfo_v1700 = sib1->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->si_SchedulingInfo_v1700; + } + + // configure default SI + nr_rrc_configure_default_SI(SI_info, sib1->si_SchedulingInfo, si_SchedInfo_v1700); + // configure timers and constant + nr_rrc_set_sib1_timers_and_constants(&rrc->timers_and_constants, sib1); + // RRC storage of SIB1 timers and constants (eg needed in re-establishment) + UPDATE_IE(rrc->timers_and_constants.sib1_TimersAndConstants, sib1->ue_TimersAndConstants, NR_UE_TimersAndConstants_t); + + nr_rrc_mac_config_req_sib1(rrc->ue_id, 0, sib1->si_SchedulingInfo, si_SchedInfo_v1700, sib1->servingCellConfigCommon); +} + +static void 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 + LOG_E(NR_RRC, "RRCReconfiguration includes fullConfig but this is not implemented yet\n"); + } + if (rec_1530->masterCellGroup) + nr_rrc_ue_process_masterCellGroup(rrc, rec_1530->masterCellGroup, rec_1530->fullConfig); + if (rec_1530->masterKeyUpdate) { + // TODO perform AS security key update procedure as specified in 5.3.5.7 + LOG_E(NR_RRC, "RRCReconfiguration includes masterKeyUpdate but this is not implemented yet\n"); + } + /* Check if there is dedicated NAS information to forward to NAS */ + if (rec_1530->dedicatedNAS_MessageList) { + struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList *tmp = rec_1530->dedicatedNAS_MessageList; + for (int i = 0; i < tmp->list.count; i++) { + MessageDef *ittiMsg = itti_alloc_new_message(TASK_RRC_NRUE, rrc->ue_id, NAS_CONN_ESTABLI_CNF); + nas_establish_cnf_t *msg = &NAS_CONN_ESTABLI_CNF(ittiMsg); + msg->errCode = AS_SUCCESS; + msg->nasMsg.length = tmp->list.array[i]->size; + msg->nasMsg.nas_data = tmp->list.array[i]->buf; + itti_send_msg_to_task(TASK_NAS_NRUE, rrc->ue_id, ittiMsg); + } + tmp->list.count = 0; // to prevent the automatic free by ASN1_FREE + } + NR_UE_RRC_SI_INFO *SI_info = &rrc->perNB[gNB_index].SInfo; + if (rec_1530->dedicatedSIB1_Delivery) { + NR_SIB1_t *sib1 = NULL; + asn_dec_rval_t dec_rval = uper_decode(NULL, + &asn_DEF_NR_SIB1, + (void **)&sib1, + (uint8_t *)rec_1530->dedicatedSIB1_Delivery->buf, + rec_1530->dedicatedSIB1_Delivery->size, + 0, + 0); + if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { + LOG_E(NR_RRC, "dedicatedSIB1-Delivery decode error\n"); + SEQUENCE_free(&asn_DEF_NR_SIB1, sib1, 1); + } else { + nr_rrc_process_sib1(rrc, SI_info, sib1); + } + } + if (rec_1530->dedicatedSystemInformationDelivery) { + NR_SystemInformation_t *si = NULL; + asn_dec_rval_t dec_rval = uper_decode(NULL, + &asn_DEF_NR_SystemInformation, + (void **)&si, + (uint8_t *)rec_1530->dedicatedSystemInformationDelivery->buf, + rec_1530->dedicatedSystemInformationDelivery->size, + 0, + 0); + if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { + LOG_E(NR_RRC, "dedicatedSystemInformationDelivery decode error\n"); + SEQUENCE_free(&asn_DEF_NR_SystemInformation, si, 1); + } else { + LOG_I(NR_RRC, "[UE %ld] Decoding dedicatedSystemInformationDelivery\n", rrc->ue_id); + nr_decode_SI(SI_info, si); + } + } + if (rec_1530->otherConfig) { + // TODO perform the other configuration procedure as specified in 5.3.5.9 + LOG_E(NR_RRC, "RRCReconfiguration includes otherConfig but this is not handled yet\n"); + } + NR_RRCReconfiguration_v1540_IEs_t *rec_1540 = rec_1530->nonCriticalExtension; + if (rec_1540) { + NR_RRCReconfiguration_v1560_IEs_t *rec_1560 = rec_1540->nonCriticalExtension; + if (rec_1560->sk_Counter) { + // TODO perform AS security key update procedure as specified in 5.3.5.7 + LOG_E(NR_RRC, "RRCReconfiguration includes sk-Counter but this is not implemented yet\n"); + } + if (rec_1560->mrdc_SecondaryCellGroupConfig) { + // TODO perform handling of mrdc-SecondaryCellGroupConfig as specified in 5.3.5.3 + LOG_E(NR_RRC, "RRCReconfiguration includes mrdc-SecondaryCellGroupConfig but this is not handled yet\n"); + } + if (rec_1560->radioBearerConfig2) { + NR_RadioBearerConfig_t *RadioBearerConfig = NULL; + asn_dec_rval_t dec_rval = uper_decode(NULL, + &asn_DEF_NR_RadioBearerConfig, + (void **)&RadioBearerConfig, + (uint8_t *)rec_1560->radioBearerConfig2->buf, + rec_1560->radioBearerConfig2->size, + 0, + 0); + if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { + LOG_E(NR_RRC, "radioBearerConfig2 decode error\n"); + SEQUENCE_free(&asn_DEF_NR_RadioBearerConfig, RadioBearerConfig, 1); + } else + nr_rrc_ue_process_RadioBearerConfig(rrc, RadioBearerConfig); + } + } +} + +static void nr_rrc_ue_process_rrcReconfiguration(NR_UE_RRC_INST_t *rrc, int gNB_index, NR_RRCReconfiguration_t *reconfiguration) { rrcPerNB_t *rrcNB = rrc->perNB + gNB_index; - switch (rrcReconfiguration->criticalExtensions.present) { + switch (reconfiguration->criticalExtensions.present) { case NR_RRCReconfiguration__criticalExtensions_PR_rrcReconfiguration: { - NR_RRCReconfiguration_IEs_t *ie = rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration; + NR_RRCReconfiguration_IEs_t *ie = reconfiguration->criticalExtensions.choice.rrcReconfiguration; - if (ie->radioBearerConfig != NULL) { - LOG_I(NR_RRC, "radio Bearer Configuration is present\n"); + if (ie->radioBearerConfig) { + LOG_I(NR_RRC, "RRCReconfiguration includes radio Bearer Configuration\n"); nr_rrc_ue_process_RadioBearerConfig(rrc, ie->radioBearerConfig); if (LOG_DEBUGFLAG(DEBUG_ASN1)) xer_fprint(stdout, &asn_DEF_NR_RadioBearerConfig, (const void *)ie->radioBearerConfig); } - if (ie->nonCriticalExtension) { - NR_RRCReconfiguration_v1530_IEs_t *ext = ie->nonCriticalExtension; - if (ext->masterCellGroup) - nr_rrc_ue_process_masterCellGroup(rrc, ext->masterCellGroup, ext->fullConfig); - /* Check if there is dedicated NAS information to forward to NAS */ - if (ie->nonCriticalExtension->dedicatedNAS_MessageList) { - struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList *tmp = ext->dedicatedNAS_MessageList; - for (int i = 0; i < tmp->list.count; i++) { - MessageDef *ittiMsg = itti_alloc_new_message(TASK_RRC_NRUE, rrc->ue_id, NAS_CONN_ESTABLI_CNF); - nas_establish_cnf_t *msg = &NAS_CONN_ESTABLI_CNF(ittiMsg); - msg->errCode = AS_SUCCESS; - msg->nasMsg.length = tmp->list.array[i]->size; - msg->nasMsg.nas_data = tmp->list.array[i]->buf; - itti_send_msg_to_task(TASK_NAS_NRUE, rrc->ue_id, ittiMsg); - } - tmp->list.count = 0; // to prevent the automatic free by ASN1_FREE - } - } + if (ie->nonCriticalExtension) + nr_rrc_process_reconfiguration_v1530(rrc, ie->nonCriticalExtension, gNB_index); - if (ie->secondaryCellGroup != NULL) { + if (ie->secondaryCellGroup) { NR_CellGroupConfig_t *cellGroupConfig = NULL; asn_dec_rval_t dec_rval = uper_decode(NULL, &asn_DEF_NR_CellGroupConfig, // might be added prefix later @@ -233,15 +468,14 @@ static void nr_rrc_ue_process_rrcReconfiguration(NR_UE_RRC_INST_t *rrc, nr_rrc_mac_config_req_cg(rrc->ue_id, 0, cellGroupConfig, rrc->UECap.UE_NR_Capability); asn1cFreeStruc(asn_DEF_NR_CellGroupConfig, cellGroupConfig); } - if (ie->measConfig != NULL) { - LOG_I(NR_RRC, "Measurement Configuration is present\n"); + if (ie->measConfig) { + LOG_I(NR_RRC, "RRCReconfiguration includes Measurement Configuration\n"); nr_rrc_ue_process_measConfig(rrcNB, ie->measConfig, &rrc->timers_and_constants); } - if (ie->lateNonCriticalExtension != NULL) { - // unuse now + if (ie->lateNonCriticalExtension) { + LOG_E(NR_RRC, "RRCReconfiguration includes lateNonCriticalExtension. Not handled.\n"); } } break; - case NR_RRCReconfiguration__criticalExtensions_PR_NOTHING: case NR_RRCReconfiguration__criticalExtensions_PR_criticalExtensionsFuture: default: @@ -263,7 +497,7 @@ void process_nsa_message(NR_UE_RRC_INST_t *rrc, nsa_message_t nsa_message_type, if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { LOG_E(NR_RRC, "NR_RRCReconfiguration decode error\n"); // free the memory - SEQUENCE_free( &asn_DEF_NR_RRCReconfiguration, RRCReconfiguration, 1 ); + SEQUENCE_free(&asn_DEF_NR_RRCReconfiguration, RRCReconfiguration, 1); return; } nr_rrc_ue_process_rrcReconfiguration(rrc, 0, RRCReconfiguration); @@ -329,6 +563,7 @@ NR_UE_RRC_INST_t* nr_rrc_init_ue(char* uecap_file, int nb_inst, int num_ant_tx) rrc->ul_bwp_id = 0; rrc->as_security_activated = false; rrc->detach_after_release = false; + rrc->reconfig_after_reestab = false; FILE *f = NULL; if (uecap_file) @@ -377,55 +612,55 @@ bool check_si_validity(NR_UE_RRC_SI_INFO *SI_info, int si_type) { switch (si_type) { case NR_SIB_TypeInfo__type_sibType2: - if (!SI_info->sib2) + if (!SI_info->sib2_validity) return false; break; case NR_SIB_TypeInfo__type_sibType3: - if (!SI_info->sib3) + if (!SI_info->sib3_validity) return false; break; case NR_SIB_TypeInfo__type_sibType4: - if (!SI_info->sib4) + if (!SI_info->sib4_validity) return false; break; case NR_SIB_TypeInfo__type_sibType5: - if (!SI_info->sib5) + if (!SI_info->sib5_validity) return false; break; case NR_SIB_TypeInfo__type_sibType6: - if (!SI_info->sib6) + if (!SI_info->sib6_validity) return false; break; case NR_SIB_TypeInfo__type_sibType7: - if (!SI_info->sib7) + if (!SI_info->sib7_validity) return false; break; case NR_SIB_TypeInfo__type_sibType8: - if (!SI_info->sib8) + if (!SI_info->sib8_validity) return false; break; case NR_SIB_TypeInfo__type_sibType9: - if (!SI_info->sib9) + if (!SI_info->sib9_validity) return false; break; case NR_SIB_TypeInfo__type_sibType10_v1610: - if (!SI_info->sib10) + if (!SI_info->sib10_validity) return false; break; case NR_SIB_TypeInfo__type_sibType11_v1610: - if (!SI_info->sib11) + if (!SI_info->sib11_validity) return false; break; case NR_SIB_TypeInfo__type_sibType12_v1610: - if (!SI_info->sib12) + if (!SI_info->sib12_validity) return false; break; case NR_SIB_TypeInfo__type_sibType13_v1610: - if (!SI_info->sib13) + if (!SI_info->sib13_validity) return false; break; case NR_SIB_TypeInfo__type_sibType14_v1610: - if (!SI_info->sib14) + if (!SI_info->sib14_validity) return false; break; default : @@ -438,31 +673,31 @@ bool check_si_validity_r17(NR_UE_RRC_SI_INFO_r17 *SI_info, int si_type) { switch (si_type) { case NR_SIB_TypeInfo_v1700__sibType_r17__type1_r17_sibType15: - if (!SI_info->sib15) + if (!SI_info->sib15_validity) return false; break; case NR_SIB_TypeInfo_v1700__sibType_r17__type1_r17_sibType16: - if (!SI_info->sib16) + if (!SI_info->sib16_validity) return false; break; case NR_SIB_TypeInfo_v1700__sibType_r17__type1_r17_sibType17: - if (!SI_info->sib17) + if (!SI_info->sib17_validity) return false; break; case NR_SIB_TypeInfo_v1700__sibType_r17__type1_r17_sibType18: - if (!SI_info->sib18) + if (!SI_info->sib18_validity) return false; break; case NR_SIB_TypeInfo_v1700__sibType_r17__type1_r17_sibType19: - if (!SI_info->sib19) + if (!SI_info->sib19_validity) return false; break; case NR_SIB_TypeInfo_v1700__sibType_r17__type1_r17_sibType20: - if (!SI_info->sib20) + if (!SI_info->sib20_validity) return false; break; case NR_SIB_TypeInfo_v1700__sibType_r17__type1_r17_sibType21: - if (!SI_info->sib21) + if (!SI_info->sib21_validity) return false; break; default : @@ -474,10 +709,10 @@ bool check_si_validity_r17(NR_UE_RRC_SI_INFO_r17 *SI_info, int si_type) int check_si_status(NR_UE_RRC_SI_INFO *SI_info) { // schedule reception of SIB1 if RRC doesn't have it - if (!SI_info->sib1) + if (!SI_info->sib1_validity) return 1; else { - if (SI_info->sib1->si_SchedulingInfo) { + if (SI_info->default_otherSI_map) { // Check if RRC has configured default SI // from SIB2 to SIB14 as current ASN1 version // TODO can be used for on demand SI when (if) implemented @@ -571,133 +806,6 @@ static void nr_rrc_ue_decode_NR_BCCH_BCH_Message(NR_UE_RRC_INST_t *rrc, return; } -static int nr_decode_SI(NR_UE_RRC_SI_INFO *SI_info, NR_SystemInformation_t *si) -{ - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_UE_DECODE_SI, VCD_FUNCTION_IN ); - - // Dump contents - if (si->criticalExtensions.present == NR_SystemInformation__criticalExtensions_PR_systemInformation || - si->criticalExtensions.present == NR_SystemInformation__criticalExtensions_PR_criticalExtensionsFuture_r16) { - LOG_D(NR_RRC, - "[UE] si->criticalExtensions.choice.NR_SystemInformation_t->sib_TypeAndInfo.list.count %d\n", - si->criticalExtensions.choice.systemInformation->sib_TypeAndInfo.list.count); - } else { - LOG_D(NR_RRC, "[UE] Unknown criticalExtension version (not Rel16)\n"); - return -1; - } - - for (int i = 0; i < si->criticalExtensions.choice.systemInformation->sib_TypeAndInfo.list.count; i++) { - SystemInformation_IEs__sib_TypeAndInfo__Member *typeandinfo; - typeandinfo = si->criticalExtensions.choice.systemInformation->sib_TypeAndInfo.list.array[i]; - LOG_I(NR_RRC, "Found SIB%d\n", typeandinfo->present + 1); - switch(typeandinfo->present) { - case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib2: - if(!SI_info->sib2) - SI_info->sib2 = calloc(1, sizeof(*SI_info->sib2)); - memcpy(SI_info->sib2, typeandinfo->choice.sib2, sizeof(NR_SIB2_t)); - nr_timer_start(&SI_info->sib2_timer); - break; - - case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib3: - if(!SI_info->sib3) - SI_info->sib3 = calloc(1, sizeof(*SI_info->sib3)); - memcpy(SI_info->sib3, typeandinfo->choice.sib3, sizeof(NR_SIB3_t)); - nr_timer_start(&SI_info->sib3_timer); - break; - - case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib4: - if(!SI_info->sib4) - SI_info->sib4 = calloc(1, sizeof(*SI_info->sib4)); - memcpy(SI_info->sib4, typeandinfo->choice.sib4, sizeof(NR_SIB4_t)); - nr_timer_start(&SI_info->sib4_timer); - break; - - case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib5: - if(!SI_info->sib5) - SI_info->sib5 = calloc(1, sizeof(*SI_info->sib5)); - memcpy(SI_info->sib5, typeandinfo->choice.sib5, sizeof(NR_SIB5_t)); - nr_timer_start(&SI_info->sib5_timer); - break; - - case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib6: - if(!SI_info->sib6) - SI_info->sib6 = calloc(1, sizeof(*SI_info->sib6)); - memcpy(SI_info->sib6, typeandinfo->choice.sib6, sizeof(NR_SIB6_t)); - nr_timer_start(&SI_info->sib6_timer); - break; - - case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib7: - if(!SI_info->sib7) - SI_info->sib7 = calloc(1, sizeof(*SI_info->sib7)); - memcpy(SI_info->sib7, typeandinfo->choice.sib7, sizeof(NR_SIB7_t)); - nr_timer_start(&SI_info->sib7_timer); - break; - - case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib8: - if(!SI_info->sib8) - SI_info->sib8 = calloc(1, sizeof(*SI_info->sib8)); - memcpy(SI_info->sib8, typeandinfo->choice.sib8, sizeof(NR_SIB8_t)); - nr_timer_start(&SI_info->sib8_timer); - break; - - case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib9: - if(!SI_info->sib9) - SI_info->sib9 = calloc(1, sizeof(*SI_info->sib9)); - memcpy(SI_info->sib9, typeandinfo->choice.sib9, sizeof(NR_SIB9_t)); - nr_timer_start(&SI_info->sib9_timer); - break; - - case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib10_v1610: - if(!SI_info->sib10) - SI_info->sib10 = calloc(1, sizeof(*SI_info->sib10)); - memcpy(SI_info->sib10, typeandinfo->choice.sib10_v1610, sizeof(NR_SIB10_r16_t)); - nr_timer_start(&SI_info->sib10_timer); - break; - - case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib11_v1610: - if(!SI_info->sib11) - SI_info->sib11 = calloc(1, sizeof(*SI_info->sib11)); - memcpy(SI_info->sib11, typeandinfo->choice.sib11_v1610, sizeof(NR_SIB11_r16_t)); - nr_timer_start(&SI_info->sib11_timer); - break; - - case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib12_v1610: - if(!SI_info->sib12) - SI_info->sib12 = calloc(1, sizeof(*SI_info->sib12)); - memcpy(SI_info->sib12, typeandinfo->choice.sib12_v1610, sizeof(NR_SIB12_r16_t)); - nr_timer_start(&SI_info->sib12_timer); - break; - - case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib13_v1610: - if(!SI_info->sib13) - SI_info->sib13 = calloc(1, sizeof(*SI_info->sib13)); - memcpy(SI_info->sib13, typeandinfo->choice.sib13_v1610, sizeof(NR_SIB13_r16_t)); - nr_timer_start(&SI_info->sib13_timer); - break; - - case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib14_v1610: - if(!SI_info->sib14) - SI_info->sib14 = calloc(1, sizeof(*SI_info->sib14)); - memcpy(SI_info->sib12, typeandinfo->choice.sib14_v1610, sizeof(NR_SIB14_r16_t)); - nr_timer_start(&SI_info->sib14_timer); - break; - - case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib19_v1700: - if(!SI_info->SInfo_r17.sib19) - SI_info->SInfo_r17.sib19 = calloc(1, sizeof(*SI_info->SInfo_r17.sib19)); - asn_copy(&asn_DEF_NR_SIB19_r17, (void **) &SI_info->SInfo_r17.sib19, typeandinfo->choice.sib19_v1700); - if (g_log->log_component[NR_RRC].level >= OAILOG_DEBUG) - xer_fprint(stdout, &asn_DEF_NR_SIB19_r17, (const void *)SI_info->SInfo_r17.sib19); - nr_timer_start(&SI_info->SInfo_r17.sib19_timer); - break; - default: - break; - } - } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_UE_DECODE_SI, VCD_FUNCTION_OUT); - return 0; -} - static void nr_rrc_handle_msg3_indication(NR_UE_RRC_INST_t *rrc, rnti_t rnti) { NR_UE_Timers_Constants_t *tac = &rrc->timers_and_constants; @@ -748,63 +856,6 @@ static void nr_rrc_handle_msg3_indication(NR_UE_RRC_INST_t *rrc, rnti_t rnti) } } -static void nr_rrc_ue_prepare_RRCSetupRequest(NR_UE_RRC_INST_t *rrc) -{ - LOG_D(NR_RRC, "Generation of RRCSetupRequest\n"); - uint8_t rv[6]; - // Get RRCConnectionRequest, fill random for now - // Generate random byte stream for contention resolution - for (int i = 0; i < 6; i++) { -#ifdef SMBV - // if SMBV is configured the contention resolution needs to be fix for the connection procedure to succeed - rv[i] = i; -#else - rv[i] = taus() & 0xff; -#endif - } - - uint8_t buf[1024]; - int len = do_RRCSetupRequest(buf, sizeof(buf), rv); - - nr_rlc_srb_recv_sdu(rrc->ue_id, 0, buf, len); -} - -static void nr_rrc_configure_default_SI(NR_UE_RRC_SI_INFO *SI_info, NR_SIB1_t *sib1) -{ - struct NR_SI_SchedulingInfo *si_SchedulingInfo = sib1->si_SchedulingInfo; - struct NR_SI_SchedulingInfo_v1700 *si_SchedulingInfo_v1700 = NULL; - - if (sib1->nonCriticalExtension && sib1->nonCriticalExtension->nonCriticalExtension - && sib1->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension - && sib1->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->si_SchedulingInfo_v1700) { - si_SchedulingInfo_v1700 = sib1->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->si_SchedulingInfo_v1700; - } - - if (si_SchedulingInfo) { - SI_info->default_otherSI_map = 0; - for (int i = 0; i < si_SchedulingInfo->schedulingInfoList.list.count; i++) { - struct NR_SchedulingInfo *schedulingInfo = si_SchedulingInfo->schedulingInfoList.list.array[i]; - for (int j = 0; j < schedulingInfo->sib_MappingInfo.list.count; j++) { - struct NR_SIB_TypeInfo *sib_Type = schedulingInfo->sib_MappingInfo.list.array[j]; - SI_info->default_otherSI_map |= 1 << sib_Type->type; - } - } - } - - if (si_SchedulingInfo_v1700) { - SI_info->SInfo_r17.default_otherSI_map_r17 = 0; - for (int i = 0; i < si_SchedulingInfo_v1700->schedulingInfoList2_r17.list.count; i++) { - struct NR_SchedulingInfo2_r17 *schedulingInfo2 = si_SchedulingInfo_v1700->schedulingInfoList2_r17.list.array[i]; - for (int j = 0; j < schedulingInfo2->sib_MappingInfo_r17.list.count; j++) { - struct NR_SIB_TypeInfo_v1700 *sib_TypeInfo_v1700 = schedulingInfo2->sib_MappingInfo_r17.list.array[j]; - if (sib_TypeInfo_v1700->sibType_r17.present == NR_SIB_TypeInfo_v1700__sibType_r17_PR_type1_r17) { - SI_info->SInfo_r17.default_otherSI_map_r17 |= 1 << sib_TypeInfo_v1700->sibType_r17.choice.type1_r17; - } - } - } - } -} - static int8_t nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(NR_UE_RRC_INST_t *rrc, const uint8_t gNB_index, uint8_t *const Sdu, @@ -839,31 +890,8 @@ static int8_t nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(NR_UE_RRC_INST_t *rrc, if (bcch_message->message.present == NR_BCCH_DL_SCH_MessageType_PR_c1) { switch (bcch_message->message.choice.c1->present) { case NR_BCCH_DL_SCH_MessageType__c1_PR_systemInformationBlockType1: - LOG_D(NR_RRC, "[UE %ld] Decoding SIB1\n", rrc->ue_id); - UPDATE_IE(SI_info->sib1, bcch_message->message.choice.c1->choice.systemInformationBlockType1, NR_SIB1_t); - if(g_log->log_component[NR_RRC].level >= OAILOG_DEBUG) - xer_fprint(stdout, &asn_DEF_NR_SIB1, (const void *) SI_info->sib1); - LOG_A(NR_RRC, "SIB1 decoded\n"); - nr_timer_start(&SI_info->sib1_timer); - if (rrc->nrRrcState == RRC_STATE_IDLE_NR) { - rrc->ra_trigger = RRC_CONNECTION_SETUP; - // preparing RRC setup request payload in advance - nr_rrc_ue_prepare_RRCSetupRequest(rrc); - } - // configure default SI - nr_rrc_configure_default_SI(SI_info, SI_info->sib1); - // configure timers and constant - nr_rrc_set_sib1_timers_and_constants(&rrc->timers_and_constants, SI_info->sib1); - - NR_SI_SchedulingInfo_v1700_t *si_SchedulingInfo_v1700 = NULL; - if (SI_info->sib1->nonCriticalExtension && SI_info->sib1->nonCriticalExtension->nonCriticalExtension - && SI_info->sib1->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension) { - si_SchedulingInfo_v1700 = SI_info->sib1->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->si_SchedulingInfo_v1700; - } - - nr_rrc_mac_config_req_sib1(rrc->ue_id, 0, SI_info->sib1->si_SchedulingInfo, si_SchedulingInfo_v1700, SI_info->sib1->servingCellConfigCommon); + nr_rrc_process_sib1(rrc, SI_info, bcch_message->message.choice.c1->choice.systemInformationBlockType1); break; - case NR_BCCH_DL_SCH_MessageType__c1_PR_systemInformation: LOG_I(NR_RRC, "[UE %ld] Decoding SI\n", rrc->ue_id); NR_SystemInformation_t *si = bcch_message->message.choice.c1->choice.systemInformation; @@ -925,40 +953,39 @@ static void nr_rrc_manage_rlc_bearers(NR_UE_RRC_INST_t *rrc, } } +static void nr_rrc_process_reconfigurationWithSync(NR_UE_RRC_INST_t *rrc, NR_ReconfigurationWithSync_t *reconfigurationWithSync) +{ + // 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 && + reconfigurationWithSync->spCellConfigCommon->downlinkConfigCommon && + reconfigurationWithSync->spCellConfigCommon->downlinkConfigCommon->frequencyInfoDL && + reconfigurationWithSync->spCellConfigCommon->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB) + rrc->arfcn_ssb = *reconfigurationWithSync->spCellConfigCommon->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB; + + NR_UE_Timers_Constants_t *tac = &rrc->timers_and_constants; + nr_timer_stop(&tac->T310); + 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) +} + void nr_rrc_cellgroup_configuration(NR_UE_RRC_INST_t *rrc, NR_CellGroupConfig_t *cellGroupConfig) { - NR_UE_Timers_Constants_t *tac = &rrc->timers_and_constants; - NR_SpCellConfig_t *spCellConfig = cellGroupConfig->spCellConfig; - if(spCellConfig != NULL) { - if (spCellConfig->reconfigurationWithSync != NULL) { - NR_ReconfigurationWithSync_t *reconfigurationWithSync = spCellConfig->reconfigurationWithSync; - if (reconfigurationWithSync->spCellConfigCommon && - reconfigurationWithSync->spCellConfigCommon->downlinkConfigCommon && - reconfigurationWithSync->spCellConfigCommon->downlinkConfigCommon->frequencyInfoDL && - reconfigurationWithSync->spCellConfigCommon->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB) - rrc->arfcn_ssb = *reconfigurationWithSync->spCellConfigCommon->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB; - // perform Reconfiguration with sync according to 5.3.5.5.2 - if (!rrc->as_security_activated && rrc->nrRrcState != RRC_STATE_IDLE_NR) { - // perform the actions upon going to RRC_IDLE as specified in 5.3.11 - // with the release cause 'other' upon which the procedure ends - // TODO - } - nr_timer_stop(&tac->T310); - 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; - // resume suspended radio bearers - for (int i = 0; i < NR_NUM_SRB; i++) { - if (rrc->Srb[i] == RB_SUSPENDED) - rrc->Srb[i] = RB_ESTABLISHED; - } - for (int i = 1; i <= MAX_DRBS_PER_UE; i++) { - if (get_DRB_status(rrc, i) == RB_SUSPENDED) - set_DRB_status(rrc, i, RB_ESTABLISHED); - } - // TODO reset MAC + if(spCellConfig) { + if (spCellConfig->reconfigurationWithSync) { + LOG_I(NR_RRC, "Processing reconfigurationWithSync\n"); + nr_rrc_process_reconfigurationWithSync(rrc, spCellConfig->reconfigurationWithSync); } nr_rrc_handle_SetupRelease_RLF_TimersAndConstants(rrc, spCellConfig->rlf_TimersAndConstants); if (spCellConfig->spCellConfigDedicated) { @@ -972,11 +999,10 @@ void nr_rrc_cellgroup_configuration(NR_UE_RRC_INST_t *rrc, NR_CellGroupConfig_t nr_rrc_manage_rlc_bearers(rrc, cellGroupConfig); - AssertFatal(cellGroupConfig->sCellToReleaseList == NULL, - "Secondary serving cell release not implemented\n"); - - AssertFatal(cellGroupConfig->sCellToAddModList == NULL, - "Secondary serving cell addition not implemented\n"); + 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"); } @@ -1692,6 +1718,8 @@ static void nr_rrc_ue_process_rrcReestablishment(NR_UE_RRC_INST_t *rrc, // resetting the RA trigger state after receiving MSG4 with RRCReestablishment rrc->ra_trigger = RA_NOT_RUNNING; + // to flag 1st reconfiguration after reestablishment + rrc->reconfig_after_reestab = true; // submit the RRCReestablishmentComplete message to lower layers for transmission nr_rrc_ue_generate_rrcReestablishmentComplete(rrc, rrcReestablishment); @@ -1732,6 +1760,17 @@ static int nr_rrc_ue_decode_dcch(NR_UE_RRC_INST_t *rrc, case NR_DL_DCCH_MessageType__c1_PR_rrcReconfiguration: { nr_rrc_ue_process_rrcReconfiguration(rrc, gNB_indexP, c1->choice.rrcReconfiguration); + if (rrc->reconfig_after_reestab) { + // if this is the first RRCReconfiguration message after successful completion of the RRC re-establishment procedure + // resume SRB2 and DRBs that are suspended + if (rrc->Srb[2] == RB_SUSPENDED) + rrc->Srb[2] = RB_ESTABLISHED; + for (int i = 1; i <= MAX_DRBS_PER_UE; i++) { + if (get_DRB_status(rrc, i) == RB_SUSPENDED) + set_DRB_status(rrc, i, RB_ESTABLISHED); + } + rrc->reconfig_after_reestab = false; + } nr_rrc_ue_generate_RRCReconfigurationComplete(rrc, Srb_id, c1->choice.rrcReconfiguration->rrc_TransactionIdentifier); } break; @@ -2042,18 +2081,15 @@ static void nr_rrc_ue_process_ueCapabilityEnquiry(NR_UE_RRC_INST_t *rrc, NR_UECa ASN_STRUCT_RESET(asn_DEF_NR_UL_DCCH_Message, &ul_dcch_msg); } -void nr_rrc_initiate_rrcReestablishment(NR_UE_RRC_INST_t *rrc, - NR_ReestablishmentCause_t cause, - const int gnb_id) +static void nr_rrc_initiate_rrcReestablishment(NR_UE_RRC_INST_t *rrc, NR_ReestablishmentCause_t cause) { rrc->reestablishment_cause = cause; 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); + set_rlf_sib1_timers_and_constants(timers, rrc->timers_and_constants.sib1_TimersAndConstants); // stop timer T310, if running nr_timer_stop(&timers->T310); @@ -2322,7 +2358,7 @@ void handle_rlf_detection(NR_UE_RRC_INST_t *rrc) } if (rrc->as_security_activated && srb2 && any_drb) // initiate the connection re-establishment procedure - nr_rrc_initiate_rrcReestablishment(rrc, NR_ReestablishmentCause_otherFailure, 0); + nr_rrc_initiate_rrcReestablishment(rrc, NR_ReestablishmentCause_otherFailure); else { NR_Release_Cause_t cause = rrc->as_security_activated ? RRC_CONNECTION_FAILURE : OTHER; nr_rrc_going_to_IDLE(rrc, cause, NULL); @@ -2417,24 +2453,33 @@ void nr_rrc_going_to_IDLE(NR_UE_RRC_INST_t *rrc, rrcPerNB_t *nb = &rrc->perNB[i]; NR_UE_RRC_SI_INFO *SI_info = &nb->SInfo; init_SI_timers(SI_info); - asn1cFreeStruc(asn_DEF_NR_SIB1, SI_info->sib1); - asn1cFreeStruc(asn_DEF_NR_SIB2, SI_info->sib2); - asn1cFreeStruc(asn_DEF_NR_SIB3, SI_info->sib3); - asn1cFreeStruc(asn_DEF_NR_SIB4, SI_info->sib4); - asn1cFreeStruc(asn_DEF_NR_SIB5, SI_info->sib5); - asn1cFreeStruc(asn_DEF_NR_SIB6, SI_info->sib6); - asn1cFreeStruc(asn_DEF_NR_SIB7, SI_info->sib7); - asn1cFreeStruc(asn_DEF_NR_SIB8, SI_info->sib8); - asn1cFreeStruc(asn_DEF_NR_SIB9, SI_info->sib9); - asn1cFreeStruc(asn_DEF_NR_SIB10_r16, SI_info->sib10); - asn1cFreeStruc(asn_DEF_NR_SIB11_r16, SI_info->sib11); - asn1cFreeStruc(asn_DEF_NR_SIB12_r16, SI_info->sib12); - asn1cFreeStruc(asn_DEF_NR_SIB13_r16, SI_info->sib13); - asn1cFreeStruc(asn_DEF_NR_SIB14_r16, SI_info->sib14); + SI_info->sib1_validity = false; + SI_info->sib2_validity = false; + SI_info->sib3_validity = false; + SI_info->sib4_validity = false; + SI_info->sib5_validity = false; + SI_info->sib6_validity = false; + SI_info->sib7_validity = false; + SI_info->sib8_validity = false; + SI_info->sib9_validity = false; + SI_info->sib10_validity = false; + SI_info->sib11_validity = false; + SI_info->sib12_validity = false; + SI_info->sib13_validity = false; + SI_info->sib14_validity = false; + SI_info->SInfo_r17.sib15_validity = false; + SI_info->SInfo_r17.sib16_validity = false; + SI_info->SInfo_r17.sib17_validity = false; + SI_info->SInfo_r17.sib18_validity = false; + SI_info->SInfo_r17.sib19_validity = false; + SI_info->SInfo_r17.sib20_validity = false; + SI_info->SInfo_r17.sib21_validity = false; } - if (rrc->nrRrcState == RRC_STATE_DETACH_NR) + if (rrc->nrRrcState == RRC_STATE_DETACH_NR) { asn1cFreeStruc(asn_DEF_NR_UE_NR_Capability, rrc->UECap.UE_NR_Capability); + asn1cFreeStruc(asn_DEF_NR_UE_TimersAndConstants, tac->sib1_TimersAndConstants); + } // reset MAC NR_UE_MAC_reset_cause_t cause = (rrc->nrRrcState == RRC_STATE_DETACH_NR) ? DETACH : GO_TO_IDLE; diff --git a/openair2/RRC/NR_UE/rrc_defs.h b/openair2/RRC/NR_UE/rrc_defs.h index 26a102fdb0..a4cd52ee23 100644 --- a/openair2/RRC/NR_UE/rrc_defs.h +++ b/openair2/RRC/NR_UE/rrc_defs.h @@ -106,51 +106,51 @@ typedef enum RA_trigger_e { typedef struct UE_RRC_SI_INFO_NR_r17_s { uint32_t default_otherSI_map_r17; - NR_SIB15_r17_t *sib15; + bool sib15_validity; NR_timer_t sib15_timer; - NR_SIB16_r17_t *sib16; + bool sib16_validity; NR_timer_t sib16_timer; - NR_SIB17_r17_t *sib17; + bool sib17_validity; NR_timer_t sib17_timer; - NR_SIB18_r17_t *sib18; + bool sib18_validity; NR_timer_t sib18_timer; - NR_SIB19_r17_t *sib19; + bool sib19_validity; NR_timer_t sib19_timer; - NR_SIB20_r17_t *sib20; + bool sib20_validity; NR_timer_t sib20_timer; - NR_SIB21_r17_t *sib21; + bool sib21_validity; NR_timer_t sib21_timer; } NR_UE_RRC_SI_INFO_r17; typedef struct UE_RRC_SI_INFO_NR_s { uint32_t default_otherSI_map; - NR_SIB1_t *sib1; + bool sib1_validity; NR_timer_t sib1_timer; - NR_SIB2_t *sib2; + bool sib2_validity; NR_timer_t sib2_timer; - NR_SIB3_t *sib3; + bool sib3_validity; NR_timer_t sib3_timer; - NR_SIB4_t *sib4; + bool sib4_validity; NR_timer_t sib4_timer; - NR_SIB5_t *sib5; + bool sib5_validity; NR_timer_t sib5_timer; - NR_SIB6_t *sib6; + bool sib6_validity; NR_timer_t sib6_timer; - NR_SIB7_t *sib7; + bool sib7_validity; NR_timer_t sib7_timer; - NR_SIB8_t *sib8; + bool sib8_validity; NR_timer_t sib8_timer; - NR_SIB9_t *sib9; + bool sib9_validity; NR_timer_t sib9_timer; - NR_SIB10_r16_t *sib10; + bool sib10_validity; NR_timer_t sib10_timer; - NR_SIB11_r16_t *sib11; + bool sib11_validity; NR_timer_t sib11_timer; - NR_SIB12_r16_t *sib12; + bool sib12_validity; NR_timer_t sib12_timer; - NR_SIB13_r16_t *sib13; + bool sib13_validity; NR_timer_t sib13_timer; - NR_SIB14_r16_t *sib14; + bool sib14_validity; NR_timer_t sib14_timer; NR_UE_RRC_SI_INFO_r17 SInfo_r17; } NR_UE_RRC_SI_INFO; @@ -175,6 +175,7 @@ typedef struct NR_UE_Timers_Constants_s { // constants (limits configured by the network) uint32_t N310_k; uint32_t N311_k; + NR_UE_TimersAndConstants_t *sib1_TimersAndConstants; } NR_UE_Timers_Constants_t; typedef enum { @@ -230,7 +231,8 @@ typedef struct NR_UE_RRC_INST_s { NR_RRCRelease_t *RRCRelease; long selected_plmn_identity; Rrc_State_NR_t nrRrcState; - + // flag to identify 1st reconfiguration after reestablishment + bool reconfig_after_reestab; //Sidelink params NR_SL_PreconfigurationNR_r16_t *sl_preconfig; diff --git a/openair2/RRC/NR_UE/rrc_proto.h b/openair2/RRC/NR_UE/rrc_proto.h index d1f1d3228f..f4728f0f58 100644 --- a/openair2/RRC/NR_UE/rrc_proto.h +++ b/openair2/RRC/NR_UE/rrc_proto.h @@ -55,7 +55,7 @@ void nr_rrc_going_to_IDLE(NR_UE_RRC_INST_t *rrc, void handle_RRCRelease(NR_UE_RRC_INST_t *rrc); -void set_rlf_sib1_timers_and_constants(NR_UE_Timers_Constants_t *tac, NR_SIB1_t *sib1); +void set_rlf_sib1_timers_and_constants(NR_UE_Timers_Constants_t *tac, NR_UE_TimersAndConstants_t *ue_TimersAndConstants); /**\brief RRC UE task. \param void *args_p Pointer on arguments to start the task. */ diff --git a/openair2/RRC/NR_UE/rrc_timers_and_constants.c b/openair2/RRC/NR_UE/rrc_timers_and_constants.c index 7e0c040731..6629055b3a 100644 --- a/openair2/RRC/NR_UE/rrc_timers_and_constants.c +++ b/openair2/RRC/NR_UE/rrc_timers_and_constants.c @@ -45,80 +45,80 @@ void init_SI_timers(NR_UE_RRC_SI_INFO *SInfo) void nr_rrc_SI_timers(NR_UE_RRC_SI_INFO *SInfo) { - if (SInfo->sib1) { + if (SInfo->sib1_validity) { bool sib1_expired = nr_timer_tick(&SInfo->sib1_timer); if (sib1_expired) - asn1cFreeStruc(asn_DEF_NR_SIB1, SInfo->sib1); + SInfo->sib1_validity = false; } - if (SInfo->sib2) { + if (SInfo->sib2_validity) { bool sib2_expired = nr_timer_tick(&SInfo->sib2_timer); if (sib2_expired) - asn1cFreeStruc(asn_DEF_NR_SIB2, SInfo->sib2); + SInfo->sib2_validity = false; } - if (SInfo->sib3) { + if (SInfo->sib3_validity) { bool sib3_expired = nr_timer_tick(&SInfo->sib3_timer); if (sib3_expired) - asn1cFreeStruc(asn_DEF_NR_SIB3, SInfo->sib3); + SInfo->sib3_validity = false; } - if (SInfo->sib4) { + if (SInfo->sib4_validity) { bool sib4_expired = nr_timer_tick(&SInfo->sib4_timer); if (sib4_expired) - asn1cFreeStruc(asn_DEF_NR_SIB4, SInfo->sib4); + SInfo->sib4_validity = false; } - if (SInfo->sib5) { + if (SInfo->sib5_validity) { bool sib5_expired = nr_timer_tick(&SInfo->sib5_timer); if (sib5_expired) - asn1cFreeStruc(asn_DEF_NR_SIB5, SInfo->sib5); + SInfo->sib5_validity = false; } - if (SInfo->sib6) { + if (SInfo->sib6_validity) { bool sib6_expired = nr_timer_tick(&SInfo->sib6_timer); if (sib6_expired) - asn1cFreeStruc(asn_DEF_NR_SIB6, SInfo->sib6); + SInfo->sib6_validity = false; } - if (SInfo->sib7) { + if (SInfo->sib7_validity) { bool sib7_expired = nr_timer_tick(&SInfo->sib7_timer); if (sib7_expired) - asn1cFreeStruc(asn_DEF_NR_SIB7, SInfo->sib7); + SInfo->sib7_validity = false; } - if (SInfo->sib8) { + if (SInfo->sib8_validity) { bool sib8_expired = nr_timer_tick(&SInfo->sib8_timer); if (sib8_expired) - asn1cFreeStruc(asn_DEF_NR_SIB8, SInfo->sib8); + SInfo->sib8_validity = false; } - if (SInfo->sib9) { + if (SInfo->sib9_validity) { bool sib9_expired = nr_timer_tick(&SInfo->sib9_timer); if (sib9_expired) - asn1cFreeStruc(asn_DEF_NR_SIB9, SInfo->sib9); + SInfo->sib9_validity = false; } - if (SInfo->sib10) { + if (SInfo->sib10_validity) { bool sib10_expired = nr_timer_tick(&SInfo->sib10_timer); if (sib10_expired) - asn1cFreeStruc(asn_DEF_NR_SIB10_r16, SInfo->sib10); + SInfo->sib10_validity = false; } - if (SInfo->sib11) { + if (SInfo->sib11_validity) { bool sib11_expired = nr_timer_tick(&SInfo->sib11_timer); if (sib11_expired) - asn1cFreeStruc(asn_DEF_NR_SIB11_r16, SInfo->sib11); + SInfo->sib11_validity = false; } - if (SInfo->sib12) { + if (SInfo->sib12_validity) { bool sib12_expired = nr_timer_tick(&SInfo->sib12_timer); if (sib12_expired) - asn1cFreeStruc(asn_DEF_NR_SIB12_r16, SInfo->sib12); + SInfo->sib12_validity = false; } - if (SInfo->sib13) { + if (SInfo->sib13_validity) { bool sib13_expired = nr_timer_tick(&SInfo->sib13_timer); if (sib13_expired) - asn1cFreeStruc(asn_DEF_NR_SIB13_r16, SInfo->sib13); + SInfo->sib13_validity = false; } - if (SInfo->sib14) { + if (SInfo->sib14_validity) { bool sib14_expired = nr_timer_tick(&SInfo->sib14_timer); if (sib14_expired) - asn1cFreeStruc(asn_DEF_NR_SIB14_r16, SInfo->sib14); + SInfo->sib14_validity = false; } - if (SInfo->SInfo_r17.sib19) { + if (SInfo->SInfo_r17.sib19_validity) { bool sib19_expired = nr_timer_tick(&SInfo->SInfo_r17.sib19_timer); if (sib19_expired) - asn1cFreeStruc(asn_DEF_NR_SIB19_r17, SInfo->SInfo_r17.sib19); + SInfo->SInfo_r17.sib19_validity = false; } } @@ -205,11 +205,11 @@ int nr_rrc_get_T304(long t304) return target; } -void set_rlf_sib1_timers_and_constants(NR_UE_Timers_Constants_t *tac, NR_SIB1_t *sib1) +void set_rlf_sib1_timers_and_constants(NR_UE_Timers_Constants_t *tac, NR_UE_TimersAndConstants_t *ue_TimersAndConstants) { - if(sib1 && sib1->ue_TimersAndConstants) { + if(ue_TimersAndConstants) { int k = 0; - switch (sib1->ue_TimersAndConstants->t301) { + switch (ue_TimersAndConstants->t301) { case NR_UE_TimersAndConstants__t301_ms100 : k = 100; break; @@ -235,10 +235,10 @@ void set_rlf_sib1_timers_and_constants(NR_UE_Timers_Constants_t *tac, NR_SIB1_t k = 2000; break; default : - AssertFatal(false, "Invalid T301 %ld\n", sib1->ue_TimersAndConstants->t301); + AssertFatal(false, "Invalid T301 %ld\n", ue_TimersAndConstants->t301); } nr_timer_setup(&tac->T301, k, 10); // 10ms step - switch (sib1->ue_TimersAndConstants->t310) { + switch (ue_TimersAndConstants->t310) { case NR_UE_TimersAndConstants__t310_ms0 : k = 0; break; @@ -261,10 +261,10 @@ void set_rlf_sib1_timers_and_constants(NR_UE_Timers_Constants_t *tac, NR_SIB1_t k = 2000; break; default : - AssertFatal(false, "Invalid T310 %ld\n", sib1->ue_TimersAndConstants->t310); + AssertFatal(false, "Invalid T310 %ld\n", ue_TimersAndConstants->t310); } nr_timer_setup(&tac->T310, k, 10); // 10ms step - switch (sib1->ue_TimersAndConstants->t311) { + switch (ue_TimersAndConstants->t311) { case NR_UE_TimersAndConstants__t311_ms1000 : k = 1000; break; @@ -287,10 +287,10 @@ void set_rlf_sib1_timers_and_constants(NR_UE_Timers_Constants_t *tac, NR_SIB1_t k = 30000; break; default : - AssertFatal(false, "Invalid T311 %ld\n", sib1->ue_TimersAndConstants->t311); + AssertFatal(false, "Invalid T311 %ld\n", ue_TimersAndConstants->t311); } nr_timer_setup(&tac->T311, k, 10); // 10ms step - switch (sib1->ue_TimersAndConstants->n310) { + switch (ue_TimersAndConstants->n310) { case NR_UE_TimersAndConstants__n310_n1 : tac->N310_k = 1; break; @@ -316,9 +316,9 @@ void set_rlf_sib1_timers_and_constants(NR_UE_Timers_Constants_t *tac, NR_SIB1_t tac->N310_k = 20; break; default : - AssertFatal(false, "Invalid N310 %ld\n", sib1->ue_TimersAndConstants->n310); + AssertFatal(false, "Invalid N310 %ld\n", ue_TimersAndConstants->n310); } - switch (sib1->ue_TimersAndConstants->n311) { + switch (ue_TimersAndConstants->n311) { case NR_UE_TimersAndConstants__n311_n1 : tac->N311_k = 1; break; @@ -344,16 +344,16 @@ void set_rlf_sib1_timers_and_constants(NR_UE_Timers_Constants_t *tac, NR_SIB1_t tac->N311_k = 10; break; default : - AssertFatal(false, "Invalid N311 %ld\n", sib1->ue_TimersAndConstants->n311); + AssertFatal(false, "Invalid N311 %ld\n", ue_TimersAndConstants->n311); } } else - LOG_E(NR_RRC,"SIB1 should not be NULL and neither UE_Timers_Constants\n"); + LOG_E(NR_RRC,"UE_Timers_Constants should not be NULL\n"); } void nr_rrc_set_sib1_timers_and_constants(NR_UE_Timers_Constants_t *tac, NR_SIB1_t *sib1) { - set_rlf_sib1_timers_and_constants(tac, sib1); + set_rlf_sib1_timers_and_constants(tac, sib1->ue_TimersAndConstants); if(sib1 && sib1->ue_TimersAndConstants) { int k = 0; switch (sib1->ue_TimersAndConstants->t300) { @@ -430,7 +430,7 @@ void nr_rrc_handle_SetupRelease_RLF_TimersAndConstants(NR_UE_RRC_INST_t *rrc, switch(rlf_TimersAndConstants->present){ case NR_SetupRelease_RLF_TimersAndConstants_PR_release : // use values for timers T301, T310, T311 and constants N310, N311, as included in ue-TimersAndConstants received in SIB1 - set_rlf_sib1_timers_and_constants(tac, rrc->perNB[0].SInfo.sib1); + set_rlf_sib1_timers_and_constants(tac, rrc->timers_and_constants.sib1_TimersAndConstants); break; case NR_SetupRelease_RLF_TimersAndConstants_PR_setup : rlf_tac = rlf_TimersAndConstants->choice.setup;