diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index 7d8cd856c4..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); diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index 1530846d6b..7c57668968 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -510,6 +510,23 @@ typedef enum { ON_PUSCH } CSI_mapping_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; @@ -520,9 +537,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 68dd57efd1..5cad51e626 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; @@ -262,7 +262,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;