aboutsummaryrefslogtreecommitdiffstats
path: root/src/gprs/gprs_llc.c
diff options
context:
space:
mode:
authorJonathan Santos <jrsantos@jonathanrsantos.com>2011-06-23 17:53:27 -0400
committerJonathan Santos <jrsantos@jonathanrsantos.com>2011-06-23 17:57:06 -0400
commit5f7d3cd6d2c2790c186a6d83286b6f9ee68e5f71 (patch)
tree0432da21ed8da663aaf7baa0d4b37529689422e0 /src/gprs/gprs_llc.c
parent7ad066c5c380a93aa525356ff588c1f8776ad4a2 (diff)
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.
Diffstat (limited to 'src/gprs/gprs_llc.c')
-rw-r--r--src/gprs/gprs_llc.c26
1 files changed, 15 insertions, 11 deletions
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;
}