218 lines
5.6 KiB
C++
218 lines
5.6 KiB
C++
#include <stdint.h>
|
|
#include <string.h>
|
|
|
|
#include "rlc.h"
|
|
#include "gprs_debug.h"
|
|
#include <gprs_rlcmac.h>
|
|
#include "egprs_rlc_compression.h"
|
|
|
|
extern "C" {
|
|
#include <osmocom/core/logging.h>
|
|
#include <osmocom/core/bitvec.h>
|
|
#include <osmocom/core/utils.h>
|
|
#include <osmocom/core/application.h>
|
|
}
|
|
|
|
#define NEW 1
|
|
#define MASK(n) (0xFF << (8-n))
|
|
#define MAX_CRBB_LEN 23
|
|
#define MAX_URBB_LEN 40
|
|
#define CEIL_DIV_8(x) (((x) + 7)/8)
|
|
#define _LOG(fmt, args...) \
|
|
fprintf(stderr, fmt, ## args)
|
|
|
|
void *tall_pcu_ctx;
|
|
|
|
struct test_data {
|
|
int8_t crbb_len;
|
|
uint8_t cc;
|
|
uint8_t crbb_data[MAX_CRBB_LEN]; /* compressed data */
|
|
uint8_t ucmp_data[MAX_URBB_LEN]; /* uncompressed data */
|
|
int ucmp_len;
|
|
int expect_rc;
|
|
} test[] = {
|
|
{ .crbb_len = 67, .cc = 1,
|
|
.crbb_data = {
|
|
0x02, 0x0c, 0xa0, 0x30, 0xcb, 0x1a, 0x0c, 0xe3, 0x6c
|
|
},
|
|
.ucmp_data = {
|
|
0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x01, 0xff, 0xff,
|
|
0xff, 0xf8, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xfe,
|
|
0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0
|
|
},
|
|
.ucmp_len = 194,
|
|
.expect_rc = 0,
|
|
},
|
|
{ .crbb_len = 40, .cc = 1,
|
|
.crbb_data = {
|
|
0x53, 0x06, 0xc5, 0x40, 0x6d
|
|
},
|
|
.ucmp_data = {
|
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00,
|
|
0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8,
|
|
0x00, 0x00, 0x00, 0x00, 0x00
|
|
},
|
|
.ucmp_len = 182,
|
|
.expect_rc = 0,
|
|
},
|
|
{ .crbb_len = 8, .cc = 1,
|
|
.crbb_data = {0x02},
|
|
.ucmp_data = {0xff, 0xff, 0xff, 0xf8},
|
|
.ucmp_len = 29,
|
|
.expect_rc = 0,
|
|
},
|
|
{ .crbb_len = 103, .cc = 1,
|
|
.crbb_data = {
|
|
0x02, 0x0c, 0xe0, 0x41, 0xa0, 0x0c, 0x36, 0x0d, 0x03,
|
|
0x71, 0xb0, 0x6e, 0x24
|
|
},
|
|
.ucmp_data = {
|
|
0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0xff, 0xff, 0xff,
|
|
0xf8, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xfe, 0x00, 0x00,
|
|
0x0f, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x7f, 0xff,
|
|
0xff, 0xff, 0x80, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff
|
|
},
|
|
.ucmp_len = 288,
|
|
.expect_rc = 0,
|
|
},
|
|
/* Test vector from libosmocore test */
|
|
{ .crbb_len = 35, .cc = 0,
|
|
.crbb_data = {0xde, 0x88, 0x75, 0x65, 0x80},
|
|
.ucmp_data = {0x37, 0x47, 0x81, 0xf0},
|
|
.ucmp_len = 28,
|
|
.expect_rc = 0,
|
|
},
|
|
{ .crbb_len = 18, .cc = 1,
|
|
.crbb_data = {0xdd, 0x41, 0x00},
|
|
.ucmp_data = {
|
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
0xff, 0x00, 0x00
|
|
},
|
|
.ucmp_len = 90,
|
|
.expect_rc = 0,
|
|
},
|
|
/* Invalid inputs */
|
|
{ .crbb_len = 18, .cc = 1,
|
|
.crbb_data = {0x1E, 0x70, 0xc0},
|
|
.ucmp_data = {0xb0, 0x00, 0x00},
|
|
.ucmp_len = 19,
|
|
.expect_rc = -1,
|
|
},
|
|
{ .crbb_len = 14, .cc = 1,
|
|
.crbb_data = {0x00, 0x1E, 0x7c},
|
|
.ucmp_data = {0x0},
|
|
.ucmp_len = 0,
|
|
.expect_rc = -1,
|
|
},
|
|
{ .crbb_len = 24, .cc = 0,
|
|
.crbb_data = {0x00, 0x00, 0x00},
|
|
.ucmp_data = {0x0},
|
|
.ucmp_len = 0,
|
|
.expect_rc = -1,
|
|
}
|
|
};
|
|
|
|
bool result_matches(const bitvec &bits, const uint8_t *exp_data, unsigned int exp_len)
|
|
{
|
|
if (bits.cur_bit != exp_len)
|
|
return false;
|
|
return (memcmp(exp_data, bits.data, CEIL_DIV_8(exp_len)) == 0);
|
|
}
|
|
|
|
/* To test decoding of compressed bitmap by Tree based method
|
|
* and to verify the result with expected result
|
|
* for invalid input verfication is suppressed
|
|
*/
|
|
static void test_EPDAN_decode_tree(void)
|
|
{
|
|
bitvec dest;
|
|
unsigned int itr;
|
|
int rc;
|
|
uint8_t bits_data[RLC_EGPRS_MAX_WS/8];
|
|
|
|
printf("=== start %s ===\n", __func__);
|
|
|
|
for (itr = 0 ; itr < (sizeof(test) / sizeof(test_data)) ; itr++) {
|
|
memset(bits_data, 0, sizeof(bits_data));
|
|
dest.data = bits_data;
|
|
dest.data_len = sizeof(bits_data);
|
|
dest.cur_bit = 0;
|
|
_LOG("\nTest:%d\n"
|
|
"Tree based decoding:\n"
|
|
"compressed data = %s\n"
|
|
"len = %d\n",
|
|
itr + 1,
|
|
osmo_hexdump(test[itr].crbb_data,
|
|
CEIL_DIV_8(test[itr].crbb_len)),
|
|
test[itr].crbb_len);
|
|
rc = egprs_compress::decompress_crbb(test[itr].crbb_len,
|
|
test[itr].cc, test[itr].crbb_data, &dest);
|
|
_LOG("rc = %d\n", rc);
|
|
OSMO_ASSERT(test[itr].expect_rc == rc);
|
|
if (rc < 0) {
|
|
_LOG("Failed to decode CRBB: length %d, data %s\n",
|
|
test[itr].crbb_len,
|
|
osmo_hexdump(test[itr].crbb_data,
|
|
CEIL_DIV_8(test[itr].crbb_len)));
|
|
continue;
|
|
}
|
|
if (!result_matches(dest, test[itr].ucmp_data,
|
|
test[itr].ucmp_len)) {
|
|
_LOG("\nTree based decoding: Error\n"
|
|
"expected data = %s\n"
|
|
"expected len = %d\n",
|
|
osmo_hexdump(test[itr].ucmp_data,
|
|
CEIL_DIV_8(test[itr].ucmp_len)),
|
|
test[itr].ucmp_len);
|
|
_LOG("decoded data = %s\n"
|
|
"decoded len = %d\n",
|
|
osmo_hexdump(dest.data,
|
|
CEIL_DIV_8(dest.cur_bit)),
|
|
dest.cur_bit);
|
|
OSMO_ASSERT(0);
|
|
}
|
|
_LOG("\nexpected data = %s\n"
|
|
"expected len = %d\n",
|
|
osmo_hexdump(test[itr].ucmp_data,
|
|
CEIL_DIV_8(test[itr].ucmp_len)),
|
|
test[itr].ucmp_len);
|
|
_LOG("decoded data = %s\n"
|
|
"decoded len = %d\n",
|
|
osmo_hexdump(dest.data, CEIL_DIV_8(dest.cur_bit)),
|
|
dest.cur_bit);
|
|
}
|
|
|
|
printf("=== end %s ===\n", __func__);
|
|
}
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
tall_pcu_ctx = talloc_named_const(NULL, 1, "moiji-mobile bitcompTest context");
|
|
if (!tall_pcu_ctx)
|
|
abort();
|
|
|
|
osmo_init_logging2(tall_pcu_ctx, &gprs_log_info);
|
|
log_set_use_color(osmo_stderr_target, 0);
|
|
log_set_print_filename2(osmo_stderr_target, LOG_FILENAME_NONE);
|
|
log_set_print_category(osmo_stderr_target, 0);
|
|
log_set_print_category_hex(osmo_stderr_target, 0);
|
|
log_parse_category_mask(osmo_stderr_target, "DRLCMACUL,1");
|
|
|
|
test_EPDAN_decode_tree();
|
|
|
|
if (getenv("TALLOC_REPORT_FULL"))
|
|
talloc_report_full(tall_pcu_ctx, stderr);
|
|
talloc_free(tall_pcu_ctx);
|
|
return EXIT_SUCCESS;
|
|
}
|
|
|
|
/*
|
|
* stubs that should not be reached
|
|
*/
|
|
extern "C" {
|
|
void l1if_pdch_req() { abort(); }
|
|
void l1if_connect_pdch() { abort(); }
|
|
void l1if_close_pdch() { abort(); }
|
|
void l1if_open_pdch() { abort(); }
|
|
}
|