diff --git a/lib/include/srsran/rlc/rlc_am_nr.h b/lib/include/srsran/rlc/rlc_am_nr.h index bd9c96909..91ce60dea 100644 --- a/lib/include/srsran/rlc/rlc_am_nr.h +++ b/lib/include/srsran/rlc/rlc_am_nr.h @@ -153,7 +153,6 @@ private: std::unique_ptr > retx_queue; uint32_t sdu_under_segmentation_sn = INVALID_RLC_SN; // SN of the SDU currently being segmented. pdcp_sn_vector_t notify_info_vec; - rlc_am_nr_status_pdu_t tx_status; // Helper constants uint32_t min_hdr_size = 2; diff --git a/lib/include/srsran/rlc/rlc_am_nr_packing.h b/lib/include/srsran/rlc/rlc_am_nr_packing.h index fb6d846b8..e427bf5d8 100644 --- a/lib/include/srsran/rlc/rlc_am_nr_packing.h +++ b/lib/include/srsran/rlc/rlc_am_nr_packing.h @@ -78,22 +78,27 @@ struct rlc_amd_tx_sdu_nr_t { explicit rlc_amd_tx_sdu_nr_t(uint32_t rlc_sn_) : rlc_sn(rlc_sn_) {} }; -///< AM NR Status PDU header (perhaps merge with LTE version) -struct rlc_am_nr_status_pdu_t { - rlc_am_nr_control_pdu_type_t cpt; - uint32_t ack_sn; ///< SN of the next not received RLC Data PDU - std::vector nacks; - - rlc_am_nr_status_pdu_t() : cpt(rlc_am_nr_control_pdu_type_t::status_pdu), ack_sn(INVALID_RLC_SN), nacks(0) - { - nacks.reserve(RLC_AM_NR_TYP_NACKS); - } - void reset() - { - cpt = rlc_am_nr_control_pdu_type_t::status_pdu; - ack_sn = INVALID_RLC_SN; - nacks.clear(); - } +///< AM NR Status PDU header +class rlc_am_nr_status_pdu_t +{ +private: + rlc_am_nr_sn_size_t sn_size; ///< Stored SN size required to compute the packed size + std::vector nacks_; ///< Internal NACK container; keep in sync with packed_size_ + uint32_t packed_size_; ///< Stores the current packed size; sync on each change of nacks_ + + void refresh_packed_size(); + +public: + rlc_am_nr_control_pdu_type_t cpt; ///< CPT header + uint32_t ack_sn; ///< SN of the next not received RLC Data PDU + const std::vector& nacks; ///< Read-only reference to NACKs + const uint32_t& packed_size; ///< Read-only reference to packed size + + rlc_am_nr_status_pdu_t(rlc_am_nr_sn_size_t sn_size); + void reset(); + void push_nack(const rlc_status_nack_t& nack); + const std::vector& get_nacks() const { return nacks_; } + uint32_t get_packed_size() const { return packed_size; } }; /**************************************************************************** @@ -114,6 +119,16 @@ uint32_t rlc_am_nr_write_data_pdu_header(const rlc_am_nr_pdu_header_t& header, b uint32_t rlc_am_nr_packed_length(const rlc_am_nr_pdu_header_t& header); +/**************************************************************************** + * Status PDU pack/unpack helper functions for NR + * Ref: 3GPP TS 38.322 v16.2.0 Section 6.2.2.5 + ***************************************************************************/ +constexpr uint32_t rlc_am_nr_status_pdu_sizeof_header_ack_sn = 3; // header fixed part and ACK SN +constexpr uint32_t rlc_am_nr_status_pdu_sizeof_nack_sn_ext_12bit_sn = 2; // NACK SN and extension fields (12 bit SN) +constexpr uint32_t rlc_am_nr_status_pdu_sizeof_nack_sn_ext_18bit_sn = 3; // NACK SN and extension fields (18 bit SN) +constexpr uint32_t rlc_am_nr_status_pdu_sizeof_nack_so = 4; // NACK segment offsets (start and end) +constexpr uint32_t rlc_am_nr_status_pdu_sizeof_nack_range = 1; // NACK range (nof consecutively lost SDUs) + uint32_t rlc_am_nr_read_status_pdu(const byte_buffer_t* pdu, const rlc_am_nr_sn_size_t sn_size, rlc_am_nr_status_pdu_t* status); diff --git a/lib/src/rlc/rlc_am_nr.cc b/lib/src/rlc/rlc_am_nr.cc index efb8542b3..49ea68591 100644 --- a/lib/src/rlc/rlc_am_nr.cc +++ b/lib/src/rlc/rlc_am_nr.cc @@ -724,15 +724,16 @@ uint32_t rlc_am_nr_tx::get_retx_expected_hdr_len(const rlc_amd_retx_nr_t& retx) uint32_t rlc_am_nr_tx::build_status_pdu(byte_buffer_t* payload, uint32_t nof_bytes) { RlcInfo("generating status PDU. Bytes available:%d", nof_bytes); - tx_status.reset(); - int pdu_len = rx->get_status_pdu(&tx_status, nof_bytes); + rlc_am_nr_status_pdu_t status(cfg.rx_sn_field_length); // carries status of RX entity, hence use SN length of RX + status.reset(); + int pdu_len = rx->get_status_pdu(&status, nof_bytes); if (pdu_len == SRSRAN_ERROR) { RlcDebug("deferred status PDU. Cause: Failed to acquire rx lock"); pdu_len = 0; } else if (pdu_len > 0 && nof_bytes >= static_cast(pdu_len)) { RlcDebug("generated status PDU. Bytes:%d", pdu_len); - log_rlc_am_nr_status_pdu_to_string(logger.info, "TX status PDU - %s", &tx_status, rb_name); - pdu_len = rlc_am_nr_write_status_pdu(tx_status, cfg.tx_sn_field_length, payload); + log_rlc_am_nr_status_pdu_to_string(logger.info, "TX status PDU - %s", &status, rb_name); + pdu_len = rlc_am_nr_write_status_pdu(status, cfg.tx_sn_field_length, payload); } else { RlcInfo("cannot tx status PDU - %d bytes available, %d bytes required", nof_bytes, pdu_len); pdu_len = 0; @@ -748,7 +749,7 @@ void rlc_am_nr_tx::handle_control_pdu(uint8_t* payload, uint32_t nof_bytes) } std::lock_guard lock(mutex); - rlc_am_nr_status_pdu_t status = {}; + rlc_am_nr_status_pdu_t status(cfg.tx_sn_field_length); RlcHexDebug(payload, nof_bytes, "%s Rx control PDU", parent->rb_name); rlc_am_nr_read_status_pdu(payload, nof_bytes, cfg.tx_sn_field_length, &status); log_rlc_am_nr_status_pdu_to_string(logger.info, "RX status PDU: %s", &status, parent->rb_name); @@ -1408,11 +1409,11 @@ uint32_t rlc_am_nr_rx::get_status_pdu(rlc_am_nr_status_pdu_t* status, uint32_t m { std::unique_lock lock(mutex, std::try_to_lock); if (not lock.owns_lock()) { - return 0; + return SRSRAN_ERROR; } - status->nacks.clear(); - status->ack_sn = st.rx_next; // Start with the lower end of the window + status->reset(); + byte_buffer_t tmp_buf; /* @@ -1430,15 +1431,15 @@ uint32_t rlc_am_nr_rx::get_status_pdu(rlc_am_nr_status_pdu_t* status, uint32_t m } else { if (not rx_window->has_sn(i)) { // No segment received, NACK the whole SDU - RlcDebug("Updating NACK for full SDU. NACK SN=%d", i); + RlcDebug("Adding NACK for full SDU. NACK SN=%d", i); rlc_status_nack_t nack; nack.nack_sn = i; nack.has_so = false; - status->nacks.push_back(nack); + status->push_nack(nack); } else if (not(*rx_window)[i].fully_received) { // Some segments were received, but not all. // NACK non consecutive missing bytes - RlcDebug("Updating NACK for partial SDU. NACK SN=%d", i); + RlcDebug("Adding NACKs for segmented SDU. NACK SN=%d", i); uint32_t last_so = 0; bool last_segment_rx = false; for (auto segm = (*rx_window)[i].segments.begin(); segm != (*rx_window)[i].segments.end(); segm++) { @@ -1449,7 +1450,7 @@ uint32_t rlc_am_nr_rx::get_status_pdu(rlc_am_nr_status_pdu_t* status, uint32_t m nack.has_so = true; nack.so_start = last_so; nack.so_end = segm->header.so - 1; // set to last missing byte - status->nacks.push_back(nack); + status->push_nack(nack); RlcDebug("First/middle segment missing. NACK_SN=%d. SO_start=%d, SO_end=%d", nack.nack_sn, nack.so_start, @@ -1460,14 +1461,14 @@ uint32_t rlc_am_nr_rx::get_status_pdu(rlc_am_nr_status_pdu_t* status, uint32_t m last_segment_rx = true; } last_so = segm->header.so + segm->buf->N_bytes; - } + } // Segment loop if (not last_segment_rx) { rlc_status_nack_t nack; nack.nack_sn = i; nack.has_so = true; nack.so_start = last_so; nack.so_end = so_end_of_sdu; - status->nacks.push_back(nack); + status->push_nack(nack); RlcDebug( "Final segment missing. NACK_SN=%d. SO_start=%d, SO_end=%d", nack.nack_sn, nack.so_start, nack.so_end); srsran_assert(nack.so_start <= nack.so_end, "Error: SO_start > SO_end. NACK_SN=%d", nack.nack_sn); @@ -1499,8 +1500,10 @@ uint32_t rlc_am_nr_rx::get_status_pdu(rlc_am_nr_status_pdu_t* status, uint32_t m uint32_t rlc_am_nr_rx::get_status_pdu_length() { - rlc_am_nr_status_pdu_t tmp_status; - return get_status_pdu(&tmp_status, UINT32_MAX); + rlc_am_nr_status_pdu_t tmp_status(cfg.rx_sn_field_length); + tmp_status.reset(); + get_status_pdu(&tmp_status, UINT32_MAX); + return tmp_status.get_packed_size(); } bool rlc_am_nr_rx::get_do_status() diff --git a/lib/src/rlc/rlc_am_nr_packing.cc b/lib/src/rlc/rlc_am_nr_packing.cc index e0d5d69ba..df8785015 100644 --- a/lib/src/rlc/rlc_am_nr_packing.cc +++ b/lib/src/rlc/rlc_am_nr_packing.cc @@ -15,6 +15,58 @@ namespace srsran { +/**************************************************************************** + * Container implementation for pack/unpack functions + ***************************************************************************/ + +void rlc_am_nr_status_pdu_t::refresh_packed_size() +{ + uint32_t packed_size = rlc_am_nr_status_pdu_sizeof_header_ack_sn; + for (auto nack : nacks_) { + packed_size += sn_size == rlc_am_nr_sn_size_t::size12bits ? rlc_am_nr_status_pdu_sizeof_nack_sn_ext_12bit_sn + : rlc_am_nr_status_pdu_sizeof_nack_sn_ext_18bit_sn; + if (nack.has_so) { + packed_size += rlc_am_nr_status_pdu_sizeof_nack_so; + } + if (nack.has_nack_range) { + packed_size += rlc_am_nr_status_pdu_sizeof_nack_range; + } + } +} + +rlc_am_nr_status_pdu_t::rlc_am_nr_status_pdu_t(rlc_am_nr_sn_size_t sn_size) : + sn_size(sn_size), + nacks_(0), + packed_size_(rlc_am_nr_status_pdu_sizeof_header_ack_sn), + cpt(rlc_am_nr_control_pdu_type_t::status_pdu), + ack_sn(INVALID_RLC_SN), + nacks(nacks_), + packed_size(packed_size_) +{ + nacks_.reserve(RLC_AM_NR_TYP_NACKS); +} + +void rlc_am_nr_status_pdu_t::reset() +{ + cpt = rlc_am_nr_control_pdu_type_t::status_pdu; + ack_sn = INVALID_RLC_SN; + nacks_.clear(); + packed_size_ = rlc_am_nr_status_pdu_sizeof_header_ack_sn; +} + +void rlc_am_nr_status_pdu_t::push_nack(const rlc_status_nack_t& nack) +{ + nacks_.push_back(nack); + packed_size_ += sn_size == rlc_am_nr_sn_size_t::size12bits ? rlc_am_nr_status_pdu_sizeof_nack_sn_ext_12bit_sn + : rlc_am_nr_status_pdu_sizeof_nack_sn_ext_18bit_sn; + if (nack.has_so) { + packed_size_ += rlc_am_nr_status_pdu_sizeof_nack_so; + } + if (nack.has_nack_range) { + packed_size_ += rlc_am_nr_status_pdu_sizeof_nack_range; + } +} + /**************************************************************************** * Header pack/unpack helper functions * Ref: 3GPP TS 38.322 v15.3.0 Section 6.2.2.4 @@ -231,7 +283,7 @@ rlc_am_nr_read_status_pdu_12bit_sn(const uint8_t* payload, const uint32_t nof_by nack.nack_range = (*ptr); ptr++; } - status->nacks.push_back(nack); + status->push_nack(nack); if (uint32_t(ptr - payload) > nof_bytes) { fprintf(stderr, "Malformed PDU, trying to read more bytes than it is available\n"); return 0; @@ -313,7 +365,7 @@ rlc_am_nr_read_status_pdu_18bit_sn(const uint8_t* payload, const uint32_t nof_by nack.nack_range = (*ptr); ptr++; } - status->nacks.push_back(nack); + status->push_nack(nack); if (uint32_t(ptr - payload) > nof_bytes) { fprintf(stderr, "Malformed PDU, trying to read more bytes than it is available\n"); return 0; diff --git a/lib/test/rlc/rlc_am_nr_pdu_test.cc b/lib/test/rlc/rlc_am_nr_pdu_test.cc index cad7e8bc3..d826ef896 100644 --- a/lib/test/rlc/rlc_am_nr_pdu_test.cc +++ b/lib/test/rlc/rlc_am_nr_pdu_test.cc @@ -233,7 +233,7 @@ int rlc_am_nr_control_pdu_12bit_sn_test1() TESTASSERT(rlc_am_is_control_pdu(pdu.msg) == true); // unpack PDU - rlc_am_nr_status_pdu_t status_pdu = {}; + rlc_am_nr_status_pdu_t status_pdu(srsran::rlc_am_nr_sn_size_t::size12bits); TESTASSERT(rlc_am_nr_read_status_pdu(&pdu, srsran::rlc_am_nr_sn_size_t::size12bits, &status_pdu) == SRSRAN_SUCCESS); TESTASSERT(status_pdu.ack_sn == 2065); TESTASSERT(status_pdu.nacks.size() == 0); @@ -263,7 +263,7 @@ int rlc_am_nr_control_pdu_12bit_sn_test2() TESTASSERT(rlc_am_is_control_pdu(pdu.msg) == true); // unpack PDU - rlc_am_nr_status_pdu_t status_pdu = {}; + rlc_am_nr_status_pdu_t status_pdu(srsran::rlc_am_nr_sn_size_t::size12bits); TESTASSERT(rlc_am_nr_read_status_pdu(&pdu, srsran::rlc_am_nr_sn_size_t::size12bits, &status_pdu) == SRSRAN_SUCCESS); TESTASSERT(status_pdu.ack_sn == 2065); TESTASSERT(status_pdu.nacks.size() == 1); @@ -296,7 +296,7 @@ int rlc_am_nr_control_pdu_12bit_sn_test3() TESTASSERT(rlc_am_is_control_pdu(pdu.msg) == true); // unpack PDU - rlc_am_nr_status_pdu_t status_pdu = {}; + rlc_am_nr_status_pdu_t status_pdu(srsran::rlc_am_nr_sn_size_t::size12bits); TESTASSERT(rlc_am_nr_read_status_pdu(&pdu, srsran::rlc_am_nr_sn_size_t::size12bits, &status_pdu) == SRSRAN_SUCCESS); TESTASSERT(status_pdu.ack_sn == 2065); TESTASSERT(status_pdu.nacks.size() == 2); @@ -332,7 +332,7 @@ int rlc_am_nr_control_pdu_12bit_sn_test4() TESTASSERT(rlc_am_is_control_pdu(pdu.msg) == true); // unpack PDU - rlc_am_nr_status_pdu_t status_pdu = {}; + rlc_am_nr_status_pdu_t status_pdu(srsran::rlc_am_nr_sn_size_t::size12bits); TESTASSERT(rlc_am_nr_read_status_pdu(&pdu, srsran::rlc_am_nr_sn_size_t::size12bits, &status_pdu) == SRSRAN_SUCCESS); TESTASSERT(status_pdu.ack_sn == 2065); TESTASSERT(status_pdu.nacks.size() == 2); @@ -370,7 +370,7 @@ int rlc_am_nr_control_pdu_12bit_sn_test5() TESTASSERT(rlc_am_is_control_pdu(pdu.msg) == true); // unpack PDU - rlc_am_nr_status_pdu_t status_pdu = {}; + rlc_am_nr_status_pdu_t status_pdu(srsran::rlc_am_nr_sn_size_t::size12bits); TESTASSERT(rlc_am_nr_read_status_pdu(&pdu, srsran::rlc_am_nr_sn_size_t::size12bits, &status_pdu) == 0); return SRSRAN_SUCCESS; @@ -404,7 +404,7 @@ int rlc_am_nr_control_pdu_12bit_sn_test_nack_range() TESTASSERT(rlc_am_is_control_pdu(pdu.msg) == true); // unpack PDU - rlc_am_nr_status_pdu_t status_pdu = {}; + rlc_am_nr_status_pdu_t status_pdu(srsran::rlc_am_nr_sn_size_t::size12bits); TESTASSERT(rlc_am_nr_read_status_pdu(&pdu, srsran::rlc_am_nr_sn_size_t::size12bits, &status_pdu) == SRSRAN_SUCCESS); TESTASSERT(status_pdu.ack_sn == 2065); TESTASSERT(status_pdu.nacks.size() == 2); @@ -445,7 +445,7 @@ int rlc_am_nr_control_pdu_18bit_sn_test1() TESTASSERT(rlc_am_is_control_pdu(pdu.msg) == true); // unpack PDU - rlc_am_nr_status_pdu_t status_pdu = {}; + rlc_am_nr_status_pdu_t status_pdu(srsran::rlc_am_nr_sn_size_t::size18bits); TESTASSERT(rlc_am_nr_read_status_pdu(&pdu, srsran::rlc_am_nr_sn_size_t::size18bits, &status_pdu) == SRSRAN_SUCCESS); TESTASSERT(status_pdu.ack_sn == 235929); TESTASSERT(status_pdu.nacks.size() == 0); @@ -476,7 +476,7 @@ int rlc_am_nr_control_pdu_18bit_sn_test2() TESTASSERT(rlc_am_is_control_pdu(pdu.msg) == true); // unpack PDU - rlc_am_nr_status_pdu_t status_pdu = {}; + rlc_am_nr_status_pdu_t status_pdu(srsran::rlc_am_nr_sn_size_t::size18bits); TESTASSERT(rlc_am_nr_read_status_pdu(&pdu, srsran::rlc_am_nr_sn_size_t::size18bits, &status_pdu) == SRSRAN_SUCCESS); TESTASSERT(status_pdu.ack_sn == 235929); TESTASSERT(status_pdu.nacks.size() == 1); @@ -527,7 +527,7 @@ int rlc_am_nr_control_pdu_18bit_sn_test3() TESTASSERT(rlc_am_is_control_pdu(pdu.msg) == true); // unpack PDU - rlc_am_nr_status_pdu_t status_pdu = {}; + rlc_am_nr_status_pdu_t status_pdu(srsran::rlc_am_nr_sn_size_t::size18bits); TESTASSERT(rlc_am_nr_read_status_pdu(&pdu, srsran::rlc_am_nr_sn_size_t::size18bits, &status_pdu) == SRSRAN_SUCCESS); TESTASSERT(status_pdu.ack_sn == 235929); TESTASSERT(status_pdu.nacks.size() == 2); @@ -579,7 +579,7 @@ int rlc_am_nr_control_pdu_18bit_sn_test4() TESTASSERT(rlc_am_is_control_pdu(pdu.msg) == true); // unpack PDU - rlc_am_nr_status_pdu_t status_pdu = {}; + rlc_am_nr_status_pdu_t status_pdu(srsran::rlc_am_nr_sn_size_t::size18bits); TESTASSERT(rlc_am_nr_read_status_pdu(&pdu, srsran::rlc_am_nr_sn_size_t::size18bits, &status_pdu) == SRSRAN_SUCCESS); TESTASSERT(status_pdu.ack_sn == 235929); TESTASSERT(status_pdu.nacks.size() == 2); @@ -635,7 +635,7 @@ int rlc_am_nr_control_pdu_18bit_sn_test5() TESTASSERT(rlc_am_is_control_pdu(pdu.msg) == true); // unpack PDU - rlc_am_nr_status_pdu_t status_pdu = {}; + rlc_am_nr_status_pdu_t status_pdu(srsran::rlc_am_nr_sn_size_t::size18bits); TESTASSERT(rlc_am_nr_read_status_pdu(&pdu, srsran::rlc_am_nr_sn_size_t::size18bits, &status_pdu) == 0); return SRSRAN_SUCCESS; @@ -671,7 +671,7 @@ int rlc_am_nr_control_pdu_18bit_sn_test_nack_range() TESTASSERT(rlc_am_is_control_pdu(pdu.msg) == true); // unpack PDU - rlc_am_nr_status_pdu_t status_pdu = {}; + rlc_am_nr_status_pdu_t status_pdu(srsran::rlc_am_nr_sn_size_t::size18bits); TESTASSERT(rlc_am_nr_read_status_pdu(&pdu, srsran::rlc_am_nr_sn_size_t::size18bits, &status_pdu) == SRSRAN_SUCCESS); TESTASSERT(status_pdu.ack_sn == 200977); TESTASSERT(status_pdu.nacks.size() == 2); diff --git a/lib/test/rlc/rlc_am_nr_test.cc b/lib/test/rlc/rlc_am_nr_test.cc index 2a8b9d72a..1ab1d84a1 100644 --- a/lib/test/rlc/rlc_am_nr_test.cc +++ b/lib/test/rlc/rlc_am_nr_test.cc @@ -251,7 +251,7 @@ int basic_test(rlc_am_nr_sn_size_t sn_size) TESTASSERT_EQ(0, rlc2.get_buffer_state()); // Assert status is correct - rlc_am_nr_status_pdu_t status_check = {}; + rlc_am_nr_status_pdu_t status_check(sn_size); rlc_am_nr_read_status_pdu(&status_buf, sn_size, &status_check); TESTASSERT_EQ(5, status_check.ack_sn); // 5 is the last SN that was not received. @@ -364,7 +364,7 @@ int lost_pdu_test(rlc_am_nr_sn_size_t sn_size) TESTASSERT(0 == rlc2.get_buffer_state()); // Assert status is correct - rlc_am_nr_status_pdu_t status_check = {}; + rlc_am_nr_status_pdu_t status_check(sn_size); rlc_am_nr_read_status_pdu(&status_buf, sn_size, &status_check); TESTASSERT_EQ(3, status_check.ack_sn); // 3 is the next expected SN (i.e. the lost packet.) @@ -390,7 +390,7 @@ int lost_pdu_test(rlc_am_nr_sn_size_t sn_size) TESTASSERT_EQ(0, rlc2.get_buffer_state()); // Assert status is correct - rlc_am_nr_status_pdu_t status_check = {}; + rlc_am_nr_status_pdu_t status_check(sn_size); rlc_am_nr_read_status_pdu(&status_buf, sn_size, &status_check); TESTASSERT_EQ(5, status_check.ack_sn); // 5 is the next expected SN. TESTASSERT_EQ(1, status_check.nacks.size()); // We lost one PDU. @@ -423,7 +423,7 @@ int lost_pdu_test(rlc_am_nr_sn_size_t sn_size) TESTASSERT_EQ(0, rlc2.get_buffer_state()); // Assert status is correct - rlc_am_nr_status_pdu_t status_check = {}; + rlc_am_nr_status_pdu_t status_check(sn_size); rlc_am_nr_read_status_pdu(&status_buf, sn_size, &status_check); TESTASSERT_EQ(5, status_check.ack_sn); // 5 is the next expected SN. TESTASSERT_EQ(0, status_check.nacks.size()); // All PDUs are acked now @@ -531,7 +531,7 @@ int lost_pdu_duplicated_nack_test(rlc_am_nr_sn_size_t sn_size) TESTASSERT(0 == rlc2.get_buffer_state()); // Assert status is correct - rlc_am_nr_status_pdu_t status_check = {}; + rlc_am_nr_status_pdu_t status_check(sn_size); rlc_am_nr_read_status_pdu(&status_buf, sn_size, &status_check); TESTASSERT_EQ(3, status_check.ack_sn); // 3 is the next expected SN (i.e. the lost packet.) @@ -563,7 +563,7 @@ int lost_pdu_duplicated_nack_test(rlc_am_nr_sn_size_t sn_size) TESTASSERT_EQ(0, rlc2.get_buffer_state()); // Assert status is correct - rlc_am_nr_status_pdu_t status_check = {}; + rlc_am_nr_status_pdu_t status_check(sn_size); rlc_am_nr_read_status_pdu(&status_buf, sn_size, &status_check); TESTASSERT_EQ(5, status_check.ack_sn); // 5 is the next expected SN. TESTASSERT_EQ(1, status_check.nacks.size()); // We lost one PDU. @@ -599,7 +599,7 @@ int lost_pdu_duplicated_nack_test(rlc_am_nr_sn_size_t sn_size) TESTASSERT_EQ(0, rlc2.get_buffer_state()); // Assert status is correct - rlc_am_nr_status_pdu_t status_check = {}; + rlc_am_nr_status_pdu_t status_check(sn_size); rlc_am_nr_read_status_pdu(&status_buf, sn_size, &status_check); TESTASSERT_EQ(5, status_check.ack_sn); // 5 is the next expected SN. TESTASSERT_EQ(0, status_check.nacks.size()); // All PDUs are acked now @@ -817,7 +817,7 @@ int segment_retx_test(rlc_am_nr_sn_size_t sn_size) TESTASSERT_EQ(0, rlc2.get_buffer_state()); // Assert status is correct - rlc_am_nr_status_pdu_t status_check = {}; + rlc_am_nr_status_pdu_t status_check(sn_size); rlc_am_nr_read_status_pdu(&status_buf, sn_size, &status_check); TESTASSERT_EQ(3, status_check.ack_sn); // 3 is the next expected SN (i.e. the lost packet.) @@ -843,7 +843,7 @@ int segment_retx_test(rlc_am_nr_sn_size_t sn_size) TESTASSERT_EQ(0, rlc2.get_buffer_state()); // Assert status is correct - rlc_am_nr_status_pdu_t status_check = {}; + rlc_am_nr_status_pdu_t status_check(sn_size); rlc_am_nr_read_status_pdu(&status_buf, sn_size, &status_check); TESTASSERT_EQ(5, status_check.ack_sn); // 5 is the next expected SN. TESTASSERT_EQ(1, status_check.nacks.size()); // We lost one PDU. @@ -1014,7 +1014,7 @@ int segment_retx_and_loose_segments_test(rlc_am_nr_sn_size_t sn_size) TESTASSERT_EQ(0, rlc2.get_buffer_state()); // Assert status is correct - rlc_am_nr_status_pdu_t status_check = {}; + rlc_am_nr_status_pdu_t status_check(sn_size); rlc_am_nr_read_status_pdu(&status_buf, sn_size, &status_check); TESTASSERT_EQ(3, status_check.ack_sn); // 3 is the next expected SN (i.e. the lost packet.) @@ -1040,7 +1040,7 @@ int segment_retx_and_loose_segments_test(rlc_am_nr_sn_size_t sn_size) TESTASSERT_EQ(0, rlc2.get_buffer_state()); // Assert status is correct - rlc_am_nr_status_pdu_t status_check = {}; + rlc_am_nr_status_pdu_t status_check(sn_size); rlc_am_nr_read_status_pdu(&status_buf, sn_size, &status_check); TESTASSERT_EQ(5, status_check.ack_sn); // 5 is the next expected SN. TESTASSERT_EQ(1, status_check.nacks.size()); // We lost one PDU. @@ -1108,7 +1108,7 @@ int segment_retx_and_loose_segments_test(rlc_am_nr_sn_size_t sn_size) TESTASSERT_EQ(0, rlc2.get_buffer_state()); // Assert status is correct - rlc_am_nr_status_pdu_t status_check = {}; + rlc_am_nr_status_pdu_t status_check(sn_size); rlc_am_nr_read_status_pdu(&status_buf, sn_size, &status_check); TESTASSERT_EQ(5, status_check.ack_sn); // 5 is the next expected SN. TESTASSERT_EQ(2, status_check.nacks.size()); // We lost two PDU segments. @@ -1310,7 +1310,7 @@ int retx_segment_test(rlc_am_nr_sn_size_t sn_size) TESTASSERT_EQ(0, rlc2.get_buffer_state()); // Assert status is correct - rlc_am_nr_status_pdu_t status_check = {}; + rlc_am_nr_status_pdu_t status_check(sn_size); rlc_am_nr_read_status_pdu(&status_buf, sn_size, &status_check); TESTASSERT_EQ(1, status_check.ack_sn); // 1 is the next expected SN (i.e. the first lost packet.) @@ -1353,7 +1353,7 @@ int retx_segment_test(rlc_am_nr_sn_size_t sn_size) TESTASSERT_EQ(0, rlc2.get_buffer_state()); // Assert status is correct - rlc_am_nr_status_pdu_t status_check = {}; + rlc_am_nr_status_pdu_t status_check(sn_size); rlc_am_nr_read_status_pdu(&status_buf, sn_size, &status_check); TESTASSERT_EQ(2, status_check.ack_sn); // 5 is the next expected SN. TESTASSERT_EQ(1, status_check.nacks.size()); // We lost one PDU. @@ -1394,7 +1394,7 @@ int retx_segment_test(rlc_am_nr_sn_size_t sn_size) TESTASSERT_EQ(0, rlc2.get_buffer_state()); // Assert status is correct - rlc_am_nr_status_pdu_t status_check = {}; + rlc_am_nr_status_pdu_t status_check(sn_size); rlc_am_nr_read_status_pdu(&status_buf, sn_size, &status_check); TESTASSERT_EQ(5, status_check.ack_sn); // 5 is the next expected SN. TESTASSERT_EQ(3, status_check.nacks.size()); // We lost one PDU. @@ -1548,11 +1548,11 @@ int max_retx_lost_sdu_test(rlc_am_nr_sn_size_t sn_size) TESTASSERT(0 == rlc1.get_buffer_state()); // Fake status PDU that ack SN=1 and nack SN=0 - rlc_am_nr_status_pdu_t fake_status = {}; + rlc_am_nr_status_pdu_t fake_status(sn_size); fake_status.ack_sn = 2; // delivered up to SN=1 rlc_status_nack_t nack; // one SN was lost nack.nack_sn = 0; // it was SN=0 that was lost - fake_status.nacks.push_back(nack); + fake_status.push_nack(nack); // pack into PDU byte_buffer_t status_pdu; @@ -1629,8 +1629,8 @@ int max_retx_lost_segments_test(rlc_am_nr_sn_size_t sn_size) TESTASSERT(0 == rlc1.get_buffer_state()); // Fake status PDU that ack SN=1 and nack {SN=0 segment 0, SN=0 segment 1} - rlc_am_nr_status_pdu_t status_lost_both_segments = {}; - status_lost_both_segments.ack_sn = 2; // delivered up to SN=1 + rlc_am_nr_status_pdu_t status_lost_both_segments(sn_size); + status_lost_both_segments.ack_sn = 2; // delivered up to SN=1 // two segments lost { @@ -1639,7 +1639,7 @@ int max_retx_lost_segments_test(rlc_am_nr_sn_size_t sn_size) nack.has_so = true; // this NACKs a segment nack.so_start = 0; // segment starts at (and includes) byte 0 nack.so_end = 12; // segment ends at (and includes) byte 12 - status_lost_both_segments.nacks.push_back(nack); + status_lost_both_segments.push_nack(nack); } { @@ -1648,7 +1648,7 @@ int max_retx_lost_segments_test(rlc_am_nr_sn_size_t sn_size) nack.has_so = true; // this NACKs a segment nack.so_start = 13; // segment starts at (and includes) byte 13 nack.so_end = 19; // segment ends at (and includes) byte 19 - status_lost_both_segments.nacks.push_back(nack); + status_lost_both_segments.push_nack(nack); } // pack into PDU @@ -1657,8 +1657,8 @@ int max_retx_lost_segments_test(rlc_am_nr_sn_size_t sn_size) status_lost_both_segments, rlc_cfg.am_nr.tx_sn_field_length, &status_pdu_lost_both_segments); // Fake status PDU that ack SN=1 and nack {SN=0 segment 1} - rlc_am_nr_status_pdu_t status_lost_second_segment = {}; - status_lost_second_segment.ack_sn = 2; // delivered up to SN=1 + rlc_am_nr_status_pdu_t status_lost_second_segment(sn_size); + status_lost_second_segment.ack_sn = 2; // delivered up to SN=1 // one SN was lost { @@ -1667,7 +1667,7 @@ int max_retx_lost_segments_test(rlc_am_nr_sn_size_t sn_size) nack.has_so = true; // this NACKs a segment nack.so_start = 13; // segment starts at (and includes) byte 13 nack.so_end = 19; // segment ends at (and includes) byte 19 - status_lost_second_segment.nacks.push_back(nack); + status_lost_second_segment.push_nack(nack); } // pack into PDU @@ -1971,12 +1971,12 @@ int poll_retx() { unique_byte_buffer_t status_pdu = srsran::make_byte_buffer(); TESTASSERT(status_pdu != nullptr); - rlc_am_nr_status_pdu_t status = {}; + rlc_am_nr_status_pdu_t status(rlc_am_nr_sn_size_t::size12bits); status.ack_sn = 2; { rlc_status_nack_t nack; nack.nack_sn = 1; // SN=1 needs RETX - status.nacks.push_back(nack); + status.push_nack(nack); } rlc_am_nr_write_status_pdu(status, rlc_cnfg.am_nr.tx_sn_field_length, status_pdu.get()); rlc1.write_pdu(status_pdu->msg, status_pdu->N_bytes); @@ -2002,12 +2002,12 @@ int poll_retx() { unique_byte_buffer_t status_pdu = srsran::make_byte_buffer(); TESTASSERT(status_pdu != nullptr); - rlc_am_nr_status_pdu_t status = {}; + rlc_am_nr_status_pdu_t status(rlc_am_nr_sn_size_t::size12bits); status.ack_sn = 4; { rlc_status_nack_t nack; nack.nack_sn = 1; // SN=1 needs RETX - status.nacks.push_back(nack); + status.push_nack(nack); } rlc_am_nr_write_status_pdu(status, rlc_cnfg.am_nr.tx_sn_field_length, status_pdu.get()); rlc1.write_pdu(status_pdu->msg, status_pdu->N_bytes);