567 lines
19 KiB
C
567 lines
19 KiB
C
/*
|
|
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
|
* contributor license agreements. See the NOTICE file distributed with
|
|
* this work for additional information regarding copyright ownership.
|
|
* The OpenAirInterface Software Alliance licenses this file to You under
|
|
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
|
* except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.openairinterface.org/?page_id=698
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*-------------------------------------------------------------------------------
|
|
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
|
* contact@openairinterface.org
|
|
*/
|
|
|
|
#include "openair2/RRC/NR_UE/rrc_proto.h"
|
|
#include "executables/softmodem-common.h"
|
|
|
|
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
|
|
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);
|
|
nr_timer_setup(&SInfo->SInfo_r17.sib19_timer, 10800000, 10);
|
|
}
|
|
|
|
static SIB_validity_t check_sib_timer_validity(SIB_validity_t sib_validity, NR_timer_t *sib_timer)
|
|
{
|
|
if (sib_validity == SIB_VALID) {
|
|
bool sib_expired = nr_timer_tick(sib_timer);
|
|
if (sib_expired)
|
|
return SIB_NOT_VALID;
|
|
}
|
|
return sib_validity;
|
|
}
|
|
|
|
void nr_rrc_SI_timers(NR_UE_RRC_SI_INFO *SInfo)
|
|
{
|
|
SInfo->sib1_validity = check_sib_timer_validity(SInfo->sib1_validity, &SInfo->sib1_timer);
|
|
SInfo->sib2_validity = check_sib_timer_validity(SInfo->sib2_validity, &SInfo->sib2_timer);
|
|
SInfo->sib3_validity = check_sib_timer_validity(SInfo->sib3_validity, &SInfo->sib3_timer);
|
|
SInfo->sib4_validity = check_sib_timer_validity(SInfo->sib4_validity, &SInfo->sib4_timer);
|
|
SInfo->sib5_validity = check_sib_timer_validity(SInfo->sib5_validity, &SInfo->sib5_timer);
|
|
SInfo->sib6_validity = check_sib_timer_validity(SInfo->sib6_validity, &SInfo->sib6_timer);
|
|
SInfo->sib7_validity = check_sib_timer_validity(SInfo->sib7_validity, &SInfo->sib7_timer);
|
|
SInfo->sib8_validity = check_sib_timer_validity(SInfo->sib8_validity, &SInfo->sib8_timer);
|
|
SInfo->sib9_validity = check_sib_timer_validity(SInfo->sib9_validity, &SInfo->sib9_timer);
|
|
SInfo->sib10_validity = check_sib_timer_validity(SInfo->sib10_validity, &SInfo->sib10_timer);
|
|
SInfo->sib11_validity = check_sib_timer_validity(SInfo->sib11_validity, &SInfo->sib11_timer);
|
|
SInfo->sib12_validity = check_sib_timer_validity(SInfo->sib12_validity, &SInfo->sib12_timer);
|
|
SInfo->sib13_validity = check_sib_timer_validity(SInfo->sib13_validity, &SInfo->sib13_timer);
|
|
SInfo->sib14_validity = check_sib_timer_validity(SInfo->sib14_validity, &SInfo->sib14_timer);
|
|
SInfo->SInfo_r17.sib19_validity = check_sib_timer_validity(SInfo->SInfo_r17.sib19_validity, &SInfo->SInfo_r17.sib19_timer);
|
|
}
|
|
|
|
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");
|
|
handle_t300_expiry(rrc);
|
|
}
|
|
|
|
bool t301_expired = nr_timer_tick(&timers->T301);
|
|
// Upon T301 expiry, the UE shall perform the actions upon going to RRC_IDLE
|
|
// with release cause 'RRC connection failure'
|
|
if(t301_expired) {
|
|
LOG_W(NR_RRC, "Timer T301 expired! No timely response to RRCReestabilshmentRequest\n");
|
|
nr_rrc_going_to_IDLE(rrc, RRC_CONNECTION_FAILURE, NULL);
|
|
}
|
|
|
|
bool t304_expired = nr_timer_tick(&timers->T304);
|
|
if(t304_expired) {
|
|
LOG_W(NR_RRC, "Timer T304 expired\n");
|
|
// 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) {
|
|
LOG_W(NR_RRC, "Timer T310 expired\n");
|
|
// handle detection of radio link failure
|
|
// as described in 5.3.10.3 of 38.331
|
|
handle_rlf_detection(rrc);
|
|
}
|
|
|
|
bool t311_expired = nr_timer_tick(&timers->T311);
|
|
if(t311_expired) {
|
|
LOG_W(NR_RRC, "Timer T311 expired! No suitable cell found in time after initiation of re-establishment\n");
|
|
// 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);
|
|
}
|
|
}
|
|
|
|
int nr_rrc_get_T304(long 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_UE_TimersAndConstants_t *ue_TimersAndConstants)
|
|
{
|
|
if(ue_TimersAndConstants) {
|
|
int k = 0;
|
|
switch (ue_TimersAndConstants->t301) {
|
|
case NR_UE_TimersAndConstants__t301_ms100 :
|
|
k = 100;
|
|
break;
|
|
case NR_UE_TimersAndConstants__t301_ms200 :
|
|
k = 200;
|
|
break;
|
|
case NR_UE_TimersAndConstants__t301_ms300 :
|
|
k = 300;
|
|
break;
|
|
case NR_UE_TimersAndConstants__t301_ms400 :
|
|
k = 400;
|
|
break;
|
|
case NR_UE_TimersAndConstants__t301_ms600 :
|
|
k = 600;
|
|
break;
|
|
case NR_UE_TimersAndConstants__t301_ms1000 :
|
|
k = 1000;
|
|
break;
|
|
case NR_UE_TimersAndConstants__t301_ms1500 :
|
|
k = 1500;
|
|
break;
|
|
case NR_UE_TimersAndConstants__t301_ms2000 :
|
|
k = 2000;
|
|
break;
|
|
default :
|
|
AssertFatal(false, "Invalid T301 %ld\n", ue_TimersAndConstants->t301);
|
|
}
|
|
nr_timer_setup(&tac->T301, k, 10); // 10ms step
|
|
switch (ue_TimersAndConstants->t310) {
|
|
case NR_UE_TimersAndConstants__t310_ms0 :
|
|
k = 0;
|
|
break;
|
|
case NR_UE_TimersAndConstants__t310_ms50 :
|
|
k = 50;
|
|
break;
|
|
case NR_UE_TimersAndConstants__t310_ms100 :
|
|
k = 100;
|
|
break;
|
|
case NR_UE_TimersAndConstants__t310_ms200 :
|
|
k = 200;
|
|
break;
|
|
case NR_UE_TimersAndConstants__t310_ms500 :
|
|
k = 500;
|
|
break;
|
|
case NR_UE_TimersAndConstants__t310_ms1000 :
|
|
k = 1000;
|
|
break;
|
|
case NR_UE_TimersAndConstants__t310_ms2000 :
|
|
k = 2000;
|
|
break;
|
|
default :
|
|
AssertFatal(false, "Invalid T310 %ld\n", ue_TimersAndConstants->t310);
|
|
}
|
|
nr_timer_setup(&tac->T310, k, 10); // 10ms step
|
|
switch (ue_TimersAndConstants->t311) {
|
|
case NR_UE_TimersAndConstants__t311_ms1000 :
|
|
k = 1000;
|
|
break;
|
|
case NR_UE_TimersAndConstants__t311_ms3000 :
|
|
k = 3000;
|
|
break;
|
|
case NR_UE_TimersAndConstants__t311_ms5000 :
|
|
k = 5000;
|
|
break;
|
|
case NR_UE_TimersAndConstants__t311_ms10000 :
|
|
k = 10000;
|
|
break;
|
|
case NR_UE_TimersAndConstants__t311_ms15000 :
|
|
k = 15000;
|
|
break;
|
|
case NR_UE_TimersAndConstants__t311_ms20000 :
|
|
k = 20000;
|
|
break;
|
|
case NR_UE_TimersAndConstants__t311_ms30000 :
|
|
k = 30000;
|
|
break;
|
|
default :
|
|
AssertFatal(false, "Invalid T311 %ld\n", ue_TimersAndConstants->t311);
|
|
}
|
|
nr_timer_setup(&tac->T311, k, 10); // 10ms step
|
|
switch (ue_TimersAndConstants->n310) {
|
|
case NR_UE_TimersAndConstants__n310_n1 :
|
|
tac->N310_k = 1;
|
|
break;
|
|
case NR_UE_TimersAndConstants__n310_n2 :
|
|
tac->N310_k = 2;
|
|
break;
|
|
case NR_UE_TimersAndConstants__n310_n3 :
|
|
tac->N310_k = 3;
|
|
break;
|
|
case NR_UE_TimersAndConstants__n310_n4 :
|
|
tac->N310_k = 4;
|
|
break;
|
|
case NR_UE_TimersAndConstants__n310_n6 :
|
|
tac->N310_k = 6;
|
|
break;
|
|
case NR_UE_TimersAndConstants__n310_n8 :
|
|
tac->N310_k = 8;
|
|
break;
|
|
case NR_UE_TimersAndConstants__n310_n10 :
|
|
tac->N310_k = 10;
|
|
break;
|
|
case NR_UE_TimersAndConstants__n310_n20 :
|
|
tac->N310_k = 20;
|
|
break;
|
|
default :
|
|
AssertFatal(false, "Invalid N310 %ld\n", ue_TimersAndConstants->n310);
|
|
}
|
|
switch (ue_TimersAndConstants->n311) {
|
|
case NR_UE_TimersAndConstants__n311_n1 :
|
|
tac->N311_k = 1;
|
|
break;
|
|
case NR_UE_TimersAndConstants__n311_n2 :
|
|
tac->N311_k = 2;
|
|
break;
|
|
case NR_UE_TimersAndConstants__n311_n3 :
|
|
tac->N311_k = 3;
|
|
break;
|
|
case NR_UE_TimersAndConstants__n311_n4 :
|
|
tac->N311_k = 4;
|
|
break;
|
|
case NR_UE_TimersAndConstants__n311_n5 :
|
|
tac->N311_k = 5;
|
|
break;
|
|
case NR_UE_TimersAndConstants__n311_n6 :
|
|
tac->N311_k = 6;
|
|
break;
|
|
case NR_UE_TimersAndConstants__n311_n8 :
|
|
tac->N311_k = 8;
|
|
break;
|
|
case NR_UE_TimersAndConstants__n311_n10 :
|
|
tac->N311_k = 10;
|
|
break;
|
|
default :
|
|
AssertFatal(false, "Invalid N311 %ld\n", ue_TimersAndConstants->n311);
|
|
}
|
|
}
|
|
else
|
|
LOG_E(NR_RRC,"UE_Timers_Constants should not be NULL\n");
|
|
}
|
|
|
|
void nr_rrc_set_sib1_timers_and_constants(NR_UE_Timers_Constants_t *tac, NR_SIB1_t *sib1)
|
|
{
|
|
set_rlf_sib1_timers_and_constants(tac, sib1->ue_TimersAndConstants);
|
|
if(sib1 && sib1->ue_TimersAndConstants) {
|
|
int k = 0;
|
|
switch (sib1->ue_TimersAndConstants->t300) {
|
|
case NR_UE_TimersAndConstants__t300_ms100 :
|
|
k = 100;
|
|
break;
|
|
case NR_UE_TimersAndConstants__t300_ms200 :
|
|
k = 200;
|
|
break;
|
|
case NR_UE_TimersAndConstants__t300_ms300 :
|
|
k = 300;
|
|
break;
|
|
case NR_UE_TimersAndConstants__t300_ms400 :
|
|
k = 400;
|
|
break;
|
|
case NR_UE_TimersAndConstants__t300_ms600 :
|
|
k = 600;
|
|
break;
|
|
case NR_UE_TimersAndConstants__t300_ms1000 :
|
|
k = 1000;
|
|
break;
|
|
case NR_UE_TimersAndConstants__t300_ms1500 :
|
|
k = 1500;
|
|
break;
|
|
case NR_UE_TimersAndConstants__t300_ms2000 :
|
|
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 :
|
|
k = 100;
|
|
break;
|
|
case NR_UE_TimersAndConstants__t319_ms200 :
|
|
k = 200;
|
|
break;
|
|
case NR_UE_TimersAndConstants__t319_ms300 :
|
|
k = 300;
|
|
break;
|
|
case NR_UE_TimersAndConstants__t319_ms400 :
|
|
k = 400;
|
|
break;
|
|
case NR_UE_TimersAndConstants__t319_ms600 :
|
|
k = 600;
|
|
break;
|
|
case NR_UE_TimersAndConstants__t319_ms1000 :
|
|
k = 1000;
|
|
break;
|
|
case NR_UE_TimersAndConstants__t319_ms1500 :
|
|
k = 1500;
|
|
break;
|
|
case NR_UE_TimersAndConstants__t319_ms2000 :
|
|
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");
|
|
}
|
|
|
|
void nr_rrc_handle_SetupRelease_RLF_TimersAndConstants(NR_UE_RRC_INST_t *rrc,
|
|
struct NR_SetupRelease_RLF_TimersAndConstants *rlf_TimersAndConstants)
|
|
{
|
|
if(rlf_TimersAndConstants == NULL)
|
|
return;
|
|
|
|
NR_UE_Timers_Constants_t *tac = &rrc->timers_and_constants;
|
|
NR_RLF_TimersAndConstants_t *rlf_tac = NULL;
|
|
switch(rlf_TimersAndConstants->present){
|
|
case NR_SetupRelease_RLF_TimersAndConstants_PR_release :
|
|
// use values for timers T301, T310, T311 and constants N310, N311, as included in ue-TimersAndConstants received in SIB1
|
|
set_rlf_sib1_timers_and_constants(tac, rrc->timers_and_constants.sib1_TimersAndConstants);
|
|
break;
|
|
case NR_SetupRelease_RLF_TimersAndConstants_PR_setup :
|
|
rlf_tac = rlf_TimersAndConstants->choice.setup;
|
|
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 :
|
|
k = 0;
|
|
break;
|
|
case NR_RLF_TimersAndConstants__t310_ms50 :
|
|
k = 50;
|
|
break;
|
|
case NR_RLF_TimersAndConstants__t310_ms100 :
|
|
k = 100;
|
|
break;
|
|
case NR_RLF_TimersAndConstants__t310_ms200 :
|
|
k = 200;
|
|
break;
|
|
case NR_RLF_TimersAndConstants__t310_ms500 :
|
|
k = 500;
|
|
break;
|
|
case NR_RLF_TimersAndConstants__t310_ms1000 :
|
|
k = 1000;
|
|
break;
|
|
case NR_RLF_TimersAndConstants__t310_ms2000 :
|
|
k = 2000;
|
|
break;
|
|
case NR_RLF_TimersAndConstants__t310_ms4000 :
|
|
k = 4000;
|
|
break;
|
|
case NR_RLF_TimersAndConstants__t310_ms6000 :
|
|
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;
|
|
break;
|
|
case NR_RLF_TimersAndConstants__n310_n2 :
|
|
tac->N310_k = 2;
|
|
break;
|
|
case NR_RLF_TimersAndConstants__n310_n3 :
|
|
tac->N310_k = 3;
|
|
break;
|
|
case NR_RLF_TimersAndConstants__n310_n4 :
|
|
tac->N310_k = 4;
|
|
break;
|
|
case NR_RLF_TimersAndConstants__n310_n6 :
|
|
tac->N310_k = 6;
|
|
break;
|
|
case NR_RLF_TimersAndConstants__n310_n8 :
|
|
tac->N310_k = 8;
|
|
break;
|
|
case NR_RLF_TimersAndConstants__n310_n10 :
|
|
tac->N310_k = 10;
|
|
break;
|
|
case NR_RLF_TimersAndConstants__n310_n20 :
|
|
tac->N310_k = 20;
|
|
break;
|
|
default :
|
|
AssertFatal(false, "Invalid N310 %ld\n", rlf_tac->n310);
|
|
}
|
|
switch (rlf_tac->n311) {
|
|
case NR_RLF_TimersAndConstants__n311_n1 :
|
|
tac->N311_k = 1;
|
|
break;
|
|
case NR_RLF_TimersAndConstants__n311_n2 :
|
|
tac->N311_k = 2;
|
|
break;
|
|
case NR_RLF_TimersAndConstants__n311_n3 :
|
|
tac->N311_k = 3;
|
|
break;
|
|
case NR_RLF_TimersAndConstants__n311_n4 :
|
|
tac->N311_k = 4;
|
|
break;
|
|
case NR_RLF_TimersAndConstants__n311_n5 :
|
|
tac->N311_k = 5;
|
|
break;
|
|
case NR_RLF_TimersAndConstants__n311_n6 :
|
|
tac->N311_k = 6;
|
|
break;
|
|
case NR_RLF_TimersAndConstants__n311_n8 :
|
|
tac->N311_k = 8;
|
|
break;
|
|
case NR_RLF_TimersAndConstants__n311_n10 :
|
|
tac->N311_k = 10;
|
|
break;
|
|
default :
|
|
AssertFatal(false, "Invalid N311 %ld\n", rlf_tac->n311);
|
|
}
|
|
if (rlf_tac->ext1) {
|
|
switch (rlf_tac->ext1->t311) {
|
|
case NR_RLF_TimersAndConstants__ext1__t311_ms1000 :
|
|
k = 1000;
|
|
break;
|
|
case NR_RLF_TimersAndConstants__ext1__t311_ms3000 :
|
|
k = 3000;
|
|
break;
|
|
case NR_RLF_TimersAndConstants__ext1__t311_ms5000 :
|
|
k = 5000;
|
|
break;
|
|
case NR_RLF_TimersAndConstants__ext1__t311_ms10000 :
|
|
k = 10000;
|
|
break;
|
|
case NR_RLF_TimersAndConstants__ext1__t311_ms15000 :
|
|
k = 15000;
|
|
break;
|
|
case NR_RLF_TimersAndConstants__ext1__t311_ms20000 :
|
|
k = 20000;
|
|
break;
|
|
case NR_RLF_TimersAndConstants__ext1__t311_ms30000 :
|
|
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;
|
|
default :
|
|
AssertFatal(false, "Invalid rlf_TimersAndConstants\n");
|
|
}
|
|
}
|
|
|
|
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 (nr_timer_is_active(&tac->T310)) {
|
|
tac->N311_cnt++;
|
|
// Upon receiving N311 consecutive "in-sync" indications
|
|
if (tac->N311_cnt >= tac->N311_k) {
|
|
// stop timer T310
|
|
nr_timer_stop(&tac->T310);
|
|
tac->N311_cnt = 0;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
// OUT_OF_SYNC
|
|
tac->N311_cnt = 0;
|
|
if(get_softmodem_params()->phy_test ||
|
|
nr_timer_is_active(&tac->T300) ||
|
|
nr_timer_is_active(&tac->T301) ||
|
|
nr_timer_is_active(&tac->T304) ||
|
|
nr_timer_is_active(&tac->T310) ||
|
|
nr_timer_is_active(&tac->T311) ||
|
|
nr_timer_is_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
|
|
nr_timer_start(&tac->T310);
|
|
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
|
|
nr_timer_setup(&tac->T310, 1000, 10); // 10ms step
|
|
nr_timer_setup(&tac->T311, 30000, 10); // 10ms step
|
|
tac->N310_k = 1;
|
|
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
|
|
nr_timer_stop(&tac->T310);
|
|
// reset the counters N310 and N311
|
|
tac->N310_cnt = 0;
|
|
tac->N311_cnt = 0;
|
|
}
|