aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Eversberg <jolly@eversberg.eu>2012-10-07 15:50:51 +0200
committerAndreas Eversberg <jolly@eversberg.eu>2012-12-18 10:02:58 +0100
commit0c9b50c4986d13518d0b3c2e1230b9ea79ad2c16 (patch)
tree2f7cd6e4a8e044a39d2cb5f73256cf7d1dafff14
parentaafcd703f341c7dc8a56ff45ba1823470dd5ff00 (diff)
Fix: Handling of final acknowledge on downlink TBFs
It is essential to initialize the first_fin_ack variable. Also it is essential not to free TBF, in case the final ack is not received, but all frames have been acked. In this special case, we resend the final block again and again (and poll), until we receive the final ack.
-rw-r--r--src/gprs_rlcmac_data.cpp21
1 files changed, 11 insertions, 10 deletions
diff --git a/src/gprs_rlcmac_data.cpp b/src/gprs_rlcmac_data.cpp
index c52af14..dca3f0c 100644
--- a/src/gprs_rlcmac_data.cpp
+++ b/src/gprs_rlcmac_data.cpp
@@ -1245,7 +1245,7 @@ struct msgb *gprs_rlcmac_send_data_block_acknowledged(
uint8_t *delimiter, *data, *e_pointer;
uint8_t len;
uint16_t space, chunk;
- int first_fin_ack;
+ int first_fin_ack = 0;
LOGP(DRLCMACDL, LOGL_DEBUG, "DL DATA TBF=%d downlink (V(A)==%d .. "
"V(S)==%d)\n", tbf->tfi, tbf->dir.dl.v_a, tbf->dir.dl.v_s);
@@ -1286,8 +1286,8 @@ do_resend:
* indication from MS. This should never happen if MS works
* correctly. */
if (tbf->dir.dl.v_s == tbf->dir.dl.v_a) {
- LOGP(DRLCMACDL, LOGL_ERROR, "- MS acked all block, "
- "but we still transmitting!\n");
+ LOGP(DRLCMACDL, LOGL_DEBUG, "- MS acked all blocks, "
+ "so we re-transmit final block!\n");
/* we just send final block again */
index = ((tbf->dir.dl.v_s - 1) & mod_sns_half);
goto tx_block;
@@ -1633,15 +1633,16 @@ int gprs_rlcmac_downlink_ack(struct gprs_rlcmac_tbf *tbf, uint8_t final,
if (tbf->state == GPRS_RLCMAC_FINISHED
&& tbf->dir.dl.v_s == tbf->dir.dl.v_a) {
- LOGP(DRLCMACDL, LOGL_NOTICE, "Received final block, "
- "but without final ack inidcation\n");
- } else
- return 0;
- } else {
- LOGP(DRLCMACDL, LOGL_DEBUG, "- Final ACK received.\n");
- debug_diagram(tbf->diag, "got Final ACK");
+ LOGP(DRLCMACDL, LOGL_NOTICE, "Received acknowledge of "
+ "all blocks, but without final ack "
+ "inidcation (don't worry)\n");
+ }
+ return 0;
}
+ LOGP(DRLCMACDL, LOGL_DEBUG, "- Final ACK received.\n");
+ debug_diagram(tbf->diag, "got Final ACK");
+
/* check for LLC PDU in the LLC Queue */
msg = llc_dequeue(tbf);
if (!msg) {