diff --git a/lib/src/upper/rlc_am_lte.cc b/lib/src/upper/rlc_am_lte.cc index dcbf335bd..6c04c3fca 100644 --- a/lib/src/upper/rlc_am_lte.cc +++ b/lib/src/upper/rlc_am_lte.cc @@ -1670,13 +1670,13 @@ int rlc_am_lte::rlc_am_lte_rx::get_status_pdu(rlc_status_pdu_t* status, const ui // We don't use segment NACKs - just NACK the full PDU uint32_t i = vr_r; - while (RX_MOD_BASE(i) < RX_MOD_BASE(vr_ms) && status->N_nack < RLC_AM_WINDOW_SIZE) { - if (rx_window.find(i) == rx_window.end()) { + while (RX_MOD_BASE(i) <= RX_MOD_BASE(vr_ms) && status->N_nack < RLC_AM_WINDOW_SIZE) { + if (rx_window.find(i) != rx_window.end() || i == vr_ms) { + // only update ACK_SN if this SN has been received, or if we reached the maximum possible SN + status->ack_sn = i; + } else { status->nacks[status->N_nack].nack_sn = i; status->N_nack++; - } else { - // only update ACK_SN if this SN has been received - status->ack_sn = i; } // make sure we don't exceed grant size diff --git a/lib/test/upper/rlc_am_test.cc b/lib/test/upper/rlc_am_test.cc index 6ad587a9d..667df51fa 100644 --- a/lib/test/upper/rlc_am_test.cc +++ b/lib/test/upper/rlc_am_test.cc @@ -173,6 +173,11 @@ bool basic_test() assert(0 == rlc2.get_buffer_state()); + // Assert status is correct + rlc_status_pdu_t status_check = {}; + rlc_am_read_status_pdu(status_buf.msg, status_buf.N_bytes, &status_check); + TESTASSERT(status_check.ack_sn == 5); // 5 is the last SN that was not received. + // Write status PDU to RLC1 rlc1.write_pdu(status_buf.msg, status_buf.N_bytes); @@ -225,7 +230,21 @@ bool concat_test() // Write PDU into RLC2 rlc2.write_pdu(pdu_buf.msg, pdu_buf.N_bytes); - // No status report as we haven't crossed polling thresholds + // Check status report + TESTASSERT(2 == rlc2.get_buffer_state()); + byte_buffer_t status_buf; + len = rlc2.read_pdu(status_buf.msg, 2); + status_buf.N_bytes = len; + + TESTASSERT(0 == rlc2.get_buffer_state()); + + // Assert status is correct + rlc_status_pdu_t status_check = {}; + rlc_am_read_status_pdu(status_buf.msg, status_buf.N_bytes, &status_check); + TESTASSERT(status_check.ack_sn == 1); // 1 is the last SN that was not received. + + // Write status PDU to RLC1 + rlc1.write_pdu(status_buf.msg, status_buf.N_bytes); assert(tester.n_sdus == 5); for (int i = 0; i < tester.n_sdus; i++) { @@ -302,6 +321,11 @@ bool segment_test(bool in_seq_rx) len = rlc2.read_pdu(status_buf.msg, 10); // 10 bytes is enough to hold the status status_buf.N_bytes = len; + // Assert status is correct + rlc_status_pdu_t status_check = {}; + rlc_am_read_status_pdu(status_buf.msg, status_buf.N_bytes, &status_check); + TESTASSERT(status_check.ack_sn == n_pdus); // n_pdus (8) is the last SN that was not received. + // Write status PDU to RLC1 rlc1.write_pdu(status_buf.msg, status_buf.N_bytes); } @@ -383,6 +407,16 @@ bool retx_test() len = rlc2.read_pdu(status_buf.msg, buffer_state); // provide exactly the reported buffer state status_buf.N_bytes = len; + // Assert all bytes for status PDU were read + buffer_state = rlc2.get_buffer_state(); + TESTASSERT(0 == buffer_state); + + // Assert status is correct + rlc_status_pdu_t status_check = {}; + rlc_am_read_status_pdu(status_buf.msg, status_buf.N_bytes, &status_check); + TESTASSERT(status_check.N_nack == 1); // 1 packet was lost. + TESTASSERT(status_check.ack_sn == 5); // Delivered up to SN 4. + // Write status PDU to RLC1 rlc1.write_pdu(status_buf.msg, status_buf.N_bytes); @@ -433,7 +467,7 @@ bool segment_retx_test() for (uint32_t i = 0; i < nof_sdus; i++) { sdu_bufs[i] = srslte::allocate_unique_buffer(*pool, true); sdu_bufs[i]->msg[0] = i; // Write the index into the buffer - sdu_bufs[i]->N_bytes = 10; // Give each buffer a size of 1 byte + sdu_bufs[i]->N_bytes = 10; // Give each buffer a size of 10 bytes rlc1.write_sdu(std::move(sdu_bufs[i])); }