rlc: implement SDU discard for AM+UM in NR+LTE

- Implemented in common base classes
- Added locking
master
Robert Falkenberg 3 years ago
parent 9b44d13471
commit 95ebc06ec1

@ -134,7 +134,6 @@ public:
virtual void get_buffer_state(uint32_t& tx_queue, uint32_t& prio_tx_queue) = 0; virtual void get_buffer_state(uint32_t& tx_queue, uint32_t& prio_tx_queue) = 0;
virtual void reestablish() = 0; virtual void reestablish() = 0;
virtual void empty_queue() = 0; virtual void empty_queue() = 0;
virtual void discard_sdu(uint32_t pdcp_sn) = 0;
virtual bool sdu_queue_is_full() = 0; virtual bool sdu_queue_is_full() = 0;
virtual bool has_data() = 0; virtual bool has_data() = 0;
virtual void stop() = 0; virtual void stop() = 0;
@ -142,6 +141,7 @@ public:
void set_bsr_callback(bsr_callback_t callback); void set_bsr_callback(bsr_callback_t callback);
int write_sdu(unique_byte_buffer_t sdu); int write_sdu(unique_byte_buffer_t sdu);
virtual void discard_sdu(uint32_t pdcp_sn);
virtual uint32_t read_pdu(uint8_t* payload, uint32_t nof_bytes) = 0; virtual uint32_t read_pdu(uint8_t* payload, uint32_t nof_bytes) = 0;
bool tx_enabled = false; bool tx_enabled = false;

@ -59,7 +59,6 @@ public:
void stop(); void stop();
uint32_t read_pdu(uint8_t* payload, uint32_t nof_bytes); uint32_t read_pdu(uint8_t* payload, uint32_t nof_bytes);
void discard_sdu(uint32_t discard_sn);
bool sdu_queue_is_full(); bool sdu_queue_is_full();
bool has_data(); bool has_data();

@ -97,7 +97,6 @@ public:
uint32_t read_pdu(uint8_t* payload, uint32_t nof_bytes) final; uint32_t read_pdu(uint8_t* payload, uint32_t nof_bytes) final;
void handle_control_pdu(uint8_t* payload, uint32_t nof_bytes) final; void handle_control_pdu(uint8_t* payload, uint32_t nof_bytes) final;
void discard_sdu(uint32_t discard_sn) final;
bool sdu_queue_is_full() final; bool sdu_queue_is_full() final;
void reestablish() final; void reestablish() final;

@ -49,6 +49,7 @@ private:
bool configure(const rlc_config_t& cfg, std::string rb_name); bool configure(const rlc_config_t& cfg, std::string rb_name);
uint32_t build_data_pdu(unique_byte_buffer_t pdu, uint8_t* payload, uint32_t nof_bytes); uint32_t build_data_pdu(unique_byte_buffer_t pdu, uint8_t* payload, uint32_t nof_bytes);
void discard_sdu(uint32_t discard_sn);
uint32_t get_buffer_state(); uint32_t get_buffer_state();
bool sdu_queue_is_full(); bool sdu_queue_is_full();

@ -53,6 +53,7 @@ private:
bool configure(const rlc_config_t& cfg, std::string rb_name); bool configure(const rlc_config_t& cfg, std::string rb_name);
uint32_t build_data_pdu(unique_byte_buffer_t pdu, uint8_t* payload, uint32_t nof_bytes); uint32_t build_data_pdu(unique_byte_buffer_t pdu, uint8_t* payload, uint32_t nof_bytes);
void discard_sdu(uint32_t discard_sn);
uint32_t get_buffer_state(); uint32_t get_buffer_state();
private: private:

@ -235,6 +235,25 @@ int rlc_am::rlc_am_base_tx::write_sdu(unique_byte_buffer_t sdu)
return SRSRAN_SUCCESS; return SRSRAN_SUCCESS;
} }
void rlc_am::rlc_am_base_tx::discard_sdu(uint32_t discard_sn)
{
std::lock_guard<std::mutex> lock(mutex);
if (!tx_enabled) {
return;
}
bool discarded = tx_sdu_queue.apply_first([&discard_sn, this](unique_byte_buffer_t& sdu) {
if (sdu != nullptr && sdu->md.pdcp_sn == discard_sn) {
tx_sdu_queue.queue.pop_func(sdu);
sdu = nullptr;
}
return false;
});
// Discard fails when the PDCP PDU is already in Tx window.
RlcInfo("%s PDU with PDCP_SN=%d", discarded ? "Discarding" : "Couldn't discard", discard_sn);
}
void rlc_am::rlc_am_base_tx::set_bsr_callback(bsr_callback_t callback) void rlc_am::rlc_am_base_tx::set_bsr_callback(bsr_callback_t callback)
{ {
bsr_callback = callback; bsr_callback = callback;

@ -268,24 +268,6 @@ void rlc_am_lte_tx::get_buffer_state_nolock(uint32_t& n_bytes_newtx, uint32_t& n
} }
} }
void rlc_am_lte_tx::discard_sdu(uint32_t discard_sn)
{
if (!tx_enabled) {
return;
}
bool discarded = tx_sdu_queue.apply_first([&discard_sn, this](unique_byte_buffer_t& sdu) {
if (sdu != nullptr && sdu->md.pdcp_sn == discard_sn) {
tx_sdu_queue.queue.pop_func(sdu);
sdu = nullptr;
}
return false;
});
// Discard fails when the PDCP PDU is already in Tx window.
RlcInfo("%s PDU with PDCP_SN=%d", discarded ? "Discarding" : "Couldn't discard", discard_sn);
}
bool rlc_am_lte_tx::sdu_queue_is_full() bool rlc_am_lte_tx::sdu_queue_is_full()
{ {
return tx_sdu_queue.is_full(); return tx_sdu_queue.is_full();

@ -856,8 +856,6 @@ void rlc_am_nr_tx::reestablish()
stop(); stop();
} }
void rlc_am_nr_tx::discard_sdu(uint32_t discard_sn) {}
bool rlc_am_nr_tx::sdu_queue_is_full() bool rlc_am_nr_tx::sdu_queue_is_full()
{ {
return false; return false;

@ -298,7 +298,18 @@ int rlc_um_base::rlc_um_base_tx::try_write_sdu(unique_byte_buffer_t sdu)
void rlc_um_base::rlc_um_base_tx::discard_sdu(uint32_t discard_sn) void rlc_um_base::rlc_um_base_tx::discard_sdu(uint32_t discard_sn)
{ {
RlcWarning("RLC UM: Discard SDU not implemented yet."); std::lock_guard<std::mutex> lock(mutex);
bool discarded = tx_sdu_queue.apply_first([&discard_sn, this](unique_byte_buffer_t& sdu) {
if (sdu != nullptr && sdu->md.pdcp_sn == discard_sn) {
tx_sdu_queue.queue.pop_func(sdu);
sdu = nullptr;
}
return false;
});
// Discard fails when the PDCP PDU is already in Tx window.
RlcInfo("%s PDU with PDCP_SN=%d", discarded ? "Discarding" : "Couldn't discard", discard_sn);
} }
bool rlc_um_base::rlc_um_base_tx::sdu_queue_is_full() bool rlc_um_base::rlc_um_base_tx::sdu_queue_is_full()

Loading…
Cancel
Save