From da26eacfd49ba39cedd902e1a5d1832097831ae9 Mon Sep 17 00:00:00 2001 From: francescomani Date: Sat, 6 Apr 2024 09:39:58 +0200 Subject: [PATCH] improvements in handling RRC Release --- openair2/RRC/NR_UE/rrc_UE.c | 51 ++++++++++++++++--- openair2/RRC/NR_UE/rrc_defs.h | 9 ++-- openair2/RRC/NR_UE/rrc_proto.h | 2 +- openair2/RRC/NR_UE/rrc_timers_and_constants.c | 4 ++ 4 files changed, 55 insertions(+), 11 deletions(-) diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 6442594eef..71cd78ea31 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -1623,15 +1623,14 @@ static int nr_rrc_ue_decode_dcch(NR_UE_RRC_INST_t *rrc, } break; case NR_DL_DCCH_MessageType__c1_PR_rrcResume: - LOG_I(NR_RRC, "Received rrcResume on DL-DCCH-Message\n"); + LOG_E(NR_RRC, "Received rrcResume on DL-DCCH-Message -> Not handled\n"); break; case NR_DL_DCCH_MessageType__c1_PR_rrcRelease: LOG_I(NR_RRC, "[UE %ld] Received RRC Release (gNB %d)\n", rrc->ue_id, gNB_indexP); - // TODO properly implement procedures in 5.3.8.3 of 38.331 - NR_Release_Cause_t cause = OTHER; - if (rrc->detach_after_release) - rrc->nrRrcState = RRC_STATE_DETACH_NR; - nr_rrc_going_to_IDLE(rrc, cause, dl_dcch_msg->message.choice.c1->choice.rrcRelease); + // delay the actions 60 ms from the moment the RRCRelease message was received + UPDATE_IE(rrc->RRCRelease, dl_dcch_msg->message.choice.c1->choice.rrcRelease, NR_RRCRelease_t); + nr_timer_setup(&rrc->release_timer, 60, 10); // 10ms step + nr_timer_start(&rrc->release_timer); break; case NR_DL_DCCH_MessageType__c1_PR_ueCapabilityEnquiry: @@ -2136,6 +2135,46 @@ static void process_lte_nsa_msg(NR_UE_RRC_INST_t *rrc, nsa_msg_t *msg, int msg_l } } +void handle_RRCRelease(NR_UE_RRC_INST_t *rrc) +{ + NR_UE_Timers_Constants_t *tac = &rrc->timers_and_constants; + // stop timer T380, if running + nr_timer_stop(&tac->T380); + // stop timer T320, if running + nr_timer_stop(&tac->T320); + if (rrc->detach_after_release) + rrc->nrRrcState = RRC_STATE_DETACH_NR; + const struct NR_RRCRelease_IEs *rrcReleaseIEs = rrc->RRCRelease ? rrc->RRCRelease->criticalExtensions.choice.rrcRelease : NULL; + if (!rrc->as_security_activated) { + // ignore any field included in RRCRelease message except waitTime + // 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 cause = OTHER; + nr_rrc_going_to_IDLE(rrc, cause, rrc->RRCRelease); + asn1cFreeStruc(asn_DEF_NR_RRCRelease, rrc->RRCRelease); + return; + } + bool suspend = false; + if (rrcReleaseIEs) { + if (rrcReleaseIEs->redirectedCarrierInfo) + LOG_E(NR_RRC, "redirectedCarrierInfo in RRCRelease not handled\n"); + if (rrcReleaseIEs->cellReselectionPriorities) + LOG_E(NR_RRC, "cellReselectionPriorities in RRCRelease not handled\n"); + if (rrcReleaseIEs->deprioritisationReq) + LOG_E(NR_RRC, "deprioritisationReq in RRCRelease not handled\n"); + if (rrcReleaseIEs->suspendConfig) { + suspend = true; + // procedures to go in INACTIVE state + AssertFatal(false, "Inactive State not supported\n"); + } + } + if (!suspend) { + NR_Release_Cause_t cause = OTHER; + nr_rrc_going_to_IDLE(rrc, cause, rrc->RRCRelease); + } + asn1cFreeStruc(asn_DEF_NR_RRCRelease, rrc->RRCRelease); +} + void nr_rrc_going_to_IDLE(NR_UE_RRC_INST_t *rrc, NR_Release_Cause_t release_cause, NR_RRCRelease_t *RRCRelease) diff --git a/openair2/RRC/NR_UE/rrc_defs.h b/openair2/RRC/NR_UE/rrc_defs.h index 533b3870f5..c22132767e 100644 --- a/openair2/RRC/NR_UE/rrc_defs.h +++ b/openair2/RRC/NR_UE/rrc_defs.h @@ -159,6 +159,7 @@ typedef struct NR_UE_Timers_Constants_s { NR_timer_t T320; NR_timer_t T321; NR_timer_t T325; + NR_timer_t T380; NR_timer_t T390; // counters uint32_t N310_cnt; @@ -217,10 +218,10 @@ typedef struct NR_UE_RRC_INST_s { long keyToUse; bool as_security_activated; bool detach_after_release; - - long selected_plmn_identity; - Rrc_State_NR_t nrRrcState; - as_nas_info_t initialNasMsg; + NR_timer_t release_timer; + NR_RRCRelease_t *RRCRelease; + long selected_plmn_identity; + Rrc_State_NR_t nrRrcState; //Sidelink params NR_SL_PreconfigurationNR_r16_t *sl_preconfig; diff --git a/openair2/RRC/NR_UE/rrc_proto.h b/openair2/RRC/NR_UE/rrc_proto.h index 556898c304..1de5c19122 100644 --- a/openair2/RRC/NR_UE/rrc_proto.h +++ b/openair2/RRC/NR_UE/rrc_proto.h @@ -86,7 +86,7 @@ void nr_mac_rrc_sync_ind(const module_id_t module_id, void nr_rrc_going_to_IDLE(NR_UE_RRC_INST_t *rrc, NR_Release_Cause_t release_cause, NR_RRCRelease_t *RRCRelease); - +void handle_RRCRelease(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, int gnb_id); void set_rlf_sib1_timers_and_constants(NR_UE_Timers_Constants_t *tac, NR_SIB1_t *sib1); diff --git a/openair2/RRC/NR_UE/rrc_timers_and_constants.c b/openair2/RRC/NR_UE/rrc_timers_and_constants.c index 10f50dbf9b..70a467691b 100644 --- a/openair2/RRC/NR_UE/rrc_timers_and_constants.c +++ b/openair2/RRC/NR_UE/rrc_timers_and_constants.c @@ -119,6 +119,10 @@ void nr_rrc_handle_timers(NR_UE_RRC_INST_t *rrc) { NR_UE_Timers_Constants_t *timers = &rrc->timers_and_constants; + bool release_timer_expired = nr_timer_tick(&rrc->release_timer); + if (release_timer_expired) + handle_RRCRelease(rrc); + bool t300_expired = nr_timer_tick(&timers->T300); if(t300_expired) { LOG_W(NR_RRC, "Timer T300 expired! No timely response to RRCSetupRequest\n");