lib,rlc_am_nr: extend status PDU struct with self-contained packed size info

This change refactors the rlc_am_nr_status_pdu_t from a simple
container into a class with integrated counter of the packed size.
As this depends on the SN length, the SN length must be passed
via constructor.
master
Robert Falkenberg 3 years ago
parent eec4a395d0
commit 489259dc78

@ -153,7 +153,6 @@ private:
std::unique_ptr<pdu_retx_queue_base<rlc_amd_retx_nr_t> > retx_queue; std::unique_ptr<pdu_retx_queue_base<rlc_amd_retx_nr_t> > retx_queue;
uint32_t sdu_under_segmentation_sn = INVALID_RLC_SN; // SN of the SDU currently being segmented. uint32_t sdu_under_segmentation_sn = INVALID_RLC_SN; // SN of the SDU currently being segmented.
pdcp_sn_vector_t notify_info_vec; pdcp_sn_vector_t notify_info_vec;
rlc_am_nr_status_pdu_t tx_status;
// Helper constants // Helper constants
uint32_t min_hdr_size = 2; uint32_t min_hdr_size = 2;

@ -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_) {} 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) ///< AM NR Status PDU header
struct rlc_am_nr_status_pdu_t { class 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 private:
std::vector<rlc_status_nack_t> nacks; rlc_am_nr_sn_size_t sn_size; ///< Stored SN size required to compute the packed size
std::vector<rlc_status_nack_t> nacks_; ///< Internal NACK container; keep in sync with packed_size_
rlc_am_nr_status_pdu_t() : cpt(rlc_am_nr_control_pdu_type_t::status_pdu), ack_sn(INVALID_RLC_SN), nacks(0) uint32_t packed_size_; ///< Stores the current packed size; sync on each change of nacks_
{
nacks.reserve(RLC_AM_NR_TYP_NACKS); void refresh_packed_size();
}
void reset() public:
{ rlc_am_nr_control_pdu_type_t cpt; ///< CPT header
cpt = rlc_am_nr_control_pdu_type_t::status_pdu; uint32_t ack_sn; ///< SN of the next not received RLC Data PDU
ack_sn = INVALID_RLC_SN; const std::vector<rlc_status_nack_t>& nacks; ///< Read-only reference to NACKs
nacks.clear(); 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<rlc_status_nack_t>& 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); 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 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); 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);

