diff --git a/lib/include/srslte/common/bounded_bitset.h b/lib/include/srslte/common/bounded_bitset.h index 66d1065d0..d571e6ea9 100644 --- a/lib/include/srslte/common/bounded_bitset.h +++ b/lib/include/srslte/common/bounded_bitset.h @@ -25,10 +25,15 @@ #include #include -#define CEILFRAC(x, y) ((((x)-1) / (y)) + 1) +#define CEILFRAC(x, y) (((x) > 0) ? ((((x)-1) / (y)) + 1) : 0) namespace srslte { +constexpr uint32_t ceil_div(uint32_t x, uint32_t y) +{ + return (x > 0) ? (x - 1) / y + 1 : 0; +} + template class bounded_bitset { @@ -49,10 +54,12 @@ public: if (new_size > max_size()) { printf("ERROR: bitset resize out of bounds: %lu>=%lu\n", max_size(), new_size); return; + } else if (new_size == cur_size) { + return; } cur_size = new_size; sanitize_(); - for (size_t i = nof_words_(); i < sizeof(buffer); ++i) { + for (size_t i = nof_words_(); i < max_nof_words_(); ++i) { get_word_(i) = static_cast(0); } } @@ -63,8 +70,7 @@ public: printf("ERROR: bitset out of bounds: %lu>=%lu\n", pos, size()); return; } - pos = reversed ? size() - 1 - pos : pos; - get_word_(pos) |= maskbit(pos); + set_(pos); } void reset(size_t pos) noexcept @@ -73,8 +79,7 @@ public: printf("ERROR: bitset out of bounds: %lu>=%lu\n", pos, size()); return; } - pos = reversed ? size() - 1 - pos : pos; - get_word_(pos) &= ~(maskbit(pos)); + reset_(pos); } void reset() noexcept @@ -111,11 +116,11 @@ public: // NOTE: can be optimized if (value) { for (size_t i = startpos; i < endpos; ++i) { - set(i); + set_(i); } } else { for (size_t i = startpos; i < endpos; ++i) { - reset(i); + reset_(i); } } return *this; @@ -176,7 +181,7 @@ public: return result; } - bool operator==(bounded_bitset& other) const noexcept + bool operator==(const bounded_bitset& other) const noexcept { if (size() != other.size()) { return false; @@ -188,7 +193,7 @@ public: return true; } - bool operator!=(bounded_bitset& other) const noexcept { return not(*this == other); } + bool operator!=(const bounded_bitset& other) const noexcept { return not(*this == other); } bounded_bitset& operator|=(const bounded_bitset& other) noexcept { @@ -253,7 +258,7 @@ public: std::string to_hex() const noexcept { size_t nof_digits = (size() - 1) / 4 + 1; - char cstr[CEILFRAC(CEILFRAC(N, bits_per_word) * bits_per_word, 4) + 1]; + char cstr[ceil_div(ceil_div(N, bits_per_word) * bits_per_word, 4) + 1]; size_t count = 0; for (int i = nof_words_() - 1; i >= 0; --i) { @@ -271,8 +276,9 @@ private: void sanitize_() { - if (N % bits_per_word != 0) { - buffer[nof_words_() - 1] &= ~((~static_cast(0)) << (size() % bits_per_word)); + size_t n = size() % bits_per_word; + if (n != 0) { + buffer[nof_words_() - 1] &= ~((~static_cast(0)) << n); } } @@ -282,6 +288,18 @@ private: return ((get_word_(pos) & maskbit(pos)) != static_cast(0)); } + void set_(size_t pos) noexcept + { + pos = reversed ? size() - 1 - pos : pos; + get_word_(pos) |= maskbit(pos); + } + + void reset_(size_t pos) noexcept + { + pos = reversed ? size() - 1 - pos : pos; + get_word_(pos) &= ~(maskbit(pos)); + } + size_t nof_words_() const noexcept { return size() > 0 ? (size() - 1) / bits_per_word + 1 : 0; } word_t& get_word_(size_t pos) noexcept { return buffer[pos / bits_per_word]; } @@ -291,6 +309,8 @@ private: size_t word_idx_(size_t pos) const { return pos / bits_per_word; } static word_t maskbit(size_t pos) { return (static_cast(1)) << (pos % bits_per_word); } + + static size_t max_nof_words_() { return (N - 1) / bits_per_word + 1; } }; template @@ -315,7 +335,6 @@ template inline bounded_bitset fliplr(const bounded_bitset& other) noexcept { bounded_bitset ret(other.size()); - ret.reset(); for (uint32_t i = 0; i < ret.size(); ++i) { if (other.test(i)) { ret.set(ret.size() - 1 - i); diff --git a/lib/test/asn1/srslte_asn1_rrc_connection_reconf_test.cc b/lib/test/asn1/srslte_asn1_rrc_connection_reconf_test.cc deleted file mode 100644 index 93a157a29..000000000 --- a/lib/test/asn1/srslte_asn1_rrc_connection_reconf_test.cc +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2013-2019 Software Radio Systems Limited - * - * This file is part of srsLTE. - * - * srsLTE is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * srsLTE is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * A copy of the GNU Affero General Public License can be found in - * the LICENSE file in the top-level directory of this distribution - * and at http://www.gnu.org/licenses/. - * - */ - -#include - -#include "srslte/asn1/liblte_rrc.h" -#include "srslte/common/log_filter.h" -#include "srslte/srslte.h" - -#define TESTASSERT(cond) \ - { \ - if (!(cond)) { \ - std::cout << "[" << __FUNCTION__ << "][Line " << __LINE__ << "]: FAIL at " << (#cond) << std::endl; \ - return -1; \ - } \ - } - -int rrc_connection_reconf_test() -{ - srslte::log_filter log1("RRC"); - log1.set_level(srslte::LOG_LEVEL_DEBUG); - log1.set_hex_limit(128); - - LIBLTE_BIT_MSG_STRUCT bit_buf; - LIBLTE_BIT_MSG_STRUCT bit_buf2; - LIBLTE_BYTE_MSG_STRUCT byte_buf; - LIBLTE_RRC_DL_DCCH_MSG_STRUCT dl_dcch_msg; - - uint8_t rrc_message[] = {0x20, 0x02, 0x01, 0x80, 0x01, 0x10, 0x10, 0x08, 0x21, 0x60, 0xCA, 0x32, 0x00, 0x06, 0x60}; - uint32_t rrc_message_len = sizeof(rrc_message); - // 20020180011010082160CA32000660 - - bzero(&dl_dcch_msg, sizeof(dl_dcch_msg)); - srslte_bit_unpack_vector(rrc_message, bit_buf.msg, rrc_message_len * 8); - bit_buf.N_bits = rrc_message_len * 8; - liblte_rrc_unpack_dl_dcch_msg((LIBLTE_BIT_MSG_STRUCT*)&bit_buf, &dl_dcch_msg); - TESTASSERT(dl_dcch_msg.msg_type == LIBLTE_RRC_DL_DCCH_MSG_TYPE_RRC_CON_RECONFIG); - - LIBLTE_RRC_CONNECTION_RECONFIGURATION_STRUCT* reconf = &dl_dcch_msg.msg.rrc_con_reconfig; - TESTASSERT(reconf->rrc_transaction_id == 0); - TESTASSERT(not reconf->meas_cnfg_present); - TESTASSERT(not reconf->mob_ctrl_info_present); - TESTASSERT(reconf->N_ded_info_nas == 0); - TESTASSERT(reconf->rr_cnfg_ded_present); - TESTASSERT(not reconf->sec_cnfg_ho_present); - - // RR Config - TESTASSERT(reconf->rr_cnfg_ded.phy_cnfg_ded_present); - TESTASSERT(reconf->rr_cnfg_ded.drb_to_add_mod_list_size == 0); - - TESTASSERT(reconf->rr_cnfg_ded.phy_cnfg_ded.ext); - TESTASSERT(reconf->rr_cnfg_ded.phy_cnfg_ded.ext_groups.N_groups == 5); - TESTASSERT(reconf->rr_cnfg_ded.phy_cnfg_ded.ext_groups.groups_present[1]); - TESTASSERT(reconf->rr_cnfg_ded.phy_cnfg_ded.ext_groups.group1.pucch_config_dedicated_v1020_present); - LIBLTE_RRC_PUCCH_CONFIG_DEDICATED_v1020* v1020 = - &reconf->rr_cnfg_ded.phy_cnfg_ded.ext_groups.group1.pucch_config_dedicated_v1020; - - TESTASSERT(v1020->pucch_format_r10_present); - TESTASSERT(v1020->pucch_format_r10_choice == LIBLTE_RRC_PUCCH_CONFIG_DEDICATED_v1020::format3_r10); - TESTASSERT(v1020->pucch_format_r10.format3_r10.N_n3_pucch_an_list_r13 == 4); - TESTASSERT(v1020->pucch_format_r10.format3_r10.n3_pucch_an_list_r13[0] == 25); - TESTASSERT(v1020->pucch_format_r10.format3_r10.n3_pucch_an_list_r13[1] == 281); - TESTASSERT(v1020->pucch_format_r10.format3_r10.n3_pucch_an_list_r13[2] == 0); - TESTASSERT(v1020->pucch_format_r10.format3_r10.n3_pucch_an_list_r13[3] == 51); - - return 0; -} - -int main(int argc, char** argv) -{ - TESTASSERT(rrc_connection_reconf_test() == 0); -} \ No newline at end of file diff --git a/srsenb/src/enb.cc b/srsenb/src/enb.cc index 8f64d3082..238654a94 100644 --- a/srsenb/src/enb.cc +++ b/srsenb/src/enb.cc @@ -171,8 +171,10 @@ bool enb::init(all_args_t *args_) } else { // 6 PRB case if (prach_freq_offset + 6 > cell_cfg.nof_prb) { fprintf(stderr, - "Invalid PRACH configuration: frequency interval=(%d, %d) does not fit into the eNB PRBs=(0,%d)\n", - prach_freq_offset, prach_freq_offset + 6, cell_cfg.nof_prb); + "Warning: Invalid PRACH configuration - prach=(%d, %d) does not fit into the eNB PRBs=(0,%d)\n", + prach_freq_offset, + prach_freq_offset + 6, + cell_cfg.nof_prb); return false; } } diff --git a/srsenb/src/enb_cfg_parser.cc b/srsenb/src/enb_cfg_parser.cc index d7da60456..4bb995cfb 100644 --- a/srsenb/src/enb_cfg_parser.cc +++ b/srsenb/src/enb_cfg_parser.cc @@ -702,6 +702,18 @@ int enb::parse_sibs(all_args_t* args, rrc_cfg_t* rrc_cfg, phy_cfg_t* phy_config_ } } + // Resolve invalid prach offset + uint32_t prach_freq_offset = sib2->rr_cfg_common.prach_cfg.prach_cfg_info.prach_freq_offset; + if (prach_freq_offset + 6 > rrc_cfg->cell.nof_prb) { + fprintf(stderr, + "Warning: Invalid PRACH configuration - prach=(%d, %d) does not fit into the eNB PRBs=(0,%d)\n", + prach_freq_offset, + prach_freq_offset + 6, + rrc_cfg->cell.nof_prb); + fprintf(stderr, "Warning: Going to use default prach offset. Change sib.conf to suppress with warning.\n"); + sib2->rr_cfg_common.prach_cfg.prach_cfg_info.prach_freq_offset = 0; + } + // Copy PHY common configuration bzero(&phy_config_common->cell, sizeof(phy_config_common->cell)); phy_config_common->prach_cnfg = sib2->rr_cfg_common.prach_cfg; diff --git a/srsenb/src/mac/scheduler.cc b/srsenb/src/mac/scheduler.cc index bf2fa342e..ffe748043 100644 --- a/srsenb/src/mac/scheduler.cc +++ b/srsenb/src/mac/scheduler.cc @@ -125,9 +125,9 @@ int sched::cell_cfg(sched_interface::cell_cfg_t* cell_cfg) } P = srslte_ra_type0_P(cfg.cell.nof_prb); - si_n_rbg = ceilf((float) 4/P); - rar_n_rbg = ceilf((float) 3/P); - nof_rbg = (uint32_t) ceil((float) cfg.cell.nof_prb/P); + si_n_rbg = srslte::ceil_div(4, P); + rar_n_rbg = srslte::ceil_div(3, P); + nof_rbg = srslte::ceil_div(cfg.cell.nof_prb, P); sched_vars.init(this); // Compute Common locations for DCI for each CFI @@ -144,17 +144,6 @@ int sched::cell_cfg(sched_interface::cell_cfg_t* cell_cfg) } configured = true; - // PRACH has to fit within the PUSCH space - bool invalid_prach = cfg.cell.nof_prb == 6 and (cfg.prach_freq_offset + 6 > cfg.cell.nof_prb); - invalid_prach |= cfg.cell.nof_prb > 6 and ((cfg.prach_freq_offset + 6) > (cfg.cell.nof_prb - cfg.nrb_pucch) or - (int) cfg.prach_freq_offset < cfg.nrb_pucch); - if (invalid_prach) { - log_h->error("Invalid PRACH configuration: frequency offset=%d outside bandwidth limits\n", cfg.prach_freq_offset); - log_h->console("Invalid PRACH configuration: frequency offset=%d outside bandwidth limits\n", - cfg.prach_freq_offset); - return -1; - } - if (common_locations[sched_cfg.nof_ctrl_symbols - 1].nof_loc[2] == 0) { Error("SCHED: Current cfi=%d is not valid for broadcast (check scheduler.nof_ctrl_symbols in conf file).\n", sched_cfg.nof_ctrl_symbols);