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

Submitted by Bhargava Abhyankar on March 30, 2016, 1:28 p.m.

Details

Message ID 1459344522-15503-1-git-send-email-Bhargava.Abhyankar@radisys.com
State Superseded
Series "Series without cover letter"
Headers show

Commit Message

Bhargava Abhyankar March 30, 2016, 1:28 p.m.
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        |  54 +++++++++++++++--
 src/decoding.h          |   5 +-
 tests/edge/EdgeTest.cpp | 151 +++++++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 203 insertions(+), 7 deletions(-)

Patch hide | download patch | download mbox

diff --git a/src/decoding.cpp b/src/decoding.cpp
index f2b548c..ad5b05f 100644
--- a/src/decoding.cpp
+++ b/src/decoding.cpp
@@ -411,11 +411,11 @@  int Decoding::rlc_parse_ul_data_header(struct gprs_rlc_data_info *rlc,
 		/* skip data area */
 		cur_bit += cs.maxDataBlockBytes() * 8;
 		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",
@@ -426,6 +426,50 @@  int Decoding::rlc_parse_ul_data_header(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,
+	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 58ecd18..2cb053d 100644
--- a/src/decoding.h
+++ b/src/decoding.h
@@ -43,7 +43,10 @@  public:
 
 	static void extract_rbb(const uint8_t *rbb, char *extracted_rbb);
 	static void extract_rbb(const struct bitvec *rbb, char *show_rbb);
-
+	static int rlc_parse_ul_data_header_egprs_type_2(
+		struct gprs_rlc_data_info *rlc,
+		const uint8_t *data,
+		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__);
 }
 

Comments

Harald Welte March 30, 2016, 8:12 p.m.
Hi Bhargava,

On Wed, Mar 30, 2016 at 06:58:41PM +0530, Bhargava Abhyankar wrote:
> 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.

The patches look fine to me (keep in mind, I'm not the PCU expert in the
team, so others might disagree).  However, unfortunately your patch
doesn't apply on current master, please re-base and re-submit.
Bhargava Abhyankar March 31, 2016, 2:39 p.m.
Hi Harald,

On Thurs, Mar 31, 2016 at 1:45 AM, Harald Welte wrote :
> unfortunately your patch doesn't apply on current master, please re-base and re-submit

As suggested by you, I have re-based and then re-submitted the patches.

Regards
Bhargava Abhyankar