@ -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) 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); RlcInfo("generating status PDU. Bytes available:%d", nof_bytes);
tx_status.reset(); rlc_am_nr_status_pdu_t status(cfg.rx_sn_field_length); // carries status of RX entity, hence use SN length of RX
int pdu_len = rx->get_status_pdu(&tx_status, nof_bytes); status.reset();
int pdu_len = rx->get_status_pdu(&status, nof_bytes);
if (pdu_len == SRSRAN_ERROR) { if (pdu_len == SRSRAN_ERROR) {
RlcDebug("deferred status PDU. Cause: Failed to acquire rx lock"); RlcDebug("deferred status PDU. Cause: Failed to acquire rx lock");
pdu_len = 0; pdu_len = 0;
} else if (pdu_len > 0 && nof_bytes >= static_cast<uint32_t>(pdu_len)) { } else if (pdu_len > 0 && nof_bytes >= static_cast<uint32_t>(pdu_len)) {
RlcDebug("generated status PDU. Bytes:%d", 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); 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(tx_status, cfg.tx_sn_field_length, payload); pdu_len = rlc_am_nr_write_status_pdu(status, cfg.tx_sn_field_length, payload);
} else { } else {
RlcInfo("cannot tx status PDU - %d bytes available, %d bytes required", nof_bytes, pdu_len); RlcInfo("cannot tx status PDU - %d bytes available, %d bytes required", nof_bytes, pdu_len);
pdu_len = 0; 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<std::mutex> lock(mutex); std::lock_guard<std::mutex> 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); 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); 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); 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<std::mutex> lock(mutex, std::try_to_lock); std::unique_lock<std::mutex> lock(mutex, std::try_to_lock);
if (not lock.owns_lock()) { if (not lock.owns_lock()) {
return 0; return SRSRAN_ERROR;
} }
status->nacks.clear(); status->reset();
status->ack_sn = st.rx_next; // Start with the lower end of the window
byte_buffer_t tmp_buf; 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 { } else {
if (not rx_window->has_sn(i)) { if (not rx_window->has_sn(i)) {
// No segment received, NACK the whole SDU // 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; rlc_status_nack_t nack;
nack.nack_sn = i; nack.nack_sn = i;
nack.has_so = false; nack.has_so = false;
status->nacks.push_back(nack); status->push_nack(nack);
} else if (not(*rx_window)[i].fully_received) { } else if (not(*rx_window)[i].fully_received) {
// Some segments were received, but not all. // Some segments were received, but not all.
// NACK non consecutive missing bytes // 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; uint32_t last_so = 0;
bool last_segment_rx = false; bool last_segment_rx = false;
for (auto segm = (*rx_window)[i].segments.begin(); segm != (*rx_window)[i].segments.end(); segm++) { 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.has_so = true;
nack.so_start = last_so; nack.so_start = last_so;
nack.so_end = segm->header.so - 1; // set to last missing byte 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", RlcDebug("First/middle segment missing. NACK_SN=%d. SO_start=%d, SO_end=%d",
nack.nack_sn, nack.nack_sn,
nack.so_start, 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_segment_rx = true;
} }
last_so = segm->header.so + segm->buf->N_bytes; last_so = segm->header.so + segm->buf->N_bytes;
} } // Segment loop
if (not last_segment_rx) { if (not last_segment_rx) {
rlc_status_nack_t nack; rlc_status_nack_t nack;
nack.nack_sn = i; nack.nack_sn = i;
nack.has_so = true; nack.has_so = true;
nack.so_start = last_so; nack.so_start = last_so;
nack.so_end = so_end_of_sdu; nack.so_end = so_end_of_sdu;
status->nacks.push_back(nack); status->push_nack(nack);
RlcDebug( RlcDebug(
"Final segment missing. NACK_SN=%d. SO_start=%d, SO_end=%d", nack.nack_sn, nack.so_start, nack.so_end); "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); 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() uint32_t rlc_am_nr_rx::get_status_pdu_length()
{ {
rlc_am_nr_status_pdu_t tmp_status; rlc_am_nr_status_pdu_t tmp_status(cfg.rx_sn_field_length);
return get_status_pdu(&tmp_status, UINT32_MAX); tmp_status.reset();
get_status_pdu(&tmp_status, UINT32_MAX);
return tmp_status.get_packed_size();
} }
bool rlc_am_nr_rx::get_do_status() bool rlc_am_nr_rx::get_do_status()

@ -15,6 +15,58 @@
namespace srsran { 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 * Header pack/unpack helper functions
* Ref: 3GPP TS 38.322 v15.3.0 Section 6.2.2.4 * 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); nack.nack_range = (*ptr);
ptr++; ptr++;
} }
status->nacks.push_back(nack); status->push_nack(nack);
if (uint32_t(ptr - payload) > nof_bytes) { if (uint32_t(ptr - payload) > nof_bytes) {
fprintf(stderr, "Malformed PDU, trying to read more bytes than it is available\n"); fprintf(stderr, "Malformed PDU, trying to read more bytes than it is available\n");
return 0; 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); nack.nack_range = (*ptr);
ptr++; ptr++;
} }
status->nacks.push_back(nack); status->push_nack(nack);
if (uint32_t(ptr - payload) > nof_bytes) { if (uint32_t(ptr - payload) > nof_bytes) {
fprintf(stderr, "Malformed PDU, trying to read more bytes than it is available\n"); fprintf(stderr, "Malformed PDU, trying to read more bytes than it is available\n");
return 0; return 0;

@ -233,7 +233,7 @@ int rlc_am_nr_control_pdu_12bit_sn_test1()
TESTASSERT(rlc_am_is_control_pdu(pdu.msg) == true); TESTASSERT(rlc_am_is_control_pdu(pdu.msg) == true);
// unpack PDU // 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(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.ack_sn == 2065);
TESTASSERT(status_pdu.nacks.size() == 0); 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); TESTASSERT(rlc_am_is_control_pdu(pdu.msg) == true);
// unpack PDU // 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(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.ack_sn == 2065);
TESTASSERT(status_pdu.nacks.size() == 1); 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); TESTASSERT(rlc_am_is_control_pdu(pdu.msg) == true);
// unpack PDU // 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(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.ack_sn == 2065);
TESTASSERT(status_pdu.nacks.size() == 2); 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); TESTASSERT(rlc_am_is_control_pdu(pdu.msg) == true);
// unpack PDU // 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(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.ack_sn == 2065);
TESTASSERT(status_pdu.nacks.size() == 2); 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); TESTASSERT(rlc_am_is_control_pdu(pdu.msg) == true);
// unpack PDU // 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); TESTASSERT(rlc_am_nr_read_status_pdu(&pdu, srsran::rlc_am_nr_sn_size_t::size12bits, &status_pdu) == 0);
return SRSRAN_SUCCESS; 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); TESTASSERT(rlc_am_is_control_pdu(pdu.msg) == true);
// unpack PDU // 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(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.ack_sn == 2065);
TESTASSERT(status_pdu.nacks.size() == 2); 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); TESTASSERT(rlc_am_is_control_pdu(pdu.msg) == true);
// unpack PDU // 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(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.ack_sn == 235929);
TESTASSERT(status_pdu.nacks.size() == 0); 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); TESTASSERT(rlc_am_is_control_pdu(pdu.msg) == true);
// unpack PDU // 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(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.ack_sn == 235929);
TESTASSERT(status_pdu.nacks.size() == 1); 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); TESTASSERT(rlc_am_is_control_pdu(pdu.msg) == true);
// unpack PDU // 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(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.ack_sn == 235929);
TESTASSERT(status_pdu.nacks.size() == 2); 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); TESTASSERT(rlc_am_is_control_pdu(pdu.msg) == true);
// unpack PDU // 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(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.ack_sn == 235929);
TESTASSERT(status_pdu.nacks.size() == 2); 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); TESTASSERT(rlc_am_is_control_pdu(pdu.msg) == true);
// unpack PDU // 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); TESTASSERT(rlc_am_nr_read_status_pdu(&pdu, srsran::rlc_am_nr_sn_size_t::size18bits, &status_pdu) == 0);
return SRSRAN_SUCCESS; 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); TESTASSERT(rlc_am_is_control_pdu(pdu.msg) == true);
// unpack PDU // 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(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.ack_sn == 200977);
TESTASSERT(status_pdu.nacks.size() == 2); TESTASSERT(status_pdu.nacks.size() == 2);

