Remove SNR threshold based link failure detection

master
Ismael Gomez 5 years ago committed by Andre Puschmann
parent 874e614970
commit 493b7ea2da

@ -182,10 +182,6 @@ public:
virtual int get_mch_sched(uint32_t tti, bool is_mcch, dl_sched_list_t& dl_sched_res) = 0; virtual int get_mch_sched(uint32_t tti, bool is_mcch, dl_sched_list_t& dl_sched_res) = 0;
virtual int get_ul_sched(uint32_t tti, ul_sched_list_t& ul_sched_res) = 0; virtual int get_ul_sched(uint32_t tti, ul_sched_list_t& ul_sched_res) = 0;
virtual void set_sched_dl_tti_mask(uint8_t* tti_mask, uint32_t nof_sfs) = 0; virtual void set_sched_dl_tti_mask(uint8_t* tti_mask, uint32_t nof_sfs) = 0;
// Radio-Link status
virtual void rl_failure(uint16_t rnti) = 0;
virtual void rl_ok(uint16_t rnti) = 0;
}; };
/* Interface MAC -> PHY */ /* Interface MAC -> PHY */
@ -410,7 +406,6 @@ class rrc_interface_mac
{ {
public: public:
/* Radio Link failure */ /* Radio Link failure */
virtual void rl_failure(uint16_t rnti) = 0;
virtual void add_user(uint16_t rnti, const sched_interface::ue_cfg_t& init_ue_cfg) = 0; virtual void add_user(uint16_t rnti, const sched_interface::ue_cfg_t& init_ue_cfg) = 0;
virtual void upd_user(uint16_t new_rnti, uint16_t old_rnti) = 0; virtual void upd_user(uint16_t new_rnti, uint16_t old_rnti) = 0;
virtual void set_activity_user(uint16_t rnti) = 0; virtual void set_activity_user(uint16_t rnti) = 0;
@ -544,7 +539,6 @@ typedef struct {
typedef struct { typedef struct {
uint32_t nof_prb; ///< Needed to dimension MAC softbuffers for all cells uint32_t nof_prb; ///< Needed to dimension MAC softbuffers for all cells
sched_interface::sched_args_t sched; sched_interface::sched_args_t sched;
int link_failure_nof_err;
int nr_tb_size = -1; int nr_tb_size = -1;
} mac_args_t; } mac_args_t;

@ -531,7 +531,11 @@ enb_dl_get_ack_fdd_pcell_skip_drx(const srslte_uci_value_t* uci_value, srslte_pd
for (uint32_t tb = 0; tb < nof_tb; tb++) { for (uint32_t tb = 0; tb < nof_tb; tb++) {
// Check that TB was transmitted // Check that TB was transmitted
if (pdsch_ack->cc[0].m[0].value[tb] != 2) { if (pdsch_ack->cc[0].m[0].value[tb] != 2) {
pdsch_ack->cc[0].m[0].value[tb] = uci_value->ack.ack_value[ack_idx++]; if (uci_value->ack.valid) {
pdsch_ack->cc[0].m[0].value[tb] = uci_value->ack.ack_value[ack_idx++];
} else {
pdsch_ack->cc[0].m[0].value[tb] = 0;
}
} }
} }
} }
@ -545,7 +549,11 @@ enb_dl_get_ack_fdd_all_keep_drx(const srslte_uci_value_t* uci_value, srslte_pdsc
for (uint32_t tb = 0; tb < nof_tb; tb++) { for (uint32_t tb = 0; tb < nof_tb; tb++) {
// Check that TB was transmitted // Check that TB was transmitted
if (pdsch_ack->cc[cc_idx].m[0].value[tb] != 2) { if (pdsch_ack->cc[cc_idx].m[0].value[tb] != 2) {
pdsch_ack->cc[cc_idx].m[0].value[tb] = uci_value->ack.ack_value[cc_idx * nof_tb + tb]; if (uci_value->ack.valid) {
pdsch_ack->cc[cc_idx].m[0].value[tb] = uci_value->ack.ack_value[cc_idx * nof_tb + tb];
} else {
pdsch_ack->cc[cc_idx].m[0].value[tb] = 0;
}
} }
} }
} }

@ -277,8 +277,6 @@ pusch_max_mcs = 16
# metrics_csv_filename: File path to use for CSV metrics. # metrics_csv_filename: File path to use for CSV metrics.
# pregenerate_signals: Pregenerate uplink signals after attach. Improves CPU performance. # pregenerate_signals: Pregenerate uplink signals after attach. Improves CPU performance.
# tx_amplitude: Transmit amplitude factor (set 0-1 to reduce PAPR) # tx_amplitude: Transmit amplitude factor (set 0-1 to reduce PAPR)
# link_failure_nof_err: Number of PUSCH failures after which a radio-link failure is triggered.
# a link failure is when SNR<0 and CRC=KO
# max_prach_offset_us: Maximum allowed RACH offset (in us) # max_prach_offset_us: Maximum allowed RACH offset (in us)
# eea_pref_list: Ordered preference list for the selection of encryption algorithm (EEA) (default: EEA0, EEA2, EEA1). # eea_pref_list: Ordered preference list for the selection of encryption algorithm (EEA) (default: EEA0, EEA2, EEA1).
# eia_pref_list: Ordered preference list for the selection of integrity algorithm (EIA) (default: EIA2, EIA1, EIA0). # eia_pref_list: Ordered preference list for the selection of integrity algorithm (EIA) (default: EIA2, EIA1, EIA0).
@ -293,7 +291,6 @@ pusch_max_mcs = 16
#metrics_csv_filename = /tmp/enb_metrics.csv #metrics_csv_filename = /tmp/enb_metrics.csv
#pregenerate_signals = false #pregenerate_signals = false
#tx_amplitude = 0.6 #tx_amplitude = 0.6
#link_failure_nof_err = 50
#rrc_inactivity_timer = 60000 #rrc_inactivity_timer = 60000
#max_prach_offset_us = 30 #max_prach_offset_us = 30
#eea_pref_list = EEA0, EEA2, EEA1 #eea_pref_list = EEA0, EEA2, EEA1

@ -101,9 +101,6 @@ public:
{ {
mac.set_sched_dl_tti_mask(tti_mask, nof_sfs); mac.set_sched_dl_tti_mask(tti_mask, nof_sfs);
} }
// Radio-Link status
void rl_failure(uint16_t rnti) final { mac.rl_failure(rnti); }
void rl_ok(uint16_t rnti) final { mac.rl_ok(rnti); }
void tti_clock() override; void tti_clock() override;
/* STACK-S1AP interface*/ /* STACK-S1AP interface*/

@ -74,8 +74,6 @@ public:
scheduler.set_dl_tti_mask(tti_mask, nof_sfs); scheduler.set_dl_tti_mask(tti_mask, nof_sfs);
} }
void build_mch_sched(uint32_t tbs); void build_mch_sched(uint32_t tbs);
void rl_failure(uint16_t rnti) override;
void rl_ok(uint16_t rnti) override;
/******** Interface from RRC (RRC -> MAC) ****************/ /******** Interface from RRC (RRC -> MAC) ****************/
/* Provides cell configuration including SIB periodicity, etc. */ /* Provides cell configuration including SIB periodicity, etc. */

