blob: c5fde2ea621d850a2db5a2e0c1f8cdab5be42459 [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;
32 int verify;
33} 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 },
43 .ucmp_len = 194, .verify = 1
44 },
45 { .crbb_len = 40, .cc = 1,
46 .crbb_data = {
47 0x53, 0x06, 0xc5, 0x40, 0x6d
48 },
49 .ucmp_data = {
50 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00,
51 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8,
Neels Hofmeyr5382e0f2017-03-26 23:39:44 +020052 0x00, 0x00, 0x00, 0x00, 0x00
Pravin Kumarvel0a4a6c12016-10-17 11:00:57 +053053 },
54 .ucmp_len = 182, .verify = 1
55 },
56 { .crbb_len = 8, .cc = 1,
57 .crbb_data = {0x02},
58 .ucmp_data = {0xff, 0xff, 0xff, 0xf8},
59 .ucmp_len = 29, .verify = 1
60 },
61 { .crbb_len = 103, .cc = 1,
62 .crbb_data = {
63 0x02, 0x0c, 0xe0, 0x41, 0xa0, 0x0c, 0x36, 0x0d, 0x03,
64 0x71, 0xb0, 0x6e, 0x24
65 },
66 .ucmp_data = {
67 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0xff, 0xff, 0xff,
68 0xf8, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xfe, 0x00, 0x00,
69 0x0f, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x7f, 0xff,
70 0xff, 0xff, 0x80, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff
71 },
72 .ucmp_len = 288, .verify = 1
73 },
74 /* Test vector from libosmocore test */
75 { .crbb_len = 35, .cc = 0,
76 .crbb_data = {0xde, 0x88, 0x75, 0x65, 0x80},
77 .ucmp_data = {0x37, 0x47, 0x81, 0xf0},
78 .ucmp_len = 28, .verify = 1
79 },
80 { .crbb_len = 18, .cc = 1,
81 .crbb_data = {0xdd, 0x41, 0x00},
82 .ucmp_data = {
83 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
84 0xff, 0x00, 0x00
85 },
86 .ucmp_len = 90, .verify = 1
87 },
88 /*Invalid inputs*/
89 { .crbb_len = 18, .cc = 1,
90 .crbb_data = {0x1E, 0x70, 0xc0},
91 .ucmp_data = {0x0},
92 .ucmp_len = 0, .verify = 0
93 },
94 { .crbb_len = 14, .cc = 1,
95 .crbb_data = {0x00, 0x1E, 0x7c},
96 .ucmp_data = {0x0},
97 .ucmp_len = 0, .verify = 0
98 },
99 { .crbb_len = 24, .cc = 0,
100 .crbb_data = {0x00, 0x00, 0x00},
101 .ucmp_data = {0x0},
102 .ucmp_len = 0, .verify = 0
103 }
104 };
105
106static const struct log_info_cat default_categories[] = {
107 {"DCSN1", "\033[1;31m", "Concrete Syntax Notation One (CSN1)", LOGL_INFO, 0},
108 {"DL1IF", "\033[1;32m", "GPRS PCU L1 interface (L1IF)", LOGL_DEBUG, 1},
109 {"DRLCMAC", "\033[0;33m", "GPRS RLC/MAC layer (RLCMAC)", LOGL_DEBUG, 1},
110 {"DRLCMACDATA", "\033[0;33m", "GPRS RLC/MAC layer Data (RLCMAC)", LOGL_DEBUG, 1},
111 {"DRLCMACDL", "\033[1;33m", "GPRS RLC/MAC layer Downlink (RLCMAC)", LOGL_DEBUG, 1},
112 {"DRLCMACUL", "\033[1;36m", "GPRS RLC/MAC layer Uplink (RLCMAC)", LOGL_DEBUG, 1},
113 {"DRLCMACSCHED", "\033[0;36m", "GPRS RLC/MAC layer Scheduling (RLCMAC)", LOGL_DEBUG, 1},
114 {"DRLCMACMEAS", "\033[1;31m", "GPRS RLC/MAC layer Measurements (RLCMAC)", LOGL_INFO, 1},
115 {"DNS", "\033[1;34m", "GPRS Network Service Protocol (NS)", LOGL_INFO, 1},
116 {"DBSSGP", "\033[1;34m", "GPRS BSS Gateway Protocol (BSSGP)", LOGL_INFO, 1},
117 {"DPCU", "\033[1;35m", "GPRS Packet Control Unit (PCU)", LOGL_NOTICE, 1},
118};
119
120static int filter_fn(const struct log_context *ctx,
121 struct log_target *tar)
122{
123 return 1;
124}
125
Neels Hofmeyr77839642017-03-26 23:12:26 +0200126bool result_matches(const bitvec &bits, const uint8_t *exp_data, unsigned int exp_len)
Pravin Kumarvel0a4a6c12016-10-17 11:00:57 +0530127{
128 if (bits.cur_bit != exp_len)
Neels Hofmeyr77839642017-03-26 23:12:26 +0200129 return false;
Neels Hofmeyr5382e0f2017-03-26 23:39:44 +0200130 return (memcmp(exp_data, bits.data, CEIL_DIV_8(exp_len)) == 0);
Pravin Kumarvel0a4a6c12016-10-17 11:00:57 +0530131}
132
133/* To test decoding of compressed bitmap by Tree based method
134 * and to verify the result with expected result
135 * for invalid input verfication is suppressed
136 */
137static void test_EPDAN_decode_tree(void)
138{
139 bitvec dest;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +0100140 unsigned int itr;
Pravin Kumarvel0a4a6c12016-10-17 11:00:57 +0530141 int rc;
142 uint8_t bits_data[RLC_EGPRS_MAX_WS/8];
143
144 printf("=== start %s ===\n", __func__);
145
146 for (itr = 0 ; itr < (sizeof(test) / sizeof(test_data)) ; itr++) {
Neels Hofmeyr77839642017-03-26 23:12:26 +0200147 memset(bits_data, 0, sizeof(bits_data));
Pravin Kumarvel0a4a6c12016-10-17 11:00:57 +0530148 dest.data = bits_data;
149 dest.data_len = sizeof(bits_data);
150 dest.cur_bit = 0;
Neels Hofmeyrdd1700a2017-03-26 23:21:16 +0200151 _LOG("\nTest:%d\n"
Neels Hofmeyr77839642017-03-26 23:12:26 +0200152 "Tree based decoding:\n"
153 "uncompressed data = %s\n"
154 "len = %d\n",
155 itr + 1,
156 osmo_hexdump(test[itr].crbb_data,
157 CEIL_DIV_8(test[itr].crbb_len)),
158 test[itr].crbb_len);
Pravin Kumarvel0a4a6c12016-10-17 11:00:57 +0530159 rc = egprs_compress::decompress_crbb(test[itr].crbb_len,
160 test[itr].cc, test[itr].crbb_data, &dest);
161 if (rc < 0) {
Neels Hofmeyrdd1700a2017-03-26 23:21:16 +0200162 _LOG("\nFailed to decode CRBB: length %d, data %s",
Neels Hofmeyr77839642017-03-26 23:12:26 +0200163 test[itr].crbb_len,
164 osmo_hexdump(test[itr].crbb_data,
165 CEIL_DIV_8(test[itr].crbb_len)));
Pravin Kumarvel0a4a6c12016-10-17 11:00:57 +0530166 }
Pravin Kumarvel0a4a6c12016-10-17 11:00:57 +0530167 if (test[itr].verify) {
Neels Hofmeyr77839642017-03-26 23:12:26 +0200168 if (!result_matches(dest, test[itr].ucmp_data,
169 test[itr].ucmp_len)) {
Neels Hofmeyrdd1700a2017-03-26 23:21:16 +0200170 _LOG("\nTree based decoding: Error\n"
Neels Hofmeyr77839642017-03-26 23:12:26 +0200171 "expected data = %s\n"
Neels Hofmeyrdd1700a2017-03-26 23:21:16 +0200172 "expected len = %d\n",
Neels Hofmeyr77839642017-03-26 23:12:26 +0200173 osmo_hexdump(test[itr].ucmp_data,
174 CEIL_DIV_8(test[itr].ucmp_len)),
Neels Hofmeyrdd1700a2017-03-26 23:21:16 +0200175 test[itr].ucmp_len);
176 _LOG("decoded data = %s\n"
177 "decoded len = %d\n",
Neels Hofmeyr77839642017-03-26 23:12:26 +0200178 osmo_hexdump(dest.data,
179 CEIL_DIV_8(dest.cur_bit)),
180 dest.cur_bit);
Pravin Kumarvel0a4a6c12016-10-17 11:00:57 +0530181 OSMO_ASSERT(0);
182 }
183 }
Neels Hofmeyrdd1700a2017-03-26 23:21:16 +0200184 _LOG("\nexpected data = %s\n"
185 "expected len = %d\n",
Neels Hofmeyr77839642017-03-26 23:12:26 +0200186 osmo_hexdump(test[itr].ucmp_data,
187 CEIL_DIV_8(test[itr].ucmp_len)),
Neels Hofmeyrdd1700a2017-03-26 23:21:16 +0200188 test[itr].ucmp_len);
189 _LOG("decoded data = %s\n"
190 "decoded len = %d\n",
Neels Hofmeyr77839642017-03-26 23:12:26 +0200191 osmo_hexdump(dest.data, CEIL_DIV_8(dest.cur_bit)),
192 dest.cur_bit);
Pravin Kumarvel0a4a6c12016-10-17 11:00:57 +0530193 }
194
195 printf("=== end %s ===\n", __func__);
196}
197
198const struct log_info debug_log_info = {
199 filter_fn,
200 (struct log_info_cat *)default_categories,
201 ARRAY_SIZE(default_categories),
202};
203
204int main(int argc, char **argv)
205{
206 osmo_init_logging(&debug_log_info);
207 log_set_use_color(osmo_stderr_target, 0);
208 log_set_print_filename(osmo_stderr_target, 0);
209
210 tall_pcu_ctx = talloc_named_const(NULL, 1, "moiji-mobile bitcompTest context");
211 if (!tall_pcu_ctx)
212 abort();
213
214 test_EPDAN_decode_tree();
215
216 if (getenv("TALLOC_REPORT_FULL"))
217 talloc_report_full(tall_pcu_ctx, stderr);
218 talloc_free(tall_pcu_ctx);
219 return EXIT_SUCCESS;
220}
221
222/*
223 * stubs that should not be reached
224 */
225extern "C" {
226void l1if_pdch_req() { abort(); }
227void l1if_connect_pdch() { abort(); }
228void l1if_close_pdch() { abort(); }
229void l1if_open_pdch() { abort(); }
230}
231