[PATCH] osmo-pcu[master]: Add decoding of compressed bitmap in EPDAN

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/gerrit-log@lists.osmocom.org/.

pravin gerrit-no-reply at lists.osmocom.org
Fri Jul 15 07:26:01 UTC 2016


Hello Max, Jenkins Builder, Holger Freyther,

I'd like you to reexamine a change.  Please visit

    https://gerrit.osmocom.org/416

to look at the new patch set (#4).

Add decoding of compressed bitmap in EPDAN

Implemented tree based algorithm to decode compressed bitmap in EPDAN
as described in section 9.1.10 of 3GPP 44.060.
This algorithm intends to improve the performance over existing method.

Change-Id: Ieae1992ed4b02bb1e09eec2d3de1a030eabd16ce
---
M src/Makefile.am
M src/decoding.cpp
M src/decoding.h
M src/pcu_main.cpp
M tests/tbf/TbfTest.cpp
5 files changed, 147 insertions(+), 37 deletions(-)


  git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/16/416/4

diff --git a/src/Makefile.am b/src/Makefile.am
index 9bdec2f..9b047e7 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -62,7 +62,8 @@
 	rlc.cpp \
 	osmobts_sock.cpp \
 	gprs_codel.c \
-	gprs_coding_scheme.cpp
+	gprs_coding_scheme.cpp \
+	egprs_rlc_compression.cpp
 
 bin_PROGRAMS = \
 	osmo-pcu
@@ -94,7 +95,8 @@
 	pcu_utils.h \
 	cxx_linuxlist.h \
 	gprs_codel.h \
-	gprs_coding_scheme.h
+	gprs_coding_scheme.h \
+	egprs_rlc_compression.h
 
 osmo_pcu_SOURCES = pcu_main.cpp
 
diff --git a/src/decoding.cpp b/src/decoding.cpp
index 7c00ff7..3f8b11b 100644
--- a/src/decoding.cpp
+++ b/src/decoding.cpp
@@ -651,11 +651,10 @@
 	int crbb_len = 0;
 	int num_blocks = 0;
 	struct bitvec urbb;
-	int i;
+	int i, rc;
 	bool have_bitmap;
 	int implicitly_acked_blocks;
 	int ssn = desc->STARTING_SEQUENCE_NUMBER;
-	int rc;
 
 	if (desc->FINAL_ACK_INDICATION)
 		return handle_final_ack(bits, bsn_begin, bsn_end, window);
@@ -695,27 +694,22 @@
 
 	if (crbb_len > 0) {
 		int old_len = bits->cur_bit;
-		struct bitvec crbb;
 
-		crbb.data = (uint8_t *)desc->CRBB;
-		crbb.data_len = sizeof(desc->CRBB);
-		crbb.cur_bit = desc->CRBB_LENGTH;
-
-		rc = osmo_t4_decode(&crbb, desc->CRBB_STARTING_COLOR_CODE,
-			bits);
-
+		LOGP(DRLCMACDL, LOGL_DEBUG, "Compress bitmap exist,"
+			"CRBB LEN =%d and Starting color code =%d",
+			desc->CRBB_LENGTH, desc->CRBB_STARTING_COLOR_CODE);
+		rc = decompress_crbb(desc->CRBB_LENGTH, desc->CRBB_STARTING_COLOR_CODE,
+					desc->CRBB, bits);
 		if (rc < 0) {
 			LOGP(DRLCMACUL, LOGL_NOTICE,
-				"Failed to decode CRBB: "
-				"length %d, data '%s'\n",
-				desc->CRBB_LENGTH,
-				osmo_hexdump(crbb.data, crbb.data_len));
+				"Failed to decode CRBB: length %d, data '%s'\n",
+				desc->CRBB_LENGTH, osmo_hexdump(
+					desc->CRBB, (desc->CRBB_LENGTH + 7)/8));
 			/* We don't know the SSN offset for the URBB,
-			 * return what we have so far and assume the
-			 * bitmap has stopped here */
+			* return what we have so far and assume the
+			* bitmap has stopped here */
 			goto aborted;
 		}
-
 		LOGP(DRLCMACDL, LOGL_DEBUG,
 			"CRBB len: %d, decoded len: %d, cc: %d, crbb: '%s'\n",
 			desc->CRBB_LENGTH, bits->cur_bit - old_len,
diff --git a/src/decoding.h b/src/decoding.h
index d1371d5..cb18fcb 100644
--- a/src/decoding.h
+++ b/src/decoding.h
@@ -76,6 +76,12 @@
 		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);
+		bitvec * bits, int *bsn_begin, int *bsn_end,
+		gprs_rlc_dl_window * window);
+	static int decompress_crbb(
+			int8_t compress_bmap_len,
+			uint8_t clr_code_bit,
+			const uint8_t *orig_buf,
+			bitvec * dest
+			);
 };
