Merge remote-tracking branch 'origin/ue_ho_improve' into integration_2025_w50
This commit is contained in:
@@ -706,7 +706,6 @@ typedef struct
|
||||
uint8_t restricted_set_config;//PRACH restricted set config Value: 0: unrestricted 1: restricted set type A 2: restricted set type B
|
||||
uint8_t num_prach_fd_occasions;//Corresponds to the parameter 𝑀 in [38.211, sec 6.3.3.2] which equals the higher layer parameter msg1FDM Value: 1,2,4,8
|
||||
fapi_nr_num_prach_fd_occasions_t* num_prach_fd_occasions_list;
|
||||
uint8_t ssb_per_rach;//SSB-per-RACH-occasion Value: 0: 1/8 1:1/4, 2:1/2 3:1 4:2 5:4, 6:8 7:16
|
||||
uint8_t prach_multiple_carriers_in_a_band;//0 = disabled 1 = enabled
|
||||
uint8_t root_seq_computed; // flag set and used only in PHY to indicate if table is computed with this config
|
||||
|
||||
|
||||
@@ -964,7 +964,7 @@ int main(int argc, char **argv)
|
||||
|
||||
//Configure UE
|
||||
NR_BCCH_BCH_Message_t *mib = get_new_MIB_NR(scc);
|
||||
nr_rrc_mac_config_req_mib(0, 0, mib->message.choice.mib, false, false);
|
||||
nr_rrc_mac_config_req_mib(0, 0, mib->message.choice.mib, false);
|
||||
nr_rrc_mac_config_req_cg(0, 0, 0, 0, UE_CellGroup, UE_Capability_nr);
|
||||
|
||||
asn1cFreeStruc(asn_DEF_NR_CellGroupConfig, UE_CellGroup);
|
||||
|
||||
@@ -78,6 +78,7 @@
|
||||
|
||||
typedef struct NRRrcMacRaInd_s {
|
||||
bool RA_succeeded;
|
||||
int gnb_index;
|
||||
} NRRrcMacRaInd;
|
||||
|
||||
typedef struct NRRrcMacMsg3Ind_s {
|
||||
|
||||
@@ -481,7 +481,6 @@ typedef struct {
|
||||
} nr_mac_rrc_config_cg_t;
|
||||
typedef struct {
|
||||
NR_BCCH_BCH_Message_t *bcch;
|
||||
int get_sib;
|
||||
bool access_barred;
|
||||
} nr_mac_rrc_config_mib_t;
|
||||
typedef struct {
|
||||
@@ -494,6 +493,10 @@ typedef struct {
|
||||
int frame;
|
||||
bool can_start_ra;
|
||||
} nr_mac_rrc_config_other_sib_t;
|
||||
typedef struct {
|
||||
int get_sib;
|
||||
} nr_mac_rrc_sched_sib_t;
|
||||
|
||||
|
||||
enum payload_type {
|
||||
NR_MAC_RRC_CONFIG_RESET,
|
||||
@@ -501,6 +504,7 @@ enum payload_type {
|
||||
NR_MAC_RRC_CONFIG_MIB,
|
||||
NR_MAC_RRC_CONFIG_SIB1,
|
||||
NR_MAC_RRC_CONFIG_OTHER_SIB,
|
||||
NR_MAC_RRC_SCHED_SIB,
|
||||
NR_MAC_RRC_RESUME_RB
|
||||
};
|
||||
|
||||
@@ -511,6 +515,7 @@ typedef struct {
|
||||
nr_mac_rrc_config_cg_t config_cg;
|
||||
nr_mac_rrc_config_mib_t config_mib;
|
||||
nr_mac_rrc_config_sib1_t config_sib1;
|
||||
nr_mac_rrc_sched_sib_t sched_sib;
|
||||
nr_mac_rrc_config_other_sib_t config_other_sib;
|
||||
nr_mac_rrc_resume_rb_t resume_rb;
|
||||
} payload;
|
||||
|
||||
@@ -260,8 +260,6 @@ static void config_common_ue_sa(NR_UE_MAC_INST_t *mac, NR_ServingCellConfigCommo
|
||||
mac->frequency_range);
|
||||
//prach_fd_occasion->num_unused_root_sequences = ???
|
||||
}
|
||||
cfg->prach_config.ssb_per_rach = rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present-1;
|
||||
|
||||
}
|
||||
|
||||
// prepare data for orbit propagation based on SIB19 ephemeris data to be able to compute the round-trip-time between ue and sat
|
||||
@@ -548,7 +546,6 @@ static void config_common_ue(NR_UE_MAC_INST_t *mac, NR_ServingCellConfigCommon_t
|
||||
prach_fd_occasion->num_root_sequences =
|
||||
compute_nr_root_seq(rach_ConfigCommon, nb_preambles, frame_type, mac->frequency_range);
|
||||
|
||||
cfg->prach_config.ssb_per_rach = rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present - 1;
|
||||
// prach_fd_occasion->num_unused_root_sequences = ???
|
||||
}
|
||||
}
|
||||
@@ -887,7 +884,8 @@ static void nr_configure_lc_config(NR_UE_MAC_INST_t *mac,
|
||||
nr_lcid_rb_t rb)
|
||||
{
|
||||
NR_LC_SCHEDULING_INFO *lc_sched_info = get_scheduling_info_from_lcid(mac, lc_info->lcid);
|
||||
lc_info->rb = rb;
|
||||
if (rb.type != NR_LCID_NONE)
|
||||
lc_info->rb = rb;
|
||||
lc_info->rb_suspended = false;
|
||||
if (rb.type == NR_LCID_SRB && !mac_lc_config->ul_SpecificParameters) {
|
||||
// release configuration and reset to default
|
||||
@@ -915,6 +913,12 @@ static void nr_configure_lc_config(NR_UE_MAC_INST_t *mac,
|
||||
static nr_lcid_rb_t configure_lcid_rb(NR_RLC_BearerConfig_t *rlc_bearer)
|
||||
{
|
||||
nr_lcid_rb_t rb;
|
||||
if (!rlc_bearer->servedRadioBearer) {
|
||||
LOG_W(NR_MAC, "RLC bearer config does not contain servedRadioBearer.\n");
|
||||
rb.type = NR_LCID_NONE;
|
||||
return rb;
|
||||
}
|
||||
|
||||
if (rlc_bearer->servedRadioBearer->present == NR_RLC_BearerConfig__servedRadioBearer_PR_srb_Identity) {
|
||||
rb.type = NR_LCID_SRB;
|
||||
rb.choice.srb_id = rlc_bearer->servedRadioBearer->choice.srb_Identity;
|
||||
@@ -954,8 +958,6 @@ static void configure_logicalChannelBearer(NR_UE_MAC_INST_t *mac,
|
||||
for (int i = 0; i < rlc_toadd_list->list.count; i++) {
|
||||
NR_RLC_BearerConfig_t *rlc_bearer = rlc_toadd_list->list.array[i];
|
||||
nr_lcid_rb_t rb = configure_lcid_rb(rlc_bearer);
|
||||
if (rb.type == NR_LCID_NONE)
|
||||
continue;
|
||||
int lc_identity = rlc_bearer->logicalChannelIdentity;
|
||||
NR_LogicalChannelConfig_t *mac_lc_config = rlc_bearer->mac_LogicalChannelConfig;
|
||||
int j;
|
||||
@@ -1023,7 +1025,21 @@ static bool is_cset0_present(frequency_range_t const fr, uint8_t const kssb)
|
||||
return (fr == FR1) ? (kssb < 24) : (kssb < 12);
|
||||
}
|
||||
|
||||
void nr_rrc_mac_config_req_mib(module_id_t module_id, int cc_idP, NR_MIB_t *mib, int sched_sib, bool barred)
|
||||
void nr_rrc_mac_sched_sib(module_id_t module_id, int sched_sib)
|
||||
{
|
||||
NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
|
||||
if (sched_sib == 1) {
|
||||
bool const is_c0 = is_cset0_present(mac->frequency_range, mac->ssb_subcarrier_offset);
|
||||
mac->get_sib1 = is_c0;
|
||||
AssertFatal(is_c0, "RRC scheduling SIB1 reception but MIB indicates no SIB1 present in current cell\n");
|
||||
} else if (sched_sib > 1)
|
||||
mac->get_otherSI[sched_sib - 2] = true;
|
||||
|
||||
if (mac->state == UE_NOT_SYNC && mac->get_sib1)
|
||||
mac->state = UE_RECEIVING_SIB;
|
||||
}
|
||||
|
||||
void nr_rrc_mac_config_req_mib(module_id_t module_id, int cc_idP, NR_MIB_t *mib, bool barred)
|
||||
{
|
||||
NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
|
||||
int ret = pthread_mutex_lock(&mac->if_mutex);
|
||||
@@ -1043,22 +1059,10 @@ void nr_rrc_mac_config_req_mib(module_id_t module_id, int cc_idP, NR_MIB_t *mib,
|
||||
mac->phy_config.CC_id = cc_idP;
|
||||
|
||||
nr_ue_decode_mib(mac, cc_idP);
|
||||
|
||||
if (sched_sib == 1) {
|
||||
bool const is_c0 = is_cset0_present(mac->frequency_range, mac->ssb_subcarrier_offset);
|
||||
mac->get_sib1 = is_c0;
|
||||
AssertFatal(is_c0, "RRC scheduling SIB1 reception but MIB indicates no SIB1 present in current cell\n");
|
||||
} else if (sched_sib > 1)
|
||||
mac->get_otherSI[sched_sib - 2] = true;
|
||||
|
||||
if (get_softmodem_params()->phy_test)
|
||||
mac->state = UE_CONNECTED;
|
||||
else if (mac->state == UE_NOT_SYNC) {
|
||||
if (IS_SA_MODE(get_softmodem_params()) && mac->get_sib1)
|
||||
mac->state = UE_RECEIVING_SIB;
|
||||
else
|
||||
mac->state = UE_PERFORMING_RA;
|
||||
}
|
||||
else if (mac->state == UE_NOT_SYNC_RECONF)
|
||||
mac->state = UE_PERFORMING_RA;
|
||||
|
||||
ret = pthread_mutex_unlock(&mac->if_mutex);
|
||||
AssertFatal(!ret, "mutex failed %d\n", ret);
|
||||
@@ -1714,10 +1718,13 @@ static void configure_common_BWP_ul(NR_UE_MAC_INST_t *mac, int bwp_id, NR_BWP_Up
|
||||
mac->sc_info.initial_ul_BWPStart = bwp->BWPStart;
|
||||
}
|
||||
if (ul_common->rach_ConfigCommon) {
|
||||
HANDLE_SETUPRELEASE_DIRECT(bwp->rach_ConfigCommon,
|
||||
ul_common->rach_ConfigCommon,
|
||||
NR_RACH_ConfigCommon_t,
|
||||
asn_DEF_NR_RACH_ConfigCommon);
|
||||
// ssb_perRACH_OccasionAndCB_PreamblesPerSSB is need M
|
||||
// if NULL we need to maintain the information
|
||||
NR_SetupRelease_RACH_ConfigCommon_t *rachcommon = ul_common->rach_ConfigCommon;
|
||||
if (rachcommon->present == NR_SetupRelease_RACH_ConfigCommon_PR_setup
|
||||
&& rachcommon->choice.setup->ssb_perRACH_OccasionAndCB_PreamblesPerSSB)
|
||||
mac->ssb_ro_preambles = get_ssb_ro_preambles_4step(rachcommon->choice.setup->ssb_perRACH_OccasionAndCB_PreamblesPerSSB);
|
||||
HANDLE_SETUPRELEASE_DIRECT(bwp->rach_ConfigCommon, rachcommon, NR_RACH_ConfigCommon_t, asn_DEF_NR_RACH_ConfigCommon);
|
||||
}
|
||||
if (ul_common->ext1 && ul_common->ext1->msgA_ConfigCommon_r16) {
|
||||
HANDLE_SETUPRELEASE_DIRECT(bwp->msgA_ConfigCommon_r16,
|
||||
@@ -1805,7 +1812,7 @@ void nr_rrc_mac_config_req_reset(module_id_t module_id, NR_UE_MAC_reset_cause_t
|
||||
LOG_A(NR_MAC, "Received detach indication\n");
|
||||
reset_ra(mac, true);
|
||||
reset_mac_inst(mac);
|
||||
nr_ue_reset_sync_state(mac);
|
||||
nr_ue_reset_sync_state(mac, false);
|
||||
release_mac_configuration(mac, cause);
|
||||
mac->state = UE_DETACHING;
|
||||
break;
|
||||
@@ -1822,7 +1829,7 @@ void nr_rrc_mac_config_req_reset(module_id_t module_id, NR_UE_MAC_reset_cause_t
|
||||
case RE_ESTABLISHMENT:
|
||||
reset_mac_inst(mac);
|
||||
nr_ue_mac_default_configs(mac);
|
||||
nr_ue_reset_sync_state(mac);
|
||||
nr_ue_reset_sync_state(mac, true);
|
||||
release_mac_configuration(mac, cause);
|
||||
// suspend all RBs except SRB0
|
||||
for (int j = 0; j < mac->lc_ordered_list.count; j++) {
|
||||
@@ -1976,12 +1983,23 @@ static void handle_reconfiguration_with_sync(NR_UE_MAC_INST_t *mac,
|
||||
LOG_I(NR_MAC, "Configuring CRNTI %x\n", mac->crnti);
|
||||
|
||||
RA_config_t *ra = &mac->ra;
|
||||
bool is_cfra = false;
|
||||
if (reconfWithSync->rach_ConfigDedicated) {
|
||||
AssertFatal(reconfWithSync->rach_ConfigDedicated->present == NR_ReconfigurationWithSync__rach_ConfigDedicated_PR_uplink,
|
||||
"RACH on supplementaryUplink not supported\n");
|
||||
NR_RACH_ConfigDedicated_t *rach_ConfigDedicated = reconfWithSync->rach_ConfigDedicated->choice.uplink;
|
||||
if (rach_ConfigDedicated->cfra)
|
||||
is_cfra = true;
|
||||
if (rach_ConfigDedicated->ext1 && rach_ConfigDedicated->ext1->cfra_TwoStep_r16)
|
||||
is_cfra = true;
|
||||
UPDATE_IE(ra->rach_ConfigDedicated, reconfWithSync->rach_ConfigDedicated->choice.uplink, NR_RACH_ConfigDedicated_t);
|
||||
}
|
||||
|
||||
// in case of CBRA and reconfiguration with sync (handover)
|
||||
// the UE sends MSG3 with C-RNTI to identify itself
|
||||
if (!is_cfra)
|
||||
mac->msg3_C_RNTI = true;
|
||||
|
||||
if (reconfWithSync->spCellConfigCommon) {
|
||||
NR_ServingCellConfigCommon_t *scc = reconfWithSync->spCellConfigCommon;
|
||||
if (scc->physCellId)
|
||||
@@ -2000,7 +2018,7 @@ static void handle_reconfiguration_with_sync(NR_UE_MAC_INST_t *mac,
|
||||
configure_common_BWP_ul(mac, bwp_id, scc->uplinkConfigCommon->initialUplinkBWP);
|
||||
}
|
||||
|
||||
mac->state = UE_NOT_SYNC;
|
||||
mac->state = UE_NOT_SYNC_RECONF;
|
||||
ra->ra_state = nrRA_UE_IDLE;
|
||||
nr_ue_mac_default_configs(mac);
|
||||
|
||||
|
||||
@@ -150,6 +150,7 @@
|
||||
// Define the UE L2 states with X-Macro
|
||||
#define NR_UE_L2_STATES \
|
||||
UE_STATE(UE_NOT_SYNC) \
|
||||
UE_STATE(UE_NOT_SYNC_RECONF) \
|
||||
UE_STATE(UE_BARRED) \
|
||||
UE_STATE(UE_RECEIVING_SIB) \
|
||||
UE_STATE(UE_PERFORMING_RA) \
|
||||
@@ -644,6 +645,7 @@ typedef struct NR_UE_MAC_INST_s {
|
||||
|
||||
NR_SSB_meas_t ssb_measurements[MAX_NB_SSB];
|
||||
NR_CSIRS_meas_t csirs_measurements;
|
||||
ssb_ro_preambles_t ssb_ro_preambles;
|
||||
|
||||
dci_pdu_rel15_t def_dci_pdu_rel15[NR_MAX_SLOTS_PER_FRAME][8];
|
||||
|
||||
|
||||
@@ -88,8 +88,8 @@ void nr_rrc_mac_config_req_cg(module_id_t module_id,
|
||||
NR_CellGroupConfig_t *cell_group_config,
|
||||
NR_UE_NR_Capability_t *ue_Capability);
|
||||
|
||||
void nr_rrc_mac_config_req_mib(module_id_t module_id, int cc_idP, NR_MIB_t *mibP, int sched_sib1, bool barred);
|
||||
|
||||
void nr_rrc_mac_config_req_mib(module_id_t module_id, int cc_idP, NR_MIB_t *mibP, bool barred);
|
||||
void nr_rrc_mac_sched_sib(module_id_t module_id, int sched_sib);
|
||||
void nr_rrc_mac_config_req_sib1(module_id_t module_id, int cc_idP, NR_SIB1_t *sib1, bool can_start_ra);
|
||||
|
||||
struct position; /* forward declaration */
|
||||
@@ -255,7 +255,7 @@ void nr_get_RA_window(NR_UE_MAC_INST_t *mac);
|
||||
void prepare_msg4_msgb_feedback(NR_UE_MAC_INST_t *mac, int pid, int ack_nack);
|
||||
void configure_initial_pucch(PUCCH_sched_t *pucch, int res_ind);
|
||||
void release_PUCCH_SRS(NR_UE_MAC_INST_t *mac);
|
||||
void nr_ue_reset_sync_state(NR_UE_MAC_INST_t *mac);
|
||||
void nr_ue_reset_sync_state(NR_UE_MAC_INST_t *mac, bool reconf);
|
||||
void nr_ue_send_synch_request(NR_UE_MAC_INST_t *mac, module_id_t module_id, int cc_id, const fapi_nr_synch_request_t *sync_req);
|
||||
bool is_ss_monitor_occasion(const int frame, const int slot, const int slots_per_frame, const NR_SearchSpace_t *ss);
|
||||
|
||||
@@ -363,5 +363,5 @@ int sl_nr_ue_slot_select(const sl_nr_phy_config_request_t *cfg, int nr_slot, uin
|
||||
void nr_ue_sidelink_scheduler(nr_sidelink_indication_t *sl_ind, NR_UE_MAC_INST_t *mac);
|
||||
|
||||
NR_SearchSpace_t *get_common_search_space(const NR_UE_MAC_INST_t *mac, const NR_SearchSpaceId_t ss_id);
|
||||
|
||||
ssb_ro_preambles_t get_ssb_ro_preambles_4step(struct NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB *config);
|
||||
#endif
|
||||
|
||||
@@ -54,7 +54,7 @@ void send_srb0_rrc(int ue_id, const uint8_t *sdu, sdu_size_t sdu_len, void *data
|
||||
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);
|
||||
nr_ue_reset_sync_state(mac, false);
|
||||
mac->get_sib1 = false;
|
||||
for (int i = 0; i < MAX_SI_GROUPS; i++)
|
||||
mac->get_otherSI[i] = false;
|
||||
@@ -117,10 +117,10 @@ void nr_ue_send_synch_request(NR_UE_MAC_INST_t *mac, module_id_t module_id, int
|
||||
mac->if_module->synch_request(&mac->synch_request);
|
||||
}
|
||||
|
||||
void nr_ue_reset_sync_state(NR_UE_MAC_INST_t *mac)
|
||||
void nr_ue_reset_sync_state(NR_UE_MAC_INST_t *mac, bool reconf)
|
||||
{
|
||||
// reset synchornization status
|
||||
mac->state = UE_NOT_SYNC;
|
||||
mac->state = reconf ? UE_NOT_SYNC_RECONF : UE_NOT_SYNC;
|
||||
mac->ra.ra_state = nrRA_UE_IDLE;
|
||||
}
|
||||
|
||||
|
||||
@@ -190,7 +190,7 @@ static void select_preamble_group(NR_UE_MAC_INST_t *mac)
|
||||
// else if Msg3 is being retransmitted, we keep what used in first transmission of Msg3
|
||||
}
|
||||
|
||||
static ssb_ro_preambles_t get_ssb_ro_preambles_4step(struct NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB *config)
|
||||
ssb_ro_preambles_t get_ssb_ro_preambles_4step(struct NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB *config)
|
||||
{
|
||||
ssb_ro_preambles_t ret = {0};
|
||||
switch (config->present) {
|
||||
@@ -293,9 +293,7 @@ static void config_preamble_index(NR_UE_MAC_INST_t *mac)
|
||||
bool groupBconfigured = false;
|
||||
int preamb_ga = 0;
|
||||
if (ra->ra_type == RA_4_STEP) {
|
||||
AssertFatal(nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB,
|
||||
"Not expeting ssb_perRACH_OccasionAndCB_PreamblesPerSSB to be NULL here\n");
|
||||
ra->ssb_ro_config = get_ssb_ro_preambles_4step(nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB);
|
||||
ra->ssb_ro_config = mac->ssb_ro_preambles;
|
||||
if (nr_rach_ConfigCommon->totalNumberOfRA_Preambles)
|
||||
nb_of_preambles = *nr_rach_ConfigCommon->totalNumberOfRA_Preambles;
|
||||
// Amongst the contention-based Random Access Preambles associated with an SSB the first numberOfRA-PreamblesGroupA
|
||||
@@ -321,7 +319,7 @@ static void config_preamble_index(NR_UE_MAC_INST_t *mac)
|
||||
if (twostep->msgA_SSB_PerRACH_OccasionAndCB_PreamblesPerSSB_r16)
|
||||
ra->ssb_ro_config = get_ssb_ro_preambles_2step(twostep->msgA_SSB_PerRACH_OccasionAndCB_PreamblesPerSSB_r16);
|
||||
else
|
||||
ra->ssb_ro_config = get_ssb_ro_preambles_4step(nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB);
|
||||
ra->ssb_ro_config = mac->ssb_ro_preambles;
|
||||
if (twostep->msgA_TotalNumberOfRA_Preambles_r16)
|
||||
nb_of_preambles = *twostep->msgA_TotalNumberOfRA_Preambles_r16;
|
||||
}
|
||||
|
||||
@@ -480,6 +480,15 @@ void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl
|
||||
}
|
||||
config_dci_pdu(mac, dl_config, rnti_type, slot, ra_SS);
|
||||
}
|
||||
// If Msg3 has C-RNTI MAC CE, also monitor dedicated search spaces during contention resolution
|
||||
// according to TS 38.321 section 5.1.5
|
||||
if (ra->ra_state == nrRA_WAIT_CONTENTION_RESOLUTION && mac->msg3_C_RNTI) {
|
||||
for (int i = 0; i < pdcch_config->list_SS.count; i++) {
|
||||
NR_SearchSpace_t *ss = pdcch_config->list_SS.array[i];
|
||||
if (is_ss_monitor_occasion(frame, slot, slots_per_frame, ss))
|
||||
config_dci_pdu(mac, dl_config, TYPE_C_RNTI_, slot, ss);
|
||||
}
|
||||
}
|
||||
} else if (mac->state == UE_CONNECTED) {
|
||||
/*
|
||||
In RRC Connected state, the UE monitors for fallback DCI with C-RNTI in common and UE-specific SS.
|
||||
|
||||
@@ -1145,7 +1145,7 @@ void nr_ue_dl_scheduler(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *dl_info
|
||||
dl_config->slot = rx_slot;
|
||||
dl_config->number_pdus = 0;
|
||||
|
||||
if (mac->state == UE_NOT_SYNC || mac->state == UE_DETACHING)
|
||||
if (mac->state == UE_NOT_SYNC || mac->state == UE_NOT_SYNC_RECONF || mac->state == UE_DETACHING)
|
||||
return;
|
||||
|
||||
if (mac->state == UE_CONNECTED) {
|
||||
|
||||
@@ -154,7 +154,6 @@ void process_msg_rcc_to_mac(nr_mac_rrc_message_t *msg, int instance_id)
|
||||
nr_rrc_mac_config_req_mib(instance_id,
|
||||
0,
|
||||
msg->payload.config_mib.bcch->message.choice.mib,
|
||||
msg->payload.config_mib.get_sib,
|
||||
msg->payload.config_mib.access_barred);
|
||||
ASN_STRUCT_FREE(asn_DEF_NR_BCCH_BCH_Message, msg->payload.config_mib.bcch);
|
||||
break;
|
||||
@@ -171,6 +170,9 @@ void process_msg_rcc_to_mac(nr_mac_rrc_message_t *msg, int instance_id)
|
||||
msg->payload.config_other_sib.frame,
|
||||
msg->payload.config_other_sib.can_start_ra);
|
||||
} break;
|
||||
case NR_MAC_RRC_SCHED_SIB:
|
||||
nr_rrc_mac_sched_sib(instance_id, msg->payload.sched_sib.get_sib);
|
||||
break;
|
||||
case NR_MAC_RRC_RESUME_RB:
|
||||
nr_rrc_mac_resume_rb(instance_id, msg->payload.resume_rb.is_srb, msg->payload.resume_rb.rb_id);
|
||||
break;
|
||||
|
||||
+226
-160
@@ -750,6 +750,189 @@ static void nr_rrc_ue_process_RadioBearerConfig(NR_UE_RRC_INST_t *ue_rrc, NR_Rad
|
||||
LOG_I(NR_RRC, "State = NR_RRC_CONNECTED\n");
|
||||
}
|
||||
|
||||
static void nr_rrc_signal_maxrtxindication(int ue_id)
|
||||
{
|
||||
MessageDef *msg = itti_alloc_new_message(TASK_RLC_UE, ue_id, NR_RRC_RLC_MAXRTX);
|
||||
NR_RRC_RLC_MAXRTX(msg).ue_id = ue_id;
|
||||
itti_send_msg_to_task(TASK_RRC_NRUE, ue_id, msg);
|
||||
}
|
||||
|
||||
/** @brief Release all active RLC entities for a UE and set to inactive.
|
||||
* This is typically used when tearing down all DRBs at UE side,
|
||||
* such as after a PDU session release or full reconfiguration.
|
||||
* @param rrc Pointer to NR_UE_RRC_INST_t structure
|
||||
* @param id Logical Channel ID (must be in range [0, NR_MAX_NUM_LCID-1]) */
|
||||
static void nr_rrc_release_rlc_entity(NR_UE_RRC_INST_t *rrc, int id)
|
||||
{
|
||||
DevAssert(rrc);
|
||||
DevAssert(id >= 0 && id < NR_MAX_NUM_LCID);
|
||||
if (rrc->active_RLC_entity[id]) {
|
||||
rrc->active_RLC_entity[id] = false;
|
||||
nr_rlc_release_entity(rrc->ue_id, id);
|
||||
LOG_I(RLC, "Released RLC entity: ue_id=%ld, lc_id=%d\n", rrc->ue_id, id);
|
||||
}
|
||||
}
|
||||
|
||||
static void nr_rrc_manage_rlc_bearers(NR_UE_RRC_INST_t *rrc, const NR_CellGroupConfig_t *cellGroupConfig)
|
||||
{
|
||||
if (cellGroupConfig->rlc_BearerToReleaseList != NULL) {
|
||||
for (int i = 0; i < cellGroupConfig->rlc_BearerToReleaseList->list.count; i++) {
|
||||
NR_LogicalChannelIdentity_t *lcid = cellGroupConfig->rlc_BearerToReleaseList->list.array[i];
|
||||
AssertFatal(lcid, "LogicalChannelIdentity shouldn't be null here\n");
|
||||
nr_rrc_release_rlc_entity(rrc, *lcid);
|
||||
}
|
||||
}
|
||||
|
||||
if (cellGroupConfig->rlc_BearerToAddModList != NULL) {
|
||||
for (int i = 0; i < cellGroupConfig->rlc_BearerToAddModList->list.count; i++) {
|
||||
NR_RLC_BearerConfig_t *rlc_bearer = cellGroupConfig->rlc_BearerToAddModList->list.array[i];
|
||||
NR_LogicalChannelIdentity_t lcid = rlc_bearer->logicalChannelIdentity;
|
||||
if (rrc->active_RLC_entity[lcid]) {
|
||||
if (rlc_bearer->reestablishRLC)
|
||||
nr_rlc_reestablish_entity(rrc->ue_id, lcid);
|
||||
if (rlc_bearer->rlc_Config)
|
||||
nr_rlc_reconfigure_entity(rrc->ue_id, lcid, rlc_bearer->rlc_Config);
|
||||
} else {
|
||||
rrc->active_RLC_entity[lcid] = true;
|
||||
AssertFatal(rlc_bearer->servedRadioBearer, "servedRadioBearer mandatory in case of setup\n");
|
||||
AssertFatal(rlc_bearer->servedRadioBearer->present != NR_RLC_BearerConfig__servedRadioBearer_PR_NOTHING,
|
||||
"Invalid RB for RLC configuration\n");
|
||||
if (rlc_bearer->servedRadioBearer->present == NR_RLC_BearerConfig__servedRadioBearer_PR_srb_Identity) {
|
||||
NR_SRB_Identity_t srb_id = rlc_bearer->servedRadioBearer->choice.srb_Identity;
|
||||
nr_rlc_add_srb(rrc->ue_id, srb_id, rlc_bearer);
|
||||
nr_rlc_set_rlf_handler(rrc->ue_id, nr_rrc_signal_maxrtxindication);
|
||||
} else { // DRB
|
||||
NR_DRB_Identity_t drb_id = rlc_bearer->servedRadioBearer->choice.drb_Identity;
|
||||
if (!rlc_bearer->rlc_Config) {
|
||||
LOG_E(RLC, "RLC-Config not present but is mandatory for setup\n");
|
||||
rrc->active_RLC_entity[lcid] = false;
|
||||
} else {
|
||||
nr_rlc_add_drb(rrc->ue_id, drb_id, rlc_bearer);
|
||||
nr_rlc_set_rlf_handler(rrc->ue_id, nr_rrc_signal_maxrtxindication);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void nr_rrc_process_reconfigurationWithSync(NR_UE_RRC_INST_t *rrc,
|
||||
NR_ReconfigurationWithSync_t *reconfigurationWithSync,
|
||||
int gNB_index)
|
||||
{
|
||||
// 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) {
|
||||
/* if the frequencyInfoDL is included, consider the target SpCell
|
||||
to be one on the SSB frequency indicated by the frequencyInfoDL */
|
||||
const NR_DownlinkConfigCommon_t *dcc = reconfigurationWithSync->spCellConfigCommon->downlinkConfigCommon;
|
||||
if (dcc && dcc->frequencyInfoDL && dcc->frequencyInfoDL->absoluteFrequencySSB)
|
||||
rrc->arfcn_ssb = *dcc->frequencyInfoDL->absoluteFrequencySSB;
|
||||
|
||||
// consider the target SpCell to be one with a physical cell identity indicated by the physCellId
|
||||
if (!reconfigurationWithSync->spCellConfigCommon->physCellId)
|
||||
LOG_E(NR_RRC, "physCellId absent but should be mandatory present upon cell change and cell addition\n");
|
||||
else
|
||||
rrc->phyCellID = *reconfigurationWithSync->spCellConfigCommon->physCellId;
|
||||
}
|
||||
|
||||
NR_UE_Timers_Constants_t *tac = &rrc->timers_and_constants;
|
||||
nr_timer_stop(&tac->T310);
|
||||
if (!get_softmodem_params()->phy_test) {
|
||||
// T304 is stopped upon completion of RA procedure which is not done in phy-test mode
|
||||
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)
|
||||
|
||||
// 3GPP TS38.331 section 5.3.5.5.2
|
||||
nr_timer_stop(&tac->T430);
|
||||
|
||||
if (rrc->target_ntncfg) {
|
||||
ASN_STRUCT_FREE(asn_DEF_NR_NTN_Config_r17, rrc->target_ntncfg);
|
||||
rrc->target_ntncfg = NULL;
|
||||
rrc->process_target_ntncfg = false;
|
||||
}
|
||||
if (reconfigurationWithSync->spCellConfigCommon &&
|
||||
reconfigurationWithSync->spCellConfigCommon->ext2 &&
|
||||
reconfigurationWithSync->spCellConfigCommon->ext2->ntn_Config_r17) {
|
||||
NR_NTN_Config_r17_t *ntncfg = reconfigurationWithSync->spCellConfigCommon->ext2->ntn_Config_r17;
|
||||
// EPOCH time is always sent if NTN config is sent through DCCH
|
||||
AssertFatal(ntncfg->epochTime_r17, "NTN-CONFIG sent in dedicated mode should have EPOCHTIME\n");
|
||||
const int copy_result = asn_copy(&asn_DEF_NR_NTN_Config_r17, (void **)&rrc->target_ntncfg, ntncfg);
|
||||
AssertFatal(copy_result == 0, "unable to copy NR_NTN_Config_r17_t\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void nr_rrc_cellgroup_configuration(NR_UE_RRC_INST_t *rrc, NR_CellGroupConfig_t *cgConfig, int gNB_index, bool dedicatedsib1)
|
||||
{
|
||||
NR_SpCellConfig_t *spCellConfig = cgConfig->spCellConfig;
|
||||
if(spCellConfig) {
|
||||
NR_ServingCellConfig_t *spCellConfigDedicated = spCellConfig->spCellConfigDedicated;
|
||||
if (spCellConfigDedicated) {
|
||||
if (spCellConfigDedicated->firstActiveDownlinkBWP_Id)
|
||||
rrc->dl_bwp_id = *spCellConfigDedicated->firstActiveDownlinkBWP_Id;
|
||||
if (spCellConfigDedicated->uplinkConfig && spCellConfigDedicated->uplinkConfig->firstActiveUplinkBWP_Id)
|
||||
rrc->ul_bwp_id = *spCellConfigDedicated->uplinkConfig->firstActiveUplinkBWP_Id;
|
||||
}
|
||||
NR_ReconfigurationWithSync_t *reconfigurationWithSync = spCellConfig->reconfigurationWithSync;
|
||||
if (reconfigurationWithSync) {
|
||||
LOG_I(NR_RRC, "Processing reconfigurationWithSync\n");
|
||||
nr_rrc_process_reconfigurationWithSync(rrc, reconfigurationWithSync, gNB_index);
|
||||
// if RRCReconfiguration does not include dedicatedSIB1-Delivery
|
||||
// if the active downlink BWP, which is indicated by the firstActiveDownlinkBWP-Id for the target SpCell of the MCG,
|
||||
// has a common search space configured by searchSpaceSIB1
|
||||
// acquire the SIB1, which is scheduled as specified in TS 38.213 [13], of the target SpCell of the MCG
|
||||
if (!dedicatedsib1 && IS_SA_MODE(get_softmodem_params())) {
|
||||
if (rrc->dl_bwp_id == 0) {
|
||||
// Check initial DL BWP for searchSpaceSIB1
|
||||
NR_ServingCellConfigCommon_t *spCellConfigCommon = reconfigurationWithSync->spCellConfigCommon;
|
||||
if (spCellConfigCommon) {
|
||||
NR_DownlinkConfigCommon_t *downlinkConfig = spCellConfigCommon->downlinkConfigCommon;
|
||||
if (downlinkConfig
|
||||
&& downlinkConfig->initialDownlinkBWP
|
||||
&& downlinkConfig->initialDownlinkBWP->pdcch_ConfigCommon
|
||||
&& downlinkConfig->initialDownlinkBWP->pdcch_ConfigCommon->present == NR_SetupRelease_PDCCH_ConfigCommon_PR_setup
|
||||
&& downlinkConfig->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->searchSpaceSIB1) {
|
||||
rrc->sched_reconfsync_sib1 = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Check dedicated DL BWP for searchSpaceSIB1
|
||||
if (spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList) {
|
||||
for (int i = 0; i < spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count; i++) {
|
||||
NR_BWP_Downlink_t *bwp = spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[i];
|
||||
if (bwp->bwp_Id == rrc->dl_bwp_id && bwp->bwp_Common && bwp->bwp_Common->pdcch_ConfigCommon
|
||||
&& bwp->bwp_Common->pdcch_ConfigCommon->present == NR_SetupRelease_PDCCH_ConfigCommon_PR_setup
|
||||
&& bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->searchSpaceSIB1) {
|
||||
rrc->sched_reconfsync_sib1 = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
nr_rrc_handle_SetupRelease_RLF_TimersAndConstants(rrc, spCellConfig->rlf_TimersAndConstants);
|
||||
}
|
||||
|
||||
nr_rrc_manage_rlc_bearers(rrc, cgConfig);
|
||||
|
||||
if (cgConfig->ext1)
|
||||
AssertFatal(cgConfig->ext1->reportUplinkTxDirectCurrent == NULL, "Reporting of UplinkTxDirectCurrent not implemented\n");
|
||||
AssertFatal(cgConfig->sCellToReleaseList == NULL, "Secondary serving cell release not implemented\n");
|
||||
AssertFatal(cgConfig->sCellToAddModList == NULL, "Secondary serving cell addition not implemented\n");
|
||||
}
|
||||
|
||||
static void nr_rrc_ue_process_masterCellGroup(NR_UE_RRC_INST_t *rrc,
|
||||
OCTET_STRING_t *masterCellGroup,
|
||||
long *fullConfig,
|
||||
@@ -770,7 +953,7 @@ static void nr_rrc_ue_process_masterCellGroup(NR_UE_RRC_INST_t *rrc,
|
||||
xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void *) cellGroupConfig);
|
||||
}
|
||||
|
||||
nr_rrc_cellgroup_configuration(rrc, cellGroupConfig, gNB_index);
|
||||
nr_rrc_cellgroup_configuration(rrc, cellGroupConfig, gNB_index, false);
|
||||
|
||||
LOG_D(RRC, "Sending CellGroupConfig to MAC the pointer will be managed by mac\n");
|
||||
nr_mac_rrc_message_t rrc_msg = {0};
|
||||
@@ -783,7 +966,7 @@ static void nr_rrc_ue_process_masterCellGroup(NR_UE_RRC_INST_t *rrc,
|
||||
nr_rrc_send_msg_to_mac(rrc, &rrc_msg);
|
||||
}
|
||||
|
||||
static void nr_rrc_process_reconfiguration_v1530(NR_UE_RRC_INST_t *rrc, NR_RRCReconfiguration_v1530_IEs_t *rec_1530, int gNB_index)
|
||||
static bool 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
|
||||
@@ -797,7 +980,9 @@ static void nr_rrc_process_reconfiguration_v1530(NR_UE_RRC_INST_t *rrc, NR_RRCRe
|
||||
nr_pdcp_config_set_security(rrc->ue_id, 1, true, &sp);
|
||||
}
|
||||
NR_UE_RRC_SI_INFO *SI_info = &rrc->perNB[gNB_index].SInfo;
|
||||
bool dedicatedsib1 = false;
|
||||
if (rec_1530->dedicatedSIB1_Delivery) {
|
||||
dedicatedsib1 = true;
|
||||
NR_SIB1_t *sib1 = NULL;
|
||||
asn_dec_rval_t dec_rval = uper_decode(NULL,
|
||||
&asn_DEF_NR_SIB1,
|
||||
@@ -864,6 +1049,7 @@ static void nr_rrc_process_reconfiguration_v1530(NR_UE_RRC_INST_t *rrc, NR_RRCRe
|
||||
}
|
||||
}
|
||||
}
|
||||
return dedicatedsib1;
|
||||
}
|
||||
|
||||
static void handle_meas_reporting_remove(rrcPerNB_t *rrc, int id, NR_UE_Timers_Constants_t *timers)
|
||||
@@ -1142,8 +1328,9 @@ static void nr_rrc_ue_process_rrcReconfiguration(NR_UE_RRC_INST_t *rrc, int gNB_
|
||||
case NR_RRCReconfiguration__criticalExtensions_PR_rrcReconfiguration: {
|
||||
NR_RRCReconfiguration_IEs_t *ie = reconfiguration->criticalExtensions.choice.rrcReconfiguration;
|
||||
|
||||
bool dedicatedsib1 = false;
|
||||
if (ie->nonCriticalExtension)
|
||||
nr_rrc_process_reconfiguration_v1530(rrc, ie->nonCriticalExtension, gNB_index);
|
||||
dedicatedsib1 = nr_rrc_process_reconfiguration_v1530(rrc, ie->nonCriticalExtension, gNB_index);
|
||||
|
||||
if (ie->radioBearerConfig) {
|
||||
LOG_I(NR_RRC, "RRCReconfiguration includes radio Bearer Configuration\n");
|
||||
@@ -1179,7 +1366,7 @@ static void nr_rrc_ue_process_rrcReconfiguration(NR_UE_RRC_INST_t *rrc, int gNB_
|
||||
if (LOG_DEBUGFLAG(DEBUG_ASN1))
|
||||
xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void *) cellGroupConfig);
|
||||
|
||||
nr_rrc_cellgroup_configuration(rrc, cellGroupConfig, gNB_index);
|
||||
nr_rrc_cellgroup_configuration(rrc, cellGroupConfig, gNB_index, dedicatedsib1);
|
||||
AssertFatal(!IS_SA_MODE(get_softmodem_params()), "secondaryCellGroup only used in NSA for now\n");
|
||||
nr_mac_rrc_message_t rrc_msg = {0};
|
||||
rrc_msg.payload_type = NR_MAC_RRC_CONFIG_CG;
|
||||
@@ -1284,6 +1471,7 @@ NR_UE_RRC_INST_t* nr_rrc_init_ue(char* uecap_file, int instance_id, int num_ant_
|
||||
rrc->dl_bwp_id = 0;
|
||||
rrc->ul_bwp_id = 0;
|
||||
rrc->as_security_activated = false;
|
||||
rrc->sched_reconfsync_sib1 = false;
|
||||
rrc->detach_after_release = false;
|
||||
rrc->reconfig_after_reestab = false;
|
||||
/* 5G-S-TMSI */
|
||||
@@ -1513,17 +1701,21 @@ static void nr_rrc_ue_decode_NR_BCCH_BCH_Message(NR_UE_RRC_INST_t *rrc,
|
||||
&& rrc->nrRrcState != RRC_STATE_DETACH_NR) {
|
||||
// to schedule MAC to get SI if required
|
||||
get_sib = check_si_status(SI_info);
|
||||
if (get_sib)
|
||||
SI_info->sib_pending = true;
|
||||
}
|
||||
if (bcch_message->message.present == NR_BCCH_BCH_MessageType_PR_mib) {
|
||||
nr_mac_rrc_message_t rrc_msg = {0};
|
||||
rrc_msg.payload_type = NR_MAC_RRC_CONFIG_MIB;
|
||||
nr_mac_rrc_config_mib_t *config_mib = &rrc_msg.payload.config_mib;
|
||||
config_mib->bcch = bcch_message;
|
||||
config_mib->get_sib = get_sib;
|
||||
config_mib->access_barred = barred;
|
||||
nr_rrc_send_msg_to_mac(rrc, &rrc_msg);
|
||||
if (get_sib) {
|
||||
SI_info->sib_pending = true;
|
||||
nr_mac_rrc_message_t sib_msg = {0};
|
||||
sib_msg.payload_type = NR_MAC_RRC_SCHED_SIB;
|
||||
sib_msg.payload.sched_sib.get_sib = get_sib;
|
||||
nr_rrc_send_msg_to_mac(rrc, &sib_msg);
|
||||
}
|
||||
} else {
|
||||
LOG_E(NR_RRC, "RRC-received BCCH message is not a MIB\n");
|
||||
ASN_STRUCT_FREE(asn_DEF_NR_BCCH_BCH_Message, bcch_message);
|
||||
@@ -1668,155 +1860,6 @@ static void nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(NR_UE_RRC_INST_t *rrc,
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_BCCH, VCD_FUNCTION_OUT );
|
||||
}
|
||||
|
||||
static void nr_rrc_signal_maxrtxindication(int ue_id)
|
||||
{
|
||||
MessageDef *msg = itti_alloc_new_message(TASK_RLC_UE, ue_id, NR_RRC_RLC_MAXRTX);
|
||||
NR_RRC_RLC_MAXRTX(msg).ue_id = ue_id;
|
||||
itti_send_msg_to_task(TASK_RRC_NRUE, ue_id, msg);
|
||||
}
|
||||
|
||||
/** @brief Release all active RLC entities for a UE and set to inactive.
|
||||
* This is typically used when tearing down all DRBs at UE side,
|
||||
* such as after a PDU session release or full reconfiguration.
|
||||
* @param rrc Pointer to NR_UE_RRC_INST_t structure
|
||||
* @param id Logical Channel ID (must be in range [0, NR_MAX_NUM_LCID-1]) */
|
||||
static void nr_rrc_release_rlc_entity(NR_UE_RRC_INST_t *rrc, int id)
|
||||
{
|
||||
DevAssert(rrc);
|
||||
DevAssert(id >= 0 && id < NR_MAX_NUM_LCID);
|
||||
if (rrc->active_RLC_entity[id]) {
|
||||
rrc->active_RLC_entity[id] = false;
|
||||
nr_rlc_release_entity(rrc->ue_id, id);
|
||||
LOG_I(RLC, "Released RLC entity: ue_id=%ld, lc_id=%d\n", rrc->ue_id, id);
|
||||
}
|
||||
}
|
||||
|
||||
static void nr_rrc_manage_rlc_bearers(NR_UE_RRC_INST_t *rrc, const NR_CellGroupConfig_t *cellGroupConfig)
|
||||
{
|
||||
if (cellGroupConfig->rlc_BearerToReleaseList != NULL) {
|
||||
for (int i = 0; i < cellGroupConfig->rlc_BearerToReleaseList->list.count; i++) {
|
||||
NR_LogicalChannelIdentity_t *lcid = cellGroupConfig->rlc_BearerToReleaseList->list.array[i];
|
||||
AssertFatal(lcid, "LogicalChannelIdentity shouldn't be null here\n");
|
||||
nr_rrc_release_rlc_entity(rrc, *lcid);
|
||||
}
|
||||
}
|
||||
|
||||
if (cellGroupConfig->rlc_BearerToAddModList != NULL) {
|
||||
for (int i = 0; i < cellGroupConfig->rlc_BearerToAddModList->list.count; i++) {
|
||||
NR_RLC_BearerConfig_t *rlc_bearer = cellGroupConfig->rlc_BearerToAddModList->list.array[i];
|
||||
NR_LogicalChannelIdentity_t lcid = rlc_bearer->logicalChannelIdentity;
|
||||
if (rrc->active_RLC_entity[lcid]) {
|
||||
if (rlc_bearer->reestablishRLC)
|
||||
nr_rlc_reestablish_entity(rrc->ue_id, lcid);
|
||||
if (rlc_bearer->rlc_Config)
|
||||
nr_rlc_reconfigure_entity(rrc->ue_id, lcid, rlc_bearer->rlc_Config);
|
||||
} else {
|
||||
rrc->active_RLC_entity[lcid] = true;
|
||||
AssertFatal(rlc_bearer->servedRadioBearer, "servedRadioBearer mandatory in case of setup\n");
|
||||
AssertFatal(rlc_bearer->servedRadioBearer->present != NR_RLC_BearerConfig__servedRadioBearer_PR_NOTHING,
|
||||
"Invalid RB for RLC configuration\n");
|
||||
if (rlc_bearer->servedRadioBearer->present == NR_RLC_BearerConfig__servedRadioBearer_PR_srb_Identity) {
|
||||
NR_SRB_Identity_t srb_id = rlc_bearer->servedRadioBearer->choice.srb_Identity;
|
||||
nr_rlc_add_srb(rrc->ue_id, srb_id, rlc_bearer);
|
||||
nr_rlc_set_rlf_handler(rrc->ue_id, nr_rrc_signal_maxrtxindication);
|
||||
} else { // DRB
|
||||
NR_DRB_Identity_t drb_id = rlc_bearer->servedRadioBearer->choice.drb_Identity;
|
||||
if (!rlc_bearer->rlc_Config) {
|
||||
LOG_E(RLC, "RLC-Config not present but is mandatory for setup\n");
|
||||
rrc->active_RLC_entity[lcid] = false;
|
||||
} else {
|
||||
nr_rlc_add_drb(rrc->ue_id, drb_id, rlc_bearer);
|
||||
nr_rlc_set_rlf_handler(rrc->ue_id, nr_rrc_signal_maxrtxindication);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void nr_rrc_process_reconfigurationWithSync(NR_UE_RRC_INST_t *rrc,
|
||||
NR_ReconfigurationWithSync_t *reconfigurationWithSync,
|
||||
int gNB_index)
|
||||
{
|
||||
// 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) {
|
||||
/* if the frequencyInfoDL is included, consider the target SpCell
|
||||
to be one on the SSB frequency indicated by the frequencyInfoDL */
|
||||
const NR_DownlinkConfigCommon_t *dcc = reconfigurationWithSync->spCellConfigCommon->downlinkConfigCommon;
|
||||
if (dcc && dcc->frequencyInfoDL && dcc->frequencyInfoDL->absoluteFrequencySSB)
|
||||
rrc->arfcn_ssb = *dcc->frequencyInfoDL->absoluteFrequencySSB;
|
||||
|
||||
// consider the target SpCell to be one with a physical cell identity indicated by the physCellId
|
||||
if (!reconfigurationWithSync->spCellConfigCommon->physCellId)
|
||||
LOG_E(NR_RRC, "physCellId absent but should be mandatory present upon cell change and cell addition\n");
|
||||
else
|
||||
rrc->phyCellID = *reconfigurationWithSync->spCellConfigCommon->physCellId;
|
||||
}
|
||||
|
||||
NR_UE_Timers_Constants_t *tac = &rrc->timers_and_constants;
|
||||
nr_timer_stop(&tac->T310);
|
||||
if (!get_softmodem_params()->phy_test) {
|
||||
// T304 is stopped upon completion of RA procedure which is not done in phy-test mode
|
||||
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)
|
||||
|
||||
// 3GPP TS38.331 section 5.3.5.5.2
|
||||
nr_timer_stop(&tac->T430);
|
||||
|
||||
if (rrc->target_ntncfg) {
|
||||
ASN_STRUCT_FREE(asn_DEF_NR_NTN_Config_r17, rrc->target_ntncfg);
|
||||
rrc->target_ntncfg = NULL;
|
||||
rrc->process_target_ntncfg = false;
|
||||
}
|
||||
if (reconfigurationWithSync->spCellConfigCommon &&
|
||||
reconfigurationWithSync->spCellConfigCommon->ext2 &&
|
||||
reconfigurationWithSync->spCellConfigCommon->ext2->ntn_Config_r17) {
|
||||
NR_NTN_Config_r17_t *ntncfg = reconfigurationWithSync->spCellConfigCommon->ext2->ntn_Config_r17;
|
||||
// EPOCH time is always sent if NTN config is sent through DCCH
|
||||
AssertFatal(ntncfg->epochTime_r17, "NTN-CONFIG sent in dedicated mode should have EPOCHTIME\n");
|
||||
const int copy_result = asn_copy(&asn_DEF_NR_NTN_Config_r17, (void **)&rrc->target_ntncfg, ntncfg);
|
||||
AssertFatal(copy_result == 0, "unable to copy NR_NTN_Config_r17_t\n");
|
||||
}
|
||||
}
|
||||
|
||||
void nr_rrc_cellgroup_configuration(NR_UE_RRC_INST_t *rrc, NR_CellGroupConfig_t *cellGroupConfig, int gNB_index)
|
||||
{
|
||||
NR_SpCellConfig_t *spCellConfig = cellGroupConfig->spCellConfig;
|
||||
if(spCellConfig) {
|
||||
if (spCellConfig->reconfigurationWithSync) {
|
||||
LOG_I(NR_RRC, "Processing reconfigurationWithSync\n");
|
||||
nr_rrc_process_reconfigurationWithSync(rrc, spCellConfig->reconfigurationWithSync, gNB_index);
|
||||
}
|
||||
nr_rrc_handle_SetupRelease_RLF_TimersAndConstants(rrc, spCellConfig->rlf_TimersAndConstants);
|
||||
if (spCellConfig->spCellConfigDedicated) {
|
||||
if (spCellConfig->spCellConfigDedicated->firstActiveDownlinkBWP_Id)
|
||||
rrc->dl_bwp_id = *spCellConfig->spCellConfigDedicated->firstActiveDownlinkBWP_Id;
|
||||
if (spCellConfig->spCellConfigDedicated->uplinkConfig &&
|
||||
spCellConfig->spCellConfigDedicated->uplinkConfig->firstActiveUplinkBWP_Id)
|
||||
rrc->dl_bwp_id = *spCellConfig->spCellConfigDedicated->uplinkConfig->firstActiveUplinkBWP_Id;
|
||||
}
|
||||
}
|
||||
|
||||
nr_rrc_manage_rlc_bearers(rrc, cellGroupConfig);
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
static void rrc_ue_generate_RRCSetupComplete(const NR_UE_RRC_INST_t *rrc, const uint8_t Transaction_id)
|
||||
{
|
||||
uint8_t buffer[100];
|
||||
@@ -2592,14 +2635,37 @@ static void nr_ue_check_meas_report(NR_UE_RRC_INST_t *rrc, const uint8_t gnb_ind
|
||||
}
|
||||
}
|
||||
|
||||
void nr_rrc_handle_ra_indication(NR_UE_RRC_INST_t *rrc, bool ra_succeeded)
|
||||
static void nr_rrc_handle_ra_indication(NR_UE_RRC_INST_t *rrc, bool ra_succeeded, int gNB_index)
|
||||
{
|
||||
NR_UE_Timers_Constants_t *timers = &rrc->timers_and_constants;
|
||||
if (ra_succeeded && nr_timer_is_active(&timers->T304)) {
|
||||
// successful Random Access procedure triggered by reconfigurationWithSync
|
||||
nr_timer_stop(&timers->T304);
|
||||
// TODO handle the rest of procedures as described in 5.3.5.3 for when
|
||||
// procedures described in 5.3.5.3 of 38.331 when
|
||||
// reconfigurationWithSync is included in spCellConfig
|
||||
nr_timer_stop(&timers->T304);
|
||||
|
||||
// TODO apply the parts of the CQI reporting configuration,
|
||||
// the scheduling request configuration and the sounding RS
|
||||
// configuration that do not require the UE to know the SFN of the respective target SpCell
|
||||
// TODO apply the parts of the measurement and the radio resource configuration
|
||||
// that require the UE to know the SFN of the respective target SpCell
|
||||
// (not sure what to do for these two points, probably not relevant for our implementation)
|
||||
|
||||
// if T390 is running stop timer T390 for all access categories
|
||||
if (nr_timer_is_active(&timers->T390)) {
|
||||
nr_timer_stop(&timers->T390);
|
||||
// TODO perform the actions as specified in 5.3.14.4.
|
||||
}
|
||||
|
||||
if (rrc->sched_reconfsync_sib1) {
|
||||
rrc->sched_reconfsync_sib1 = false;
|
||||
NR_UE_RRC_SI_INFO *SI_info = &rrc->perNB[gNB_index].SInfo;
|
||||
SI_info->sib_pending = true;
|
||||
nr_mac_rrc_message_t sib_msg = {0};
|
||||
sib_msg.payload_type = NR_MAC_RRC_SCHED_SIB;
|
||||
sib_msg.payload.sched_sib.get_sib = 1;
|
||||
nr_rrc_send_msg_to_mac(rrc, &sib_msg);
|
||||
}
|
||||
} else if (!ra_succeeded) {
|
||||
// upon random access problem indication from MCG MAC
|
||||
// while neither T300, T301, T304, T311 nor T319 are running
|
||||
@@ -2691,7 +2757,7 @@ void *rrc_nrue(void *notUsed)
|
||||
rrc->ue_id,
|
||||
ITTI_MSG_NAME(msg_p),
|
||||
NR_RRC_MAC_RA_IND(msg_p).RA_succeeded ? "successful" : "failed");
|
||||
nr_rrc_handle_ra_indication(rrc, NR_RRC_MAC_RA_IND(msg_p).RA_succeeded);
|
||||
nr_rrc_handle_ra_indication(rrc, NR_RRC_MAC_RA_IND(msg_p).RA_succeeded, NR_RRC_MAC_RA_IND(msg_p).gnb_index);
|
||||
break;
|
||||
|
||||
case NR_RRC_MAC_BCCH_DATA_IND:
|
||||
|
||||
@@ -264,7 +264,7 @@ typedef struct NR_UE_RRC_INST_s {
|
||||
// Frame timing received from MAC
|
||||
int current_hfn;
|
||||
int current_frame;
|
||||
|
||||
bool sched_reconfsync_sib1;
|
||||
//Sidelink params
|
||||
NR_SL_PreconfigurationNR_r16_t *sl_preconfig;
|
||||
// NTN params
|
||||
|
||||
@@ -46,9 +46,6 @@ NR_UE_RRC_INST_t* get_NR_UE_rrc_inst(int instance);
|
||||
void init_nsa_message (NR_UE_RRC_INST_t *rrc, char* reconfig_file, char* rbconfig_file);
|
||||
|
||||
void process_nsa_message(NR_UE_RRC_INST_t *rrc, nsa_message_t nsa_message_type, void *message, int msg_len);
|
||||
|
||||
void nr_rrc_cellgroup_configuration(NR_UE_RRC_INST_t *rrc, NR_CellGroupConfig_t *cellGroupConfig, int gNB_index);
|
||||
|
||||
void nr_rrc_going_to_IDLE(NR_UE_RRC_INST_t *rrc,
|
||||
NR_Release_Cause_t release_cause,
|
||||
NR_RRCRelease_t *RRCRelease);
|
||||
|
||||
Reference in New Issue
Block a user