Added support for roaming PLMN

master
Ismael Gomez 7 years ago
parent af376e6f04
commit 2159ad3280

@ -113,7 +113,7 @@ inline bool mnc_to_string(uint16_t mnc, std::string *str)
*str += (mnc & 0x000F) + '0';
return true;
}
inline std::string plmn_id_to_c_str(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id) {
inline std::string plmn_id_to_string(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id) {
std::string mcc_str, mnc_str;
mnc_to_string(plmn_id.mnc, &mnc_str);
mcc_to_string(plmn_id.mcc, &mcc_str);

@ -104,6 +104,7 @@ public:
virtual uint32_t get_ul_count() = 0;
virtual bool get_s_tmsi(LIBLTE_RRC_S_TMSI_STRUCT *s_tmsi) = 0;
virtual void plmn_found(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id, uint16_t tracking_area_code) = 0;
virtual void plmn_search_end() = 0;
};
// NAS interface for UE
@ -140,6 +141,7 @@ class rrc_interface_phy
public:
virtual void in_sync() = 0;
virtual void out_of_sync() = 0;
virtual void earfcn_end() = 0;
virtual void cell_found(uint32_t earfcn, srslte_cell_t phy_cell, float rsrp) = 0;
};

@ -91,6 +91,7 @@ public:
bool get_s_tmsi(LIBLTE_RRC_S_TMSI_STRUCT *s_tmsi);
void plmn_found(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id, uint16_t tracking_area_code);
void plmn_search_end();
// UE interface
void attach_request();

@ -177,8 +177,8 @@ private:
// PHY interface
void in_sync();
void out_of_sync();
void earfcn_end();
void cell_found(uint32_t earfcn, srslte_cell_t phy_cell, float rsrp);
// MAC interface

@ -479,6 +479,7 @@ void phch_recv::cell_search_inc()
if (cur_earfcn_index >= 0) {
if (cur_earfcn_index >= (int) earfcn.size() - 1) {
cur_earfcn_index = 0;
rrc->earfcn_end();
}
}
Info("SYNC: Cell Search idx %d/%d\n", cur_earfcn_index, earfcn.size());

@ -72,7 +72,7 @@ void nas::attach_request() {
nas_log->info("Starting PLMN Search...\n");
rrc->plmn_search();
} else if (plmn_selection == PLMN_SELECTED) {
nas_log->info("Selecting PLMN %s\n", plmn_id_to_c_str(current_plmn).c_str());
nas_log->info("Selecting PLMN %s\n", plmn_id_to_string(current_plmn).c_str());
rrc->plmn_select(current_plmn);
selecting_plmn = current_plmn;
}
@ -96,25 +96,49 @@ RRC interface
void nas::plmn_found(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id, uint16_t tracking_area_code) {
// Store PLMN if not registered
// Check if already registered
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) {
nas_log->info("Detected known PLMN %s\n", plmn_id_to_c_str(plmn_id).c_str());
nas_log->info("Found known PLMN Id=%s\n", plmn_id_to_string(plmn_id).c_str());
if (plmn_id.mcc == home_plmn.mcc && plmn_id.mnc == home_plmn.mnc) {
nas_log->info("Connecting Home PLMN Id=%s\n", plmn_id_to_string(plmn_id).c_str());
rrc->plmn_select(plmn_id);
selecting_plmn = plmn_id;
}
return;
}
}
nas_log->info("Found PLMN: Id=%s, TAC=%d\n", plmn_id_to_c_str(plmn_id).c_str(),
// Save if new PLMN
known_plmns.push_back(plmn_id);
nas_log->info("Found PLMN: Id=%s, TAC=%d\n", plmn_id_to_string(plmn_id).c_str(),
tracking_area_code);
nas_log->console("Found PLMN: Id=%s, TAC=%d\n", plmn_id_to_c_str(plmn_id).c_str(),
nas_log->console("Found PLMN: Id=%s, TAC=%d\n", plmn_id_to_string(plmn_id).c_str(),
tracking_area_code);
if (plmn_id.mcc == home_plmn.mcc && plmn_id.mnc == home_plmn.mnc) {
rrc->plmn_select(plmn_id);
selecting_plmn = plmn_id;
}
}
// RRC indicates that the UE has gone through all EARFCN and finished PLMN selection
void nas::plmn_search_end() {
if (known_plmns.size() > 0) {
nas_log->info("Could not find Home PLMN Id=%s, trying to connect to PLMN Id=%s\n",
plmn_id_to_string(home_plmn).c_str(),
plmn_id_to_string(known_plmns[0]).c_str());
nas_log->console("Could not find Home PLMN Id=%s, trying to connect to PLMN Id=%s\n",
plmn_id_to_string(home_plmn).c_str(),
plmn_id_to_string(known_plmns[0]).c_str());
rrc->plmn_select(known_plmns[0]);
} else {
nas_log->info("Finished searching PLMN in current EARFCN set but no networks were found.\n");
}
}
bool nas::is_attached() {

@ -177,7 +177,7 @@ void rrc::run_thread() {
case RRC_STATE_PLMN_SELECTION:
plmn_select_timeout++;
if (plmn_select_timeout >= RRC_PLMN_SELECT_TIMEOUT) {
rrc_log->info("RRC PLMN Search: timeout expired. Searching again\n");
rrc_log->info("RRC PLMN Search: timeout expired\n");
phy->cell_search_stop();
sleep(1);
rrc_log->console("\nRRC PLMN Search: timeout expired. Searching again\n");
@ -369,7 +369,7 @@ void rrc::plmn_select(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id) {
state = RRC_STATE_CELL_SELECTING;
select_cell_timeout = 0;
} else {
rrc_log->info("PLMN %s selected\n", plmn_id_to_c_str(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
selected_plmn_id = plmn_id;
@ -431,6 +431,8 @@ void rrc::cell_found(uint32_t earfcn, srslte_cell_t phy_cell, float rsrp) {
for (uint32_t i = 0; i < current_cell->sib1.N_plmn_ids; i++) {
nas->plmn_found(current_cell->sib1.plmn_id[i].id, current_cell->sib1.tracking_area_code);
}
usleep(5000);
phy->cell_search_next();
}
return;
}
@ -454,6 +456,15 @@ void rrc::cell_found(uint32_t earfcn, srslte_cell_t phy_cell, float rsrp) {
cell.earfcn, cell.rsrp);
}
// PHY indicates that has gone through all known EARFCN
void rrc::earfcn_end() {
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 (state == RRC_STATE_PLMN_SELECTION) {
nas->plmn_search_end();
}
}

Loading…
Cancel
Save