improvements at UE to receive multiple instances of otherSIB

for example SIB2 and SIB19 which are scheduled in separate messages
This commit is contained in:
francescomani
2025-04-14 10:15:50 +02:00
parent e4cb8be023
commit 08da0bd2cc
9 changed files with 108 additions and 96 deletions
+1
View File
@@ -38,6 +38,7 @@
#include "assertions.h"
#include "common/utils/utils.h"
#define MAX_SI_GROUPS 3
#define NR_MAX_PDSCH_TBS 3824
#define MAX_NUM_BEAM_PERIODS 4
#define MAX_BWP_SIZE 275
+3 -6
View File
@@ -936,10 +936,7 @@ static void update_mib_conf(NR_MIB_t *target, NR_MIB_t *source)
target->intraFreqReselection = source->intraFreqReselection;
}
void nr_rrc_mac_config_req_mib(module_id_t module_id,
int cc_idP,
NR_MIB_t *mib,
int sched_sib)
void nr_rrc_mac_config_req_mib(module_id_t module_id, int cc_idP, NR_MIB_t *mib, int sched_sib)
{
NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
int ret = pthread_mutex_lock(&mac->if_mutex);
@@ -952,8 +949,8 @@ void nr_rrc_mac_config_req_mib(module_id_t module_id,
mac->phy_config.CC_id = cc_idP;
if (sched_sib == 1)
mac->get_sib1 = true;
else if (sched_sib == 2)
mac->get_otherSI = true;
else if (sched_sib > 1)
mac->get_otherSI[sched_sib - 2] = true;
nr_ue_decode_mib(mac, cc_idP);
ret = pthread_mutex_unlock(&mac->if_mutex);
AssertFatal(!ret, "mutex failed %d\n", ret);
+1 -1
View File
@@ -539,7 +539,7 @@ typedef struct NR_UE_MAC_INST_s {
int servCellIndex;
long physCellId;
bool get_sib1;
bool get_otherSI;
bool get_otherSI[MAX_SI_GROUPS];
NR_MIB_t *mib;
si_schedInfo_t si_SchedInfo;
+2 -1
View File
@@ -56,7 +56,8 @@ 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);
mac->get_sib1 = false;
mac->get_otherSI = false;
for (int i = 0; i < MAX_SI_GROUPS; i++)
mac->get_otherSI[i] = false;
memset(&mac->phy_config, 0, sizeof(mac->phy_config));
mac->si_SchedInfo.si_window_start = -1;
mac->servCellIndex = 0;
@@ -375,7 +375,6 @@ bool search_space_monitoring_ocasion_other_si(NR_UE_MAC_INST_t *mac,
if (((frame * slots_per_frame + slot - offset - i) % period) == 0) {
int N = mac->ssb_list.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 rel_slot = abs_slot - mac->si_SchedInfo.si_window_start;
int current_monitor_occasion = (rel_slot % period) + (duration * rel_slot / period);
@@ -399,43 +398,41 @@ bool is_window_valid(NR_UE_MAC_INST_t *mac, int window_slots, int abs_slot)
return true;
}
bool monitor_dci_for_other_SI(NR_UE_MAC_INST_t *mac,
const NR_SearchSpace_t *ss,
const int slots_per_frame,
const int frame,
const int slot)
static bool monitor_dci_for_other_SI(NR_UE_MAC_INST_t *mac,
const NR_SearchSpace_t *ss,
const int si_idx,
const int slots_per_frame,
const int frame,
const int slot)
{
// according to 5.2.2.3.2 in 331
const int abs_slot = frame * slots_per_frame + 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
}
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))
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;
}
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);
break;
default :
AssertFatal(false, "Invalid SI-SchedulingInfo case\n");
}
si_schedinfo_config_t *config = mac->si_SchedInfo.si_SchedInfo_list.array[si_idx];
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
}
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))
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;
}
if (is_window_valid(mac, window_slots, abs_slot))
return search_space_monitoring_ocasion_other_si(mac, ss, abs_slot, frame, slot, slots_per_frame);
break;
default :
AssertFatal(false, "Invalid SI-SchedulingInfo case\n");
}
return false;
}
@@ -478,13 +475,15 @@ void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl
config_dci_pdu(mac, dl_config, TYPE_SI_RNTI_, slot, mac->search_space_zero);
}
}
if (mac->get_otherSI) {
for (int i = 0; i < MAX_SI_GROUPS; i++) {
if (!mac->get_otherSI[i])
continue;
// If searchSpaceOtherSystemInformation is set to zero,
// PDCCH monitoring occasions for SI message reception in SI-window
// are same as PDCCH monitoring occasions for SIB1
const NR_SearchSpace_t *ss = pdcch_config->otherSI_SS ? pdcch_config->otherSI_SS : mac->search_space_zero;
// TODO configure SI-window
if (monitor_dci_for_other_SI(mac, ss, slots_per_frame, frame, slot)) {
if (monitor_dci_for_other_SI(mac, ss, i, slots_per_frame, frame, slot)) {
LOG_D(NR_MAC_DCI, "Monitoring DCI for other SIs in frame %d slot %d\n", frame, slot);
config_dci_pdu(mac, dl_config, TYPE_SI_RNTI_, slot, ss);
}
+15 -3
View File
@@ -310,8 +310,12 @@ int8_t nr_ue_decode_BCCH_DL_SCH(NR_UE_MAC_INST_t *mac,
if(ack_nack) {
LOG_D(NR_MAC, "Decoding NR-BCCH-DL-SCH-Message (SIB1 or SI)\n");
nr_mac_rrc_data_ind_ue(mac->ue_id, cc_id, gNB_index, 0, 0, 0, mac->physCellId, 0, NR_BCCH_DL_SCH, (uint8_t *) pduP, pdu_len);
mac->get_sib1 = false;
mac->get_otherSI = false;
if (mac->get_sib1)
mac->get_sib1 = false;
for (int i = 0; i < MAX_SI_GROUPS; i++) {
if (mac->get_otherSI[i])
mac->get_otherSI[i] = false;
}
T(T_NRUE_MAC_DL_PDU_WITH_DATA,
T_INT(SI_RNTI),
T_INT(-1 /* frame, unavailable here */),
@@ -742,8 +746,16 @@ static int nr_ue_process_dci_dl_10(NR_UE_MAC_INST_t *mac,
LOG_W(MAC, "[%d.%d] Invalid frequency_domain_assignment. Possibly due to false DCI. Ignoring DCI!\n", frame, slot);
return -1;
}
dlsch_pdu->rb_offset = dlsch_pdu->start_rb + dlsch_pdu->BWPStart;
if (mac->get_sib1 || mac->get_otherSI)
bool otherSI = false;
for (int i = 0; i < MAX_SI_GROUPS; i++) {
if (mac->get_otherSI[i]) {
otherSI = true;
break;
}
}
if (mac->get_sib1 || otherSI)
dlsch_pdu->rb_offset -= dlsch_pdu->BWPStart;
/* TIME_DOM_RESOURCE_ASSIGNMENT */
@@ -342,7 +342,7 @@ static uint32_t get_tbs_bch(NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config,
return TBS;
}
static uint32_t schedule_control_sib1(module_id_t module_id,
static uint32_t schedule_control_sib1(gNB_MAC_INST *gNB_mac,
int CC_id,
NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config,
int time_domain_allocation,
@@ -352,7 +352,6 @@ static uint32_t schedule_control_sib1(module_id_t module_id,
int beam,
uint16_t num_total_bytes)
{
gNB_MAC_INST *gNB_mac = RC.nrmac[module_id];
AssertFatal(gNB_mac->sched_ctrlCommon, "sched_ctrlCommon is NULL\n");
NR_COMMON_channels_t *cc = &gNB_mac->common_channels[CC_id];
uint16_t *vrb_map = cc->vrb_map[beam];
@@ -625,7 +624,8 @@ void schedule_nr_sib1(module_id_t module_idP,
NR_COMMON_channels_t *cc = &gNB_mac->common_channels[0];
// Configure sched_ctrlCommon for SIB1
uint32_t TBS = schedule_control_sib1(module_idP, CC_id,
uint32_t TBS = schedule_control_sib1(gNB_mac,
CC_id,
type0_PDCCH_CSS_config,
time_domain_allocation,
&dmrs_parms,
@@ -709,8 +709,11 @@ static void other_sib_sched_control(module_id_t module_idP,
int n_slots_frame = gNB_mac->frame_structure.numb_slots_frame;
NR_beam_alloc_t beam = beam_allocation_procedure(&gNB_mac->beam_info, frame, slot, beam_index, n_slots_frame);
AssertFatal(beam.idx >= 0, "Cannot allocate otherSIB corresponding for SSB number %d in any available beam\n", beam_index);
LOG_D(NR_MAC, "(%d.%d) otherSIB transmission for ssb number %d\n", frame, slot, beam_index);
LOG_D(NR_MAC, "(%d.%d) otherSIB payload %d transmission for ssb number %d\n", frame, slot, payload_idx, beam_index);
NR_COMMON_channels_t *cc = &gNB_mac->common_channels[0];
NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config = &gNB_mac->type0_PDCCH_CSS_config[cc->ssb_index[beam_index]];
AssertFatal(gNB_mac->sched_ctrlCommon, "sched_ctrlCommon is NULL\n");
NR_PDSCH_ConfigCommon_t *pdsch_ConfigCommon = scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup;
int time_domain_allocation = 1;
NR_tda_info_t tda_info = set_tda_info_from_list(pdsch_ConfigCommon->pdsch_TimeDomainAllocationList, time_domain_allocation);
@@ -728,8 +731,6 @@ static void other_sib_sched_control(module_id_t module_idP,
AssertFatal(nr_of_candidates > 0, "nr_of_candidates is 0\n");
NR_ControlResourceSet_t *coreset = get_coreset(gNB_mac, scc, NULL, ss, NR_SearchSpace__searchSpaceType_PR_common);
NR_COMMON_channels_t *cc = &gNB_mac->common_channels[0];
NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config = &gNB_mac->type0_PDCCH_CSS_config[cc->ssb_index[beam_index]];
if (!gNB_mac->sched_pdcch_otherSI) {
gNB_mac->sched_pdcch_otherSI = calloc(1, sizeof(*gNB_mac->sched_pdcch_otherSI));
*gNB_mac->sched_pdcch_otherSI = set_pdcch_structure(gNB_mac, ss, coreset, scc, NULL, type0_PDCCH_CSS_config);
+43 -41
View File
@@ -282,28 +282,34 @@ 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,
struct NR_SI_SchedulingInfo *si_SchedulingInfo,
struct NR_SI_SchedulingInfo_v1700 *si_SchedulingInfo_v1700)
NR_SI_SchedulingInfo_t *si_SchedulingInfo,
NR_SI_SchedulingInfo_v1700_t *si_SchedulingInfo_v1700)
{
for (int i = 0; i < MAX_SI_GROUPS; i++)
SI_info->default_otherSI_map[i] = 0;
int nb_groups = 0;
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];
nb_groups = si_SchedulingInfo->schedulingInfoList.list.count;
AssertFatal(nb_groups <= MAX_SI_GROUPS, "Exceeding max number of SI groups configured\n");
for (int i = 0; i < nb_groups; i++) {
NR_SchedulingInfo_t *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;
NR_SIB_TypeInfo_t *sib_Type = schedulingInfo->sib_MappingInfo.list.array[j];
SI_info->default_otherSI_map[i] |= 1 << sib_Type->type;
}
}
}
if (si_SchedulingInfo_v1700) {
SI_info->SInfo_r17.default_otherSI_map_r17 = 0;
int start_idx = nb_groups;
nb_groups += si_SchedulingInfo_v1700->schedulingInfoList2_r17.list.count;
AssertFatal(nb_groups <= MAX_SI_GROUPS, "Exceeding max number of SI groups configured\n");
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];
NR_SchedulingInfo2_r17_t *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];
NR_SIB_TypeInfo_v1700_t *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;
SI_info->default_otherSI_map[start_idx + i] |= 1 << (sib_TypeInfo_v1700->sibType_r17.choice.type1_r17 + 13);
}
}
}
@@ -318,11 +324,14 @@ static bool verify_NTN_access(const NR_UE_RRC_SI_INFO *SI_info, const NR_SIB1_v1
&& *sib1_v1700->cellBarredNTN_r17 == NR_SIB1_v1700_IEs__cellBarredNTN_r17_notBarred)
ntn_access = true;
uint32_t sib19_mask = 1 << NR_SIB_TypeInfo_v1700__sibType_r17__type1_r17_sibType19;
int sib19_present = SI_info->SInfo_r17.default_otherSI_map_r17 & sib19_mask;
uint32_t sib19_mask = 1 << (NR_SIB_TypeInfo_v1700__sibType_r17__type1_r17_sibType19 + 13);
int sib19_present = false;
for (int i = 0; i < MAX_SI_GROUPS; i++) {
sib19_present = SI_info->default_otherSI_map[i] & sib19_mask;
if (sib19_present)
break;
}
AssertFatal(!ntn_access || sib19_present, "NTN cell, but SIB19 not configured.\n");
return ntn_access && sib19_present;
}
@@ -783,7 +792,7 @@ bool check_si_validity_r17(NR_UE_RRC_SI_INFO_r17 *SI_info, int si_type)
return true;
}
int check_si_status(NR_UE_RRC_SI_INFO *SI_info)
static 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_validity == SIB_NOT_VALID) {
@@ -791,31 +800,22 @@ int check_si_status(NR_UE_RRC_SI_INFO *SI_info)
return 1;
}
else {
if (SI_info->default_otherSI_map) {
for (int j = 0; j < MAX_SI_GROUPS; j++) {
if (!SI_info->default_otherSI_map[j])
continue;
// 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
for (int i = 2; i < 15; i++) {
int si_index = i - 2;
if ((SI_info->default_otherSI_map >> 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(SI_info, si_index))
return 2;
}
}
}
// 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;
for (int i = 2; i < 22; i++) {
if (!((SI_info->default_otherSI_map[j] >> (i - 2)) & 0x01))
continue;
// if RRC has no valid version of one of the default configured SI
// Then schedule reception of otherSI
if (i < 15) {
if (!check_si_validity(SI_info, i - 2))
return 2 + j;
} else {
if (!check_si_validity_r17(&SI_info->SInfo_r17, i - 15))
return 2 + j;
}
}
}
@@ -862,8 +862,10 @@ static void nr_rrc_ue_decode_NR_BCCH_BCH_Message(NR_UE_RRC_INST_t *rrc,
}
int get_sib = 0;
if (IS_SA_MODE(get_softmodem_params()) && bcch_message->message.present == NR_BCCH_BCH_MessageType_PR_mib
&& bcch_message->message.choice.mib->cellBarred == NR_MIB__cellBarred_notBarred && rrc->nrRrcState != RRC_STATE_DETACH_NR) {
if (IS_SA_MODE(get_softmodem_params())
&& bcch_message->message.present == NR_BCCH_BCH_MessageType_PR_mib
&& bcch_message->message.choice.mib->cellBarred == NR_MIB__cellBarred_notBarred
&& rrc->nrRrcState != RRC_STATE_DETACH_NR) {
NR_UE_RRC_SI_INFO *SI_info = &rrc->perNB[gNB_index].SInfo;
// to schedule MAC to get SI if required
get_sib = check_si_status(SI_info);
+1 -2
View File
@@ -111,7 +111,6 @@ typedef enum {
} SIB_validity_t;
typedef struct UE_RRC_SI_INFO_NR_r17_s {
uint32_t default_otherSI_map_r17;
SIB_validity_t sib15_validity;
NR_timer_t sib15_timer;
SIB_validity_t sib16_validity;
@@ -129,7 +128,7 @@ typedef struct UE_RRC_SI_INFO_NR_r17_s {
} NR_UE_RRC_SI_INFO_r17;
typedef struct UE_RRC_SI_INFO_NR_s {
uint32_t default_otherSI_map;
uint32_t default_otherSI_map[MAX_SI_GROUPS];
SIB_validity_t sib1_validity;
NR_timer_t sib1_timer;
SIB_validity_t sib2_validity;