Merge remote-tracking branch 'origin/NR_UE_RRC_Reconfiguration_improvements' into integration_2024_w47 (!2996)
Improvements in handling RRC Reconfiguration at UE
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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];
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
+368
-323
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user