Implemented proper cell reselection. Tested reestablishment from one cell to another.

master
Ismael Gomez 7 years ago
parent c0e79477b5
commit c69d4a37e8

@ -152,9 +152,6 @@ private:
rrc_args_t args; rrc_args_t args;
bool first_stimsi_attempt; bool first_stimsi_attempt;
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;
@ -367,7 +364,8 @@ private:
void cell_reselection_eval(float rsrp, float rsrq); void cell_reselection_eval(float rsrp, float rsrq);
bool cell_selection_eval(float rsrp, float rsrq = 0); bool cell_selection_eval(float rsrp, float rsrq = 0);
bool connection_requested;
void plmn_select_rrc(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id);
// RLC interface // RLC interface
void max_retx_attempted(); void max_retx_attempted();

@ -301,16 +301,17 @@ void phch_recv::cell_search_inc()
{ {
cur_earfcn_index++; cur_earfcn_index++;
if (cur_earfcn_index >= 0) { if (cur_earfcn_index >= 0) {
if (cur_earfcn_index >= (int) earfcn.size() - 1) { if (cur_earfcn_index >= (int) earfcn.size()) {
cur_earfcn_index = 0; cur_earfcn_index = 0;
rrc->earfcn_end(); rrc->earfcn_end();
} else {
Info("SYNC: Cell Search idx %d/%d\n", cur_earfcn_index, earfcn.size());
if (current_earfcn != earfcn[cur_earfcn_index]) {
current_earfcn = earfcn[cur_earfcn_index];
set_frequency();
}
} }
} }
Info("SYNC: Cell Search idx %d/%d\n", cur_earfcn_index, earfcn.size());
if (current_earfcn != earfcn[cur_earfcn_index]) {
current_earfcn = earfcn[cur_earfcn_index];
set_frequency();
}
} }
void phch_recv::cell_search_next(bool reset) { void phch_recv::cell_search_next(bool reset) {
@ -329,12 +330,16 @@ void phch_recv::cell_search_next(bool reset) {
} }
void phch_recv::cell_search_start() { void phch_recv::cell_search_start() {
if (earfcn.size() > 0) { if (phy_state == CELL_CAMP) {
Info("SYNC: Starting Cell Search procedure in %d EARFCNs...\n", earfcn.size()); Warning("SYNC: Can't start cell search procedure while camping on cell\n");
cell_search_next(true);
} else { } else {
Info("SYNC: Empty EARFCN list. Stopping cell search...\n"); if (earfcn.size() > 0) {
log_h->console("Empty EARFCN list. Stopping cell search...\n"); Info("SYNC: Starting Cell Search procedure in %d EARFCNs...\n", earfcn.size());
cell_search_next(true);
} else {
Info("SYNC: Empty EARFCN list. Stopping cell search...\n");
log_h->console("Empty EARFCN list. Stopping cell search...\n");
}
} }
} }

@ -268,7 +268,7 @@ void phch_worker::work_imp()
} }
} }
} }
Info("dl_ack={%d, %d}, generate_ack=%d\n", dl_ack[0], dl_ack[1], dl_action.generate_ack); Debug("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);
} }

