blob: 4ec6f2956b4ad08d9b70b1de064f106e99af1559 [file] [log] [blame]
Pravin Kumarvel0a4a6c12016-10-17 11:00:57 +05301#include <stdint.h>
2#include <string.h>
3
4#include "rlc.h"
5#include "gprs_debug.h"
6#include <gprs_rlcmac.h>
7#include "egprs_rlc_compression.h"
8
9extern "C" {
10#include <osmocom/core/logging.h>
11#include <osmocom/core/bitvec.h>
12#include <osmocom/core/utils.h>
13#include <osmocom/core/application.h>
14}
15
16#define NEW 1
17#define MASK(n) (0xFF << (8-n))
18#define MAX_CRBB_LEN 23
19#define MAX_URBB_LEN 40
Neels Hofmeyr77839642017-03-26 23:12:26 +020020#define CEIL_DIV_8(x) (((x) + 7)/8)
Neels Hofmeyrdd1700a2017-03-26 23:21:16 +020021#define _LOG(fmt, args...) \
22 fprintf(stderr, fmt, ## args)
Pravin Kumarvel0a4a6c12016-10-17 11:00:57 +053023
24void *tall_pcu_ctx;
25
26struct test_data {
27 int8_t crbb_len;
28 uint8_t cc;
29 uint8_t crbb_data[MAX_CRBB_LEN]; /* compressed data */
30 uint8_t ucmp_data[MAX_URBB_LEN]; /* uncompressed data */
31 int ucmp_len;
Neels Hofmeyre6d26ec2017-03-27 00:13:14 +020032 int expect_rc;
Pravin Kumarvel0a4a6c12016-10-17 11:00:57 +053033} test[] = {
34 { .crbb_len = 67, .cc = 1,
35 .crbb_data = {
36 0x02, 0x0c, 0xa0, 0x30, 0xcb, 0x1a, 0x0c, 0xe3, 0x6c
37 },
38 .ucmp_data = {
39 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x01, 0xff, 0xff,
40 0xff, 0xf8, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xfe,
Neels Hofmeyr5382e0f2017-03-26 23:39:44 +020041 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0
Pravin Kumarvel0a4a6c12016-10-17 11:00:57 +053042 },
Neels Hofmeyre6d26ec2017-03-27 00:13:14 +020043 .ucmp_len = 194,
44 .expect_rc = 0,
Pravin Kumarvel0a4a6c12016-10-17 11:00:57 +053045 },
46 { .crbb_len = 40, .cc = 1,
47 .crbb_data = {
48 0x53, 0x06, 0xc5, 0x40, 0x6d
49 },
50 .ucmp_data = {
51 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00,
52 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8,
Neels Hofmeyr5382e0f2017-03-26 23:39:44 +020053 0x00, 0x00, 0x00, 0x00, 0x00
Pravin Kumarvel0a4a6c12016-10-17 11:00:57 +053054 },
Neels Hofmeyre6d26ec2017-03-27 00:13:14 +020055 .ucmp_len = 182,
56 .expect_rc = 0,
Pravin Kumarvel0a4a6c12016-10-17 11:00:57 +053057 },
58 { .crbb_len = 8, .cc = 1,
59 .crbb_data = {0x02},
60 .ucmp_data = {0xff, 0xff, 0xff, 0xf8},
Neels Hofmeyre6d26ec2017-03-27 00:13:14 +020061 .ucmp_len = 29,
62 .expect_rc = 0,
Pravin Kumarvel0a4a6c12016-10-17 11:00:57 +053063 },
64 { .crbb_len = 103, .cc = 1,
65 .crbb_data = {
66 0x02, 0x0c, 0xe0, 0x41, 0xa0, 0x0c, 0x36, 0x0d, 0x03,
67 0x71, 0xb0, 0x6e, 0x24
68 },
69 .ucmp_data = {
70 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0xff, 0xff, 0xff,
71 0xf8, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xfe, 0x00, 0x00,
72 0x0f, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x7f, 0xff,
73 0xff, 0xff, 0x80, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff
74 },
Neels Hofmeyre6d26ec2017-03-27 00:13:14 +020075 .ucmp_len = 288,
76 .expect_rc = 0,
Pravin Kumarvel0a4a6c12016-10-17 11:00:57 +053077 },
78 /* Test vector from libosmocore test */
79 { .crbb_len = 35, .cc = 0,
80 .crbb_data = {0xde, 0x88, 0x75, 0x65, 0x80},
81 .ucmp_data = {0x37, 0x47, 0x81, 0xf0},
Neels Hofmeyre6d26ec2017-03-27 00:13:14 +020082 .ucmp_len = 28,
83 .expect_rc = 0,
Pravin Kumarvel0a4a6c12016-10-17 11:00:57 +053084 },
85 { .crbb_len = 18, .cc = 1,
86 .crbb_data = {0xdd, 0x41, 0x00},
87 .ucmp_data = {
88 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
89 0xff, 0x00, 0x00
90 },
Neels Hofmeyre6d26ec2017-03-27 00:13:14 +020091 .ucmp_len = 90,
92 .expect_rc = 0,
Pravin Kumarvel0a4a6c12016-10-17 11:00:57 +053093 },
Neels Hofmeyre6d26ec2017-03-27 00:13:14 +020094 /* TODO: previously marked as "Invalid inputs" but succeeds */
Pravin Kumarvel0a4a6c12016-10-17 11:00:57 +053095 { .crbb_len = 18, .cc = 1,
96 .crbb_data = {0x1E, 0x70, 0xc0},
Neels Hofmeyre6d26ec2017-03-27 00:13:14 +020097 .ucmp_data = {0xb0, 0x00, 0x00},
98 .ucmp_len = 19,
99 .expect_rc = 0,
Pravin Kumarvel0a4a6c12016-10-17 11:00:57 +0530100 },
Neels Hofmeyre6d26ec2017-03-27 00:13:14 +0200101 /* Invalid inputs */
Pravin Kumarvel0a4a6c12016-10-17 11:00:57 +0530102 { .crbb_len = 14, .cc = 1,
103 .crbb_data = {0x00, 0x1E, 0x7c},
104 .ucmp_data = {0x0},
Neels Hofmeyre6d26ec2017-03-27 00:13:14 +0200105 .ucmp_len = 0,
106 .expect_rc = -1,
Pravin Kumarvel0a4a6c12016-10-17 11:00:57 +0530107 },
108 { .crbb_len = 24, .cc = 0,
109 .crbb_data = {0x00, 0x00, 0x00},
110 .ucmp_data = {0x0},
Neels Hofmeyre6d26ec2017-03-27 00:13:14 +0200111 .ucmp_len = 0,
112 .expect_rc = -1,
Pravin Kumarvel0a4a6c12016-10-17 11:00:57 +0530113 }
114 };
115
116static const struct log_info_cat default_categories[] = {
117 {"DCSN1", "\033[1;31m", "Concrete Syntax Notation One (CSN1)", LOGL_INFO, 0},
118 {"DL1IF", "\033[1;32m", "GPRS PCU L1 interface (L1IF)", LOGL_DEBUG, 1},
119 {"DRLCMAC", "\033[0;33m", "GPRS RLC/MAC layer (RLCMAC)", LOGL_DEBUG, 1},
120 {"DRLCMACDATA", "\033[0;33m", "GPRS RLC/MAC layer Data (RLCMAC)", LOGL_DEBUG, 1},
121 {"DRLCMACDL", "\033[1;33m", "GPRS RLC/MAC layer Downlink (RLCMAC)", LOGL_DEBUG, 1},
122 {"DRLCMACUL", "\033[1;36m", "GPRS RLC/MAC layer Uplink (RLCMAC)", LOGL_DEBUG, 1},
123 {"DRLCMACSCHED", "\033[0;36m", "GPRS RLC/MAC layer Scheduling (RLCMAC)", LOGL_DEBUG, 1},
124 {"DRLCMACMEAS", "\033[1;31m", "GPRS RLC/MAC layer Measurements (RLCMAC)", LOGL_INFO, 1},
125 {"DNS", "\033[1;34m", "GPRS Network Service Protocol (NS)", LOGL_INFO, 1},
126 {"DBSSGP", "\033[1;34m", "GPRS BSS Gateway Protocol (BSSGP)", LOGL_INFO, 1},
127 {"DPCU", "\033[1;35m", "GPRS Packet Control Unit (PCU)", LOGL_NOTICE, 1},
128};
129
130static int filter_fn(const struct log_context *ctx,
131 struct log_target *tar)
132{
133 return 1;
134}
135
Neels Hofmeyr77839642017-03-26 23:12:26 +0200136bool result_matches(const bitvec &bits, const uint8_t *exp_data, unsigned int exp_len)
Pravin Kumarvel0a4a6c12016-10-17 11:00:57 +0530137{
138 if (bits.cur_bit != exp_len)
Neels Hofmeyr77839642017-03-26 23:12:26 +0200139 return false;
Neels Hofmeyr5382e0f2017-03-26 23:39:44 +0200140 return (memcmp(exp_data, bits.data, CEIL_DIV_8(exp_len)) == 0);
Pravin Kumarvel0a4a6c12016-10-17 11:00:57 +0530141}
142
143/* To test decoding of compressed bitmap by Tree based method
144 * and to verify the result with expected result
145 * for invalid input verfication is suppressed
146 */
147static void test_EPDAN_decode_tree(void)
148{
149 bitvec dest;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +0100150 unsigned int itr;
Pravin Kumarvel0a4a6c12016-10-17 11:00:57 +0530151 int rc;
152 uint8_t bits_data[RLC_EGPRS_MAX_WS/8];
153
154 printf("=== start %s ===\n", __func__);
155
156 for (itr = 0 ; itr < (sizeof(test) / sizeof(test_data)) ; itr++) {
Neels Hofmeyr77839642017-03-26 23:12:26 +0200157 memset(bits_data, 0, sizeof(bits_data));
Pravin Kumarvel0a4a6c12016-10-17 11:00:57 +0530158 dest.data = bits_data;
159 dest.data_len = sizeof(bits_data);
160 dest.cur_bit = 0;
Neels Hofmeyrdd1700a2017-03-26 23:21:16 +0200161 _LOG("\nTest:%d\n"
Neels Hofmeyr77839642017-03-26 23:12:26 +0200162 "Tree based decoding:\n"
163 "uncompressed data = %s\n"
164 "len = %d\n",
165 itr + 1,
166 osmo_hexdump(test[itr].crbb_data,
167 CEIL_DIV_8(test[itr].crbb_len)),
168 test[itr].crbb_len);
Pravin Kumarvel0a4a6c12016-10-17 11:00:57 +0530169 rc = egprs_compress::decompress_crbb(test[itr].crbb_len,
170 test[itr].cc, test[itr].crbb_data, &dest);
Neels Hofmeyre6d26ec2017-03-27 00:13:14 +0200171 _LOG("rc = %d\n", rc);
172 OSMO_ASSERT(test[itr].expect_rc == rc);
Pravin Kumarvel0a4a6c12016-10-17 11:00:57 +0530173 if (rc < 0) {
Neels Hofmeyre6d26ec2017-03-27 00:13:14 +0200174 _LOG("Failed to decode CRBB: length %d, data %s\n",
Neels Hofmeyr77839642017-03-26 23:12:26 +0200175 test[itr].crbb_len,
176 osmo_hexdump(test[itr].crbb_data,
177 CEIL_DIV_8(test[itr].crbb_len)));
Neels Hofmeyre6d26ec2017-03-27 00:13:14 +0200178 continue;
Pravin Kumarvel0a4a6c12016-10-17 11:00:57 +0530179 }
Neels Hofmeyre6d26ec2017-03-27 00:13:14 +0200180 if (!result_matches(dest, test[itr].ucmp_data,
181 test[itr].ucmp_len)) {
182 _LOG("\nTree based decoding: Error\n"
183 "expected data = %s\n"
184 "expected len = %d\n",
185 osmo_hexdump(test[itr].ucmp_data,
186 CEIL_DIV_8(test[itr].ucmp_len)),
187 test[itr].ucmp_len);
188 _LOG("decoded data = %s\n"
189 "decoded len = %d\n",
190 osmo_hexdump(dest.data,
191 CEIL_DIV_8(dest.cur_bit)),
192 dest.cur_bit);
193 OSMO_ASSERT(0);
Pravin Kumarvel0a4a6c12016-10-17 11:00:57 +0530194 }
Neels Hofmeyrdd1700a2017-03-26 23:21:16 +0200195 _LOG("\nexpected data = %s\n"
196 "expected len = %d\n",
Neels Hofmeyr77839642017-03-26 23:12:26 +0200197 osmo_hexdump(test[itr].ucmp_data,
198 CEIL_DIV_8(test[itr].ucmp_len)),
Neels Hofmeyrdd1700a2017-03-26 23:21:16 +0200199 test[itr].ucmp_len);
200 _LOG("decoded data = %s\n"
201 "decoded len = %d\n",
Neels Hofmeyr77839642017-03-26 23:12:26 +0200202 osmo_hexdump(dest.data, CEIL_DIV_8(dest.cur_bit)),
203 dest.cur_bit);
Pravin Kumarvel0a4a6c12016-10-17 11:00:57 +0530204 }
205
206 printf("=== end %s ===\n", __func__);
207}
208
209const struct log_info debug_log_info = {
210 filter_fn,
211 (struct log_info_cat *)default_categories,
212 ARRAY_SIZE(default_categories),
213};
214
215int main(int argc, char **argv)
216{
217 osmo_init_logging(&debug_log_info);
218 log_set_use_color(osmo_stderr_target, 0);
219 log_set_print_filename(osmo_stderr_target, 0);
220
221 tall_pcu_ctx = talloc_named_const(NULL, 1, "moiji-mobile bitcompTest context");
222 if (!tall_pcu_ctx)
223 abort();
224
225 test_EPDAN_decode_tree();
226
227 if (getenv("TALLOC_REPORT_FULL"))
228 talloc_report_full(tall_pcu_ctx, stderr);
229 talloc_free(tall_pcu_ctx);
230 return EXIT_SUCCESS;
231}
232
233/*
234 * stubs that should not be reached
235 */
236extern "C" {
237void l1if_pdch_req() { abort(); }
238void l1if_connect_pdch() { abort(); }
239void l1if_close_pdch() { abort(); }
240void l1if_open_pdch() { abort(); }
241}
242