tbf_ul: Fix UL ACK not sent to MS if intermediate UL block is lost
In normal conditions ACKing of UL blocks is only sent every SEND_ACK_AFTER_FRAMES (20) frames. Which means if CV=0 is received (and hence no more packets are received) less than 20 frames before a lost, the PCU won't ask for a retransmission and wait there until some timer destroys the TBF. This issue is shown by TTCN3 test PCU_Tests.ttcn TC_ul_intermediate_retrans. Unit tests triggering this condition are adapted. Some similar tests are not triggering it because BSN/CV relation being used is totally wrong (like CV=0 being sent on a BSN with previous value than others). Change-Id: I9b4ef7b7277efa645bdb5becf2e9f6b32c99a9b1
This commit is contained in:
parent
5bb87b83d1
commit
c33a024d4a
|
@ -188,6 +188,9 @@ int gprs_rlcmac_ul_tbf::rcv_data_block_acknowledged(
|
|||
const struct gprs_rlc_data_info *rlc,
|
||||
uint8_t *data, struct pcu_l1_meas *meas)
|
||||
{
|
||||
const struct gprs_rlc_data_block_info *rdbi;
|
||||
struct gprs_rlc_data *block;
|
||||
|
||||
int8_t rssi = meas->have_rssi ? meas->rssi : 0;
|
||||
|
||||
const uint16_t ws = m_window.ws();
|
||||
|
@ -218,10 +221,8 @@ int gprs_rlcmac_ul_tbf::rcv_data_block_acknowledged(
|
|||
for (block_idx = 0; block_idx < rlc->num_data_blocks; block_idx++) {
|
||||
int num_chunks;
|
||||
uint8_t *rlc_data;
|
||||
const struct gprs_rlc_data_block_info *rdbi =
|
||||
&rlc->block_info[block_idx];
|
||||
rdbi = &rlc->block_info[block_idx];
|
||||
bool need_rlc_data = false;
|
||||
struct gprs_rlc_data *block;
|
||||
|
||||
LOGPTBFUL(this, LOGL_DEBUG,
|
||||
"Got %s RLC data block: CV=%d, BSN=%d, SPB=%d, PI=%d, E=%d, TI=%d, bitoffs=%d\n",
|
||||
|
@ -330,14 +331,13 @@ int gprs_rlcmac_ul_tbf::rcv_data_block_acknowledged(
|
|||
assemble_forward_llc(m_rlc.block(index));
|
||||
}
|
||||
|
||||
/* Check CV of last frame in buffer */
|
||||
/* Last frame in buffer: */
|
||||
block = m_rlc.block(m_window.mod_sns(m_window.v_r() - 1));
|
||||
rdbi = &block->block_info;
|
||||
|
||||
/* Check if we already received all data TBF had to send: */
|
||||
if (this->state_is(GPRS_RLCMAC_FLOW) /* still in flow state */
|
||||
&& this->m_window.v_q() == this->m_window.v_r()) { /* if complete */
|
||||
struct gprs_rlc_data *block =
|
||||
m_rlc.block(m_window.mod_sns(m_window.v_r() - 1));
|
||||
const struct gprs_rlc_data_block_info *rdbi =
|
||||
&block->block_info;
|
||||
|
||||
LOGPTBFUL(this, LOGL_DEBUG,
|
||||
"No gaps in received block, last block: BSN=%d CV=%d\n",
|
||||
rdbi->bsn, rdbi->cv);
|
||||
|
@ -351,13 +351,13 @@ int gprs_rlcmac_ul_tbf::rcv_data_block_acknowledged(
|
|||
|
||||
/* If TLLI is included or if we received half of the window, we send
|
||||
* an ack/nack */
|
||||
maybe_schedule_uplink_acknack(rlc);
|
||||
maybe_schedule_uplink_acknack(rlc, rdbi->cv == 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void gprs_rlcmac_ul_tbf::maybe_schedule_uplink_acknack(
|
||||
const gprs_rlc_data_info *rlc)
|
||||
const gprs_rlc_data_info *rlc, bool countdown_finished)
|
||||
{
|
||||
bool require_ack = false;
|
||||
bool have_ti = rlc->block_info[0].ti ||
|
||||
|
@ -373,10 +373,14 @@ void gprs_rlcmac_ul_tbf::maybe_schedule_uplink_acknack(
|
|||
LOGPTBFUL(this, LOGL_DEBUG,
|
||||
"Scheduling Ack/Nack, because TLLI is included.\n");
|
||||
}
|
||||
if (state_is(GPRS_RLCMAC_FINISHED)) {
|
||||
if (countdown_finished) {
|
||||
require_ack = true;
|
||||
LOGPTBFUL(this, LOGL_DEBUG,
|
||||
"Scheduling final Ack/Nack, because all data was received and last block has CV==0.\n");
|
||||
if (state_is(GPRS_RLCMAC_FLOW))
|
||||
LOGPTBFUL(this, LOGL_DEBUG,
|
||||
"Scheduling Ack/Nack, because some data is missing and last block has CV==0.\n");
|
||||
else if (state_is(GPRS_RLCMAC_FINISHED))
|
||||
LOGPTBFUL(this, LOGL_DEBUG,
|
||||
"Scheduling final Ack/Nack, because all data was received and last block has CV==0.\n");
|
||||
}
|
||||
if ((m_rx_counter % SEND_ACK_AFTER_FRAMES) == 0) {
|
||||
require_ack = true;
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "tbf.h"
|
||||
/*
|
||||
* TBF instance
|
||||
|
@ -97,7 +99,7 @@ struct gprs_rlcmac_ul_tbf : public gprs_rlcmac_tbf {
|
|||
struct rate_ctr_group *m_ul_egprs_ctrs;
|
||||
|
||||
protected:
|
||||
void maybe_schedule_uplink_acknack(const gprs_rlc_data_info *rlc);
|
||||
void maybe_schedule_uplink_acknack(const gprs_rlc_data_info *rlc, bool countdown_finished);
|
||||
|
||||
/* Please note that all variables below will be reset when changing
|
||||
* from WAIT RELEASE back to FLOW state (re-use of TBF).
|
||||
|
|
|
@ -1459,6 +1459,7 @@ static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_puan_URBB_with_length(BTS
|
|||
|
||||
pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
|
||||
pdch->rcv_block(&data[0], sizeof(data), *fn, &meas);
|
||||
ul_tbf->create_ul_ack(*fn, ts_no);
|
||||
|
||||
request_dl_rlc_block(ul_tbf, fn);
|
||||
|
||||
|
|
|
@ -7193,6 +7193,9 @@ TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) restarting timer T3169 [acked
|
|||
TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) Got MCS-4 RLC data block: CV=0, BSN=64, SPB=0, PI=0, E=1, TI=0, bitoffs=33
|
||||
TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) BSN 64 storing in window (1..192)
|
||||
TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) data_length=44, data=80 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95
|
||||
TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) Scheduling Ack/Nack, because some data is missing and last block has CV==0.
|
||||
TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) changes UL ACK state from GPRS_RLCMAC_UL_ACK_NONE to GPRS_RLCMAC_UL_ACK_SEND_ACK
|
||||
TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) changes UL ACK state from GPRS_RLCMAC_UL_ACK_SEND_ACK to GPRS_RLCMAC_UL_ACK_NONE
|
||||
Received RTS for PDCH: TRX=0 TS=7 FN=2654279 block_nr=10 scheduling USF=0 for required uplink resource of UL TFI=0
|
||||
TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN EGPRS) start Packet Downlink Assignment (PACCH)
|
||||
+++++++++++++++++++++++++ TX : Packet Downlink Assignment +++++++++++++++++++++++++
|
||||
|
|
Loading…
Reference in New Issue