diff --git a/src/pcu_main.cpp b/src/pcu_main.cpp
index 2d86cda..1a31eb9 100644
--- a/src/pcu_main.cpp
+++ b/src/pcu_main.cpp
@@ -28,6 +28,7 @@
 #include <signal.h>
 #include <sched.h>
 #include <bts.h>
+#include <egprs_rlc_compression.h>
 extern "C" {
 #include "pcu_vty.h"
 #include <osmocom/vty/telnet_interface.h>
@@ -253,6 +254,8 @@
 	if (!bts->alloc_algorithm)
 		bts->alloc_algorithm = alloc_algorithm_dynamic;
 
+	egprs_compress::instance()->decode_tree_init();
+
 	rc = pcu_l1if_open();
 
 	if (rc < 0)
@@ -290,8 +293,8 @@
 
 	pcu_l1if_close();
 
+	egprs_compress::instance()->decode_tree_free();
 	talloc_report_full(tall_pcu_ctx, stderr);
 	talloc_free(tall_pcu_ctx);
-
 	return 0;
 }
diff --git a/tests/tbf/TbfTest.cpp b/tests/tbf/TbfTest.cpp
index 2f93a6e..219fe24 100644
--- a/tests/tbf/TbfTest.cpp
+++ b/tests/tbf/TbfTest.cpp
@@ -26,10 +26,11 @@
 #include "pcu_utils.h"
 #include "gprs_bssgp_pcu.h"
 #include "pcu_l1_if.h"
