mirror of https://github.com/PentHertz/srsLTE.git
automatically resolve invalid prach_offset for prb6
This commit is contained in:
parent
47acbc1e08
commit
1674c8939f
|
@ -25,10 +25,15 @@
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#define CEILFRAC(x, y) ((((x)-1) / (y)) + 1)
|
#define CEILFRAC(x, y) (((x) > 0) ? ((((x)-1) / (y)) + 1) : 0)
|
||||||
|
|
||||||
namespace srslte {
|
namespace srslte {
|
||||||
|
|
||||||
|
constexpr uint32_t ceil_div(uint32_t x, uint32_t y)
|
||||||
|
{
|
||||||
|
return (x > 0) ? (x - 1) / y + 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
template <size_t N, bool reversed = false>
|
template <size_t N, bool reversed = false>
|
||||||
class bounded_bitset
|
class bounded_bitset
|
||||||
{
|
{
|
||||||
|
@ -49,10 +54,12 @@ public:
|
||||||
if (new_size > max_size()) {
|
if (new_size > max_size()) {
|
||||||
printf("ERROR: bitset resize out of bounds: %lu>=%lu\n", max_size(), new_size);
|
printf("ERROR: bitset resize out of bounds: %lu>=%lu\n", max_size(), new_size);
|
||||||
return;
|
return;
|
||||||
|
} else if (new_size == cur_size) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
cur_size = new_size;
|
cur_size = new_size;
|
||||||
sanitize_();
|
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<word_t>(0);
|
get_word_(i) = static_cast<word_t>(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -63,8 +70,7 @@ public:
|
||||||
printf("ERROR: bitset out of bounds: %lu>=%lu\n", pos, size());
|
printf("ERROR: bitset out of bounds: %lu>=%lu\n", pos, size());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
pos = reversed ? size() - 1 - pos : pos;
|
set_(pos);
|
||||||
get_word_(pos) |= maskbit(pos);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset(size_t pos) noexcept
|
void reset(size_t pos) noexcept
|
||||||
|
@ -73,8 +79,7 @@ public:
|
||||||
printf("ERROR: bitset out of bounds: %lu>=%lu\n", pos, size());
|
printf("ERROR: bitset out of bounds: %lu>=%lu\n", pos, size());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
pos = reversed ? size() - 1 - pos : pos;
|
reset_(pos);
|
||||||
get_word_(pos) &= ~(maskbit(pos));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset() noexcept
|
void reset() noexcept
|
||||||
|
@ -111,11 +116,11 @@ public:
|
||||||
// NOTE: can be optimized
|
// NOTE: can be optimized
|
||||||
if (value) {
|
if (value) {
|
||||||
for (size_t i = startpos; i < endpos; ++i) {
|
for (size_t i = startpos; i < endpos; ++i) {
|
||||||
set(i);
|
set_(i);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (size_t i = startpos; i < endpos; ++i) {
|
for (size_t i = startpos; i < endpos; ++i) {
|
||||||
reset(i);
|
reset_(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
|
@ -176,7 +181,7 @@ public:
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(bounded_bitset<N, reversed>& other) const noexcept
|
bool operator==(const bounded_bitset<N, reversed>& other) const noexcept
|
||||||
{
|
{
|
||||||
if (size() != other.size()) {
|
if (size() != other.size()) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -188,7 +193,7 @@ public:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator!=(bounded_bitset<N, reversed>& other) const noexcept { return not(*this == other); }
|
bool operator!=(const bounded_bitset<N, reversed>& other) const noexcept { return not(*this == other); }
|
||||||
|
|
||||||
bounded_bitset<N, reversed>& operator|=(const bounded_bitset<N, reversed>& other) noexcept
|
bounded_bitset<N, reversed>& operator|=(const bounded_bitset<N, reversed>& other) noexcept
|
||||||
{
|
{
|
||||||
|
@ -253,7 +258,7 @@ public:
|
||||||
std::string to_hex() const noexcept
|
std::string to_hex() const noexcept
|
||||||
{
|
{
|
||||||
size_t nof_digits = (size() - 1) / 4 + 1;
|
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;
|
size_t count = 0;
|
||||||
|
|
||||||
for (int i = nof_words_() - 1; i >= 0; --i) {
|
for (int i = nof_words_() - 1; i >= 0; --i) {
|
||||||
|
@ -271,8 +276,9 @@ private:
|
||||||
|
|
||||||
void sanitize_()
|
void sanitize_()
|
||||||
{
|
{
|
||||||
if (N % bits_per_word != 0) {
|
size_t n = size() % bits_per_word;
|
||||||
buffer[nof_words_() - 1] &= ~((~static_cast<word_t>(0)) << (size() % bits_per_word));
|
if (n != 0) {
|
||||||
|
buffer[nof_words_() - 1] &= ~((~static_cast<word_t>(0)) << n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -282,6 +288,18 @@ private:
|
||||||
return ((get_word_(pos) & maskbit(pos)) != static_cast<word_t>(0));
|
return ((get_word_(pos) & maskbit(pos)) != static_cast<word_t>(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; }
|
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]; }
|
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; }
|
size_t word_idx_(size_t pos) const { return pos / bits_per_word; }
|
||||||
|
|
||||||
static word_t maskbit(size_t pos) { return (static_cast<word_t>(1)) << (pos % bits_per_word); }
|
static word_t maskbit(size_t pos) { return (static_cast<word_t>(1)) << (pos % bits_per_word); }
|
||||||
|
|
||||||
|
static size_t max_nof_words_() { return (N - 1) / bits_per_word + 1; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <size_t N, bool reversed>
|
template <size_t N, bool reversed>
|
||||||
|
@ -315,7 +335,6 @@ template <size_t N, bool reversed>
|
||||||
inline bounded_bitset<N, reversed> fliplr(const bounded_bitset<N, reversed>& other) noexcept
|
inline bounded_bitset<N, reversed> fliplr(const bounded_bitset<N, reversed>& other) noexcept
|
||||||
{
|
{
|
||||||
bounded_bitset<N, reversed> ret(other.size());
|
bounded_bitset<N, reversed> ret(other.size());
|
||||||
ret.reset();
|
|
||||||
for (uint32_t i = 0; i < ret.size(); ++i) {
|
for (uint32_t i = 0; i < ret.size(); ++i) {
|
||||||
if (other.test(i)) {
|
if (other.test(i)) {
|
||||||
ret.set(ret.size() - 1 - i);
|
ret.set(ret.size() - 1 - i);
|
||||||
|
|
|
@ -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 <iostream>
|
|
||||||
|
|
||||||
#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);
|
|
||||||
}
|
|
|
@ -171,8 +171,10 @@ bool enb::init(all_args_t *args_)
|
||||||
} else { // 6 PRB case
|
} else { // 6 PRB case
|
||||||
if (prach_freq_offset + 6 > cell_cfg.nof_prb) {
|
if (prach_freq_offset + 6 > cell_cfg.nof_prb) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Invalid PRACH configuration: frequency interval=(%d, %d) does not fit into the eNB PRBs=(0,%d)\n",
|
"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);
|
prach_freq_offset,
|
||||||
|
prach_freq_offset + 6,
|
||||||
|
cell_cfg.nof_prb);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
// Copy PHY common configuration
|
||||||
bzero(&phy_config_common->cell, sizeof(phy_config_common->cell));
|
bzero(&phy_config_common->cell, sizeof(phy_config_common->cell));
|
||||||
phy_config_common->prach_cnfg = sib2->rr_cfg_common.prach_cfg;
|
phy_config_common->prach_cnfg = sib2->rr_cfg_common.prach_cfg;
|
||||||
|
|
|
@ -125,9 +125,9 @@ int sched::cell_cfg(sched_interface::cell_cfg_t* cell_cfg)
|
||||||
}
|
}
|
||||||
|
|
||||||
P = srslte_ra_type0_P(cfg.cell.nof_prb);
|
P = srslte_ra_type0_P(cfg.cell.nof_prb);
|
||||||
si_n_rbg = ceilf((float) 4/P);
|
si_n_rbg = srslte::ceil_div(4, P);
|
||||||
rar_n_rbg = ceilf((float) 3/P);
|
rar_n_rbg = srslte::ceil_div(3, P);
|
||||||
nof_rbg = (uint32_t) ceil((float) cfg.cell.nof_prb/P);
|
nof_rbg = srslte::ceil_div(cfg.cell.nof_prb, P);
|
||||||
sched_vars.init(this);
|
sched_vars.init(this);
|
||||||
|
|
||||||
// Compute Common locations for DCI for each CFI
|
// 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;
|
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) {
|
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",
|
Error("SCHED: Current cfi=%d is not valid for broadcast (check scheduler.nof_ctrl_symbols in conf file).\n",
|
||||||
sched_cfg.nof_ctrl_symbols);
|
sched_cfg.nof_ctrl_symbols);
|
||||||
|
|
Loading…
Reference in New Issue