diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index 2b8d6b1db6..0958172537 100644 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -1590,6 +1590,7 @@ void nr_rrc_mac_config_req_reset(module_id_t module_id, void nr_rrc_mac_config_req_sib1(module_id_t module_id, int cc_idP, NR_SI_SchedulingInfo_t *si_SchedulingInfo, + NR_SI_SchedulingInfo_v1700_t *si_SchedulingInfo_v1700, NR_ServingCellConfigCommonSIB_t *scc) { NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); @@ -1597,6 +1598,7 @@ void nr_rrc_mac_config_req_sib1(module_id_t module_id, 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); config_common_ue_sa(mac, scc, cc_idP); configure_common_BWP_dl(mac, diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index dbf272f40f..fb727aeb5e 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -519,6 +519,7 @@ typedef struct NR_UE_MAC_INST_s { 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; 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/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index 9a0bc8e911..bb42701ec3 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -88,6 +88,7 @@ void nr_rrc_mac_config_req_mib(module_id_t module_id, void nr_rrc_mac_config_req_sib1(module_id_t module_id, int cc_idP, NR_SI_SchedulingInfo_t *si_SchedulingInfo, + NR_SI_SchedulingInfo_v1700_t *si_SchedulingInfo_v1700, NR_ServingCellConfigCommonSIB_t *scc); void nr_rrc_mac_config_req_sib19_r17(module_id_t module_id, @@ -375,7 +376,7 @@ int16_t compute_nr_SSB_PL(NR_UE_MAC_INST_t *mac, short ssb_rsrp_dBm); // PUSCH scheduler: // - Calculate the slot in which ULSCH should be scheduled. This is current slot + K2, // - where K2 is the offset between the slot in which UL DCI is received and the slot -// - in which ULSCH should be scheduled. K2 is configured in RRC configuration. +// - in which ULSCH should be scheduled. K2 is configured in RRC configuration. // PUSCH Msg3 scheduler: // - scheduled by RAR UL grant according to 8.3 of TS 38.213 int nr_ue_pusch_scheduler(const NR_UE_MAC_INST_t *mac, 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 27219bed1f..550ae2b8da 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c @@ -419,6 +419,45 @@ bool is_ss_monitor_occasion(const int frame, const int slot, const int slots_per return monitor; } +bool search_space_monitoring_ocasion_other_si(NR_UE_MAC_INST_t *mac, + const NR_SearchSpace_t *ss, + const int abs_slot, + const int frame, + const int slot, + const int slots_per_frame, + const int bwp_id) +{ + const int duration = ss->duration ? *ss->duration : 1; + int period, offset; + get_monitoring_period_offset(ss, &period, &offset); + for (int i = 0; i < duration; i++) { + if (((frame * slots_per_frame + slot - offset - i) % period) == 0) { + int N = mac->ssb_list[bwp_id].nb_tx_ssb; + 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); + return current_monitor_occasion % N == K; + } + } + + return false; +} + +bool is_window_valid(NR_UE_MAC_INST_t *mac, int window_slots, int abs_slot) +{ + if (mac->si_window_start == -1) { + // out of window + return false; + } else if (abs_slot > mac->si_window_start + window_slots) { + // window expired + mac->si_window_start = -1; + return false; + } + return true; +} + bool monitor_dci_for_other_SI(NR_UE_MAC_INST_t *mac, const NR_SearchSpace_t *ss, const int slots_per_frame, @@ -426,51 +465,60 @@ bool monitor_dci_for_other_SI(NR_UE_MAC_INST_t *mac, 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) + + if (!si_SchedulingInfo_v1700 && !si_SchedulingInfo) { + LOG_D(NR_MAC_DCI, "No scheduling info provided in SIB1\n"); return false; - const int si_window_slots = 5 << si_SchedulingInfo->si_WindowLength; + } + const int abs_slot = frame * slots_per_frame + slot; const int bwp_id = mac->current_DL_BWP->bwp_id; - 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 + + 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 (mac->si_window_start == -1) { - // out of window - return false; - } - else if (abs_slot > mac->si_window_start + si_window_slots) { - // window expired - mac->si_window_start = -1; - return false; - } - else { - const int duration = ss->duration ? *ss->duration : 1; - int period, offset; - get_monitoring_period_offset(ss, &period, &offset); - for (int i = 0; i < duration; i++) { - if (((frame * slots_per_frame + slot - offset - i) % period) == 0) { - int N = mac->ssb_list[bwp_id].nb_tx_ssb; - 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); - return current_monitor_occasion % N == K; + } + + 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; } } + + 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); + } } } return false; } - void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl_config, const frame_t frame, const int slot) { const NR_UE_DL_BWP_t *current_DL_BWP = mac->current_DL_BWP; diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 0b88661a74..fdff0bc421 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -264,7 +264,7 @@ void process_nsa_message(NR_UE_RRC_INST_t *rrc, nsa_message_t nsa_message_type, ASN_STRUCT_FREE(asn_DEF_NR_RRCReconfiguration, RRCReconfiguration); } break; - + case nr_RadioBearerConfigX_r15: { NR_RadioBearerConfig_t *RadioBearerConfig=NULL; asn_dec_rval_t dec_rval = uper_decode_complete(NULL, @@ -428,6 +428,43 @@ bool check_si_validity(NR_UE_RRC_SI_INFO *SI_info, int si_type) return true; } +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) + return false; + break; + case NR_SIB_TypeInfo_v1700__sibType_r17__type1_r17_sibType16: + if (!SI_info->sib16) + return false; + break; + case NR_SIB_TypeInfo_v1700__sibType_r17__type1_r17_sibType17: + if (!SI_info->sib17) + return false; + break; + case NR_SIB_TypeInfo_v1700__sibType_r17__type1_r17_sibType18: + if (!SI_info->sib18) + return false; + break; + case NR_SIB_TypeInfo_v1700__sibType_r17__type1_r17_sibType19: + if (!SI_info->sib19) + return false; + break; + case NR_SIB_TypeInfo_v1700__sibType_r17__type1_r17_sibType20: + if (!SI_info->sib20) + return false; + break; + case NR_SIB_TypeInfo_v1700__sibType_r17__type1_r17_sibType21: + if (!SI_info->sib21) + return false; + break; + default : + AssertFatal(false, "Invalid SIB r17 type %d\n", si_type); + } + return true; +} + int check_si_status(NR_UE_RRC_SI_INFO *SI_info) { // schedule reception of SIB1 if RRC doesn't have it @@ -448,6 +485,20 @@ int check_si_status(NR_UE_RRC_SI_INFO *SI_info) } } } + + // Check if RRC has configured default SI + // from SIB15 to SIB21 as current r17 version + if (SI_info->SInfo_r17.default_otherSI_map_r17) { + for (int i = 15; i < 22; i++) { + int si_index = i - 15; + if ((SI_info->SInfo_r17.default_otherSI_map_r17 >> si_index) & 0x01) { + // if RRC has no valid version of one of the default configured SI + // Then schedule reception of otherSI + if (!check_si_validity_r17(&SI_info->SInfo_r17, si_index)) + return 2; + } + } + } } return 0; } @@ -476,7 +527,7 @@ static void nr_rrc_ue_decode_NR_BCCH_BCH_Message(NR_UE_RRC_INST_t *rrc, } if (LOG_DEBUGFLAG(DEBUG_ASN1)) xer_fprint(stdout, &asn_DEF_NR_BCCH_BCH_Message, (void *)bcch_message); - + // Actions following cell selection while T311 is running NR_UE_Timers_Constants_t *timers = &rrc->timers_and_constants; if (nr_timer_is_active(&timers->T311)) { @@ -621,6 +672,13 @@ static int nr_decode_SI(NR_UE_RRC_SI_INFO *SI_info, NR_SystemInformation_t *si) 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); + nr_timer_start(&SI_info->SInfo_r17.sib19_timer); + break; default: break; } @@ -703,14 +761,35 @@ static void nr_rrc_ue_prepare_RRCSetupRequest(NR_UE_RRC_INST_t *rrc) 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; - if (!si_SchedulingInfo) - return; - 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; + 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; + } + } } } } @@ -764,8 +843,16 @@ static int8_t nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(NR_UE_RRC_INST_t *rrc, 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_rrc_mac_config_req_sib1(rrc->ue_id, 0, SI_info->sib1->si_SchedulingInfo, SI_info->sib1->servingCellConfigCommon); + + 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); 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; @@ -1776,7 +1863,7 @@ void *rrc_nrue(void *notUsed) case NR_RRC_MAC_SBCCH_DATA_IND: LOG_D(NR_RRC, "[UE %ld] Received %s: gNB %d\n", instance, ITTI_MSG_NAME(msg_p), NR_RRC_MAC_SBCCH_DATA_IND(msg_p).gnb_index); NRRrcMacSBcchDataInd *sbcch = &NR_RRC_MAC_SBCCH_DATA_IND(msg_p); - + nr_rrc_ue_decode_NR_SBCCH_SL_BCH_Message(rrc, sbcch->gnb_index,sbcch->frame, sbcch->slot, sbcch->sdu, sbcch->sdu_size, sbcch->rx_slss_id); break; diff --git a/openair2/RRC/NR_UE/rrc_defs.h b/openair2/RRC/NR_UE/rrc_defs.h index c22132767e..26a102fdb0 100644 --- a/openair2/RRC/NR_UE/rrc_defs.h +++ b/openair2/RRC/NR_UE/rrc_defs.h @@ -91,17 +91,6 @@ typedef enum Rrc_State_NR_e { RRC_STATE_DETACH_NR, } Rrc_State_NR_t; -typedef enum requested_SI_List_e { - SIB2 = 1, - SIB3 = 2, - SIB4 = 4, - SIB5 = 8, - SIB6 = 16, - SIB7 = 32, - SIB8 = 64, - SIB9 = 128 -} requested_SI_List_t; - // 3GPP TS 38.300 Section 9.2.6 typedef enum RA_trigger_e { RA_NOT_RUNNING, @@ -115,6 +104,24 @@ typedef enum RA_trigger_e { BEAM_FAILURE_RECOVERY, } RA_trigger_t; +typedef struct UE_RRC_SI_INFO_NR_r17_s { + uint32_t default_otherSI_map_r17; + NR_SIB15_r17_t *sib15; + NR_timer_t sib15_timer; + NR_SIB16_r17_t *sib16; + NR_timer_t sib16_timer; + NR_SIB17_r17_t *sib17; + NR_timer_t sib17_timer; + NR_SIB18_r17_t *sib18; + NR_timer_t sib18_timer; + NR_SIB19_r17_t *sib19; + NR_timer_t sib19_timer; + NR_SIB20_r17_t *sib20; + NR_timer_t sib20_timer; + NR_SIB21_r17_t *sib21; + 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; @@ -145,6 +152,7 @@ typedef struct UE_RRC_SI_INFO_NR_s { NR_timer_t sib13_timer; NR_SIB14_r16_t *sib14; NR_timer_t sib14_timer; + NR_UE_RRC_SI_INFO_r17 SInfo_r17; } NR_UE_RRC_SI_INFO; typedef struct NR_UE_Timers_Constants_s { diff --git a/openair2/RRC/NR_UE/rrc_timers_and_constants.c b/openair2/RRC/NR_UE/rrc_timers_and_constants.c index 7ee8ed2d38..f0635b16b2 100644 --- a/openair2/RRC/NR_UE/rrc_timers_and_constants.c +++ b/openair2/RRC/NR_UE/rrc_timers_and_constants.c @@ -40,6 +40,7 @@ void init_SI_timers(NR_UE_RRC_SI_INFO *SInfo) nr_timer_setup(&SInfo->sib12_timer, 10800000, 10); nr_timer_setup(&SInfo->sib13_timer, 10800000, 10); nr_timer_setup(&SInfo->sib14_timer, 10800000, 10); + nr_timer_setup(&SInfo->SInfo_r17.sib19_timer, 10800000, 10); } void nr_rrc_SI_timers(NR_UE_RRC_SI_INFO *SInfo) @@ -114,6 +115,11 @@ void nr_rrc_SI_timers(NR_UE_RRC_SI_INFO *SInfo) if (sib14_expired) asn1cFreeStruc(asn_DEF_NR_SIB14_r16, SInfo->sib14); } + if (SInfo->SInfo_r17.sib19) { + bool sib19_expired = nr_timer_tick(&SInfo->SInfo_r17.sib19_timer); + if (sib19_expired) + asn1cFreeStruc(asn_DEF_NR_SIB19_r17, SInfo->SInfo_r17.sib19); + } } void nr_rrc_handle_timers(NR_UE_RRC_INST_t *rrc)