fix edge case where serving cell is good enough for reestablishment but the sibs are not yet acquired

master
Francisco Paisana 4 years ago
parent f32d9f8322
commit 045f647914

@ -329,7 +329,7 @@ private:
// Senders
void send_con_request(srslte::establishment_cause_t cause);
void send_con_restablish_request(asn1::rrc::reest_cause_e cause, uint16_t rnti, uint16_t pci);
void send_con_restablish_request(asn1::rrc::reest_cause_e cause, uint16_t rnti, uint16_t pci, uint32_t cellid);
void send_con_restablish_complete();
void send_con_setup_complete(srslte::unique_byte_buffer_t nas_msg);
void send_ul_info_transfer(srslte::unique_byte_buffer_t nas_msg);

@ -89,6 +89,7 @@ public:
uint32_t get_cell_id() const { return (uint32_t)sib1.cell_access_related_info.cell_id.to_number(); }
bool has_sibs(srslte::span<uint32_t> indexes) const;
bool has_sib(uint32_t index) const;
bool has_sib1() const { return has_valid_sib1; }
bool has_sib2() const { return has_valid_sib2; }

@ -286,11 +286,10 @@ public:
private:
enum class state_t { wait_cell_selection, wait_reest_msg } state;
rrc* rrc_ptr = nullptr;
asn1::rrc::reest_cause_e reest_cause = asn1::rrc::reest_cause_e::nulltype;
uint16_t reest_rnti = 0;
uint16_t reest_source_pci = 0;
uint32_t reest_source_freq = 0;
rrc* rrc_ptr = nullptr;
asn1::rrc::reest_cause_e reest_cause = asn1::rrc::reest_cause_e::nulltype;
uint16_t reest_rnti = 0, reest_source_pci = 0;
uint32_t reest_source_freq = 0, reest_cellid = 0;
bool passes_cell_criteria() const;
srslte::proc_outcome_t cell_criteria();

@ -723,25 +723,11 @@ void rrc::send_con_request(srslte::establishment_cause_t cause)
}
/* RRC connection re-establishment procedure (5.3.7.4) */
void rrc::send_con_restablish_request(reest_cause_e cause, uint16_t crnti, uint16_t pci)
void rrc::send_con_restablish_request(reest_cause_e cause, uint16_t crnti, uint16_t pci, uint32_t cellid)
{
uint32_t cellid;
// Clean reestablishment type
reestablishment_successful = false;
if (cause == reest_cause_e::ho_fail) {
crnti = ho_handler.get()->ho_src_rnti;
pci = ho_handler.get()->ho_src_cell.get_pci();
cellid = ho_handler.get()->ho_src_cell.get_cell_id();
} else if (cause == reest_cause_e::other_fail) {
// use source PCI after RLF
cellid = meas_cells.serving_cell().get_cell_id();
} else {
pci = meas_cells.serving_cell().get_pci();
cellid = meas_cells.serving_cell().get_cell_id();
}
// Compute shortMAC-I
uint8_t varShortMAC_packed[16] = {};
asn1::bit_ref bref(varShortMAC_packed, sizeof(varShortMAC_packed));
@ -806,6 +792,10 @@ void rrc::send_con_restablish_request(reest_cause_e cause, uint16_t crnti, uint1
meas_cells.serving_cell().phy_cell.pci,
meas_cells.serving_cell().phy_cell.earfcn,
cause.to_string().c_str());
rrc_log->info("RRC Connection Reestablishment to PCI=%d, EARFCN=%d (Cause: \"%s\")\n",
meas_cells.serving_cell().phy_cell.pci,
meas_cells.serving_cell().phy_cell.earfcn,
cause.to_string().c_str());
send_ul_ccch_msg(ul_ccch_msg);
}

