From 5f7d3cd6d2c2790c186a6d83286b6f9ee68e5f71 Mon Sep 17 00:00:00 2001 From: Jonathan Santos Date: Thu, 23 Jun 2011 17:53:27 -0400 Subject: gprs: Fix LLC UI window According to TS 44.064 section 8.4.2, the LLC layer should only drop UI frames if V(UR)-32 <= N(U) < V(UR). The code was dropping frames whenever N(U) < V(UR). Consequently, large amounts of packets could be dropped if, e.g., V(UR)==511 and the frame with N(U)==511 was lost. All frames would be dropped until the next time a frame with N(U)==511 is received. --- src/gprs/gprs_llc.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/gprs/gprs_llc.c b/src/gprs/gprs_llc.c index 0b4a5de94..07294aadc 100644 --- a/src/gprs/gprs_llc.c +++ b/src/gprs/gprs_llc.c @@ -482,17 +482,21 @@ static int gprs_llc_hdr_rx(struct gprs_llc_hdr_parsed *gph, } break; case GPRS_LLC_UI: - if (gph->seq_tx < lle->vu_recv) { - LOGP(DLLC, LOGL_NOTICE, "TLLI=%08x dropping UI, vurecv %u <= %u\n", - lle->llme ? lle->llme->tlli : -1, - gph->seq_tx, lle->vu_recv); - return -EIO; - } - /* Increment the sequence number that we expect in the next frame */ - lle->vu_recv = (gph->seq_tx + 1) % 512; - /* Increment Overflow Counter */ - if ((gph->seq_tx + 1) / 512) - lle->oc_ui_recv += 512; + { + int delta = (lle->vu_recv - gph->seq_tx) & 0x1ff; + if (0 < delta && delta < 32) { + LOGP(DLLC, LOGL_NOTICE, "TLLI=%08x dropping UI, vurecv %u <= %u\n", + lle->llme ? lle->llme->tlli : -1, + gph->seq_tx, lle->vu_recv); + return -EIO; + } + /* Increment the sequence number that we expect in the next frame */ + lle->vu_recv = (gph->seq_tx + 1) & 0x1ff; + /* Increment Overflow Counter */ + if (lle->vu_recv == 0) { + lle->oc_ui_recv += 512; + } + } break; } -- cgit v1.2.3