blob: 1c846e118f4f7a50438f9c889ab5ccc0b51bbf44 [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
Alexander Couzens25854512019-06-17 01:50:33 +02005 * Copyright (C) 2019 by Sysmocom s.f.m.c. GmbH
Holger Hans Peter Freyther60582202013-11-21 21:30:23 +01006 *
7 * All Rights Reserved
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU Affero General Public License as published by
11 * the Free Software Foundation; either version 3 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU Affero General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 *
22 */
23#include "bts.h"
24#include "tbf.h"
Pau Espin Pedrol9d1cdb12019-09-25 17:47:02 +020025#include "tbf_ul.h"
Max20c7c462017-12-22 14:20:05 +010026#include "pcu_utils.h"
Holger Hans Peter Freyther60582202013-11-21 21:30:23 +010027#include "gprs_debug.h"
Daniel Willmann0f2b5fc2013-12-11 16:49:43 +010028#include "encoding.h"
Daniel Willmannf1786a32013-12-11 18:44:49 +010029#include "decoding.h"
Max7426c5f2019-02-18 20:42:42 +010030#include "gprs_rlcmac.h"
Alexander Couzens25854512019-06-17 01:50:33 +020031#include "egprs_rlc_compression.h"
Holger Hans Peter Freyther60582202013-11-21 21:30:23 +010032
33extern "C" {
34#include <osmocom/core/application.h>
35#include <osmocom/core/msgb.h>
36#include <osmocom/core/talloc.h>
37#include <osmocom/core/utils.h>
Max20c7c462017-12-22 14:20:05 +010038#include <osmocom/core/bits.h>
Holger Hans Peter Freyther60582202013-11-21 21:30:23 +010039}
40
Daniel Willmannc3f43302013-12-11 16:47:19 +010041#define OSMO_ASSERT_STR_EQ(a, b) \
42 do { \
43 if (strcmp(a, b)) { \
44 printf("String mismatch:\nGot:\t%s\nWant:\t%s\n", a, b); \
45 OSMO_ASSERT(false); \
46 } \
47 } while (0)
48
Holger Hans Peter Freyther60582202013-11-21 21:30:23 +010049void *tall_pcu_ctx;
50int16_t spoof_mnc = 0, spoof_mcc = 0;
Neels Hofmeyrbdc55fa2018-02-21 00:39:07 +010051bool spoof_mnc_3_digits = false;
Holger Hans Peter Freyther60582202013-11-21 21:30:23 +010052
53static void test_llc(void)
54{
55 {
56 uint8_t data[LLC_MAX_LEN] = {1, 2, 3, 4, };
57 uint8_t out;
58 gprs_llc llc;
59 llc.init();
60
61 OSMO_ASSERT(llc.chunk_size() == 0);
62 OSMO_ASSERT(llc.remaining_space() == LLC_MAX_LEN);
63 OSMO_ASSERT(llc.frame_length() == 0);
64
65 llc.put_frame(data, 2);
66 OSMO_ASSERT(llc.remaining_space() == LLC_MAX_LEN - 2);
67 OSMO_ASSERT(llc.frame_length() == 2);
68 OSMO_ASSERT(llc.chunk_size() == 2);
69 OSMO_ASSERT(llc.frame[0] == 1);
70 OSMO_ASSERT(llc.frame[1] == 2);
71
72 llc.append_frame(&data[3], 1);
73 OSMO_ASSERT(llc.remaining_space() == LLC_MAX_LEN - 3);
74 OSMO_ASSERT(llc.frame_length() == 3);
75 OSMO_ASSERT(llc.chunk_size() == 3);
76
77 /* consume two bytes */
78 llc.consume(&out, 1);
79 OSMO_ASSERT(llc.remaining_space() == LLC_MAX_LEN - 3);
80 OSMO_ASSERT(llc.frame_length() == 3);
81 OSMO_ASSERT(llc.chunk_size() == 2);
82
83 /* check that the bytes are as we expected */
84 OSMO_ASSERT(llc.frame[0] == 1);
85 OSMO_ASSERT(llc.frame[1] == 2);
86 OSMO_ASSERT(llc.frame[2] == 4);
87
88 /* now fill the frame */
89 llc.append_frame(data, llc.remaining_space() - 1);
90 OSMO_ASSERT(llc.fits_in_current_frame(1));
91 OSMO_ASSERT(!llc.fits_in_current_frame(2));
Pau Espin Pedrol488aa292019-09-25 17:48:35 +020092 }
Holger Hans Peter Freyther60582202013-11-21 21:30:23 +010093}
94
Holger Hans Peter Freytherc6382dd2013-11-21 21:42:20 +010095static void test_rlc()
96{
97 {
98 struct gprs_rlc_data rlc = { 0, };
99 memset(rlc.block, 0x23, RLC_MAX_LEN);
Pau Espin Pedrol5bb87b82020-05-18 11:02:39 +0200100 uint8_t *p = prepare(&rlc, 20);
Holger Hans Peter Freytherc6382dd2013-11-21 21:42:20 +0100101 OSMO_ASSERT(p == rlc.block);
102 for (int i = 0; i < 20; ++i)
103 OSMO_ASSERT(p[i] == 0x2B);
104 for (int i = 20; i < RLC_MAX_LEN; ++i)
105 OSMO_ASSERT(p[i] == 0x0);
106 }
107}
108
Holger Hans Peter Freyther95255672013-11-23 16:18:18 +0100109static void test_rlc_v_b()
110{
111 {
112 gprs_rlc_v_b vb;
113 vb.reset();
114
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100115 for (size_t i = 0; i < RLC_MAX_SNS; ++i)
Holger Hans Peter Freyther95255672013-11-23 16:18:18 +0100116 OSMO_ASSERT(vb.is_invalid(i));
117
118 vb.mark_unacked(23);
119 OSMO_ASSERT(vb.is_unacked(23));
120
121 vb.mark_nacked(23);
122 OSMO_ASSERT(vb.is_nacked(23));
123
124 vb.mark_acked(23);
125 OSMO_ASSERT(vb.is_acked(23));
126
127 vb.mark_resend(23);
128 OSMO_ASSERT(vb.is_resend(23));
129
130 vb.mark_invalid(23);
131 OSMO_ASSERT(vb.is_invalid(23));
132 }
133}
134
Holger Hans Peter Freythere9b1ebb2013-11-24 22:00:43 +0100135static void test_rlc_v_n()
136{
137 {
138 gprs_rlc_v_n vn;
139 vn.reset();
140
141 OSMO_ASSERT(!vn.is_received(0x23));
Daniel Willmannd54d9f52013-12-28 21:16:13 +0100142 OSMO_ASSERT(vn.state(0x23) == GPRS_RLC_UL_BSN_INVALID);
Holger Hans Peter Freythere9b1ebb2013-11-24 22:00:43 +0100143
144 vn.mark_received(0x23);
145 OSMO_ASSERT(vn.is_received(0x23));
Daniel Willmannd54d9f52013-12-28 21:16:13 +0100146 OSMO_ASSERT(vn.state(0x23) == GPRS_RLC_UL_BSN_RECEIVED);
Holger Hans Peter Freythere9b1ebb2013-11-24 22:00:43 +0100147
148 vn.mark_missing(0x23);
149 OSMO_ASSERT(!vn.is_received(0x23));
Daniel Willmannd54d9f52013-12-28 21:16:13 +0100150 OSMO_ASSERT(vn.state(0x23) == GPRS_RLC_UL_BSN_MISSING);
Holger Hans Peter Freythere9b1ebb2013-11-24 22:00:43 +0100151 }
152}
153
Holger Hans Peter Freytherfaf3ef42013-11-24 22:17:40 +0100154static void test_rlc_dl_ul_basic()
155{
156 {
Jacob Erlbecka3a567e2015-12-28 13:46:32 +0100157 gprs_rlc_dl_window dl_win;
Holger Hans Peter Freytherfaf3ef42013-11-24 22:17:40 +0100158 OSMO_ASSERT(dl_win.window_empty());
159 OSMO_ASSERT(!dl_win.window_stalled());
160 OSMO_ASSERT(dl_win.distance() == 0);
161
162 dl_win.increment_send();
163 OSMO_ASSERT(!dl_win.window_empty());
164 OSMO_ASSERT(!dl_win.window_stalled());
165 OSMO_ASSERT(dl_win.distance() == 1);
166
167 for (int i = 1; i < 64; ++i) {
168 dl_win.increment_send();
169 OSMO_ASSERT(!dl_win.window_empty());
170 OSMO_ASSERT(dl_win.distance() == i + 1);
171 }
172
173 OSMO_ASSERT(dl_win.distance() == 64);
174 OSMO_ASSERT(dl_win.window_stalled());
175
176 dl_win.raise(1);
177 OSMO_ASSERT(dl_win.distance() == 63);
178 OSMO_ASSERT(!dl_win.window_stalled());
179 for (int i = 62; i >= 0; --i) {
180 dl_win.raise(1);
181 OSMO_ASSERT(dl_win.distance() == i);
182 }
183
184 OSMO_ASSERT(dl_win.distance() == 0);
185 OSMO_ASSERT(dl_win.window_empty());
186
187 dl_win.increment_send();
188 dl_win.increment_send();
189 dl_win.increment_send();
190 dl_win.increment_send();
191 OSMO_ASSERT(dl_win.distance() == 4);
192
193 for (int i = 0; i < 128; ++i) {
194 dl_win.increment_send();
195 dl_win.increment_send();
196 dl_win.raise(2);
197 OSMO_ASSERT(dl_win.distance() == 4);
198 }
199 }
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100200
201 {
Jacob Erlbecka3a567e2015-12-28 13:46:32 +0100202 gprs_rlc_ul_window ul_win;
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100203 int count;
Daniel Willmannf86fb7a2013-11-27 17:56:02 +0100204 const char *rbb;
Daniel Willmannc3f43302013-12-11 16:47:19 +0100205 char win_rbb[65];
Daniel Willmann0f2b5fc2013-12-11 16:49:43 +0100206 uint8_t bin_rbb[8];
Daniel Willmannc3f43302013-12-11 16:47:19 +0100207 win_rbb[64] = '\0';
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100208
Daniel Willmann7c3751b2013-12-28 13:59:24 +0100209 ul_win.m_v_n.reset();
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100210
211 OSMO_ASSERT(ul_win.is_in_window(0));
212 OSMO_ASSERT(ul_win.is_in_window(63));
213 OSMO_ASSERT(!ul_win.is_in_window(64));
214
Daniel Willmann7c3751b2013-12-28 13:59:24 +0100215 OSMO_ASSERT(!ul_win.m_v_n.is_received(0));
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100216
Daniel Willmannf86fb7a2013-11-27 17:56:02 +0100217 rbb = "IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII";
218 OSMO_ASSERT(ul_win.ssn() == 0);
Daniel Willmann7c3751b2013-12-28 13:59:24 +0100219 ul_win.update_rbb(win_rbb);
Daniel Willmannc3f43302013-12-11 16:47:19 +0100220 OSMO_ASSERT_STR_EQ(win_rbb, rbb);
Daniel Willmann0f2b5fc2013-12-11 16:49:43 +0100221 Encoding::encode_rbb(win_rbb, bin_rbb);
222 printf("rbb: %s\n", osmo_hexdump(bin_rbb, sizeof(bin_rbb)));
Daniel Willmannf1786a32013-12-11 18:44:49 +0100223 Decoding::extract_rbb(bin_rbb, win_rbb);
224 OSMO_ASSERT_STR_EQ(win_rbb, rbb);
Daniel Willmannf86fb7a2013-11-27 17:56:02 +0100225
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100226 /* simulate to have received 0, 1 and 5 */
227 OSMO_ASSERT(ul_win.is_in_window(0));
Jacob Erlbeckd87e1d62015-12-14 11:43:04 +0100228 ul_win.receive_bsn(0);
229 count = ul_win.raise_v_q();
Daniel Willmann7c3751b2013-12-28 13:59:24 +0100230 OSMO_ASSERT(ul_win.m_v_n.is_received(0));
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100231 OSMO_ASSERT(ul_win.v_q() == 1);
232 OSMO_ASSERT(ul_win.v_r() == 1);
233 OSMO_ASSERT(count == 1);
234
Daniel Willmannf86fb7a2013-11-27 17:56:02 +0100235 rbb = "IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIR";
236 OSMO_ASSERT(ul_win.ssn() == 1);
Daniel Willmann7c3751b2013-12-28 13:59:24 +0100237 ul_win.update_rbb(win_rbb);
Daniel Willmannc3f43302013-12-11 16:47:19 +0100238 OSMO_ASSERT_STR_EQ(win_rbb, rbb);
Daniel Willmann0f2b5fc2013-12-11 16:49:43 +0100239 Encoding::encode_rbb(win_rbb, bin_rbb);
240 printf("rbb: %s\n", osmo_hexdump(bin_rbb, sizeof(bin_rbb)));
Daniel Willmannf1786a32013-12-11 18:44:49 +0100241 Decoding::extract_rbb(bin_rbb, win_rbb);
242 OSMO_ASSERT_STR_EQ(win_rbb, rbb);
Daniel Willmannf86fb7a2013-11-27 17:56:02 +0100243
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100244 OSMO_ASSERT(ul_win.is_in_window(1));
Jacob Erlbeckd87e1d62015-12-14 11:43:04 +0100245 ul_win.receive_bsn(1);
246 count = ul_win.raise_v_q();
Daniel Willmann7c3751b2013-12-28 13:59:24 +0100247 OSMO_ASSERT(ul_win.m_v_n.is_received(0));
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100248 OSMO_ASSERT(ul_win.v_q() == 2);
249 OSMO_ASSERT(ul_win.v_r() == 2);
250 OSMO_ASSERT(count == 1);
251
Daniel Willmannf86fb7a2013-11-27 17:56:02 +0100252 rbb = "IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIRR";
253 OSMO_ASSERT(ul_win.ssn() == 2);
Daniel Willmann7c3751b2013-12-28 13:59:24 +0100254 ul_win.update_rbb(win_rbb);
Daniel Willmannc3f43302013-12-11 16:47:19 +0100255 OSMO_ASSERT_STR_EQ(win_rbb, rbb);
Daniel Willmann0f2b5fc2013-12-11 16:49:43 +0100256 Encoding::encode_rbb(win_rbb, bin_rbb);
257 printf("rbb: %s\n", osmo_hexdump(bin_rbb, sizeof(bin_rbb)));
Daniel Willmannf1786a32013-12-11 18:44:49 +0100258 Decoding::extract_rbb(bin_rbb, win_rbb);
259 OSMO_ASSERT_STR_EQ(win_rbb, rbb);
Daniel Willmannf86fb7a2013-11-27 17:56:02 +0100260
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100261 OSMO_ASSERT(ul_win.is_in_window(5));
Jacob Erlbeckd87e1d62015-12-14 11:43:04 +0100262 ul_win.receive_bsn(5);
263 count = ul_win.raise_v_q();
Daniel Willmann7c3751b2013-12-28 13:59:24 +0100264 OSMO_ASSERT(ul_win.m_v_n.is_received(0));
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100265 OSMO_ASSERT(ul_win.v_q() == 2);
266 OSMO_ASSERT(ul_win.v_r() == 6);
267 OSMO_ASSERT(count == 0);
268
Daniel Willmannf86fb7a2013-11-27 17:56:02 +0100269 rbb = "IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIRRIIIR";
270 OSMO_ASSERT(ul_win.ssn() == 6);
Daniel Willmann7c3751b2013-12-28 13:59:24 +0100271 ul_win.update_rbb(win_rbb);
Daniel Willmannc3f43302013-12-11 16:47:19 +0100272 OSMO_ASSERT_STR_EQ(win_rbb, rbb);
Daniel Willmann0f2b5fc2013-12-11 16:49:43 +0100273 Encoding::encode_rbb(win_rbb, bin_rbb);
274 printf("rbb: %s\n", osmo_hexdump(bin_rbb, sizeof(bin_rbb)));
Daniel Willmannf1786a32013-12-11 18:44:49 +0100275 Decoding::extract_rbb(bin_rbb, win_rbb);
276 OSMO_ASSERT_STR_EQ(win_rbb, rbb);
Daniel Willmannf86fb7a2013-11-27 17:56:02 +0100277
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100278 OSMO_ASSERT(ul_win.is_in_window(65));
279 OSMO_ASSERT(ul_win.is_in_window(2));
Daniel Willmann7c3751b2013-12-28 13:59:24 +0100280 OSMO_ASSERT(ul_win.m_v_n.is_received(5));
Jacob Erlbeckd87e1d62015-12-14 11:43:04 +0100281 ul_win.receive_bsn(65);
282 count = ul_win.raise_v_q();
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100283 OSMO_ASSERT(count == 0);
Daniel Willmann7c3751b2013-12-28 13:59:24 +0100284 OSMO_ASSERT(ul_win.m_v_n.is_received(5));
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100285 OSMO_ASSERT(ul_win.v_q() == 2);
286 OSMO_ASSERT(ul_win.v_r() == 66);
287
Daniel Willmannf86fb7a2013-11-27 17:56:02 +0100288 rbb = "IIIRIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIR";
289 OSMO_ASSERT(ul_win.ssn() == 66);
Daniel Willmann7c3751b2013-12-28 13:59:24 +0100290 ul_win.update_rbb(win_rbb);
Daniel Willmannc3f43302013-12-11 16:47:19 +0100291 OSMO_ASSERT_STR_EQ(win_rbb, rbb);
Daniel Willmann0f2b5fc2013-12-11 16:49:43 +0100292 Encoding::encode_rbb(win_rbb, bin_rbb);
293 printf("rbb: %s\n", osmo_hexdump(bin_rbb, sizeof(bin_rbb)));
Daniel Willmannf1786a32013-12-11 18:44:49 +0100294 Decoding::extract_rbb(bin_rbb, win_rbb);
295 OSMO_ASSERT_STR_EQ(win_rbb, rbb);
Daniel Willmannf86fb7a2013-11-27 17:56:02 +0100296
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100297 OSMO_ASSERT(ul_win.is_in_window(2));
298 OSMO_ASSERT(!ul_win.is_in_window(66));
Jacob Erlbeckd87e1d62015-12-14 11:43:04 +0100299 ul_win.receive_bsn(2);
300 count = ul_win.raise_v_q();
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100301 OSMO_ASSERT(count == 1);
302 OSMO_ASSERT(ul_win.v_q() == 3);
303 OSMO_ASSERT(ul_win.v_r() == 66);
304
305 OSMO_ASSERT(ul_win.is_in_window(66));
Jacob Erlbeckd87e1d62015-12-14 11:43:04 +0100306 ul_win.receive_bsn(66);
307 count = ul_win.raise_v_q();
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100308 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) {
Daniel Willmann55844792013-12-28 14:41:00 +0100313 ul_win.receive_bsn(i);
Jacob Erlbeckd87e1d62015-12-14 11:43:04 +0100314 ul_win.raise_v_q();
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100315 }
316
317 OSMO_ASSERT(ul_win.v_q() == 68);
318 OSMO_ASSERT(ul_win.v_r() == 68);
319
Jacob Erlbeckd87e1d62015-12-14 11:43:04 +0100320 ul_win.receive_bsn(68);
321 count = ul_win.raise_v_q();
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100322 OSMO_ASSERT(ul_win.v_q() == 69);
323 OSMO_ASSERT(ul_win.v_r() == 69);
324 OSMO_ASSERT(count == 1);
325
326 /* now test the wrapping */
327 OSMO_ASSERT(ul_win.is_in_window(4));
328 OSMO_ASSERT(!ul_win.is_in_window(5));
Jacob Erlbeckd87e1d62015-12-14 11:43:04 +0100329 ul_win.receive_bsn(4);
330 count = ul_win.raise_v_q();
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100331 OSMO_ASSERT(count == 0);
Aravind Sirsikara35c9112016-08-30 13:00:14 +0530332
333 /*
334 * SSN wrap around case
Aravind Sirsikar7c7a86c2016-08-30 13:08:28 +0530335 * Should not expect any BSN as nacked.
Aravind Sirsikara35c9112016-08-30 13:00:14 +0530336 */
Aravind Sirsikar7c7a86c2016-08-30 13:08:28 +0530337 rbb = "RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR";
Aravind Sirsikara35c9112016-08-30 13:00:14 +0530338 for (int i = 0; i < 128; ++i) {
339 ul_win.receive_bsn(i);
340 ul_win.raise_v_q();
341 }
342 ul_win.receive_bsn(0);
343 ul_win.raise_v_q();
344 ul_win.receive_bsn(1);
345 ul_win.raise_v_q();
346 ul_win.update_rbb(win_rbb);
347 OSMO_ASSERT_STR_EQ(win_rbb, rbb);
348 OSMO_ASSERT(ul_win.ssn() == 2);
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100349 }
Daniel Willmann48df40d2013-12-11 16:51:26 +0100350
351 {
Daniel Willmann48df40d2013-12-11 16:51:26 +0100352 uint16_t lost = 0, recv = 0;
353 char show_rbb[65];
Jacob Erlbeck419b0342016-01-14 13:40:01 +0100354 uint8_t bits_data[8];
Daniel Willmann48df40d2013-12-11 16:51:26 +0100355 BTS dummy_bts;
Jacob Erlbecka3a567e2015-12-28 13:46:32 +0100356 gprs_rlc_dl_window dl_win;
Jacob Erlbeck419b0342016-01-14 13:40:01 +0100357 bitvec bits;
358 int bsn_begin, bsn_end, num_blocks;
359 Ack_Nack_Description_t desc;
Daniel Willmann48df40d2013-12-11 16:51:26 +0100360
Daniel Willmann146514e2013-12-28 18:24:42 +0100361 dl_win.m_v_b.reset();
Daniel Willmann48df40d2013-12-11 16:51:26 +0100362
363 OSMO_ASSERT(dl_win.window_empty());
364 OSMO_ASSERT(!dl_win.window_stalled());
365 OSMO_ASSERT(dl_win.distance() == 0);
366
367 dl_win.increment_send();
368 OSMO_ASSERT(!dl_win.window_empty());
369 OSMO_ASSERT(!dl_win.window_stalled());
370 OSMO_ASSERT(dl_win.distance() == 1);
371
372 for (int i = 0; i < 35; ++i) {
373 dl_win.increment_send();
374 OSMO_ASSERT(!dl_win.window_empty());
375 OSMO_ASSERT(dl_win.distance() == i + 2);
376 }
377
378 uint8_t rbb_cmp[8] = { 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff };
Jacob Erlbeck419b0342016-01-14 13:40:01 +0100379 bits.data = bits_data;
380 bits.data_len = sizeof(bits_data);
381 bits.cur_bit = 0;
382
383 memcpy(desc.RECEIVED_BLOCK_BITMAP, rbb_cmp,
384 sizeof(desc.RECEIVED_BLOCK_BITMAP));
385 desc.FINAL_ACK_INDICATION = 0;
386 desc.STARTING_SEQUENCE_NUMBER = 35;
387
388 num_blocks = Decoding::decode_gprs_acknack_bits(
389 &desc, &bits,
390 &bsn_begin, &bsn_end, &dl_win);
391 Decoding::extract_rbb(&bits, show_rbb);
Daniel Willmann48df40d2013-12-11 16:51:26 +0100392 printf("show_rbb: %s\n", show_rbb);
393
Jacob Erlbeck419b0342016-01-14 13:40:01 +0100394 dl_win.update(&dummy_bts, &bits, 0, &lost, &recv);
Daniel Willmann48df40d2013-12-11 16:51:26 +0100395 OSMO_ASSERT(lost == 0);
396 OSMO_ASSERT(recv == 35);
Jacob Erlbeck419b0342016-01-14 13:40:01 +0100397 OSMO_ASSERT(bsn_begin == 0);
398 OSMO_ASSERT(bsn_end == 35);
399 OSMO_ASSERT(num_blocks == 35);
Daniel Willmann48df40d2013-12-11 16:51:26 +0100400
Jacob Erlbeck419b0342016-01-14 13:40:01 +0100401 dl_win.raise(dl_win.move_window());
402
403 for (int i = 0; i < 8; ++i) {
404 dl_win.increment_send();
405 OSMO_ASSERT(!dl_win.window_empty());
406 OSMO_ASSERT(dl_win.distance() == 2 + i);
407 }
408
409 uint8_t rbb_cmp2[8] = { 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0x31 };
410 bits.data = bits_data;
411 bits.data_len = sizeof(bits_data);
412 bits.cur_bit = 0;
413
414 memcpy(desc.RECEIVED_BLOCK_BITMAP, rbb_cmp2,
415 sizeof(desc.RECEIVED_BLOCK_BITMAP));
416 desc.FINAL_ACK_INDICATION = 0;
417 desc.STARTING_SEQUENCE_NUMBER = 35 + 8;
418
419 num_blocks = Decoding::decode_gprs_acknack_bits(
420 &desc, &bits,
421 &bsn_begin, &bsn_end, &dl_win);
422 Decoding::extract_rbb(&bits, show_rbb);
423 printf("show_rbb: %s\n", show_rbb);
424
425 lost = recv = 0;
426 dl_win.update(&dummy_bts, &bits, 0, &lost, &recv);
427 OSMO_ASSERT(lost == 5);
428 OSMO_ASSERT(recv == 3);
429 OSMO_ASSERT(bitvec_get_bit_pos(&bits, 0) == 0);
430 OSMO_ASSERT(bitvec_get_bit_pos(&bits, 7) == 1);
431 OSMO_ASSERT(bsn_begin == 35);
432 OSMO_ASSERT(bsn_end == 43);
433 OSMO_ASSERT(num_blocks == 8);
Daniel Willmann48df40d2013-12-11 16:51:26 +0100434 }
Holger Hans Peter Freytherfaf3ef42013-11-24 22:17:40 +0100435}
436
Alexander Couzens25854512019-06-17 01:50:33 +0200437struct crbb_test {
438 bool has_crbb;
439 bitvec *crbb;
440 uint8_t length;
441 bool color_code;
442};
443
444static void extract_egprs_ul_ack_nack(
445 struct gprs_rlcmac_ul_tbf *tbf,
446 struct bitvec *dest,
447 uint16_t *ssn,
448 struct crbb_test *crbb_test,
449 struct bitvec **urbb,
450 bool is_final)
451{
452 uint8_t bytelength;
453
454 /* Start of Ack/Nack Description struct */
455 uint8_t startbit_ack_nack = 0;
456
457 bool has_length = false;
458 uint8_t length = 0;
459
460 bool bow = false;
461 uint8_t urbb_length = 0;
462 dest->cur_bit = 0;
463
464 /* ignore the first 8 bit */
465 bitvec_get_uint(dest, 8);
466
467 /* uplink ack/nack message content */
468 OSMO_ASSERT(bitvec_get_uint(dest, 6) == 0b001001);
469
470 /* ignore page mode*/
471 bitvec_get_uint(dest, 2);
472
473 /* fix 00 */
474 OSMO_ASSERT(bitvec_get_uint(dest, 2) == 0);
475
476 OSMO_ASSERT(bitvec_get_uint(dest, 5) == tbf->tfi());
477
478 /* egprs ack/nack */
479 OSMO_ASSERT(bitvec_get_uint(dest, 1) == 1);
480
481 /* fix 00 */
482 OSMO_ASSERT(bitvec_get_uint(dest, 2) == 0);
483
484 /* ignore Channel Coding Command */
485 bitvec_get_uint(dest, 4);
486
487 /* we always allow resegmentation */
488 OSMO_ASSERT(bitvec_get_uint(dest, 1) == 1);
489
490 /* ignore pre emptive transmission */
491 bitvec_get_uint(dest, 1);
492
493 /* ignore PRR retransmission request */
494 bitvec_get_uint(dest, 1);
495
496 /* ignore ARAC retransmission request */
497 bitvec_get_uint(dest, 1);
498
499 if (bitvec_get_uint(dest, 1)) {
500 OSMO_ASSERT((uint32_t) bitvec_get_uint(dest, 32) == tbf->tlli());
501 }
502
503 /* ignore TBF_EST */
504 bitvec_get_uint(dest, 1);
505
506 /* Timing Advance */
507 if (bitvec_get_uint(dest, 1)) {
508 /* Timing Advance Value */
509 if (bitvec_get_uint(dest, 1))
510 bitvec_get_uint(dest, 6);
511
512 /* Timing Advance Index*/
513 if (bitvec_get_uint(dest, 1))
514 bitvec_get_uint(dest, 6);
515 /* Timing Advance Timeslot Number */
516 bitvec_get_uint(dest, 3);
517 }
518
519 /* Packet Extended Timing Advance */
520 if (bitvec_get_uint(dest, 1))
521 bitvec_get_uint(dest, 2);
522
523 /* Power Control Parameters */
524 if (bitvec_get_uint(dest, 1)) {
525 /* Alpha */
526 bitvec_get_uint(dest, 4);
527 for (int i=0; i<8 ; i++) {
528 /* Gamma */
529 if (bitvec_get_uint(dest, 1))
530 bitvec_get_uint(dest, 5);
531 }
532 }
533
534 /* Extension Bits */
535 if (bitvec_get_uint(dest, 1)) {
536 int length = bitvec_get_uint(dest, 6);
537 bitvec_get_uint(dest, length);
538 }
539
540 /* Beging of the EGPRS Ack/Nack */
541 has_length = bitvec_get_uint(dest, 1);
542 if (has_length) {
543 length = bitvec_get_uint(dest, 8);
544 } else {
545 /* remaining bits is the length */
546 length = dest->data_len * 8 - dest->cur_bit;
547 }
548 startbit_ack_nack = dest->cur_bit;
549
550 OSMO_ASSERT(bitvec_get_uint(dest, 1) == is_final);
551
552 /* bow Begin Of Window */
553 bow = bitvec_get_uint(dest, 1);
554 /* TODO: check if bow is always present in our implementation */
555
556 /* eow End Of Window */
557 /* TODO: eow checking */
558 bitvec_get_uint(dest, 1);
559
560 *ssn = bitvec_get_uint(dest, 11);
561 if (bow) {
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +0200562 OSMO_ASSERT(*ssn == static_cast<gprs_rlc_ul_window *>(tbf->window())->v_q() + 1);
Alexander Couzens25854512019-06-17 01:50:33 +0200563 }
564
565 crbb_test->has_crbb = bitvec_get_uint(dest, 1);
566 if (crbb_test->has_crbb) {
567 crbb_test->length = bitvec_get_uint(dest, 7);
568 crbb_test->color_code = bitvec_get_uint(dest, 1);
569 if (crbb_test->length % 8)
570 bytelength = crbb_test->length * 8 + 1;
571 else
572 bytelength = crbb_test->length * 8;
573
574 crbb_test->crbb = bitvec_alloc(bytelength, tall_pcu_ctx);
575 for (int i=0; i<crbb_test->length; i++)
576 bitvec_set_bit(crbb_test->crbb, bitvec_get_bit_pos(dest, dest->cur_bit + i));
577
578 dest->cur_bit += crbb_test->length;
579 }
580
581 OSMO_ASSERT(dest->cur_bit < dest->data_len * 8);
582 urbb_length = length - (dest->cur_bit - startbit_ack_nack);
583
584 if (urbb_length > 0) {
585 if (urbb_length % 8)
586 bytelength = urbb_length / 8 + 1;
587 else
588 bytelength = urbb_length / 8;
589
590 *urbb = bitvec_alloc(bytelength, tall_pcu_ctx);
591 for (int i=urbb_length; i>0; i--) {
592 bitvec_set_bit(*urbb, bitvec_get_bit_pos(dest, dest->cur_bit + i - 1));
593 }
594 }
595}
596
597static void check_egprs_bitmap(struct gprs_rlcmac_ul_tbf *tbf, uint16_t ssn, struct crbb_test *crbb_test, bitvec *urbb, unsigned int *rbb_size)
598{
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +0200599 gprs_rlc_ul_window *win = static_cast<gprs_rlc_ul_window *>(tbf->window());
Alexander Couzens25854512019-06-17 01:50:33 +0200600 uint8_t rbb_should[RLC_EGPRS_MAX_WS] = {0};
601 bitvec rbb_should_bv;
602 rbb_should_bv.data = rbb_should;
603 rbb_should_bv.data_len = RLC_EGPRS_MAX_WS;
604 rbb_should_bv.cur_bit = 0;
605
606 /* rbb starting at ssn without mod */
607 bitvec *rbb_ssn_bv = bitvec_alloc(RLC_EGPRS_MAX_WS, tall_pcu_ctx);
608
609 /* even any ssn is allowed, pcu should only use v_q() at least for now */
610 OSMO_ASSERT(ssn == (win->v_q() + 1));
611
612 if (crbb_test->has_crbb) {
613 OSMO_ASSERT(0 == egprs_compress::decompress_crbb(
614 crbb_test->length,
615 crbb_test->color_code,
616 crbb_test->crbb->data,
617 rbb_ssn_bv));
618 }
619
620 if (urbb && urbb->cur_bit > 0) {
621 for (unsigned int i=0; i<urbb->cur_bit; i++) {
622 bitvec_set_bit(rbb_ssn_bv, bitvec_get_bit_pos(urbb, i));
623 }
624 }
625
626 /* check our rbb is equal the decompressed */
627 rbb_should_bv.cur_bit = win->update_egprs_rbb(rbb_should);
628
629 bool failed = false;
630 for (unsigned int i=0; i < rbb_ssn_bv->cur_bit; i++) {
631 if (bitvec_get_bit_pos(&rbb_should_bv, i) !=
632 bitvec_get_bit_pos(rbb_ssn_bv, i))
633 failed = true;
634 }
635 if (failed) {
636 fprintf(stderr, "SSN %d\n", ssn);
637 for (int i=win->v_q(); i<win->ws(); i++) {
638 fprintf(stderr, "bsn %d is %s\n", i, win->is_received( i) ? "received" : "MISS");
639 }
640 char to_dump[256] = { 0 };
641 bitvec_to_string_r(&rbb_should_bv, to_dump);
642 fprintf(stderr, "should: %s\n", to_dump);
643 memset(to_dump, 0x0, 256);
644 bitvec_to_string_r(rbb_ssn_bv, to_dump);
645 fprintf(stderr, "is : %s\n", to_dump);
646 OSMO_ASSERT(false);
647 }
648
649 if (rbb_size)
650 *rbb_size = rbb_ssn_bv->cur_bit;
651}
652
653static void free_egprs_ul_ack_nack(bitvec **rbb, struct crbb_test *crbb_test)
654{
655 if (*rbb) {
656 bitvec_free(*rbb);
657 *rbb = NULL;
658 }
659
660 if (crbb_test->crbb) {
661 bitvec_free(crbb_test->crbb);
662 crbb_test->crbb = NULL;
663 }
664}
665
666static void test_egprs_ul_ack_nack()
667{
668 bitvec *dest = bitvec_alloc(23, tall_pcu_ctx);
669
670 fprintf(stderr, "############## test_egprs_ul_ack_nack\n");
671
672 BTS the_bts;
673 the_bts.bts_data()->egprs_enabled = true;
674 the_bts.bts_data()->alloc_algorithm = alloc_algorithm_a;
675 the_bts.bts_data()->trx[0].pdch[4].enable();
676
Pau Espin Pedrol17402a52020-05-08 17:44:33 +0200677 GprsMs *ms = the_bts.ms_alloc(1, 1);
678 struct gprs_rlcmac_ul_tbf *tbf = tbf_alloc_ul_tbf(the_bts.bts_data(), ms, 0, true);
Alexander Couzens25854512019-06-17 01:50:33 +0200679 struct crbb_test crbb_test = {0};
680 bitvec *rbb = NULL;
681 unsigned int rbb_size;
682 uint16_t ssn = 0;
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +0200683 gprs_rlc_ul_window *win = static_cast<gprs_rlc_ul_window *>(tbf->window());
Alexander Couzens25854512019-06-17 01:50:33 +0200684
685 fprintf(stderr, "************** Test with empty window\n");
686 win->reset_state();
687 win->set_ws(256);
688
689 Encoding::write_packet_uplink_ack(dest, tbf, false, 0);
690 extract_egprs_ul_ack_nack(tbf, dest, &ssn, &crbb_test, &rbb, false);
691 check_egprs_bitmap(tbf, ssn, &crbb_test, rbb, &rbb_size);
692 free_egprs_ul_ack_nack(&rbb, &crbb_test);
693 OSMO_ASSERT(rbb_size == 0);
694
695 fprintf(stderr, "************** Test with 1 lost packet\n");
696 win->reset_state();
697 win->set_ws(256);
698 win->receive_bsn(1);
699
700 Encoding::write_packet_uplink_ack(dest, tbf, false, 0);
701 extract_egprs_ul_ack_nack(tbf, dest, &ssn, &crbb_test, &rbb, false);
702 check_egprs_bitmap(tbf, ssn, &crbb_test, rbb, &rbb_size);
703 free_egprs_ul_ack_nack(&rbb, &crbb_test);
704 OSMO_ASSERT(rbb_size == 1);
705
706 fprintf(stderr, "************** Test with compressed window\n");
707 win->reset_state();
708 win->set_ws(128);
709 win->receive_bsn(127);
710
711 Encoding::write_packet_uplink_ack(dest, tbf, false, 0);
712 extract_egprs_ul_ack_nack(tbf, dest, &ssn, &crbb_test, &rbb, false);
713 check_egprs_bitmap(tbf, ssn, &crbb_test, rbb, &rbb_size);
714 free_egprs_ul_ack_nack(&rbb, &crbb_test);
715
716 fprintf(stderr, "************** Provoke an uncompressed ACK without EOW\n");
717 win->reset_state();
718 win->set_ws(384);
719 for (uint16_t i=1; i<384/2; i++)
720 win->receive_bsn(i*2);
721
722 Encoding::write_packet_uplink_ack(dest, tbf, false, 0);
723 extract_egprs_ul_ack_nack(tbf, dest, &ssn, &crbb_test, &rbb, false);
724 check_egprs_bitmap(tbf, ssn, &crbb_test, rbb, &rbb_size);
725 free_egprs_ul_ack_nack(&rbb, &crbb_test);
726}
727
Max81b58cc2019-02-18 20:46:47 +0100728static void check_imm_ass(struct gprs_rlcmac_tbf *tbf, bool dl, enum ph_burst_type bt, const uint8_t *exp, uint8_t len,
729 const char *kind)
730{
Vadim Yanitskiy11567762020-07-18 23:34:17 +0700731 uint8_t alpha = 7, gamma = 8, ta = 35, usf = 1, sz = sizeof(DUMMY_VEC) / 2, plen;
Max81b58cc2019-02-18 20:46:47 +0100732 bitvec *immediate_assignment = bitvec_alloc(sz, tall_pcu_ctx);
733 struct msgb *m = msgb_alloc(80, "test");
734 bool poll = true;
Vadim Yanitskiy11567762020-07-18 23:34:17 +0700735 uint16_t ra = 13;
Max81b58cc2019-02-18 20:46:47 +0100736 uint32_t ref_fn = 24, fn = 11;
737 int8_t ta_idx = 0;
738
Vadim Yanitskiy11567762020-07-18 23:34:17 +0700739 /* HACK: tbf can be NULL, so we cannot use tbf->trx here */
740 struct gprs_rlcmac_trx trx = { };
741 trx.pdch[5].trx = &trx;
742 trx.pdch[5].ts_no = 5;
743 trx.pdch[5].tsc = 1;
744 trx.arfcn = 877;
745
Max81b58cc2019-02-18 20:46:47 +0100746 bitvec_unhex(immediate_assignment, DUMMY_VEC);
Vadim Yanitskiy11567762020-07-18 23:34:17 +0700747 plen = Encoding::write_immediate_assignment(&trx.pdch[5], tbf,
748 immediate_assignment,
749 dl, ra, ref_fn, ta, usf,
Max81b58cc2019-02-18 20:46:47 +0100750 poll, fn, alpha, gamma, ta_idx, bt);
751 printf("[%u] %s Immediate Assignment <%s>:\n\t%s\n", plen, dl ? "DL" : "UL", kind,
752 osmo_hexdump(immediate_assignment->data, sz));
753
754 memcpy(msgb_put(m, sz), immediate_assignment->data, sz);
755 if (!msgb_eq_data_print(m, exp, len))
756 printf("%s(%s, %s) failed!\n", __func__, dl ? "DL" : "UL", kind);
757
758 msgb_free(m);
759}
760
761void test_immediate_assign_dl()
762{
763 BTS the_bts;
764 the_bts.bts_data()->alloc_algorithm = alloc_algorithm_a;
765 the_bts.bts_data()->trx[0].pdch[2].enable();
766 the_bts.bts_data()->trx[0].pdch[3].enable();
Pau Espin Pedrol322456e2020-05-08 18:15:59 +0200767 GprsMs *ms = the_bts.ms_alloc(1, 1);
Max81b58cc2019-02-18 20:46:47 +0100768
Pau Espin Pedrol322456e2020-05-08 18:15:59 +0200769 struct gprs_rlcmac_tbf *tbf = tbf_alloc_dl_tbf(the_bts.bts_data(), ms, 0, false);
Max81b58cc2019-02-18 20:46:47 +0100770 static uint8_t res[] = { 0x06,
771 0x3f, /* Immediate Assignment Message Type */
772 0x30, /* §10.5.2.26 Page Mode and §10.5.2.25b Dedicated mode/TBF */
773 0x0d, 0x23, 0x6d, /* §10.5.2.25a Packet Channel Description */
774 /* ETSI TS 44.018 §10.5.2.30 Request Reference */
775 0x7f, /* RA */
776 0x03, 0x18, /* T1'-T3 */
777 0x23, /* TA */
778 0x00, /* 0-length §10.5.2.21 Mobile Allocation */
779 /* ETSI TS 44.018 §10.5.2.16 IA Rest Octets */
780 0xd0, 0x00, 0x00, 0x00, 0x08, 0x17, 0x47, 0x08, 0x0b, 0x5b, 0x2b, 0x2b, };
781
782 check_imm_ass(tbf, true, GSM_L1_BURST_TYPE_ACCESS_2, res, sizeof(res), "ia_rest_downlink");
783}
784
785void test_immediate_assign_ul0m()
786{
787 BTS the_bts;
788 the_bts.bts_data()->alloc_algorithm = alloc_algorithm_a;
789 the_bts.bts_data()->trx[0].pdch[4].enable();
790 the_bts.bts_data()->trx[0].pdch[5].enable();
791
Pau Espin Pedrol17402a52020-05-08 17:44:33 +0200792 GprsMs *ms = the_bts.ms_alloc(1, 1);
793 struct gprs_rlcmac_tbf *tbf = tbf_alloc_ul_tbf(the_bts.bts_data(), ms, 0, false);
Max81b58cc2019-02-18 20:46:47 +0100794 static uint8_t res[] = { 0x06,
795 0x3f, /* Immediate Assignment Message Type */
796 0x10, /* §10.5.2.26 Page Mode and §10.5.2.25b Dedicated mode/TBF */
797 0x0d, 0x23, 0x6d, /* §10.5.2.25a Packet Channel Description */
798 /* ETSI TS 44.018 §10.5.2.30 Request Reference */
799 0x0d, /* RA */
800 0x03, 0x18, /* T1'-T3 */
801 0x23, /* TA */
802 0x00, /* 0-length §10.5.2.21 Mobile Allocation */
803 /* ETSI TS 44.018 §10.5.2.16 IA Rest Octets */
Maxe742cc02019-03-12 18:42:09 +0100804 0xc8, 0x02, 0x1b, 0xa2, 0x0b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, };
Max81b58cc2019-02-18 20:46:47 +0100805
806 check_imm_ass(tbf, false, GSM_L1_BURST_TYPE_ACCESS_0, res, sizeof(res), "ia_rest_uplink(MBA)");
807}
808
809void test_immediate_assign_ul0s()
810{
811 static uint8_t res[] = { 0x06,
812 0x3f, /* Immediate Assignment Message Type */
813 0x10, /* §10.5.2.26 Page Mode and §10.5.2.25b Dedicated mode/TBF */
814 0x0d, 0x23, 0x6d, /* §10.5.2.25a Packet Channel Description */
815 /* ETSI TS 44.018 §10.5.2.30 Request Reference */
816 0x0d, /* RA */
817 0x03, 0x18, /* T1'-T3 */
818 0x23, /* TA */
819 0x00, /* 0-length §10.5.2.21 Mobile Allocation */
820 /* ETSI TS 44.018 §10.5.2.16 IA Rest Octets */
Max3eb47362019-02-19 18:41:22 +0100821 0xc5, 0xd0, 0x80, 0xb5, 0xab, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, };
Max81b58cc2019-02-18 20:46:47 +0100822
823 check_imm_ass(NULL, false, GSM_L1_BURST_TYPE_ACCESS_0, res, sizeof(res), "ia_rest_uplink(SBA)");
824}
825
826void test_immediate_assign_ul1s()
827{
828 BTS the_bts;
829 the_bts.bts_data()->alloc_algorithm = alloc_algorithm_a;
830 the_bts.bts_data()->trx[0].pdch[1].enable();
831 the_bts.bts_data()->trx[0].pdch[2].enable();
832
Pau Espin Pedrol17402a52020-05-08 17:44:33 +0200833 GprsMs *ms = the_bts.ms_alloc(1, 1);
834 struct gprs_rlcmac_tbf *tbf = tbf_alloc_ul_tbf(the_bts.bts_data(), ms, 0, false);
Max81b58cc2019-02-18 20:46:47 +0100835 static uint8_t res[] = { 0x06,
836 0x3f, /* Immediate Assignment Message Type */
837 0x10, /* §10.5.2.26 Page Mode and §10.5.2.25b Dedicated mode/TBF */
838 0x0d, 0x23, 0x6d, /* §10.5.2.25a Packet Channel Description */
839 /* ETSI TS 44.018 §10.5.2.30 Request Reference */
840 0x7f, /* RA */
841 0x03, 0x18, /* T1'-T3 */
842 0x23, /* TA */
843 0x00, /* 0-length §10.5.2.21 Mobile Allocation */
844 /* ETSI TS 44.018 §10.5.2.16 IA Rest Octets */
Maxe742cc02019-03-12 18:42:09 +0100845 0x46, 0xa0, 0x08, 0x00, 0x17, 0x44, 0x0b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, };
Max81b58cc2019-02-18 20:46:47 +0100846
847 check_imm_ass(tbf, false, GSM_L1_BURST_TYPE_ACCESS_1, res, sizeof(res), "ia_rest_egprs_uplink(SBA)");
848}
849
850void test_immediate_assign_ul1m()
851{
852 static uint8_t res[] = { 0x06,
853 0x3f, /* Immediate Assignment Message Type */
854 0x10, /* §10.5.2.26 Page Mode and §10.5.2.25b Dedicated mode/TBF */
855 0x0d, 0x23, 0x6d, /* §10.5.2.25a Packet Channel Description */
856 /* ETSI TS 44.018 §10.5.2.30 Request Reference */
857 0x7f, /* RA */
858 0x03, 0x18, /* T1'-T3 */
859 0x23, /* TA */
860 0x00, /* 0-length §10.5.2.21 Mobile Allocation */
861 /* ETSI TS 44.018 §10.5.2.16 IA Rest Octets */
862 0x46, 0x97, 0x40, 0x0b, 0x58, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, };
863
864 check_imm_ass(NULL, false, GSM_L1_BURST_TYPE_ACCESS_1, res, sizeof(res), "ia_rest_egprs_uplink(MBA)");
865}
866
aravind sirsikarc0c3afd2016-11-09 16:27:00 +0530867void test_immediate_assign_rej()
868{
869 uint8_t plen;
Alexander Couzensccde5c92017-02-04 03:10:08 +0100870 bitvec *immediate_assignment_rej = bitvec_alloc(22, tall_pcu_ctx);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +0530871
Max7426c5f2019-02-18 20:42:42 +0100872 bitvec_unhex(immediate_assignment_rej, DUMMY_VEC);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +0530873 plen = Encoding::write_immediate_assignment_reject(
874 immediate_assignment_rej, 112, 100,
875 GSM_L1_BURST_TYPE_ACCESS_1);
876
877 printf("assignment reject: %s\n",
878 osmo_hexdump(immediate_assignment_rej->data, 22));
879
880 OSMO_ASSERT(plen == 19);
881 /* RA value */
882 OSMO_ASSERT(immediate_assignment_rej->data[3] == 0x7f);
883 /* Extended RA value */
884 OSMO_ASSERT(immediate_assignment_rej->data[19] == 0xc0);
885
Max7426c5f2019-02-18 20:42:42 +0100886 bitvec_unhex(immediate_assignment_rej, DUMMY_VEC);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +0530887
888 plen = Encoding::write_immediate_assignment_reject(
889 immediate_assignment_rej, 112, 100,
890 GSM_L1_BURST_TYPE_ACCESS_0);
891
892 printf("assignment reject: %s\n",
893 osmo_hexdump(immediate_assignment_rej->data, 22));
894
895 OSMO_ASSERT(plen == 19);
896 /* RA value */
897 OSMO_ASSERT(immediate_assignment_rej->data[3] == 0x70);
898
899}
900
Max20c7c462017-12-22 14:20:05 +0100901static void test_lsb()
902{
903 uint8_t u = 0;
904
905 printf("Testing LBS utility...\n");
906
907 do {
908 uint8_t x = pcu_lsb(u); /* equivalent of (1 << ffs(u)) / 2 */
909 printf("%2X " OSMO_BIT_SPEC ": {%d} %3d\n",
910 u, OSMO_BIT_PRINT(u), pcu_bitcount(u), x);
911 u++;
912 } while (u);
913}
914
Holger Hans Peter Freyther60582202013-11-21 21:30:23 +0100915int main(int argc, char **argv)
916{
Max71affce2018-01-15 11:03:00 +0100917 tall_pcu_ctx = talloc_named_const(NULL, 1, "types test context");
918 if (!tall_pcu_ctx)
919 abort();
920
921 msgb_talloc_ctx_init(tall_pcu_ctx, 0);
Neels Hofmeyr42f2d612018-04-01 16:54:40 +0200922 osmo_init_logging2(tall_pcu_ctx, &gprs_log_info);
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100923 log_set_use_color(osmo_stderr_target, 0);
924 log_set_print_filename(osmo_stderr_target, 0);
925
Philipp Maierde0e5582020-03-25 12:23:52 +0100926 log_set_category_filter(osmo_stderr_target, DTBF, 1, LOGL_INFO);
927 log_set_category_filter(osmo_stderr_target, DTBFUL, 1, LOGL_INFO);
928
Holger Hans Peter Freyther60582202013-11-21 21:30:23 +0100929 printf("Making some basic type testing.\n");
Alexander Couzens25854512019-06-17 01:50:33 +0200930
Holger Hans Peter Freyther60582202013-11-21 21:30:23 +0100931 test_llc();
Holger Hans Peter Freytherc6382dd2013-11-21 21:42:20 +0100932 test_rlc();
Holger Hans Peter Freyther95255672013-11-23 16:18:18 +0100933 test_rlc_v_b();
Holger Hans Peter Freythere9b1ebb2013-11-24 22:00:43 +0100934 test_rlc_v_n();
Holger Hans Peter Freytherfaf3ef42013-11-24 22:17:40 +0100935 test_rlc_dl_ul_basic();
Max81b58cc2019-02-18 20:46:47 +0100936 test_immediate_assign_dl();
937 test_immediate_assign_ul0m();
938 test_immediate_assign_ul0s();
939 test_immediate_assign_ul1m();
940 test_immediate_assign_ul1s();
aravind sirsikarc0c3afd2016-11-09 16:27:00 +0530941 test_immediate_assign_rej();
Max20c7c462017-12-22 14:20:05 +0100942 test_lsb();
Alexander Couzens25854512019-06-17 01:50:33 +0200943 test_egprs_ul_ack_nack();
Max20c7c462017-12-22 14:20:05 +0100944
Holger Hans Peter Freyther60582202013-11-21 21:30:23 +0100945 return EXIT_SUCCESS;
946}
947
948/*
949 * stubs that should not be reached
950 */
951extern "C" {
952void l1if_pdch_req() { abort(); }
953void l1if_connect_pdch() { abort(); }
954void l1if_close_pdch() { abort(); }
955void l1if_open_pdch() { abort(); }
956}