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_amd_pdu_header_t *header);
|
||||||
uint32_t rlc_am_packed_length(rlc_status_pdu_t *status);
|
uint32_t rlc_am_packed_length(rlc_status_pdu_t *status);
|
||||||
uint32_t rlc_am_packed_length(rlc_amd_retx_t retx);
|
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(byte_buffer_t *pdu);
|
||||||
bool rlc_am_is_control_pdu(uint8_t *payload);
|
bool rlc_am_is_control_pdu(uint8_t *payload);
|
||||||
bool rlc_am_is_pdu_segment(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
|
} // namespace srslte
|
||||||
|
|
||||||
|
|
||||||
#endif // SRSLTE_RLC_AM_H
|
#endif // SRSLTE_RLC_AM_H
|
||||||
|
|
|
@ -154,7 +154,7 @@ struct rlc_status_nack_t{
|
||||||
|
|
||||||
// STATUS PDU
|
// STATUS PDU
|
||||||
struct rlc_status_pdu_t{
|
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;
|
uint32_t N_nack;
|
||||||
rlc_status_nack_t nacks[RLC_AM_WINDOW_SIZE];
|
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) {
|
if (status->N_nack >= 1) {
|
||||||
log->debug("Removing last NACK SN=%d\n", status->nacks[status->N_nack].nack_sn);
|
log->debug("Removing last NACK SN=%d\n", status->nacks[status->N_nack].nack_sn);
|
||||||
status->N_nack--;
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -2024,6 +2032,16 @@ int rlc_am_write_status_pdu(rlc_status_pdu_t *status, uint8_t *payload)
|
||||||
return tmp.N_bits/8;
|
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 rlc_am_packed_length(rlc_amd_pdu_header_t *header)
|
||||||
{
|
{
|
||||||
uint32_t len = 2; // Fixed part is 2 bytes
|
uint32_t len = 2; // Fixed part is 2 bytes
|
||||||
|
|
|
@ -1586,11 +1586,18 @@ bool status_pdu_test()
|
||||||
|
|
||||||
// Read status PDU from RLC2
|
// Read status PDU from RLC2
|
||||||
byte_buffer_t status_buf;
|
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;
|
status_buf.N_bytes = len;
|
||||||
|
|
||||||
assert(status_buf.N_bytes != 0);
|
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
|
// Write status PDU to RLC1
|
||||||
rlc1.write_pdu(status_buf.msg, status_buf.N_bytes);
|
rlc1.write_pdu(status_buf.msg, status_buf.N_bytes);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue