From 7b7f045f1c0639f5d08929f372dcd417efbc9e18 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 15 Jun 2023 09:44:11 +0200 Subject: [PATCH] DU: trigger UE Context Modification Required and handle --- .../NR_MAC_gNB/gNB_scheduler_primitives.c | 22 ++++++++ .../LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 8 +-- openair2/LAYER2/NR_MAC_gNB/mac_proto.h | 2 + .../LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c | 54 +++++++++++++++++-- 4 files changed, 79 insertions(+), 7 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index 19a2641b58..fc161e1e30 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -43,6 +43,7 @@ #include "UTIL/OPT/opt.h" #include "openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h" +#include "F1AP_CauseRadioNetwork.h" #include "RRC/NR/MESSAGES/asn1_msg.h" @@ -2995,3 +2996,24 @@ void nr_mac_check_ul_failure(const gNB_MAC_INST *nrmac, int rnti, NR_UE_sched_ct nrmac->mac_rrc.ue_context_release_request(&request); } } + +void nr_mac_trigger_reconfiguration(const gNB_MAC_INST *nrmac, const NR_UE_info_t *UE) +{ + DevAssert(UE->CellGroup != NULL); + uint8_t buf[2048]; + asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CellGroupConfig, NULL, UE->CellGroup, buf, sizeof(buf)); + AssertFatal(enc_rval.encoded > 0, "ASN1 encoding of CellGroupConfig failed, failed type %s\n", enc_rval.failed_type->name); + du_to_cu_rrc_information_t du2cu = { + .cellGroupConfig = buf, + .cellGroupConfig_length = (enc_rval.encoded + 7) >> 3, + }; + f1_ue_data_t ue_data = du_get_f1_ue_data(UE->rnti); + f1ap_ue_context_modif_required_t required = { + .gNB_CU_ue_id = ue_data.secondary_ue, + .gNB_DU_ue_id = UE->rnti, + .du_to_cu_rrc_information = &du2cu, + .cause = F1AP_CAUSE_RADIO_NETWORK, + .cause_value = F1AP_CauseRadioNetwork_action_desirable_for_radio_reasons, + }; + nrmac->mac_rrc.ue_context_modification_required(&required); +} diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 0bc137f910..18693ac20e 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -225,7 +225,6 @@ static int nr_process_mac_pdu(instance_t module_idP, if (ra->state >= WAIT_Msg3 && ra->rnti == UE->rnti) { ra->crnti = ((pduP[1]&0xFF)<<8)|(pduP[2]&0xFF); ra->state = Msg3_dcch_dtch; - LOG_I(NR_MAC, "Received UL_SCH_LCID_C_RNTI with C-RNTI 0x%04x\n", ra->crnti); break; } } @@ -786,6 +785,7 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP, // Let's abort the current RA, so the UE will trigger a new RA later but using RRCSetupRequest instead. A better solution may be implemented mac_remove_nr_ue(gNB_mac, ra->rnti); nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra); + LOG_W(NR_MAC, "No UE found with C-RNTI %04x, ignoring Msg.3 to have UE come back with new RA attempt\n", ra->crnti); return; } else { // The UE identified by C-RNTI still exists at the gNB @@ -794,9 +794,11 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP, // Reset HARQ processes reset_dl_harq_list(&UE_C->UE_sched_ctrl); reset_ul_harq_list(&UE_C->UE_sched_ctrl); + + // Trigger RRC Reconfiguration + LOG_I(NR_MAC, "Received UL_SCH_LCID_C_RNTI with C-RNTI 0x%04x, triggering RRC Reconfiguration\n", UE_C->rnti); + nr_mac_trigger_reconfiguration(RC.nrmac[gnb_mod_idP], UE_C); } - LOG_I(NR_MAC, "Activating scheduling response to MSG3 with DCCH/DTCCH and RNTI 0x%04x (state %d)\n", - ra->crnti, ra->state); } else { LOG_I(NR_MAC, "Activating scheduling RA-Msg4 for TC_RNTI 0x%04x (state %d)\n", diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index 10ba95928d..4d49dc51db 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -447,4 +447,6 @@ void nr_mac_trigger_ul_failure(NR_UE_sched_ctrl_t *sched_ctrl, NR_SubcarrierSpac void nr_mac_reset_ul_failure(NR_UE_sched_ctrl_t *sched_ctrl); void nr_mac_check_ul_failure(const gNB_MAC_INST *nrmac, int rnti, NR_UE_sched_ctrl_t *sched_ctrl); +void nr_mac_trigger_reconfiguration(const gNB_MAC_INST *nrmac, const NR_UE_info_t *UE); + #endif /*__LAYER2_NR_MAC_PROTO_H__*/ diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c index 7e6df48e38..404eebc3b5 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c @@ -25,6 +25,7 @@ #include "openair2/F1AP/f1ap_ids.h" #include "openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h" #include "openair2/RRC/NR/MESSAGES/asn1_msg.h" +#include "F1AP_CauseRadioNetwork.h" #include "uper_decoder.h" #include "uper_encoder.h" @@ -245,14 +246,59 @@ void ue_context_modification_request(const f1ap_ue_context_modif_req_t *req) void ue_context_modification_confirm(const f1ap_ue_context_modif_confirm_t *confirm) { - (void) confirm; - AssertFatal(false, "%s() not implemented yet\n", __func__); + LOG_I(MAC, "Received UE Context Modification Confirm for UE %04x\n", confirm->gNB_DU_ue_id); + + gNB_MAC_INST *mac = RC.nrmac[0]; + NR_SCHED_LOCK(&mac->sched_lock); + /* check first that the scheduler knows such UE */ + NR_UE_info_t *UE = find_nr_UE(&mac->UE_info, confirm->gNB_DU_ue_id); + if (UE == NULL) { + LOG_E(MAC, "ERROR: unknown UE with RNTI %04x, ignoring UE Context Modification Confirm\n", confirm->gNB_DU_ue_id); + NR_SCHED_UNLOCK(&mac->sched_lock); + return; + } + NR_SCHED_UNLOCK(&mac->sched_lock); + + if (confirm->rrc_container_length > 0) + nr_rlc_srb_recv_sdu(confirm->gNB_DU_ue_id, DCCH, confirm->rrc_container, confirm->rrc_container_length); + + /* nothing else to be done? */ } void ue_context_modification_refuse(const f1ap_ue_context_modif_refuse_t *refuse) { - (void) refuse; - AssertFatal(false, "%s() not implemented yet\n", __func__); + /* Currently, we only use the UE Context Modification Required procedure to + * trigger a RRC reconfigurtion after Msg.3 with C-RNTI MAC CE. If the CU + * refuses, it cannot do this reconfiguration, leaving the UE in an + * unconfigured state. Therefore, we just free all RA-related info, and + * request the release of the UE. */ + LOG_W(MAC, "Received UE Context Modification Refuse for %04x, requesting release\n", refuse->gNB_DU_ue_id); + + gNB_MAC_INST *mac = RC.nrmac[0]; + NR_SCHED_LOCK(&mac->sched_lock); + NR_UE_info_t *UE = find_nr_UE(&RC.nrmac[0]->UE_info, refuse->gNB_DU_ue_id); + if (UE == NULL) { + LOG_E(MAC, "ERROR: unknown UE with RNTI %04x, ignoring UE Context Modification Refuse\n", refuse->gNB_DU_ue_id); + NR_SCHED_UNLOCK(&mac->sched_lock); + return; + } + + const int CC_id = 0; + NR_COMMON_channels_t *cc = &mac->common_channels[CC_id]; + for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) { + NR_RA_t *ra = &cc->ra[i]; + if (ra->crnti == UE->rnti) + nr_clear_ra_proc(0, CC_id, 0 /* frame */, ra); + } + NR_SCHED_UNLOCK(&mac->sched_lock); + + f1ap_ue_context_release_req_t request = { + .gNB_CU_ue_id = refuse->gNB_CU_ue_id, + .gNB_DU_ue_id = refuse->gNB_DU_ue_id, + .cause = F1AP_CAUSE_RADIO_NETWORK, + .cause_value = F1AP_CauseRadioNetwork_procedure_cancelled, + }; + mac->mac_rrc.ue_context_release_request(&request); } void ue_context_release_command(const f1ap_ue_context_release_cmd_t *cmd)