diff --git a/srsue/hdr/phy/prach.h b/srsue/hdr/phy/prach.h index 2a6bd526b..1181bee1b 100644 --- a/srsue/hdr/phy/prach.h +++ b/srsue/hdr/phy/prach.h @@ -22,41 +22,29 @@ #ifndef SRSUE_PRACH_H #define SRSUE_PRACH_H -#include -#include - #include "srslte/common/log.h" #include "srslte/interfaces/ue_interfaces.h" #include "srslte/radio/radio.h" #include "srslte/srslte.h" +#include namespace srsue { class prach { public: - prach() - { - bzero(&prach_obj, sizeof(srslte_prach_t)); - bzero(&cell, sizeof(srslte_cell_t)); - bzero(&cfo_h, sizeof(srslte_cfo_t)); + prach() = default; + ~prach() { stop(); } - transmitted_tti = 0; - target_power_dbm = 0; - mem_initiated = false; - cell_initiated = false; - signal_buffer = NULL; - } - ~prach(); void init(uint32_t max_prb, srslte::log* log_h); void stop(); bool set_cell(srslte_cell_t cell, srslte_prach_cfg_t prach_cfg); bool prepare_to_send(uint32_t preamble_idx, int allowed_subframe = -1, float target_power_dbm = -1); bool is_ready_to_send(uint32_t current_tti); - bool is_pending(); + bool is_pending() const; cf_t* generate(float cfo, uint32_t* nof_sf, float* target_power = NULL); - phy_interface_mac_lte::prach_info_t get_info(); + phy_interface_mac_lte::prach_info_t get_info() const; private: bool generate_buffer(uint32_t f_idx); @@ -72,23 +60,25 @@ private: } private: - const static int MAX_LEN_SF = 3; + static constexpr unsigned MAX_LEN_SF = 3; + static constexpr unsigned max_fs = 12; + static constexpr unsigned max_preambles = 64; - srslte::log* log_h; - int preamble_idx; - int allowed_subframe; - bool mem_initiated; - bool cell_initiated; - uint32_t len; - cf_t* buffer[12][64]; - std::bitset<12 * 64> buffer_bitmask; - srslte_prach_t prach_obj; - int transmitted_tti; - srslte_cell_t cell; - cf_t* signal_buffer; - srslte_cfo_t cfo_h; - float target_power_dbm; - srslte_prach_cfg_t cfg = {}; + srslte::log* log_h = nullptr; + srslte_prach_t prach_obj = {}; + srslte_cell_t cell = {}; + srslte_cfo_t cfo_h = {}; + srslte_prach_cfg_t cfg = {}; + std::array, max_fs> buffer = {}; + cf_t* signal_buffer = nullptr; + int preamble_idx = 0; + uint32_t len = 0; + int allowed_subframe = 0; + int transmitted_tti = 0; + float target_power_dbm = 0; + bool mem_initiated = false; + bool cell_initiated = false; + std::bitset buffer_bitmask; }; } // namespace srsue diff --git a/srsue/src/phy/prach.cc b/srsue/src/phy/prach.cc index aea1a2f5a..e7671b82a 100644 --- a/srsue/src/phy/prach.cc +++ b/srsue/src/phy/prach.cc @@ -19,15 +19,10 @@ * */ -#include -#include -#include - +#include "srsue/hdr/phy/prach.h" #include "srslte/common/log.h" #include "srslte/interfaces/ue_interfaces.h" #include "srslte/srslte.h" -#include "srsue/hdr/phy/phy.h" -#include "srsue/hdr/phy/prach.h" #define Error(fmt, ...) \ if (SRSLTE_DEBUG_ENABLED) \ @@ -42,100 +37,100 @@ if (SRSLTE_DEBUG_ENABLED) \ log_h->debug(fmt, ##__VA_ARGS__) -namespace srsue { - -prach::~prach() -{ - stop(); -} +using namespace srsue; void prach::init(uint32_t max_prb, srslte::log* log_h_) { log_h = log_h_; - for (int i = 0; i < 64; i++) { - for (int f = 0; f < 12; f++) { - buffer[f][i] = srslte_vec_cf_malloc(SRSLTE_PRACH_MAX_LEN); - if (!buffer[f][i]) { + for (auto& i : buffer) { + for (auto& j : i) { + j = srslte_vec_cf_malloc(SRSLTE_PRACH_MAX_LEN); + if (!j) { perror("malloc"); return; } } } + if (srslte_cfo_init(&cfo_h, SRSLTE_PRACH_MAX_LEN)) { ERROR("PRACH: Error initiating CFO\n"); return; } + srslte_cfo_set_tol(&cfo_h, 0); + signal_buffer = srslte_vec_cf_malloc(MAX_LEN_SF * 30720U); if (!signal_buffer) { perror("malloc"); return; } + if (srslte_prach_init(&prach_obj, srslte_symbol_sz(max_prb))) { Error("Initiating PRACH library\n"); return; } + mem_initiated = true; } void prach::stop() { - if (mem_initiated) { - for (int i = 0; i < 64; i++) { - for (int f = 0; f < 12; f++) { - if (buffer[f][i]) { - free(buffer[f][i]); - } - } - } - if (signal_buffer) { - free(signal_buffer); + if (!mem_initiated) { + return; + } + + for (auto& i : buffer) { + for (auto& j : i) { + free(j); } - srslte_cfo_free(&cfo_h); - srslte_prach_free(&prach_obj); - mem_initiated = false; } + + free(signal_buffer); + srslte_cfo_free(&cfo_h); + srslte_prach_free(&prach_obj); + mem_initiated = false; } bool prach::set_cell(srslte_cell_t cell_, srslte_prach_cfg_t prach_cfg) { - if (mem_initiated) { - // TODO: Check if other PRACH parameters changed - if (cell.id != cell_.id || !cell_initiated) { - cell = cell_; - cfg = prach_cfg; - preamble_idx = -1; - - if (6 + prach_cfg.freq_offset > cell.nof_prb) { - log_h->console( - "Error no space for PRACH: frequency offset=%d, N_rb_ul=%d\n", prach_cfg.freq_offset, cell.nof_prb); - log_h->error( - "Error no space for PRACH: frequency offset=%d, N_rb_ul=%d\n", prach_cfg.freq_offset, cell.nof_prb); - return false; - } + if (!mem_initiated) { + ERROR("PRACH: Error must call init() first\n"); + return false; + } - Info("PRACH: configIdx=%d, rootSequence=%d, zeroCorrelationConfig=%d, freqOffset=%d\n", - prach_cfg.config_idx, - prach_cfg.root_seq_idx, - prach_cfg.zero_corr_zone, - prach_cfg.freq_offset); + // TODO: Check if other PRACH parameters changed + if (cell.id == cell_.id && cell_initiated) { + return true; + } - if (srslte_prach_set_cfg(&prach_obj, &prach_cfg, cell.nof_prb)) { - Error("Initiating PRACH library\n"); - return false; - } + cell = cell_; + cfg = prach_cfg; + preamble_idx = -1; - buffer_bitmask.reset(); - len = prach_obj.N_seq + prach_obj.N_cp; - transmitted_tti = -1; - cell_initiated = true; - } - return true; - } else { - ERROR("PRACH: Error must call init() first\n"); + if (6 + prach_cfg.freq_offset > cell.nof_prb) { + log_h->console("Error no space for PRACH: frequency offset=%d, N_rb_ul=%d\n", prach_cfg.freq_offset, cell.nof_prb); + log_h->error("Error no space for PRACH: frequency offset=%d, N_rb_ul=%d\n", prach_cfg.freq_offset, cell.nof_prb); + return false; + } + + Info("PRACH: configIdx=%d, rootSequence=%d, zeroCorrelationConfig=%d, freqOffset=%d\n", + prach_cfg.config_idx, + prach_cfg.root_seq_idx, + prach_cfg.zero_corr_zone, + prach_cfg.freq_offset); + + if (srslte_prach_set_cfg(&prach_obj, &prach_cfg, cell.nof_prb)) { + Error("Initiating PRACH library\n"); return false; } + + buffer_bitmask.reset(); + len = prach_obj.N_seq + prach_obj.N_cp; + transmitted_tti = -1; + cell_initiated = true; + + return true; } bool prach::generate_buffer(uint32_t f_idx) @@ -161,26 +156,26 @@ bool prach::generate_buffer(uint32_t f_idx) bool prach::prepare_to_send(uint32_t preamble_idx_, int allowed_subframe_, float target_power_dbm_) { - if (cell_initiated && preamble_idx_ < 64) { + if (cell_initiated && preamble_idx_ < max_preambles) { preamble_idx = preamble_idx_; target_power_dbm = target_power_dbm_; allowed_subframe = allowed_subframe_; transmitted_tti = -1; Debug("PRACH: prepare to send preamble %d\n", preamble_idx); return true; + } + + if (!cell_initiated) { + Error("PRACH: Cell not configured\n"); } else { - if (!cell_initiated) { - Error("PRACH: Cell not configured\n"); - } else { - Error("PRACH: Invalid preamble %d\n", preamble_idx_); - } - return false; + Error("PRACH: Invalid preamble %d\n", preamble_idx_); } + return false; } -bool prach::is_pending() +bool prach::is_pending() const { - return cell_initiated && preamble_idx >= 0 && preamble_idx < 64; + return cell_initiated && preamble_idx >= 0 && unsigned(preamble_idx) < max_preambles; } bool prach::is_ready_to_send(uint32_t current_tti_) @@ -197,7 +192,7 @@ bool prach::is_ready_to_send(uint32_t current_tti_) return false; } -phy_interface_mac_lte::prach_info_t prach::get_info() +phy_interface_mac_lte::prach_info_t prach::get_info() const { phy_interface_mac_lte::prach_info_t info = {}; @@ -217,61 +212,58 @@ phy_interface_mac_lte::prach_info_t prach::get_info() cf_t* prach::generate(float cfo, uint32_t* nof_sf, float* target_power) { - if (cell_initiated && preamble_idx >= 0 && nof_sf && preamble_idx < 64 && srslte_cell_isvalid(&cell) && - len < MAX_LEN_SF * 30720 && len > 0) { - - uint32_t f_idx = 0; - if (cell.frame_type == SRSLTE_TDD) { - f_idx = prach_obj.current_prach_idx; - // For format4, choose odd or even position - if (prach_obj.config_idx >= 48) { - f_idx += 6; - } - if (f_idx >= 12) { - Error("PRACH Buffer: Invalid f_idx=%d\n", f_idx); - f_idx = 0; - } - } + if (!cell_initiated || preamble_idx < 0 || !nof_sf || unsigned(preamble_idx) >= max_preambles || + !srslte_cell_isvalid(&cell) || len >= MAX_LEN_SF * 30720 || len == 0) { + Error("PRACH: Invalid parameters: cell_initiated=%d, preamble_idx=%d, cell.nof_prb=%d, len=%d\n", + cell_initiated, + preamble_idx, + cell.nof_prb, + len); + return nullptr; + } - if (!generate_buffer(f_idx)) { - return NULL; + uint32_t f_idx = 0; + if (cell.frame_type == SRSLTE_TDD) { + f_idx = prach_obj.current_prach_idx; + // For format4, choose odd or even position + if (prach_obj.config_idx >= 48) { + f_idx += 6; } - - if (!is_buffer_generated(f_idx, preamble_idx)) { - Error("PRACH Buffer not generated: f_idx=%d preamble_idx=%d\n", f_idx, preamble_idx); - return NULL; + if (f_idx >= max_fs) { + Error("PRACH Buffer: Invalid f_idx=%d\n", f_idx); + f_idx = 0; } + } - // Correct CFO before transmission - srslte_cfo_correct(&cfo_h, buffer[f_idx][preamble_idx], signal_buffer, cfo / srslte_symbol_sz(cell.nof_prb)); + if (!generate_buffer(f_idx)) { + return nullptr; + } - // pad guard symbols with zeros - uint32_t nsf = (len - 1) / SRSLTE_SF_LEN_PRB(cell.nof_prb) + 1; - srslte_vec_cf_zero(&signal_buffer[len], (nsf * SRSLTE_SF_LEN_PRB(cell.nof_prb) - len)); + if (!is_buffer_generated(f_idx, preamble_idx)) { + Error("PRACH Buffer not generated: f_idx=%d preamble_idx=%d\n", f_idx, preamble_idx); + return nullptr; + } - *nof_sf = nsf; + // Correct CFO before transmission + srslte_cfo_correct(&cfo_h, buffer[f_idx][preamble_idx], signal_buffer, cfo / srslte_symbol_sz(cell.nof_prb)); - if (target_power) { - *target_power = target_power_dbm; - } + // pad guard symbols with zeros + uint32_t nsf = (len - 1) / SRSLTE_SF_LEN_PRB(cell.nof_prb) + 1; + srslte_vec_cf_zero(&signal_buffer[len], (nsf * SRSLTE_SF_LEN_PRB(cell.nof_prb) - len)); - Info("PRACH: Transmitted preamble=%d, tti_tx=%d, CFO=%.2f KHz, nof_sf=%d, target_power=%.1f dBm\n", - preamble_idx, - transmitted_tti, - cfo * 15, - nsf, - target_power_dbm); - preamble_idx = -1; + *nof_sf = nsf; - return signal_buffer; - } else { - Error("PRACH: Invalid parameters: cell_initiated=%d, preamble_idx=%d, cell.nof_prb=%d, len=%d\n", - cell_initiated, - preamble_idx, - cell.nof_prb, - len); - return NULL; + if (target_power) { + *target_power = target_power_dbm; } -} -} // namespace srsue + Info("PRACH: Transmitted preamble=%d, tti_tx=%d, CFO=%.2f KHz, nof_sf=%d, target_power=%.1f dBm\n", + preamble_idx, + transmitted_tti, + cfo * 15, + nsf, + target_power_dbm); + preamble_idx = -1; + + return signal_buffer; +}