@ -84,9 +84,6 @@ public:
void push_pdu(const uint32_t ue_cc_idx, const uint32_t tti, uint32_t len); void push_pdu(const uint32_t ue_cc_idx, const uint32_t tti, uint32_t len);
void deallocate_pdu(const uint32_t ue_cc_idx, const uint32_t tti); void deallocate_pdu(const uint32_t ue_cc_idx, const uint32_t tti);
uint32_t rl_failure();
void rl_failure_reset();
void set_lcg(uint32_t lcid, uint32_t lcg); void set_lcg(uint32_t lcid, uint32_t lcg);
void metrics_read(srsenb::mac_metrics_t* metrics); void metrics_read(srsenb::mac_metrics_t* metrics);

@ -69,7 +69,6 @@ public:
void tti_clock(); void tti_clock();
// rrc_interface_mac // rrc_interface_mac
void rl_failure(uint16_t rnti) override;
void add_user(uint16_t rnti, const sched_interface::ue_cfg_t& init_ue_cfg) override; void add_user(uint16_t rnti, const sched_interface::ue_cfg_t& init_ue_cfg) override;
void upd_user(uint16_t new_rnti, uint16_t old_rnti) override; void upd_user(uint16_t new_rnti, uint16_t old_rnti) override;
void set_activity_user(uint16_t rnti) override; void set_activity_user(uint16_t rnti) override;
@ -142,7 +141,6 @@ private:
std::map<uint32_t, asn1::rrc::paging_record_s> pending_paging; std::map<uint32_t, asn1::rrc::paging_record_s> pending_paging;
void process_release_complete(uint16_t rnti); void process_release_complete(uint16_t rnti);
void process_rl_failure(uint16_t rnti);
void rem_user(uint16_t rnti); void rem_user(uint16_t rnti);
uint32_t generate_sibs(); uint32_t generate_sibs();
void configure_mbsfn_sibs(asn1::rrc::sib_type2_s* sib2, asn1::rrc::sib_type13_r9_s* sib13); void configure_mbsfn_sibs(asn1::rrc::sib_type2_s* sib2, asn1::rrc::sib_type13_r9_s* sib13);
@ -162,7 +160,6 @@ private:
const static uint32_t LCID_EXIT = 0xffff0000; const static uint32_t LCID_EXIT = 0xffff0000;
const static uint32_t LCID_REM_USER = 0xffff0001; const static uint32_t LCID_REM_USER = 0xffff0001;
const static uint32_t LCID_REL_USER = 0xffff0002; const static uint32_t LCID_REL_USER = 0xffff0002;
const static uint32_t LCID_RLF_USER = 0xffff0003;
const static uint32_t LCID_ACT_USER = 0xffff0004; const static uint32_t LCID_ACT_USER = 0xffff0004;
bool running = false; bool running = false;

