Fixed cell reselection when radio-link failure

master
Ismael Gomez 7 years ago
parent 6b264732d2
commit c0e79477b5

@ -64,7 +64,7 @@ public:
return (counter < timeout) && running; return (counter < timeout) && running;
} }
bool is_expired() { bool is_expired() {
return callback && (counter >= timeout || !running); return (timeout > 0) && (counter >= timeout || !running);
} }
uint32_t get_timeout() { uint32_t get_timeout() {
return timeout; return timeout;
@ -72,6 +72,9 @@ public:
void reset() { void reset() {
counter = 0; counter = 0;
} }
uint32_t value() {
return counter;
}
void step() { void step() {
if (running) { if (running) {
counter++; counter++;

@ -50,6 +50,7 @@ class tti_sync
init_counters(0); init_counters(0);
} }
virtual void increase() = 0; virtual void increase() = 0;
virtual void increase(uint32_t cnt) = 0;
virtual void resync() = 0; virtual void resync() = 0;
virtual uint32_t wait() = 0; virtual uint32_t wait() = 0;
virtual void set_producer_cntr(uint32_t) = 0; virtual void set_producer_cntr(uint32_t) = 0;
@ -60,6 +61,7 @@ class tti_sync
} }
protected: protected:
void increase_producer() { producer_cntr = (producer_cntr + increment)%modulus; } void increase_producer() { producer_cntr = (producer_cntr + increment)%modulus; }
void increase_producer(uint32_t cnt) { producer_cntr = cnt%modulus; }
void increase_consumer() { consumer_cntr = (consumer_cntr + increment)%modulus; } void increase_consumer() { consumer_cntr = (consumer_cntr + increment)%modulus; }
bool wait_condition() { return producer_cntr == consumer_cntr; } bool wait_condition() { return producer_cntr == consumer_cntr; }
void init_counters(uint32_t val) void init_counters(uint32_t val)

@ -44,6 +44,7 @@ class tti_sync_cv : public tti_sync
tti_sync_cv(uint32_t modulus = 10240); tti_sync_cv(uint32_t modulus = 10240);
~tti_sync_cv(); ~tti_sync_cv();
void increase(); void increase();
void increase(uint32_t cnt);
uint32_t wait(); uint32_t wait();
void resync(); void resync();
void set_producer_cntr(uint32_t producer_cntr); void set_producer_cntr(uint32_t producer_cntr);

@ -75,4 +75,11 @@ namespace srslte {
pthread_cond_signal(&cond); pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex); pthread_mutex_unlock(&mutex);
} }
void tti_sync_cv::increase(uint32_t tti)
{
pthread_mutex_lock(&mutex);
increase_producer(tti);
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
}
} }