@ -108,7 +108,6 @@ void nas::attach_request() {
} else if (state == EMM_STATE_REGISTERED) { } else if (state == EMM_STATE_REGISTERED) {
nas_log->info("NAS state is registered, connecting to same PLMN\n"); nas_log->info("NAS state is registered, connecting to same PLMN\n");
rrc->plmn_select(current_plmn); rrc->plmn_select(current_plmn);
selecting_plmn = current_plmn;
} else { } else {
nas_log->info("Attach request ignored. State = %s\n", emm_state_text[state]); nas_log->info("Attach request ignored. State = %s\n", emm_state_text[state]);
} }
@ -125,6 +124,11 @@ void nas::deattach_request() {
void nas::plmn_found(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id, uint16_t tracking_area_code) { void nas::plmn_found(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id, uint16_t tracking_area_code) {
// Do not process new PLMN if already selected
if (plmn_selection == PLMN_SELECTED) {
return;
}
// Check if already registered // Check if already registered
for (uint32_t i=0;i<known_plmns.size();i++) { for (uint32_t i=0;i<known_plmns.size();i++) {
if (plmn_id.mcc == known_plmns[i].mcc && plmn_id.mnc == known_plmns[i].mnc) { if (plmn_id.mcc == known_plmns[i].mcc && plmn_id.mnc == known_plmns[i].mnc) {

@ -96,8 +96,6 @@ void rrc::init(phy_interface_rrc *phy_,
pthread_mutex_init(&mutex, NULL); pthread_mutex_init(&mutex, NULL);
first_stimsi_attempt = false; first_stimsi_attempt = 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;
@ -176,14 +174,14 @@ void rrc::run_thread() {
if (nas->is_attaching()) { if (nas->is_attaching()) {
sleep(1); sleep(1);
rrc_log->info("RRC IDLE: NAS is attaching and camping on cell, reselecting...\n"); rrc_log->info("RRC IDLE: NAS is attaching and camping on cell, reselecting...\n");
plmn_select(selected_plmn_id); plmn_select_rrc(selected_plmn_id);
} }
// If not camping on a cell // If not camping on a cell
} else { } else {
// If NAS is attached, perform cell reselection on current PLMN // If NAS is attached, perform cell reselection on current PLMN
if (nas->is_attached()) { if (nas->is_attached()) {
rrc_log->info("RRC IDLE: NAS is attached, PHY not synchronized. Re-selecting cell...\n"); rrc_log->info("RRC IDLE: NAS is attached, PHY not synchronized. Re-selecting cell...\n");
plmn_select(selected_plmn_id); plmn_select_rrc(selected_plmn_id);
} else if (nas->is_attaching()) { } else if (nas->is_attaching()) {
sleep(1); sleep(1);
rrc_log->info("RRC IDLE: NAS is attaching, searching again PLMN\n"); rrc_log->info("RRC IDLE: NAS is attaching, searching again PLMN\n");
@ -204,6 +202,10 @@ void rrc::run_thread() {
} }
break; break;
case RRC_STATE_CELL_SELECTING: case RRC_STATE_CELL_SELECTING:
/* During cell selection, apply SIB configurations if available or receive them if not.
* Cell is selected when all SIBs downloaded or applied.
*/
if (phy->sync_status()) { if (phy->sync_status()) {
if (!current_cell->has_valid_sib1) { if (!current_cell->has_valid_sib1) {
si_acquire_state = SI_ACQUIRE_SIB1; si_acquire_state = SI_ACQUIRE_SIB1;
@ -216,29 +218,36 @@ void rrc::run_thread() {
state = RRC_STATE_CELL_SELECTED; state = RRC_STATE_CELL_SELECTED;
} }
} }
if (!reestablishment_in_progress) { // Don't time out during restablishment (T311 running)
if (!mac_timers->timer_get(t311)->is_running()) {
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");
state = RRC_STATE_PLMN_SELECTION;
plmn_select_timeout = 0; plmn_select_timeout = 0;
select_cell_timeout = 0;
phy->cell_search_start(); phy->cell_search_start();
} }
} }
break; break;
case RRC_STATE_CELL_SELECTED: case RRC_STATE_CELL_SELECTED:
/* The cell is selected when the SIBs are received and applied.
* If we were in RRC_CONNECTED and arrive here it means a RLF occurred and we are in Reestablishment procedure.
* If T311 is running means there is a reestablishment in progress, send ConnectionReestablishmentRequest.
* If not, do a ConnectionRequest if NAS is established or go to IDLE an camp on cell otherwise.
*/
if (mac_timers->timer_get(t311)->is_running()) { if (mac_timers->timer_get(t311)->is_running()) {
//
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) { } else if (connection_requested) {
connection_requested = false;
rrc_log->info("RRC Cell Selected: Sending connection request...\n"); rrc_log->info("RRC Cell Selected: Sending connection request...\n");
send_con_request(); send_con_request();
state = RRC_STATE_CONNECTING; state = RRC_STATE_CONNECTING;
connecting_timeout = 0; connecting_timeout = 0;
connection_requested = false;
} else { } else {
rrc_log->info("RRC Cell Selected: Starting paging and going to IDLE...\n"); rrc_log->info("RRC Cell Selected: Starting paging and going to IDLE...\n");
mac->pcch_start_rx(); mac->pcch_start_rx();
@ -265,9 +274,9 @@ void rrc::run_thread() {
break; break;
case RRC_STATE_LEAVE_CONNECTED: case RRC_STATE_LEAVE_CONNECTED:
usleep(60000); usleep(60000);
rrc_log->console("RRC IDLE\n");
rrc_log->info("Leaving RRC_CONNECTED state\n"); rrc_log->info("Leaving RRC_CONNECTED state\n");
drb_up = false; drb_up = false;
reestablishment_in_progress = false;
measurements.reset(); measurements.reset();
pdcp->reset(); pdcp->reset();
rlc->reset(); rlc->reset();
@ -275,12 +284,14 @@ void rrc::run_thread() {
mac->reset(); mac->reset();
set_phy_default(); set_phy_default();
set_mac_default(); set_mac_default();
mac->pcch_start_rx();
mac_timers->timer_get(t310)->stop(); mac_timers->timer_get(t310)->stop();
mac_timers->timer_get(t311)->stop(); mac_timers->timer_get(t311)->stop();
if (phy->sync_status()) {
// Instruct PHY to measure serving cell for cell reselection // Instruct MAC to look for P-RNTI
phy->meas_start(phy->get_current_earfcn(), phy->get_current_pci()); mac->pcch_start_rx();
// Instruct PHY to measure serving cell for cell reselection
phy->meas_start(phy->get_current_earfcn(), phy->get_current_pci());
}
// Move to RRC_IDLE // Move to RRC_IDLE
state = RRC_STATE_IDLE; state = RRC_STATE_IDLE;
@ -421,15 +432,24 @@ void rrc::plmn_search() {
plmn_select_timeout = 0; plmn_select_timeout = 0;
} }
/* This is the NAS interface. When NAS requests to select a PLMN we have to
* connect to either register or because there is pending higher layer traffic.
*/
void rrc::plmn_select(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id) { void rrc::plmn_select(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id) {
connection_requested = true;
plmn_select_rrc(plmn_id);
}
/* This is called by RRC only. In this case, we do not want to connect, just camp on the
* selected PLMN
*/
void rrc::plmn_select_rrc(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id) {
// If already camping on the selected PLMN, select this cell // If already camping on the selected PLMN, select this cell
if (state == RRC_STATE_IDLE || state == RRC_STATE_CONNECTED || state == RRC_STATE_PLMN_SELECTION) { if (state == RRC_STATE_IDLE || state == RRC_STATE_CONNECTED || state == RRC_STATE_PLMN_SELECTION) {
if (phy->sync_status() && selected_plmn_id.mcc == plmn_id.mcc && selected_plmn_id.mnc == plmn_id.mnc) { if (phy->sync_status() && selected_plmn_id.mcc == plmn_id.mcc && selected_plmn_id.mnc == plmn_id.mnc) {
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
@ -438,7 +458,6 @@ 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();
} }
@ -477,7 +496,8 @@ void rrc::select_next_cell_in_plmn() {
} }
} }
} }
rrc_log->info("No more known cells...\n"); rrc_log->info("No more known cells. Starting again\n");
last_selected_cell = -1;
} }
void rrc::new_phy_meas(float rsrp, float rsrq, uint32_t tti, uint32_t earfcn, uint32_t pci) { void rrc::new_phy_meas(float rsrp, float rsrq, uint32_t tti, uint32_t earfcn, uint32_t pci) {
@ -603,11 +623,15 @@ rrc::cell_t* rrc::add_new_cell(uint32_t earfcn, srslte_cell_t phy_cell, float rs
// PHY indicates that has gone through all known EARFCN // PHY indicates that has gone through all known EARFCN
void rrc::earfcn_end() { void rrc::earfcn_end() {
rrc_log->debug("Finished searching cells in EARFCN set while in state %s\n", rrc_state_text[state]); rrc_log->info("Finished searching cells in EARFCN set while in state %s\n", rrc_state_text[state]);
// If searching for PLMN, indicate NAS we scanned all frequencies // If searching for PLMN, indicate NAS we scanned all frequencies
if (state == RRC_STATE_PLMN_SELECTION) { if (state == RRC_STATE_PLMN_SELECTION) {
nas->plmn_search_end(); 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();
} }
} }
@ -631,7 +655,7 @@ void rrc::cell_reselection_eval(float rsrp, float rsrq)
{ {
// Intra-frequency cell-reselection criteria // Intra-frequency cell-reselection criteria
if (get_srxlev(rsrp) > cell_resel_cfg.s_intrasearchP && rsrp > -80.0) { if (get_srxlev(rsrp) > cell_resel_cfg.s_intrasearchP && rsrp > -70.0) {
// UE may not perform intra-frequency measurements. // UE may not perform intra-frequency measurements.
phy->meas_reset(); phy->meas_reset();
// keep measuring serving cell // keep measuring serving cell
@ -864,8 +888,6 @@ void rrc::send_con_restablish_request() {
ul_ccch_msg.msg.rrc_con_reest_req.cause = LIBLTE_RRC_CON_REEST_REQ_CAUSE_OTHER_FAILURE; ul_ccch_msg.msg.rrc_con_reest_req.cause = LIBLTE_RRC_CON_REEST_REQ_CAUSE_OTHER_FAILURE;
liblte_rrc_pack_ul_ccch_msg(&ul_ccch_msg, (LIBLTE_BIT_MSG_STRUCT *) &bit_buf); liblte_rrc_pack_ul_ccch_msg(&ul_ccch_msg, (LIBLTE_BIT_MSG_STRUCT *) &bit_buf);
reestablishment_in_progress = true;
rrc_log->info("Initiating RRC Connection Reestablishment Procedure\n"); rrc_log->info("Initiating RRC Connection Reestablishment Procedure\n");
rrc_log->console("RRC Connection Reestablishment\n"); rrc_log->console("RRC Connection Reestablishment\n");
mac_timers->timer_get(t310)->stop(); mac_timers->timer_get(t310)->stop();
@ -882,7 +904,6 @@ void rrc::send_con_restablish_request() {
// Actions following cell reselection 5.3.7.3 // Actions following cell reselection 5.3.7.3
void rrc::con_restablish_cell_reselected() void rrc::con_restablish_cell_reselected()
{ {
reestablishment_in_progress = false;
rrc_log->info("Cell Selection finished. Initiating transmission of RRC Connection Reestablishment Request\n"); rrc_log->info("Cell Selection finished. Initiating transmission of RRC Connection Reestablishment Request\n");
mac_timers->timer_get(t301)->reset(); mac_timers->timer_get(t301)->reset();
mac_timers->timer_get(t301)->run(); mac_timers->timer_get(t301)->run();
@ -1218,6 +1239,7 @@ void rrc::handle_sib2()
rrc_log->info("SIB2 received\n"); rrc_log->info("SIB2 received\n");
apply_sib2_configs(&current_cell->sib2); apply_sib2_configs(&current_cell->sib2);
} }
void rrc::handle_sib3() void rrc::handle_sib3()

Loading…
Cancel
Save