From 617e0ddb6739f85abe38570810a186e6c67afbf9 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 25 Jan 2021 21:49:20 +0100 Subject: [PATCH] band_helper: add helper class for RF bands attempt to C++ify handling of radio bands and (E/NR)ARFCNs, etc. --- lib/include/srslte/common/band_helper.h | 106 ++++++++++++++++++++++++ lib/src/common/CMakeLists.txt | 1 + lib/src/common/band_helper.cc | 64 ++++++++++++++ lib/src/common/test/CMakeLists.txt | 3 + lib/src/common/test/band_helper_test.cc | 48 +++++++++++ 5 files changed, 222 insertions(+) create mode 100644 lib/include/srslte/common/band_helper.h create mode 100644 lib/src/common/band_helper.cc create mode 100644 lib/src/common/test/band_helper_test.cc diff --git a/lib/include/srslte/common/band_helper.h b/lib/include/srslte/common/band_helper.h new file mode 100644 index 000000000..e2521277a --- /dev/null +++ b/lib/include/srslte/common/band_helper.h @@ -0,0 +1,106 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2020 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 SRSLTE_BAND_HELPER_H +#define SRSLTE_BAND_HELPER_H + +#include +#include +#include + +namespace srslte { + +// Helper class to handle frequency bands and ARFCNs +// For NR: NR-ARFCN and channel raster as per TS 38.104 +class srslte_band_helper +{ +public: + srslte_band_helper() = default; + ~srslte_band_helper() = default; + + // Return frequency of given NR-ARFCN in Hz + double nr_arfcn_to_freq(uint32_t nr_arfcn); + + // Possible values of delta f_raster in Table 5.4.2.3-1 and Table 5.4.2.3-2 + enum delta_f_raster_t { + DEFAULT = 0, // for bands with 2 possible values for delta_f_raster (e.g. 15 and 30 kHz), the lower is chosen + KHZ_15, + KHZ_30, + KHZ_60, + KHZ_100, + KHZ_120 + }; + + // Return vector of bands that ARFCN is valid for + // For bands with 2 possible raster offsets, delta_f_raster needs to be specified + std::vector get_bands_nr(uint32_t nr_arfcn, delta_f_raster_t delta_f_raster = DEFAULT); + +private: + // Table 5.4.2.1-1 + struct nr_raster_params { + double delta_F_global_kHz; + double F_REF_Offs_MHz; + uint32_t N_REF_Offs; + uint32_t N_REF_min; + uint32_t N_REF_max; + }; + + // Helper to calculate F_REF according to Table 5.4.2.1-1 + nr_raster_params get_raster_params(uint32_t nr_arfcn); + + static const uint32_t max_nr_arfcn = 3279165; + static constexpr std::array nr_fr_params = {{ + // clang-format off + // Frequency range 0 - 3000 MHz + {5, 0.0, 0, 0, 599999}, + // Frequency range 3000 - 24250 MHz + {15, 3000.0, 600000, 600000, 2016666}, + // Frequency range 24250 - 100000 MHz + {60, 24250.08, 2016667, 2016667, max_nr_arfcn} + // clang-format on + }}; + + // Elements of Table 5.4.2.3-1 in TS 38.104 + struct nr_band { + uint8_t band; + delta_f_raster_t delta_f_raster; + uint32_t ul_nref_first; + uint32_t ul_nref_step; + uint32_t ul_nref_last; + uint32_t dl_nref_first; + uint32_t dl_nref_step; + uint32_t dl_nref_last; + }; + + // List of NR bands for FR1 (Table 5.4.2.3-1) + // bands with more than one raster offset have multiple entries + // TODO: add remaining bands + static const uint32_t nof_nr_bands_fr1 = 7; + static constexpr std::array nr_band_table_fr1 = {{ + // clang-format off + {74, KHZ_100, 285400, 20, 294000, 295000, 20, 303600}, + // n75+n76 missing + {77, KHZ_15, 620000, 1, 680000, 620000, 1, 680000}, + {77, KHZ_30, 620000, 2, 680000, 620000, 2, 680000}, + + {78, KHZ_15, 620000, 1, 653333, 620000, 1, 653333}, + {78, KHZ_30, 620000, 2, 653332, 620000, 2, 653332}, + + {79, KHZ_15, 693334, 2, 733333, 693334, 2, 733333}, + {79, KHZ_30, 693334, 2, 733332, 693334, 2, 733332} + // clang-format on + }}; +}; + +} // namespace srslte + +#endif // SRSLTE_BAND_HELPER_H \ No newline at end of file diff --git a/lib/src/common/CMakeLists.txt b/lib/src/common/CMakeLists.txt index 9ae4a2f91..c6bc79b4d 100644 --- a/lib/src/common/CMakeLists.txt +++ b/lib/src/common/CMakeLists.txt @@ -10,6 +10,7 @@ set(SOURCES arch_select.cc enb_events.cc backtrace.c + band_helper.cc buffer_pool.cc crash_handler.c gen_mch_tables.c diff --git a/lib/src/common/band_helper.cc b/lib/src/common/band_helper.cc new file mode 100644 index 000000000..3e04fbb0b --- /dev/null +++ b/lib/src/common/band_helper.cc @@ -0,0 +1,64 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2020 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 "srslte/common/band_helper.h" +#include + +namespace srslte { + +// definition of static members +constexpr std::array + srslte_band_helper::nr_band_table_fr1; +constexpr std::array srslte_band_helper::nr_fr_params; + +// Formula in 5.4.2.1 +double srslte_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 srslte_band_helper::get_bands_nr(uint32_t nr_arfcn, + srslte_band_helper::delta_f_raster_t delta_f_raster) +{ + std::vector 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; +} + +srslte_band_helper::nr_raster_params srslte_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 srslte \ No newline at end of file diff --git a/lib/src/common/test/CMakeLists.txt b/lib/src/common/test/CMakeLists.txt index f075ed644..cec9f2306 100644 --- a/lib/src/common/test/CMakeLists.txt +++ b/lib/src/common/test/CMakeLists.txt @@ -16,3 +16,6 @@ target_link_libraries(thread_test srslte_common) add_test(thread_test thread_test) +add_executable(band_helper_test band_helper_test.cc) +target_link_libraries(band_helper_test srslte_common) +add_test(band_helper_test band_helper_test) \ No newline at end of file diff --git a/lib/src/common/test/band_helper_test.cc b/lib/src/common/test/band_helper_test.cc new file mode 100644 index 000000000..fb8064479 --- /dev/null +++ b/lib/src/common/test/band_helper_test.cc @@ -0,0 +1,48 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2020 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 "srslte/common/band_helper.h" +#include "srslte/common/test_common.h" + +int bands_test_nr() +{ + srslte::srslte_band_helper bands; + + TESTASSERT(bands.nr_arfcn_to_freq(632628) == 3489.42e6); + + const uint32_t max_valid_nr_arfcn = 3279165; + + // Max ARFCN is 3279165 at almost 10 GHz + TESTASSERT(bands.nr_arfcn_to_freq(max_valid_nr_arfcn) == 99.99996e9); + + // Invalid ARFCN + TESTASSERT(bands.nr_arfcn_to_freq(max_valid_nr_arfcn + 1) == 0.0); + + std::vector band_vector = bands.get_bands_nr(632628); + TESTASSERT(band_vector.size() == 2); + TESTASSERT(band_vector.at(0) == 77); + TESTASSERT(band_vector.at(1) == 78); + + // Invalid configs + // For 30 kHz, 620001 is not a valid ARFCN, only every 2nd + band_vector = bands.get_bands_nr(620001, srslte::srslte_band_helper::KHZ_30); + TESTASSERT(band_vector.empty()); + + return SRSLTE_SUCCESS; +} + +int main(int argc, char** argv) +{ + TESTASSERT(bands_test_nr() == SRSLTE_SUCCESS); + + return SRSLTE_SUCCESS; +} \ No newline at end of file