mirror of https://github.com/PentHertz/srsLTE.git
Improved stability after radio link failure and radio transport error
This commit is contained in:
parent
fcbcf1ec7b
commit
4a86967530
|
@ -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;
|
||||
|
|
|
@ -54,7 +54,7 @@ public:
|
|||
|
||||
void set_earfcn(std::vector<uint32_t> 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<uint32_t> 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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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<uint32_t> 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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue