From 85aaf3a0bae47cdaa4551ed4cd6aed3306015330 Mon Sep 17 00:00:00 2001 From: francescomani Date: Fri, 9 Jun 2023 16:42:32 +0200 Subject: [PATCH] upper layers handling of radio link monitoring --- .../nfapi/public_inc/fapi_nr_ue_interface.h | 8 +++ openair1/PHY/NR_UE_TRANSPORT/csi_rx.c | 1 + openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 7 ++- .../SIMULATION/NR_PHY/nr_dummy_functions.c | 4 ++ openair2/COMMON/mac_messages_def.h | 1 + openair2/COMMON/mac_messages_types.h | 10 +++- openair2/LAYER2/NR_MAC_UE/mac_defs.h | 3 - openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 2 - openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c | 25 ++++---- openair2/RRC/NR_UE/L2_interface_ue.c | 10 ++++ openair2/RRC/NR_UE/rrc_UE.c | 32 ++++------ openair2/RRC/NR_UE/rrc_defs.h | 5 ++ openair2/RRC/NR_UE/rrc_proto.h | 9 ++- openair2/RRC/NR_UE/rrc_timers_and_constants.c | 60 +++++++++++++++++++ 14 files changed, 136 insertions(+), 41 deletions(-) diff --git a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h index a425d6b0f5..20cc15dda2 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h @@ -49,6 +49,12 @@ typedef struct { uint32_t sr; } fapi_nr_uci_pdu_rel15_t; +typedef enum { + RLM_no_monitoring = 0, + RLM_out_of_sync = 1, + RLM_in_sync = 2 +} rlm_t; + typedef struct { uint32_t rsrp; int rsrp_dBm; @@ -56,6 +62,7 @@ typedef struct { uint8_t i1; uint8_t i2; uint8_t cqi; + rlm_t radiolink_monitoring; } fapi_nr_csirs_measurements_t; typedef struct { @@ -125,6 +132,7 @@ typedef struct { uint16_t cell_id; uint16_t ssb_start_subcarrier; short rsrp_dBm; + rlm_t radiolink_monitoring; // -1 no monitoring, 0 out_of_sync, 1 in_sync } fapi_nr_ssb_pdu_t; typedef struct { diff --git a/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c b/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c index b38184f453..068e1dacf3 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c +++ b/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c @@ -1006,6 +1006,7 @@ void nr_ue_csi_rs_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, c16_t csirs_measurements.i1 = *i1; csirs_measurements.i2 = *i2; csirs_measurements.cqi = cqi; + csirs_measurements.radiolink_monitoring = RLM_no_monitoring; // TODO do be activated in case of RLM based on CSI-RS nr_downlink_indication_t dl_indication; fapi_nr_rx_indication_t rx_ind = {0}; nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, NULL); diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index 5609f7d608..0a71a1fbae 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -159,15 +159,18 @@ void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind, fapiPbch_t *pbch = (fapiPbch_t *)typeSpecific; memcpy(ssb_pdu->pdu, pbch->decoded_output, sizeof(pbch->decoded_output)); ssb_pdu->additional_bits = pbch->xtra_byte; - ssb_pdu->ssb_index = (frame_parms->ssb_index)&0x7; + ssb_pdu->ssb_index = (frame_parms->ssb_index) & 0x7; ssb_pdu->ssb_length = frame_parms->Lmax; ssb_pdu->cell_id = frame_parms->Nid_cell; ssb_pdu->ssb_start_subcarrier = frame_parms->ssb_start_subcarrier; ssb_pdu->rsrp_dBm = ue->measurements.ssb_rsrp_dBm[frame_parms->ssb_index]; + ssb_pdu->radiolink_monitoring = RLM_in_sync; // TODO to be removed from here ssb_pdu->decoded_pdu = true; } - else + else { + ssb_pdu->radiolink_monitoring = RLM_out_of_sync; // TODO to be removed from here ssb_pdu->decoded_pdu = false; + } } break; case FAPI_NR_CSIRS_IND: diff --git a/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c b/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c index 930e0d3840..dccdce2934 100644 --- a/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c +++ b/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c @@ -28,6 +28,10 @@ int nfapi_nr_p7_message_pack(void *pMessageBuf, void *pPackedBuf, uint32_t packe int nfapi_nr_p7_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen, nfapi_p7_codec_config_t* config) { return 0; } int nfapi_p7_message_header_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen, nfapi_p7_codec_config_t *config) { return 0; } +void nr_mac_rrc_sync_ind(const module_id_t module_id, + const frame_t frame, + const bool in_sync) {} + void rrc_data_ind(const protocol_ctxt_t *const ctxt_pP, const rb_id_t Srb_id, const sdu_size_t sdu_sizeP, diff --git a/openair2/COMMON/mac_messages_def.h b/openair2/COMMON/mac_messages_def.h index eeef0d4494..d4a923b90b 100644 --- a/openair2/COMMON/mac_messages_def.h +++ b/openair2/COMMON/mac_messages_def.h @@ -30,6 +30,7 @@ // Messages between RRC and MAC layers MESSAGE_DEF(RRC_MAC_IN_SYNC_IND, MESSAGE_PRIORITY_MED_PLUS, RrcMacInSyncInd, rrc_mac_in_sync_ind) MESSAGE_DEF(RRC_MAC_OUT_OF_SYNC_IND, MESSAGE_PRIORITY_MED_PLUS, RrcMacOutOfSyncInd, rrc_mac_out_of_sync_ind) +MESSAGE_DEF(NR_RRC_MAC_SYNC_IND, MESSAGE_PRIORITY_MED_PLUS, NRRrcMacSyncInd, nr_rrc_mac_sync_ind) MESSAGE_DEF(RRC_MAC_BCCH_DATA_REQ, MESSAGE_PRIORITY_MED_PLUS, RrcMacBcchDataReq, rrc_mac_bcch_data_req) MESSAGE_DEF(RRC_MAC_BCCH_DATA_IND, MESSAGE_PRIORITY_MED_PLUS, RrcMacBcchDataInd, rrc_mac_bcch_data_ind) diff --git a/openair2/COMMON/mac_messages_types.h b/openair2/COMMON/mac_messages_types.h index 6a671eeb10..fde990b0fe 100644 --- a/openair2/COMMON/mac_messages_types.h +++ b/openair2/COMMON/mac_messages_types.h @@ -36,13 +36,14 @@ // Defines to access message fields. #define RRC_MAC_IN_SYNC_IND(mSGpTR) (mSGpTR)->ittiMsg.rrc_mac_in_sync_ind #define RRC_MAC_OUT_OF_SYNC_IND(mSGpTR) (mSGpTR)->ittiMsg.rrc_mac_out_of_sync_ind +#define NR_RRC_MAC_SYNC_IND(mSGpTR) (mSGpTR)->ittiMsg.nr_rrc_mac_sync_ind #define RRC_MAC_BCCH_DATA_REQ(mSGpTR) (mSGpTR)->ittiMsg.rrc_mac_bcch_data_req #define RRC_MAC_BCCH_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.rrc_mac_bcch_data_ind #define NR_RRC_MAC_BCCH_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.nr_rrc_mac_bcch_data_ind -#define RRC_MAC_BCCH_MBMS_DATA_REQ(mSGpTR) (mSGpTR)->ittiMsg.rrc_mac_bcch_mbms_data_req -#define RRC_MAC_BCCH_MBMS_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.rrc_mac_bcch_mbms_data_ind +#define RRC_MAC_BCCH_MBMS_DATA_REQ(mSGpTR) (mSGpTR)->ittiMsg.rrc_mac_bcch_mbms_data_req +#define RRC_MAC_BCCH_MBMS_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.rrc_mac_bcch_mbms_data_ind #define RRC_MAC_CCCH_DATA_REQ(mSGpTR) (mSGpTR)->ittiMsg.rrc_mac_ccch_data_req #define RRC_MAC_CCCH_DATA_CNF(mSGpTR) (mSGpTR)->ittiMsg.rrc_mac_ccch_data_cnf @@ -72,6 +73,11 @@ typedef struct RrcMacInSyncInd_s { typedef RrcMacInSyncInd RrcMacOutOfSyncInd; +typedef struct NRRrcMacSyncInd_s { + uint32_t frame; + bool in_sync; +} NRRrcMacSyncInd; + typedef struct RrcMacBcchDataReq_s { uint32_t frame; uint32_t sdu_size; diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index 77a0fc8e58..99c7ba6dcd 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -367,12 +367,9 @@ typedef struct { } PUCCH_sched_t; typedef struct { - uint32_t ssb_index; /// SSB RSRP in dBm short ssb_rsrp_dBm; - int consecutive_bch_failures; - } NR_SSB_meas_t; typedef struct NR_UL_TIME_ALIGNMENT { diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 2cc400d2d2..22fbef5614 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -269,8 +269,6 @@ int8_t nr_ue_decode_mib(module_id_t module_id, AssertFatal(mac->mib != NULL, "nr_ue_decode_mib() mac->mib == NULL\n"); - mac->ssb_measurements.consecutive_bch_failures = 0; // resetting decoding failures - uint16_t frame = (mac->mib->systemFrameNumber.buf[0] >> mac->mib->systemFrameNumber.bits_unused); uint16_t frame_number_4lsb = 0; diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c index 1459d97dc6..d4d03d408f 100644 --- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c @@ -1052,14 +1052,6 @@ int handle_bcch_bch(module_id_t module_id, int cc_id, } -void handle_bch_failure(NR_UE_MAC_INST_t *mac) -{ - mac->ssb_measurements.consecutive_bch_failures++; - //TODO handle this properly by scheduling re-synchronization - AssertFatal(mac->ssb_measurements.consecutive_bch_failures < 100, - "Radio link failure caused by 100 consecutive PBCH detection failures.\n"); -} - // L2 Abstraction Layer int handle_bcch_dlsch(module_id_t module_id, int cc_id, unsigned int gNB_index, uint8_t ack_nack, uint8_t *pduP, uint32_t pdu_len){ return nr_ue_decode_BCCH_DL_SCH(module_id, cc_id, gNB_index, ack_nack, pduP, pdu_len); @@ -1098,7 +1090,17 @@ int8_t handle_dlsch(nr_downlink_indication_t *dl_info, int pdu_id) return 0; } -int8_t handle_csirs_measurements(module_id_t module_id, frame_t frame, int slot, fapi_nr_csirs_measurements_t *csirs_measurements) { +void handle_rlm(rlm_t rlm_result, int frame, module_id_t module_id) +{ + if (rlm_result == RLM_no_monitoring) + return; + bool is_sync = rlm_result == RLM_in_sync ? true : false; + nr_mac_rrc_sync_ind(module_id, frame, is_sync); +} + +int8_t handle_csirs_measurements(module_id_t module_id, frame_t frame, int slot, fapi_nr_csirs_measurements_t *csirs_measurements) +{ + handle_rlm(csirs_measurements->radiolink_monitoring, frame, module_id); return nr_ue_process_csirs_measurements(module_id, frame, slot, csirs_measurements); } @@ -1197,6 +1199,9 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info) switch(rx_indication_body.pdu_type){ case FAPI_NR_RX_PDU_TYPE_SSB: + handle_rlm(rx_indication_body.ssb_pdu.radiolink_monitoring, + dl_info->frame, + dl_info->module_id); if(rx_indication_body.ssb_pdu.decoded_pdu) { handle_ssb_meas(mac, rx_indication_body.ssb_pdu.ssb_index, @@ -1209,8 +1214,6 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info) rx_indication_body.ssb_pdu.ssb_start_subcarrier, rx_indication_body.ssb_pdu.cell_id)) << FAPI_NR_RX_PDU_TYPE_SSB; } - else - handle_bch_failure(mac); break; case FAPI_NR_RX_PDU_TYPE_SIB: ret_mask |= (handle_bcch_dlsch(dl_info->module_id, diff --git a/openair2/RRC/NR_UE/L2_interface_ue.c b/openair2/RRC/NR_UE/L2_interface_ue.c index ce0b2ff44b..7222defbe4 100644 --- a/openair2/RRC/NR_UE/L2_interface_ue.c +++ b/openair2/RRC/NR_UE/L2_interface_ue.c @@ -39,6 +39,16 @@ typedef uint32_t channel_t; +void nr_mac_rrc_sync_ind(const module_id_t module_id, + const frame_t frame, + const bool in_sync) +{ + MessageDef *message_p = itti_alloc_new_message(TASK_MAC_UE, 0, NR_RRC_MAC_SYNC_IND); + NR_RRC_MAC_SYNC_IND (message_p).frame = frame; + NR_RRC_MAC_SYNC_IND (message_p).in_sync = in_sync; + itti_send_msg_to_task(TASK_RRC_NRUE, GNB_MODULE_ID_TO_INSTANCE(module_id), message_p); +} + int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, const int CC_id, const uint8_t gNB_index, diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index c8d4403094..9d14f19ece 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -2264,24 +2264,6 @@ nr_rrc_ue_establish_srb2( return 0; } - -void nr_rrc_handle_timers(unsigned int mod_id) -{ - NR_UE_Timers_Constants_t *timers = &NR_UE_rrc_inst[mod_id].timers_and_constants; - // T304 - if (timers->T304_active == true) { - timers->T304_cnt += 10; - if(timers->T304_cnt >= timers->T304_k) { - // TODO - // For T304 of MCG, in case of the handover from NR or intra-NR - // handover, initiate the RRC re-establishment procedure; - // In case of handover to NR, perform the actions defined in the - // specifications applicable for the source RAT. - } - } -} - - void *rrc_nrue_task(void *args_p) { MessageDef *msg_p; @@ -2308,10 +2290,22 @@ void *rrc_nrue_task(void *args_p) LOG_D(NR_RRC, "[UE %d] Received %s\n", ue_mod_id, ITTI_MSG_NAME (msg_p)); break; + case NR_RRC_MAC_SYNC_IND: + LOG_D(NR_RRC, "[UE %d] Received %s: frame %d\n", + ue_mod_id, + ITTI_MSG_NAME (msg_p), + NR_RRC_MAC_SYNC_IND (msg_p).frame); + nr_sync_msg_t sync_msg = NR_RRC_MAC_SYNC_IND (msg_p).in_sync ? + IN_SYNC : OUT_OF_SYNC; + NR_UE_Timers_Constants_t *tac = &NR_UE_rrc_inst[ue_mod_id].timers_and_constants; + handle_rlf_sync(tac, sync_msg); + break; + case NRRRC_SLOT_PROCESS: LOG_D(NR_RRC, "[UE %d] Receided %s: frame %d slot %d\n", ue_mod_id, ITTI_MSG_NAME (msg_p), NRRRC_SLOT_PROCESS (msg_p).frame, NRRRC_SLOT_PROCESS (msg_p).slot); - nr_rrc_handle_timers(ue_mod_id); + NR_UE_Timers_Constants_t *timers = &NR_UE_rrc_inst[ue_mod_id].timers_and_constants; + nr_rrc_handle_timers(timers); break; case NR_RRC_MAC_BCCH_DATA_IND: diff --git a/openair2/RRC/NR_UE/rrc_defs.h b/openair2/RRC/NR_UE/rrc_defs.h index 996069ad68..28d3c52cef 100644 --- a/openair2/RRC/NR_UE/rrc_defs.h +++ b/openair2/RRC/NR_UE/rrc_defs.h @@ -182,6 +182,11 @@ typedef struct NR_UE_Timers_Constants_s { uint32_t T319_k; } NR_UE_Timers_Constants_t; +typedef enum { + OUT_OF_SYNC = 0, + IN_SYNC = 1 +} nr_sync_msg_t; + typedef struct NR_UE_RRC_INST_s { NR_MeasConfig_t *meas_config; diff --git a/openair2/RRC/NR_UE/rrc_proto.h b/openair2/RRC/NR_UE/rrc_proto.h index 418c71240c..f303d809fe 100644 --- a/openair2/RRC/NR_UE/rrc_proto.h +++ b/openair2/RRC/NR_UE/rrc_proto.h @@ -113,6 +113,10 @@ int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, const uint8_t* pduP, const sdu_size_t pdu_len); +void nr_mac_rrc_sync_ind(const module_id_t module_id, + const frame_t frame, + const bool in_sync); + /**\brief \param module_id module id \param CC_id component carrier id @@ -133,8 +137,7 @@ int8_t nr_rrc_RA_succeeded(const module_id_t mod_id, const uint8_t gNB_index); \param void *args_p Pointer on arguments to start the task. */ void *rrc_nrue_task(void *args_p); -/**\brief RRC timers update at UE. */ -void *nr_rrc_timers_update(); +void nr_rrc_handle_timers(NR_UE_Timers_Constants_t *timers); /**\brief RRC NSA UE task. \param void *args_p Pointer on arguments to start the task. */ @@ -162,6 +165,8 @@ void reset_rlf_timers_and_constants(NR_UE_Timers_Constants_t *tac); void set_default_timers_and_constants(NR_UE_Timers_Constants_t *tac); void nr_rrc_set_sib1_timers_and_constants(NR_UE_Timers_Constants_t *tac, NR_SIB1_t *sib1); void nr_rrc_set_T304(NR_UE_Timers_Constants_t *tac, NR_ReconfigurationWithSync_t *reconfigurationWithSync); +void handle_rlf_sync(NR_UE_Timers_Constants_t *tac, + nr_sync_msg_t sync_msg); void nr_rrc_handle_SetupRelease_RLF_TimersAndConstants(NR_UE_RRC_INST_t *rrc, struct NR_SetupRelease_RLF_TimersAndConstants *rlf_TimersAndConstants); diff --git a/openair2/RRC/NR_UE/rrc_timers_and_constants.c b/openair2/RRC/NR_UE/rrc_timers_and_constants.c index f9fc11095b..50c2240339 100644 --- a/openair2/RRC/NR_UE/rrc_timers_and_constants.c +++ b/openair2/RRC/NR_UE/rrc_timers_and_constants.c @@ -21,6 +21,29 @@ #include "openair2/RRC/NR_UE/rrc_proto.h" +void nr_rrc_handle_timers(NR_UE_Timers_Constants_t *timers) +{ + // T304 + if (timers->T304_active == true) { + timers->T304_cnt += 10; + if(timers->T304_cnt >= timers->T304_k) { + // TODO + // For T304 of MCG, in case of the handover from NR or intra-NR + // handover, initiate the RRC re-establishment procedure; + // In case of handover to NR, perform the actions defined in the + // specifications applicable for the source RAT. + } + } + if (timers->T310_active == true) { + timers->T310_cnt += 10; + if(timers->T310_cnt >= timers->T310_k) { + // TODO + // handle detection of radio link failure + // as described in 5.3.10.3 of 38.331 + AssertFatal(false, "Radio link failure! Not handled yet!\n"); + } + } +} void nr_rrc_set_T304(NR_UE_Timers_Constants_t *tac, NR_ReconfigurationWithSync_t *reconfigurationWithSync) { @@ -402,6 +425,43 @@ void nr_rrc_handle_SetupRelease_RLF_TimersAndConstants(NR_UE_RRC_INST_t *rrc, } } +void handle_rlf_sync(NR_UE_Timers_Constants_t *tac, + nr_sync_msg_t sync_msg) +{ + if (sync_msg == IN_SYNC) { + tac->N310_cnt = 0; + if (tac->T310_active) { + tac->N311_cnt++; + // Upon receiving N311 consecutive "in-sync" indications + if (tac->N311_cnt >= tac->N311_k) { + // stop timer T310 + tac->T310_active = false; + tac->T310_cnt = 0; + tac->N311_cnt = 0; + } + } + } + else { + // OUT_OF_SYNC + tac->N311_cnt = 0; + if(tac->T300_active || + tac->T301_active || + tac->T304_active || + tac->T310_active || + tac->T311_active || + tac->T319_active) + return; + tac->N310_cnt++; + // upon receiving N310 consecutive "out-of-sync" indications + if (tac->N310_cnt >= tac->N310_k) { + // start timer T310 + tac->T310_active = true; + tac->T310_cnt = 0; + tac->N310_cnt = 0; + } + } +} + void set_default_timers_and_constants(NR_UE_Timers_Constants_t *tac) { // 38.331 9.2.3 Default values timers and constants