Avoid re-assigning DL TBF over PACCH upon duplicate FinalACKs received
Due to the fn-advance feature, we schedule DL blocks in advance, which
may make several retransmitted DL ACK/NACK [RRBP] be in flight, and
hence several of them may be answered by the MS.
When the first one is received, we attempt to initiate a PktDlAss over
PACCH if new DL data was received meanwhile from SGSN.
However, if we receive duplicates of that final PKT CTRL ACK, we don't
want to re-initiate it again, since it is already ongoing.
Related: OS#5471
Change-Id: Idc204aba61ad98f75853dcd46200f5dcc4139203
diff --git a/src/tbf_dl.cpp b/src/tbf_dl.cpp
index 40442c3..f4439d3 100644
--- a/src/tbf_dl.cpp
+++ b/src/tbf_dl.cpp
@@ -1053,9 +1053,7 @@
int gprs_rlcmac_dl_tbf::rcvd_dl_final_ack()
{
uint16_t received;
- int rc = 0;
-
- osmo_fsm_inst_dispatch(this->state_fi, TBF_EV_FINAL_ACK_RECVD, NULL);
+ int rc;
/* range V(A)..V(S)-1 */
received = m_window.count_unacked();
@@ -1064,10 +1062,7 @@
m_tx_counter = 0;
m_window.reset();
- /* check for LLC PDU in the LLC Queue */
- if (llc_queue_size(llc_queue()) > 0)
- /* we have more data so we will re-use this tbf */
- rc = ms_new_dl_tbf_assigned_on_pacch(ms(), dl_tbf_as_tbf(this));
+ rc = osmo_fsm_inst_dispatch(this->state_fi, TBF_EV_FINAL_ACK_RECVD, NULL);
return rc;
}
diff --git a/src/tbf_dl_fsm.c b/src/tbf_dl_fsm.c
index ba7fc5a..557fb7a 100644
--- a/src/tbf_dl_fsm.c
+++ b/src/tbf_dl_fsm.c
@@ -260,8 +260,10 @@
static void st_wait_release_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state)
{
struct tbf_dl_fsm_ctx *ctx = (struct tbf_dl_fsm_ctx *)fi->priv;
+ struct GprsMs *ms = tbf_ms(ctx->tbf);
- /* T3192 is running on the MS and has also been armed by this FSM now.
+ /* This state was entered because FinalACK was received; now T3192 is
+ * running on the MS and has also been armed by this FSM.
* During that time, it is possible to reach the MS over PACCH to assign
* new DL TBF.
* Upon T3192 expiration, FSM will transition to TBF_ST_WAIT_REUSE_TFI
@@ -270,6 +272,12 @@
*/
mod_ass_type(ctx, GPRS_RLCMAC_FLAG_CCCH, false);
+
+ /* check for LLC PDU in the LLC Queue */
+ if (llc_queue_size(ms_llc_queue(ms)) > 0) {
+ /* we have more data so we will re-use this tbf */
+ ms_new_dl_tbf_assigned_on_pacch(ms, ctx->tbf);
+ }
}
static void st_wait_release(struct osmo_fsm_inst *fi, uint32_t event, void *data)