@ -259,7 +259,7 @@ private:
memcpy(&cur_grant, &grant, sizeof(Tgrant)); memcpy(&cur_grant, &grant, sizeof(Tgrant));
// If data has not yet been successfully decoded // If data has not yet been successfully decoded
if (!ack || (grant.rv[tid]==0 && grant.phy_grant.dl.mcs[tid].idx < 29)) { if (!ack) {
// Instruct the PHY To combine the received data and attempt to decode it // Instruct the PHY To combine the received data and attempt to decode it
if (pid == HARQ_BCCH_PID) { if (pid == HARQ_BCCH_PID) {

@ -149,12 +149,11 @@ private:
uint8_t transaction_id; uint8_t transaction_id;
bool drb_up; bool drb_up;
bool paging_received;
rrc_args_t args; rrc_args_t args;
bool first_stimsi_attempt; bool first_stimsi_attempt;
bool reestablishment_in_progress; bool reestablishment_in_progress;
bool connection_requested;
bool pending_mob_reconf; bool pending_mob_reconf;
LIBLTE_RRC_CONNECTION_RECONFIGURATION_STRUCT mob_reconf; LIBLTE_RRC_CONNECTION_RECONFIGURATION_STRUCT mob_reconf;
@ -186,8 +185,6 @@ private:
// RRC constants and timers // RRC constants and timers
srslte::mac_interface_timers *mac_timers; srslte::mac_interface_timers *mac_timers;
uint32_t sync_reset_cnt;
const static uint32_t SYNC_RESET_TIMEOUT = 10;
uint32_t n310_cnt, N310; uint32_t n310_cnt, N310;
uint32_t n311_cnt, N311; uint32_t n311_cnt, N311;
uint32_t t301, t310, t311, t304; uint32_t t301, t310, t311, t304;

@ -162,8 +162,7 @@ void mac::run_thread() {
while(started) { while(started) {
/* Warning: Here order of invocation of procedures is important!! */ /* Warning: Here order of invocation of procedures is important!! */
ttisync.wait(); tti = ttisync.wait();
tti = phy_h->get_current_tti();
log_h->step(tti); log_h->step(tti);
timers.step_all(); timers.step_all();
@ -229,7 +228,7 @@ void mac::pcch_stop_rx()
void mac::tti_clock(uint32_t tti) void mac::tti_clock(uint32_t tti)
{ {
ttisync.increase(); ttisync.increase(tti);
} }
void mac::bch_decoded_ok(uint8_t* payload, uint32_t len) void mac::bch_decoded_ok(uint8_t* payload, uint32_t len)

@ -233,7 +233,7 @@ void parse_args(all_args_t *args, int argc, char *argv[]) {
("expert.cfo_loop_pss_conv", ("expert.cfo_loop_pss_conv",
bpo::value<uint32_t>(&args->expert.phy.cfo_loop_pss_conv)->default_value(50), bpo::value<uint32_t>(&args->expert.phy.cfo_loop_pss_conv)->default_value(20),
"After the PSS estimation is below cfo_loop_pss_tol for cfo_loop_pss_timeout times consecutively, RS adjustments are allowed.") "After the PSS estimation is below cfo_loop_pss_tol for cfo_loop_pss_timeout times consecutively, RS adjustments are allowed.")
("expert.average_subframe_enabled", ("expert.average_subframe_enabled",

@ -258,9 +258,6 @@ void phch_common::worker_end(uint32_t tti, bool tx_enable,
// Trigger next transmission // Trigger next transmission
pthread_mutex_unlock(&tx_mutex[(tti+1)%nof_mutex]); pthread_mutex_unlock(&tx_mutex[(tti+1)%nof_mutex]);
// Trigger MAC clock
mac->tti_clock(tti);
} }

@ -596,10 +596,12 @@ void phch_recv::run_thread()
} }
break; break;
case sfn_sync::TIMEOUT: case sfn_sync::TIMEOUT:
if (phy_state == CELL_SELECT) { if (cell_search_in_progress) {
log_h->warning("SYNC: Timeout while synchronizing SFN. Going back to cell search\n");
phy_state = CELL_SEARCH; phy_state = CELL_SEARCH;
} else { } else {
phy_state = IDLE; log_h->warning("SYNC: Timeout while synchronizing SFN. Reselecting cell\n");
resync_sfn(true, true);
} }
break; break;
case sfn_sync::IDLE: case sfn_sync::IDLE:
@ -706,8 +708,8 @@ void phch_recv::run_thread()
} }
// Increase TTI counter and trigger MAC clock (lower priority) // Increase TTI counter and trigger MAC clock (lower priority)
tti = (tti+1) % 10240;
mac->tti_clock(tti); mac->tti_clock(tti);
tti = (tti+1) % 10240;
} }
} }
@ -973,7 +975,6 @@ phch_recv::sfn_sync::ret_code phch_recv::sfn_sync::run_subframe(srslte_cell_t *c
cnt++; cnt++;
if (cnt >= timeout) { if (cnt >= timeout) {
cnt = 0; cnt = 0;
log_h->warning("SYNC: Timeout while synchronizing SFN\n");
return TIMEOUT; return TIMEOUT;
} }

@ -230,14 +230,15 @@ void phch_worker::work_imp()
/* Do FFT and extract PDCCH LLR, or quit if no actions are required in this subframe */ /* Do FFT and extract PDCCH LLR, or quit if no actions are required in this subframe */
bool chest_ok = extract_fft_and_pdcch_llr(); bool chest_ok = extract_fft_and_pdcch_llr();
bool snr_th_ok = 10*log10(srslte_chest_dl_get_snr(&ue_dl.chest))>-20.0; bool snr_th_err = 10*log10(srslte_chest_dl_get_snr(&ue_dl.chest))<-20.0;
bool snr_th_ok = 10*log10(srslte_chest_dl_get_snr(&ue_dl.chest))>-15.0;
// Call feedback loop for chest // Call feedback loop for chest
if (chest_loop && ((1<<(tti%10)) & phy->args->cfo_ref_mask)) { if (chest_loop && ((1<<(tti%10)) & phy->args->cfo_ref_mask)) {
chest_loop->set_cfo(srslte_chest_dl_get_cfo(&ue_dl.chest)); chest_loop->set_cfo(srslte_chest_dl_get_cfo(&ue_dl.chest));
} }
if (chest_ok && snr_th_ok) { if (chest_ok && !snr_th_err) {
/***** Downlink Processing *******/ /***** Downlink Processing *******/
@ -267,7 +268,7 @@ void phch_worker::work_imp()
} }
} }
} }
Debug("dl_ack={%d, %d}, generate_ack=%d\n", dl_ack[0], dl_ack[1], dl_action.generate_ack); Info("dl_ack={%d, %d}, generate_ack=%d\n", dl_ack[0], dl_ack[1], dl_action.generate_ack);
if (dl_action.generate_ack) { if (dl_action.generate_ack) {
set_uci_ack(dl_ack, dl_mac_grant.tb_en); set_uci_ack(dl_ack, dl_mac_grant.tb_en);
} }
@ -393,7 +394,7 @@ void phch_worker::work_imp()
if (snr_th_ok) { if (snr_th_ok) {
phy->rrc->in_sync(); phy->rrc->in_sync();
log_h->debug("SYNC: Sending in-sync to RRC\n"); log_h->debug("SYNC: Sending in-sync to RRC\n");
} else { } else if (snr_th_err) {
phy->rrc->out_of_sync(); phy->rrc->out_of_sync();
log_h->info("SNR=%.1f dB under threshold. Sending out-of-sync to RRC\n", log_h->info("SNR=%.1f dB under threshold. Sending out-of-sync to RRC\n",
10*log10(srslte_chest_dl_get_snr(&ue_dl.chest))); 10*log10(srslte_chest_dl_get_snr(&ue_dl.chest)));

@ -49,7 +49,6 @@ rrc::rrc()
,drb_up(false) ,drb_up(false)
,sysinfo_index(0) ,sysinfo_index(0)
{ {
sync_reset_cnt = 0;
n310_cnt = 0; n310_cnt = 0;
n311_cnt = 0; n311_cnt = 0;
} }
@ -98,6 +97,7 @@ void rrc::init(phy_interface_rrc *phy_,
first_stimsi_attempt = false; first_stimsi_attempt = false;
reestablishment_in_progress = false; reestablishment_in_progress = false;
connection_requested = false;
args.ue_category = SRSLTE_UE_CATEGORY; args.ue_category = SRSLTE_UE_CATEGORY;
args.supported_bands[0] = 7; args.supported_bands[0] = 7;
@ -216,6 +216,7 @@ void rrc::run_thread() {
state = RRC_STATE_CELL_SELECTED; state = RRC_STATE_CELL_SELECTED;
} }
} }
if (!reestablishment_in_progress) {
select_cell_timeout++; select_cell_timeout++;
if (select_cell_timeout >= RRC_SELECT_CELL_TIMEOUT) { if (select_cell_timeout >= RRC_SELECT_CELL_TIMEOUT) {
rrc_log->info("RRC Cell Selecting: timeout expired. Starting Cell Search...\n"); rrc_log->info("RRC Cell Selecting: timeout expired. Starting Cell Search...\n");
@ -223,21 +224,23 @@ void rrc::run_thread() {
plmn_select_timeout = 0; plmn_select_timeout = 0;
phy->cell_search_start(); phy->cell_search_start();
} }
}
break; break;
case RRC_STATE_CELL_SELECTED: case RRC_STATE_CELL_SELECTED:
if (!nas->is_attached() || paging_received) {
paging_received = false; if (mac_timers->timer_get(t311)->is_running()) {
rrc_log->info("RRC Cell Selected: Sending connection request...\n");
send_con_request();
state = RRC_STATE_CONNECTING;
connecting_timeout = 0;
} else if (reestablishment_in_progress) {
rrc_log->info("RRC Cell Selected: Sending connection reestablishment...\n"); rrc_log->info("RRC Cell Selected: Sending connection reestablishment...\n");
con_restablish_cell_reselected(); con_restablish_cell_reselected();
state = RRC_STATE_CONNECTING; state = RRC_STATE_CONNECTING;
connecting_timeout = 0; connecting_timeout = 0;
} else if (connection_requested) {
rrc_log->info("RRC Cell Selected: Sending connection request...\n");
send_con_request();
state = RRC_STATE_CONNECTING;
connecting_timeout = 0;
connection_requested = false;
} else { } else {
rrc_log->console("RRC Cell Selected: New PCI=%d\n", current_cell->phy_cell.id); rrc_log->info("RRC Cell Selected: Starting paging and going to IDLE...\n");
mac->pcch_start_rx(); mac->pcch_start_rx();
state = RRC_STATE_IDLE; state = RRC_STATE_IDLE;
} }
@ -426,6 +429,7 @@ void rrc::plmn_select(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id) {
rrc_log->info("Already camping on selected PLMN, connecting...\n"); rrc_log->info("Already camping on selected PLMN, connecting...\n");
state = RRC_STATE_CELL_SELECTING; state = RRC_STATE_CELL_SELECTING;
select_cell_timeout = 0; select_cell_timeout = 0;
connection_requested = true;
} else { } else {
rrc_log->info("PLMN Id=%s selected\n", plmn_id_to_string(plmn_id).c_str()); rrc_log->info("PLMN Id=%s selected\n", plmn_id_to_string(plmn_id).c_str());
// Sort cells according to RSRP // Sort cells according to RSRP
@ -434,6 +438,7 @@ void rrc::plmn_select(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id) {
last_selected_cell = -1; last_selected_cell = -1;
select_cell_timeout = 0; select_cell_timeout = 0;
connection_requested = true;
state = RRC_STATE_CELL_SELECTING; state = RRC_STATE_CELL_SELECTING;
select_next_cell_in_plmn(); select_next_cell_in_plmn();
} }
@ -674,12 +679,6 @@ float rrc::get_squal(float Qqualmeas) {
// Detection of physical layer problems (5.3.11.1) // Detection of physical layer problems (5.3.11.1)
void rrc::out_of_sync() { void rrc::out_of_sync() {
// attempt resync // attempt resync
sync_reset_cnt++;
if (sync_reset_cnt >= SYNC_RESET_TIMEOUT) {
rrc_log->info("Detected %d out-of-sync from PHY. Resynchronizing PHY.\n", sync_reset_cnt);
phy->sync_reset();
sync_reset_cnt = 0;
}
current_cell->in_sync = false; current_cell->in_sync = false;
if (!mac_timers->timer_get(t311)->is_running() && !mac_timers->timer_get(t310)->is_running()) { if (!mac_timers->timer_get(t311)->is_running() && !mac_timers->timer_get(t310)->is_running()) {
n310_cnt++; n310_cnt++;
@ -748,8 +747,12 @@ void rrc::timer_expired(uint32_t timeout_id) {
rrc_log->info("Timer T311 expired: Going to RRC IDLE\n"); rrc_log->info("Timer T311 expired: Going to RRC IDLE\n");
state = RRC_STATE_LEAVE_CONNECTED; state = RRC_STATE_LEAVE_CONNECTED;
} else if (timeout_id == t301) { } else if (timeout_id == t301) {
if (state == RRC_STATE_IDLE) {
rrc_log->info("Timer T301 expired: Already in IDLE.\n");
} else {
rrc_log->info("Timer T301 expired: Going to RRC IDLE\n"); rrc_log->info("Timer T301 expired: Going to RRC IDLE\n");
state = RRC_STATE_LEAVE_CONNECTED; state = RRC_STATE_LEAVE_CONNECTED;
}
} else if (timeout_id == t304) { } else if (timeout_id == t304) {
rrc_log->console("Timer T304 expired: Handover failed\n"); rrc_log->console("Timer T304 expired: Handover failed\n");
// fw to measurement // fw to measurement
@ -873,6 +876,7 @@ void rrc::send_con_restablish_request() {
set_phy_default(); set_phy_default();
mac->reset(); mac->reset();
set_mac_default(); set_mac_default();
state = RRC_STATE_CELL_SELECTING;
} }
// Actions following cell reselection 5.3.7.3 // Actions following cell reselection 5.3.7.3
@ -890,7 +894,7 @@ void rrc::con_restablish_cell_reselected()
bit_buf.msg[bit_buf.N_bits + i] = 0; bit_buf.msg[bit_buf.N_bits + i] = 0;
bit_buf.N_bits += 8 - (bit_buf.N_bits % 8); bit_buf.N_bits += 8 - (bit_buf.N_bits % 8);
} }
byte_buffer_t *pdcp_buf = pool_allocate;; byte_buffer_t *pdcp_buf = pool_allocate;
srslte_bit_pack_vector(bit_buf.msg, pdcp_buf->msg, bit_buf.N_bits); srslte_bit_pack_vector(bit_buf.msg, pdcp_buf->msg, bit_buf.N_bits);
pdcp_buf->N_bytes = bit_buf.N_bits / 8; pdcp_buf->N_bytes = bit_buf.N_bits / 8;
@ -1296,8 +1300,8 @@ void rrc::write_pdu_pcch(byte_buffer_t *pdu) {
mac->pcch_stop_rx(); mac->pcch_stop_rx();
if (RRC_STATE_IDLE == state) { if (RRC_STATE_IDLE == state) {
rrc_log->info("RRC in IDLE state - sending connection request.\n"); rrc_log->info("RRC in IDLE state - sending connection request.\n");
paging_received = true; send_con_request();
state = RRC_STATE_CELL_SELECTING; state = RRC_STATE_CONNECTING;
} }
} }
} }

Loading…
Cancel
Save