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

@ -50,6 +50,7 @@ class tti_sync
init_counters(0);
}
virtual void increase() = 0;
virtual void increase(uint32_t cnt) = 0;
virtual void resync() = 0;
virtual uint32_t wait() = 0;
virtual void set_producer_cntr(uint32_t) = 0;
@ -60,6 +61,7 @@ class tti_sync
}
protected:
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; }
bool wait_condition() { return producer_cntr == consumer_cntr; }
void init_counters(uint32_t val)

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

@ -75,4 +75,11 @@ namespace srslte {
pthread_cond_signal(&cond);
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));
// 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
if (pid == HARQ_BCCH_PID) {

@ -149,12 +149,11 @@ private:
uint8_t transaction_id;
bool drb_up;
bool paging_received;
rrc_args_t args;
bool first_stimsi_attempt;
bool reestablishment_in_progress;
bool connection_requested;
bool pending_mob_reconf;
LIBLTE_RRC_CONNECTION_RECONFIGURATION_STRUCT mob_reconf;
@ -186,8 +185,6 @@ private:
// RRC constants and 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 n311_cnt, N311;
uint32_t t301, t310, t311, t304;

@ -162,8 +162,7 @@ void mac::run_thread() {
while(started) {
/* Warning: Here order of invocation of procedures is important!! */
ttisync.wait();
tti = phy_h->get_current_tti();
tti = ttisync.wait();
log_h->step(tti);
timers.step_all();
@ -229,7 +228,7 @@ void mac::pcch_stop_rx()
void mac::tti_clock(uint32_t tti)
{
ttisync.increase();
ttisync.increase(tti);
}
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",
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.")
("expert.average_subframe_enabled",

@ -257,9 +257,6 @@ void phch_common::worker_end(uint32_t tti, bool tx_enable,
}
// Trigger next transmission
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;
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;
} else {
phy_state = IDLE;
log_h->warning("SYNC: Timeout while synchronizing SFN. Reselecting cell\n");
resync_sfn(true, true);
}
break;
case sfn_sync::IDLE:
@ -706,8 +708,8 @@ void phch_recv::run_thread()
}
// Increase TTI counter and trigger MAC clock (lower priority)
tti = (tti+1) % 10240;
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++;
if (cnt >= timeout) {
cnt = 0;
log_h->warning("SYNC: Timeout while synchronizing SFN\n");
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 */
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
if (chest_loop && ((1<<(tti%10)) & phy->args->cfo_ref_mask)) {
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 *******/
@ -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) {
set_uci_ack(dl_ack, dl_mac_grant.tb_en);
}
@ -393,7 +394,7 @@ void phch_worker::work_imp()
if (snr_th_ok) {
phy->rrc->in_sync();
log_h->debug("SYNC: Sending in-sync to RRC\n");
} else {
} else if (snr_th_err) {
phy->rrc->out_of_sync();
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)));

@ -49,7 +49,6 @@ rrc::rrc()
,drb_up(false)
,sysinfo_index(0)
{
sync_reset_cnt = 0;
n310_cnt = 0;
n311_cnt = 0;
}
@ -98,6 +97,7 @@ void rrc::init(phy_interface_rrc *phy_,
first_stimsi_attempt = false;
reestablishment_in_progress = false;
connection_requested = false;
args.ue_category = SRSLTE_UE_CATEGORY;
args.supported_bands[0] = 7;
@ -216,28 +216,31 @@ void rrc::run_thread() {
state = RRC_STATE_CELL_SELECTED;
}
}
select_cell_timeout++;
if (select_cell_timeout >= RRC_SELECT_CELL_TIMEOUT) {
rrc_log->info("RRC Cell Selecting: timeout expired. Starting Cell Search...\n");
state = RRC_STATE_PLMN_SELECTION;
plmn_select_timeout = 0;
phy->cell_search_start();
if (!reestablishment_in_progress) {
select_cell_timeout++;
if (select_cell_timeout >= RRC_SELECT_CELL_TIMEOUT) {
rrc_log->info("RRC Cell Selecting: timeout expired. Starting Cell Search...\n");
state = RRC_STATE_PLMN_SELECTION;
plmn_select_timeout = 0;
phy->cell_search_start();
}
}
break;
case RRC_STATE_CELL_SELECTED:
if (!nas->is_attached() || paging_received) {
paging_received = false;
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) {
if (mac_timers->timer_get(t311)->is_running()) {
rrc_log->info("RRC Cell Selected: Sending connection reestablishment...\n");
con_restablish_cell_reselected();
state = RRC_STATE_CONNECTING;
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 {
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();
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");
state = RRC_STATE_CELL_SELECTING;
select_cell_timeout = 0;
connection_requested = true;
} else {
rrc_log->info("PLMN Id=%s selected\n", plmn_id_to_string(plmn_id).c_str());
// Sort cells according to RSRP
@ -434,6 +438,7 @@ void rrc::plmn_select(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id) {
last_selected_cell = -1;
select_cell_timeout = 0;
connection_requested = true;
state = RRC_STATE_CELL_SELECTING;
select_next_cell_in_plmn();
}
@ -499,7 +504,7 @@ void rrc::new_phy_meas(float rsrp, float rsrq, uint32_t tti, uint32_t earfcn, ui
// Verify cell selection criteria
if (cell_selection_eval(known_cells[best_cell_idx].rsrp) &&
known_cells[best_cell_idx].rsrp > current_cell->rsrp + 5 &&
known_cells[best_cell_idx].rsrp > current_cell->rsrp + 5 &&
best_cell.id != phy->get_current_pci())
{
rrc_log->info("Selecting best neighbour cell PCI=%d, rsrp=%.1f dBm\n", best_cell.id, known_cells[best_cell_idx].rsrp);
@ -674,12 +679,6 @@ float rrc::get_squal(float Qqualmeas) {
// Detection of physical layer problems (5.3.11.1)
void rrc::out_of_sync() {
// 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;
if (!mac_timers->timer_get(t311)->is_running() && !mac_timers->timer_get(t310)->is_running()) {
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");
state = RRC_STATE_LEAVE_CONNECTED;
} else if (timeout_id == t301) {
rrc_log->info("Timer T301 expired: Going to RRC IDLE\n");
state = RRC_STATE_LEAVE_CONNECTED;
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");
state = RRC_STATE_LEAVE_CONNECTED;
}
} else if (timeout_id == t304) {
rrc_log->console("Timer T304 expired: Handover failed\n");
// fw to measurement
@ -873,6 +876,7 @@ void rrc::send_con_restablish_request() {
set_phy_default();
mac->reset();
set_mac_default();
state = RRC_STATE_CELL_SELECTING;
}
// 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.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);
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();
if (RRC_STATE_IDLE == state) {
rrc_log->info("RRC in IDLE state - sending connection request.\n");
paging_received = true;
state = RRC_STATE_CELL_SELECTING;
send_con_request();
state = RRC_STATE_CONNECTING;
}
}
}

Loading…
Cancel
Save