diff --git a/common/utils/nr/nr_common.c b/common/utils/nr/nr_common.c index 24e04f833a..73f4f89241 100644 --- a/common/utils/nr/nr_common.c +++ b/common/utils/nr/nr_common.c @@ -865,3 +865,44 @@ void nr_est_delay(int ofdm_symbol_size, const c16_t *ls_est, c16_t *ch_estimates delay->delay_max_val = max_val; delay->est_delay = max_pos - sync_pos; } + +void nr_timer_start(NR_timer_t *timer) +{ + timer->active = true; + timer->counter = 0; +} + +void nr_timer_stop(NR_timer_t *timer) +{ + timer->active = false; + timer->counter = 0; +} + +bool is_nr_timer_active(NR_timer_t timer) +{ + return timer.active; +} + +bool nr_timer_tick(NR_timer_t *timer) +{ + bool expired = false; + if (timer->active) { + timer->counter += timer->step; + expired = nr_timer_expired(*timer); + if (expired) + timer->active = false; + } + return expired; +} + +bool nr_timer_expired(NR_timer_t timer) +{ + return (timer.counter >= timer.target); +} + +void nr_timer_setup(NR_timer_t *timer, const uint32_t target, const uint32_t step) +{ + timer->target = target; + timer->step = step; + nr_timer_stop(timer); +} diff --git a/common/utils/nr/nr_common.h b/common/utils/nr/nr_common.h index 3cc3844cc4..671f232928 100644 --- a/common/utils/nr/nr_common.h +++ b/common/utils/nr/nr_common.h @@ -116,6 +116,49 @@ typedef struct { int delay_max_val; } delay_t; +typedef struct { + bool active; + uint32_t counter; + uint32_t target; + uint32_t step; +} NR_timer_t; + +/** + * @brief To start a timer + * @param timer Timer to be started + */ +void nr_timer_start(NR_timer_t *timer); +/** + * @brief To stop a timer + * @param timer Timer to stopped + */ +void nr_timer_stop(NR_timer_t *timer); +/** + * @brief If active, it increases timer counter by an amout of units equal to step. It stops timer if expired + * @param timer Timer to be handled + * @return Indication if the timer is expired or not + */ +bool nr_timer_tick(NR_timer_t *timer); +/** + * @brief To setup a timer + * @param timer Timer to setup + * @param target Target value for timer (when reached, timer is considered expired) + * @param step Amount of units to add to timer counter every tick + */ +void nr_timer_setup(NR_timer_t *timer, const uint32_t target, const uint32_t step); +/** + * @brief To check if a timer is expired + * @param timer Timer to be checked + * @return Indication if the timer is expired or not + */ +bool nr_timer_expired(NR_timer_t timer); +/** + * @brief To check if a timer is active + * @param timer Timer to be checked + * @return Indication if the timer is active or not + */ +bool is_nr_timer_active(NR_timer_t timer); + extern const nr_bandentry_t nr_bandtable[]; static inline int get_num_dmrs(uint16_t dmrs_mask ) { diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index a1391927b6..a38c0fded0 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -33,7 +33,6 @@ #define RRC_UE #define RRC_UE_C -#include "oai_asn1.h" #include "NR_DL-DCCH-Message.h" //asn_DEF_NR_DL_DCCH_Message #include "NR_DL-CCCH-Message.h" //asn_DEF_NR_DL_CCCH_Message #include "NR_BCCH-BCH-Message.h" //asn_DEF_NR_BCCH_BCH_Message @@ -311,9 +310,12 @@ NR_UE_RRC_INST_t* nr_rrc_init_ue(char* uecap_file, int nb_inst) rrc->ra_trigger = RA_NOT_RUNNING; rrc->uecap_file = uecap_file; + memset(&rrc->timers_and_constants, 0, sizeof(rrc->timers_and_constants)); + for (int i = 0; i < NB_CNX_UE; i++) { rrcPerNB_t *ptr = &rrc->perNB[i]; ptr->SInfo = (NR_UE_RRC_SI_INFO){0}; + init_SI_timers(&ptr->SInfo); for (int j = 0; j < NR_NUM_SRB; j++) ptr->Srb[j] = RB_NOT_PRESENT; for (int j = 0; j < MAX_DRBS_PER_UE; j++) @@ -334,57 +336,44 @@ bool check_si_validity(NR_UE_RRC_SI_INFO *SI_info, int si_type) { switch (si_type) { case NR_SIB_TypeInfo__type_sibType2: - if (!SI_info->sib2 || SI_info->sib2_timer == -1) + if (!SI_info->sib2) return false; - break; case NR_SIB_TypeInfo__type_sibType3: - if (!SI_info->sib3 || SI_info->sib3_timer == -1) + if (!SI_info->sib3) return false; - break; case NR_SIB_TypeInfo__type_sibType4: - if (!SI_info->sib4 || SI_info->sib4_timer == -1) + if (!SI_info->sib4) return false; - break; case NR_SIB_TypeInfo__type_sibType5: - if (!SI_info->sib5 || SI_info->sib5_timer == -1) + if (!SI_info->sib5) return false; - break; case NR_SIB_TypeInfo__type_sibType6: - if (!SI_info->sib6 || SI_info->sib6_timer == -1) + if (!SI_info->sib6) return false; - break; case NR_SIB_TypeInfo__type_sibType7: - if (!SI_info->sib7 || SI_info->sib7_timer == -1) + if (!SI_info->sib7) return false; - break; case NR_SIB_TypeInfo__type_sibType8: - if (!SI_info->sib8 || SI_info->sib8_timer == -1) + if (!SI_info->sib8) return false; - break; case NR_SIB_TypeInfo__type_sibType9: - if (!SI_info->sib9 || SI_info->sib9_timer == -1) + if (!SI_info->sib9) return false; - break; case NR_SIB_TypeInfo__type_sibType10_v1610: - if (!SI_info->sib10 || SI_info->sib10_timer == -1) + if (!SI_info->sib10) return false; - break; case NR_SIB_TypeInfo__type_sibType11_v1610: - if (!SI_info->sib11 || SI_info->sib11_timer == -1) + if (!SI_info->sib11) return false; - break; case NR_SIB_TypeInfo__type_sibType12_v1610: - if (!SI_info->sib12 || SI_info->sib12_timer == -1) + if (!SI_info->sib12) return false; - break; case NR_SIB_TypeInfo__type_sibType13_v1610: - if (!SI_info->sib13 || SI_info->sib13_timer == -1) + if (!SI_info->sib13) return false; - break; case NR_SIB_TypeInfo__type_sibType14_v1610: - if (!SI_info->sib14 || SI_info->sib14_timer == -1) + if (!SI_info->sib14) return false; - break; default : AssertFatal(false, "Invalid SIB type %d\n", si_type); } @@ -394,8 +383,7 @@ bool check_si_validity(NR_UE_RRC_SI_INFO *SI_info, int si_type) int check_si_status(NR_UE_RRC_SI_INFO *SI_info) { // schedule reception of SIB1 if RRC doesn't have it - // or if the timer expired - if (!SI_info->sib1 || SI_info->sib1_timer == -1) + if (!SI_info->sib1) return 1; else { if (SI_info->sib1->si_SchedulingInfo) { @@ -471,91 +459,91 @@ static int nr_decode_SI(NR_UE_RRC_SI_INFO *SI_info, NR_SystemInformation_t *si) if(!SI_info->sib2) SI_info->sib2 = calloc(1, sizeof(*SI_info->sib2)); memcpy(SI_info->sib2, typeandinfo->choice.sib2, sizeof(NR_SIB2_t)); - SI_info->sib2_timer = 0; + nr_timer_start(&SI_info->sib2_timer); break; case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib3: if(!SI_info->sib3) SI_info->sib3 = calloc(1, sizeof(*SI_info->sib3)); memcpy(SI_info->sib3, typeandinfo->choice.sib3, sizeof(NR_SIB3_t)); - SI_info->sib3_timer = 0; + nr_timer_start(&SI_info->sib3_timer); break; case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib4: if(!SI_info->sib4) SI_info->sib4 = calloc(1, sizeof(*SI_info->sib4)); memcpy(SI_info->sib4, typeandinfo->choice.sib4, sizeof(NR_SIB4_t)); - SI_info->sib4_timer = 0; + nr_timer_start(&SI_info->sib4_timer); break; case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib5: if(!SI_info->sib5) SI_info->sib5 = calloc(1, sizeof(*SI_info->sib5)); memcpy(SI_info->sib5, typeandinfo->choice.sib5, sizeof(NR_SIB5_t)); - SI_info->sib5_timer = 0; + nr_timer_start(&SI_info->sib5_timer); break; case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib6: if(!SI_info->sib6) SI_info->sib6 = calloc(1, sizeof(*SI_info->sib6)); memcpy(SI_info->sib6, typeandinfo->choice.sib6, sizeof(NR_SIB6_t)); - SI_info->sib6_timer = 0; + nr_timer_start(&SI_info->sib6_timer); break; case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib7: if(!SI_info->sib7) SI_info->sib7 = calloc(1, sizeof(*SI_info->sib7)); memcpy(SI_info->sib7, typeandinfo->choice.sib7, sizeof(NR_SIB7_t)); - SI_info->sib7_timer = 0; + nr_timer_start(&SI_info->sib7_timer); break; case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib8: if(!SI_info->sib8) SI_info->sib8 = calloc(1, sizeof(*SI_info->sib8)); memcpy(SI_info->sib8, typeandinfo->choice.sib8, sizeof(NR_SIB8_t)); - SI_info->sib8_timer = 0; + nr_timer_start(&SI_info->sib8_timer); break; case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib9: if(!SI_info->sib9) SI_info->sib9 = calloc(1, sizeof(*SI_info->sib9)); memcpy(SI_info->sib9, typeandinfo->choice.sib9, sizeof(NR_SIB9_t)); - SI_info->sib9_timer = 0; + nr_timer_start(&SI_info->sib9_timer); break; case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib10_v1610: if(!SI_info->sib10) SI_info->sib10 = calloc(1, sizeof(*SI_info->sib10)); memcpy(SI_info->sib10, typeandinfo->choice.sib10_v1610, sizeof(NR_SIB10_r16_t)); - SI_info->sib10_timer = 0; + nr_timer_start(&SI_info->sib10_timer); break; case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib11_v1610: if(!SI_info->sib11) SI_info->sib11 = calloc(1, sizeof(*SI_info->sib11)); memcpy(SI_info->sib11, typeandinfo->choice.sib11_v1610, sizeof(NR_SIB11_r16_t)); - SI_info->sib11_timer = 0; + nr_timer_start(&SI_info->sib11_timer); break; case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib12_v1610: if(!SI_info->sib12) SI_info->sib12 = calloc(1, sizeof(*SI_info->sib12)); memcpy(SI_info->sib12, typeandinfo->choice.sib12_v1610, sizeof(NR_SIB12_r16_t)); - SI_info->sib12_timer = 0; + nr_timer_start(&SI_info->sib12_timer); break; case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib13_v1610: if(!SI_info->sib13) SI_info->sib13 = calloc(1, sizeof(*SI_info->sib13)); memcpy(SI_info->sib13, typeandinfo->choice.sib13_v1610, sizeof(NR_SIB13_r16_t)); - SI_info->sib13_timer = 0; + nr_timer_start(&SI_info->sib13_timer); break; case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib14_v1610: if(!SI_info->sib14) SI_info->sib14 = calloc(1, sizeof(*SI_info->sib14)); memcpy(SI_info->sib12, typeandinfo->choice.sib14_v1610, sizeof(NR_SIB14_r16_t)); - SI_info->sib14_timer = 0; + nr_timer_start(&SI_info->sib14_timer); break; default: break; @@ -573,7 +561,7 @@ static void nr_rrc_handle_msg3_indication(NR_UE_RRC_INST_t *rrc, rnti_t rnti) rrc->rnti = rnti; // start timer T300 NR_UE_Timers_Constants_t *tac = &rrc->timers_and_constants; - tac->T300_active = true; + nr_timer_start(&tac->T300); break; case RRC_CONNECTION_REESTABLISHMENT: AssertFatal(1==0, "ra_trigger not implemented yet!\n"); @@ -682,7 +670,7 @@ static int8_t nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(NR_UE_RRC_INST_t *rrc, if(g_log->log_component[NR_RRC].level >= OAILOG_DEBUG) xer_fprint(stdout, &asn_DEF_NR_SIB1, (const void *) SI_info->sib1); LOG_A(NR_RRC, "SIB1 decoded\n"); - SI_info->sib1_timer = 0; + nr_timer_start(&SI_info->sib1_timer); if (rrc->nrRrcState == RRC_STATE_IDLE_NR) { rrc->ra_trigger = INITIAL_ACCESS_FROM_RRC_IDLE; // preparing RRC setup request payload in advance @@ -760,13 +748,10 @@ void nr_rrc_cellgroup_configuration(rrcPerNB_t *rrcNB, NR_UE_RRC_INST_t *rrc, NR // with the release cause 'other' upon which the procedure ends // TODO } - if (tac->T310_active) { - tac->T310_active = false; - tac->T310_cnt = 0; - } - nr_rrc_set_T304(&rrc->timers_and_constants, reconfigurationWithSync); - tac->T304_active = true; - tac->T304_cnt = 0; + nr_timer_stop(&tac->T310); + 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; // resume suspended radio bearers for (int i = 0; i < NR_NUM_SRB; i++) { @@ -871,16 +856,12 @@ static void nr_rrc_process_rrcsetup(NR_UE_RRC_INST_t *rrc, // TODO (not handled) if stored, discard the cell reselection priority information provided by // the cellReselectionPriorities or inherited from another RAT - // stop timer T300, T301 or T319 if running; + // stop timer T300, T301, T319, T320 if running; NR_UE_Timers_Constants_t *timers = &rrc->timers_and_constants; - timers->T300_active = false; - timers->T300_cnt = 0; - timers->T301_active = false; - timers->T301_cnt = 0; - timers->T319_active = false; - timers->T319_cnt = 0; - timers->T320_active = false; - timers->T320_cnt = 0; + nr_timer_stop(&timers->T300); + nr_timer_stop(&timers->T301); + nr_timer_stop(&timers->T319); + nr_timer_stop(&timers->T320); // TODO if T390 and T302 are running (not implemented) @@ -1383,10 +1364,9 @@ static int nr_rrc_ue_decode_dcch(NR_UE_RRC_INST_t *rrc, void nr_rrc_handle_ra_indication(NR_UE_RRC_INST_t *rrc, bool ra_succeeded) { NR_UE_Timers_Constants_t *timers = &rrc->timers_and_constants; - if (ra_succeeded && timers->T304_active == true) { + if (ra_succeeded && is_nr_timer_active(timers->T304)) { // successful Random Access procedure triggered by reconfigurationWithSync - timers->T304_active = false; - timers->T304_cnt = 0; + nr_timer_stop(&timers->T304); // TODO handle the rest of procedures as described in 5.3.5.3 for when // reconfigurationWithSync is included in spCellConfig } @@ -1823,11 +1803,11 @@ void nr_rrc_going_to_IDLE(NR_UE_RRC_INST_t *rrc, waitTime = rrcReleaseIEs->nonCriticalExtension ? rrcReleaseIEs->nonCriticalExtension->waitTime : NULL; if (waitTime) { - if (tac->T302_active) - tac->T302_cnt = 0; // stop 302 + nr_timer_stop(&tac->T302); // stop 302 // start timer T302 with the value set to the waitTime - tac->T302_active = true; - tac->T302_k = *waitTime * 1000; // waitTime is in seconds + int target = *waitTime * 1000; // waitTime is in seconds + nr_timer_setup(&tac->T302, target, 10); + nr_timer_start(&tac->T302); // TODO inform upper layers that access barring is applicable // for all access categories except categories '0' and '2'. LOG_E(NR_RRC,"Go to IDLE. Handling RRCRelease message including a waitTime not implemented\n"); @@ -1835,17 +1815,15 @@ void nr_rrc_going_to_IDLE(NR_UE_RRC_INST_t *rrc, } } if (!waitTime) { - if (tac->T302_active) { - tac->T302_cnt = 0; - tac->T302_active = false; + if (is_nr_timer_active(tac->T302)) { + nr_timer_stop(&tac->T302); // TODO barring alleviation as in 5.3.14.4 // not implemented LOG_E(NR_RRC,"Go to IDLE. Barring alleviation not implemented\n"); } } - if (tac->T390_active) { - tac->T390_cnt = 0; - tac->T390_active = false; + if (is_nr_timer_active(tac->T390)) { + nr_timer_stop(&tac->T390); // TODO barring alleviation as in 5.3.14.4 // not implemented LOG_E(NR_RRC,"Go to IDLE. Barring alleviation not implemented\n"); @@ -1853,24 +1831,15 @@ void nr_rrc_going_to_IDLE(NR_UE_RRC_INST_t *rrc, if (!RRCRelease && rrc->nrRrcState == RRC_STATE_INACTIVE_NR) { // TODO discard the cell reselection priority information provided by the cellReselectionPriorities // cell reselection priorities not implemented yet - if (tac->T320_active) { - tac->T320_cnt = 0; - tac->T320_active = false; - } + nr_timer_stop(&tac->T320); } // Stop all the timers except T302, T320 and T325 - tac->T300_active = false; - tac->T300_cnt = 0; - tac->T301_active = false; - tac->T301_cnt = 0; - tac->T304_active = false; - tac->T304_cnt = 0; - tac->T310_active = false; - tac->T310_cnt = 0; - tac->T311_active = false; - tac->T311_cnt = 0; - tac->T319_active = false; - tac->T319_cnt = 0; + nr_timer_stop(&tac->T300); + nr_timer_stop(&tac->T301); + nr_timer_stop(&tac->T304); + nr_timer_stop(&tac->T310); + nr_timer_stop(&tac->T311); + nr_timer_stop(&tac->T319); // discard the UE Inactive AS context // TODO there is no inactive AS context @@ -1909,6 +1878,7 @@ void nr_rrc_going_to_IDLE(NR_UE_RRC_INST_t *rrc, for (int i = 0; i < NB_CNX_UE; i++) { rrcPerNB_t *nb = &rrc->perNB[i]; NR_UE_RRC_SI_INFO *SI_info = &nb->SInfo; + init_SI_timers(SI_info); asn1cFreeStruc(asn_DEF_NR_SIB1, SI_info->sib1); asn1cFreeStruc(asn_DEF_NR_SIB2, SI_info->sib2); asn1cFreeStruc(asn_DEF_NR_SIB3, SI_info->sib3); diff --git a/openair2/RRC/NR_UE/rrc_defs.h b/openair2/RRC/NR_UE/rrc_defs.h index 73f2d0827f..9c2ef2a00a 100644 --- a/openair2/RRC/NR_UE/rrc_defs.h +++ b/openair2/RRC/NR_UE/rrc_defs.h @@ -114,74 +114,53 @@ typedef enum RA_trigger_e { typedef struct UE_RRC_SI_INFO_NR_s { uint32_t default_otherSI_map; NR_SIB1_t *sib1; - int sib1_timer; + NR_timer_t sib1_timer; NR_SIB2_t *sib2; - int sib2_timer; + NR_timer_t sib2_timer; NR_SIB3_t *sib3; - int sib3_timer; + NR_timer_t sib3_timer; NR_SIB4_t *sib4; - int sib4_timer; + NR_timer_t sib4_timer; NR_SIB5_t *sib5; - int sib5_timer; + NR_timer_t sib5_timer; NR_SIB6_t *sib6; - int sib6_timer; + NR_timer_t sib6_timer; NR_SIB7_t *sib7; - int sib7_timer; + NR_timer_t sib7_timer; NR_SIB8_t *sib8; - int sib8_timer; + NR_timer_t sib8_timer; NR_SIB9_t *sib9; - int sib9_timer; + NR_timer_t sib9_timer; NR_SIB10_r16_t *sib10; - int sib10_timer; + NR_timer_t sib10_timer; NR_SIB11_r16_t *sib11; - int sib11_timer; + NR_timer_t sib11_timer; NR_SIB12_r16_t *sib12; - int sib12_timer; + NR_timer_t sib12_timer; NR_SIB13_r16_t *sib13; - int sib13_timer; + NR_timer_t sib13_timer; NR_SIB14_r16_t *sib14; - int sib14_timer; -} __attribute__ ((__packed__)) NR_UE_RRC_SI_INFO; + NR_timer_t sib14_timer; +} NR_UE_RRC_SI_INFO; typedef struct NR_UE_Timers_Constants_s { - // timers status - bool T300_active; - bool T301_active; - bool T302_active; - bool T304_active; - bool T310_active; - bool T311_active; - bool T319_active; - bool T320_active; - bool T325_active; - bool T390_active; // timers - uint32_t T300_cnt; - uint32_t T301_cnt; - uint32_t T302_cnt; - uint32_t T304_cnt; - uint32_t T310_cnt; - uint32_t T311_cnt; - uint32_t T319_cnt; - uint32_t T320_cnt; - uint32_t T325_cnt; - uint32_t T390_cnt; + NR_timer_t T300; + NR_timer_t T301; + NR_timer_t T302; + NR_timer_t T304; + NR_timer_t T310; + NR_timer_t T311; + NR_timer_t T319; + NR_timer_t T320; + NR_timer_t T325; + NR_timer_t T390; // counters uint32_t N310_cnt; uint32_t N311_cnt; // constants (limits configured by the network) uint32_t N310_k; uint32_t N311_k; - uint32_t T300_k; - uint32_t T301_k; - uint32_t T302_k; - uint32_t T304_k; - uint32_t T310_k; - uint32_t T311_k; - uint32_t T319_k; - uint32_t T320_k; - uint32_t T325_k; - uint32_t T390_k; } NR_UE_Timers_Constants_t; typedef enum { diff --git a/openair2/RRC/NR_UE/rrc_proto.h b/openair2/RRC/NR_UE/rrc_proto.h index 1001652037..45fb1a1c0f 100644 --- a/openair2/RRC/NR_UE/rrc_proto.h +++ b/openair2/RRC/NR_UE/rrc_proto.h @@ -33,7 +33,7 @@ #ifndef _RRC_PROTO_H_ #define _RRC_PROTO_H_ - +#include "oai_asn1.h" #include "rrc_defs.h" #include "NR_RRCReconfiguration.h" #include "NR_MeasConfig.h" @@ -108,6 +108,7 @@ extern void start_oai_nrue_threads(void); int get_from_lte_ue_fd(); void nr_rrc_SI_timers(NR_UE_RRC_SI_INFO *SInfo); +void init_SI_timers(NR_UE_RRC_SI_INFO *SInfo); void nr_ue_rrc_timer_trigger(int module_id, int frame, int gnb_id); void handle_t300_expiry(NR_UE_RRC_INST_t *rrc); @@ -115,9 +116,8 @@ void handle_t300_expiry(NR_UE_RRC_INST_t *rrc); 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); +int nr_rrc_get_T304(long t304); +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 c01755e4de..cd5b79640c 100644 --- a/openair2/RRC/NR_UE/rrc_timers_and_constants.c +++ b/openair2/RRC/NR_UE/rrc_timers_and_constants.c @@ -21,80 +21,97 @@ #include "openair2/RRC/NR_UE/rrc_proto.h" -void nr_rrc_SI_timers(NR_UE_RRC_SI_INFO *SInfo) +void init_SI_timers(NR_UE_RRC_SI_INFO *SInfo) { // delete any stored version of a SIB after 3 hours // from the moment it was successfully confirmed as valid - if (SInfo->sib1 && SInfo->sib1_timer >= 0) { - SInfo->sib1_timer += 10; - if (SInfo->sib1_timer > 10800000) - SInfo->sib1_timer = -1; - } - if (SInfo->sib2 && SInfo->sib2_timer >= 0) { - SInfo->sib2_timer += 10; - if (SInfo->sib2_timer > 10800000) - SInfo->sib2_timer = -1; - } - if (SInfo->sib3 && SInfo->sib3_timer >= 0) { - SInfo->sib3_timer += 10; - if (SInfo->sib3_timer > 10800000) - SInfo->sib3_timer = -1; - } - if (SInfo->sib4 && SInfo->sib4_timer >= 0) { - SInfo->sib4_timer += 10; - if (SInfo->sib4_timer > 10800000) - SInfo->sib4_timer = -1; - } - if (SInfo->sib5 && SInfo->sib5_timer >= 0) { - SInfo->sib5_timer += 10; - if (SInfo->sib5_timer > 10800000) - SInfo->sib5_timer = -1; - } - if (SInfo->sib6 && SInfo->sib6_timer >= 0) { - SInfo->sib6_timer += 10; - if (SInfo->sib6_timer > 10800000) - SInfo->sib6_timer = -1; - } - if (SInfo->sib7 && SInfo->sib7_timer >= 0) { - SInfo->sib7_timer += 10; - if (SInfo->sib7_timer > 10800000) - SInfo->sib7_timer = -1; - } - if (SInfo->sib8 && SInfo->sib8_timer >= 0) { - SInfo->sib8_timer += 10; - if (SInfo->sib8_timer > 10800000) - SInfo->sib8_timer = -1; - } - if (SInfo->sib9 && SInfo->sib9_timer >= 0) { - SInfo->sib9_timer += 10; - if (SInfo->sib9_timer > 10800000) - SInfo->sib9_timer = -1; + nr_timer_setup(&SInfo->sib1_timer, 10800000, 10); + nr_timer_setup(&SInfo->sib2_timer, 10800000, 10); + nr_timer_setup(&SInfo->sib3_timer, 10800000, 10); + nr_timer_setup(&SInfo->sib4_timer, 10800000, 10); + nr_timer_setup(&SInfo->sib5_timer, 10800000, 10); + nr_timer_setup(&SInfo->sib6_timer, 10800000, 10); + nr_timer_setup(&SInfo->sib7_timer, 10800000, 10); + nr_timer_setup(&SInfo->sib8_timer, 10800000, 10); + nr_timer_setup(&SInfo->sib9_timer, 10800000, 10); + nr_timer_setup(&SInfo->sib10_timer, 10800000, 10); + nr_timer_setup(&SInfo->sib11_timer, 10800000, 10); + nr_timer_setup(&SInfo->sib12_timer, 10800000, 10); + nr_timer_setup(&SInfo->sib13_timer, 10800000, 10); + nr_timer_setup(&SInfo->sib14_timer, 10800000, 10); +} +void nr_rrc_SI_timers(NR_UE_RRC_SI_INFO *SInfo) +{ + if (SInfo->sib1) { + bool sib1_expired = nr_timer_tick(&SInfo->sib1_timer); + if (sib1_expired) + asn1cFreeStruc(asn_DEF_NR_SIB1, SInfo->sib1); } - if (SInfo->sib10 && SInfo->sib10_timer >= 0) { - SInfo->sib10_timer += 10; - if (SInfo->sib10_timer > 10800000) - SInfo->sib10_timer = -1; + if (SInfo->sib2) { + bool sib2_expired = nr_timer_tick(&SInfo->sib2_timer); + if (sib2_expired) + asn1cFreeStruc(asn_DEF_NR_SIB2, SInfo->sib2); } - if (SInfo->sib11 && SInfo->sib11_timer >= 0) { - SInfo->sib11_timer += 10; - if (SInfo->sib11_timer > 10800000) - SInfo->sib11_timer = -1; + if (SInfo->sib3) { + bool sib3_expired = nr_timer_tick(&SInfo->sib3_timer); + if (sib3_expired) + asn1cFreeStruc(asn_DEF_NR_SIB3, SInfo->sib3); } - if (SInfo->sib12 && SInfo->sib12_timer >= 0) { - SInfo->sib12_timer += 10; - if (SInfo->sib12_timer > 10800000) - SInfo->sib12_timer = -1; + if (SInfo->sib4) { + bool sib4_expired = nr_timer_tick(&SInfo->sib4_timer); + if (sib4_expired) + asn1cFreeStruc(asn_DEF_NR_SIB4, SInfo->sib4); } - if (SInfo->sib13 && SInfo->sib13_timer >= 0) { - SInfo->sib13_timer += 10; - if (SInfo->sib13_timer > 10800000) - SInfo->sib13_timer = -1; + if (SInfo->sib5) { + bool sib5_expired = nr_timer_tick(&SInfo->sib5_timer); + if (sib5_expired) + asn1cFreeStruc(asn_DEF_NR_SIB5, SInfo->sib5); } - if (SInfo->sib14 && SInfo->sib14_timer >= 0) { - SInfo->sib14_timer += 10; - if (SInfo->sib14_timer > 10800000) - SInfo->sib14_timer = -1; + if (SInfo->sib6) { + bool sib6_expired = nr_timer_tick(&SInfo->sib6_timer); + if (sib6_expired) + asn1cFreeStruc(asn_DEF_NR_SIB6, SInfo->sib6); + } + if (SInfo->sib7) { + bool sib7_expired = nr_timer_tick(&SInfo->sib7_timer); + if (sib7_expired) + asn1cFreeStruc(asn_DEF_NR_SIB7, SInfo->sib7); + } + if (SInfo->sib8) { + bool sib8_expired = nr_timer_tick(&SInfo->sib8_timer); + if (sib8_expired) + asn1cFreeStruc(asn_DEF_NR_SIB8, SInfo->sib8); + } + if (SInfo->sib9) { + bool sib9_expired = nr_timer_tick(&SInfo->sib9_timer); + if (sib9_expired) + asn1cFreeStruc(asn_DEF_NR_SIB9, SInfo->sib9); + } + if (SInfo->sib10) { + bool sib10_expired = nr_timer_tick(&SInfo->sib10_timer); + if (sib10_expired) + asn1cFreeStruc(asn_DEF_NR_SIB10_r16, SInfo->sib10); + } + if (SInfo->sib11) { + bool sib11_expired = nr_timer_tick(&SInfo->sib11_timer); + if (sib11_expired) + asn1cFreeStruc(asn_DEF_NR_SIB11_r16, SInfo->sib11); + } + if (SInfo->sib12) { + bool sib12_expired = nr_timer_tick(&SInfo->sib12_timer); + if (sib12_expired) + asn1cFreeStruc(asn_DEF_NR_SIB12_r16, SInfo->sib12); + } + if (SInfo->sib13) { + bool sib13_expired = nr_timer_tick(&SInfo->sib13_timer); + if (sib13_expired) + asn1cFreeStruc(asn_DEF_NR_SIB13_r16, SInfo->sib13); + } + if (SInfo->sib14) { + bool sib14_expired = nr_timer_tick(&SInfo->sib14_timer); + if (sib14_expired) + asn1cFreeStruc(asn_DEF_NR_SIB14_r16, SInfo->sib14); } } @@ -102,158 +119,154 @@ void nr_rrc_handle_timers(NR_UE_RRC_INST_t *rrc) { NR_UE_Timers_Constants_t *timers = &rrc->timers_and_constants; - if (timers->T300_active == true) { - timers->T300_cnt += 10; - if(timers->T300_cnt >= timers->T300_k) { - timers->T300_active = false; - timers->T300_cnt = 0; - handle_t300_expiry(rrc); - } + bool t300_expired = nr_timer_tick(&timers->T300); + if(t300_expired) + handle_t300_expiry(rrc); + + bool t304_expired = nr_timer_tick(&timers->T304); + if(t304_expired) { + // 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->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. - } + + bool t310_expired = nr_timer_tick(&timers->T310); + if(t310_expired) { + // 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"); } - 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"); - } - } - if (timers->T311_active == true) { - timers->T311_cnt += 10; - if(timers->T311_cnt >= timers->T311_k) { - // Upon T311 expiry, the UE shall perform the actions upon going to RRC_IDLE - // with release cause 'RRC connection failure' - nr_rrc_going_to_IDLE(rrc, RRC_CONNECTION_FAILURE, NULL); - } + + bool t311_expired = nr_timer_tick(&timers->T311); + if(t311_expired) { + // Upon T311 expiry, the UE shall perform the actions upon going to RRC_IDLE + // with release cause 'RRC connection failure' + nr_rrc_going_to_IDLE(rrc, RRC_CONNECTION_FAILURE, NULL); } } -void nr_rrc_set_T304(NR_UE_Timers_Constants_t *tac, NR_ReconfigurationWithSync_t *reconfigurationWithSync) +int nr_rrc_get_T304(long t304) { - if(reconfigurationWithSync) { - switch (reconfigurationWithSync->t304) { - case NR_ReconfigurationWithSync__t304_ms50 : - tac->T304_k = 50; - break; - case NR_ReconfigurationWithSync__t304_ms100 : - tac->T304_k = 100; - break; - case NR_ReconfigurationWithSync__t304_ms150 : - tac->T304_k = 150; - break; - case NR_ReconfigurationWithSync__t304_ms200 : - tac->T304_k = 200; - break; - case NR_ReconfigurationWithSync__t304_ms500 : - tac->T304_k = 500; - break; - case NR_ReconfigurationWithSync__t304_ms1000 : - tac->T304_k = 1000; - break; - case NR_ReconfigurationWithSync__t304_ms2000 : - tac->T304_k = 2000; - break; - case NR_ReconfigurationWithSync__t304_ms10000 : - tac->T304_k = 10000; - break; - default : - AssertFatal(false, "Invalid T304 %ld\n", reconfigurationWithSync->t304); - } + int target = 0; + switch (t304) { + case NR_ReconfigurationWithSync__t304_ms50 : + target = 50; + break; + case NR_ReconfigurationWithSync__t304_ms100 : + target = 100; + break; + case NR_ReconfigurationWithSync__t304_ms150 : + target = 150; + break; + case NR_ReconfigurationWithSync__t304_ms200 : + target = 200; + break; + case NR_ReconfigurationWithSync__t304_ms500 : + target = 500; + break; + case NR_ReconfigurationWithSync__t304_ms1000 : + target = 1000; + break; + case NR_ReconfigurationWithSync__t304_ms2000 : + target = 2000; + break; + case NR_ReconfigurationWithSync__t304_ms10000 : + target = 10000; + break; + default : + AssertFatal(false, "Invalid T304 %ld\n", t304); } + return target; } void set_rlf_sib1_timers_and_constants(NR_UE_Timers_Constants_t *tac, NR_SIB1_t *sib1) { if(sib1 && sib1->ue_TimersAndConstants) { + int k = 0; switch (sib1->ue_TimersAndConstants->t301) { case NR_UE_TimersAndConstants__t301_ms100 : - tac->T301_k = 100; + k = 100; break; case NR_UE_TimersAndConstants__t301_ms200 : - tac->T301_k = 200; + k = 200; break; case NR_UE_TimersAndConstants__t301_ms300 : - tac->T301_k = 300; + k = 300; break; case NR_UE_TimersAndConstants__t301_ms400 : - tac->T301_k = 400; + k = 400; break; case NR_UE_TimersAndConstants__t301_ms600 : - tac->T301_k = 600; + k = 600; break; case NR_UE_TimersAndConstants__t301_ms1000 : - tac->T301_k = 1000; + k = 1000; break; case NR_UE_TimersAndConstants__t301_ms1500 : - tac->T301_k = 1500; + k = 1500; break; case NR_UE_TimersAndConstants__t301_ms2000 : - tac->T301_k = 2000; + k = 2000; break; default : AssertFatal(false, "Invalid T301 %ld\n", sib1->ue_TimersAndConstants->t301); } + nr_timer_setup(&tac->T301, k, 10); // 10ms step switch (sib1->ue_TimersAndConstants->t310) { case NR_UE_TimersAndConstants__t310_ms0 : - tac->T310_k = 0; + k = 0; break; case NR_UE_TimersAndConstants__t310_ms50 : - tac->T310_k = 50; + k = 50; break; case NR_UE_TimersAndConstants__t310_ms100 : - tac->T310_k = 100; + k = 100; break; case NR_UE_TimersAndConstants__t310_ms200 : - tac->T310_k = 200; + k = 200; break; case NR_UE_TimersAndConstants__t310_ms500 : - tac->T310_k = 500; + k = 500; break; case NR_UE_TimersAndConstants__t310_ms1000 : - tac->T310_k = 1000; + k = 1000; break; case NR_UE_TimersAndConstants__t310_ms2000 : - tac->T310_k = 2000; + k = 2000; break; default : AssertFatal(false, "Invalid T310 %ld\n", sib1->ue_TimersAndConstants->t310); } + nr_timer_setup(&tac->T310, k, 10); // 10ms step switch (sib1->ue_TimersAndConstants->t311) { case NR_UE_TimersAndConstants__t311_ms1000 : - tac->T311_k = 1000; + k = 1000; break; case NR_UE_TimersAndConstants__t311_ms3000 : - tac->T311_k = 3000; + k = 3000; break; case NR_UE_TimersAndConstants__t311_ms5000 : - tac->T311_k = 5000; + k = 5000; break; case NR_UE_TimersAndConstants__t311_ms10000 : - tac->T311_k = 10000; + k = 10000; break; case NR_UE_TimersAndConstants__t311_ms15000 : - tac->T311_k = 15000; + k = 15000; break; case NR_UE_TimersAndConstants__t311_ms20000 : - tac->T311_k = 20000; + k = 20000; break; case NR_UE_TimersAndConstants__t311_ms30000 : - tac->T311_k = 30000; + k = 30000; break; default : AssertFatal(false, "Invalid T311 %ld\n", sib1->ue_TimersAndConstants->t311); } + nr_timer_setup(&tac->T311, k, 10); // 10ms step switch (sib1->ue_TimersAndConstants->n310) { case NR_UE_TimersAndConstants__n310_n1 : tac->N310_k = 1; @@ -319,62 +332,65 @@ void nr_rrc_set_sib1_timers_and_constants(NR_UE_Timers_Constants_t *tac, NR_SIB1 { set_rlf_sib1_timers_and_constants(tac, sib1); if(sib1 && sib1->ue_TimersAndConstants) { + int k = 0; switch (sib1->ue_TimersAndConstants->t300) { case NR_UE_TimersAndConstants__t300_ms100 : - tac->T300_k = 100; + k = 100; break; case NR_UE_TimersAndConstants__t300_ms200 : - tac->T300_k = 200; + k = 200; break; case NR_UE_TimersAndConstants__t300_ms300 : - tac->T300_k = 300; + k = 300; break; case NR_UE_TimersAndConstants__t300_ms400 : - tac->T300_k = 400; + k = 400; break; case NR_UE_TimersAndConstants__t300_ms600 : - tac->T300_k = 600; + k = 600; break; case NR_UE_TimersAndConstants__t300_ms1000 : - tac->T300_k = 1000; + k = 1000; break; case NR_UE_TimersAndConstants__t300_ms1500 : - tac->T300_k = 1500; + k = 1500; break; case NR_UE_TimersAndConstants__t300_ms2000 : - tac->T300_k = 2000; + k = 2000; break; default : AssertFatal(false, "Invalid T300 %ld\n", sib1->ue_TimersAndConstants->t300); } + nr_timer_setup(&tac->T300, k, 10); // 10ms step switch (sib1->ue_TimersAndConstants->t319) { case NR_UE_TimersAndConstants__t319_ms100 : - tac->T319_k = 100; + k = 100; break; case NR_UE_TimersAndConstants__t319_ms200 : - tac->T319_k = 200; + k = 200; break; case NR_UE_TimersAndConstants__t319_ms300 : - tac->T319_k = 300; + k = 300; break; case NR_UE_TimersAndConstants__t319_ms400 : - tac->T319_k = 400; + k = 400; break; case NR_UE_TimersAndConstants__t319_ms600 : - tac->T319_k = 600; + k = 600; break; case NR_UE_TimersAndConstants__t319_ms1000 : - tac->T319_k = 1000; + k = 1000; break; case NR_UE_TimersAndConstants__t319_ms1500 : - tac->T319_k = 1500; + k = 1500; break; case NR_UE_TimersAndConstants__t319_ms2000 : - tac->T319_k = 2000; + k = 2000; break; default : AssertFatal(false, "Invalid T319 %ld\n", sib1->ue_TimersAndConstants->t319); } + nr_timer_setup(&tac->T319, k, 10); // 10ms step } else LOG_E(NR_RRC,"SIB1 should not be NULL and neither UE_Timers_Constants\n"); @@ -398,37 +414,39 @@ void nr_rrc_handle_SetupRelease_RLF_TimersAndConstants(NR_UE_RRC_INST_t *rrc, if (rlf_tac == NULL) return; // (re-)configure the value of timers and constants in accordance with received rlf-TimersAndConstants + int k = 0; switch (rlf_tac->t310) { case NR_RLF_TimersAndConstants__t310_ms0 : - tac->T310_k = 0; + k = 0; break; case NR_RLF_TimersAndConstants__t310_ms50 : - tac->T310_k = 50; + k = 50; break; case NR_RLF_TimersAndConstants__t310_ms100 : - tac->T310_k = 100; + k = 100; break; case NR_RLF_TimersAndConstants__t310_ms200 : - tac->T310_k = 200; + k = 200; break; case NR_RLF_TimersAndConstants__t310_ms500 : - tac->T310_k = 500; + k = 500; break; case NR_RLF_TimersAndConstants__t310_ms1000 : - tac->T310_k = 1000; + k = 1000; break; case NR_RLF_TimersAndConstants__t310_ms2000 : - tac->T310_k = 2000; + k = 2000; break; case NR_RLF_TimersAndConstants__t310_ms4000 : - tac->T310_k = 4000; + k = 4000; break; case NR_RLF_TimersAndConstants__t310_ms6000 : - tac->T310_k = 6000; + k = 6000; break; default : AssertFatal(false, "Invalid T310 %ld\n", rlf_tac->t310); } + nr_timer_setup(&tac->T310, k, 10); // 10ms step switch (rlf_tac->n310) { case NR_RLF_TimersAndConstants__n310_n1 : tac->N310_k = 1; @@ -488,29 +506,30 @@ void nr_rrc_handle_SetupRelease_RLF_TimersAndConstants(NR_UE_RRC_INST_t *rrc, if (rlf_tac->ext1) { switch (rlf_tac->ext1->t311) { case NR_RLF_TimersAndConstants__ext1__t311_ms1000 : - tac->T311_k = 1000; + k = 1000; break; case NR_RLF_TimersAndConstants__ext1__t311_ms3000 : - tac->T311_k = 3000; + k = 3000; break; case NR_RLF_TimersAndConstants__ext1__t311_ms5000 : - tac->T311_k = 5000; + k = 5000; break; case NR_RLF_TimersAndConstants__ext1__t311_ms10000 : - tac->T311_k = 10000; + k = 10000; break; case NR_RLF_TimersAndConstants__ext1__t311_ms15000 : - tac->T311_k = 15000; + k = 15000; break; case NR_RLF_TimersAndConstants__ext1__t311_ms20000 : - tac->T311_k = 20000; + k = 20000; break; case NR_RLF_TimersAndConstants__ext1__t311_ms30000 : - tac->T311_k = 30000; + k = 30000; break; default : AssertFatal(false, "Invalid T311 %ld\n", rlf_tac->ext1->t311); } + nr_timer_setup(&tac->T311, k, 10); // 10ms step } reset_rlf_timers_and_constants(tac); break; @@ -524,13 +543,12 @@ void handle_rlf_sync(NR_UE_Timers_Constants_t *tac, { if (sync_msg == IN_SYNC) { tac->N310_cnt = 0; - if (tac->T310_active) { + if (is_nr_timer_active(tac->T310)) { 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; + nr_timer_stop(&tac->T310); tac->N311_cnt = 0; } } @@ -538,20 +556,19 @@ void handle_rlf_sync(NR_UE_Timers_Constants_t *tac, 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) + if(is_nr_timer_active(tac->T300) || + is_nr_timer_active(tac->T301) || + is_nr_timer_active(tac->T304) || + is_nr_timer_active(tac->T310) || + is_nr_timer_active(tac->T311) || + is_nr_timer_active(tac->T319)) 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; + nr_timer_start(&tac->T310); + tac->N310_cnt = 0; } } } @@ -559,17 +576,16 @@ void handle_rlf_sync(NR_UE_Timers_Constants_t *tac, void set_default_timers_and_constants(NR_UE_Timers_Constants_t *tac) { // 38.331 9.2.3 Default values timers and constants - tac->T310_k = 1000; + nr_timer_setup(&tac->T310, 1000, 10); // 10ms step + nr_timer_setup(&tac->T310, 30000, 10); // 10ms step tac->N310_k = 1; - tac->T311_k = 30000; tac->N311_k = 1; } void reset_rlf_timers_and_constants(NR_UE_Timers_Constants_t *tac) { // stop timer T310 for this cell group, if running - tac->T310_active = false; - tac->T310_cnt = 0; + nr_timer_stop(&tac->T310); // reset the counters N310 and N311 tac->N310_cnt = 0; tac->N311_cnt = 0;