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
|
} // 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
|
} // namespace srsran
|
||||||
|
|
||||||
#endif // SRSRAN_RLC_AM_NR_H
|
#endif // SRSRAN_RLC_AM_LTE_PACKING_H
|
||||||
|
|
|
@ -25,7 +25,113 @@
|
||||||
|
|
||||||
namespace srsran {
|
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
|
} // 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
|
} // 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
|
* RLC AM NR class
|
||||||
******************************/
|
******************************/
|
||||||
|
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
|
// 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
|
} // namespace srsran
|
||||||
|
|
Loading…
Reference in New Issue