@ -251,7 +251,7 @@ int basic_test(rlc_am_nr_sn_size_t sn_size)
TESTASSERT_EQ(0, rlc2.get_buffer_state()); TESTASSERT_EQ(0, rlc2.get_buffer_state());
// Assert status is correct // 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); 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. 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()); TESTASSERT(0 == rlc2.get_buffer_state());
// Assert status is correct // 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); 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.) 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()); TESTASSERT_EQ(0, rlc2.get_buffer_state());
// Assert status is correct // 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); 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(5, status_check.ack_sn); // 5 is the next expected SN.
TESTASSERT_EQ(1, status_check.nacks.size()); // We lost one PDU. 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()); TESTASSERT_EQ(0, rlc2.get_buffer_state());
// Assert status is correct // 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); 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(5, status_check.ack_sn); // 5 is the next expected SN.
TESTASSERT_EQ(0, status_check.nacks.size()); // All PDUs are acked now 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()); TESTASSERT(0 == rlc2.get_buffer_state());
// Assert status is correct // 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); 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.) 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()); TESTASSERT_EQ(0, rlc2.get_buffer_state());
// Assert status is correct // 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); 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(5, status_check.ack_sn); // 5 is the next expected SN.
TESTASSERT_EQ(1, status_check.nacks.size()); // We lost one PDU. 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()); TESTASSERT_EQ(0, rlc2.get_buffer_state());
// Assert status is correct // 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); 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(5, status_check.ack_sn); // 5 is the next expected SN.
TESTASSERT_EQ(0, status_check.nacks.size()); // All PDUs are acked now 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()); TESTASSERT_EQ(0, rlc2.get_buffer_state());
// Assert status is correct // 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); 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.) 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()); TESTASSERT_EQ(0, rlc2.get_buffer_state());
// Assert status is correct // 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); 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(5, status_check.ack_sn); // 5 is the next expected SN.
TESTASSERT_EQ(1, status_check.nacks.size()); // We lost one PDU. 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()); TESTASSERT_EQ(0, rlc2.get_buffer_state());
// Assert status is correct // 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); 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.) 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()); TESTASSERT_EQ(0, rlc2.get_buffer_state());
// Assert status is correct // 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); 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(5, status_check.ack_sn); // 5 is the next expected SN.
TESTASSERT_EQ(1, status_check.nacks.size()); // We lost one PDU. 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()); TESTASSERT_EQ(0, rlc2.get_buffer_state());
// Assert status is correct // 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); 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(5, status_check.ack_sn); // 5 is the next expected SN.
TESTASSERT_EQ(2, status_check.nacks.size()); // We lost two PDU segments. 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()); TESTASSERT_EQ(0, rlc2.get_buffer_state());
// Assert status is correct // 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); 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.) 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()); TESTASSERT_EQ(0, rlc2.get_buffer_state());
// Assert status is correct // 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); 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(2, status_check.ack_sn); // 5 is the next expected SN.
TESTASSERT_EQ(1, status_check.nacks.size()); // We lost one PDU. 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()); TESTASSERT_EQ(0, rlc2.get_buffer_state());
// Assert status is correct // 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); 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(5, status_check.ack_sn); // 5 is the next expected SN.
TESTASSERT_EQ(3, status_check.nacks.size()); // We lost one PDU. 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()); TESTASSERT(0 == rlc1.get_buffer_state());
// Fake status PDU that ack SN=1 and nack SN=0 // 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 fake_status.ack_sn = 2; // delivered up to SN=1
rlc_status_nack_t nack; // one SN was lost rlc_status_nack_t nack; // one SN was lost
nack.nack_sn = 0; // it was SN=0 that 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 // pack into PDU
byte_buffer_t status_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()); TESTASSERT(0 == rlc1.get_buffer_state());
// Fake status PDU that ack SN=1 and nack {SN=0 segment 0, SN=0 segment 1} // 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 = {}; rlc_am_nr_status_pdu_t status_lost_both_segments(sn_size);
status_lost_both_segments.ack_sn = 2; // delivered up to SN=1 status_lost_both_segments.ack_sn = 2; // delivered up to SN=1
// two segments lost // 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.has_so = true; // this NACKs a segment
nack.so_start = 0; // segment starts at (and includes) byte 0 nack.so_start = 0; // segment starts at (and includes) byte 0
nack.so_end = 12; // segment ends at (and includes) byte 12 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.has_so = true; // this NACKs a segment
nack.so_start = 13; // segment starts at (and includes) byte 13 nack.so_start = 13; // segment starts at (and includes) byte 13
nack.so_end = 19; // segment ends at (and includes) byte 19 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 // 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); 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} // Fake status PDU that ack SN=1 and nack {SN=0 segment 1}
rlc_am_nr_status_pdu_t status_lost_second_segment = {}; rlc_am_nr_status_pdu_t status_lost_second_segment(sn_size);
status_lost_second_segment.ack_sn = 2; // delivered up to SN=1 status_lost_second_segment.ack_sn = 2; // delivered up to SN=1
// one SN was lost // 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.has_so = true; // this NACKs a segment
nack.so_start = 13; // segment starts at (and includes) byte 13 nack.so_start = 13; // segment starts at (and includes) byte 13
nack.so_end = 19; // segment ends at (and includes) byte 19 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 // pack into PDU
@ -1971,12 +1971,12 @@ int poll_retx()
{ {
unique_byte_buffer_t status_pdu = srsran::make_byte_buffer(); unique_byte_buffer_t status_pdu = srsran::make_byte_buffer();
TESTASSERT(status_pdu != nullptr); 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; status.ack_sn = 2;
{ {
rlc_status_nack_t nack; rlc_status_nack_t nack;
nack.nack_sn = 1; // SN=1 needs RETX 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()); 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); 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(); unique_byte_buffer_t status_pdu = srsran::make_byte_buffer();
TESTASSERT(status_pdu != nullptr); 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; status.ack_sn = 4;
{ {
rlc_status_nack_t nack; rlc_status_nack_t nack;
nack.nack_sn = 1; // SN=1 needs RETX 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()); 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); rlc1.write_pdu(status_pdu->msg, status_pdu->N_bytes);

Loading…
Cancel
Save