-
+#include "egprs_rlc_compression.h"
+#include "decoding.h"
 extern "C" {
 #include "pcu_vty.h"
-
+#include <osmocom/core/bitcomp.h>
 #include <osmocom/core/application.h>
 #include <osmocom/core/msgb.h>
 #include <osmocom/core/talloc.h>
@@ -39,8 +40,40 @@
 
 #include <errno.h>
 
+#define NUMBER_OF_TEST_CASE 9
+#define NEW 1
+#define DELTA 1000
+#define MASK(n) (0xFF << (8-n))
 void *tall_pcu_ctx;
 int16_t spoof_mnc = 0, spoof_mcc = 0;
+struct test_data {
+	int8_t crbb_len;
+	uint8_t cc;
+	uint8_t data[23];
+	uint8_t exp_data[40];
+	int exp_len;
+	int verify;
+}test[NUMBER_OF_TEST_CASE] = { { (int8_t)67, (uint8_t)1, {0x02, 0x0c, 0xa0, 0x30, 0xcb, 0x1a, 0x0c, 0xe3, 0x6c},
+		{0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xf8, 0x00,
+		0x00, 0x00, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff,
+		0xdb}, (int)194, 1},
+		{(int8_t)40, (uint8_t)1, {0x53, 0x06, 0xc5, 0x40, 0x6d}, {0xff, 0xff, 0xff, 0xff, 0xff,
+		0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00,
+		0x00, 0x00, 0x00, 0x03}, (int)182, 1},
+		{ (int8_t)8, (uint8_t)1, {0x02}, {0xff, 0xff, 0xff, 0xf8}, (int)29, 1},
+		{ (int8_t)103, (uint8_t)1, {0x02, 0x0c, 0xe0, 0x41, 0xa0, 0x0c, 0x36, 0x0d, 0x03,
+		0x71, 0xb0, 0x6e, 0x24}, {0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0xff, 0xff, 0xff,
+		0xf8, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff,
+		0xe0, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0x80, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff},
+		(int)288, 1},
+		/* Test vector from libosmocore test */
+		{ (int8_t)32, (uint8_t)0, {0xde, 0x88, 0x75, 0x65, 0x80}, {0x37, 0x47, 0x81, 0xf0}, (int)28},
+		{ (int8_t)18, (uint8_t)1, {0xdd, 0x41, 0x00}, {0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+		0xff, 0xff, 0xff, 0xff, 0x00, 0x00}, (int)90, 1},
+		/*Invalid inputs*/
+		{ (int8_t)18, (uint8_t)1, {0x1E, 0x70, 0xc0}, {0x0}, (int)0, 0},
+		{ (int8_t)14, (uint8_t)1, {0x00, 0x1E, 0x7c}, {0x0}, (int)0, 0},
+		{ (int8_t)24, (uint8_t)0, {0x00, 0x00, 0x00}, {0x0}, (int)0, 0} };
 
 static void check_tbf(gprs_rlcmac_tbf *tbf)
 {
@@ -51,19 +84,89 @@
 		OSMO_ASSERT(tbf->T != 0);
 }
 
-/*
-static unsigned inc_fn(fn)
+/* To verify the result with expected result */
+int check_result(bitvec bits, uint8_t *exp_data, int exp_len)
 {
-	unsigned next_fn;
-
-	next_fn = fn + 4;
-	if ((block_nr % 3) == 2)
-		next_fn ++;
-	next_fn = next_fn % 2715648;
-
-	return next_fn;
+	if (bits.cur_bit != exp_len)
+		return 0;
+	size_t n = (exp_len / 8);
+	int rem = (exp_len % 8);
+	if (memcmp (exp_data, bits.data, n) == 0) {
+		if (rem == 0)
+			return 1;
+		if ((bits.data[n] & MASK(rem)) == ((*(exp_data + n)) & MASK(rem)))
+			return 1;
+		else
+			return 0;
+	} else {
+		return 0;
+	}
 }
-*/
+
+/*  To check time taken to decode crbb by Tree based method
+ *  and to verify the result with expected result 
+ *  for invalid input verfication is suppressed */
+void test_EPDAN_time_tree(int test_run)
+{
+	long long int min_tree[NUMBER_OF_TEST_CASE] = {0}, max_tree[NUMBER_OF_TEST_CASE] = {0};
+	long long int sum[NUMBER_OF_TEST_CASE] = {0}, avg[NUMBER_OF_TEST_CASE] = {0};
+	float avg_tree[NUMBER_OF_TEST_CASE] = {0};
+	bitvec bits;
+	struct bitvec data1;
+	int loop = 0;
+
+	while (loop++ < test_run) {
+		int init_flag = 1, first[NUMBER_OF_TEST_CASE] = {0}, last[NUMBER_OF_TEST_CASE] = {0};
+		int count[NUMBER_OF_TEST_CASE] = {0}, itr = 0;
+
+		for (itr ; itr < NUMBER_OF_TEST_CASE ; itr++) {
+			data1.data_len = ((test[itr].crbb_len + 7)/8);
+			data1.cur_bit = test[itr].crbb_len;
+			struct timeval t0, t1;
+
+			data1.data = test[itr].data;
+			uint8_t bits_data[RLC_EGPRS_MAX_WS/8];
+			bits.data = bits_data;
+			bits.data_len = sizeof(bits_data);
+			bits.cur_bit = 0;
+			gettimeofday(&t0, 0);
+			Decoding::decompress_crbb(test[itr].crbb_len, test[itr].cc, test[itr].data, &bits);
+			gettimeofday(&t1, 0);
+			long long elapsed = (t1.tv_sec-t0.tv_sec)*1000000LL + t1.tv_usec-t0.tv_usec;
+
+			if (init_flag)
+				init_flag = 0;
+			if (test[itr].verify) {
+				if (check_result(bits, test[itr].exp_data, test[itr].exp_len) == 0) {
+					LOGP (DRLCMACDL, LOGL_DEBUG, "Tree based decoding :Error\n");
+					OSMO_ASSERT(0);
+				}
+			}
+			if (loop == 1) {
+				first[itr] = elapsed;
+				min_tree[itr] = elapsed;
+				max_tree[itr] = elapsed;
+				sum[itr] = elapsed;
+				avg[itr] = elapsed;
+				avg_tree[itr] = elapsed;
+			} else {
+				if (loop == test_run-1)
+					last[itr] = elapsed;
+				if (elapsed > (avg[itr]+DELTA))
+					count[itr]++;
+				sum[itr] = sum[itr] + elapsed;
+				avg[itr] = sum[itr] / loop;
+				if (min_tree[itr] > elapsed)
+					min_tree[itr] = elapsed;
+				if (max_tree[itr] < elapsed)
+					max_tree[itr] = elapsed;
+				avg_tree[itr] = avg_tree[itr] + elapsed;
+			}
+		}
+	}
+	for (int i = 0 ; i < NUMBER_OF_TEST_CASE ; i++)
+		avg_tree[i] = avg_tree[i]/test_run;
+}
 
 static void test_tbf_base()
 {
@@ -1563,7 +1666,8 @@
 
 	vty_init(&pcu_vty_info);
 	pcu_vty_init(&debug_log_info);
-
+	/*initialization_of_tree*/
+	egprs_compress::instance()->decode_tree_init();
 	test_tbf_base();
 	test_tbf_tlli_update();
 	test_tbf_final_ack(TEST_MODE_STANDARD);
@@ -1583,7 +1687,8 @@
 	test_tbf_egprs_two_phase();
 	test_tbf_egprs_dl();
 	test_tbf_egprs_retx_dl();
-
+	test_EPDAN_time_tree(1);
+	egprs_compress::instance()->decode_tree_free();
 	if (getenv("TALLOC_REPORT_FULL"))
 		talloc_report_full(tall_pcu_ctx, stderr);
 	return EXIT_SUCCESS;

-- 
To view, visit https://gerrit.osmocom.org/416
To unsubscribe, visit https://gerrit.osmocom.org/settings

Gerrit-MessageType: newpatchset
Gerrit-Change-Id: Ieae1992ed4b02bb1e09eec2d3de1a030eabd16ce
Gerrit-PatchSet: 4
Gerrit-Project: osmo-pcu
Gerrit-Branch: master
Gerrit-Owner: pravin <pravin.manoharan at radisys.com>
Gerrit-Reviewer: Holger Freyther <holger at freyther.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: Max <msuraev at sysmocom.de>
Gerrit-Reviewer: pravin <pravin.manoharan at radisys.com>



More information about the gerrit-log mailing list