blob: f35d6bec4fc5b27dc7893d85facda4ae2077d9ae [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,
41 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xdb
42 },
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,
52 0x00, 0x00, 0x00, 0x00, 0x03
53 },
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;
Pravin Kumarvel0a4a6c12016-10-17 11:00:57 +0530130 size_t n = (exp_len / 8);
131 int rem = (exp_len % 8);
132
133 if (memcmp(exp_data, bits.data, n) == 0) {
134 if (rem == 0)
Neels Hofmeyr77839642017-03-26 23:12:26 +0200135 return true;
Pravin Kumarvel0a4a6c12016-10-17 11:00:57 +0530136 if ((bits.data[n] & MASK(rem)) == ((*(exp_data + n)) & MASK(rem)))
Neels Hofmeyr77839642017-03-26 23:12:26 +0200137 return true;
Pravin Kumarvel0a4a6c12016-10-17 11:00:57 +0530138 else
Neels Hofmeyr77839642017-03-26 23:12:26 +0200139 return false;
Pravin Kumarvel0a4a6c12016-10-17 11:00:57 +0530140 } else
Neels Hofmeyr77839642017-03-26 23:12:26 +0200141 return false;
Pravin Kumarvel0a4a6c12016-10-17 11:00:57 +0530142}
143
144/* To test decoding of compressed bitmap by Tree based method
145 * and to verify the result with expected result
146 * for invalid input verfication is suppressed
147 */
148static void test_EPDAN_decode_tree(void)
149{
150 bitvec dest;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +0100151 unsigned int itr;
Pravin Kumarvel0a4a6c12016-10-17 11:00:57 +0530152 int rc;
153 uint8_t bits_data[RLC_EGPRS_MAX_WS/8];
154
155 printf("=== start %s ===\n", __func__);
156
157 for (itr = 0 ; itr < (sizeof(test) / sizeof(test_data)) ; itr++) {
Neels Hofmeyr77839642017-03-26 23:12:26 +0200158 memset(bits_data, 0, sizeof(bits_data));
Pravin Kumarvel0a4a6c12016-10-17 11:00:57 +0530159 dest.data = bits_data;
160 dest.data_len = sizeof(bits_data);
161 dest.cur_bit = 0;
Neels Hofmeyrdd1700a2017-03-26 23:21:16 +0200162 _LOG("\nTest:%d\n"
Neels Hofmeyr77839642017-03-26 23:12:26 +0200163 "Tree based decoding:\n"
164 "uncompressed data = %s\n"
165 "len = %d\n",
166 itr + 1,
167 osmo_hexdump(test[itr].crbb_data,
168 CEIL_DIV_8(test[itr].crbb_len)),
169 test[itr].crbb_len);
Pravin Kumarvel0a4a6c12016-10-17 11:00:57 +0530170 rc = egprs_compress::decompress_crbb(test[itr].crbb_len,
171 test[itr].cc, test[itr].crbb_data, &dest);
172 if (rc < 0) {
Neels Hofmeyrdd1700a2017-03-26 23:21:16 +0200173 _LOG("\nFailed to decode CRBB: length %d, data %s",
Neels Hofmeyr77839642017-03-26 23:12:26 +0200174 test[itr].crbb_len,
175 osmo_hexdump(test[itr].crbb_data,
176 CEIL_DIV_8(test[itr].crbb_len)));
Pravin Kumarvel0a4a6c12016-10-17 11:00:57 +0530177 }
Pravin Kumarvel0a4a6c12016-10-17 11:00:57 +0530178 if (test[itr].verify) {
Neels Hofmeyr77839642017-03-26 23:12:26 +0200179 if (!result_matches(dest, test[itr].ucmp_data,
180 test[itr].ucmp_len)) {
Neels Hofmeyrdd1700a2017-03-26 23:21:16 +0200181 _LOG("\nTree based decoding: Error\n"
Neels Hofmeyr77839642017-03-26 23:12:26 +0200182 "expected data = %s\n"
Neels Hofmeyrdd1700a2017-03-26 23:21:16 +0200183 "expected len = %d\n",
Neels Hofmeyr77839642017-03-26 23:12:26 +0200184 osmo_hexdump(test[itr].ucmp_data,
185 CEIL_DIV_8(test[itr].ucmp_len)),
Neels Hofmeyrdd1700a2017-03-26 23:21:16 +0200186 test[itr].ucmp_len);
187 _LOG("decoded data = %s\n"
188 "decoded len = %d\n",
Neels Hofmeyr77839642017-03-26 23:12:26 +0200189 osmo_hexdump(dest.data,
190 CEIL_DIV_8(dest.cur_bit)),
191 dest.cur_bit);
Pravin Kumarvel0a4a6c12016-10-17 11:00:57 +0530192 OSMO_ASSERT(0);
193 }
194 }
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