rrc::meas_cell now uses stack timers instead of system timers.

master
Francisco Paisana 4 years ago
parent 49ad1a4312
commit d910c910a4

@ -28,19 +28,29 @@
namespace srsue {
inline std::string to_string(const srsue::phy_cell_t& c)
{
char buffer[64];
snprintf(buffer, 64, "{earfcn=%d, pci=%d}\n", c.earfcn, c.pci);
return {buffer};
}
class meas_cell
{
public:
meas_cell() { gettimeofday(&last_update, nullptr); }
explicit meas_cell(phy_cell_t phy_cell_) : meas_cell() { phy_cell = phy_cell_; }
const static int neighbour_timeout_ms = 5000;
explicit meas_cell(srslte::unique_timer timer);
meas_cell(const phy_cell_t& phy_cell_, srslte::unique_timer timer);
// comparison based on pci and earfcn
bool is_valid() { return phy_cell.earfcn != 0 && srslte_cellid_isvalid(phy_cell.pci); }
bool is_valid() const { return phy_cell.earfcn != 0 && srslte_cellid_isvalid(phy_cell.pci); }
bool equals(const meas_cell& x) { return equals(x.phy_cell.earfcn, x.phy_cell.pci); }
bool equals(uint32_t earfcn, uint32_t pci) { return earfcn == phy_cell.earfcn && pci == phy_cell.pci; }
// NaN means an RSRP value has not yet been obtained. Keep then in the list and clean them if never updated
bool greater(meas_cell* x) { return rsrp > x->rsrp || std::isnan(rsrp); }
bool greater(const meas_cell* x) const { return rsrp > x->rsrp || std::isnan(rsrp); }
bool greater(const meas_cell& x) const { return rsrp > x.rsrp || std::isnan(rsrp); }
bool has_plmn_id(asn1::rrc::plmn_id_s plmn_id) const;
uint32_t nof_plmns() const { return has_sib1() ? sib1.cell_access_related_info.plmn_id_list.size() : 0; }
@ -55,7 +65,7 @@ public:
if (!std::isnan(rsrp_)) {
rsrp = rsrp_;
}
gettimeofday(&last_update, nullptr);
timer.run();
}
void set_rsrq(float rsrq_)
{
@ -74,9 +84,6 @@ public:
float get_rsrq() const { return rsrq; }
float get_cfo_hz() const { return phy_cell.cfo_hz; }
// TODO: replace with TTI count
uint32_t timeout_secs(struct timeval now) const;
void set_sib1(const asn1::rrc::sib_type1_s& sib1_);
void set_sib2(const asn1::rrc::sib_type2_s& sib2_);
void set_sib3(const asn1::rrc::sib_type3_s& sib3_);
@ -118,13 +125,12 @@ public:
asn1::rrc::sib_type3_s sib3 = {};
asn1::rrc::sib_type13_r9_s sib13 = {};
asn1::rrc::mcch_msg_s mcch = {};
srslte::unique_timer timer;
private:
float rsrp = NAN;
float rsrq = NAN;
struct timeval last_update = {};
bool has_valid_sib1 = false;
bool has_valid_sib2 = false;
bool has_valid_sib3 = false;
@ -168,7 +174,7 @@ public:
const static int MAX_NEIGHBOUR_CELLS = 8;
typedef std::unique_ptr<meas_cell> unique_meas_cell;
meas_cell_list();
explicit meas_cell_list(srslte::task_sched_handle task_sched_);
bool add_meas_cell(const phy_meas_t& meas);
bool add_meas_cell(unique_meas_cell cell);
@ -205,7 +211,9 @@ public:
private:
bool add_neighbour_cell_unsorted(unique_meas_cell cell);
srslte::log_ref log_h{"RRC"};
// args
srslte::log_ref log_h{"RRC"};
srslte::task_sched_handle task_sched;
unique_meas_cell serv_cell;
std::vector<unique_meas_cell> neighbour_cells;

@ -69,7 +69,8 @@ rrc::rrc(stack_interface_rrc* stack_, srslte::task_sched_handle task_sched_) :
cell_reselector(this),
connection_reest(this),
ho_handler(this),
conn_recfg_proc(this)
conn_recfg_proc(this),
meas_cells(task_sched_)
{}
rrc::~rrc() = default;

@ -23,6 +23,16 @@
namespace srsue {
meas_cell::meas_cell(srslte::unique_timer timer_) : timer(std::move(timer_))
{
timer.set(neighbour_timeout_ms);
timer.run();
}
meas_cell::meas_cell(const phy_cell_t& phy_cell_, srslte::unique_timer timer) : meas_cell(std::move(timer))
{
phy_cell = phy_cell_;
}
srslte::plmn_id_t meas_cell::get_plmn(uint32_t idx) const
{
if (idx < sib1.cell_access_related_info.plmn_id_list.size() && has_valid_sib1) {
@ -66,15 +76,6 @@ bool meas_cell::is_sib_scheduled(uint32_t sib_index) const
return sib_info_map.find(sib_index) != sib_info_map.end();
}
uint32_t meas_cell::timeout_secs(struct timeval now) const
{
struct timeval t[3];
memcpy(&t[2], &now, sizeof(struct timeval));
memcpy(&t[1], &last_update, sizeof(struct timeval));
get_time_interval(t);
return t[0].tv_sec;
}
bool meas_cell::has_sibs(srslte::span<uint32_t> indexes) const
{
for (uint32_t idx : indexes) {
@ -160,7 +161,10 @@ uint16_t meas_cell::get_mnc() const
* Neighbour Cell List
********************************************/
meas_cell_list::meas_cell_list() : serv_cell(new meas_cell()) {}
meas_cell_list::meas_cell_list(srslte::task_sched_handle task_sched_) :
serv_cell(new meas_cell(task_sched_.get_unique_timer())),
task_sched(task_sched_)
{}
meas_cell* meas_cell_list::get_neighbour_cell_handle(uint32_t earfcn, uint32_t pci)
{
@ -184,7 +188,7 @@ bool meas_cell_list::add_meas_cell(const rrc_interface_phy_lte::phy_meas_t& meas
phy_cell_t phy_cell = {};
phy_cell.earfcn = meas.earfcn;
phy_cell.pci = meas.pci;
unique_meas_cell c = unique_meas_cell(new meas_cell(phy_cell));
unique_meas_cell c = unique_meas_cell(new meas_cell(phy_cell, task_sched.get_unique_timer()));
c.get()->set_rsrp(meas.rsrp);
c.get()->set_rsrq(meas.rsrq);
c.get()->set_cfo(meas.cfo_hz);
@ -296,11 +300,8 @@ void meas_cell_list::log_neighbour_cells() const
//! Called by main RRC thread to remove neighbours from which measurements have not been received in a while
void meas_cell_list::clean_neighbours()
{
struct timeval now;
gettimeofday(&now, nullptr);
for (auto it = neighbour_cells.begin(); it != neighbour_cells.end();) {
if ((*it)->timeout_secs(now) > NEIGHBOUR_TIMEOUT) {
if (it->get()->timer.is_expired()) {
log_h->info("Neighbour PCI=%d timed out. Deleting\n", (*it)->get_pci());
it = neighbour_cells.erase(it);
} else {

@ -90,7 +90,8 @@ proc_outcome_t rrc::cell_search_proc::handle_cell_found(const phy_cell_t& new_ce
Info("Cell found in this frequency. Setting new serving cell EARFCN=%d PCI=%d ...\n", new_cell.earfcn, new_cell.pci);
// Create a cell with NaN RSRP. Will be updated by new_phy_meas() during SIB search.
if (not rrc_ptr->meas_cells.add_meas_cell(unique_cell_t(new meas_cell(new_cell)))) {
if (not rrc_ptr->meas_cells.add_meas_cell(
unique_cell_t(new meas_cell(new_cell, rrc_ptr->task_sched.get_unique_timer())))) {
Error("Could not add new found cell\n");
return proc_outcome_t::error;
}

@ -26,7 +26,8 @@ using namespace srsue;
int test_meas_cell()
{
meas_cell invalid_cell{}, cell{phy_cell_t{1, 3400}};
srslte::task_scheduler task_sched;
meas_cell invalid_cell{task_sched.get_unique_timer()}, cell{phy_cell_t{1, 3400}, task_sched.get_unique_timer()};
TESTASSERT(not invalid_cell.is_valid());
TESTASSERT(cell.is_valid());
@ -40,12 +41,26 @@ int test_meas_cell()
cell.set_rsrp(NAN);
TESTASSERT(cell.get_rsrp() == -50);
// Test meas timer expiry
for (size_t i = 0; i < meas_cell::neighbour_timeout_ms; ++i) {
TESTASSERT(not cell.timer.is_expired());
task_sched.tic();
}
TESTASSERT(cell.timer.is_expired());
cell.set_rsrp(-20);
for (size_t i = 0; i < meas_cell::neighbour_timeout_ms; ++i) {
TESTASSERT(not cell.timer.is_expired());
task_sched.tic();
}
TESTASSERT(cell.timer.is_expired());
return SRSLTE_SUCCESS;
}
int test_add_neighbours()
{
meas_cell_list list;
srslte::task_scheduler task_sched;
meas_cell_list list{&task_sched};
TESTASSERT(list.nof_neighbours() == 0);
TESTASSERT(not list.serving_cell().is_valid());
TESTASSERT(list.get_neighbour_cell_handle(0, 0) == nullptr);
@ -80,6 +95,19 @@ int test_add_neighbours()
TESTASSERT(c2 != nullptr and c2->is_valid() and c2->equals(3400, 1));
TESTASSERT(list.nof_neighbours() == 0);
TESTASSERT(list.add_meas_cell(pmeas));
TESTASSERT(list.nof_neighbours() == 1);
task_sched.tic();
task_sched.tic();
list.get_neighbour_cell_handle(3400, 1)->set_rsrp(-20);
for (size_t i = 0; i < meas_cell::neighbour_timeout_ms; ++i) {
TESTASSERT(list.nof_neighbours() == 1);
list.clean_neighbours();
task_sched.tic();
}
list.clean_neighbours();
TESTASSERT(list.nof_neighbours() == 0);
return SRSLTE_SUCCESS;
}

Loading…
Cancel
Save