reestablishment initiation
This commit is contained in:
@@ -1355,21 +1355,40 @@ static void configure_common_BWP_ul(NR_UE_MAC_INST_t *mac, int bwp_id, NR_BWP_Up
|
||||
}
|
||||
|
||||
void nr_rrc_mac_config_req_reset(module_id_t module_id,
|
||||
NR_UE_MAC_reset_cause_t reset_cause)
|
||||
NR_UE_MAC_reset_cause_t cause)
|
||||
{
|
||||
NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
|
||||
reset_mac_inst(mac);
|
||||
reset_ra(&mac->ra);
|
||||
release_mac_configuration(mac);
|
||||
nr_ue_init_mac(mac);
|
||||
|
||||
// Sending to PHY a request to resync
|
||||
// with no target cell ID
|
||||
if (reset_cause != DETACH) {
|
||||
mac->synch_request.Mod_id = module_id;
|
||||
mac->synch_request.CC_id = 0;
|
||||
mac->synch_request.synch_req.target_Nid_cell = -1;
|
||||
mac->if_module->synch_request(&mac->synch_request);
|
||||
switch (cause) {
|
||||
case GO_TO_IDLE:
|
||||
reset_ra(&mac->ra);
|
||||
release_mac_configuration(mac, cause);
|
||||
nr_ue_init_mac(mac);
|
||||
nr_ue_mac_default_configs(mac);
|
||||
// new sync but no target cell id -> -1
|
||||
nr_ue_send_synch_request(mac, module_id, 0, -1);
|
||||
break;
|
||||
case DETACH:
|
||||
reset_ra(&mac->ra);
|
||||
reset_mac_inst(mac);
|
||||
nr_ue_reset_sync_state(mac);
|
||||
release_mac_configuration(mac, cause);
|
||||
break;
|
||||
case T300_EXPIRY:
|
||||
reset_mac_inst(mac);
|
||||
reset_ra(&mac->ra);
|
||||
mac->state = UE_SYNC; // still in sync but need to restart RA
|
||||
break;
|
||||
case RE_ESTABLISHMENT:
|
||||
reset_mac_inst(mac);
|
||||
nr_ue_mac_default_configs(mac);
|
||||
nr_ue_reset_sync_state(mac);
|
||||
release_mac_configuration(mac, cause);
|
||||
// new sync with old cell ID (re-establishment on the same cell)
|
||||
nr_ue_send_synch_request(mac, module_id, 0, mac->physCellId);
|
||||
break;
|
||||
default:
|
||||
AssertFatal(false, "Invalid MAC reset cause %d\n", cause);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -205,7 +205,8 @@ NR_UE_MAC_INST_t *get_mac_inst(module_id_t module_id);
|
||||
|
||||
void reset_mac_inst(NR_UE_MAC_INST_t *nr_mac);
|
||||
void reset_ra(RA_config_t *ra);
|
||||
void release_mac_configuration(NR_UE_MAC_INST_t *mac);
|
||||
void release_mac_configuration(NR_UE_MAC_INST_t *mac,
|
||||
NR_UE_MAC_reset_cause_t cause);
|
||||
|
||||
/**\brief called at each slot, slot length based on numerology. now use u=0, scs=15kHz, slot=1ms
|
||||
performs BSR/SR/PHR procedures, random access procedure handler and DLSCH/ULSCH procedures.
|
||||
@@ -450,6 +451,9 @@ void nr_get_prach_resources(NR_UE_MAC_INST_t *mac,
|
||||
void prepare_msg4_feedback(NR_UE_MAC_INST_t *mac, int pid, int ack_nack);
|
||||
void configure_initial_pucch(PUCCH_sched_t *pucch, int res_ind);
|
||||
|
||||
void nr_ue_reset_sync_state(NR_UE_MAC_INST_t *mac);
|
||||
void nr_ue_send_synch_request(NR_UE_MAC_INST_t *mac, module_id_t module_id, int cc_id, int cell_id);
|
||||
|
||||
void init_RA(NR_UE_MAC_INST_t *mac,
|
||||
NR_PRACH_RESOURCES_t *prach_resources,
|
||||
NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon,
|
||||
|
||||
@@ -56,12 +56,11 @@ 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);
|
||||
mac->first_sync_frame = -1;
|
||||
nr_ue_reset_sync_state(mac);
|
||||
mac->get_sib1 = false;
|
||||
mac->get_otherSI = false;
|
||||
mac->phy_config_request_sent = false;
|
||||
memset(&mac->phy_config, 0, sizeof(mac->phy_config));
|
||||
mac->state = UE_NOT_SYNC;
|
||||
mac->si_window_start = -1;
|
||||
mac->servCellIndex = 0;
|
||||
mac->harq_ACK_SpatialBundlingPUCCH = false;
|
||||
@@ -69,6 +68,9 @@ void nr_ue_init_mac(NR_UE_MAC_INST_t *mac)
|
||||
mac->uecap_maxMIMO_PDSCH_layers = 0;
|
||||
mac->uecap_maxMIMO_PUSCH_layers_cb = 0;
|
||||
mac->uecap_maxMIMO_PUSCH_layers_nocb = 0;
|
||||
mac->p_Max = INT_MIN;
|
||||
mac->p_Max_alt = INT_MIN;
|
||||
reset_mac_inst(mac);
|
||||
|
||||
memset(&mac->ssb_measurements, 0, sizeof(mac->ssb_measurements));
|
||||
memset(&mac->ul_time_alignment, 0, sizeof(mac->ul_time_alignment));
|
||||
@@ -76,35 +78,32 @@ void nr_ue_init_mac(NR_UE_MAC_INST_t *mac)
|
||||
memset(&mac->ssb_list[i], 0, sizeof(mac->ssb_list[i]));
|
||||
memset(&mac->prach_assoc_pattern[i], 0, sizeof(mac->prach_assoc_pattern[i]));
|
||||
}
|
||||
for (int k = 0; k < NR_MAX_HARQ_PROCESSES; k++) {
|
||||
mac->ul_harq_info[k].last_ndi = -1; // initialize to invalid value
|
||||
mac->dl_harq_info[k].last_ndi = -1; // initialize to invalid value
|
||||
}
|
||||
}
|
||||
|
||||
void nr_ue_mac_default_configs(NR_UE_MAC_INST_t *mac)
|
||||
{
|
||||
// default values as defined in 38.331 sec 9.2.2
|
||||
mac->scheduling_info.retxBSR_Timer = NR_BSR_Config__retxBSR_Timer_sf10240;
|
||||
mac->scheduling_info.periodicBSR_Timer = NR_BSR_Config__periodicBSR_Timer_infinity;
|
||||
mac->scheduling_info.SR_COUNTER = 0;
|
||||
mac->scheduling_info.SR_pending = 0;
|
||||
mac->scheduling_info.sr_ProhibitTimer = 0;
|
||||
mac->scheduling_info.sr_ProhibitTimer_Running = 0;
|
||||
mac->scheduling_info.sr_id = -1; // invalid init value
|
||||
mac->scheduling_info.retxBSR_Timer = NR_BSR_Config__retxBSR_Timer_sf80;
|
||||
mac->scheduling_info.periodicBSR_Timer = NR_BSR_Config__periodicBSR_Timer_sf10;
|
||||
mac->scheduling_info.periodicPHR_Timer = NR_PHR_Config__phr_PeriodicTimer_sf10;
|
||||
mac->scheduling_info.prohibitPHR_Timer = NR_PHR_Config__phr_ProhibitTimer_sf10;
|
||||
}
|
||||
|
||||
// set init value 0xFFFF, make sure periodic timer and retx time counters are NOT active, after bsr transmission set the value
|
||||
// configured by the NW.
|
||||
mac->scheduling_info.periodicBSR_SF = NR_MAC_UE_BSR_TIMER_NOT_RUNNING;
|
||||
mac->scheduling_info.retxBSR_SF = NR_MAC_UE_BSR_TIMER_NOT_RUNNING;
|
||||
mac->BSR_reporting_active = NR_BSR_TRIGGER_NONE;
|
||||
void nr_ue_send_synch_request(NR_UE_MAC_INST_t *mac, module_id_t module_id, int cc_id, int cell_id)
|
||||
{
|
||||
// Sending to PHY a request to resync
|
||||
mac->synch_request.Mod_id = module_id;
|
||||
mac->synch_request.CC_id = cc_id;
|
||||
mac->synch_request.synch_req.target_Nid_cell = cell_id;
|
||||
mac->if_module->synch_request(&mac->synch_request);
|
||||
}
|
||||
|
||||
for (int i = 0; i < NR_MAX_NUM_LCID; i++) {
|
||||
LOG_D(NR_MAC, "Applying default logical channel config for LCGID %d\n", i);
|
||||
mac->scheduling_info.lc_sched_info[i].LCID_buffer_with_data = false;
|
||||
mac->scheduling_info.lc_sched_info[i].LCID_buffer_remain = 0;
|
||||
mac->scheduling_info.lc_sched_info[i].Bj = 0;
|
||||
}
|
||||
void nr_ue_reset_sync_state(NR_UE_MAC_INST_t *mac)
|
||||
{
|
||||
// reset synchornization status
|
||||
mac->first_sync_frame = -1;
|
||||
mac->state = UE_NOT_SYNC;
|
||||
mac->ra.ra_state = RA_UE_IDLE;
|
||||
}
|
||||
|
||||
NR_UE_MAC_INST_t *nr_l2_init_ue(int nb_inst)
|
||||
@@ -144,14 +143,16 @@ void reset_mac_inst(NR_UE_MAC_INST_t *nr_mac)
|
||||
{
|
||||
// MAC reset according to 38.321 Section 5.12
|
||||
|
||||
nr_ue_mac_default_configs(nr_mac);
|
||||
|
||||
// initialize Bj for each logical channel to zero
|
||||
for (int i = 0; i < NR_MAX_NUM_LCID; i++)
|
||||
// TODO reset also other status variables of LC, is this ok?
|
||||
for (int i = 0; i < NR_MAX_NUM_LCID; i++) {
|
||||
nr_mac->scheduling_info.lc_sched_info[i].Bj = 0;
|
||||
nr_mac->scheduling_info.lc_sched_info[i].LCID_buffer_with_data = false;
|
||||
nr_mac->scheduling_info.lc_sched_info[i].LCID_buffer_remain = 0;
|
||||
}
|
||||
|
||||
// stop all running timers
|
||||
// TODO
|
||||
// TODO stop all running timers
|
||||
nr_timer_stop(&nr_mac->ra.contention_resolution_timer);
|
||||
|
||||
// consider all timeAlignmentTimers as expired and perform the corresponding actions in clause 5.2
|
||||
// TODO
|
||||
@@ -171,10 +172,16 @@ void reset_mac_inst(NR_UE_MAC_INST_t *nr_mac)
|
||||
free_and_zero(nr_mac->ra.Msg3_buffer);
|
||||
|
||||
// cancel any triggered Scheduling Request procedure
|
||||
// Done in default config
|
||||
nr_mac->scheduling_info.SR_COUNTER = 0;
|
||||
nr_mac->scheduling_info.SR_pending = 0;
|
||||
nr_mac->scheduling_info.sr_ProhibitTimer = 0;
|
||||
nr_mac->scheduling_info.sr_ProhibitTimer_Running = 0;
|
||||
nr_mac->scheduling_info.sr_id = -1; // invalid init value
|
||||
|
||||
// cancel any triggered Buffer Status Reporting procedure
|
||||
// Done in default config
|
||||
nr_mac->scheduling_info.periodicBSR_SF = NR_MAC_UE_BSR_TIMER_NOT_RUNNING;
|
||||
nr_mac->scheduling_info.retxBSR_SF = NR_MAC_UE_BSR_TIMER_NOT_RUNNING;
|
||||
nr_mac->BSR_reporting_active = NR_BSR_TRIGGER_NONE;
|
||||
|
||||
// cancel any triggered Power Headroom Reporting procedure
|
||||
// TODO PHR not implemented yet
|
||||
@@ -194,12 +201,24 @@ void reset_mac_inst(NR_UE_MAC_INST_t *nr_mac)
|
||||
// TODO beam failure procedure not implemented
|
||||
}
|
||||
|
||||
void release_mac_configuration(NR_UE_MAC_INST_t *mac)
|
||||
void release_mac_configuration(NR_UE_MAC_INST_t *mac,
|
||||
NR_UE_MAC_reset_cause_t cause)
|
||||
{
|
||||
asn1cFreeStruc(asn_DEF_NR_MIB, mac->mib);
|
||||
asn1cFreeStruc(asn_DEF_NR_SI_SchedulingInfo, mac->si_SchedulingInfo);
|
||||
asn1cFreeStruc(asn_DEF_NR_TDD_UL_DL_ConfigCommon, mac->tdd_UL_DL_ConfigurationCommon);
|
||||
NR_UE_ServingCell_Info_t *sc = &mac->sc_info;
|
||||
// if cause is Re-establishment, release spCellConfig only
|
||||
if (cause == GO_TO_IDLE) {
|
||||
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);
|
||||
asn1cFreeStruc(asn_DEF_NR_TDD_UL_DL_ConfigCommon, mac->tdd_UL_DL_ConfigurationCommon);
|
||||
for (int i = 0; i < mac->lc_ordered_list.count; i++) {
|
||||
nr_lcordered_info_t *lc_info = mac->lc_ordered_list.array[i];
|
||||
asn_sequence_del(&mac->lc_ordered_list, i, 0);
|
||||
free(lc_info);
|
||||
}
|
||||
}
|
||||
|
||||
asn1cFreeStruc(asn_DEF_NR_CrossCarrierSchedulingConfig, sc->crossCarrierSchedulingConfig);
|
||||
asn1cFreeStruc(asn_DEF_NR_SRS_CarrierSwitching, sc->carrierSwitching);
|
||||
asn1cFreeStruc(asn_DEF_NR_UplinkConfig, sc->supplementaryUplink);
|
||||
@@ -218,20 +237,35 @@ void release_mac_configuration(NR_UE_MAC_INST_t *mac)
|
||||
mac->current_DL_BWP = NULL;
|
||||
mac->current_UL_BWP = NULL;
|
||||
|
||||
for (int i = 0; i < mac->dl_BWPs.count; i++)
|
||||
release_dl_BWP(mac, i);
|
||||
for (int i = 0; i < mac->ul_BWPs.count; i++)
|
||||
release_ul_BWP(mac, i);
|
||||
|
||||
asn1cFreeStruc(asn_DEF_NR_SearchSpace, mac->search_space_zero);
|
||||
asn1cFreeStruc(asn_DEF_NR_ControlResourceSet, mac->coreset0);
|
||||
|
||||
for (int i = 0; i < mac->lc_ordered_list.count; i++) {
|
||||
nr_lcordered_info_t *lc_info = mac->lc_ordered_list.array[i];
|
||||
asn_sequence_del(&mac->lc_ordered_list, i, 0);
|
||||
free(lc_info);
|
||||
// in case of re-establishment we don't need to release initial BWP config common
|
||||
int first_bwp_rel = 0; // first BWP to release
|
||||
if (cause == RE_ESTABLISHMENT) {
|
||||
first_bwp_rel = 1;
|
||||
// release dedicated BWP0 config
|
||||
NR_UE_DL_BWP_t *bwp = mac->dl_BWPs.array[0];
|
||||
NR_BWP_PDCCH_t *pdcch = &mac->config_BWP_PDCCH[0];
|
||||
for (int i = 0; pdcch->list_Coreset.count; i++)
|
||||
asn_sequence_del(&pdcch->list_Coreset, i, 1);
|
||||
for (int i = 0; pdcch->list_SS.count; i++)
|
||||
asn_sequence_del(&pdcch->list_SS, i, 1);
|
||||
asn1cFreeStruc(asn_DEF_NR_PDSCH_Config, bwp->pdsch_Config);
|
||||
NR_UE_UL_BWP_t *ubwp = mac->ul_BWPs.array[0];
|
||||
asn1cFreeStruc(asn_DEF_NR_PUCCH_Config, ubwp->pucch_Config);
|
||||
asn1cFreeStruc(asn_DEF_NR_SRS_Config, ubwp->srs_Config);
|
||||
asn1cFreeStruc(asn_DEF_NR_PUSCH_Config, ubwp->pusch_Config);
|
||||
mac->current_DL_BWP = bwp;
|
||||
mac->current_UL_BWP = ubwp;
|
||||
mac->sc_info.initial_dl_BWPSize = bwp->BWPSize;
|
||||
mac->sc_info.initial_dl_BWPStart = bwp->BWPStart;
|
||||
mac->sc_info.initial_ul_BWPSize = ubwp->BWPSize;
|
||||
mac->sc_info.initial_ul_BWPStart = ubwp->BWPStart;
|
||||
}
|
||||
|
||||
for (int i = first_bwp_rel; i < mac->dl_BWPs.count; i++)
|
||||
release_dl_BWP(mac, i);
|
||||
for (int i = first_bwp_rel; i < mac->ul_BWPs.count; i++)
|
||||
release_ul_BWP(mac, i);
|
||||
|
||||
memset(&mac->ssb_measurements, 0, sizeof(mac->ssb_measurements));
|
||||
memset(&mac->csirs_measurements, 0, sizeof(mac->csirs_measurements));
|
||||
memset(&mac->ul_time_alignment, 0, sizeof(mac->ul_time_alignment));
|
||||
|
||||
@@ -1601,6 +1601,45 @@ static void nr_rrc_ue_process_ueCapabilityEnquiry(NR_UE_RRC_INST_t *rrc, NR_UECa
|
||||
}
|
||||
}
|
||||
|
||||
void nr_rrc_initiate_rrcReestablishment(NR_UE_RRC_INST_t *rrc,
|
||||
const int gnb_id)
|
||||
{
|
||||
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);
|
||||
|
||||
// stop timer T310, if running
|
||||
nr_timer_stop(&timers->T310);
|
||||
// stop timer T304, if running
|
||||
nr_timer_stop(&timers->T304);
|
||||
// start timer T311
|
||||
nr_timer_start(&timers->T311);
|
||||
// suspend all RBs, except SRB0
|
||||
for (int i = 1; i < 4; i++) {
|
||||
if (rrc->Srb[i] == RB_ESTABLISHED) {
|
||||
rrc->Srb[i] = RB_SUSPENDED;
|
||||
nr_pdcp_suspend_srb(rrc->ue_id, i);
|
||||
}
|
||||
}
|
||||
for (int i = 1; i <= MAX_DRBS_PER_UE; i++) {
|
||||
if (get_DRB_status(rrc, i) == RB_ESTABLISHED) {
|
||||
set_DRB_status(rrc, i, RB_SUSPENDED);
|
||||
nr_pdcp_suspend_drb(rrc->ue_id, i);
|
||||
}
|
||||
}
|
||||
// release the MCG SCell(s), if configured
|
||||
// no SCell configured in our implementation
|
||||
rrc->nrRrcState = RRC_STATE_REESTABLISHMENT;
|
||||
|
||||
// reset MAC
|
||||
// release spCellConfig, if configured
|
||||
// perform cell selection in accordance with the cell selection process
|
||||
nr_rrc_mac_config_req_reset(rrc->ue_id, RE_ESTABLISHMENT);
|
||||
}
|
||||
|
||||
static void nr_rrc_ue_generate_rrcReestablishmentComplete(NR_RRCReestablishment_t *rrcReestablishment)
|
||||
{
|
||||
uint8_t buffer[RRC_BUFFER_SIZE] = {0};
|
||||
|
||||
@@ -85,8 +85,7 @@ typedef enum Rrc_State_NR_e {
|
||||
RRC_STATE_INACTIVE_NR,
|
||||
RRC_STATE_CONNECTED_NR,
|
||||
RRC_STATE_DETACH_NR,
|
||||
RRC_STATE_FIRST_NR = RRC_STATE_IDLE_NR,
|
||||
RRC_STATE_LAST_NR = RRC_STATE_CONNECTED_NR,
|
||||
RRC_STATE_REESTABLISHMENT
|
||||
} Rrc_State_NR_t;
|
||||
|
||||
typedef enum requested_SI_List_e {
|
||||
|
||||
@@ -87,6 +87,7 @@ void nr_rrc_going_to_IDLE(NR_UE_RRC_INST_t *rrc,
|
||||
|
||||
void nr_mac_rrc_ra_ind(const module_id_t mod_id, int frame, bool success);
|
||||
void nr_mac_rrc_msg3_ind(const module_id_t mod_id, const int rnti);
|
||||
void set_rlf_sib1_timers_and_constants(NR_UE_Timers_Constants_t *tac, NR_SIB1_t *sib1);
|
||||
|
||||
/**\brief RRC UE task.
|
||||
\param void *args_p Pointer on arguments to start the task. */
|
||||
|
||||
Reference in New Issue
Block a user