@ -47,8 +47,6 @@ public:
void set_activity(); void set_activity();
void activity_timer_expired(); void activity_timer_expired();
uint32_t rl_failure();
rrc_state_t get_state(); rrc_state_t get_state();
void send_connection_setup(); void send_connection_setup();

@ -184,7 +184,6 @@ void parse_args(all_args_t* args, int argc, char* argv[])
("expert.pusch_meas_evm", bpo::value<bool>(&args->phy.pusch_meas_evm)->default_value(false), "Enable/Disable PUSCH EVM measure") ("expert.pusch_meas_evm", bpo::value<bool>(&args->phy.pusch_meas_evm)->default_value(false), "Enable/Disable PUSCH EVM measure")
("expert.tx_amplitude", bpo::value<float>(&args->phy.tx_amplitude)->default_value(0.6), "Transmit amplitude factor") ("expert.tx_amplitude", bpo::value<float>(&args->phy.tx_amplitude)->default_value(0.6), "Transmit amplitude factor")
("expert.nof_phy_threads", bpo::value<int>(&args->phy.nof_phy_threads)->default_value(3), "Number of PHY threads") ("expert.nof_phy_threads", bpo::value<int>(&args->phy.nof_phy_threads)->default_value(3), "Number of PHY threads")
("expert.link_failure_nof_err", bpo::value<int>(&args->stack.mac.link_failure_nof_err)->default_value(100), "Number of PUSCH failures after which a radio-link failure is triggered")
("expert.max_prach_offset_us", bpo::value<float>(&args->phy.max_prach_offset_us)->default_value(30), "Maximum allowed RACH offset (in us)") ("expert.max_prach_offset_us", bpo::value<float>(&args->phy.max_prach_offset_us)->default_value(30), "Maximum allowed RACH offset (in us)")
("expert.equalizer_mode", bpo::value<string>(&args->phy.equalizer_mode)->default_value("mmse"), "Equalizer mode") ("expert.equalizer_mode", bpo::value<string>(&args->phy.equalizer_mode)->default_value("mmse"), "Equalizer mode")
("expert.estimator_fil_w", bpo::value<float>(&args->phy.estimator_fil_w)->default_value(0.1), "Chooses the coefficients for the 3-tap channel estimator centered filter.") ("expert.estimator_fil_w", bpo::value<float>(&args->phy.estimator_fil_w)->default_value(0.1), "Chooses the coefficients for the 3-tap channel estimator centered filter.")

