Changed cell selection/reselection to avoid stopping/restarting radio. Fixed SIB message search

This commit is contained in:
Ismael Gomez 2018-02-24 21:33:13 +01:00
parent 56455b31ef
commit 42ece73453
5 changed files with 54 additions and 44 deletions

View File

@ -104,7 +104,7 @@ private:
bool set_cell();
void cell_search_inc();
void resync_sfn(bool is_connected = false, bool rx_now = false);
void resync_sfn(bool restart_radio, bool restart_now = false);
bool stop_sync();
void stop_rx();
@ -307,7 +307,6 @@ private:
IDLE = 0,
CELL_SEARCH,
CELL_SELECT,
CELL_RESELECT,
CELL_MEASURE,
CELL_CAMP,
IDLE_RX

View File

@ -33,6 +33,7 @@ namespace srsue {
// RRC states (3GPP 36.331 v10.0.0)
typedef enum {
RRC_STATE_IDLE = 0,
RRC_STATE_PLMN_START,
RRC_STATE_PLMN_SELECTION,
RRC_STATE_CELL_SELECTING,
RRC_STATE_CELL_SELECTED,
@ -44,11 +45,14 @@ typedef enum {
RRC_STATE_N_ITEMS,
} rrc_state_t;
static const char rrc_state_text[RRC_STATE_N_ITEMS][100] = {"IDLE",
"PLMN SELECTED",
"PLMN SELECTION",
"CELL SELECTING",
"CELL SELECTED",
"CONNECTING",
"CONNECTED",
"HO PREPARE",
"HO PROCESS",
"LEAVE CONNECTED"};
} // namespace srsue

View File

@ -265,17 +265,22 @@ bool phch_recv::set_cell() {
return cell_is_set;
}
void phch_recv::resync_sfn(bool is_connected, bool now) {
void phch_recv::resync_sfn(bool restart_radio, bool restart_now) {
if (!now) {
if (restart_radio) {
wait_radio_reset();
stop_rx();
usleep(100000);
}
start_rx(now);
sfn_p.reset();
Info("SYNC: Starting SFN synchronization\n");
search_p.reset();
srslte_ue_sync_reset(&ue_sync);
phy_state = is_connected?CELL_RESELECT:CELL_SELECT;
if (restart_radio) {
start_rx(restart_now);
}
phy_state = CELL_SELECT;
}
void phch_recv::set_earfcn(std::vector<uint32_t> earfcn) {
@ -294,7 +299,7 @@ bool phch_recv::stop_sync() {
if (phy_state == IDLE && is_in_idle) {
return true;
} else {
Info("SYNC: Going to IDLE\n");
Info("SYNC: Going to IDLE (state=%d)\n", phy_state);
phy_state = IDLE;
int cnt = 0;
while (!is_in_idle && cnt < 100) {
@ -302,7 +307,7 @@ bool phch_recv::stop_sync() {
cnt++;
}
if (!is_in_idle) {
Warning("SYNC: Could not go to IDLE\n");
Warning("SYNC: Could not go to IDLE (state=%d)\n", phy_state);
}
return is_in_idle;
}
@ -310,11 +315,12 @@ bool phch_recv::stop_sync() {
void phch_recv::reset_sync() {
Warning("SYNC: Resetting sync, cell_search_in_progress=%s\n", cell_search_in_progress?"yes":"no");
search_p.reset();
srslte_ue_sync_reset(&ue_sync);
resync_sfn(true, true);
if (phy_state != CELL_SELECT) {
Warning("SYNC: Resetting sync, cell_search_in_progress=%s\n", cell_search_in_progress?"yes":"no");
resync_sfn(false);
} else {
Warning("SYNC: Trying to reset sync while in cell reselection\n");
}
}
void phch_recv::cell_search_inc()
@ -323,6 +329,8 @@ void phch_recv::cell_search_inc()
if (cur_earfcn_index >= 0) {
if (cur_earfcn_index >= (int) earfcn.size()) {
cur_earfcn_index = 0;
cell_search_in_progress = false;
phy_state = IDLE;
rrc->earfcn_end();
} else {
Info("SYNC: Cell Search idx %d/%d\n", cur_earfcn_index, earfcn.size());
@ -338,7 +346,7 @@ void phch_recv::cell_search_next(bool reset) {
if (cell_search_in_progress || reset) {
cell_search_in_progress = false;
if (!stop_sync()) {
log_h->warning("SYNC: Couldn't stop PHY\n");
log_h->warning("SYNC: Couldn't stop PHY (state=%d)\n", phy_state);
}
if (reset) {
cur_earfcn_index = -1;
@ -393,9 +401,7 @@ bool phch_recv::cell_handover(srslte_cell_t cell)
if (is_in_idle_rx) {
Info("Cell HO: Reconfiguring cell\n");
if (set_cell()) {
//resync_sfn(true, true);
sfn_p.reset();
phy_state = CELL_RESELECT;
resync_sfn(false);
Info("Cell HO: Synchronizing with new cell\n");
ret = true;
} else {
@ -419,7 +425,7 @@ bool phch_recv::cell_select(uint32_t earfcn, srslte_cell_t cell) {
set_sampling_rate();
}
if (phy_state < CELL_SELECT) {
resync_sfn();
resync_sfn(true, false);
}
return true;
} else {
@ -444,9 +450,7 @@ bool phch_recv::cell_select(uint32_t earfcn, srslte_cell_t cell) {
if (set_cell()) {
log_h->info("Cell Select: Synchronizing on cell...\n");
resync_sfn();
usleep(500000); // Time offset we set start_rx to start receiving samples
resync_sfn(true, false);
return true;
}
return false;
@ -616,13 +620,14 @@ void phch_recv::run_thread()
}
if (set_cell()) {
set_sampling_rate();
resync_sfn();
resync_sfn(true, false);
}
break;
case search::CELL_NOT_FOUND:
if (cell_search_in_progress) {
cell_search_inc();
}
phy_state = IDLE;
break;
default:
radio_error();
@ -630,7 +635,6 @@ void phch_recv::run_thread()
}
}
break;
case CELL_RESELECT:
case CELL_SELECT:
switch (sfn_p.run_subframe(&cell, &tti))
{
@ -650,7 +654,7 @@ void phch_recv::run_thread()
phy_state = CELL_SEARCH;
} else {
log_h->warning("SYNC: Timeout while synchronizing SFN. Reselecting cell\n");
resync_sfn(true, true);
resync_sfn(false);
}
break;
case sfn_sync::IDLE:
@ -666,6 +670,7 @@ void phch_recv::run_thread()
case measure::MEASURE_OK:
log_h->info("SYNC: Measured OK. Camping on cell PCI=%d...\n", cell.id);
phy_state = CELL_CAMP;
cell_search_in_progress = false;
rrc->cell_found(earfcn[cur_earfcn_index], cell, measure_p.rsrp());
break;
case measure::IDLE:

View File

@ -171,7 +171,10 @@ void nas::plmn_search_end() {
rrc->plmn_select(known_plmns[0]);
} else {
nas_log->debug("Finished searching PLMN in current EARFCN set but no networks were found.\n");
nas_log->info("Finished searching PLMN in current EARFCN set but no networks were found.\n");
if (state == EMM_STATE_REGISTERED_INITIATED && plmn_selection == PLMN_NOT_SELECTED) {
rrc->plmn_search();
}
}
}

View File

@ -202,6 +202,12 @@ void rrc::run_thread() {
// If not attached, PLMN selection will be triggered from higher layers
}
break;
case RRC_STATE_PLMN_START:
rrc_log->info("RRC PLMN Search: Starting cell search\n");
plmn_select_timeout = 0;
phy->cell_search_start();
state = RRC_STATE_PLMN_SELECTION;
break;
case RRC_STATE_PLMN_SELECTION:
plmn_select_timeout++;
if (plmn_select_timeout >= RRC_PLMN_SELECT_TIMEOUT) {
@ -209,8 +215,7 @@ void rrc::run_thread() {
phy->cell_search_stop();
sleep(1);
rrc_log->console("\nRRC PLMN Search: timeout expired. Searching again\n");
plmn_select_timeout = 0;
phy->cell_search_start();
}
break;
case RRC_STATE_CELL_SELECTING:
@ -230,7 +235,7 @@ void rrc::run_thread() {
state = RRC_STATE_CELL_SELECTED;
}
}
// Don't time out during restablishment (T311 running)
// Don't time out during reestablishment (T311 running)
if (!mac_timers->timer_get(t311)->is_running()) {
select_cell_timeout++;
if (select_cell_timeout >= RRC_SELECT_CELL_TIMEOUT) {
@ -351,7 +356,7 @@ void rrc::run_si_acquisition_procedure()
tti = mac->get_current_tti();
si_win_start = sib_start_tti(tti, 2, 0, 5);
if (last_win_start == 0 ||
(srslte_tti_interval(last_win_start, tti) > 20 && srslte_tti_interval(last_win_start, tti) < 1000))
(srslte_tti_interval(tti, last_win_start) >= 20 && srslte_tti_interval(tti, last_win_start) < 1000))
{
last_win_start = si_win_start;
@ -384,12 +389,12 @@ void rrc::run_si_acquisition_procedure()
si_win_len = liblte_rrc_si_window_length_num[serving_cell->sib1ptr()->si_window_length];
if (last_win_start == 0 ||
(srslte_tti_interval(last_win_start, tti) > period*10 && srslte_tti_interval(last_win_start, tti) < 1000))
(srslte_tti_interval(tti, last_win_start) > period*10 && srslte_tti_interval(tti, last_win_start) < 1000))
{
last_win_start = si_win_start;
mac->bcch_start_rx(si_win_start, si_win_len);
rrc_log->info("Instructed MAC to search for system info, win_start=%d, win_len=%d\n",
rrc_log->debug("Instructed MAC to search for system info, win_start=%d, win_len=%d\n",
si_win_start, si_win_len);
}
@ -433,10 +438,7 @@ uint16_t rrc::get_mnc() {
}
void rrc::plmn_search() {
rrc_log->info("Starting PLMN search procedure\n");
state = RRC_STATE_PLMN_SELECTION;
phy->cell_search_start();
plmn_select_timeout = 0;
state = RRC_STATE_PLMN_START;
}
/* This is the NAS interface. When NAS requests to select a PLMN we have to
@ -576,7 +578,8 @@ void rrc::new_phy_meas(float rsrp, float rsrq, uint32_t tti, int earfcn_i, int p
}
// Verify cell selection criteria with strongest neighbour cell (always first)
if (cell_selection_eval(neighbour_cells[0]->get_rsrp()) &&
if (neighbour_cells.size() > 1 &&
cell_selection_eval(neighbour_cells[0]->get_rsrp()) &&
neighbour_cells[0]->get_rsrp() > serving_cell->get_rsrp() + 5)
{
set_serving_cell(0);
@ -761,10 +764,6 @@ void rrc::earfcn_end() {
// If searching for PLMN, indicate NAS we scanned all frequencies
if (state == RRC_STATE_PLMN_SELECTION) {
nas->plmn_search_end();
} else if (state == RRC_STATE_CELL_SELECTING) {
select_cell_timeout = 0;
rrc_log->info("Starting cell search again\n");
phy->cell_search_start();
}
}
@ -825,11 +824,11 @@ void rrc::out_of_sync() {
if (!mac_timers->timer_get(t311)->is_running() && !mac_timers->timer_get(t310)->is_running()) {
n310_cnt++;
if (n310_cnt == N310) {
rrc_log->info("Detected %d out-of-sync from PHY. Trying to resync. Starting T310 timer %d ms\n",
N310, mac_timers->timer_get(t310)->get_timeout());
mac_timers->timer_get(t310)->reset();
mac_timers->timer_get(t310)->run();
n310_cnt = 0;
phy->sync_reset();
rrc_log->info("Detected %d out-of-sync from PHY. Trying to resync. Starting T310 timer\n", N310);
}
}
} else {
@ -856,7 +855,6 @@ void rrc::in_sync() {
void rrc::radio_link_failure() {
// TODO: Generate and store failure report
phy->sync_reset();
rrc_log->warning("Detected Radio-Link Failure\n");
rrc_log->console("Warning: Detected Radio-Link Failure\n");
if (state != RRC_STATE_CONNECTED) {
@ -1016,6 +1014,7 @@ void rrc::send_con_restablish_request(LIBLTE_RRC_CON_REEST_REQ_CAUSE_ENUM cause,
set_phy_default();
mac->reset();
set_mac_default();
phy->sync_reset();
state = RRC_STATE_CELL_SELECTING;
}