mirror of https://github.com/PentHertz/srsLTE.git
fix RLC AM issue where an invalid status PDU was generated
happens when very small grant is provided and the status PDU generation fails because of a too small grant add extra check to prevent that ACK_SN is also in NACKS list
This commit is contained in:
parent
a166b3c2d9
commit
f07a9277a0
|
@ -306,6 +306,7 @@ int rlc_am_write_status_pdu(rlc_status_pdu_t *status, uint8_t *payload);
|
|||
uint32_t rlc_am_packed_length(rlc_amd_pdu_header_t *header);
|
||||
uint32_t rlc_am_packed_length(rlc_status_pdu_t *status);
|
||||
uint32_t rlc_am_packed_length(rlc_amd_retx_t retx);
|
||||
bool rlc_am_is_valid_status_pdu(const rlc_status_pdu_t& status);
|
||||
bool rlc_am_is_control_pdu(byte_buffer_t *pdu);
|
||||
bool rlc_am_is_control_pdu(uint8_t *payload);
|
||||
bool rlc_am_is_pdu_segment(uint8_t *payload);
|
||||
|
@ -318,5 +319,4 @@ bool rlc_am_not_start_aligned(const uint8_t fi);
|
|||
|
||||
} // namespace srslte
|
||||
|
||||
|
||||
#endif // SRSLTE_RLC_AM_H
|
||||
|
|
|
@ -154,7 +154,7 @@ struct rlc_status_nack_t{
|
|||
|
||||
// STATUS PDU
|
||||
struct rlc_status_pdu_t{
|
||||
uint16_t ack_sn;
|
||||
uint16_t ack_sn; // SN of the next not received RLC Data PDU
|
||||
uint32_t N_nack;
|
||||
rlc_status_nack_t nacks[RLC_AM_WINDOW_SIZE];
|
||||
|
||||
|
|
|
@ -1629,6 +1629,14 @@ int rlc_am::rlc_am_rx::get_status_pdu(rlc_status_pdu_t* status, const uint32_t m
|
|||
if (status->N_nack >= 1) {
|
||||
log->debug("Removing last NACK SN=%d\n", status->nacks[status->N_nack].nack_sn);
|
||||
status->N_nack--;
|
||||
// make sure we don't have the current ACK_SN in the NACK list
|
||||
if (rlc_am_is_valid_status_pdu(*status) == false) {
|
||||
// No space to send any NACKs
|
||||
log->debug("Resetting N_nack to zero\n");
|
||||
status->N_nack = 0;
|
||||
}
|
||||
} else {
|
||||
log->error("Failed to generate small enough status PDU\n");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -2024,6 +2032,16 @@ int rlc_am_write_status_pdu(rlc_status_pdu_t *status, uint8_t *payload)
|
|||
return tmp.N_bits/8;
|
||||
}
|
||||
|
||||
bool rlc_am_is_valid_status_pdu(const rlc_status_pdu_t& status)
|
||||
{
|
||||
for (uint16_t i = 0; i < status.N_nack; ++i) {
|
||||
if (status.nacks[i].nack_sn == status.ack_sn) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t rlc_am_packed_length(rlc_amd_pdu_header_t *header)
|
||||
{
|
||||
uint32_t len = 2; // Fixed part is 2 bytes
|
||||
|
|
|
@ -1586,11 +1586,18 @@ bool status_pdu_test()
|
|||
|
||||
// Read status PDU from RLC2
|
||||
byte_buffer_t status_buf;
|
||||
len = rlc2.read_pdu(status_buf.msg, 3); // provide only small grant
|
||||
len = rlc2.read_pdu(status_buf.msg, 5); // provide only small grant
|
||||
status_buf.N_bytes = len;
|
||||
|
||||
assert(status_buf.N_bytes != 0);
|
||||
|
||||
// check status PDU doesn't contain ACK_SN in NACK list
|
||||
rlc_status_pdu_t status_pdu = {};
|
||||
rlc_am_read_status_pdu(status_buf.msg, status_buf.N_bytes, &status_pdu);
|
||||
if (rlc_am_is_valid_status_pdu(status_pdu) == false) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Write status PDU to RLC1
|
||||
rlc1.write_pdu(status_buf.msg, status_buf.N_bytes);
|
||||
|
||||
|
|
Loading…
Reference in New Issue