@ -335,19 +335,15 @@ void cc_worker::decode_pusch_rnti(stack_interface_phy_lte::ul_sched_grant_t& ul_
phy->stack->snr_info(ul_sf.tti, rnti, cc_idx, snr_db); phy->stack->snr_info(ul_sf.tti, rnti, cc_idx, snr_db);
if (ul_grant.dci.tb.rv == 0) { if (ul_grant.dci.tb.rv == 0) {
if (!pusch_res.crc) { // Notify MAC of Time Alignment only if it enabled and valid measurement, ignore value otherwise
Debug("PUSCH: Radio-Link failure snr=%.1f dB\n", snr_db); if (ul_cfg.pusch.meas_ta_en and not std::isnan(enb_ul.chest_res.ta_us) and
phy->stack->rl_failure(rnti); not std::isinf(enb_ul.chest_res.ta_us)) {
} else { phy->stack->ta_info(ul_sf.tti, rnti, enb_ul.chest_res.ta_us);
phy->stack->rl_ok(rnti);
// Notify MAC of Time Alignment only if it enabled and valid measurement, ignore value otherwise
if (ul_cfg.pusch.meas_ta_en and not std::isnan(enb_ul.chest_res.ta_us) and
not std::isinf(enb_ul.chest_res.ta_us)) {
phy->stack->ta_info(ul_sf.tti, rnti, enb_ul.chest_res.ta_us);
}
} }
} }
pusch_res.uci.ack.valid = true;
} else {
pusch_res.uci.ack.valid = false;
} }
// Send UCI data to MAC // Send UCI data to MAC
@ -408,16 +404,6 @@ int cc_worker::decode_pucch()
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
// Notify MAC of RL status (skip SR subframes)
if (!ul_cfg.pucch.uci_cfg.is_scheduling_request_tti) {
if (pucch_res.correlation < PUCCH_RL_CORR_TH) {
Debug("PUCCH: Radio-Link failure corr=%.1f\n", pucch_res.correlation);
phy->stack->rl_failure(rnti);
} else {
phy->stack->rl_ok(rnti);
}
}
// Send UCI data to MAC // Send UCI data to MAC
phy->ue_db.send_uci_data(tti_rx, rnti, cc_idx, ul_cfg.pucch.uci_cfg, pucch_res.uci_data); phy->ue_db.send_uci_data(tti_rx, rnti, cc_idx, ul_cfg.pucch.uci_cfg, pucch_res.uci_data);

@ -293,31 +293,6 @@ void mac::get_metrics(mac_metrics_t metrics[ENB_METRICS_MAX_USERS])
* *
*******************************************************/ *******************************************************/
void mac::rl_failure(uint16_t rnti)
{
srslte::rwlock_read_guard lock(rwlock);
if (ue_db.count(rnti)) {
uint32_t nof_fails = ue_db[rnti]->rl_failure();
if (nof_fails >= (uint32_t)args.link_failure_nof_err && args.link_failure_nof_err > 0) {
Info("Detected Uplink failure for rnti=0x%x\n", rnti);
rrc_h->rl_failure(rnti);
ue_db[rnti]->rl_failure_reset();
}
} else {
Error("User rnti=0x%x not found\n", rnti);
}
}
void mac::rl_ok(uint16_t rnti)
{
srslte::rwlock_read_guard lock(rwlock);
if (ue_db.count(rnti)) {
ue_db[rnti]->rl_failure_reset();
} else {
Error("User rnti=0x%x not found\n", rnti);
}
}
int mac::ack_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t tb_idx, bool ack) int mac::ack_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t tb_idx, bool ack)
{ {
srslte::rwlock_read_guard lock(rwlock); srslte::rwlock_read_guard lock(rwlock);
@ -329,7 +304,7 @@ int mac::ack_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t tb_
if (ack) { if (ack) {
if (nof_bytes > 64) { // do not count RLC status messages only if (nof_bytes > 64) { // do not count RLC status messages only
rrc_h->set_activity_user(rnti); rrc_h->set_activity_user(rnti);
log_h->debug("DL activity rnti=0x%x, n_bytes=%d\n", rnti, nof_bytes); log_h->info("DL activity rnti=0x%x, n_bytes=%d\n", rnti, nof_bytes);
} }
} }
} }

