Fix implementation of Random Access problem (#1689)

* Fix implementation of Random Access problem

* Apply AS activated condition on RLF before calling Reestablishment
This commit is contained in:
Ismael Gomez 2020-09-04 13:13:42 +02:00 committed by GitHub
parent f49fbd6d02
commit 4c1d3ef7e8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 79 additions and 26 deletions

View File

@ -561,8 +561,11 @@ bool rrc::mbms_service_start(uint32_t serv, uint32_t port)
*******************************************************************************/ *******************************************************************************/
/* /*
* This function is called from T310 expiry, RA problem or RLC max retx * 5.3.11.3 Detection of RLF
* Pushes a command to the command queue to process the actions in the background * The RLF procedure starts:
* - upon T310 expiry;
* - upon random access problem indication from MAC while neither T300, T301, T304 nor T311 is running; or
* - upon indication from RLC that the maximum number of retransmissions has been reached:
*/ */
void rrc::radio_link_failure_push_cmd() void rrc::radio_link_failure_push_cmd()
{ {
@ -578,11 +581,18 @@ void rrc::radio_link_failure_push_cmd()
void rrc::radio_link_failure_process() void rrc::radio_link_failure_process()
{ {
// TODO: Generate and store failure report // TODO: Generate and store failure report
rrc_log->warning("Detected Radio-Link Failure\n");
rrc_log->console("Warning: Detected Radio-Link Failure\n"); rrc_log->console("Warning: Detected Radio-Link Failure\n");
if (state == RRC_STATE_CONNECTED) { if (state == RRC_STATE_CONNECTED) {
start_con_restablishment(reest_cause_e::other_fail); if (security_is_activated) {
rrc_log->warning("Detected Radio-Link Failure while SA activated. Starting ConnectionReestablishment...\n");
start_con_restablishment(reest_cause_e::other_fail);
} else {
rrc_log->warning("Detected Radio-Link Failure while SA not activated. Going to IDLE...\n");
start_go_idle();
}
} else {
rrc_log->warning("Detected Radio-Link Failure while RRC_IDLE. Ignoring it.\n");
} }
} }
@ -597,13 +607,18 @@ void rrc::release_pucch_srs()
void rrc::ra_problem() void rrc::ra_problem()
{ {
rrc_log->warning("MAC indicated RA problem\n"); if (not t300.is_running() and not t301.is_running() and not t304.is_running() and not t311.is_running()) {
rrc_log->warning("MAC indicated RA problem. Starting RLF\n");
radio_link_failure_push_cmd();
} else {
rrc_log->warning("MAC indicated RA problem but either T300, T301, T304 or T311 is running. Ignoring it.\n");
}
} }
void rrc::max_retx_attempted() void rrc::max_retx_attempted()
{ {
// TODO: Handle the radio link failure // TODO: Handle the radio link failure
rrc_log->warning("Max RLC reTx attempted\n"); rrc_log->warning("Max RLC reTx attempted. Starting RLF\n");
radio_link_failure_push_cmd(); radio_link_failure_push_cmd();
} }

View File

@ -1190,11 +1190,7 @@ proc_outcome_t rrc::connection_reest_proc::init(asn1::rrc::reest_cause_e cause)
state = state_t::cell_reselection; state = state_t::cell_reselection;
} else { } else {
// 3GPP 36.331 Section 5.3.7.1 Warning("Conditions are NOT met to start ConnectionReestablishment\n");
// If AS security has not been activated, the UE does not initiate the procedure but instead
// moves to RRC_IDLE directly
Info("Conditions are NOT met\n");
rrc_ptr->start_go_idle();
return proc_outcome_t::success; return proc_outcome_t::success;
} }

View File

@ -52,13 +52,32 @@ public:
void set_config_mbsfn_sib2(srslte::mbsfn_sf_cfg_t* cfg_list, uint32_t nof_cfgs) override {} void set_config_mbsfn_sib2(srslte::mbsfn_sf_cfg_t* cfg_list, uint32_t nof_cfgs) override {}
void set_config_mbsfn_sib13(const srslte::sib13_t& sib13) override {} void set_config_mbsfn_sib13(const srslte::sib13_t& sib13) override {}
void set_config_mbsfn_mcch(const srslte::mcch_msg_t& mcch) override {} void set_config_mbsfn_mcch(const srslte::mcch_msg_t& mcch) override {}
cell_search_ret_t cell_search(phy_cell_t* cell) override { return {}; } cell_search_ret_t cell_search(phy_cell_t* cell) override
{
*cell = cell_search_res_cell;
cell_select_ret = true;
return cell_search_res_ret;
}
bool cell_is_camping() override { return false; } bool cell_is_camping() override { return false; }
void set_activation_deactivation_scell(uint32_t cmd) override {} void set_activation_deactivation_scell(uint32_t cmd) override {}
bool cell_select(const phy_cell_t* cell = nullptr) override bool cell_select(const phy_cell_t* cell = nullptr) override
{ {
last_selected_cell = *cell; last_selected_cell = *cell;
return true; bool ret = cell_select_ret;
if (return_to_true) {
cell_select_ret = true;
}
return ret;
}
void set_cell_select_ret(bool cell_select_ret_, bool return_to_true_)
{
cell_select_ret = cell_select_ret_;
return_to_true = return_to_true_;
}
void set_cell_search_result(phy_cell_t cell, cell_search_ret_t ret)
{
cell_search_res_cell = cell;
cell_search_res_ret = ret;
} }
void reset() override {} void reset() override {}
void enable_pregen_signals(bool enable) override {} void enable_pregen_signals(bool enable) override {}
@ -108,6 +127,10 @@ private:
std::map<uint32_t, std::set<uint32_t> > cells_started; std::map<uint32_t, std::set<uint32_t> > cells_started;
uint32_t serving_pci = 0; uint32_t serving_pci = 0;
uint32_t serving_earfcn = 0; uint32_t serving_earfcn = 0;
bool cell_select_ret = true;
bool return_to_true = true;
cell_search_ret_t cell_search_res_ret = {};
phy_cell_t cell_search_res_cell = {};
}; };
class nas_test : public srsue::nas class nas_test : public srsue::nas
@ -181,7 +204,15 @@ public:
nastest = std::unique_ptr<nas_test>(new nas_test(&stack->task_sched)); nastest = std::unique_ptr<nas_test>(new nas_test(&stack->task_sched));
pdcptest = std::unique_ptr<pdcp_test>(new pdcp_test(log_->get_service_name().c_str(), &stack->task_sched)); pdcptest = std::unique_ptr<pdcp_test>(new pdcp_test(log_->get_service_name().c_str(), &stack->task_sched));
}; };
void init() { rrc::init(&phytest, nullptr, nullptr, pdcptest.get(), nastest.get(), nullptr, nullptr, {}); } void init()
{
rrc::init(&phytest, nullptr, nullptr, pdcptest.get(), nastest.get(), nullptr, nullptr, {});
phy_interface_rrc_lte::phy_cell_t cell_search_cell = {};
phy_interface_rrc_lte::cell_search_ret_t cell_search_ret = {};
cell_search_ret.found = srsue::phy_interface_rrc_lte::cell_search_ret_t::CELL_NOT_FOUND;
cell_search_ret.last_freq = srsue::phy_interface_rrc_lte::cell_search_ret_t::NO_MORE_FREQS;
phytest.set_cell_search_result(cell_search_cell, cell_search_ret);
}
void run_tti(uint32_t tti_) void run_tti(uint32_t tti_)
{ {
@ -318,11 +349,6 @@ int cell_select_test()
TESTASSERT(rrctest.phytest.last_selected_cell.pci == 2); TESTASSERT(rrctest.phytest.last_selected_cell.pci == 2);
TESTASSERT(!rrctest.has_neighbour_cell(2, 2)); TESTASSERT(!rrctest.has_neighbour_cell(2, 2));
TESTASSERT(rrctest.has_neighbour_cell(1, 1)); TESTASSERT(rrctest.has_neighbour_cell(1, 1));
// PHY reports back the result
rrctest.cell_select_completed(true);
TESTASSERT(!rrctest.has_neighbour_cell(2, 2));
TESTASSERT(rrctest.has_neighbour_cell(1, 1));
// Note: cell selection procedure is not done yet at this point. // Note: cell selection procedure is not done yet at this point.
} }
@ -337,21 +363,37 @@ int cell_select_test()
rrctest.add_neighbour_cell(1, 1, 2.0); rrctest.add_neighbour_cell(1, 1, 2.0);
rrctest.add_neighbour_cell(2, 2, 1.0); rrctest.add_neighbour_cell(2, 2, 1.0);
rrctest.add_neighbour_cell(3, 2, 1.0);
rrctest.set_serving_cell(1, 1); rrctest.set_serving_cell(1, 1);
TESTASSERT(not rrctest.has_neighbour_cell(1, 1)); TESTASSERT(not rrctest.has_neighbour_cell(1, 1));
TESTASSERT(rrctest.has_neighbour_cell(2, 2)); TESTASSERT(rrctest.has_neighbour_cell(2, 2));
TESTASSERT(rrctest.has_neighbour_cell(2, 3));
// Start cell selection procedure. The RRC will start with strongest cell // Start cell selection procedure. The RRC will start with strongest cell
TESTASSERT(rrctest.start_cell_select() == SRSLTE_SUCCESS); TESTASSERT(rrctest.start_cell_select() == SRSLTE_SUCCESS);
rrctest.phytest.set_cell_select_ret(false, true); // failed to set serving cell
stack.run_pending_tasks();
TESTASSERT(rrctest.phytest.last_selected_cell.earfcn == 2);
TESTASSERT(rrctest.phytest.last_selected_cell.pci == 2);
TESTASSERT(rrctest.has_neighbour_cell(1, 1));
TESTASSERT(rrctest.has_neighbour_cell(2, 3));
TESTASSERT(!rrctest.has_neighbour_cell(2, 2));
rrctest.in_sync();
stack.run_pending_tasks(); stack.run_pending_tasks();
TESTASSERT(rrctest.phytest.last_selected_cell.earfcn == 1);
TESTASSERT(rrctest.phytest.last_selected_cell.pci == 1);
TESTASSERT(rrctest.has_neighbour_cell(2, 2));
TESTASSERT(!rrctest.has_neighbour_cell(1, 1)); // selected current serving cell bc it is stronger
rrctest.cell_select_completed(false); // failed to set serving cell // Cell Selection fails, make sure it goes to Cell Search
TESTASSERT(rrctest.has_neighbour_cell(2, 2)); TESTASSERT(rrctest.start_cell_select() == SRSLTE_SUCCESS);
TESTASSERT(!rrctest.has_neighbour_cell(1, 1)); phy_interface_rrc_lte::phy_cell_t cell_search_cell = {};
phy_interface_rrc_lte::cell_search_ret_t cell_search_ret = {};
cell_search_cell.pci = 5;
cell_search_cell.earfcn = 5;
cell_search_ret.found = srsue::phy_interface_rrc_lte::cell_search_ret_t::CELL_FOUND;
rrctest.phytest.set_cell_search_result(cell_search_cell, cell_search_ret);
rrctest.phytest.set_cell_select_ret(false, false); // failed to set serving cell
stack.run_pending_tasks();
rrctest.in_sync();
TESTASSERT(rrctest.phytest.last_selected_cell.earfcn == 5);
TESTASSERT(rrctest.phytest.last_selected_cell.pci == 5);
} }
return SRSLTE_SUCCESS; return SRSLTE_SUCCESS;