blob: ea9fdbebba88d10807c7f14d6f6dc2a0b0e0df04 [file] [log] [blame]
Holger Hans Peter Freyther60582202013-11-21 21:30:23 +01001/*
2 * TypesTest.cpp Test the primitive data types
3 *
4 * Copyright (C) 2013 by Holger Hans Peter Freyther
5 *
6 * All Rights Reserved
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU Affero General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU Affero General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 *
21 */
22#include "bts.h"
23#include "tbf.h"
24#include "gprs_debug.h"
Daniel Willmann0f2b5fc2013-12-11 16:49:43 +010025#include "encoding.h"
Daniel Willmannf1786a32013-12-11 18:44:49 +010026#include "decoding.h"
Holger Hans Peter Freyther60582202013-11-21 21:30:23 +010027
28extern "C" {
29#include <osmocom/core/application.h>
30#include <osmocom/core/msgb.h>
31#include <osmocom/core/talloc.h>
32#include <osmocom/core/utils.h>
33}
34
Daniel Willmannc3f43302013-12-11 16:47:19 +010035#define OSMO_ASSERT_STR_EQ(a, b) \
36 do { \
37 if (strcmp(a, b)) { \
38 printf("String mismatch:\nGot:\t%s\nWant:\t%s\n", a, b); \
39 OSMO_ASSERT(false); \
40 } \
41 } while (0)
42
Holger Hans Peter Freyther60582202013-11-21 21:30:23 +010043void *tall_pcu_ctx;
44int16_t spoof_mnc = 0, spoof_mcc = 0;
45
46static void test_llc(void)
47{
48 {
49 uint8_t data[LLC_MAX_LEN] = {1, 2, 3, 4, };
50 uint8_t out;
51 gprs_llc llc;
52 llc.init();
53
54 OSMO_ASSERT(llc.chunk_size() == 0);
55 OSMO_ASSERT(llc.remaining_space() == LLC_MAX_LEN);
56 OSMO_ASSERT(llc.frame_length() == 0);
57
58 llc.put_frame(data, 2);
59 OSMO_ASSERT(llc.remaining_space() == LLC_MAX_LEN - 2);
60 OSMO_ASSERT(llc.frame_length() == 2);
61 OSMO_ASSERT(llc.chunk_size() == 2);
62 OSMO_ASSERT(llc.frame[0] == 1);
63 OSMO_ASSERT(llc.frame[1] == 2);
64
65 llc.append_frame(&data[3], 1);
66 OSMO_ASSERT(llc.remaining_space() == LLC_MAX_LEN - 3);
67 OSMO_ASSERT(llc.frame_length() == 3);
68 OSMO_ASSERT(llc.chunk_size() == 3);
69
70 /* consume two bytes */
71 llc.consume(&out, 1);
72 OSMO_ASSERT(llc.remaining_space() == LLC_MAX_LEN - 3);
73 OSMO_ASSERT(llc.frame_length() == 3);
74 OSMO_ASSERT(llc.chunk_size() == 2);
75
76 /* check that the bytes are as we expected */
77 OSMO_ASSERT(llc.frame[0] == 1);
78 OSMO_ASSERT(llc.frame[1] == 2);
79 OSMO_ASSERT(llc.frame[2] == 4);
80
81 /* now fill the frame */
82 llc.append_frame(data, llc.remaining_space() - 1);
83 OSMO_ASSERT(llc.fits_in_current_frame(1));
84 OSMO_ASSERT(!llc.fits_in_current_frame(2));
85 }
86}
87
Holger Hans Peter Freytherc6382dd2013-11-21 21:42:20 +010088static void test_rlc()
89{
90 {
91 struct gprs_rlc_data rlc = { 0, };
92 memset(rlc.block, 0x23, RLC_MAX_LEN);
93 uint8_t *p = rlc.prepare(20);
94 OSMO_ASSERT(p == rlc.block);
95 for (int i = 0; i < 20; ++i)
96 OSMO_ASSERT(p[i] == 0x2B);
97 for (int i = 20; i < RLC_MAX_LEN; ++i)
98 OSMO_ASSERT(p[i] == 0x0);
99 }
100}
101
Holger Hans Peter Freyther95255672013-11-23 16:18:18 +0100102static void test_rlc_v_b()
103{
104 {
105 gprs_rlc_v_b vb;
106 vb.reset();
107
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100108 for (size_t i = 0; i < RLC_MAX_SNS; ++i)
Holger Hans Peter Freyther95255672013-11-23 16:18:18 +0100109 OSMO_ASSERT(vb.is_invalid(i));
110
111 vb.mark_unacked(23);
112 OSMO_ASSERT(vb.is_unacked(23));
113
114 vb.mark_nacked(23);
115 OSMO_ASSERT(vb.is_nacked(23));
116
117 vb.mark_acked(23);
118 OSMO_ASSERT(vb.is_acked(23));
119
120 vb.mark_resend(23);
121 OSMO_ASSERT(vb.is_resend(23));
122
123 vb.mark_invalid(23);
124 OSMO_ASSERT(vb.is_invalid(23));
125 }
126}
127
Holger Hans Peter Freythere9b1ebb2013-11-24 22:00:43 +0100128static void test_rlc_v_n()
129{
130 {
131 gprs_rlc_v_n vn;
132 vn.reset();
133
134 OSMO_ASSERT(!vn.is_received(0x23));
135 OSMO_ASSERT(vn.state(0x23) == ' ');
136
137 vn.mark_received(0x23);
138 OSMO_ASSERT(vn.is_received(0x23));
139 OSMO_ASSERT(vn.state(0x23) == 'R');
140
141 vn.mark_missing(0x23);
142 OSMO_ASSERT(!vn.is_received(0x23));
143 OSMO_ASSERT(vn.state(0x23) == 'N');
144 }
145}
146
Holger Hans Peter Freytherfaf3ef42013-11-24 22:17:40 +0100147static void test_rlc_dl_ul_basic()
148{
149 {
150 gprs_rlc_dl_window dl_win = { 0, };
151 OSMO_ASSERT(dl_win.window_empty());
152 OSMO_ASSERT(!dl_win.window_stalled());
153 OSMO_ASSERT(dl_win.distance() == 0);
154
155 dl_win.increment_send();
156 OSMO_ASSERT(!dl_win.window_empty());
157 OSMO_ASSERT(!dl_win.window_stalled());
158 OSMO_ASSERT(dl_win.distance() == 1);
159
160 for (int i = 1; i < 64; ++i) {
161 dl_win.increment_send();
162 OSMO_ASSERT(!dl_win.window_empty());
163 OSMO_ASSERT(dl_win.distance() == i + 1);
164 }
165
166 OSMO_ASSERT(dl_win.distance() == 64);
167 OSMO_ASSERT(dl_win.window_stalled());
168
169 dl_win.raise(1);
170 OSMO_ASSERT(dl_win.distance() == 63);
171 OSMO_ASSERT(!dl_win.window_stalled());
172 for (int i = 62; i >= 0; --i) {
173 dl_win.raise(1);
174 OSMO_ASSERT(dl_win.distance() == i);
175 }
176
177 OSMO_ASSERT(dl_win.distance() == 0);
178 OSMO_ASSERT(dl_win.window_empty());
179
180 dl_win.increment_send();
181 dl_win.increment_send();
182 dl_win.increment_send();
183 dl_win.increment_send();
184 OSMO_ASSERT(dl_win.distance() == 4);
185
186 for (int i = 0; i < 128; ++i) {
187 dl_win.increment_send();
188 dl_win.increment_send();
189 dl_win.raise(2);
190 OSMO_ASSERT(dl_win.distance() == 4);
191 }
192 }
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100193
194 {
195 gprs_rlc_ul_window ul_win = { 0, };
196 gprs_rlc_v_n v_n;
197 int count;
Daniel Willmannf86fb7a2013-11-27 17:56:02 +0100198 const char *rbb;
Daniel Willmannc3f43302013-12-11 16:47:19 +0100199 char win_rbb[65];
Daniel Willmann0f2b5fc2013-12-11 16:49:43 +0100200 uint8_t bin_rbb[8];
Daniel Willmannc3f43302013-12-11 16:47:19 +0100201 win_rbb[64] = '\0';
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100202
203 v_n.reset();
204
205 OSMO_ASSERT(ul_win.is_in_window(0));
206 OSMO_ASSERT(ul_win.is_in_window(63));
207 OSMO_ASSERT(!ul_win.is_in_window(64));
208
209 OSMO_ASSERT(!v_n.is_received(0));
210
Daniel Willmannf86fb7a2013-11-27 17:56:02 +0100211 rbb = "IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII";
212 OSMO_ASSERT(ul_win.ssn() == 0);
213 ul_win.update_rbb(&v_n, win_rbb);
Daniel Willmannc3f43302013-12-11 16:47:19 +0100214 OSMO_ASSERT_STR_EQ(win_rbb, rbb);
Daniel Willmann0f2b5fc2013-12-11 16:49:43 +0100215 Encoding::encode_rbb(win_rbb, bin_rbb);
216 printf("rbb: %s\n", osmo_hexdump(bin_rbb, sizeof(bin_rbb)));
Daniel Willmannf1786a32013-12-11 18:44:49 +0100217 Decoding::extract_rbb(bin_rbb, win_rbb);
218 OSMO_ASSERT_STR_EQ(win_rbb, rbb);
Daniel Willmannf86fb7a2013-11-27 17:56:02 +0100219
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100220 /* simulate to have received 0, 1 and 5 */
221 OSMO_ASSERT(ul_win.is_in_window(0));
222 v_n.mark_received(0);
223 ul_win.raise_v_r(0, &v_n);
224 count = ul_win.raise_v_q(&v_n);
225 OSMO_ASSERT(v_n.is_received(0));
226 OSMO_ASSERT(ul_win.v_q() == 1);
227 OSMO_ASSERT(ul_win.v_r() == 1);
228 OSMO_ASSERT(count == 1);
229
Daniel Willmannf86fb7a2013-11-27 17:56:02 +0100230 rbb = "IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIR";
231 OSMO_ASSERT(ul_win.ssn() == 1);
232 ul_win.update_rbb(&v_n, win_rbb);
Daniel Willmannc3f43302013-12-11 16:47:19 +0100233 OSMO_ASSERT_STR_EQ(win_rbb, rbb);
Daniel Willmann0f2b5fc2013-12-11 16:49:43 +0100234 Encoding::encode_rbb(win_rbb, bin_rbb);
235 printf("rbb: %s\n", osmo_hexdump(bin_rbb, sizeof(bin_rbb)));
Daniel Willmannf1786a32013-12-11 18:44:49 +0100236 Decoding::extract_rbb(bin_rbb, win_rbb);
237 OSMO_ASSERT_STR_EQ(win_rbb, rbb);
Daniel Willmannf86fb7a2013-11-27 17:56:02 +0100238
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100239 OSMO_ASSERT(ul_win.is_in_window(1));
240 v_n.mark_received(1);
241 ul_win.raise_v_r(1, &v_n);
242 count = ul_win.raise_v_q(&v_n);
243 OSMO_ASSERT(v_n.is_received(0));
244 OSMO_ASSERT(ul_win.v_q() == 2);
245 OSMO_ASSERT(ul_win.v_r() == 2);
246 OSMO_ASSERT(count == 1);
247
Daniel Willmannf86fb7a2013-11-27 17:56:02 +0100248 rbb = "IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIRR";
249 OSMO_ASSERT(ul_win.ssn() == 2);
250 ul_win.update_rbb(&v_n, win_rbb);
Daniel Willmannc3f43302013-12-11 16:47:19 +0100251 OSMO_ASSERT_STR_EQ(win_rbb, rbb);
Daniel Willmann0f2b5fc2013-12-11 16:49:43 +0100252 Encoding::encode_rbb(win_rbb, bin_rbb);
253 printf("rbb: %s\n", osmo_hexdump(bin_rbb, sizeof(bin_rbb)));
Daniel Willmannf1786a32013-12-11 18:44:49 +0100254 Decoding::extract_rbb(bin_rbb, win_rbb);
255 OSMO_ASSERT_STR_EQ(win_rbb, rbb);
Daniel Willmannf86fb7a2013-11-27 17:56:02 +0100256
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100257 OSMO_ASSERT(ul_win.is_in_window(5));
258 v_n.mark_received(5);
259 ul_win.raise_v_r(5, &v_n);
260 count = ul_win.raise_v_q(&v_n);
261 OSMO_ASSERT(v_n.is_received(0));
262 OSMO_ASSERT(ul_win.v_q() == 2);
263 OSMO_ASSERT(ul_win.v_r() == 6);
264 OSMO_ASSERT(count == 0);
265
Daniel Willmannf86fb7a2013-11-27 17:56:02 +0100266 rbb = "IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIRRIIIR";
267 OSMO_ASSERT(ul_win.ssn() == 6);
268 ul_win.update_rbb(&v_n, win_rbb);
Daniel Willmannc3f43302013-12-11 16:47:19 +0100269 OSMO_ASSERT_STR_EQ(win_rbb, rbb);
Daniel Willmann0f2b5fc2013-12-11 16:49:43 +0100270 Encoding::encode_rbb(win_rbb, bin_rbb);
271 printf("rbb: %s\n", osmo_hexdump(bin_rbb, sizeof(bin_rbb)));
Daniel Willmannf1786a32013-12-11 18:44:49 +0100272 Decoding::extract_rbb(bin_rbb, win_rbb);
273 OSMO_ASSERT_STR_EQ(win_rbb, rbb);
Daniel Willmannf86fb7a2013-11-27 17:56:02 +0100274
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100275 OSMO_ASSERT(ul_win.is_in_window(65));
276 OSMO_ASSERT(ul_win.is_in_window(2));
277 OSMO_ASSERT(v_n.is_received(5));
278 v_n.mark_received(65);
279 ul_win.raise_v_r(65, &v_n);
280 count = ul_win.raise_v_q(&v_n);
281 OSMO_ASSERT(count == 0);
282 OSMO_ASSERT(v_n.is_received(5));
283 OSMO_ASSERT(ul_win.v_q() == 2);
284 OSMO_ASSERT(ul_win.v_r() == 66);
285
Daniel Willmannf86fb7a2013-11-27 17:56:02 +0100286 rbb = "IIIRIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIR";
287 OSMO_ASSERT(ul_win.ssn() == 66);
288 ul_win.update_rbb(&v_n, win_rbb);
Daniel Willmannc3f43302013-12-11 16:47:19 +0100289 OSMO_ASSERT_STR_EQ(win_rbb, rbb);
Daniel Willmann0f2b5fc2013-12-11 16:49:43 +0100290 Encoding::encode_rbb(win_rbb, bin_rbb);
291 printf("rbb: %s\n", osmo_hexdump(bin_rbb, sizeof(bin_rbb)));
Daniel Willmannf1786a32013-12-11 18:44:49 +0100292 Decoding::extract_rbb(bin_rbb, win_rbb);
293 OSMO_ASSERT_STR_EQ(win_rbb, rbb);
Daniel Willmannf86fb7a2013-11-27 17:56:02 +0100294
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100295 OSMO_ASSERT(ul_win.is_in_window(2));
296 OSMO_ASSERT(!ul_win.is_in_window(66));
297 v_n.mark_received(2);
298 ul_win.raise_v_r(2, &v_n);
299 count = ul_win.raise_v_q(&v_n);
300 OSMO_ASSERT(count == 1);
301 OSMO_ASSERT(ul_win.v_q() == 3);
302 OSMO_ASSERT(ul_win.v_r() == 66);
303
304 OSMO_ASSERT(ul_win.is_in_window(66));
305 v_n.mark_received(66);
306 ul_win.raise_v_r(66, &v_n);
307 count = ul_win.raise_v_q(&v_n);
308 OSMO_ASSERT(count == 0);
309 OSMO_ASSERT(ul_win.v_q() == 3);
310 OSMO_ASSERT(ul_win.v_r() == 67);
311
312 for (int i = 3; i <= 67; ++i) {
313 v_n.mark_received(i);
314 ul_win.raise_v_r(i, &v_n);
315 ul_win.raise_v_q(&v_n);
316 }
317
318 OSMO_ASSERT(ul_win.v_q() == 68);
319 OSMO_ASSERT(ul_win.v_r() == 68);
320
321 v_n.mark_received(68);
322 ul_win.raise_v_r(68, &v_n);
323 count = ul_win.raise_v_q(&v_n);
324 OSMO_ASSERT(ul_win.v_q() == 69);
325 OSMO_ASSERT(ul_win.v_r() == 69);
326 OSMO_ASSERT(count == 1);
327
328 /* now test the wrapping */
329 OSMO_ASSERT(ul_win.is_in_window(4));
330 OSMO_ASSERT(!ul_win.is_in_window(5));
331 v_n.mark_received(4);
332 ul_win.raise_v_r(4, &v_n);
333 count = ul_win.raise_v_q(&v_n);
334 OSMO_ASSERT(count == 0);
335 }
Daniel Willmann48df40d2013-12-11 16:51:26 +0100336
337 {
338 int count;
339 uint8_t rbb[8];
340 uint16_t lost = 0, recv = 0;
341 char show_rbb[65];
342 BTS dummy_bts;
343 gprs_rlc_dl_window dl_win = { 0, };
344 gprs_rlc_v_b v_b;
345
346 v_b.reset();
347
348 OSMO_ASSERT(dl_win.window_empty());
349 OSMO_ASSERT(!dl_win.window_stalled());
350 OSMO_ASSERT(dl_win.distance() == 0);
351
352 dl_win.increment_send();
353 OSMO_ASSERT(!dl_win.window_empty());
354 OSMO_ASSERT(!dl_win.window_stalled());
355 OSMO_ASSERT(dl_win.distance() == 1);
356
357 for (int i = 0; i < 35; ++i) {
358 dl_win.increment_send();
359 OSMO_ASSERT(!dl_win.window_empty());
360 OSMO_ASSERT(dl_win.distance() == i + 2);
361 }
362
363 uint8_t rbb_cmp[8] = { 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff };
364 Decoding::extract_rbb(rbb_cmp, show_rbb);
365 printf("show_rbb: %s\n", show_rbb);
366
367 v_b.update(&dummy_bts, show_rbb, 35, dl_win, &lost, &recv);
368 OSMO_ASSERT(lost == 0);
369 OSMO_ASSERT(recv == 35);
370
371 }
Holger Hans Peter Freytherfaf3ef42013-11-24 22:17:40 +0100372}
373
Holger Hans Peter Freyther60582202013-11-21 21:30:23 +0100374int main(int argc, char **argv)
375{
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100376 osmo_init_logging(&gprs_log_info);
377 log_set_use_color(osmo_stderr_target, 0);
378 log_set_print_filename(osmo_stderr_target, 0);
379
Holger Hans Peter Freyther60582202013-11-21 21:30:23 +0100380 printf("Making some basic type testing.\n");
381 test_llc();
Holger Hans Peter Freytherc6382dd2013-11-21 21:42:20 +0100382 test_rlc();
Holger Hans Peter Freyther95255672013-11-23 16:18:18 +0100383 test_rlc_v_b();
Holger Hans Peter Freythere9b1ebb2013-11-24 22:00:43 +0100384 test_rlc_v_n();
Holger Hans Peter Freytherfaf3ef42013-11-24 22:17:40 +0100385 test_rlc_dl_ul_basic();
Holger Hans Peter Freyther60582202013-11-21 21:30:23 +0100386 return EXIT_SUCCESS;
387}
388
389/*
390 * stubs that should not be reached
391 */
392extern "C" {
393void l1if_pdch_req() { abort(); }
394void l1if_connect_pdch() { abort(); }
395void l1if_close_pdch() { abort(); }
396void l1if_open_pdch() { abort(); }
397}