Added RLC AM NR config structure. Added helpers to create RLC AM NR configs. Made it possible to create RLC AM NR entites in rlc.cc

master
Pedro Alvarez 3 years ago
parent 1f8d0ab557
commit 8ff545c423

@ -87,6 +87,26 @@ struct rlc_am_config_t {
int32_t t_status_prohibit; // Timer used by rx to prohibit tx of status PDU (ms)
};
struct rlc_am_nr_config_t {
/****************************************************************************
* Configurable parameters
* Ref: 3GPP TS 38.322 Section 7
***************************************************************************/
rlc_am_nr_sn_size_t tx_sn_field_length; // Number of bits used for tx (UL) sequence number
rlc_am_nr_sn_size_t rx_sn_field_length; // Number of bits used for rx (DL) sequence number
// Timers Ref: 3GPP TS 38.322 Section 7.3
int32_t t_poll_retx; // Poll retx timeout (ms)
int32_t t_reassambly; // Timer used by rx to detect PDU loss (ms)
int32_t t_status_prohibit; // Timer used by rx to prohibit tx of status PDU (ms)
// Configurable Parameters. Ref: 3GPP TS 38.322 Section 7.4
uint32_t max_retx_thresh; // Max number of retx
int32_t poll_pdu; // Insert poll bit after this many PDUs
int32_t poll_byte; // Insert poll bit after this much data (KB)
};
struct rlc_um_config_t {
/****************************************************************************
* Configurable parameters
@ -122,12 +142,13 @@ public:
srsran_rat_t rat;
rlc_mode_t rlc_mode;
rlc_am_config_t am;
rlc_am_nr_config_t am_nr;
rlc_um_config_t um;
rlc_um_nr_config_t um_nr;
uint32_t tx_queue_length;
rlc_config_t() :
rat(srsran_rat_t::lte), rlc_mode(rlc_mode_t::tm), am(), um(), um_nr(), tx_queue_length(RLC_TX_QUEUE_LEN){};
rat(srsran_rat_t::lte), rlc_mode(rlc_mode_t::tm), am(), am_nr(), um(), um_nr(), tx_queue_length(RLC_TX_QUEUE_LEN){};
// Factory for MCH
static rlc_config_t mch_config()

@ -70,7 +70,7 @@ private:
* Configurable parameters
* Ref: 3GPP TS 38.322 v10.0.0 Section 7.4
***************************************************************************/
rlc_am_config_t cfg = {};
rlc_am_nr_config_t cfg = {};
/****************************************************************************
* Tx state variables

@ -108,8 +108,25 @@ int make_rlc_config_t(const rlc_cfg_c& asn1_type, uint8_t bearer_id, rlc_config_
rlc_cfg.rat = srsran_rat_t::nr;
switch (asn1_type.type().value) {
case rlc_cfg_c::types_opts::am:
asn1::log_warning("NR RLC type %s is not supported", asn1_type.type().to_string());
return SRSRAN_ERROR;
if (asn1_type.am().dl_am_rlc.sn_field_len_present && asn1_type.am().ul_am_rlc.sn_field_len_present &&
asn1_type.am().dl_am_rlc.sn_field_len != asn1_type.am().ul_am_rlc.sn_field_len) {
asn1::log_warning("NR RLC sequence number length is not the same in uplink and downlink");
return SRSRAN_ERROR;
}
rlc_cfg.rlc_mode = rlc_mode_t::am;
switch (asn1_type.am().dl_am_rlc.sn_field_len.value) {
case asn1::rrc_nr::sn_field_len_am_opts::options::size12:
rlc_cfg.am_nr.tx_sn_field_length = rlc_am_nr_sn_size_t::size12bits;
rlc_cfg.am_nr.rx_sn_field_length = rlc_am_nr_sn_size_t::size12bits;
break;
case asn1::rrc_nr::sn_field_len_am_opts::options::size18:
rlc_cfg.am_nr.tx_sn_field_length = rlc_am_nr_sn_size_t::size18bits;
rlc_cfg.am_nr.rx_sn_field_length = rlc_am_nr_sn_size_t::size18bits;
break;
default:
break;
}
break;
case rlc_cfg_c::types_opts::um_bi_dir:
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.to_number();

@ -12,7 +12,7 @@
#include "srsran/rlc/rlc.h"
#include "srsran/common/rwlock_guard.h"
#include "srsran/rlc/rlc_am_lte.h"
#include "srsran/rlc/rlc_am_base.h"
#include "srsran/rlc/rlc_tm.h"
#include "srsran/rlc/rlc_um_lte.h"
#include "srsran/rlc/rlc_um_nr.h"
@ -398,6 +398,9 @@ int rlc::add_bearer(uint32_t lcid, const rlc_config_t& cnfg)
case srsran_rat_t::lte:
rlc_entity = std::unique_ptr<rlc_common>(new rlc_am(cnfg.rat, logger, lcid, pdcp, rrc, timers));
break;
case srsran_rat_t::nr:
rlc_entity = std::unique_ptr<rlc_common>(new rlc_am(cnfg.rat, logger, lcid, pdcp, rrc, timers));
break;
default:
logger.error("AM not supported for this RAT");
return SRSRAN_ERROR;

@ -207,7 +207,7 @@ int rlc_am::rlc_am_base_tx::write_sdu(unique_byte_buffer_t sdu)
}
if (sdu.get() == nullptr) {
srslog::fetch_basic_logger("RLC").warning("NULL SDU pointer in write_sdu()");
logger->warning("NULL SDU pointer in write_sdu()");
return SRSRAN_ERROR;
}
@ -219,16 +219,15 @@ int rlc_am::rlc_am_base_tx::write_sdu(unique_byte_buffer_t sdu)
uint32_t nof_bytes = sdu->N_bytes;
srsran::error_type<unique_byte_buffer_t> ret = tx_sdu_queue.try_write(std::move(sdu));
if (ret) {
srslog::fetch_basic_logger("RLC").info(
msg_ptr, nof_bytes, "%s Tx SDU (%d B, tx_sdu_queue_len=%d)", rb_name, nof_bytes, tx_sdu_queue.size());
logger->info(msg_ptr, nof_bytes, "%s Tx SDU (%d B, tx_sdu_queue_len=%d)", rb_name, nof_bytes, tx_sdu_queue.size());
} else {
// in case of fail, the try_write returns back the sdu
srslog::fetch_basic_logger("RLC").warning(ret.error()->msg,
ret.error()->N_bytes,
"[Dropped SDU] %s Tx SDU (%d B, tx_sdu_queue_len=%d)",
rb_name,
ret.error()->N_bytes,
tx_sdu_queue.size());
logger->warning(ret.error()->msg,
ret.error()->N_bytes,
"[Dropped SDU] %s Tx SDU (%d B, tx_sdu_queue_len=%d)",
rb_name,
ret.error()->N_bytes,
tx_sdu_queue.size());
return SRSRAN_ERROR;
}
@ -247,6 +246,7 @@ void rlc_am::rlc_am_base_tx::set_bsr_callback(bsr_callback_t callback)
*******************************************************/
void rlc_am::rlc_am_base_rx::write_pdu(uint8_t* payload, const uint32_t nof_bytes)
{
logger->info("Rx PDU -- N bytes %d", nof_bytes);
if (nof_bytes < 1) {
return;
}

@ -41,6 +41,13 @@ rlc_am_nr_tx::rlc_am_nr_tx(rlc_am* parent_) : parent(parent_), rlc_am_base_tx(&p
bool rlc_am_nr_tx::configure(const rlc_config_t& cfg_)
{
cfg = cfg_.am_nr;
if (cfg.tx_sn_field_length != rlc_am_nr_sn_size_t::size12bits) {
logger->warning("RLC AM NR only supporst 12 bit SN length.");
return false;
}
/*
if (cfg_.tx_queue_length > MAX_SDUS_PER_RLC_PDU) {
logger.error("Configuring Tx queue length of %d PDUs too big. Maximum value is %d.",
@ -49,8 +56,6 @@ bool rlc_am_nr_tx::configure(const rlc_config_t& cfg_)
return false;
}
*/
cfg = cfg_.am;
tx_enabled = true;
return true;
@ -72,13 +77,12 @@ uint32_t rlc_am_nr_tx::read_pdu(uint8_t* payload, uint32_t nof_bytes)
logger->debug("MAC opportunity - %d bytes", nof_bytes);
// logger.debug("tx_window size - %zu PDUs", tx_window.size());
// Build a PDU from SDU
unique_byte_buffer_t tx_pdu = srsran::make_byte_buffer();
// Tx STATUS if requested
if (do_status() /*&& not status_prohibit_timer.is_running()*/) {
unique_byte_buffer_t tx_pdu = srsran::make_byte_buffer();
build_status_pdu(tx_pdu.get(), nof_bytes);
memcpy(payload, tx_pdu->msg, tx_pdu->N_bytes);
logger->debug("Status PDU built - %d bytes", tx_pdu->N_bytes);
return tx_pdu->N_bytes;
}
@ -94,17 +98,23 @@ uint32_t rlc_am_nr_tx::read_pdu(uint8_t* payload, uint32_t nof_bytes)
tx_sdu = tx_sdu_queue.read();
} while (tx_sdu == nullptr && tx_sdu_queue.size() != 0);
if (tx_sdu != nullptr) {
logger->debug("Read RLC SDU - %d bytes", tx_sdu->N_bytes);
}
uint16_t hdr_size = 2;
if (tx_sdu->N_bytes + hdr_size > nof_bytes) {
logger->warning("Segmentation not supported yet");
return 0;
}
rlc_am_nr_pdu_header_t hdr = {};
hdr.dc = RLC_DC_FIELD_DATA_PDU;
hdr.p = 1; // FIXME
hdr.si = rlc_nr_si_field_t::full_sdu;
hdr.sn_size = rlc_am_nr_sn_size_t::size12bits;
hdr.sn = st.tx_next;
log_rlc_am_nr_pdu_header_to_string(logger->info, hdr);
uint32_t len = rlc_am_nr_write_data_pdu_header(hdr, tx_sdu.get());
if (len > nof_bytes) {
@ -115,6 +125,8 @@ uint32_t rlc_am_nr_tx::read_pdu(uint8_t* payload, uint32_t nof_bytes)
st.tx_next = (st.tx_next + 1) % MOD;
memcpy(payload, tx_sdu->msg, tx_sdu->N_bytes);
logger->debug("Wrote RLC PDU - %d bytes", tx_sdu->N_bytes);
return tx_sdu->N_bytes;
}

Loading…
Cancel
Save