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.
This commit is contained in:
Andreas Eversberg 2012-10-07 15:50:51 +02:00
parent aafcd703f3
commit 0c9b50c498
1 changed files with 11 additions and 10 deletions

View File

@ -1245,7 +1245,7 @@ struct msgb *gprs_rlcmac_send_data_block_acknowledged(
uint8_t *delimiter, *data, *e_pointer; uint8_t *delimiter, *data, *e_pointer;
uint8_t len; uint8_t len;
uint16_t space, chunk; 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 .. " 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); "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 * indication from MS. This should never happen if MS works
* correctly. */ * correctly. */
if (tbf->dir.dl.v_s == tbf->dir.dl.v_a) { if (tbf->dir.dl.v_s == tbf->dir.dl.v_a) {
LOGP(DRLCMACDL, LOGL_ERROR, "- MS acked all block, " LOGP(DRLCMACDL, LOGL_DEBUG, "- MS acked all blocks, "
"but we still transmitting!\n"); "so we re-transmit final block!\n");
/* we just send final block again */ /* we just send final block again */
index = ((tbf->dir.dl.v_s - 1) & mod_sns_half); index = ((tbf->dir.dl.v_s - 1) & mod_sns_half);
goto tx_block; 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 if (tbf->state == GPRS_RLCMAC_FINISHED
&& tbf->dir.dl.v_s == tbf->dir.dl.v_a) { && tbf->dir.dl.v_s == tbf->dir.dl.v_a) {
LOGP(DRLCMACDL, LOGL_NOTICE, "Received final block, " LOGP(DRLCMACDL, LOGL_NOTICE, "Received acknowledge of "
"but without final ack inidcation\n"); "all blocks, but without final ack "
} else "inidcation (don't worry)\n");
return 0; }
} else { return 0;
LOGP(DRLCMACDL, LOGL_DEBUG, "- Final ACK received.\n");
debug_diagram(tbf->diag, "got Final ACK");
} }
LOGP(DRLCMACDL, LOGL_DEBUG, "- Final ACK received.\n");
debug_diagram(tbf->diag, "got Final ACK");
/* check for LLC PDU in the LLC Queue */ /* check for LLC PDU in the LLC Queue */
msg = llc_dequeue(tbf); msg = llc_dequeue(tbf);
if (!msg) { if (!msg) {