diff --git a/lib/include/srsran/rlc/rlc_am_nr.h b/lib/include/srsran/rlc/rlc_am_nr.h index d06aa943e..cc336cbe5 100644 --- a/lib/include/srsran/rlc/rlc_am_nr.h +++ b/lib/include/srsran/rlc/rlc_am_nr.h @@ -221,7 +221,9 @@ public: int handle_segment_data_sdu(const rlc_am_nr_pdu_header_t& header, const uint8_t* payload, uint32_t nof_bytes); bool inside_rx_window(uint32_t sn); void write_to_upper_layers(uint32_t lcid, unique_byte_buffer_t sdu); - bool have_all_segments_been_received(const std::list& segment_list); + void insert_received_segment(rlc_amd_rx_pdu_nr segment, + std::set& segment_list); + bool have_all_segments_been_received(const std::set& segment_list); // Metrics uint32_t get_sdu_rx_latency_ms() final; diff --git a/lib/include/srsran/rlc/rlc_am_nr_packing.h b/lib/include/srsran/rlc/rlc_am_nr_packing.h index 44592755d..f75c60e30 100644 --- a/lib/include/srsran/rlc/rlc_am_nr_packing.h +++ b/lib/include/srsran/rlc/rlc_am_nr_packing.h @@ -15,6 +15,7 @@ #include "srsran/common/string_helpers.h" #include "srsran/rlc/rlc_am_base.h" +#include namespace srsran { @@ -52,11 +53,15 @@ struct rlc_amd_rx_pdu_nr { explicit rlc_amd_rx_pdu_nr(uint32_t rlc_sn_) : rlc_sn(rlc_sn_) {} }; +struct rlc_amd_rx_pdu_nr_cmp { + bool operator()(const rlc_amd_rx_pdu_nr& a, const rlc_amd_rx_pdu_nr& b) const { return a.header.so < b.header.so; } +}; + struct rlc_amd_rx_sdu_nr_t { - uint32_t rlc_sn = 0; - bool fully_received = false; - unique_byte_buffer_t buf; - std::list segments; + uint32_t rlc_sn = 0; + bool fully_received = false; + unique_byte_buffer_t buf; + std::set segments; rlc_amd_rx_sdu_nr_t() = default; explicit rlc_amd_rx_sdu_nr_t(uint32_t rlc_sn_) : rlc_sn(rlc_sn_) {} diff --git a/lib/src/rlc/rlc_am_nr.cc b/lib/src/rlc/rlc_am_nr.cc index 961610194..b86821bc0 100644 --- a/lib/src/rlc/rlc_am_nr.cc +++ b/lib/src/rlc/rlc_am_nr.cc @@ -1112,8 +1112,8 @@ int rlc_am_nr_rx::handle_segment_data_sdu(const rlc_am_nr_pdu_header_t& header, memcpy(pdu_segment.buf->msg, payload + hdr_len, nof_bytes - hdr_len); // Don't copy header pdu_segment.buf->N_bytes = nof_bytes - hdr_len; - // Store SDU segment. TODO sort by SO and check for duplicate bytes. - rx_sdu.segments.push_back(std::move(pdu_segment)); + // Store SDU segment. Sort by SO and check for duplicate bytes. + insert_received_segment(std::move(pdu_segment), rx_sdu.segments); // Check weather all segments have been received rx_sdu.fully_received = have_all_segments_been_received(rx_sdu.segments); @@ -1301,14 +1301,21 @@ uint32_t rlc_am_nr_rx::get_rx_buffered_bytes() return 0; } -bool rlc_am_nr_rx::have_all_segments_been_received(const std::list& segment_list) +void rlc_am_nr_rx::insert_received_segment(rlc_amd_rx_pdu_nr segment, + std::set& segment_list) +{ + segment_list.insert(std::move(segment)); +} + +bool rlc_am_nr_rx::have_all_segments_been_received( + const std::set& segment_list) { if (segment_list.empty()) { return false; } // Check if we have received the last segment - if ((--segment_list.end())->header.si != rlc_nr_si_field_t::last_segment) { + if (segment_list.rbegin()->header.si != rlc_nr_si_field_t::last_segment) { return false; }