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