[PATCH] Handle the encoding of PUAN for CRBB bitmap

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/osmocom-net-gprs@lists.osmocom.org/.

sangamesh sajjan sangamesh.sajjan at radisys.com
Mon Apr 11 12:48:54 UTC 2016


This patch includes the changes for encoding of PUAN to
handle the CRBB bitmap
---
 src/encoding.cpp |  103 ++++++++++++++++++++++++++++++++++++++++++------------
 src/rlc.cpp      |   28 +++++++++++++++
 src/rlc.h        |    1 +
 3 files changed, 109 insertions(+), 23 deletions(-)

diff --git a/src/encoding.cpp b/src/encoding.cpp
index 6c50abe..e0c29af 100644
--- a/src/encoding.cpp
+++ b/src/encoding.cpp
@@ -25,6 +25,11 @@
 #include <tbf.h>
 #include <gprs_debug.h>
 
+extern "C" {
+#include <osmocom/core/utils.h>
+#include <osmocom/core/bitcomp.h>
+}
+
 #include <errno.h>
 #include <string.h>
 
@@ -537,8 +542,6 @@ static void write_packet_ack_nack_desc_egprs(
 	gprs_rlc_ul_window *window, bool is_final)
 {
 	int urbb_len = 0;
-	int crbb_len = 0;
-	int len;
 	bool bow = true;
 	bool eow = true;
 	int ssn = window->mod_sns(window->v_q() + 1);
@@ -546,9 +549,55 @@ static void write_packet_ack_nack_desc_egprs(
 	int esn_crbb = window->mod_sns(ssn - 1);
 	int rest_bits = dest->data_len * 8 - wp;
 
-	if (num_blocks > 0)
+	uint8_t rbb[128] = {'\0'};
+	uint8_t iter = 0;
+	uint8_t crbb_len = 0;
+	uint8_t len = 0;
+	int is_compressed = 0;
+	uint16_t ucmp_bmplan = window->update_egprs_rbb(rbb);
+	uint8_t crbb_bitmap[127];
+	bool bitmap_len = 0;
+
+	LOGP(DRLCMACUL, LOGL_DEBUG, "Uncompressed bitmap length after"
+			"rbb update %d\n", ucmp_bmplan);
+
+	rbb[128] = 0;
+	bitvec out;
+
+	out.data = rbb;
+	out.cur_bit = 0;
+	out.data_len = sizeof(rbb);
+	/* if [V(R) -1] modulo SNS is explicitly included in the bitmap,
+	 set eow =1;
+
+	 * If V(Q) equals V(R), then  BOW and EOW bit shall be set to the value '1'
+	 * and no need to send bitmap in ack nack, hence no compression
+	*/
+	if (window->v_q() == window->v_r()) {
+
+		LOGP(DRLCMACUL, LOGL_DEBUG, "write_packet_ack_nack_desc_egprs:"
+				"v(Q)=V(R), hence no compression"
+				" %d %d\n", window->v_q(), window->v_r());
+		eow = bow = 1;
+		bitmap_len = 1;
+	}
+	/* Compression part, Try compression only if it is greater than or equal
+	 * to Window size Otherwise encode it in uncompressed
+	*/
+	if ((ucmp_bmplan >= (rest_bits - 15)) && (!bitmap_len)) {
+
+		is_compressed = osmo_bitmap_compress(&out, //Uncompressed bitmap
+				&ucmp_bmplan, //Uncompressed bitmap len
+				&crbb_len, //Compressed bitmap len
+				crbb_bitmap
+				);
+	}
+
+	if (num_blocks > 0) {
 		/* V(Q) is NACK and omitted -> SSN = V(Q) + 1 */
 		num_blocks -= 1;
+		urbb_len = num_blocks;
+	}
 
 	if (num_blocks > window->ws())
 		num_blocks = window->ws();
@@ -556,17 +605,10 @@ static void write_packet_ack_nack_desc_egprs(
 	if (num_blocks > rest_bits) {
 		eow = false;
 		urbb_len = rest_bits;
-		/* TODO: use compression, start encoding bits and stop when the
-		 * space is exhausted. Use the first combination that encodes
-		 * all bits. If there is none, use the combination that encodes
-		 * the largest number of bits (e.g. by setting num_blocks to the
-		 * max and repeating the construction).
-		 */
 	} else if (num_blocks > rest_bits - 9) {
 		/* union bit and length field take 9 bits */
 		eow = false;
 		urbb_len = rest_bits - 9;
-		/* TODO: use compression (see above) */
 	}
 
 	if (urbb_len + crbb_len == rest_bits)
@@ -588,20 +630,35 @@ static void write_packet_ack_nack_desc_egprs(
 	bitvec_write_field(dest, wp, bow, 1); // BEGINNING_OF_WINDOW
 	bitvec_write_field(dest, wp, eow, 1); // END_OF_WINDOW
 	bitvec_write_field(dest, wp, ssn, 11); // STARTING_SEQUENCE_NUMBER
-	bitvec_write_field(dest, wp, 0, 1); // 0: don't have CRBB
 
-	/* TODO: Add CRBB support */
-
-	LOGP(DRLCMACUL, LOGL_DEBUG,
-		" - EGPRS URBB, len = %d, SSN = %d, ESN_CRBB = %d, "
-		"SNS = %d, WS = %d, V(Q) = %d, V(R) = %d%s%s\n",
-		urbb_len, ssn, esn_crbb,
-		window->sns(), window->ws(), window->v_q(), window->v_r(),
-		bow ? ", BOW" : "", eow ? ", EOW" : "");
-	for (int i = urbb_len; i > 0; i--) {
-		/* Set bit at the appropriate position (see 3GPP TS 04.60 12.3.1) */
-		bool is_ack = window->m_v_n.is_received(esn_crbb + i);
-		bitvec_write_field(dest, wp, is_ack, 1);
+	if (is_compressed) {
+		bitvec_write_field(dest, wp, 1, 1); // CRBB_Exist
+		bitvec_write_field(dest, wp, crbb_len, 7); // CRBB_LENGTH
+		uint8_t crbb_start_clr_code = (0x80 & crbb_bitmap[0])>>7;
+		bitvec_write_field(dest, wp, crbb_start_clr_code, 1); // CRBB_clr_code
+
+		while (crbb_len != 0) {
+			if (crbb_len > 8) {
+				bitvec_write_field(dest, wp, crbb_bitmap[iter], 8);
+				crbb_len = crbb_len - 8;
+				iter++;
+			} else{
+				bitvec_write_field(dest, wp, crbb_bitmap[iter], crbb_len);
+				crbb_len = 0;
+			}
+		}
+	} else{
+		LOGP(DRLCMACUL, LOGL_DEBUG,
+				" - EGPRS URBB, len = %d, SSN = %d, ESN_CRBB = %d, "
+				"SNS = %d, WS = %d, V(Q) = %d, V(R) = %d%s%s\n",
+				urbb_len, ssn, esn_crbb,
+				window->sns(), window->ws(), window->v_q(), window->v_r(),
+				bow ? ", BOW" : "", eow ? ", EOW" : "");
+		for (int i = urbb_len; i > 0; i--) {
+			/* Set bit at the appropriate position (see 3GPP TS 04.60 12.3.1) */
+			bool is_ack = window->m_v_n.is_received(esn_crbb + i);
+			bitvec_write_field(dest, wp, is_ack, 1);
+		}
 	}
 }
 
diff --git a/src/rlc.cpp b/src/rlc.cpp
index 6770043..c201713 100644
--- a/src/rlc.cpp
+++ b/src/rlc.cpp
@@ -83,6 +83,34 @@ int gprs_rlc_dl_window::mark_for_resend()
 	return resend;
 }
 
+/* Update the receive block bitmap */
+uint16_t gprs_rlc_ul_window::update_egprs_rbb(uint8_t *rbb)
+{
+	int i;
+	uint16_t bsn;
+	int8_t bitmask = 0x80;
+	int8_t pos = 0;
+	int8_t bit_pos = 0;
+	for (i = 0, bsn = (v_q()+1); ((bsn < (v_r())) && (i < ws())); i++,
+					bsn = this->mod_sns(bsn + 1)) {
+		if (m_v_n.is_received(bsn)) {
+			rbb[pos] = rbb[pos] | bitmask;
+		} else {
+			rbb[pos] = rbb[pos] & (~bitmask);
+		}
+		bitmask = bitmask >> 1;
+		bit_pos++;
+		bit_pos = bit_pos % 8;
+		if(bit_pos == 0) {
+			pos++;
+			bitmask = 0x80;
+		}
+	}
+	LOGP(DRLCMACUL, LOGL_DEBUG, "V(N):in update_egprs_rbb \"%s\""
+			"R=Received I=Invalid\n", rbb);
+	return i;
+}
+
 int gprs_rlc_dl_window::count_unacked()
 {
 	uint16_t unacked = 0;
diff --git a/src/rlc.h b/src/rlc.h
index 8f75588..83bc5dc 100644
--- a/src/rlc.h
+++ b/src/rlc.h
@@ -260,6 +260,7 @@ struct gprs_rlc_ul_window: public gprs_rlc_window {
 	bool is_received(uint16_t bsn) const;
 
 	void update_rbb(char *rbb);
+	uint16_t update_egprs_rbb(uint8_t *rbb);
 	void raise_v_r_to(int moves);
 	void raise_v_r(const uint16_t bsn);
 	uint16_t raise_v_q();
-- 
1.7.9.5





More information about the osmocom-net-gprs mailing list