Intra-frequency miscellanous changes

master
Xavier Arteaga 4 years ago committed by Xavier Arteaga
parent 7b159563ab
commit 5eadc06dd4

@ -41,7 +41,7 @@ SRSRAN_API int srsran_refsignal_dl_sync_set_cell(srsran_refsignal_dl_sync_t* q,
SRSRAN_API void srsran_refsignal_dl_sync_free(srsran_refsignal_dl_sync_t* q); SRSRAN_API void srsran_refsignal_dl_sync_free(srsran_refsignal_dl_sync_t* q);
SRSRAN_API void srsran_refsignal_dl_sync_run(srsran_refsignal_dl_sync_t* q, cf_t* buffer, uint32_t nsamples); SRSRAN_API int srsran_refsignal_dl_sync_run(srsran_refsignal_dl_sync_t* q, cf_t* buffer, uint32_t nsamples);
SRSRAN_API void srsran_refsignal_dl_sync_measure_sf(srsran_refsignal_dl_sync_t* q, SRSRAN_API void srsran_refsignal_dl_sync_measure_sf(srsran_refsignal_dl_sync_t* q,
cf_t* buffer, cf_t* buffer,

@ -367,9 +367,11 @@ int refsignal_dl_sync_find_peak(srsran_refsignal_dl_sync_t* q, cf_t* buffer, uin
return ret; return ret;
} }
void srsran_refsignal_dl_sync_run(srsran_refsignal_dl_sync_t* q, cf_t* buffer, uint32_t nsamples) int srsran_refsignal_dl_sync_run(srsran_refsignal_dl_sync_t* q, cf_t* buffer, uint32_t nsamples)
{ {
if (q) { if (q == NULL || buffer == NULL) {
return SRSRAN_ERROR_INVALID_INPUTS;
}
uint32_t sf_len = q->ifft.sf_sz; uint32_t sf_len = q->ifft.sf_sz;
uint32_t sf_count = 0; uint32_t sf_count = 0;
float rsrp_lin = 0.0f; float rsrp_lin = 0.0f;
@ -511,7 +513,8 @@ void srsran_refsignal_dl_sync_run(srsran_refsignal_dl_sync_t* q, cf_t* buffer, u
} else { } else {
refsignal_set_results_not_found(q); refsignal_set_results_not_found(q);
} }
}
return SRSRAN_SUCCESS;
} }
void srsran_refsignal_dl_sync_measure_sf(srsran_refsignal_dl_sync_t* q, void srsran_refsignal_dl_sync_measure_sf(srsran_refsignal_dl_sync_t* q,

@ -29,7 +29,7 @@ namespace scell {
class intra_measure_base : public srsran::thread class intra_measure_base : public srsran::thread
{ {
/* /*
* The intra-cell measurment has 5 different states: * The intra-cell measurement has 5 different states:
* - idle: it has been initiated and it is waiting to get configured to start capturing samples. From any state * - idle: it has been initiated and it is waiting to get configured to start capturing samples. From any state
* except quit can transition to idle. * except quit can transition to idle.
* - wait: waits for the TTI trigger to transition to receive * - wait: waits for the TTI trigger to transition to receive
@ -40,7 +40,7 @@ class intra_measure_base : public srsran::thread
* *
* FSM abstraction: * FSM abstraction:
* *
* +------+ set_cells_to_meas +------+ intra_freq_meas_period_ms +---------+ * +------+ set_cells_to_meas +------+ receive_tti_trigger +---------+
* | Idle | --------------------->| Wait |------------------------------>| Receive | * | Idle | --------------------->| Wait |------------------------------>| Receive |
* +------+ +------+ +---------+ * +------+ +------+ +---------+
* ^ ^ | stop +------+ * ^ ^ | stop +------+
@ -48,6 +48,9 @@ class intra_measure_base : public srsran::thread
* init +---------+ intra_freq_meas_len_ms | +------+ * init +---------+ intra_freq_meas_len_ms | +------+
* meas_stop | Measure |<----------------------------------+ * meas_stop | Measure |<----------------------------------+
* +---------+ * +---------+
*
* This class has been designed to be thread safe. Any method can be called from different threads as long as
* init_generic is called when the FSM is in idle.
*/ */
public: public:
/** /**
@ -64,7 +67,7 @@ public:
* @brief Describes the default generic configuration arguments * @brief Describes the default generic configuration arguments
*/ */
struct args_t { struct args_t {
double srate_hz = 0.0; ///< Sampling rate in Hz, set to 0.0 for maximum double srate_hz = 0.0; ///< Sampling rate in Hz, optional for LTE, compulsory for NR
uint32_t len_ms = 20; ///< Amount of time to accumulate uint32_t len_ms = 20; ///< Amount of time to accumulate
uint32_t period_ms = 200; ///< Minimum time interval between measurements, set to 0 for free-run uint32_t period_ms = 200; ///< Minimum time interval between measurements, set to 0 for free-run
uint32_t tti_period = 0; ///< Measurement TTI trigger period, set to 0 to trigger at any TTI uint32_t tti_period = 0; ///< Measurement TTI trigger period, set to 0 to trigger at any TTI
@ -250,8 +253,13 @@ private:
/** /**
* @brief Pure virtual function to perform measurements * @brief Pure virtual function to perform measurements
* @note The context is pass-by-value to protect it from concurrency. However, the buffer is pass-by-reference
* as it is protected by the state.
* @param context Provides current measurement context
* @param buffer Provides current measurement context
* @return True if the measurement functions are executed without errors, otherwise false
*/ */
virtual void measure_rat(const measure_context_t& context, std::vector<cf_t>& buffer) = 0; virtual bool measure_rat(measure_context_t context, std::vector<cf_t>& buffer) = 0;
/** /**
* @brief Measurement process helper method. Encapsulates the neighbour cell measurement functionality * @brief Measurement process helper method. Encapsulates the neighbour cell measurement functionality

@ -67,8 +67,9 @@ private:
* @brief LTE specific measurement process * @brief LTE specific measurement process
* @param context Measurement context * @param context Measurement context
* @param buffer Provides the baseband buffer to perform the measurements * @param buffer Provides the baseband buffer to perform the measurements
* @return True if no error happens, otherwise false
*/ */
void measure_rat(const measure_context_t& context, std::vector<cf_t>& buffer) override; bool measure_rat(measure_context_t context, std::vector<cf_t>& buffer) override;
srslog::basic_logger& logger; srslog::basic_logger& logger;
srsran_cell_t serving_cell = {}; ///< Current serving cell in the EARFCN, to avoid reporting it srsran_cell_t serving_cell = {}; ///< Current serving cell in the EARFCN, to avoid reporting it

@ -107,8 +107,9 @@ private:
* @attention It searches and measures the SSB with best SNR * @attention It searches and measures the SSB with best SNR
* @param context Measurement context * @param context Measurement context
* @param buffer Provides the baseband buffer to perform the measurements * @param buffer Provides the baseband buffer to perform the measurements
* @return True if no error happen, otherwise false
*/ */
void measure_rat(const measure_context_t& context, std::vector<cf_t>& buffer) override; bool measure_rat(measure_context_t context, std::vector<cf_t>& buffer) override;
srslog::basic_logger& logger; srslog::basic_logger& logger;
uint32_t cc_idx = 0; uint32_t cc_idx = 0;

@ -38,9 +38,16 @@ void intra_measure_base::init_generic(uint32_t cc_idx_, const args_t& args)
context.trigger_tti_offset = args.tti_offset; context.trigger_tti_offset = args.tti_offset;
context.rx_gain_offset_db = args.rx_gain_offset_db; context.rx_gain_offset_db = args.rx_gain_offset_db;
context.sf_len = SRSRAN_SF_LEN_PRB(SRSRAN_MAX_PRB); // Compute subframe length from the sampling rate if available
if (std::isnormal(args.srate_hz)) { if (std::isnormal(args.srate_hz)) {
context.sf_len = (uint32_t)round(args.srate_hz / 1000.0); context.sf_len = (uint32_t)round(args.srate_hz / 1000.0);
} else if (get_rat() == srsran::srsran_rat_t::lte) {
// Select maximum subframe size for LTE
context.sf_len = SRSRAN_SF_LEN_PRB(SRSRAN_MAX_PRB);
} else {
// No maximum subframe length is defined for other RATs
ERROR("A sampling rate was expected for %s. Undefined behaviour.", srsran::to_string(get_rat()).c_str());
return;
} }
// Calculate the new required bytes // Calculate the new required bytes
@ -54,6 +61,7 @@ void intra_measure_base::init_generic(uint32_t cc_idx_, const args_t& args)
// Initialise buffer for the maximum number of PRB // Initialise buffer for the maximum number of PRB
if (srsran_ringbuffer_init(&ring_buffer, max_required_bytes) < SRSRAN_SUCCESS) { if (srsran_ringbuffer_init(&ring_buffer, max_required_bytes) < SRSRAN_SUCCESS) {
ERROR("Error initiating ringbuffer");
return; return;
} }
} }
@ -86,7 +94,7 @@ void intra_measure_base::meas_stop()
// Transition state to idle // Transition state to idle
// Ring-buffer shall not be reset, it will automatically be reset as soon as the FSM transitions to receive // Ring-buffer shall not be reset, it will automatically be reset as soon as the FSM transitions to receive
state.set_state(internal_state::idle); state.set_state(internal_state::idle);
Log(info, "Disabled neighbour cell search for EARFCN %d", get_earfcn()); Log(info, "Disabled neighbour cell search");
} }
void intra_measure_base::set_cells_to_meas(const std::set<uint32_t>& pci) void intra_measure_base::set_cells_to_meas(const std::set<uint32_t>& pci)
@ -95,7 +103,7 @@ void intra_measure_base::set_cells_to_meas(const std::set<uint32_t>& pci)
context.active_pci = pci; context.active_pci = pci;
active_pci_mutex.unlock(); active_pci_mutex.unlock();
state.set_state(internal_state::wait_first); state.set_state(internal_state::wait_first);
Log(info, "Received list of %zd neighbour cells to measure in EARFCN %d.", pci.size(), get_earfcn()); Log(info, "Received list of %zd neighbour cells to measure", pci.size());
} }
void intra_measure_base::write(cf_t* data, uint32_t nsamples) void intra_measure_base::write(cf_t* data, uint32_t nsamples)
@ -108,7 +116,7 @@ void intra_measure_base::write(cf_t* data, uint32_t nsamples)
// Try writing in the buffer // Try writing in the buffer
if (srsran_ringbuffer_write(&ring_buffer, data, nbytes) < nbytes) { if (srsran_ringbuffer_write(&ring_buffer, data, nbytes) < nbytes) {
Log(warning, "Error writing to ringbuffer (EARFCN=%d)", get_earfcn()); Log(warning, "Error writing to ringbuffer");
// Transition to wait, so it can keep receiving without stopping the component operation // Transition to wait, so it can keep receiving without stopping the component operation
state.set_state(internal_state::wait); state.set_state(internal_state::wait);
@ -154,11 +162,11 @@ void intra_measure_base::run_tti(uint32_t tti, cf_t* data, uint32_t nsamples)
void intra_measure_base::measure_proc() void intra_measure_base::measure_proc()
{ {
std::set<uint32_t> cells_to_measure = {};
// Read data from buffer and find cells in it // Read data from buffer and find cells in it
int ret = srsran_ringbuffer_read_timed( int ret = srsran_ringbuffer_read_timed(
&ring_buffer, search_buffer.data(), (int)(context.meas_len_ms * context.sf_len * sizeof(cf_t)), 1000); &ring_buffer, search_buffer.data(), (int)(context.meas_len_ms * context.sf_len * sizeof(cf_t)), 1000);
// As this function is called once the ring-buffer has enough data to process, it is not expected to fail
if (ret < SRSRAN_SUCCESS) { if (ret < SRSRAN_SUCCESS) {
Log(error, "Ringbuffer read returned %d", ret); Log(error, "Ringbuffer read returned %d", ret);
return; return;
@ -171,7 +179,9 @@ void intra_measure_base::measure_proc()
} }
// Perform measurements for the actual RAT // Perform measurements for the actual RAT
measure_rat(context, search_buffer); if (not measure_rat(context, search_buffer)) {
Log(error, "Error measuring RAT");
}
} }
void intra_measure_base::run_thread() void intra_measure_base::run_thread()

@ -47,7 +47,7 @@ void intra_measure_lte::set_primary_cell(uint32_t earfcn, srsran_cell_t cell)
set_current_sf_len((uint32_t)SRSRAN_SF_LEN_PRB(cell.nof_prb)); set_current_sf_len((uint32_t)SRSRAN_SF_LEN_PRB(cell.nof_prb));
} }
void intra_measure_lte::measure_rat(const measure_context_t& context, std::vector<cf_t>& buffer) bool intra_measure_lte::measure_rat(measure_context_t context, std::vector<cf_t>& buffer)
{ {
std::set<uint32_t> cells_to_measure = context.active_pci; std::set<uint32_t> cells_to_measure = context.active_pci;
@ -68,8 +68,16 @@ void intra_measure_lte::measure_rat(const measure_context_t& context, std::vecto
srsran_cell_t cell = serving_cell; srsran_cell_t cell = serving_cell;
cell.id = id; cell.id = id;
srsran_refsignal_dl_sync_set_cell(&refsignal_dl_sync, cell); if (srsran_refsignal_dl_sync_set_cell(&refsignal_dl_sync, cell) < SRSRAN_SUCCESS) {
srsran_refsignal_dl_sync_run(&refsignal_dl_sync, buffer.data(), context.meas_len_ms * context.sf_len); Log(error, "Error setting refsignal DL cell");
return false;
}
if (srsran_refsignal_dl_sync_run(&refsignal_dl_sync, buffer.data(), context.meas_len_ms * context.sf_len) <
SRSRAN_SUCCESS) {
Log(error, "Error running refsignal DL measurements");
return false;
}
if (refsignal_dl_sync.found) { if (refsignal_dl_sync.found) {
phy_meas_t m = {}; phy_meas_t m = {};
@ -96,6 +104,8 @@ void intra_measure_lte::measure_rat(const measure_context_t& context, std::vecto
if (not neighbour_cells.empty()) { if (not neighbour_cells.empty()) {
context.new_cell_itf.new_cell_meas(context.cc_idx, neighbour_cells); context.new_cell_itf.new_cell_meas(context.cc_idx, neighbour_cells);
} }
return true;
} }
} // namespace scell } // namespace scell

@ -81,7 +81,7 @@ bool intra_measure_nr::set_config(uint32_t arfcn, const config_t& cfg)
return true; return true;
} }
void intra_measure_nr::measure_rat(const measure_context_t& context, std::vector<cf_t>& buffer) bool intra_measure_nr::measure_rat(const measure_context_t context, std::vector<cf_t>& buffer)
{ {
std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now(); std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
@ -90,6 +90,7 @@ void intra_measure_nr::measure_rat(const measure_context_t& context, std::vector
uint32_t N_id = 0; uint32_t N_id = 0;
if (srsran_ssb_csi_search(&ssb, buffer.data(), context.sf_len * context.meas_len_ms, &N_id, &meas) < SRSRAN_SUCCESS) { if (srsran_ssb_csi_search(&ssb, buffer.data(), context.sf_len * context.meas_len_ms, &N_id, &meas) < SRSRAN_SUCCESS) {
Log(error, "Error searching for SSB"); Log(error, "Error searching for SSB");
return false;
} }
std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now(); std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
@ -98,7 +99,7 @@ void intra_measure_nr::measure_rat(const measure_context_t& context, std::vector
// Early return if the found PCI matches with the serving cell ID // Early return if the found PCI matches with the serving cell ID
if (serving_cell_pci == (int)N_id) { if (serving_cell_pci == (int)N_id) {
return; return true;
} }
// Take valid decision if SNR threshold is exceeded // Take valid decision if SNR threshold is exceeded
@ -124,6 +125,8 @@ void intra_measure_nr::measure_rat(const measure_context_t& context, std::vector
// Push measurements to higher layers // Push measurements to higher layers
context.new_cell_itf.new_cell_meas(cc_idx, meas_list); context.new_cell_itf.new_cell_meas(cc_idx, meas_list);
} }
return true;
} }
} // namespace scell } // namespace scell

Loading…
Cancel
Save