Commit 4c15a04b authored by Roberto Rosca's avatar Roberto Rosca

Receive SIB19 on UE

parent 469d58f9
......@@ -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,
......
......@@ -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];
......
......@@ -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,
......
......@@ -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 (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;
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;
}
}
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;
......
......@@ -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;
......
......@@ -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 {
......
......@@ -39,6 +39,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)
......@@ -113,6 +114,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)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment