Added initial skeleton for RLC AM NR entity

This commit is contained in:
Pedro Alvarez 2021-06-28 18:52:58 +01:00
parent 2bb249bf09
commit d528d8af4c
5 changed files with 300 additions and 5 deletions

View File

@ -214,4 +214,4 @@ private:
} // namespace srsran
#endif // SRSRAN_BEARER_MEM_POOL_H
#endif // SRSRAN_RLC_AM_DATA_STRUCTS_H

View File

@ -132,4 +132,4 @@ void log_rlc_am_status_pdu_to_string(srslog::log_channel& log_ch,
} // namespace srsran
#endif // SRSRAN_RLC_AM_NR_H
#endif // SRSRAN_RLC_AM_LTE_PACKING_H

View File

@ -25,7 +25,113 @@
namespace srsran {
// TODO
class rlc_am_nr : public rlc_common
{
public:
rlc_am_nr(srslog::basic_logger& logger,
uint32_t lcid_,
srsue::pdcp_interface_rlc* pdcp_,
srsue::rrc_interface_rlc* rrc_,
srsran::timer_handler* timers_);
bool configure(const rlc_config_t& cfg_) final;
void stop() final;
rlc_mode_t get_mode() final;
uint32_t get_bearer() final;
void reestablish() final;
void empty_queue() final;
void set_bsr_callback(bsr_callback_t callback) final;
// PDCP interface
void write_sdu(unique_byte_buffer_t sdu) final;
void discard_sdu(uint32_t pdcp_sn) final;
bool sdu_queue_is_full() final;
// MAC interface
bool has_data() final;
uint32_t get_buffer_state() final;
void get_buffer_state(uint32_t& tx_queue, uint32_t& prio_tx_queue) final;
uint32_t read_pdu(uint8_t* payload, uint32_t nof_bytes) final;
void write_pdu(uint8_t* payload, uint32_t nof_bytes) final;
rlc_bearer_metrics_t get_metrics() final;
void reset_metrics() final;
private:
// Transmitter sub-class
class rlc_am_nr_tx
{
public:
explicit rlc_am_nr_tx(rlc_am_nr* parent_);
~rlc_am_nr_tx() = default;
bool configure(const rlc_am_config_t& cfg_);
void stop();
int write_sdu(unique_byte_buffer_t sdu);
uint32_t read_pdu(uint8_t* payload, uint32_t nof_bytes);
void discard_sdu(uint32_t discard_sn);
bool sdu_queue_is_full();
bool has_data();
uint32_t get_buffer_state();
rlc_am_nr* parent = nullptr;
srslog::basic_logger& logger;
private:
byte_buffer_pool* pool = nullptr;
/****************************************************************************
* Configurable parameters
* Ref: 3GPP TS 38.322 v10.0.0 Section 7.4
***************************************************************************/
rlc_am_config_t cfg = {};
};
// Receiver sub-class
class rlc_am_nr_rx
{
public:
explicit rlc_am_nr_rx(rlc_am_nr* parent_);
~rlc_am_nr_rx() = default;
bool configure(const rlc_am_config_t& cfg_);
void stop();
void write_pdu(uint8_t* payload, uint32_t nof_bytes);
rlc_am_nr* parent = nullptr;
srslog::basic_logger& logger;
private:
byte_buffer_pool* pool = nullptr;
/****************************************************************************
* Configurable parameters
* Ref: 3GPP TS 38.322 v10.0.0 Section 7.4
***************************************************************************/
rlc_am_config_t cfg = {};
};
// Common variables needed/provided by parent class
srsue::rrc_interface_rlc* rrc = nullptr;
srslog::basic_logger& logger;
srsue::pdcp_interface_rlc* pdcp = nullptr;
srsran::timer_handler* timers = nullptr;
uint32_t lcid = 0;
rlc_config_t cfg = {};
std::string rb_name;
static const int poll_periodicity = 8; // After how many data PDUs a status PDU shall be requested
// Rx and Tx objects
rlc_am_nr_tx tx;
rlc_am_nr_rx rx;
rlc_bearer_metrics_t metrics = {};
};
} // namespace srsran

View File

@ -72,4 +72,4 @@ int32_t rlc_am_nr_write_status_pdu(const rlc_am_nr_status_pdu_t& status_pdu,
} // namespace srsran
#endif // SRSRAN_RLC_AM_NR_H
#endif // SRSRAN_RLC_AM_NR_PACKING_H

View File

