[PATCH 1/2] Add EGPRS header type 2 parsing function in uplink

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/.

Bhargava Abhyankar Bhargava.Abhyankar at radisys.com
Thu Mar 31 07:25:13 UTC 2016


Function is added to parse the EGPRS header type 2 in uplink tbf path.
This is added to further support mcs 5 to mcs 9 in uplink.
---
 src/decoding.cpp        |  52 +++++++++++++++--
 src/decoding.h          |   4 ++
 tests/edge/EdgeTest.cpp | 151 +++++++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 202 insertions(+), 5 deletions(-)

diff --git a/src/decoding.cpp b/src/decoding.cpp
index 0c81b2a..4d61083 100644
--- a/src/decoding.cpp
+++ b/src/decoding.cpp
@@ -352,10 +352,10 @@ int Decoding::rlc_parse_ul_data_header(struct gprs_rlc_data_info *rlc,
 	case GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_3 :
 		cur_bit = rlc_parse_ul_data_header_egprs_type_3(rlc, data, cs);
 		break;
-	case GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_1:
-	case GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_2:
-		/* TODO: Support both header types */
-		/* fall through */
+	case GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_2 :
+		cur_bit = rlc_parse_ul_data_header_egprs_type_2(rlc, data, cs);
+		break;
+	case GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_1 :
 	default:
 		LOGP(DRLCMACDL, LOGL_ERROR,
 			"Decoding of uplink %s data blocks not yet supported.\n",
@@ -438,6 +438,50 @@ int Decoding::rlc_parse_ul_data_header_gprs(struct gprs_rlc_data_info *rlc,
 	return cur_bit;
 }
 
+int Decoding::rlc_parse_ul_data_header_egprs_type_2(
+	struct gprs_rlc_data_info *rlc,
+	const uint8_t *data,
+	const GprsCodingScheme &cs)
+{
+	const struct gprs_rlc_ul_header_egprs_2 *egprs2;
+	unsigned int e_ti_header, offs, cur_bit = 0;
+	int punct, punct2, with_padding, cps;
+
+	egprs2 = static_cast < struct gprs_rlc_ul_header_egprs_2 * >
+			((void *)data);
+
+	cps    = (egprs2->cps_a << 0)  | (egprs2->cps_b << 2);
+	gprs_rlc_mcs_cps_decode(cps, cs, &punct, &punct2, &with_padding);
+	gprs_rlc_data_info_init_ul(rlc, cs, with_padding);
+
+	rlc->r      = egprs2->r;
+	rlc->si     = egprs2->si;
+	rlc->tfi    = (egprs2->tfi_a << 0)  | (egprs2->tfi_b << 2);
+	rlc->cps    = cps;
+	rlc->rsb    = egprs2->rsb;
+
+	rlc->num_data_blocks = 1;
+	rlc->block_info[0].cv  = egprs2->cv;
+	rlc->block_info[0].pi  = egprs2->pi;
+	rlc->block_info[0].bsn =
+		(egprs2->bsn1_a << 0) | (egprs2->bsn1_b << 5);
+
+	cur_bit += rlc->data_offs_bits[0] - 2;
+
+	offs = rlc->data_offs_bits[0] / 8;
+	OSMO_ASSERT(rlc->data_offs_bits[0] % 8 == 1);
+
+	e_ti_header = (data[offs-1] + (data[offs] << 8)) >> 7;
+	rlc->block_info[0].e   = !!(e_ti_header & 0x01);
+	rlc->block_info[0].ti  = !!(e_ti_header & 0x02);
+	cur_bit += 2;
+
+	/* skip data area */
+	cur_bit += cs.maxDataBlockBytes() * 8;
+
+	return cur_bit;
+}
+
 /**
  * \brief Copy LSB bitstream RLC data block to byte aligned buffer.
  *
diff --git a/src/decoding.h b/src/decoding.h
index 1043d67..9fb2c85 100644
--- a/src/decoding.h
+++ b/src/decoding.h
@@ -51,6 +51,10 @@ public:
 		struct gprs_rlc_data_info *rlc,
 		const uint8_t *data,
 		const GprsCodingScheme &cs);
+	static int rlc_parse_ul_data_header_egprs_type_2(
+		struct gprs_rlc_data_info *rlc,
+		const uint8_t *data,
+		const GprsCodingScheme &cs);
 	static int rlc_parse_ul_data_header(struct gprs_rlc_data_info *rlc,
 		const uint8_t *data, GprsCodingScheme cs);
 	static unsigned int rlc_copy_to_aligned_buffer(
diff --git a/tests/edge/EdgeTest.cpp b/tests/edge/EdgeTest.cpp
index 96ea0c1..c2dfc0b 100644
--- a/tests/edge/EdgeTest.cpp
+++ b/tests/edge/EdgeTest.cpp
@@ -26,7 +26,7 @@
 #include "encoding.h"
 #include "rlc.h"
 #include "llc.h"
-
+#include "bts.h"
 extern "C" {
 #include "pcu_vty.h"
 
@@ -495,6 +495,155 @@ static void test_rlc_unit_decoder()
 	OSMO_ASSERT(chunks[2].length == 1);
 	OSMO_ASSERT(!chunks[2].is_complete);
 
+	cs = GprsCodingScheme::MCS5;
+	rdbi.data_len = cs.maxDataBlockBytes();
+	rdbi.e = 0;
+	rdbi.ti = 0;
+	rdbi.cv = 15;
+	tlli = 0;
+	offs = 0;
+	data[offs++] = (15 << 1) | (1 << 0);
+	num_chunks = Decoding::rlc_data_from_ul_data(&rdbi, cs, data,
+		chunks, ARRAY_SIZE(chunks), &tlli);
+	OSMO_ASSERT(num_chunks == 2);
+	OSMO_ASSERT(tlli == 0);
+	OSMO_ASSERT(chunks[0].offset == 1);
+	OSMO_ASSERT(chunks[0].length == 15);
+	OSMO_ASSERT(chunks[0].is_complete);
+	OSMO_ASSERT(chunks[1].offset == 16);
+	OSMO_ASSERT(chunks[1].length == 40);
+	OSMO_ASSERT(!chunks[1].is_complete);
+
+	rdbi.e = 0;
+	rdbi.ti = 0;
+	rdbi.cv = 15;
+	tlli = 1;
+	offs = 0;
+	data[offs++] = (0 << 1) | (0 << 0);
+	data[offs++] = (7 << 1) | (0 << 0);
+	data[offs++] = (18 << 1) | (1 << 0);
+	num_chunks = Decoding::rlc_data_from_ul_data(&rdbi, cs, data,
+			chunks, ARRAY_SIZE(chunks), &tlli);
+	OSMO_ASSERT(num_chunks == 4);
+	OSMO_ASSERT(tlli == 0);
+	OSMO_ASSERT(chunks[0].length == 0);
+	OSMO_ASSERT(chunks[0].is_complete);
+	OSMO_ASSERT(chunks[1].offset == 3);
+	OSMO_ASSERT(chunks[1].length == 7);
+	OSMO_ASSERT(chunks[1].is_complete);
+	OSMO_ASSERT(chunks[2].offset == 10);
+	OSMO_ASSERT(chunks[2].length == 18);
+	OSMO_ASSERT(chunks[2].is_complete);
+
+	rdbi.e = 0;
+	rdbi.ti = 0;
+	rdbi.cv = 0;
+	tlli = 0;
+	offs = 0;
+	data[offs++] = (6 << 1) | (0 << 0);
+	data[offs++] = (12 << 1) | (0 << 0);
+	data[offs++] = (127 << 1) | (1 << 0);
+	num_chunks = Decoding::rlc_data_from_ul_data(&rdbi, cs, data,
+		chunks, ARRAY_SIZE(chunks), &tlli);
+	OSMO_ASSERT(num_chunks == 2);
+	OSMO_ASSERT(tlli == 0);
+	OSMO_ASSERT(chunks[0].offset == 3);
+	OSMO_ASSERT(chunks[0].length == 6);
+	OSMO_ASSERT(chunks[0].is_complete);
+	OSMO_ASSERT(chunks[1].offset == 9);
+	OSMO_ASSERT(chunks[1].length == 12);
+	OSMO_ASSERT(chunks[1].is_complete);
+
+	cs = GprsCodingScheme::MCS5;
+	rdbi.data_len = cs.maxDataBlockBytes();
+	rdbi.e = 1;
+	rdbi.ti = 0;
+	rdbi.cv = 0;
+	tlli = 0;
+	offs = 0;
+	num_chunks = Decoding::rlc_data_from_ul_data(&rdbi, cs, data,
+		chunks, ARRAY_SIZE(chunks), &tlli);
+	OSMO_ASSERT(num_chunks == 1);
+	OSMO_ASSERT(tlli == 0);
+	OSMO_ASSERT(chunks[0].offset == 0);
+	OSMO_ASSERT(chunks[0].length == 56);
+	OSMO_ASSERT(chunks[0].is_complete);
+
+	cs = GprsCodingScheme::MCS6;
+	rdbi.data_len = cs.maxDataBlockBytes();
+	rdbi.e = 0;
+	rdbi.ti = 0;
+	rdbi.cv = 15;
+	tlli = 0;
+	offs = 0;
+	data[offs++] = (15 << 1) | (1 << 0);
+	num_chunks = Decoding::rlc_data_from_ul_data(&rdbi, cs, data,
+		chunks, ARRAY_SIZE(chunks), &tlli);
+	OSMO_ASSERT(num_chunks == 2);
+	OSMO_ASSERT(tlli == 0);
+	OSMO_ASSERT(chunks[0].offset == 1);
+	OSMO_ASSERT(chunks[0].length == 15);
+	OSMO_ASSERT(chunks[0].is_complete);
+	OSMO_ASSERT(chunks[1].offset == 16);
+	OSMO_ASSERT(chunks[1].length == 58);
+	OSMO_ASSERT(!chunks[1].is_complete);
+
+	rdbi.e = 0;
+	rdbi.ti = 0;
+	rdbi.cv = 15;
+	tlli = 1;
+	offs = 0;
+	data[offs++] = (0 << 1) | (0 << 0);
+	data[offs++] = (7 << 1) | (0 << 0);
+	data[offs++] = (18 << 1) | (1 << 0);
+	num_chunks = Decoding::rlc_data_from_ul_data(&rdbi, cs, data,
+		chunks, ARRAY_SIZE(chunks), &tlli);
+
+	OSMO_ASSERT(num_chunks == 4);
+	OSMO_ASSERT(tlli == 0);
+	OSMO_ASSERT(chunks[0].length == 0);
+	OSMO_ASSERT(chunks[0].is_complete);
+	OSMO_ASSERT(chunks[1].offset == 3);
+	OSMO_ASSERT(chunks[1].length == 7);
+	OSMO_ASSERT(chunks[1].is_complete);
+	OSMO_ASSERT(chunks[2].offset == 10);
+	OSMO_ASSERT(chunks[2].length == 18);
+	OSMO_ASSERT(chunks[2].is_complete);
+
+	rdbi.e = 0;
+	rdbi.ti = 0;
+	rdbi.cv = 0;
+	tlli = 0;
+	offs = 0;
+	data[offs++] = (6 << 1) | (0 << 0);
+	data[offs++] = (12 << 1) | (0 << 0);
+	data[offs++] = (127 << 1) | (1 << 0);
+	num_chunks = Decoding::rlc_data_from_ul_data(&rdbi, cs, data,
+		chunks, ARRAY_SIZE(chunks), &tlli);
+	OSMO_ASSERT(num_chunks == 2);
+	OSMO_ASSERT(tlli == 0);
+	OSMO_ASSERT(chunks[0].offset == 3);
+	OSMO_ASSERT(chunks[0].length == 6);
+	OSMO_ASSERT(chunks[0].is_complete);
+	OSMO_ASSERT(chunks[1].offset == 9);
+	OSMO_ASSERT(chunks[1].length == 12);
+	OSMO_ASSERT(chunks[1].is_complete);
+
+	cs = GprsCodingScheme::MCS6;
+	rdbi.data_len = cs.maxDataBlockBytes();
+	rdbi.e = 1;
+	rdbi.ti = 0;
+	rdbi.cv = 0;
+	tlli = 0;
+	offs = 0;
+	num_chunks = Decoding::rlc_data_from_ul_data(&rdbi, cs, data,
+		chunks, ARRAY_SIZE(chunks), &tlli);
+	OSMO_ASSERT(num_chunks == 1);
+	OSMO_ASSERT(tlli == 0);
+	OSMO_ASSERT(chunks[0].offset == 0);
+	OSMO_ASSERT(chunks[0].length == 74);
+	OSMO_ASSERT(chunks[0].is_complete);
+
 	printf("=== end %s ===\n", __func__);
 }
 
-- 
2.5.0





More information about the osmocom-net-gprs mailing list