@ -158,17 +158,6 @@ void ue::start_pcap(srslte::mac_pcap* pcap_)
pcap = pcap_; pcap = pcap_;
} }
uint32_t ue::rl_failure()
{
nof_failures++;
return nof_failures;
}
void ue::rl_failure_reset()
{
nof_failures = 0;
}
void ue::set_lcg(uint32_t lcid, uint32_t lcg) void ue::set_lcg(uint32_t lcid, uint32_t lcg)
{ {
// find and remove if already exists // find and remove if already exists

@ -122,12 +122,6 @@ uint8_t* rrc::read_pdu_bcch_dlsch(const uint8_t cc_idx, const uint32_t sib_index
return nullptr; return nullptr;
} }
void rrc::rl_failure(uint16_t rnti)
{
rrc_pdu p = {rnti, LCID_RLF_USER, nullptr};
rx_pdu_queue.push(std::move(p));
}
void rrc::set_activity_user(uint16_t rnti) void rrc::set_activity_user(uint16_t rnti)
{ {
rrc_pdu p = {rnti, LCID_ACT_USER, nullptr}; rrc_pdu p = {rnti, LCID_ACT_USER, nullptr};
@ -503,31 +497,6 @@ void rrc::parse_ul_dcch(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer
} }
} }
///< User mutex must be hold by caller
void rrc::process_rl_failure(uint16_t rnti)
{
auto user_it = users.find(rnti);
if (user_it != users.end()) {
uint32_t n_rfl = user_it->second->rl_failure();
if (n_rfl == 1) {
rrc_log->info("Radio-Link failure detected rnti=0x%x\n", rnti);
if (s1ap->user_exists(rnti)) {
if (!s1ap->user_release(rnti, asn1::s1ap::cause_radio_network_opts::radio_conn_with_ue_lost)) {
rrc_log->info("Removing rnti=0x%x\n", rnti);
}
} else {
rrc_log->warning("User rnti=0x%x context not existing in S1AP. Removing user\n", rnti);
// Remove user from separate thread to wait to close all resources
rem_user_thread(rnti);
}
} else {
rrc_log->info("%d Radio-Link failure detected rnti=0x%x\n", n_rfl, rnti);
}
} else {
rrc_log->error("Radio-Link failure detected for unknown rnti=0x%x\n", rnti);
}
}
///< User mutex must be hold by caller ///< User mutex must be hold by caller
void rrc::process_release_complete(uint16_t rnti) void rrc::process_release_complete(uint16_t rnti)
{ {
@ -788,9 +757,6 @@ void rrc::tti_clock()
case LCID_REL_USER: case LCID_REL_USER:
process_release_complete(p.rnti); process_release_complete(p.rnti);
break; break;
case LCID_RLF_USER:
process_rl_failure(p.rnti);
break;
case LCID_ACT_USER: case LCID_ACT_USER:
user_it->second->set_activity(); user_it->second->set_activity();
break; break;

@ -72,12 +72,6 @@ rrc_state_t rrc::ue::get_state()
return state; return state;
} }
uint32_t rrc::ue::rl_failure()
{
rlf_cnt++;
return rlf_cnt;
}
void rrc::ue::set_activity() void rrc::ue::set_activity()
{ {
// re-start activity timer with current timeout value // re-start activity timer with current timeout value

@ -291,8 +291,6 @@ private:
CALLBACK(get_mch_sched); CALLBACK(get_mch_sched);
CALLBACK(get_ul_sched); CALLBACK(get_ul_sched);
CALLBACK(set_sched_dl_tti_mask); CALLBACK(set_sched_dl_tti_mask);
CALLBACK(rl_failure);
CALLBACK(rl_ok);
CALLBACK(tti_clock); CALLBACK(tti_clock);
typedef struct { typedef struct {
@ -679,8 +677,6 @@ public:
return SRSLTE_SUCCESS; return SRSLTE_SUCCESS;
} }
void set_sched_dl_tti_mask(uint8_t* tti_mask, uint32_t nof_sfs) override { notify_set_sched_dl_tti_mask(); } void set_sched_dl_tti_mask(uint8_t* tti_mask, uint32_t nof_sfs) override { notify_set_sched_dl_tti_mask(); }
void rl_failure(uint16_t rnti) override { notify_rl_failure(); }
void rl_ok(uint16_t rnti) override { notify_rl_ok(); }
void tti_clock() override { notify_tti_clock(); } void tti_clock() override { notify_tti_clock(); }
int run_tti(bool enable_assert) int run_tti(bool enable_assert)
{ {
@ -1283,12 +1279,6 @@ public:
{ {
int ret = SRSLTE_SUCCESS; int ret = SRSLTE_SUCCESS;
// If no assertion enabled, clear radio link failure to avoid errors in cell transitions
if (change_state != change_state_assert) {
stack->clear_rl_failure();
}
TESTASSERT(not stack->get_received_rl_failure());
TESTASSERT(ue_phy->run_tti() >= SRSLTE_SUCCESS); TESTASSERT(ue_phy->run_tti() >= SRSLTE_SUCCESS);
TESTASSERT(stack->run_tti(change_state == change_state_assert) >= SRSLTE_SUCCESS); TESTASSERT(stack->run_tti(change_state == change_state_assert) >= SRSLTE_SUCCESS);

Loading…
Cancel
Save