lib,rlc_am_nr: Added assert to check SO_start <= SO_end

master
Pedro Alvarez 3 years ago
parent 7f7656e200
commit 865dfe87e7

@ -780,6 +780,7 @@ void rlc_am_nr_tx::handle_control_pdu(uint8_t* payload, uint32_t nof_bytes)
break; break;
} }
} }
RlcDebug("Processed status report ACKs. ACK_SN=%d. Tx_Next_Ack=%d", status.ack_sn, st.tx_next_ack);
// Notify PDCP // Notify PDCP
if (not notify_info_vec.empty()) { if (not notify_info_vec.empty()) {
@ -796,8 +797,9 @@ void rlc_am_nr_tx::handle_control_pdu(uint8_t* payload, uint32_t nof_bytes)
status.nacks[nack_idx].nack_sn); status.nacks[nack_idx].nack_sn);
continue; continue;
} }
RlcDebug("Handling NACK for SN=%d", status.nacks[nack_idx].nack_sn); if (tx_mod_base_nr(st.tx_next_ack) <= tx_mod_base_nr(status.nacks[nack_idx].nack_sn) &&
if (st.tx_next_ack <= status.nacks[nack_idx].nack_sn && status.nacks[nack_idx].nack_sn <= st.tx_next) { tx_mod_base_nr(status.nacks[nack_idx].nack_sn) <= tx_mod_base_nr(st.tx_next)) {
RlcDebug("Handling NACK for SN=%d", status.nacks[nack_idx].nack_sn);
auto nack = status.nacks[nack_idx]; auto nack = status.nacks[nack_idx];
uint32_t nack_sn = nack.nack_sn; uint32_t nack_sn = nack.nack_sn;
if (tx_window->has_sn(nack_sn)) { if (tx_window->has_sn(nack_sn)) {
@ -1401,13 +1403,16 @@ uint32_t rlc_am_nr_rx::get_status_pdu(rlc_am_nr_status_pdu_t* status, uint32_t m
* starting with SN = RX_Next up to the point where the resulting STATUS PDU still fits to the total size of RLC * starting with SN = RX_Next up to the point where the resulting STATUS PDU still fits to the total size of RLC
* PDU(s) indicated by lower layer: * PDU(s) indicated by lower layer:
*/ */
RlcDebug("Generating status PDU");
for (uint32_t i = st.rx_next; rx_mod_base_nr(i) < rx_mod_base_nr(st.rx_highest_status); i = (i + 1) % mod_nr) { for (uint32_t i = st.rx_next; rx_mod_base_nr(i) < rx_mod_base_nr(st.rx_highest_status); i = (i + 1) % mod_nr) {
if ((rx_window->has_sn(i) && (*rx_window)[i].fully_received)) { if ((rx_window->has_sn(i) && (*rx_window)[i].fully_received)) {
// only update ACK_SN if this SN has been fully received // only update ACK_SN if this SN has been fully received
status->ack_sn = i; status->ack_sn = i;
RlcDebug("Updating ACK_SN. ACK_SN=%d", i);
} 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);
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;
@ -1415,6 +1420,7 @@ uint32_t rlc_am_nr_rx::get_status_pdu(rlc_am_nr_status_pdu_t* status, uint32_t m
} 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);
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++) {
@ -1426,6 +1432,11 @@ uint32_t rlc_am_nr_rx::get_status_pdu(rlc_am_nr_status_pdu_t* status, uint32_t m
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->nacks.push_back(nack);
RlcDebug("First/middle 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);
} }
if (segm->header.si == rlc_nr_si_field_t::last_segment) { if (segm->header.si == rlc_nr_si_field_t::last_segment) {
last_segment_rx = true; last_segment_rx = true;
@ -1439,6 +1450,9 @@ uint32_t rlc_am_nr_rx::get_status_pdu(rlc_am_nr_status_pdu_t* status, uint32_t m
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->nacks.push_back(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);
} }
} }
} }
@ -1507,6 +1521,10 @@ void rlc_am_nr_rx::timer_expired(uint32_t timeout_id)
} }
} }
st.rx_highest_status = sn_upd; st.rx_highest_status = sn_upd;
if (not inside_rx_window(st.rx_highest_status)) {
RlcError("Rx_Highest_Status not inside RX window");
debug_state();
}
srsran_assert(inside_rx_window(st.rx_highest_status), "Error: rx_highest_status assigned outside rx window"); srsran_assert(inside_rx_window(st.rx_highest_status), "Error: rx_highest_status assigned outside rx window");
bool restart_reassembly_timer = false; bool restart_reassembly_timer = false;

Loading…
Cancel
Save