new structure for UE timers and reworking of UE RRC timers
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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 ) {
|
||||
|
||||
+27
-46
@@ -621,7 +621,7 @@ static void nr_rrc_ue_generate_RRCSetupRequest(NR_UE_RRC_INST_t *rrc)
|
||||
|
||||
// start timer T300
|
||||
NR_UE_Timers_Constants_t *tac = &rrc->timers_and_constants;
|
||||
tac->T300_active = true;
|
||||
nr_timer_start(&tac->T300);
|
||||
|
||||
/* convention: RNTI for SRB0 is zero, as it changes all the time */
|
||||
nr_rlc_srb_recv_sdu(rrc->ue_id, 0, buf, len);
|
||||
@@ -766,13 +766,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++) {
|
||||
@@ -877,16 +874,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)
|
||||
|
||||
@@ -1389,10 +1382,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
|
||||
}
|
||||
@@ -1829,11 +1821,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");
|
||||
@@ -1841,17 +1833,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");
|
||||
@@ -1859,24 +1849,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
|
||||
|
||||
@@ -144,44 +144,23 @@ typedef struct UE_RRC_SI_INFO_NR_s {
|
||||
} __attribute__ ((__packed__)) 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 {
|
||||
|
||||
@@ -115,9 +115,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);
|
||||
|
||||
|
||||
@@ -102,158 +102,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 +315,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 +397,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 +489,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 +526,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 +539,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 +559,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;
|
||||
|
||||
Reference in New Issue
Block a user