@ -75,6 +75,16 @@ uint32_t cell_t::timeout_secs(struct timeval now) const
return t[0].tv_sec;
}
bool cell_t::has_sibs(srslte::span<uint32_t> indexes) const
{
for (uint32_t idx : indexes) {
if (not has_sib(idx)) {
return false;
}
}
return true;
}
bool cell_t::has_sib(uint32_t index) const
{
switch (index) {

@ -456,8 +456,9 @@ rrc::cell_selection_proc::cell_selection_proc(rrc* parent_) : rrc_ptr(parent_) {
*/
proc_outcome_t rrc::cell_selection_proc::init(std::vector<uint32_t> required_sibs_)
{
if (rrc_ptr->meas_cells.nof_neighbours() == 0 and rrc_ptr->phy_ctrl->is_in_sync() and
rrc_ptr->phy->cell_is_camping()) {
bool serv_cell_is_ok = rrc_ptr->phy_ctrl->is_in_sync() and rrc_ptr->phy->cell_is_camping();
if (rrc_ptr->meas_cells.nof_neighbours() == 0 and serv_cell_is_ok and
rrc_ptr->meas_cells.serving_cell().has_sibs(required_sibs_)) {
// don't bother with cell selection if there are no neighbours and we are already camping
Debug("Skipping Cell Selection Procedure as there are no neighbour and cell is camping.\n");
cs_result = cs_result_t::same_cell;
@ -480,8 +481,16 @@ proc_outcome_t rrc::cell_selection_proc::init(std::vector<uint32_t> required_sib
} else {
required_sibs = std::move(required_sibs_);
}
neigh_index = 0;
cs_result = cs_result_t::no_cell;
neigh_index = 0;
cs_result = cs_result_t::no_cell;
if (serv_cell_is_ok) {
state = search_state_t::cell_config;
if (not rrc_ptr->serv_cell_cfg.launch(&serv_cell_cfg_fut, required_sibs)) {
Warning("Failed to launch %s procedure\n", rrc_ptr->serv_cell_cfg.get()->name());
return proc_outcome_t::error;
}
return proc_outcome_t::yield;
}
state = search_state_t::cell_selection;
discard_serving = false;
serv_cell_select_attempted = false;
@ -1159,18 +1168,26 @@ proc_outcome_t rrc::connection_reest_proc::init(asn1::rrc::reest_cause_e cause)
}
// Save reestablishment Cause and current C-RNTI context
reest_rnti = uernti.crnti;
reest_cause = cause;
reest_source_pci = rrc_ptr->meas_cells.serving_cell().get_pci(); // needed for reestablishment with another cell
reest_source_freq = rrc_ptr->meas_cells.serving_cell().get_earfcn();
reest_cause = cause;
if (reest_cause.value == reest_cause_opts::ho_fail) {
reest_rnti = rrc_ptr->ho_handler.get()->ho_src_rnti;
reest_source_pci = rrc_ptr->ho_handler.get()->ho_src_cell.get_pci();
reest_cellid = rrc_ptr->ho_handler.get()->ho_src_cell.get_cell_id();
reest_source_freq = rrc_ptr->ho_handler.get()->ho_src_cell.get_earfcn();
} else {
reest_rnti = uernti.crnti;
reest_source_pci = rrc_ptr->meas_cells.serving_cell().get_pci(); // needed for reestablishment with another cell
reest_cellid = rrc_ptr->meas_cells.serving_cell().get_cell_id();
reest_source_freq = rrc_ptr->meas_cells.serving_cell().get_earfcn();
}
Info("Starting... cause: \"%s\", UE context: {C-RNTI=0x%x, PCI=%d, DL-EARFCN=%d}\n",
Info("Starting... cause: \"%s\", UE context: {C-RNTI=0x%x, PCI=%d, CELL ID=%d}\n",
reest_cause == asn1::rrc::reest_cause_opts::recfg_fail
? "Reconfiguration failure"
: cause == asn1::rrc::reest_cause_opts::ho_fail ? "Handover failure" : "Other failure",
reest_rnti,
reest_source_pci,
reest_source_freq);
reest_cellid);
// 5.3.7.2 - Initiation
@ -1240,7 +1257,7 @@ srslte::proc_outcome_t rrc::connection_reest_proc::cell_criteria()
// Not implemented yet.
// 1> initiate transmission of the RRCConnectionReestablishmentRequest message in accordance with 5.3.7.4;
rrc_ptr->send_con_restablish_request(reest_cause, reest_rnti, reest_source_pci);
rrc_ptr->send_con_restablish_request(reest_cause, reest_rnti, reest_source_pci, reest_cellid);
state = state_t::wait_reest_msg;
return proc_outcome_t::yield;

Loading…
Cancel
Save