aboutsummaryrefslogtreecommitdiffstats
path: root/src/decoding.cpp
diff options
context:
space:
mode:
authorJacob Erlbeck <jerlbeck@sysmocom.de>2016-01-14 18:31:21 +0100
committerJacob Erlbeck <jerlbeck@sysmocom.de>2016-02-02 17:06:34 +0100
commitbb15af8eb0dc84d67c665975053216cc4487746c (patch)
tree01c8e0993571c2e410a405a778905759c422d74f /src/decoding.cpp
parentf6ee36971394405373c69630a5f43e8daad2f8b2 (diff)
WIP: Fix BSN ranges in decode_egprs_acknack_bits
Ticket: OW#???? Sponsored-by: On-Waves ehf
Diffstat (limited to 'src/decoding.cpp')
-rw-r--r--src/decoding.cpp26
1 files changed, 22 insertions, 4 deletions
diff --git a/src/decoding.cpp b/src/decoding.cpp
index 61397fc0..e0733a3a 100644
--- a/src/decoding.cpp
+++ b/src/decoding.cpp
@@ -521,7 +521,7 @@ int Decoding::decode_egprs_acknack_bits(const EGPRS_AckNack_Desc_t *desc,
if (num_blocks == 0) {
*bsn_begin = desc->STARTING_SEQUENCE_NUMBER;
- *bsn_end = window->mod_sns(*bsn_begin - 1);
+ *bsn_end = *bsn_begin;
return num_blocks;
}
@@ -568,13 +568,31 @@ int Decoding::decode_gprs_acknack_bits(const Ack_Nack_Description_t *desc,
num_blocks = window->mod_sns(*bsn_end - *bsn_begin);
+ if (num_blocks < 0 || num_blocks > urbb_len) {
+ *bsn_end = *bsn_begin;
+ LOGP(DRLCMACUL, LOGL_NOTICE,
+ "Invalid GPRS Ack/Nack window %d:%d (length %d)\n",
+ *bsn_begin, *bsn_end, num_blocks);
+ return -EINVAL;
+ }
+
urbb.cur_bit = 0;
urbb.data = (uint8_t *)desc->RECEIVED_BLOCK_BITMAP;
urbb.data_len = sizeof(desc->RECEIVED_BLOCK_BITMAP);
- for (int i = urbb_len - num_blocks; i < urbb_len; i++) {
- /* Get bit from the appropriate position (see 3GPP TS 44.060 12.3) */
- int is_ack = bitvec_get_bit_pos(&urbb, i);
+ /*
+ * TS 44.060, 12.3:
+ * BSN = (SSN - bit_number) modulo 128, for bit_number = 1 to 64.
+ * The BSN values represented range from (SSN - 1) mod 128 to (SSN - 64) mod 128.
+ *
+ * We are only interested in the range from V(A) to SSN-1 which is
+ * num_blocks large. The RBB is laid out as
+ * [SSN-1] [SSN-2] ... [V(A)] ... [SSN-64]
+ * so we want to start with [V(A)] and go backwards until we reach
+ * [SSN-1] to get the needed BSNs in an increasing order.
+ */
+ for (int i = num_blocks; i > 0; i--) {
+ int is_ack = bitvec_get_bit_pos(&urbb, i-1);
bitvec_set_bit(bits, is_ack == 1 ? ONE : ZERO);
}