mirror of https://github.com/PentHertz/srsLTE.git
rlc_am_lte: fix handling of maxretx
this patch fixes the actions/handling after RLC detected maxRetx reached for a given SN. According to the TS, RLC should only inform upper layers and not try to recover from the event itself. As a consequence, we won't manipulate the Tx or Rx window. As a result of this, we might retransmit a SN more than the specified amount of times. It's the task of RRC to reestablish the bearer to recover from that.
This commit is contained in:
parent
44e7d41f57
commit
ceacf8508d
|
@ -293,7 +293,7 @@ private:
|
|||
// Helpers
|
||||
bool poll_required();
|
||||
bool do_status();
|
||||
bool sn_reached_max_retx(uint32_t sn);
|
||||
void check_sn_reached_max_retx(uint32_t sn);
|
||||
|
||||
rlc_am_lte* parent = nullptr;
|
||||
byte_buffer_pool* pool = nullptr;
|
||||
|
|
|
@ -290,41 +290,19 @@ bool rlc_am_lte::rlc_am_lte_tx::has_data()
|
|||
* Helper to check if a SN has reached the max reTx threshold
|
||||
*
|
||||
* Caller _must_ hold the mutex when calling the function.
|
||||
* If the retx has been reached for a SN. The SN is removed from the Tx window
|
||||
* and the RLC am state variables are advanced.
|
||||
* If the retx has been reached for a SN the upper layers (i.e. RRC/PDCP) will be informed.
|
||||
* The SN is _not_ removed from the Tx window, so retransmissions of that SN can still occur.
|
||||
*
|
||||
* @param sn The SN of the PDU to check
|
||||
* @return True if the max_retx counter has been reached and the SN has been removed, false otherwise
|
||||
*/
|
||||
bool rlc_am_lte::rlc_am_lte_tx::sn_reached_max_retx(uint32_t sn)
|
||||
void rlc_am_lte::rlc_am_lte_tx::check_sn_reached_max_retx(uint32_t sn)
|
||||
{
|
||||
if (tx_window[sn].retx_count >= cfg.max_retx_thresh) {
|
||||
if (tx_window[sn].retx_count == cfg.max_retx_thresh) {
|
||||
logger.warning("%s Signaling max number of reTx=%d for for SN=%d", RB_NAME, tx_window[sn].retx_count, sn);
|
||||
parent->rrc->max_retx_attempted();
|
||||
parent->pdcp->notify_failure(parent->lcid, tx_window[sn].pdcp_sns);
|
||||
parent->metrics.num_lost_pdus++;
|
||||
|
||||
// remove SN from Tx window
|
||||
tx_window.remove_pdu(sn);
|
||||
|
||||
// advance window if this is was the lowest SN we've been waiting for
|
||||
if (sn == vt_a) {
|
||||
vt_a = (vt_a + 1) % MOD;
|
||||
vt_ms = (vt_ms + 1) % MOD;
|
||||
|
||||
// Advance vt_a to the smallest SN for which ACK has not been received yet (Sec 5.1.3.1.1)
|
||||
while (TX_MOD_BASE(vt_a) < TX_MOD_BASE(vt_s) && !tx_window.has_sn(vt_a)) {
|
||||
logger.warning("SN=%d has already been removed, advance window vt_s=%d", vt_a, vt_s);
|
||||
vt_a = (vt_a + 1) % MOD;
|
||||
vt_ms = (vt_ms + 1) % MOD;
|
||||
}
|
||||
} else {
|
||||
logger.warning("Don't advance window sn=%d not vt_a=%d", sn, vt_a);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t rlc_am_lte::rlc_am_lte_tx::get_buffer_state()
|
||||
|
@ -664,9 +642,7 @@ int rlc_am_lte::rlc_am_lte_tx::build_retx_pdu(uint8_t* payload, uint32_t nof_byt
|
|||
|
||||
retx_queue.pop();
|
||||
tx_window[retx.sn].retx_count++;
|
||||
if (sn_reached_max_retx(retx.sn)) {
|
||||
return 0;
|
||||
}
|
||||
check_sn_reached_max_retx(retx.sn);
|
||||
|
||||
logger.info(payload,
|
||||
tx_window[retx.sn].buf->N_bytes,
|
||||
|
@ -830,10 +806,7 @@ int rlc_am_lte::rlc_am_lte_tx::build_segment(uint8_t* payload, uint32_t nof_byte
|
|||
tx_window[retx.sn].retx_count++;
|
||||
}
|
||||
|
||||
// Check max reTx counter and abort building segment if it passed the threshold
|
||||
if (sn_reached_max_retx(retx.sn)) {
|
||||
return 0;
|
||||
}
|
||||
check_sn_reached_max_retx(retx.sn);
|
||||
|
||||
// Write header and pdu
|
||||
uint8_t* ptr = payload;
|
||||
|
|
Loading…
Reference in New Issue