diff --git a/lib/include/srslte/interfaces/ue_interfaces.h b/lib/include/srslte/interfaces/ue_interfaces.h index 03edd0b88..2c29bd4d4 100644 --- a/lib/include/srslte/interfaces/ue_interfaces.h +++ b/lib/include/srslte/interfaces/ue_interfaces.h @@ -98,6 +98,7 @@ class nas_interface_rrc { public: virtual bool is_attached() = 0; + virtual bool is_attaching() = 0; virtual void notify_connection_setup() = 0; virtual void write_pdu(uint32_t lcid, srslte::byte_buffer_t *pdu) = 0; virtual uint32_t get_ul_count() = 0; @@ -532,6 +533,7 @@ public: /* Is the PHY downlink synchronized? */ virtual bool sync_status() = 0; + virtual void sync_reset() = 0; /* Configure UL using parameters written with set_param() */ virtual void configure_ul_params(bool pregen_disabled = false) = 0; diff --git a/srsue/hdr/phy/phch_recv.h b/srsue/hdr/phy/phch_recv.h index 82abfd304..ac033f607 100644 --- a/srsue/hdr/phy/phch_recv.h +++ b/srsue/hdr/phy/phch_recv.h @@ -54,7 +54,7 @@ public: void set_earfcn(std::vector earfcn); - bool stop_sync(); + void reset_sync(); void cell_search_start(); void cell_search_stop(); void cell_search_next(bool reset = false); @@ -73,12 +73,16 @@ private: std::vector earfcn; + void reset(); + void radio_error(); + bool wait_radio_reset(); void set_ue_sync_opts(srslte_ue_sync_t *q); void run_thread(); void set_sampling_rate(); bool set_frequency(); void resync_sfn(); + bool stop_sync(); void cell_search_inc(); @@ -89,6 +93,8 @@ private: void start_rx(); bool radio_is_rx; + bool radio_is_resetting; + bool running; srslte::radio_multi *radio_h; @@ -152,7 +158,6 @@ private: float measure_rsrp; srslte_ue_dl_t ue_dl_measure; - const static int RSRP_MEASURE_NOF_FRAMES = 5; int cell_sync_sfn(); diff --git a/srsue/hdr/phy/phy.h b/srsue/hdr/phy/phy.h index 1d500e7f7..2df93b07b 100644 --- a/srsue/hdr/phy/phy.h +++ b/srsue/hdr/phy/phy.h @@ -79,6 +79,7 @@ public: /********** RRC INTERFACE ********************/ void reset(); + void sync_reset(); void configure_ul_params(bool pregen_disabled = false); void cell_search_start(); void cell_search_stop(); diff --git a/srsue/hdr/upper/nas.h b/srsue/hdr/upper/nas.h index 1aa0ab3d6..68d00ba06 100644 --- a/srsue/hdr/upper/nas.h +++ b/srsue/hdr/upper/nas.h @@ -86,6 +86,7 @@ public: uint32_t get_ul_count(); bool is_attached(); + bool is_attaching(); bool get_s_tmsi(LIBLTE_RRC_S_TMSI_STRUCT *s_tmsi); diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index 25bfb89b2..eac26d9ec 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -79,15 +79,7 @@ void phch_recv:: init(srslte::radio_multi *_radio_handler, mac_interface_phy *_ prach_buffer = _prach_buffer; nof_rx_antennas = nof_rx_antennas_; - tx_mutex_cnt = 0; - running = true; - phy_state = IDLE; - time_adv_sec = 0; - cell_is_set = false; - sync_sfn_cnt = 0; - srate_mode = SRATE_NONE; - cell_search_in_progress = false; - current_earfcn = 0; + reset(); for (uint32_t i = 0; i < nof_rx_antennas; i++) { sf_buffer[i] = (cf_t *) srslte_vec_malloc(sizeof(cf_t) * 3 * SRSLTE_SF_LEN_PRB(100)); @@ -157,6 +149,37 @@ void phch_recv::stop() { wait_thread_finish(); } +void phch_recv::reset() { + tx_mutex_cnt = 0; + running = true; + phy_state = IDLE; + time_adv_sec = 0; + cell_is_set = false; + sync_sfn_cnt = 0; + srate_mode = SRATE_NONE; + cell_search_in_progress = false; + current_earfcn = 0; + radio_is_resetting = false; +} + +void phch_recv::radio_error() { + log_h->error("SYNC: Receiving from radio.\n"); + phy_state = IDLE; + radio_is_resetting=true; + radio_h->reset(); + reset(); + radio_is_resetting=false; +} + +bool phch_recv::wait_radio_reset() { + int cnt=0; + while(cnt < 20 && radio_is_resetting) { + sleep(1); + cnt++; + } + return radio_is_resetting; +} + void phch_recv::set_agc_enable(bool enable) { do_agc = enable; } @@ -394,6 +417,9 @@ int phch_recv::cell_meas_rsrp() { } void phch_recv::resync_sfn() { + + wait_radio_reset(); + stop_rx(); start_rx(); srslte_ue_mib_reset(&ue_mib); @@ -407,6 +433,9 @@ void phch_recv::set_earfcn(std::vector earfcn) { } bool phch_recv::stop_sync() { + + wait_radio_reset(); + if (phy_state == IDLE && is_in_idle) { return true; } else { @@ -421,6 +450,16 @@ bool phch_recv::stop_sync() { } } +void phch_recv::reset_sync() { + + wait_radio_reset(); + + Info("SYNC: Resetting sync\n"); + srslte_ue_sync_reset(&ue_mib_sync.ue_sync); + srslte_ue_sync_reset(&ue_sync); + resync_sfn(); +} + void phch_recv::cell_search_inc() { cur_earfcn_index++; @@ -540,17 +579,20 @@ bool phch_recv::set_frequency() void phch_recv::set_sampling_rate() { float srate = (float) srslte_sampling_freq_hz(cell.nof_prb); + if (srate != -1) { + Info("SYNC: Setting sampling rate %.2f MHz\n", srate/1000000); - Info("SYNC: Setting sampling rate %.2f MHz\n", srate/1000000); - - if (30720 % ((int) srate / 1000) == 0) { - radio_h->set_master_clock_rate(30.72e6); + if (30720 % ((int) srate / 1000) == 0) { + radio_h->set_master_clock_rate(30.72e6); + } else { + radio_h->set_master_clock_rate(23.04e6); + } + srate_mode = SRATE_CAMP; + radio_h->set_rx_srate(srate); + radio_h->set_tx_srate(srate); } else { - radio_h->set_master_clock_rate(23.04e6); + Error("Error setting sampling rate for cell with %d PRBs\n", cell.nof_prb); } - srate_mode = SRATE_CAMP; - radio_h->set_rx_srate(srate); - radio_h->set_tx_srate(srate); } void phch_recv::run_thread() { @@ -585,9 +627,8 @@ void phch_recv::run_thread() { } break; default: - log_h->error("SYNC: Receiving frorm radio.\n"); - phy_state = IDLE; - radio_h->reset(); + radio_error(); + break; } } break; @@ -610,9 +651,7 @@ void phch_recv::run_thread() { case 0: break; default: - log_h->error("SYNC: Receiving frorm radio.\n"); - phy_state = IDLE; - radio_h->reset(); + radio_error(); break; } sync_sfn_cnt++; @@ -632,9 +671,8 @@ void phch_recv::run_thread() { case 0: break; default: - log_h->error("SYNC: Receiving frorm radio.\n"); - phy_state = IDLE; - radio_h->reset(); + radio_error(); + break; } break; case CELL_CAMP: @@ -694,9 +732,8 @@ void phch_recv::run_thread() { worker_com->reset_ul(); break; default: - log_h->error("SYNC: Receiving from radio.\n"); - phy_state = IDLE; - radio_h->reset(); + radio_error(); + break; } } else { // wait_worker() only returns NULL if it's being closed. Quit now to avoid unnecessary loops here diff --git a/srsue/src/phy/phy.cc b/srsue/src/phy/phy.cc index 6ae745d84..afce102b3 100644 --- a/srsue/src/phy/phy.cc +++ b/srsue/src/phy/phy.cc @@ -242,6 +242,10 @@ void phy::cell_search_next() sf_recv.cell_search_next(); } +void phy::sync_reset() { + sf_recv.reset_sync(); +} + bool phy::cell_select(uint32_t earfcn, srslte_cell_t phy_cell) { return sf_recv.cell_select(earfcn, phy_cell); diff --git a/srsue/src/upper/gw.cc b/srsue/src/upper/gw.cc index 19c4f38d2..07ac36989 100644 --- a/srsue/src/upper/gw.cc +++ b/srsue/src/upper/gw.cc @@ -232,8 +232,10 @@ void gw::run_thread() int32 N_bytes; srslte::byte_buffer_t *pdu = pool_allocate; - const static uint32_t ATTACH_TIMEOUT_MS = 2000; + const static uint32_t ATTACH_TIMEOUT_MS = 10000; + const static uint32_t ATTACH_MAX_ATTEMPTS = 3; uint32_t attach_cnt = 0; + uint32_t attach_attempts = 0; gw_log->info("GW IP packet receiver thread run_enable\n"); @@ -260,10 +262,11 @@ void gw::run_thread() { gw_log->info_hex(pdu->msg, pdu->N_bytes, "TX PDU"); - while(run_enable && !pdcp->is_drb_enabled(lcid)) { + while(run_enable && !pdcp->is_drb_enabled(lcid) && attach_attempts < ATTACH_MAX_ATTEMPTS) { if (attach_cnt == 0) { - gw_log->info("LCID=%d not active, requesting NAS attach\n", lcid); + gw_log->info("LCID=%d not active, requesting NAS attach (%d/%d)\n", lcid, attach_attempts, ATTACH_MAX_ATTEMPTS); nas->attach_request(); + attach_attempts++; } attach_cnt++; if (attach_cnt == ATTACH_TIMEOUT_MS) { @@ -271,6 +274,12 @@ void gw::run_thread() } usleep(1000); } + + if (attach_attempts == ATTACH_MAX_ATTEMPTS) { + gw_log->warning("LCID=%d was not active after %d attempts\n", lcid, ATTACH_MAX_ATTEMPTS); + } + + attach_attempts = 0; attach_cnt = 0; if (!run_enable) { @@ -278,18 +287,20 @@ void gw::run_thread() } // Send PDU directly to PDCP - pdu->set_timestamp(); - ul_tput_bytes += pdu->N_bytes; - pdcp->write_sdu(lcid, pdu); + if (pdcp->is_drb_enabled(lcid)) { + pdu->set_timestamp(); + ul_tput_bytes += pdu->N_bytes; + pdcp->write_sdu(lcid, pdu); - do { - pdu = pool_allocate; - if (!pdu) { - printf("Not enough buffers in pool\n"); - usleep(100000); - } - } while(!pdu); - idx = 0; + do { + pdu = pool_allocate; + if (!pdu) { + printf("Not enough buffers in pool\n"); + usleep(100000); + } + } while(!pdu); + idx = 0; + } }else{ idx += N_bytes; } diff --git a/srsue/src/upper/nas.cc b/srsue/src/upper/nas.cc index f7f0598d3..91b35ce01 100644 --- a/srsue/src/upper/nas.cc +++ b/srsue/src/upper/nas.cc @@ -121,6 +121,10 @@ bool nas::is_attached() { return state == EMM_STATE_REGISTERED; } +bool nas::is_attaching() { + return state == EMM_STATE_REGISTERED_INITIATED; +} + void nas::notify_connection_setup() { nas_log->debug("State = %s\n", emm_state_text[state]); if (EMM_STATE_REGISTERED_INITIATED == state) { diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index a55148c59..8f064dd3a 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -154,13 +154,22 @@ void rrc::run_thread() { case RRC_STATE_IDLE: // If camping on the cell, it will receive SI and paging from PLMN if (phy->sync_status()) { - + // If attempting to attach, reselect cell + if (nas->is_attaching()) { + sleep(1); + rrc_log->info("RRC IDLE: NAS is attaching and camping on cell, reselecting...\n"); + plmn_select(selected_plmn_id); + } // If not camping on a cell } else { // If NAS is attached, perform cell reselection on current PLMN if (nas->is_attached()) { rrc_log->info("RRC IDLE: NAS is attached, PHY not synchronized. Re-selecting cell...\n"); plmn_select(selected_plmn_id); + } else if (nas->is_attaching()) { + sleep(1); + rrc_log->info("RRC IDLE: NAS is attaching, searching again PLMN\n"); + plmn_search(); } // If not attached, PLMN selection will be triggered from higher layers } @@ -358,6 +367,7 @@ void rrc::plmn_select(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id) { 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"); 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()); // Sort cells according to RSRP @@ -495,6 +505,7 @@ 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) { @@ -681,7 +692,7 @@ void rrc::send_con_restablish_request() { rrc_log->debug("Setting UE contention resolution ID: %d\n", uecri); mac->set_contention_id(uecri); - rrc_log->info("Sending RRC Connection Resetablishment Request on SRB0\n"); + rrc_log->info("Sending RRC Connection Reestablishment Request on SRB0\n"); pdcp->write_sdu(RB_ID_SRB0, pdcp_buf); }