@ -22,6 +22,195 @@ namespace srsran {
/*******************************
* RLC AM NR class
******************************/
// TODO
rlc_am_nr::rlc_am_nr(srslog::basic_logger& logger,
uint32_t lcid_,
srsue::pdcp_interface_rlc* pdcp_,
srsue::rrc_interface_rlc* rrc_,
srsran::timer_handler* timers_) :
logger(logger), rrc(rrc_), pdcp(pdcp_), timers(timers_), lcid(lcid_), tx(this), rx(this)
{}
// Applies new configuration. Must be just reestablished or initiated
bool rlc_am_nr::configure(const rlc_config_t& cfg_)
{
// determine bearer name and configure Rx/Tx objects
rb_name = rrc->get_rb_name(lcid);
// store config
cfg = cfg_;
if (not rx.configure(cfg.am)) {
logger.error("Error configuring bearer (RX)");
return false;
}
if (not tx.configure(cfg.am)) {
logger.error("Error configuring bearer (TX)");
return false;
}
logger.info("%s configured: t_poll_retx=%d, poll_pdu=%d, poll_byte=%d, max_retx_thresh=%d, "
"t_reordering=%d, t_status_prohibit=%d",
rb_name.c_str(),
cfg.am.t_poll_retx,
cfg.am.poll_pdu,
cfg.am.poll_byte,
cfg.am.max_retx_thresh,
cfg.am.t_reordering,
cfg.am.t_status_prohibit);
return true;
}
void rlc_am_nr::stop() {}
rlc_mode_t rlc_am_nr::get_mode()
{
return rlc_mode_t::am;
}
uint32_t rlc_am_nr::get_bearer()
{
return 0;
}
void rlc_am_nr::reestablish() {}
void rlc_am_nr::empty_queue() {}
void rlc_am_nr::set_bsr_callback(bsr_callback_t callback) {}
rlc_bearer_metrics_t rlc_am_nr::get_metrics()
{
return {};
}
void rlc_am_nr::reset_metrics() {}
/****************************************************************************
* PDCP interface
***************************************************************************/
void rlc_am_nr::write_sdu(unique_byte_buffer_t sdu)
{
if (tx.write_sdu(std::move(sdu)) == SRSRAN_SUCCESS) {
metrics.num_tx_sdus++;
}
}
void rlc_am_nr::discard_sdu(uint32_t pdcp_sn)
{
tx.discard_sdu(pdcp_sn);
metrics.num_lost_sdus++;
}
bool rlc_am_nr::sdu_queue_is_full()
{
return tx.sdu_queue_is_full();
}
/****************************************************************************
* MAC interface
***************************************************************************/
bool rlc_am_nr::has_data()
{
return tx.has_data();
}
uint32_t rlc_am_nr::get_buffer_state()
{
return tx.get_buffer_state();
}
void rlc_am_nr::get_buffer_state(uint32_t& tx_queue, uint32_t& prio_tx_queue)
{
// TODO
tx_queue = tx.get_buffer_state();
prio_tx_queue = 0;
}
uint32_t rlc_am_nr::read_pdu(uint8_t* payload, uint32_t nof_bytes)
{
uint32_t read_bytes = tx.read_pdu(payload, nof_bytes);
metrics.num_tx_pdus++;
metrics.num_tx_pdu_bytes += read_bytes;
return read_bytes;
}
void rlc_am_nr::write_pdu(uint8_t* payload, uint32_t nof_bytes)
{
rx.write_pdu(payload, nof_bytes);
metrics.num_rx_pdus++;
metrics.num_rx_pdu_bytes += nof_bytes;
}
/****************************************************************************
* Tx subclass implementation
***************************************************************************/
rlc_am_nr::rlc_am_nr_tx::rlc_am_nr_tx(rlc_am_nr* parent_) :
parent(parent_), logger(parent_->logger), pool(byte_buffer_pool::get_instance())
{}
bool rlc_am_nr::rlc_am_nr_tx::configure(const rlc_am_config_t& cfg_)
{
/*
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.",
cfg_.tx_queue_length,
MAX_SDUS_PER_RLC_PDU);
return false;
}
*/
cfg = cfg_;
return true;
}
int rlc_am_nr::rlc_am_nr_tx::write_sdu(unique_byte_buffer_t sdu)
{
return 0;
}
void rlc_am_nr::rlc_am_nr_tx::discard_sdu(uint32_t sn)
{
return;
}
bool rlc_am_nr::rlc_am_nr_tx::sdu_queue_is_full()
{
return false;
}
bool rlc_am_nr::rlc_am_nr_tx::has_data()
{
return true;
}
uint32_t rlc_am_nr::rlc_am_nr_tx::read_pdu(uint8_t* payload, uint32_t nof_bytes)
{
return 0;
}
uint32_t rlc_am_nr::rlc_am_nr_tx::get_buffer_state()
{
return 0;
}
/****************************************************************************
* Rx subclass implementation
***************************************************************************/
rlc_am_nr::rlc_am_nr_rx::rlc_am_nr_rx(rlc_am_nr* parent_) :
parent(parent_), pool(byte_buffer_pool::get_instance()), logger(parent_->logger)
{}
bool rlc_am_nr::rlc_am_nr_rx::configure(const rlc_am_config_t& cfg_)
{
cfg = cfg_;
return true;
}
void rlc_am_nr::rlc_am_nr_rx::stop() {}
void rlc_am_nr::rlc_am_nr_rx::write_pdu(uint8_t* payload, uint32_t nof_bytes) {}
} // namespace srsran