mirror of https://github.com/PentHertz/srsLTE.git
rrc::meas_cell now uses stack timers instead of system timers.
This commit is contained in:
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);
|
||||
|
||||
// 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…
Reference in New Issue