mirror of https://github.com/PentHertz/srsLTE.git
Added initial skeleton for RLC AM NR entity
This commit is contained in:
parent
2bb249bf09
commit
d528d8af4c
|
@ -214,4 +214,4 @@ private:
|
|||
|
||||
} // namespace srsran
|
||||
|
||||
#endif // SRSRAN_BEARER_MEM_POOL_H
|
||||
#endif // SRSRAN_RLC_AM_DATA_STRUCTS_H
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue