mirror of https://github.com/PentHertz/srsLTE.git
184 lines
5.6 KiB
C++
184 lines
5.6 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.
|
|
*
|
|
*/
|
|
|
|
#include "srsran/common/band_helper.h"
|
|
#include <algorithm>
|
|
#include <cmath>
|
|
|
|
namespace srsran {
|
|
|
|
// definition of static members
|
|
constexpr std::array<srsran_band_helper::nr_band, srsran_band_helper::nof_nr_bands_fr1>
|
|
srsran_band_helper::nr_band_table_fr1;
|
|
constexpr std::array<srsran_band_helper::nr_raster_params, 3> srsran_band_helper::nr_fr_params;
|
|
constexpr std::array<srsran_band_helper::nr_operating_band, srsran_band_helper::nof_nr_operating_band_fr1>
|
|
srsran_band_helper::nr_operating_bands_fr1;
|
|
constexpr std::array<srsran_band_helper::nr_band_ss_raster, srsran_band_helper::nof_nr_band_ss_raster>
|
|
srsran_band_helper::nr_band_ss_raster_table;
|
|
|
|
// Formula in 5.4.2.1
|
|
double srsran_band_helper::nr_arfcn_to_freq(uint32_t nr_arfcn)
|
|
{
|
|
nr_raster_params params = get_raster_params(nr_arfcn);
|
|
return (params.F_REF_Offs_MHz * 1e6 + params.delta_F_global_kHz * (nr_arfcn - params.N_REF_Offs) * 1e3);
|
|
}
|
|
|
|
// Implements 5.4.2.1 in TS 38.401
|
|
std::vector<uint32_t> srsran_band_helper::get_bands_nr(uint32_t nr_arfcn,
|
|
srsran_band_helper::delta_f_raster_t delta_f_raster)
|
|
{
|
|
std::vector<uint32_t> bands;
|
|
for (const auto& nr_band : nr_band_table_fr1) {
|
|
if (nr_arfcn >= nr_band.dl_nref_first && nr_arfcn <= nr_band.dl_nref_last && nr_arfcn % nr_band.dl_nref_step == 0) {
|
|
// band must not already be present
|
|
if (std::find(bands.begin(), bands.end(), nr_band.band) == bands.end()) {
|
|
if (delta_f_raster == DEFAULT) {
|
|
// add band if delta_f_raster has default value
|
|
bands.push_back(nr_band.band);
|
|
} else {
|
|
// if delta_f_raster is set explicitly, only add if band matches
|
|
if (nr_band.delta_f_raster == delta_f_raster) {
|
|
bands.push_back(nr_band.band);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return bands;
|
|
}
|
|
|
|
uint16_t srsran_band_helper::get_band_from_dl_freq_Hz(double freq) const
|
|
{
|
|
uint32_t freq_MHz = (uint32_t)round(freq / 1e6);
|
|
for (const nr_operating_band& band : nr_operating_bands_fr1) {
|
|
if (freq_MHz >= band.F_DL_low and freq_MHz <= band.F_DL_high) {
|
|
return band.band;
|
|
}
|
|
}
|
|
return UINT16_MAX;
|
|
}
|
|
|
|
uint16_t srsran_band_helper::get_band_from_dl_arfcn(uint32_t arfcn) const
|
|
{
|
|
for (const nr_band& band : nr_band_table_fr1) {
|
|
// Check given ARFCN is between the first and last possible ARFCN and matches step
|
|
if (arfcn >= band.dl_nref_first and arfcn <= band.dl_nref_last and
|
|
(arfcn - band.dl_nref_first) % band.dl_nref_step == 0) {
|
|
return band.band;
|
|
}
|
|
}
|
|
return UINT16_MAX;
|
|
}
|
|
|
|
srsran_ssb_patern_t srsran_band_helper::get_ssb_pattern(uint16_t band, srsran_subcarrier_spacing_t scs) const
|
|
{
|
|
// Look for the given band and SCS
|
|
for (const nr_band_ss_raster& ss_raster : nr_band_ss_raster_table) {
|
|
// Check if band and SCS match!
|
|
if (ss_raster.band == band && ss_raster.scs == scs) {
|
|
return ss_raster.pattern;
|
|
}
|
|
|
|
// As bands are in ascending order, do not waste more time if the current band is bigger
|
|
if (ss_raster.band > band) {
|
|
return SRSRAN_SSB_PATTERN_INVALID;
|
|
}
|
|
}
|
|
|
|
// Band is out of range, so consider invalid
|
|
return SRSRAN_SSB_PATTERN_INVALID;
|
|
}
|
|
|
|
srsran_duplex_mode_t srsran_band_helper::get_duplex_mode(uint16_t band) const
|
|
{
|
|
// Look for the given band
|
|
for (const nr_operating_band& b : nr_operating_bands_fr1) {
|
|
// Check if band and SCS match!
|
|
if (b.band == band) {
|
|
return b.duplex_mode;
|
|
}
|
|
|
|
// As bands are in ascending order, do not waste more time if the current band is bigger
|
|
if (b.band > band) {
|
|
return SRSRAN_DUPLEX_MODE_INVALID;
|
|
}
|
|
}
|
|
|
|
// Band is out of range, so consider invalid
|
|
return SRSRAN_DUPLEX_MODE_INVALID;
|
|
}
|
|
|
|
struct sync_raster_impl : public srsran_band_helper::sync_raster_t {
|
|
public:
|
|
sync_raster_impl(uint32_t f, uint32_t s, uint32_t l) : sync_raster_t(f, s, l)
|
|
{
|
|
// Do nothing
|
|
}
|
|
};
|
|
|
|
double srsran_band_helper::sync_raster_t::get_frequency() const
|
|
{
|
|
// Row 1
|
|
if (gscn >= 2 and gscn <= 7498) {
|
|
double N = std::ceil((gscn - 1) / 3.0);
|
|
double M = (gscn - 3 * N) / 2.0 + 3.0;
|
|
return N * 1200e3 + M * 50e3;
|
|
}
|
|
|
|
// Row 2
|
|
if (gscn >= 7499 and gscn <= 22255) {
|
|
double N = gscn - 7499;
|
|
return 3000e6 + N * 1.44e6;
|
|
}
|
|
|
|
// Row 3
|
|
if (gscn >= 22256 and gscn <= 26639) {
|
|
double N = gscn - 22256;
|
|
return 2425.08e6 + N * 17.28e6;
|
|
}
|
|
|
|
// Unhandled case
|
|
return NAN;
|
|
}
|
|
|
|
srsran_band_helper::sync_raster_t srsran_band_helper::get_sync_raster(uint16_t band,
|
|
srsran_subcarrier_spacing_t scs) const
|
|
{
|
|
// Look for the given band and SCS
|
|
for (const nr_band_ss_raster& ss_raster : nr_band_ss_raster_table) {
|
|
// Check if band and SCS match!
|
|
if (ss_raster.band == band && ss_raster.scs == scs) {
|
|
return sync_raster_impl(ss_raster.gscn_first, ss_raster.gscn_step, ss_raster.gscn_last);
|
|
}
|
|
|
|
// As bands are in ascending order, do not waste more time if the current band is bigger
|
|
if (ss_raster.band > band) {
|
|
return sync_raster_impl(0, 0, 0);
|
|
}
|
|
}
|
|
|
|
// Band is out of range, so consider invalid
|
|
return sync_raster_impl(0, 0, 0);
|
|
}
|
|
|
|
srsran_band_helper::nr_raster_params srsran_band_helper::get_raster_params(uint32_t nr_arfcn)
|
|
{
|
|
for (auto& fr : nr_fr_params) {
|
|
if (nr_arfcn >= fr.N_REF_min && nr_arfcn <= fr.N_REF_max) {
|
|
return fr;
|
|
}
|
|
}
|
|
return {}; // return empty params
|
|
}
|
|
|
|
} // namespace srsran
|