From 14bb0947b49e7f936f3ff0708e5891a873362d3b Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Tue, 12 Jan 2016 11:58:13 +0100 Subject: edge: Add Encoding::rlc_data_to_dl_append This function appends a single chunk to an RLC downlink data block. The implementation is basically taken from the gprs_rlcmac_dl_tbf::create_new_bsn method without the TBF related functionality and any side effects. Note that it still only supports GRPS. Sponsored-by: On-Waves ehf --- tests/edge/EdgeTest.cpp | 251 ++++++++++++++++++++++++++++++++++++++++++++++++ tests/edge/EdgeTest.ok | 2 + 2 files changed, 253 insertions(+) (limited to 'tests') diff --git a/tests/edge/EdgeTest.cpp b/tests/edge/EdgeTest.cpp index 11459457..70e99d53 100644 --- a/tests/edge/EdgeTest.cpp +++ b/tests/edge/EdgeTest.cpp @@ -25,6 +25,7 @@ #include "decoding.h" #include "encoding.h" #include "rlc.h" +#include "llc.h" extern "C" { #include "pcu_vty.h" @@ -483,6 +484,255 @@ static void test_rlc_unit_decoder() printf("=== end %s ===\n", __func__); } +static void test_rlc_unit_encoder() +{ + struct gprs_rlc_data_block_info rdbi = {0}; + GprsCodingScheme cs; + uint8_t data[74]; + uint8_t llc_data[1500] = {0,}; + int num_chunks = 0; + int write_offset; + struct gprs_llc llc; + Encoding::AppendResult ar; + + printf("=== start %s ===\n", __func__); + + llc.init(); + + /* TS 44.060, B.1 */ + cs = GprsCodingScheme::CS4; + gprs_rlc_data_block_info_init(&rdbi, cs); + num_chunks = 0; + write_offset = 0; + memset(data, 0, sizeof(data)); + + llc.reset(); + llc.put_frame(llc_data, 11); + + ar = Encoding::rlc_data_to_dl_append(&rdbi, + &llc, &write_offset, &num_chunks, data, false); + + OSMO_ASSERT(ar == Encoding::AR_COMPLETED_SPACE_LEFT); + OSMO_ASSERT(rdbi.e == 0); + OSMO_ASSERT(write_offset == 1 + 11); + OSMO_ASSERT(num_chunks == 1); + + llc.reset(); + llc.put_frame(llc_data, 26); + + ar = Encoding::rlc_data_to_dl_append(&rdbi, + &llc, &write_offset, &num_chunks, data, false); + + OSMO_ASSERT(ar == Encoding::AR_COMPLETED_SPACE_LEFT); + OSMO_ASSERT(rdbi.e == 0); + OSMO_ASSERT(write_offset == 2 + 11 + 26); + OSMO_ASSERT(num_chunks == 2); + + llc.reset(); + llc.put_frame(llc_data, 99); + + ar = Encoding::rlc_data_to_dl_append(&rdbi, + &llc, &write_offset, &num_chunks, data, false); + + OSMO_ASSERT(ar == Encoding::AR_NEED_MORE_BLOCKS); + OSMO_ASSERT(rdbi.e == 0); + OSMO_ASSERT(rdbi.cv != 0); + OSMO_ASSERT(write_offset == (int)rdbi.data_len); + OSMO_ASSERT(num_chunks == 3); + + OSMO_ASSERT(data[0] == ((11 << 2) | (1 << 1) | (0 << 0))); + OSMO_ASSERT(data[1] == ((26 << 2) | (1 << 1) | (1 << 0))); + OSMO_ASSERT(data[2] == 0); + + /* TS 44.060, B.2 */ + cs = GprsCodingScheme::CS1; + + /* Block 1 */ + gprs_rlc_data_block_info_init(&rdbi, cs); + num_chunks = 0; + write_offset = 0; + memset(data, 0, sizeof(data)); + + llc.reset(); + llc.put_frame(llc_data, 20); + + ar = Encoding::rlc_data_to_dl_append(&rdbi, + &llc, &write_offset, &num_chunks, data, false); + + OSMO_ASSERT(ar == Encoding::AR_NEED_MORE_BLOCKS); + OSMO_ASSERT(rdbi.e == 0); + OSMO_ASSERT(write_offset == 1 + 19); + OSMO_ASSERT(num_chunks == 1); + + OSMO_ASSERT(data[0] == ((0 << 2) | (0 << 1) | (1 << 0))); + OSMO_ASSERT(data[1] == 0); + + /* Block 2 */ + gprs_rlc_data_block_info_init(&rdbi, cs); + num_chunks = 0; + write_offset = 0; + memset(data, 0, sizeof(data)); + + OSMO_ASSERT(llc.chunk_size() == 1); + + ar = Encoding::rlc_data_to_dl_append(&rdbi, + &llc, &write_offset, &num_chunks, data, false); + + OSMO_ASSERT(ar == Encoding::AR_COMPLETED_SPACE_LEFT); + OSMO_ASSERT(rdbi.e == 0); + OSMO_ASSERT(write_offset == 1 + 1); + OSMO_ASSERT(num_chunks == 1); + + llc.reset(); + llc.put_frame(llc_data, 99); + + ar = Encoding::rlc_data_to_dl_append(&rdbi, + &llc, &write_offset, &num_chunks, data, false); + + OSMO_ASSERT(ar == Encoding::AR_NEED_MORE_BLOCKS); + OSMO_ASSERT(rdbi.e == 0); + OSMO_ASSERT(write_offset == 1 + 1 + 18); + OSMO_ASSERT(num_chunks == 2); + + OSMO_ASSERT(data[0] == ((1 << 2) | (1 << 1) | (1 << 0))); + OSMO_ASSERT(data[1] == 0); + + /* TS 44.060, B.3 */ + cs = GprsCodingScheme::CS1; + + /* Block 1 */ + gprs_rlc_data_block_info_init(&rdbi, cs); + num_chunks = 0; + write_offset = 0; + memset(data, 0, sizeof(data)); + + llc.reset(); + llc.put_frame(llc_data, 7); + + ar = Encoding::rlc_data_to_dl_append(&rdbi, + &llc, &write_offset, &num_chunks, data, false); + + OSMO_ASSERT(ar == Encoding::AR_COMPLETED_SPACE_LEFT); + OSMO_ASSERT(rdbi.e == 0); + OSMO_ASSERT(write_offset == 1 + 7); + OSMO_ASSERT(num_chunks == 1); + + llc.reset(); + llc.put_frame(llc_data, 11); + + ar = Encoding::rlc_data_to_dl_append(&rdbi, + &llc, &write_offset, &num_chunks, data, false); + + OSMO_ASSERT(ar == Encoding::AR_COMPLETED_BLOCK_FILLED); + OSMO_ASSERT(rdbi.e == 0); + OSMO_ASSERT(write_offset == 2 + 7 + 11); + OSMO_ASSERT(num_chunks == 2); + + OSMO_ASSERT(data[0] == ((7 << 2) | (1 << 1) | (0 << 0))); + OSMO_ASSERT(data[1] == ((11 << 2) | (0 << 1) | (1 << 0))); + OSMO_ASSERT(data[2] == 0); + + /* TS 44.060, B.4 */ + cs = GprsCodingScheme::CS1; + + /* Block 1 */ + gprs_rlc_data_block_info_init(&rdbi, cs); + num_chunks = 0; + write_offset = 0; + memset(data, 0, sizeof(data)); + + llc.reset(); + llc.put_frame(llc_data, 99); + + ar = Encoding::rlc_data_to_dl_append(&rdbi, + &llc, &write_offset, &num_chunks, data, false); + + OSMO_ASSERT(ar == Encoding::AR_NEED_MORE_BLOCKS); + OSMO_ASSERT(rdbi.e == 1); + OSMO_ASSERT(write_offset == 20); + OSMO_ASSERT(num_chunks == 1); + OSMO_ASSERT(rdbi.cv != 0); + + OSMO_ASSERT(data[0] == 0); + + /* TS 44.060, B.5 */ + cs = GprsCodingScheme::CS1; + + /* Block 1 */ + gprs_rlc_data_block_info_init(&rdbi, cs); + num_chunks = 0; + write_offset = 0; + memset(data, 0, sizeof(data)); + + llc.reset(); + llc.put_frame(llc_data, 20); + + ar = Encoding::rlc_data_to_dl_append(&rdbi, + &llc, &write_offset, &num_chunks, data, true); + + OSMO_ASSERT(ar == Encoding::AR_COMPLETED_BLOCK_FILLED); + OSMO_ASSERT(rdbi.e == 1); + OSMO_ASSERT(write_offset == 20); + OSMO_ASSERT(num_chunks == 1); + OSMO_ASSERT(rdbi.cv == 0); + + OSMO_ASSERT(data[0] == 0); + + /* TS 44.060, B.7 */ + cs = GprsCodingScheme::CS1; + + /* Block 1 */ + gprs_rlc_data_block_info_init(&rdbi, cs); + num_chunks = 0; + write_offset = 0; + memset(data, 0, sizeof(data)); + + llc.reset(); + llc.put_frame(llc_data, 30); + + ar = Encoding::rlc_data_to_dl_append(&rdbi, + &llc, &write_offset, &num_chunks, data, false); + + OSMO_ASSERT(ar == Encoding::AR_NEED_MORE_BLOCKS); + OSMO_ASSERT(rdbi.e == 1); + OSMO_ASSERT(write_offset == 20); + OSMO_ASSERT(num_chunks == 1); + + OSMO_ASSERT(data[0] == 0); + + /* Block 2 */ + gprs_rlc_data_block_info_init(&rdbi, cs); + num_chunks = 0; + write_offset = 0; + memset(data, 0, sizeof(data)); + + OSMO_ASSERT(llc.chunk_size() == 10); + + ar = Encoding::rlc_data_to_dl_append(&rdbi, + &llc, &write_offset, &num_chunks, data, false); + + OSMO_ASSERT(ar == Encoding::AR_COMPLETED_SPACE_LEFT); + OSMO_ASSERT(rdbi.e == 0); + OSMO_ASSERT(write_offset == 1 + 10); + OSMO_ASSERT(num_chunks == 1); + + llc.reset(); + llc.put_frame(llc_data, 99); + + ar = Encoding::rlc_data_to_dl_append(&rdbi, + &llc, &write_offset, &num_chunks, data, false); + + OSMO_ASSERT(ar == Encoding::AR_NEED_MORE_BLOCKS); + OSMO_ASSERT(rdbi.e == 0); + OSMO_ASSERT(write_offset == 1 + 10 + 9); + OSMO_ASSERT(num_chunks == 2); + + OSMO_ASSERT(data[0] == ((10 << 2) | (1 << 1) | (1 << 0))); + OSMO_ASSERT(data[1] == 0); + + printf("=== end %s ===\n", __func__); +} + static void test_rlc_unaligned_copy() { uint8_t bits[256]; @@ -614,6 +864,7 @@ int main(int argc, char **argv) test_rlc_info_init(); test_rlc_unit_decoder(); test_rlc_unaligned_copy(); + test_rlc_unit_encoder(); if (getenv("TALLOC_REPORT_FULL")) talloc_report_full(tall_pcu_ctx, stderr); diff --git a/tests/edge/EdgeTest.ok b/tests/edge/EdgeTest.ok index 95ec2b3a..9554df35 100644 --- a/tests/edge/EdgeTest.ok +++ b/tests/edge/EdgeTest.ok @@ -4,3 +4,5 @@ === end test_rlc_info_init === === start test_rlc_unit_decoder === === end test_rlc_unit_decoder === +=== start test_rlc_unit_encoder === +=== end test_rlc_unit_encoder === -- cgit v1.2.3