SRSUE: RRC measurements refactor and more fixes

master
Xavier Arteaga 5 years ago committed by Andre Puschmann
parent 52716f8716
commit f8294fb9df

@ -28,8 +28,8 @@
#ifndef SRSLTE_UE_INTERFACES_H #ifndef SRSLTE_UE_INTERFACES_H
#define SRSLTE_UE_INTERFACES_H #define SRSLTE_UE_INTERFACES_H
#include <set>
#include <string> #include <string>
#include <set>
#include "rrc_interface_types.h" #include "rrc_interface_types.h"
#include "srslte/asn1/liblte_mme.h" #include "srslte/asn1/liblte_mme.h"
@ -142,9 +142,9 @@ public:
uint32_t pci; uint32_t pci;
} phy_meas_t; } phy_meas_t;
virtual void in_sync() = 0; virtual void in_sync() = 0;
virtual void out_of_sync() = 0; virtual void out_of_sync() = 0;
virtual void new_cell_meas(std::vector<phy_meas_t>& meas) = 0; virtual void new_cell_meas(const std::vector<phy_meas_t>& meas) = 0;
}; };
// RRC interface for NAS // RRC interface for NAS
@ -227,25 +227,25 @@ public:
class pdcp_interface_rrc class pdcp_interface_rrc
{ {
public: public:
virtual void reestablish() = 0; virtual void reestablish() = 0;
virtual void reestablish(uint32_t lcid) = 0; virtual void reestablish(uint32_t lcid) = 0;
virtual void reset() = 0; virtual void reset() = 0;
virtual void write_sdu(uint32_t lcid, srslte::unique_byte_buffer_t sdu, bool blocking) = 0; virtual void write_sdu(uint32_t lcid, srslte::unique_byte_buffer_t sdu, bool blocking) = 0;
virtual void add_bearer(uint32_t lcid, srslte::pdcp_config_t cnfg) = 0; virtual void add_bearer(uint32_t lcid, srslte::pdcp_config_t cnfg) = 0;
virtual void change_lcid(uint32_t old_lcid, uint32_t new_lcid) = 0; virtual void change_lcid(uint32_t old_lcid, uint32_t new_lcid) = 0;
virtual void config_security(uint32_t lcid, virtual void config_security(uint32_t lcid,
uint8_t* k_rrc_enc_, uint8_t* k_rrc_enc_,
uint8_t* k_rrc_int_, uint8_t* k_rrc_int_,
uint8_t* k_up_enc_, uint8_t* k_up_enc_,
srslte::CIPHERING_ALGORITHM_ID_ENUM cipher_algo_, srslte::CIPHERING_ALGORITHM_ID_ENUM cipher_algo_,
srslte::INTEGRITY_ALGORITHM_ID_ENUM integ_algo_) = 0; srslte::INTEGRITY_ALGORITHM_ID_ENUM integ_algo_) = 0;
virtual void config_security_all(uint8_t* k_rrc_enc_, virtual void config_security_all(uint8_t* k_rrc_enc_,
uint8_t* k_rrc_int_, uint8_t* k_rrc_int_,
uint8_t* k_up_enc_, uint8_t* k_up_enc_,
srslte::CIPHERING_ALGORITHM_ID_ENUM cipher_algo_, srslte::CIPHERING_ALGORITHM_ID_ENUM cipher_algo_,
srslte::INTEGRITY_ALGORITHM_ID_ENUM integ_algo_) = 0; srslte::INTEGRITY_ALGORITHM_ID_ENUM integ_algo_) = 0;
virtual void enable_integrity(uint32_t lcid) = 0; virtual void enable_integrity(uint32_t lcid) = 0;
virtual void enable_encryption(uint32_t lcid) = 0; virtual void enable_encryption(uint32_t lcid) = 0;
}; };
// PDCP interface for RLC // PDCP interface for RLC
@ -601,8 +601,8 @@ public:
virtual void set_config_mbsfn_mcch(const srslte::mcch_msg_t& mcch) = 0; virtual void set_config_mbsfn_mcch(const srslte::mcch_msg_t& mcch) = 0;
/* Measurements interface */ /* Measurements interface */
virtual void set_cells_to_meas(uint32_t earfcn, std::set<uint32_t>& pci) = 0; virtual void set_cells_to_meas(uint32_t earfcn, const std::set<uint32_t>& pci) = 0;
virtual void meas_stop() = 0; virtual void meas_stop() = 0;
typedef struct { typedef struct {
enum { CELL_FOUND = 0, CELL_NOT_FOUND, ERROR } found; enum { CELL_FOUND = 0, CELL_NOT_FOUND, ERROR } found;

@ -815,7 +815,7 @@ static float get_rsrp_port(srslte_chest_dl_t* q, uint32_t port)
return sum; return sum;
} }
static float get_rsrp_neigbhour_port(srslte_chest_dl_t* q, uint32_t port) static float get_rsrp_neighbour_port(srslte_chest_dl_t* q, uint32_t port)
{ {
float sum = 0.0f; float sum = 0.0f;
for (int j = 0; j < q->cell.nof_ports; ++j) { for (int j = 0; j < q->cell.nof_ports; ++j) {
@ -855,7 +855,7 @@ static float get_rsrp_neighbour(srslte_chest_dl_t* q)
{ {
float max = -1e9; float max = -1e9;
for (int i = 0; i < q->nof_rx_antennas; ++i) { for (int i = 0; i < q->nof_rx_antennas; ++i) {
float v = get_rsrp_neigbhour_port(q, i); float v = get_rsrp_neighbour_port(q, i);
if (v > max) { if (v > max) {
max = v; max = v;
} }

@ -929,7 +929,11 @@ static void ulsch_interleave(uint8_t* g_bits,
uint8_t* ri_present) uint8_t* ri_present)
{ {
if (N_pusch_symbs == 0 || Qm == 0 || H_prime_total == 0 || H_prime_total < N_pusch_symbs) { if (N_pusch_symbs == 0 || Qm == 0 || H_prime_total == 0 || H_prime_total < N_pusch_symbs) {
ERROR("Invalid input: N_pusch_symbs=%d, Qm=%d, H_prime_total=%d, N_pusch_symbs=%d\n", N_pusch_symbs, Qm, H_prime_total, N_pusch_symbs); ERROR("Invalid input: N_pusch_symbs=%d, Qm=%d, H_prime_total=%d, N_pusch_symbs=%d\n",
N_pusch_symbs,
Qm,
H_prime_total,
N_pusch_symbs);
return; return;
} }
@ -1247,7 +1251,7 @@ int srslte_ulsch_encode(srslte_sch_t* q,
srslte_bit_pack_vector(q->temp_g_bits, g_bits, Q_prime_cqi * Qm); srslte_bit_pack_vector(q->temp_g_bits, g_bits, Q_prime_cqi * Qm);
// Reset the buffer because will be reused in ulsch_interleave // Reset the buffer because will be reused in ulsch_interleave
bzero(q->temp_g_bits, sizeof(uint8_t) * SRSLTE_MIN(Q_prime_cqi * Qm, SCH_MAX_G_BITS)); bzero(q->temp_g_bits, Q_prime_cqi * Qm);
} }
e_offset += Q_prime_cqi * Qm; e_offset += Q_prime_cqi * Qm;
@ -1323,4 +1327,4 @@ void srslte_sl_ulsch_deinterleave(int16_t* q_bits,
uint32_t* inteleaver_lut) uint32_t* inteleaver_lut)
{ {
ulsch_deinterleave(q_bits, Qm, H_prime_total, N_pusch_symbs, g_bits, NULL, 0, NULL, inteleaver_lut); ulsch_deinterleave(q_bits, Qm, H_prime_total, N_pusch_symbs, g_bits, NULL, 0, NULL, inteleaver_lut);
} }

@ -72,7 +72,7 @@ public:
cell_search_ret_t cell_search(phy_cell_t* cell) final; cell_search_ret_t cell_search(phy_cell_t* cell) final;
bool cell_select(phy_cell_t* cell) final; bool cell_select(phy_cell_t* cell) final;
void set_cells_to_meas(uint32_t earfcn, std::set<uint32_t>& pci) final; void set_cells_to_meas(uint32_t earfcn, const std::set<uint32_t>& pci) final;
void meas_stop() final; void meas_stop() final;
// also MAC interface // also MAC interface
@ -132,7 +132,7 @@ private:
std::mutex config_mutex; std::mutex config_mutex;
std::condition_variable config_cond; std::condition_variable config_cond;
bool is_configured = false; bool is_configured = false;
uint32_t nof_workers = 0; uint32_t nof_workers = 0;
const static int SF_RECV_THREAD_PRIO = 1; const static int SF_RECV_THREAD_PRIO = 1;
const static int WORKERS_THREAD_PRIO = 2; const static int WORKERS_THREAD_PRIO = 2;

@ -22,7 +22,7 @@
#ifndef SRSUE_PHY_METRICS_H #ifndef SRSUE_PHY_METRICS_H
#define SRSUE_PHY_METRICS_H #define SRSUE_PHY_METRICS_H
#include "srslte/phy/common/phy_common.h" #include "srslte/srslte.h"
namespace srsue { namespace srsue {

@ -37,16 +37,20 @@ class intra_measure : public thread
public: public:
intra_measure(); intra_measure();
~intra_measure(); ~intra_measure();
void init(phy_common* common, rrc_interface_phy_lte* rrc, srslte::log* log_h); void init(phy_common* common, rrc_interface_phy_lte* rrc, srslte::log* log_h);
void stop(); void stop();
void set_primary_cell(uint32_t earfcn, srslte_cell_t cell); void set_primary_cell(uint32_t earfcn, srslte_cell_t cell);
void set_cells_to_meas(std::set<uint32_t>& pci); void set_cells_to_meas(const std::set<uint32_t>& pci);
void meas_stop(); void meas_stop();
void write(uint32_t tti, cf_t* data, uint32_t nsamples); void write(uint32_t tti, cf_t* data, uint32_t nsamples);
uint32_t get_earfcn() { return current_earfcn; }; uint32_t get_earfcn() { return current_earfcn; };
void wait_meas()
{ // Only used by scell_search_test
meas_sync.wait();
}
private: private:
void run_thread(); void run_thread() override;
const static int INTRA_FREQ_MEAS_PRIO = DEFAULT_PRIORITY + 5; const static int INTRA_FREQ_MEAS_PRIO = DEFAULT_PRIORITY + 5;
scell_recv scell = {}; scell_recv scell = {};
@ -60,6 +64,7 @@ private:
std::mutex active_pci_mutex = {}; std::mutex active_pci_mutex = {};
srslte::tti_sync_cv tti_sync; srslte::tti_sync_cv tti_sync;
srslte::tti_sync_cv meas_sync; // Only used by scell_search_test
cf_t* search_buffer = nullptr; cf_t* search_buffer = nullptr;

@ -70,7 +70,7 @@ public:
bool cell_is_camping(); bool cell_is_camping();
// RRC interface for controlling the neighbour cell measurement // RRC interface for controlling the neighbour cell measurement
void set_cells_to_meas(uint32_t earfcn, std::set<uint32_t>& pci); void set_cells_to_meas(uint32_t earfcn, const std::set<uint32_t>& pci);
void set_inter_frequency_measurement(uint32_t cc_idx, uint32_t earfcn_, srslte_cell_t cell_); void set_inter_frequency_measurement(uint32_t cc_idx, uint32_t earfcn_, srslte_cell_t cell_);
void meas_stop(); void meas_stop();
@ -170,8 +170,8 @@ private:
bool running = false; bool running = false;
// Objects for internal use // Objects for internal use
search search_p; search search_p;
sfn_sync sfn_p; sfn_sync sfn_p;
std::vector<std::unique_ptr<scell::intra_measure> > intra_freq_meas; std::vector<std::unique_ptr<scell::intra_measure> > intra_freq_meas;
uint32_t current_sflen = 0; uint32_t current_sflen = 0;
@ -349,7 +349,7 @@ private:
srslte_timestamp_t radio_ts = {}; srslte_timestamp_t radio_ts = {};
std::array<uint8_t, SRSLTE_BCH_PAYLOAD_LEN> mib; std::array<uint8_t, SRSLTE_BCH_PAYLOAD_LEN> mib;
uint32_t nof_workers = 0; uint32_t nof_workers = 0;
float ul_dl_factor = NAN; float ul_dl_factor = NAN;
int current_earfcn = 0; int current_earfcn = 0;

@ -246,7 +246,7 @@ public:
return 0; return 0;
} }
std::string print() std::string to_string()
{ {
char buf[256]; char buf[256];
snprintf(buf, snprintf(buf,
@ -334,7 +334,7 @@ public:
// PHY interface // PHY interface
void in_sync() final; void in_sync() final;
void out_of_sync() final; void out_of_sync() final;
void new_cell_meas(std::vector<phy_meas_t>& meas); void new_cell_meas(const std::vector<phy_meas_t>& meas);
// MAC interface // MAC interface
void ho_ra_completed(bool ra_successful); void ho_ra_completed(bool ra_successful);
@ -425,9 +425,9 @@ private:
std::map<uint32_t, asn1::rrc::drb_to_add_mod_s> drbs; std::map<uint32_t, asn1::rrc::drb_to_add_mod_s> drbs;
// RRC constants and timers // RRC constants and timers
srslte::timer_handler* timers = nullptr; srslte::timer_handler* timers = nullptr;
uint32_t n310_cnt, N310 = 0; uint32_t n310_cnt = 0, N310 = 0;
uint32_t n311_cnt, N311 = 0; uint32_t n311_cnt = 0, N311 = 0;
srslte::timer_handler::unique_timer t300, t301, t302, t310, t311, t304; srslte::timer_handler::unique_timer t300, t301, t302, t310, t311, t304;
// Radio bearers // Radio bearers
@ -466,16 +466,16 @@ private:
unique_cell_t serving_cell = nullptr; unique_cell_t serving_cell = nullptr;
void set_serving_cell(uint32_t cell_idx); void set_serving_cell(uint32_t cell_idx);
unique_cell_t remove_neighbour_cell(const uint32_t earfcn, const uint32_t pci); unique_cell_t remove_neighbour_cell(const uint32_t earfcn, const uint32_t pci);
cell_t* get_neighbour_cell_handle(const uint32_t earfcn, const uint32_t pci); cell_t* get_neighbour_cell_handle(const uint32_t earfcn, const uint32_t pci);
int find_neighbour_cell(uint32_t earfcn, uint32_t pci); int find_neighbour_cell(uint32_t earfcn, uint32_t pci);
bool add_neighbour_cell(phy_meas_t meas); bool add_neighbour_cell(phy_meas_t meas);
bool add_neighbour_cell(unique_cell_t new_cell); bool add_neighbour_cell(unique_cell_t new_cell);
void log_neighbour_cells(); void log_neighbour_cells();
void sort_neighbour_cells(); void sort_neighbour_cells();
void clean_neighbours(); void clean_neighbours();
void delete_last_neighbour(); void delete_last_neighbour();
std::string print_neighbour_cells(); std::string print_neighbour_cells();
std::set<uint32_t> get_neighbour_pcis(uint32_t earfcn); std::set<uint32_t> get_neighbour_pcis(uint32_t earfcn);
bool initiated = false; bool initiated = false;
@ -490,7 +490,7 @@ private:
// Measurements private subclass // Measurements private subclass
class rrc_meas; class rrc_meas;
rrc_meas* measurements; std::unique_ptr<rrc_meas> measurements;
// Interface from rrc_meas // Interface from rrc_meas
void send_srb1_msg(const asn1::rrc::ul_dcch_msg_s& msg); void send_srb1_msg(const asn1::rrc::ul_dcch_msg_s& msg);
@ -500,7 +500,7 @@ private:
cell_t* get_serving_cell(); cell_t* get_serving_cell();
void process_cell_meas(); void process_cell_meas();
void process_new_cell_meas(std::vector<phy_meas_t>& meas); void process_new_cell_meas(const std::vector<phy_meas_t>& meas);
srslte::block_queue<std::vector<phy_meas_t> > cell_meas_q; srslte::block_queue<std::vector<phy_meas_t> > cell_meas_q;
// Cell selection/reselection functions/variables // Cell selection/reselection functions/variables

@ -77,7 +77,7 @@ public:
// RRC interface for PHY // RRC interface for PHY
void in_sync() final; void in_sync() final;
void out_of_sync() final; void out_of_sync() final;
void new_cell_meas(std::vector<phy_meas_t>& meas) { rrc.new_cell_meas(meas); } void new_cell_meas(const std::vector<phy_meas_t>& meas) override { rrc.new_cell_meas(meas); }
// MAC Interface for PHY // MAC Interface for PHY
uint16_t get_dl_sched_rnti(uint32_t tti) { return mac.get_dl_sched_rnti(tti); } uint16_t get_dl_sched_rnti(uint32_t tti) { return mac.get_dl_sched_rnti(tti); }

@ -315,7 +315,7 @@ void phy::configure_prach_params()
} }
} }
void phy::set_cells_to_meas(uint32_t earfcn, std::set<uint32_t>& pci) void phy::set_cells_to_meas(uint32_t earfcn, const std::set<uint32_t>& pci)
{ {
sfsync.set_cells_to_meas(earfcn, pci); sfsync.set_cells_to_meas(earfcn, pci);
} }

@ -97,7 +97,7 @@ void intra_measure::meas_stop()
} }
} }
void intra_measure::set_cells_to_meas(std::set<uint32_t>& pci) void intra_measure::set_cells_to_meas(const std::set<uint32_t>& pci)
{ {
active_pci_mutex.lock(); active_pci_mutex.lock();
active_pci = pci; active_pci = pci;
@ -159,7 +159,7 @@ void intra_measure::run_thread()
receiving = false; receiving = false;
std::vector<rrc_interface_phy_lte::phy_meas_t> neigbhour_cells = {}; std::vector<rrc_interface_phy_lte::phy_meas_t> neighbour_cells = {};
// Use Cell Reference signal to measure cells in the time domain for all known active PCI // Use Cell Reference signal to measure cells in the time domain for all known active PCI
for (auto id : cells_to_measure) { for (auto id : cells_to_measure) {
@ -180,7 +180,7 @@ void intra_measure::run_thread()
m.earfcn = current_earfcn; m.earfcn = current_earfcn;
m.rsrp = refsignal_dl_sync.rsrp_dBfs - common->rx_gain_offset; m.rsrp = refsignal_dl_sync.rsrp_dBfs - common->rx_gain_offset;
m.rsrq = refsignal_dl_sync.rsrq_dB; m.rsrq = refsignal_dl_sync.rsrq_dB;
neigbhour_cells.push_back(m); neighbour_cells.push_back(m);
Info("INTRA: Found neighbour cell: EARFCN=%d, PCI=%03d, RSRP=%5.1f dBm, RSRQ=%5.1f, peak_idx=%5d, " Info("INTRA: Found neighbour cell: EARFCN=%d, PCI=%03d, RSRP=%5.1f dBm, RSRQ=%5.1f, peak_idx=%5d, "
"CFO=%+.1fHz\n", "CFO=%+.1fHz\n",
@ -194,9 +194,11 @@ void intra_measure::run_thread()
} }
// Send measurements to RRC // Send measurements to RRC
if (neigbhour_cells.size() > 0) { if (not neighbour_cells.empty()) {
rrc->new_cell_meas(neigbhour_cells); rrc->new_cell_meas(neighbour_cells);
} }
meas_sync.increase();
} }
} }
} }

@ -386,7 +386,7 @@ bool sync::cell_is_camping()
void sync::run_thread() void sync::run_thread()
{ {
sf_worker* worker = nullptr; sf_worker* worker = nullptr;
cf_t* buffer[SRSLTE_MAX_RADIOS][SRSLTE_MAX_PORTS] = {}; cf_t* buffer[SRSLTE_MAX_RADIOS][SRSLTE_MAX_PORTS] = {};
srslte_cell_t temp_cell = {}; srslte_cell_t temp_cell = {};
@ -482,9 +482,9 @@ void sync::run_thread()
// Force decode MIB if required // Force decode MIB if required
if (force_camping_sfn_sync) { if (force_camping_sfn_sync) {
uint32_t _tti = 0; uint32_t _tti = 0;
temp_cell = cell; temp_cell = cell;
sync::sfn_sync::ret_code ret = sfn_p.decode_mib(&temp_cell, &_tti, buffer[0], mib); sync::sfn_sync::ret_code ret = sfn_p.decode_mib(&temp_cell, &_tti, buffer[0], mib);
if (ret == sfn_sync::SFN_FOUND) { if (ret == sfn_sync::SFN_FOUND) {
// Force tti // Force tti
tti = _tti; tti = _tti;
@ -1291,7 +1291,7 @@ void sync::set_inter_frequency_measurement(uint32_t cc_idx, uint32_t earfcn_, sr
intra_freq_meas[cc_idx]->set_primary_cell(earfcn_, cell_); intra_freq_meas[cc_idx]->set_primary_cell(earfcn_, cell_);
} }
} }
void sync::set_cells_to_meas(uint32_t earfcn_, std::set<uint32_t>& pci) void sync::set_cells_to_meas(uint32_t earfcn_, const std::set<uint32_t>& pci)
{ {
bool found = false; bool found = false;
for (size_t i = 0; i < intra_freq_meas.size() and not found; i++) { for (size_t i = 0; i < intra_freq_meas.size() and not found; i++) {

@ -67,13 +67,10 @@ rrc::rrc(srslte::log* rrc_log_) :
connection_reest(this), connection_reest(this),
serving_cell(unique_cell_t(new cell_t())) serving_cell(unique_cell_t(new cell_t()))
{ {
measurements = new rrc_meas(rrc_log); measurements = std::unique_ptr<rrc_meas>(new rrc_meas(rrc_log));
} }
rrc::~rrc() rrc::~rrc() = default;
{
delete measurements;
}
template <class T> template <class T>
void rrc::log_rrc_message(const std::string source, void rrc::log_rrc_message(const std::string source,
@ -361,7 +358,7 @@ void rrc::set_ue_identity(srslte::s_tmsi_t s_tmsi)
/* This function is called from a PHY worker thus must return very quickly. /* This function is called from a PHY worker thus must return very quickly.
* Queue the values of the measurements and process them from the RRC thread * Queue the values of the measurements and process them from the RRC thread
*/ */
void rrc::new_cell_meas(std::vector<phy_meas_t>& meas) void rrc::new_cell_meas(const std::vector<phy_meas_t>& meas)
{ {
cell_meas_q.push(meas); cell_meas_q.push(meas);
} }
@ -379,7 +376,7 @@ void rrc::process_cell_meas()
} }
} }
void rrc::process_new_cell_meas(std::vector<phy_meas_t>& meas) void rrc::process_new_cell_meas(const std::vector<phy_meas_t>& meas)
{ {
bool neighbour_added = false; bool neighbour_added = false;
rrc_log->debug("MEAS: Processing measurement of %lu cells\n", meas.size()); rrc_log->debug("MEAS: Processing measurement of %lu cells\n", meas.size());
@ -540,7 +537,7 @@ void rrc::delete_last_neighbour()
{ {
if (not neighbour_cells.empty()) { if (not neighbour_cells.empty()) {
auto& it = neighbour_cells.back(); auto& it = neighbour_cells.back();
rrc_log->debug("Delete cell earfcn=%d, pci=%d from neighbor list.\n", (*it).get_earfcn(), (*it).get_pci()); rrc_log->debug("Delete cell %s from neighbor list.\n", (*it).to_string().c_str());
neighbour_cells.pop_back(); neighbour_cells.pop_back();
} }
} }
@ -567,19 +564,9 @@ void rrc::log_neighbour_cells()
if (not neighbour_cells.empty()) { if (not neighbour_cells.empty()) {
char ordered[512] = {}; char ordered[512] = {};
int n = 0; int n = 0;
n += snprintf(ordered, n += snprintf(ordered, 512, "[%s", neighbour_cells[0]->to_string().c_str());
512,
"[earfcn=%d, pci=%d, rsrp=%.2f",
neighbour_cells[0]->get_earfcn(),
neighbour_cells[0]->phy_cell.pci,
neighbour_cells[0]->get_rsrp());
for (uint32_t i = 1; i < neighbour_cells.size(); i++) { for (uint32_t i = 1; i < neighbour_cells.size(); i++) {
int m = snprintf(&ordered[n], int m = snprintf(&ordered[n], 512 - n, " | %s", neighbour_cells[i]->to_string().c_str());
512 - n,
" | earfcn=%d, pci=%d, rsrp=%.2f",
neighbour_cells[i]->get_earfcn(),
neighbour_cells[i]->get_pci(),
neighbour_cells[i]->get_rsrp());
n += m; n += m;
} }
rrc_log->info("Neighbours: %s]\n", ordered); rrc_log->info("Neighbours: %s]\n", ordered);
@ -603,27 +590,33 @@ bool rrc::add_neighbour_cell(unique_cell_t new_cell)
bool ret = false; bool ret = false;
// Make sure cell is valid // Make sure cell is valid
if (!new_cell->is_valid()) { if (!new_cell->is_valid()) {
rrc_log->error( rrc_log->error("Trying to add cell %s but is not valid", new_cell->to_string().c_str());
"Trying to add cell EARFCN=%d, PCI=%d but is not valid", new_cell->get_earfcn(), new_cell->get_pci());
return ret; return ret;
} }
// First make sure it doesn't exist // If cell exists, update RSRP value
if (has_neighbour_cell(new_cell->get_earfcn(), new_cell->get_pci())) { cell_t* existing_cell = get_neighbour_cell_handle(new_cell->get_earfcn(), new_cell->get_pci());
rrc_log->warning( if (existing_cell != nullptr) {
"Trying to add cell EARFCN=%d, PCI=%d but already exists", new_cell->get_earfcn(), new_cell->get_pci()); if (std::isnormal(new_cell.get()->get_rsrp())) {
return ret; existing_cell->set_rsrp(new_cell.get()->get_rsrp());
} }
if (neighbour_cells.size() < NOF_NEIGHBOUR_CELLS) {
ret = true;
} else if (new_cell->greater(neighbour_cells.back().get())) {
// delete last neighbour cell
delete_last_neighbour();
ret = true; ret = true;
} else {
// If doesn't exists, add it if there is enough space
if (neighbour_cells.size() < NOF_NEIGHBOUR_CELLS) {
ret = true;
// If there isn't space, keep the strongest only
} else if (new_cell->greater(neighbour_cells.back().get())) {
// delete last neighbour cell
delete_last_neighbour();
ret = true;
}
} }
if (ret) { if (ret) {
rrc_log->info( rrc_log->info(
"Adding neighbour cell %s, nof_neighbours=%zd\n", new_cell->print().c_str(), neighbour_cells.size() + 1); "Adding neighbour cell %s, nof_neighbours=%zd\n", new_cell->to_string().c_str(), neighbour_cells.size() + 1);
neighbour_cells.push_back(std::move(new_cell)); neighbour_cells.push_back(std::move(new_cell));
} else {
rrc_log->warning("Could not add cell %s: no space in neighbours\n", new_cell->to_string().c_str());
} }
sort_neighbour_cells(); sort_neighbour_cells();
@ -679,9 +672,9 @@ std::string rrc::print_neighbour_cells()
std::string s; std::string s;
s.reserve(256); s.reserve(256);
for (auto it = neighbour_cells.begin(); it != neighbour_cells.end() - 1; ++it) { for (auto it = neighbour_cells.begin(); it != neighbour_cells.end() - 1; ++it) {
s += (*it)->print() + ", "; s += (*it)->to_string() + ", ";
} }
s += neighbour_cells.back()->print(); s += neighbour_cells.back()->to_string();
return s; return s;
} }
@ -707,8 +700,8 @@ std::set<uint32_t> rrc::get_neighbour_pcis(uint32_t earfcn)
*******************************************************************************/ *******************************************************************************/
std::string rrc::print_mbms() std::string rrc::print_mbms()
{ {
mcch_msg_type_c msg = serving_cell->mcch.msg; mcch_msg_type_c msg = serving_cell->mcch.msg;
std::stringstream ss; std::stringstream ss;
for (uint32_t i = 0; i < msg.c1().mbsfn_area_cfg_r9().pmch_info_list_r9.size(); i++) { for (uint32_t i = 0; i < msg.c1().mbsfn_area_cfg_r9().pmch_info_list_r9.size(); i++) {
ss << "PMCH: " << i << std::endl; ss << "PMCH: " << i << std::endl;
pmch_info_r9_s* pmch = &msg.c1().mbsfn_area_cfg_r9().pmch_info_list_r9[i]; pmch_info_r9_s* pmch = &msg.c1().mbsfn_area_cfg_r9().pmch_info_list_r9[i];
@ -1071,8 +1064,8 @@ bool rrc::ho_prepare()
cell_t* target_cell = get_neighbour_cell_handle(target_earfcn, mob_ctrl_info->target_pci); cell_t* target_cell = get_neighbour_cell_handle(target_earfcn, mob_ctrl_info->target_pci);
if (!phy->cell_select(&target_cell->phy_cell)) { if (!phy->cell_select(&target_cell->phy_cell)) {
rrc_log->error("Could not synchronize with target cell %s. Removing cell and trying to return to source %s\n", rrc_log->error("Could not synchronize with target cell %s. Removing cell and trying to return to source %s\n",
target_cell->print().c_str(), target_cell->to_string().c_str(),
serving_cell->print().c_str()); serving_cell->to_string().c_str());
// Remove cell from list to avoid cell re-selection, picking the same cell // Remove cell from list to avoid cell re-selection, picking the same cell
target_cell->set_rsrp(-INFINITY); target_cell->set_rsrp(-INFINITY);
@ -1440,9 +1433,10 @@ cell_t* rrc::get_serving_cell()
*******************************************************************************/ *******************************************************************************/
void rrc::write_pdu_bcch_bch(unique_byte_buffer_t pdu) void rrc::write_pdu_bcch_bch(unique_byte_buffer_t pdu)
{ {
bcch_bch_msg_s bch_msg; bcch_bch_msg_s bch_msg;
asn1::cbit_ref bch_bref(pdu->msg, pdu->N_bytes); asn1::cbit_ref bch_bref(pdu->msg, pdu->N_bytes);
asn1::SRSASN_CODE err = bch_msg.unpack(bch_bref); asn1::SRSASN_CODE err = bch_msg.unpack(bch_bref);
if (err != asn1::SRSASN_SUCCESS) { if (err != asn1::SRSASN_SUCCESS) {
rrc_log->error("Could not unpack BCCH-BCH message.\n"); rrc_log->error("Could not unpack BCCH-BCH message.\n");
return; return;
@ -1468,8 +1462,8 @@ void rrc::parse_pdu_bcch_dlsch(unique_byte_buffer_t pdu)
bcch_dl_sch_msg_s dlsch_msg; bcch_dl_sch_msg_s dlsch_msg;
asn1::cbit_ref dlsch_bref(pdu->msg, pdu->N_bytes); asn1::cbit_ref dlsch_bref(pdu->msg, pdu->N_bytes);
asn1::SRSASN_CODE err = dlsch_msg.unpack(dlsch_bref);
asn1::SRSASN_CODE err = dlsch_msg.unpack(dlsch_bref);
if (err != asn1::SRSASN_SUCCESS or dlsch_msg.msg.type().value != bcch_dl_sch_msg_type_c::types_opts::c1) { if (err != asn1::SRSASN_SUCCESS or dlsch_msg.msg.type().value != bcch_dl_sch_msg_type_c::types_opts::c1) {
rrc_log->error("Could not unpack BCCH DL-SCH message.\n"); rrc_log->error("Could not unpack BCCH DL-SCH message.\n");
return; return;
@ -1970,8 +1964,8 @@ void rrc::handle_ue_capability_enquiry(const ue_cap_enquiry_s& enquiry)
{ {
rrc_log->debug("Preparing UE Capability Info\n"); rrc_log->debug("Preparing UE Capability Info\n");
ul_dcch_msg_s ul_dcch_msg; ul_dcch_msg_s ul_dcch_msg;
ue_cap_info_r8_ies_s* info = &ul_dcch_msg.msg.set_c1().set_ue_cap_info().crit_exts.set_c1().set_ue_cap_info_r8(); ue_cap_info_r8_ies_s* info = &ul_dcch_msg.msg.set_c1().set_ue_cap_info().crit_exts.set_c1().set_ue_cap_info_r8();
ul_dcch_msg.msg.c1().ue_cap_info().rrc_transaction_id = transaction_id; ul_dcch_msg.msg.c1().ue_cap_info().rrc_transaction_id = transaction_id;
// resize container to fit all requested RATs // resize container to fit all requested RATs

@ -73,8 +73,8 @@ proc_outcome_t rrc::cell_search_proc::handle_cell_found(const phy_interface_rrc_
// Create a cell with NaN RSRP. Will be updated by new_phy_meas() during SIB search. // Create a cell with NaN RSRP. Will be updated by new_phy_meas() during SIB search.
if (not rrc_ptr->add_neighbour_cell(unique_cell_t(new cell_t(new_cell)))) { if (not rrc_ptr->add_neighbour_cell(unique_cell_t(new cell_t(new_cell)))) {
Info("No more space for neighbour cells\n"); Error("Could not add new found cell\n");
return proc_outcome_t::success; return proc_outcome_t::error;
} }
rrc_ptr->set_serving_cell(new_cell, false); rrc_ptr->set_serving_cell(new_cell, false);
@ -346,7 +346,7 @@ proc_outcome_t rrc::cell_selection_proc::init()
proc_outcome_t rrc::cell_selection_proc::step_cell_selection() proc_outcome_t rrc::cell_selection_proc::step_cell_selection()
{ {
Info("Current serving cell: %s\n", rrc_ptr->serving_cell->print().c_str()); Info("Current serving cell: %s\n", rrc_ptr->serving_cell->to_string().c_str());
// Neighbour cells are sorted in descending order of RSRP // Neighbour cells are sorted in descending order of RSRP
for (; neigh_index < rrc_ptr->neighbour_cells.size(); ++neigh_index) { for (; neigh_index < rrc_ptr->neighbour_cells.size(); ++neigh_index) {
@ -361,7 +361,7 @@ proc_outcome_t rrc::cell_selection_proc::step_cell_selection()
// Try to select Cell // Try to select Cell
rrc_ptr->set_serving_cell(rrc_ptr->neighbour_cells.at(neigh_index)->phy_cell, discard_serving); rrc_ptr->set_serving_cell(rrc_ptr->neighbour_cells.at(neigh_index)->phy_cell, discard_serving);
discard_serving = false; discard_serving = false;
Info("Selected cell: %s\n", rrc_ptr->serving_cell->print().c_str()); Info("Selected cell: %s\n", rrc_ptr->serving_cell->to_string().c_str());
/* BLOCKING CALL */ /* BLOCKING CALL */
if (rrc_ptr->phy->cell_select(&rrc_ptr->serving_cell->phy_cell)) { if (rrc_ptr->phy->cell_select(&rrc_ptr->serving_cell->phy_cell)) {
@ -379,7 +379,7 @@ proc_outcome_t rrc::cell_selection_proc::step_cell_selection()
} }
if (rrc_ptr->phy_sync_state == phy_in_sync && rrc_ptr->cell_selection_criteria(rrc_ptr->serving_cell->get_rsrp())) { if (rrc_ptr->phy_sync_state == phy_in_sync && rrc_ptr->cell_selection_criteria(rrc_ptr->serving_cell->get_rsrp())) {
if (not rrc_ptr->phy->cell_is_camping()) { if (not rrc_ptr->phy->cell_is_camping()) {
Info("Serving cell %s is in-sync but not camping. Selecting it...\n", rrc_ptr->serving_cell->print().c_str()); Info("Serving cell %s is in-sync but not camping. Selecting it...\n", rrc_ptr->serving_cell->to_string().c_str());
/* BLOCKING CALL */ /* BLOCKING CALL */
if (rrc_ptr->phy->cell_select(&rrc_ptr->serving_cell->phy_cell)) { if (rrc_ptr->phy->cell_select(&rrc_ptr->serving_cell->phy_cell)) {
@ -447,7 +447,7 @@ proc_outcome_t rrc::cell_selection_proc::step_cell_config()
return proc_outcome_t::yield; return proc_outcome_t::yield;
} }
if (serv_cell_cfg_fut.is_success()) { if (serv_cell_cfg_fut.is_success()) {
rrc_ptr->rrc_log->console("Selected cell: %s\n", rrc_ptr->serving_cell->print().c_str()); rrc_ptr->rrc_log->console("Selected cell: %s\n", rrc_ptr->serving_cell->to_string().c_str());
Info("All SIBs of serving cell obtained successfully\n"); Info("All SIBs of serving cell obtained successfully\n");
cs_result = cs_result_t::changed_cell; cs_result = cs_result_t::changed_cell;
return proc_outcome_t::success; return proc_outcome_t::success;

@ -240,7 +240,7 @@ public:
void in_sync() override {} void in_sync() override {}
void out_of_sync() override {} void out_of_sync() override {}
void new_cell_meas(std::vector<phy_meas_t>& meas) override void new_cell_meas(const std::vector<phy_meas_t>& meas) override
{ {
for (auto& m : meas) { for (auto& m : meas) {
uint32_t pci = m.pci; uint32_t pci = m.pci;

@ -85,7 +85,7 @@ private:
void in_sync() override { notify_in_sync(); } void in_sync() override { notify_in_sync(); }
void out_of_sync() override { notify_out_of_sync(); } void out_of_sync() override { notify_out_of_sync(); }
void new_cell_meas(std::vector<phy_meas_t>& meas) override void new_cell_meas(const std::vector<phy_meas_t>& meas) override
{ {
for (auto& m : meas) { for (auto& m : meas) {
notify_new_phy_meas(); notify_new_phy_meas();
@ -307,16 +307,16 @@ private:
std::unique_lock<std::mutex> lock(mutex); std::unique_lock<std::mutex> lock(mutex);
return srslte_convert_amplitude_to_dB(rx_gain); return srslte_convert_amplitude_to_dB(rx_gain);
} }
double get_freq_offset() override { return 0; } double get_freq_offset() override { return 0; }
double get_tx_freq(const uint32_t& radio_idx) override { return tx_freq; } double get_tx_freq(const uint32_t& radio_idx) override { return tx_freq; }
double get_rx_freq(const uint32_t& radio_idx) override { return rx_freq; } double get_rx_freq(const uint32_t& radio_idx) override { return rx_freq; }
float get_max_tx_power() override { return 0; } float get_max_tx_power() override { return 0; }
float get_tx_gain_offset() override { return 0; } float get_tx_gain_offset() override { return 0; }
float get_rx_gain_offset() override { return 0; } float get_rx_gain_offset() override { return 0; }
bool is_continuous_tx() override { return false; } bool is_continuous_tx() override { return false; }
bool get_is_start_of_burst(const uint32_t& radio_idx) override { return false; } bool get_is_start_of_burst(const uint32_t& radio_idx) override { return false; }
bool is_init() override { return false; } bool is_init() override { return false; }
void reset() override {} void reset() override {}
srslte_rf_info_t* get_info(const uint32_t& radio_idx) override { return &rf_info; } srslte_rf_info_t* get_info(const uint32_t& radio_idx) override { return &rf_info; }
}; };
@ -465,11 +465,11 @@ public:
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
int ret = SRSLTE_SUCCESS; int ret = SRSLTE_SUCCESS;
const uint32_t default_timeout = 60000; // 1 minute const uint32_t default_timeout = 60000; // 1 minute
// Define Cell // Define Cell
srslte_cell_t cell = {.nof_prb = 6, srslte_cell_t cell = {.nof_prb = 6,
.nof_ports = 1, .nof_ports = 1,
.id = 1, .id = 1,
.cp = SRSLTE_CP_NORM, .cp = SRSLTE_CP_NORM,

@ -58,7 +58,7 @@ public:
void reset() override {} void reset() override {}
void enable_pregen_signals(bool enable) override {} void enable_pregen_signals(bool enable) override {}
void set_cells_to_meas(uint32_t earfcn, std::set<uint32_t>& pci) override void set_cells_to_meas(uint32_t earfcn, const std::set<uint32_t>& pci) override
{ {
freqs_started.insert(earfcn); freqs_started.insert(earfcn);
cells_started[earfcn] = pci; cells_started[earfcn] = pci;
@ -117,7 +117,7 @@ public:
pdcp_test(srslte::log* log_, srslte::timer_handler* t) : srslte::pdcp(t, log_) {} pdcp_test(srslte::log* log_, srslte::timer_handler* t) : srslte::pdcp(t, log_) {}
void write_sdu(uint32_t lcid, srslte::unique_byte_buffer_t sdu, bool blocking = false) override void write_sdu(uint32_t lcid, srslte::unique_byte_buffer_t sdu, bool blocking = false) override
{ {
ul_dcch_msg_s ul_dcch_msg; ul_dcch_msg_s ul_dcch_msg;
asn1::cbit_ref bref(sdu->msg, sdu->N_bytes); asn1::cbit_ref bref(sdu->msg, sdu->N_bytes);
if (ul_dcch_msg.unpack(bref) != asn1::SRSASN_SUCCESS or if (ul_dcch_msg.unpack(bref) != asn1::SRSASN_SUCCESS or
ul_dcch_msg.msg.type().value != ul_dcch_msg_type_c::types_opts::c1) { ul_dcch_msg.msg.type().value != ul_dcch_msg_type_c::types_opts::c1) {
@ -488,7 +488,7 @@ int meas_obj_test()
TESTASSERT(rrctest.phytest.meas_cell_started(2, 23)); // was added TESTASSERT(rrctest.phytest.meas_cell_started(2, 23)); // was added
TESTASSERT(rrctest.phytest.meas_cell_started(2, 24)); // was added TESTASSERT(rrctest.phytest.meas_cell_started(2, 24)); // was added
log1.info("Test7: PHY finds new neigbhours in frequency 1 and 2, check RRC instructs to search them\n"); log1.info("Test7: PHY finds new neighbours in frequency 1 and 2, check RRC instructs to search them\n");
std::vector<rrc_interface_phy_lte::phy_meas_t> phy_meas = {}; std::vector<rrc_interface_phy_lte::phy_meas_t> phy_meas = {};
phy_meas.push_back({0, 0, 1, 31}); phy_meas.push_back({0, 0, 1, 31});
phy_meas.push_back({-1, 0, 1, 32}); phy_meas.push_back({-1, 0, 1, 32});

Loading…
Cancel
Save