You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

275 lines
9.0 KiB
C

/**
*
* \section COPYRIGHT
*
* Copyright 2013-2021 Software Radio Systems Limited
*
* By using this file, you agree to the terms and conditions set
* forth in the LICENSE file which can be found at the top level of
* the distribution.
*
*/
#ifndef SRSRAN_RRC_CELL_H
#define SRSRAN_RRC_CELL_H
#include "srsran/asn1/rrc.h"
#include "srsran/asn1/rrc_nr.h"
#include "srsran/asn1/rrc_nr_utils.h"
#include "srsran/asn1/rrc_utils.h"
#include "srsran/common/task_scheduler.h"
#include "srsran/interfaces/ue_rrc_interfaces.h"
#include "srsran/srslog/srslog.h"
#include <set>
namespace srsue {
inline std::string to_string(const 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:
const static int neighbour_timeout_ms = 5000;
explicit meas_cell(srsran::unique_timer timer);
meas_cell(const phy_cell_t& phy_cell_, srsran::unique_timer timer);
// comparison based on pci and earfcn
bool is_valid() const { return phy_cell.earfcn != 0 && srsran_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(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); }
void set_rsrp(float rsrp_)
{
if (!std::isnan(rsrp_)) {
rsrp = rsrp_;
}
timer.run();
}
void set_rsrq(float rsrq_)
{
if (!std::isnan(rsrq_)) {
rsrq = rsrq_;
}
}
void set_cfo(float cfo_Hz_)
{
if (not std::isnan(cfo_Hz_) && not std::isinf(cfo_Hz_)) {
phy_cell.cfo_hz = cfo_Hz_;
}
}
bool has_sib1() const { return has_valid_sib1; }
bool has_sib2() const { return has_valid_sib2; }
bool has_sib3() const { return has_valid_sib3; }
bool has_sib13() const { return has_valid_sib13; }
bool has_sib(uint32_t index) const;
bool has_sibs(srsran::span<const uint32_t> indexes) const;
bool is_sib_scheduled(uint32_t sib_index) const;
void reset_sibs()
{
has_valid_sib1 = false;
has_valid_sib2 = false;
has_valid_sib3 = false;
has_valid_sib13 = false;
}
uint32_t get_earfcn() const { return phy_cell.earfcn; }
uint32_t get_pci() const { return phy_cell.pci; }
float get_rsrp() const { return rsrp; }
float get_rsrq() const { return rsrq; }
float get_cfo_hz() const { return phy_cell.cfo_hz; }
phy_cell_t phy_cell = {0, 0, 0};
srsran::unique_timer timer;
protected:
float rsrp = NAN;
float rsrq = NAN;
bool has_valid_sib1 = false;
bool has_valid_sib2 = false;
bool has_valid_sib3 = false;
bool has_valid_sib13 = false;
std::map<uint32_t, uint32_t> sib_info_map; ///< map of sib_index to index of schedInfoList in SIB1
};
class meas_cell_nr : public meas_cell
{
public:
explicit meas_cell_nr(srsran::unique_timer timer) : meas_cell(std::move(timer)){};
meas_cell_nr(const phy_cell_t& phy_cell_, srsran::unique_timer timer) : meas_cell(phy_cell_, std::move(timer)){};
bool has_plmn_id(asn1::rrc_nr::plmn_id_s plmn_id) const;
uint32_t nof_plmns() const { return has_sib1() ? sib1.cell_access_related_info.plmn_id_list.size() : 0; }
srsran::plmn_id_t get_plmn(uint32_t idx) const;
void set_sib1(const asn1::rrc_nr::sib1_s& sib1_);
void set_sib2(const asn1::rrc_nr::sib2_s& sib2_);
void set_sib3(const asn1::rrc_nr::sib3_s& sib3_);
const asn1::rrc_nr::sib1_s* sib1ptr() const { return has_sib1() ? &sib1 : nullptr; }
uint32_t get_cell_id() const { return (uint32_t)0xFFFF; } // TODO find the correct sib
uint16_t get_mcc() const;
uint16_t get_mnc() const;
std::string to_string() const;
asn1::rrc_nr::sib1_s sib1 = {};
};
class meas_cell_eutra : public meas_cell
{
public:
explicit meas_cell_eutra(srsran::unique_timer timer) : meas_cell(std::move(timer)){};
meas_cell_eutra(const phy_cell_t& phy_cell_, srsran::unique_timer timer) : meas_cell(phy_cell_, std::move(timer)){};
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; }
srsran::plmn_id_t get_plmn(uint32_t idx) const;
asn1::rrc::plmn_id_s get_plmn_asn1(uint32_t idx) const;
uint16_t get_tac() const { return has_sib1() ? (uint16_t)sib1.cell_access_related_info.tac.to_number() : 0; }
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_);
void set_sib13(const asn1::rrc::sib_type13_r9_s& sib13_);
const asn1::rrc::sib_type1_s* sib1ptr() const { return has_sib1() ? &sib1 : nullptr; }
const asn1::rrc::sib_type2_s* sib2ptr() const { return has_sib2() ? &sib2 : nullptr; }
const asn1::rrc::sib_type3_s* sib3ptr() const { return has_sib3() ? &sib3 : nullptr; }
const asn1::rrc::sib_type13_r9_s* sib13ptr() const { return has_sib13() ? &sib13 : nullptr; }
uint32_t get_cell_id() const { return (uint32_t)sib1.cell_access_related_info.cell_id.to_number(); }
asn1::fixed_bitstring<28> get_cell_id_bit() const { return sib1.cell_access_related_info.cell_id; }
uint16_t get_mcc() const;
uint16_t get_mnc() const;
std::string to_string() const;
bool has_mcch = false;
asn1::rrc::sib_type1_s sib1 = {};
asn1::rrc::sib_type2_s sib2 = {};
asn1::rrc::sib_type3_s sib3 = {};
asn1::rrc::sib_type13_r9_s sib13 = {};
asn1::rrc::mcch_msg_s mcch = {};
private:
};
//! Universal methods to extract pci/earfcn and compare the two values
template <typename T>
uint32_t get_pci(const T& t)
{
return t.pci;
}
template <>
inline uint32_t get_pci(const meas_cell_eutra& t)
{
return t.get_pci();
}
template <>
inline uint32_t get_pci(const meas_cell_nr& t)
{
return t.get_pci();
}
template <typename T>
uint32_t get_earfcn(const T& t)
{
return t.earfcn;
}
template <>
inline uint32_t get_earfcn(const meas_cell_eutra& t)
{
return t.get_earfcn();
}
template <>
inline uint32_t get_earfcn(const meas_cell_nr& t)
{
return t.get_earfcn();
}
template <typename T, typename U>
bool is_same_cell(const T& lhs, const U& rhs)
{
return get_pci(lhs) == get_pci(rhs) and get_earfcn(lhs) == get_earfcn(rhs);
}
template <class T>
class meas_cell_list
{
public:
const static int NEIGHBOUR_TIMEOUT = 5;
const static int MAX_NEIGHBOUR_CELLS = 8;
typedef std::unique_ptr<T> unique_meas_cell;
explicit meas_cell_list(srsran::task_sched_handle task_sched_);
bool add_meas_cell(const phy_meas_t& meas);
bool add_meas_cell(unique_meas_cell cell);
void rem_last_neighbour();
unique_meas_cell remove_neighbour_cell(uint32_t earfcn, uint32_t pci);
void clean_neighbours();
void sort_neighbour_cells();
bool process_new_cell_meas(const std::vector<phy_meas_t>& meas,
const std::function<void(T&, const phy_meas_t&)>& filter_meas);
Upgrade loggers in srsue (#2163) * Replaced UE logger in the ue class. * Replaced loggers in the main phy class and prach. * Replaced loggers in phy common and ta_control. * Replace loggers in cc and sf workers. * Replaced loggers in intra_measure, scell_recv, search, sfn_sync, sync. * Remove last uses of the old loggers in the main phy class. * Remove stray newline in logs. * Replaced loggers in ue gw. * - Started to replace loggers in the ue stack. - Replaced loggers in usim and pcsc. - Adapted nas and usim tests. * Replace loggers in nas. * Added missing log init calls in two previously modified tests. * Replaced logger in nas idle procs. * Replaced loggers in nas emm state. * Replaced loggers in tft packet filter and adapted tft test. * Replaced loggers in main RRC class. * Replaced loggers in RRC cell. * Replaced loggers in RRC meas. * Replaced loggers in rrc procedures. * Started logger replacement in MAC layer, more precisely in demux and dl_harq classes. Been unable to inject loggers in construction for dl_tb_process due to very weird static assertions in the std::vector code being the type not constructible which is not true, so instead use the main MAC logger directly. * Replaced loggers in mac mux class. * Replaced loggers in mac pro_bsr. * Replaced loggers in mac proc phr. * Replaced loggers in mac proc SR and RA. * Replace loggers in mac UL HARQ. * Replaced loggers in main ue stack class. * Fixed nas test crashing due to a null string. * Ported mac_test to use the new loggers. * Removed TTI reporting for the PHY log as the old logger did. * Replaced loggers in UE phy tests. * Configure loggers in nas_test. * Replaced loggers in rrc_meas_test. * Replaced loggers in rrc_reconfig_test. * Added missing newline in tft_test. * Fix compilation errors in TTCN3 tests. * Fix linker error detected in CI and warning. * Replaced loggers in TTCN3 tests. * Fix a text replace error in some log messages. * Remove trailing newlines from log entries. * Remove old logger from rrc. * Flush backend before printing the test status. * - Fix compilation error from previous rebase. - Remove trailing newlines from some missing log entries.
4 years ago
T* get_neighbour_cell_handle(uint32_t earfcn, uint32_t pci);
const T* get_neighbour_cell_handle(uint32_t earfcn, uint32_t pci) const;
void log_neighbour_cells() const;
std::string print_neighbour_cells() const;
std::set<uint32_t> get_neighbour_pcis(uint32_t earfcn) const;
bool has_neighbour_cell(uint32_t earfcn, uint32_t pci) const;
size_t nof_neighbours() const { return neighbour_cells.size(); }
T& operator[](size_t idx) { return *neighbour_cells[idx]; }
const T& operator[](size_t idx) const { return *neighbour_cells[idx]; }
T& at(size_t idx) { return *neighbour_cells.at(idx); }
T* find_cell(uint32_t earfcn, uint32_t pci);
// serving cell handling
int set_serving_cell(phy_cell_t phy_cell, bool discard_serving);
// Set serving cell and earfcn for each cc_idx
void set_scell_cc_idx(uint32_t cc_idx, uint32_t earfcn, uint32_t pci);
bool get_scell_cc_idx(uint32_t earfcn, uint32_t& pci);
T& serving_cell() { return *serv_cell; }
const T& serving_cell() const { return *serv_cell; }
using iterator = typename std::vector<unique_meas_cell>::iterator;
iterator begin() { return neighbour_cells.begin(); }
iterator end() { return neighbour_cells.end(); }
private:
bool add_neighbour_cell_unsorted(unique_meas_cell cell);
// args
Upgrade loggers in srsue (#2163) * Replaced UE logger in the ue class. * Replaced loggers in the main phy class and prach. * Replaced loggers in phy common and ta_control. * Replace loggers in cc and sf workers. * Replaced loggers in intra_measure, scell_recv, search, sfn_sync, sync. * Remove last uses of the old loggers in the main phy class. * Remove stray newline in logs. * Replaced loggers in ue gw. * - Started to replace loggers in the ue stack. - Replaced loggers in usim and pcsc. - Adapted nas and usim tests. * Replace loggers in nas. * Added missing log init calls in two previously modified tests. * Replaced logger in nas idle procs. * Replaced loggers in nas emm state. * Replaced loggers in tft packet filter and adapted tft test. * Replaced loggers in main RRC class. * Replaced loggers in RRC cell. * Replaced loggers in RRC meas. * Replaced loggers in rrc procedures. * Started logger replacement in MAC layer, more precisely in demux and dl_harq classes. Been unable to inject loggers in construction for dl_tb_process due to very weird static assertions in the std::vector code being the type not constructible which is not true, so instead use the main MAC logger directly. * Replaced loggers in mac mux class. * Replaced loggers in mac pro_bsr. * Replaced loggers in mac proc phr. * Replaced loggers in mac proc SR and RA. * Replace loggers in mac UL HARQ. * Replaced loggers in main ue stack class. * Fixed nas test crashing due to a null string. * Ported mac_test to use the new loggers. * Removed TTI reporting for the PHY log as the old logger did. * Replaced loggers in UE phy tests. * Configure loggers in nas_test. * Replaced loggers in rrc_meas_test. * Replaced loggers in rrc_reconfig_test. * Added missing newline in tft_test. * Fix compilation errors in TTCN3 tests. * Fix linker error detected in CI and warning. * Replaced loggers in TTCN3 tests. * Fix a text replace error in some log messages. * Remove trailing newlines from log entries. * Remove old logger from rrc. * Flush backend before printing the test status. * - Fix compilation error from previous rebase. - Remove trailing newlines from some missing log entries.
4 years ago
srslog::basic_logger& logger = srslog::fetch_basic_logger("RRC");
srsran::task_sched_handle task_sched;
unique_meas_cell serv_cell;
std::vector<unique_meas_cell> neighbour_cells;
// store serving pci and earfcn for each carrier
std::array<std::pair<uint32_t, uint32_t>, SRSRAN_MAX_CARRIERS> current_cell_pci_earfcn = {};
};
} // namespace srsue
#endif // SRSRAN_RRC_CELL_H