diff options
Diffstat (limited to 'src/gsm/lapd_core.c')
-rw-r--r-- | src/gsm/lapd_core.c | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/src/gsm/lapd_core.c b/src/gsm/lapd_core.c index c81c2fbf..b1b5a1ba 100644 --- a/src/gsm/lapd_core.c +++ b/src/gsm/lapd_core.c @@ -1497,14 +1497,32 @@ static int lapd_rx_i(struct msgb *msg, struct lapd_msg_ctx *lctx) "V(R)=%u\n", ns, dl->v_recv); /* discard data */ msgb_free(msg); - if (!dl->seq_err_cond) { + if (dl->seq_err_cond != 1) { /* FIXME: help me understand what exactly todo here - dl->seq_err_cond = 1; */ + dl->seq_err_cond = 1; lapd_send_rej(lctx, lctx->p_f); } else { + /* If there are two subsequent sequence errors received, + * ignore it. (Ignore every second subsequent error.) + * This happens if our reply with the REJ is too slow, + * so the remote gets a T200 timeout and sends another + * frame with a sequence error. + * Test showed that replying with two subsequent REJ + * messages could the remote L2 process to abort. + * Replying too slow shouldn't happen, but may happen + * over serial link between BB and LAPD. + */ + dl->seq_err_cond = 2; } - return -EIO; + /* Even if N(s) sequence error, acknowledge to N(R)-1 */ + /* 5.5.3.1: Acknowlege all transmitted frames up the N(R)-1 */ + lapd_acknowledge(lctx); /* V(A) is also set here */ + + /* Send message, if possible due to acknowledged data */ + lapd_send_i(lctx, __LINE__); + + return 0; } dl->seq_err_cond = 0; |