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