mirror of https://github.com/PentHertz/srsLTE.git
Refactor build of RLC NR config
This commit is contained in:
parent
d1d8500ce5
commit
6d5391756c
|
@ -120,7 +120,7 @@ bool make_mac_dl_harq_cfg_nr_t(const asn1::rrc_nr::pdsch_ser
|
|||
/***************************
|
||||
* RLC Config
|
||||
**************************/
|
||||
rlc_config_t make_rlc_config_t(const asn1::rrc_nr::rlc_cfg_c& asn1_type);
|
||||
int make_rlc_config_t(const asn1::rrc_nr::rlc_cfg_c& asn1_type, rlc_config_t* rlc_config_out);
|
||||
|
||||
/***************************
|
||||
* PDCP Config
|
||||
|
|
|
@ -110,8 +110,6 @@ struct rlc_um_nr_config_t {
|
|||
***************************************************************************/
|
||||
|
||||
rlc_um_nr_sn_size_t sn_field_length; // Number of bits used for sequence number
|
||||
uint32_t UM_Window_Size;
|
||||
uint32_t mod; // Rx/Tx counter modulus
|
||||
int32_t t_reassembly_ms; // Timer used by rx to detect PDU loss (ms)
|
||||
};
|
||||
|
||||
|
@ -206,12 +204,8 @@ public:
|
|||
cnfg.rlc_mode = rlc_mode_t::um;
|
||||
if (sn_size == 6) {
|
||||
cnfg.um_nr.sn_field_length = rlc_um_nr_sn_size_t::size6bits;
|
||||
cnfg.um_nr.UM_Window_Size = 32;
|
||||
cnfg.um_nr.mod = 64;
|
||||
} else if (sn_size == 12) {
|
||||
cnfg.um_nr.sn_field_length = rlc_um_nr_sn_size_t::size12bits;
|
||||
cnfg.um_nr.UM_Window_Size = 2048;
|
||||
cnfg.um_nr.mod = 4096;
|
||||
} else {
|
||||
return {};
|
||||
}
|
||||
|
|
|
@ -62,6 +62,9 @@ private:
|
|||
|
||||
uint32_t next_so = 0; // The segment offset for the next generated PDU
|
||||
|
||||
uint32_t UM_Window_Size;
|
||||
uint32_t mod; // Rx counter modulus
|
||||
|
||||
static constexpr uint32_t head_len_full = 1; // full SDU header size is always
|
||||
uint32_t head_len_first = 0, head_len_segment = 0; // are computed during configure based on SN length
|
||||
|
||||
|
@ -96,6 +99,9 @@ private:
|
|||
uint32_t RX_Next_Highest = 0; // the SN following the SN of the UMD PDU with the highest SN among
|
||||
// received UMD PDUs. It serves as the higher edge of the reassembly window.
|
||||
|
||||
uint32_t UM_Window_Size;
|
||||
uint32_t mod; // Rx counter modulus
|
||||
|
||||
// Rx window
|
||||
typedef struct {
|
||||
std::map<uint32_t, rlc_umd_pdu_nr_t> segments; // Map of segments with SO as key
|
||||
|
|
|
@ -100,26 +100,48 @@ rach_nr_cfg_t make_mac_rach_cfg(const rach_cfg_common_s& asn1_type)
|
|||
return rach_nr_cfg;
|
||||
};
|
||||
|
||||
rlc_config_t make_rlc_config_t(const rlc_cfg_c& asn1_type)
|
||||
int make_rlc_config_t(const rlc_cfg_c& asn1_type, rlc_config_t* cfg_out)
|
||||
{
|
||||
rlc_config_t rlc_cfg = rlc_config_t::default_rlc_um_nr_config();
|
||||
rlc_cfg.rat = srsran_rat_t::nr;
|
||||
switch (asn1_type.type().value) {
|
||||
case rlc_cfg_c::types_opts::am:
|
||||
break;
|
||||
asn1::log_warning("NR RLC type %s is not supported", asn1_type.type().to_string());
|
||||
return SRSRAN_ERROR;
|
||||
case rlc_cfg_c::types_opts::um_bi_dir:
|
||||
case rlc_cfg_c::types_opts::um_uni_dir_dl:
|
||||
case rlc_cfg_c::types_opts::um_uni_dir_ul:
|
||||
rlc_cfg.rlc_mode = rlc_mode_t::um;
|
||||
rlc_cfg.um_nr.t_reassembly_ms = asn1_type.um_bi_dir().dl_um_rlc.t_reassembly.value.to_number();
|
||||
rlc_cfg.um_nr.sn_field_length = (rlc_um_nr_sn_size_t)asn1_type.um_bi_dir().dl_um_rlc.sn_field_len.value;
|
||||
rlc_cfg.um_nr.mod = (rlc_cfg.um_nr.sn_field_length == rlc_um_nr_sn_size_t::size6bits) ? 64 : 4096;
|
||||
rlc_cfg.um_nr.UM_Window_Size = (rlc_cfg.um_nr.sn_field_length == rlc_um_nr_sn_size_t::size6bits) ? 32 : 2048;
|
||||
rlc_cfg.um_nr.t_reassembly_ms = asn1_type.um_bi_dir().dl_um_rlc.t_reassembly.to_number();
|
||||
|
||||
if (asn1_type.um_bi_dir().dl_um_rlc.sn_field_len_present &&
|
||||
asn1_type.um_bi_dir().ul_um_rlc.sn_field_len_present &&
|
||||
asn1_type.um_bi_dir().dl_um_rlc.sn_field_len != asn1_type.um_bi_dir().ul_um_rlc.sn_field_len) {
|
||||
asn1::log_warning("NR RLC sequence number length is not the same in uplink and downlink");
|
||||
return SRSRAN_ERROR;
|
||||
}
|
||||
|
||||
switch (asn1_type.um_bi_dir().dl_um_rlc.sn_field_len.value) {
|
||||
case asn1::rrc_nr::sn_field_len_um_opts::options::size6:
|
||||
rlc_cfg.um_nr.sn_field_length = rlc_um_nr_sn_size_t::size6bits;
|
||||
break;
|
||||
case asn1::rrc_nr::sn_field_len_um_opts::options::size12:
|
||||
rlc_cfg.um_nr.sn_field_length = rlc_um_nr_sn_size_t::size12bits;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case rlc_cfg_c::types_opts::um_uni_dir_dl:
|
||||
asn1::log_warning("NR RLC type %s is not supported", asn1_type.type().to_string());
|
||||
return SRSRAN_ERROR;
|
||||
case rlc_cfg_c::types_opts::um_uni_dir_ul:
|
||||
asn1::log_warning("NR RLC type %s is not supported", asn1_type.type().to_string());
|
||||
return SRSRAN_ERROR;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return rlc_cfg;
|
||||
|
||||
*cfg_out = rlc_cfg;
|
||||
return SRSRAN_SUCCESS;
|
||||
}
|
||||
|
||||
srsran::pdcp_config_t make_drb_pdcp_config_t(const uint8_t bearer_id, bool is_ue, const pdcp_cfg_s& pdcp_cfg)
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
#include "srsran/interfaces/ue_pdcp_interfaces.h"
|
||||
#include <sstream>
|
||||
|
||||
#define RX_MOD_NR_BASE(x) (((x)-RX_Next_Highest - cfg.um_nr.UM_Window_Size) % cfg.um_nr.mod)
|
||||
#define RX_MOD_NR_BASE(x) (((x)-RX_Next_Highest - UM_Window_Size) % mod)
|
||||
|
||||
namespace srsran {
|
||||
|
||||
|
@ -94,10 +94,8 @@ bool rlc_um_nr::rlc_um_nr_tx::configure(const rlc_config_t& cnfg_, std::string r
|
|||
{
|
||||
cfg = cnfg_;
|
||||
|
||||
if (cfg.um_nr.mod == 0) {
|
||||
logger.error("Error configuring %s RLC UM: tx_mod==0", rb_name.c_str());
|
||||
return false;
|
||||
}
|
||||
mod = (cfg.um_nr.sn_field_length == rlc_um_nr_sn_size_t::size6bits) ? 64 : 4096;
|
||||
UM_Window_Size = (cfg.um_nr.sn_field_length == rlc_um_nr_sn_size_t::size6bits) ? 32 : 2048;
|
||||
|
||||
// calculate header sizes for configured SN length
|
||||
rlc_um_nr_pdu_header_t header = {};
|
||||
|
@ -188,7 +186,7 @@ uint32_t rlc_um_nr::rlc_um_nr_tx::build_data_pdu(unique_byte_buffer_t pdu, uint8
|
|||
|
||||
// Update SN if needed
|
||||
if (header.si == rlc_nr_si_field_t::last_segment) {
|
||||
TX_Next = (TX_Next + 1) % cfg.um_nr.mod;
|
||||
TX_Next = (TX_Next + 1) % mod;
|
||||
next_so = 0;
|
||||
}
|
||||
|
||||
|
@ -229,10 +227,8 @@ rlc_um_nr::rlc_um_nr_rx::rlc_um_nr_rx(rlc_um_base* parent_) :
|
|||
|
||||
bool rlc_um_nr::rlc_um_nr_rx::configure(const rlc_config_t& cnfg_, std::string rb_name_)
|
||||
{
|
||||
if (cfg.um_nr.mod == 0) {
|
||||
logger.error("Error configuring %s RLC UM: rx_mod==0", rb_name.c_str());
|
||||
return false;
|
||||
}
|
||||
mod = (cfg.um_nr.sn_field_length == rlc_um_nr_sn_size_t::size6bits) ? 64 : 4096;
|
||||
UM_Window_Size = (cfg.um_nr.sn_field_length == rlc_um_nr_sn_size_t::size6bits) ? 32 : 2048;
|
||||
|
||||
// check timer
|
||||
if (not reassembly_timer.is_valid()) {
|
||||
|
@ -297,7 +293,7 @@ void rlc_um_nr::rlc_um_nr_rx::timer_expired(uint32_t timeout_id)
|
|||
// update RX_Next_Reassembly to the next SN that has not been reassembled yet
|
||||
RX_Next_Reassembly = RX_Timer_Trigger;
|
||||
while (RX_MOD_NR_BASE(RX_Next_Reassembly) < RX_MOD_NR_BASE(RX_Next_Highest)) {
|
||||
RX_Next_Reassembly = (RX_Next_Reassembly + 1) % cfg.um_nr.mod;
|
||||
RX_Next_Reassembly = (RX_Next_Reassembly + 1) % mod;
|
||||
debug_state();
|
||||
}
|
||||
|
||||
|
@ -325,14 +321,14 @@ void rlc_um_nr::rlc_um_nr_rx::timer_expired(uint32_t timeout_id)
|
|||
// Sec 5.2.2.2.1
|
||||
bool rlc_um_nr::rlc_um_nr_rx::sn_in_reassembly_window(const uint32_t sn)
|
||||
{
|
||||
return (RX_MOD_NR_BASE(RX_Next_Highest - cfg.um_nr.UM_Window_Size) <= RX_MOD_NR_BASE(sn) &&
|
||||
return (RX_MOD_NR_BASE(RX_Next_Highest - UM_Window_Size) <= RX_MOD_NR_BASE(sn) &&
|
||||
RX_MOD_NR_BASE(sn) < RX_MOD_NR_BASE(RX_Next_Highest));
|
||||
}
|
||||
|
||||
// Sec 5.2.2.2.2
|
||||
bool rlc_um_nr::rlc_um_nr_rx::sn_invalid_for_rx_buffer(const uint32_t sn)
|
||||
{
|
||||
return (RX_MOD_NR_BASE(RX_Next_Highest - cfg.um_nr.UM_Window_Size) <= RX_MOD_NR_BASE(sn) &&
|
||||
return (RX_MOD_NR_BASE(RX_Next_Highest - UM_Window_Size) <= RX_MOD_NR_BASE(sn) &&
|
||||
RX_MOD_NR_BASE(sn) < RX_MOD_NR_BASE(RX_Next_Reassembly));
|
||||
}
|
||||
|
||||
|
@ -414,9 +410,9 @@ void rlc_um_nr::rlc_um_nr_rx::handle_rx_buffer_update(const uint32_t sn)
|
|||
|
||||
// find next SN in rx buffer
|
||||
if (sn == RX_Next_Reassembly) {
|
||||
RX_Next_Reassembly = ((RX_Next_Reassembly + 1) % cfg.um_nr.mod);
|
||||
RX_Next_Reassembly = ((RX_Next_Reassembly + 1) % mod);
|
||||
while (RX_MOD_NR_BASE(RX_Next_Reassembly) < RX_MOD_NR_BASE(RX_Next_Highest)) {
|
||||
RX_Next_Reassembly = (RX_Next_Reassembly + 1) % cfg.um_nr.mod;
|
||||
RX_Next_Reassembly = (RX_Next_Reassembly + 1) % mod;
|
||||
}
|
||||
logger.debug("Updating RX_Next_Reassembly=%d", RX_Next_Reassembly);
|
||||
}
|
||||
|
@ -444,7 +440,7 @@ void rlc_um_nr::rlc_um_nr_rx::handle_rx_buffer_update(const uint32_t sn)
|
|||
logger.info("%s SN: %d outside rx window [%d:%d] - discarding",
|
||||
rb_name.c_str(),
|
||||
it->first,
|
||||
RX_Next_Highest - cfg.um_nr.UM_Window_Size,
|
||||
RX_Next_Highest - UM_Window_Size,
|
||||
RX_Next_Highest);
|
||||
it = rx_window.erase(it);
|
||||
metrics.num_lost_pdus++;
|
||||
|
@ -456,7 +452,7 @@ void rlc_um_nr::rlc_um_nr_rx::handle_rx_buffer_update(const uint32_t sn)
|
|||
if (not sn_in_reassembly_window(RX_Next_Reassembly)) {
|
||||
// update RX_Next_Reassembly to first SN that has not been reassembled and delivered
|
||||
for (const auto& rx_pdu : rx_window) {
|
||||
if (rx_pdu.first >= RX_MOD_NR_BASE(RX_Next_Highest - cfg.um_nr.UM_Window_Size)) {
|
||||
if (rx_pdu.first >= RX_MOD_NR_BASE(RX_Next_Highest - UM_Window_Size)) {
|
||||
RX_Next_Reassembly = rx_pdu.first;
|
||||
logger.debug("Updating RX_Next_Reassembly=%d", RX_Next_Reassembly);
|
||||
break;
|
||||
|
|
|
@ -34,10 +34,10 @@ int test_rlc_config()
|
|||
rlc_cfg_asn1.to_json(jw);
|
||||
srslog::fetch_basic_logger("RRC").info("RLC NR Config: \n %s", jw.to_string().c_str());
|
||||
|
||||
rlc_config_t rlc_cfg = make_rlc_config_t(rlc_cfg_asn1);
|
||||
rlc_config_t rlc_cfg;
|
||||
TESTASSERT(make_rlc_config_t(rlc_cfg_asn1, &rlc_cfg) == SRSRAN_SUCCESS);
|
||||
TESTASSERT(rlc_cfg.rat == srsran_rat_t::nr);
|
||||
TESTASSERT(rlc_cfg.um_nr.sn_field_length == rlc_um_nr_sn_size_t::size12bits);
|
||||
TESTASSERT(rlc_cfg.um_nr.UM_Window_Size == 2048);
|
||||
return SRSRAN_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -461,17 +461,8 @@ bool rrc_nr::apply_rlc_add_mod(const rlc_bearer_cfg_s& rlc_bearer_cfg)
|
|||
}
|
||||
|
||||
if (rlc_bearer_cfg.rlc_cfg_present == true) {
|
||||
rlc_cfg = srsran::make_rlc_config_t(rlc_bearer_cfg.rlc_cfg);
|
||||
if (rlc_bearer_cfg.rlc_cfg.type() == asn1::rrc_nr::rlc_cfg_c::types::um_bi_dir) {
|
||||
if (rlc_bearer_cfg.rlc_cfg.um_bi_dir().dl_um_rlc.sn_field_len_present &&
|
||||
rlc_bearer_cfg.rlc_cfg.um_bi_dir().ul_um_rlc.sn_field_len_present &&
|
||||
rlc_bearer_cfg.rlc_cfg.um_bi_dir().dl_um_rlc.sn_field_len !=
|
||||
rlc_bearer_cfg.rlc_cfg.um_bi_dir().ul_um_rlc.sn_field_len) {
|
||||
logger.warning("NR RLC sequence number length is not the same in uplink and downlink");
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
logger.warning("NR RLC type is not unacknowledged mode bidirectional");
|
||||
if (srsran::make_rlc_config_t(rlc_bearer_cfg.rlc_cfg, &rlc_cfg) != SRSRAN_SUCCESS) {
|
||||
logger.warning("Failed to build RLC config");
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
|
|
Loading…
Reference in New Issue