aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJacob Erlbeck <jerlbeck@sysmocom.de>2016-02-05 13:10:29 +0100
committerJacob Erlbeck <jerlbeck@sysmocom.de>2016-02-08 00:45:34 +0100
commit192bf33ffb14de601451343cae53838d8e7feeb7 (patch)
tree5a2338b1fd8fc3be438a04ac920f85e7db0b7851
parent2bef4dbd431150dddadd52221d7e238ca49ea4a3 (diff)
decode: Add bitvec based GPRS DL ACK/NACK decoder
Currently the RBB is used and passed directly to the window handling methods. For EGPRS a more abstract bitvec is derived from the messages and will passed around instead. Add a similar function for GPRS so that the same window handling can be used for GPRS and EGPRS. Sponsored-by: On-Waves ehf
-rw-r--r--src/decoding.cpp47
-rw-r--r--src/decoding.h4
2 files changed, 51 insertions, 0 deletions
diff --git a/src/decoding.cpp b/src/decoding.cpp
index 0623bef2..4c79c83b 100644
--- a/src/decoding.cpp
+++ b/src/decoding.cpp
@@ -612,3 +612,50 @@ aborted:
return num_blocks;
}
+
+int Decoding::decode_gprs_acknack_bits(const Ack_Nack_Description_t *desc,
+ bitvec *bits, int *bsn_begin, int *bsn_end, gprs_rlc_dl_window *window)
+{
+ int urbb_len = RLC_GPRS_WS;
+ int num_blocks;
+ struct bitvec urbb;
+
+ if (desc->FINAL_ACK_INDICATION)
+ return handle_final_ack(bits, bsn_begin, bsn_end, window);
+
+ *bsn_begin = window->v_a();
+ *bsn_end = desc->STARTING_SEQUENCE_NUMBER;
+
+ 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);
+
+ /*
+ * 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. Note that
+ * the bit numbers are counted from the end of the buffer.
+ */
+ for (int i = num_blocks; i > 0; i--) {
+ int is_ack = bitvec_get_bit_pos(&urbb, urbb_len - i);
+ bitvec_set_bit(bits, is_ack == 1 ? ONE : ZERO);
+ }
+
+ return num_blocks;
+}
diff --git a/src/decoding.h b/src/decoding.h
index 99cb3187..af0bb13a 100644
--- a/src/decoding.h
+++ b/src/decoding.h
@@ -57,4 +57,8 @@ public:
const EGPRS_AckNack_Desc_t *desc,
struct bitvec *bits, int *bsn_begin, int *bsn_end,
struct gprs_rlc_dl_window *window);
+ static int decode_gprs_acknack_bits(
+ const Ack_Nack_Description_t *desc,
+ bitvec *bits, int *bsn_begin, int *bsn_end,
+ gprs_rlc_dl_window *window);
};