blob: 038d737cc26f45106edb885409d69062e24c5da0 [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"
Pau Espin Pedrol2182e622021-01-14 16:48:38 +010026#include "tbf_dl.h"
Max20c7c462017-12-22 14:20:05 +010027#include "pcu_utils.h"
Holger Hans Peter Freyther60582202013-11-21 21:30:23 +010028#include "gprs_debug.h"
Daniel Willmann0f2b5fc2013-12-11 16:49:43 +010029#include "encoding.h"
Daniel Willmannf1786a32013-12-11 18:44:49 +010030#include "decoding.h"
Max7426c5f2019-02-18 20:42:42 +010031#include "gprs_rlcmac.h"
Alexander Couzens25854512019-06-17 01:50:33 +020032#include "egprs_rlc_compression.h"
Holger Hans Peter Freyther60582202013-11-21 21:30:23 +010033
34extern "C" {
35#include <osmocom/core/application.h>
36#include <osmocom/core/msgb.h>
37#include <osmocom/core/talloc.h>
38#include <osmocom/core/utils.h>
Max20c7c462017-12-22 14:20:05 +010039#include <osmocom/core/bits.h>
Holger Hans Peter Freyther60582202013-11-21 21:30:23 +010040}
41
Daniel Willmannc3f43302013-12-11 16:47:19 +010042#define OSMO_ASSERT_STR_EQ(a, b) \
43 do { \
44 if (strcmp(a, b)) { \
45 printf("String mismatch:\nGot:\t%s\nWant:\t%s\n", a, b); \
46 OSMO_ASSERT(false); \
47 } \
48 } while (0)
49
Holger Hans Peter Freyther60582202013-11-21 21:30:23 +010050void *tall_pcu_ctx;
51int16_t spoof_mnc = 0, spoof_mcc = 0;
Neels Hofmeyrbdc55fa2018-02-21 00:39:07 +010052bool spoof_mnc_3_digits = false;
Holger Hans Peter Freyther60582202013-11-21 21:30:23 +010053
54static void test_llc(void)
55{
56 {
57 uint8_t data[LLC_MAX_LEN] = {1, 2, 3, 4, };
58 uint8_t out;
59 gprs_llc llc;
60 llc.init();
61
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +010062 OSMO_ASSERT(llc_chunk_size(&llc) == 0);
63 OSMO_ASSERT(llc_remaining_space(&llc) == LLC_MAX_LEN);
64 OSMO_ASSERT(llc_frame_length(&llc) == 0);
Holger Hans Peter Freyther60582202013-11-21 21:30:23 +010065
66 llc.put_frame(data, 2);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +010067 OSMO_ASSERT(llc_remaining_space(&llc) == LLC_MAX_LEN - 2);
68 OSMO_ASSERT(llc_frame_length(&llc) == 2);
69 OSMO_ASSERT(llc_chunk_size(&llc) == 2);
Holger Hans Peter Freyther60582202013-11-21 21:30:23 +010070 OSMO_ASSERT(llc.frame[0] == 1);
71 OSMO_ASSERT(llc.frame[1] == 2);
72
73 llc.append_frame(&data[3], 1);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +010074 OSMO_ASSERT(llc_remaining_space(&llc) == LLC_MAX_LEN - 3);
75 OSMO_ASSERT(llc_frame_length(&llc) == 3);
76 OSMO_ASSERT(llc_chunk_size(&llc) == 3);
Holger Hans Peter Freyther60582202013-11-21 21:30:23 +010077
78 /* consume two bytes */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +010079 llc_consume_data(&llc, &out, 1);
80 OSMO_ASSERT(llc_remaining_space(&llc) == LLC_MAX_LEN - 3);
81 OSMO_ASSERT(llc_frame_length(&llc) == 3);
82 OSMO_ASSERT(llc_chunk_size(&llc) == 2);
Holger Hans Peter Freyther60582202013-11-21 21:30:23 +010083
84 /* check that the bytes are as we expected */
85 OSMO_ASSERT(llc.frame[0] == 1);
86 OSMO_ASSERT(llc.frame[1] == 2);
87 OSMO_ASSERT(llc.frame[2] == 4);
88
89 /* now fill the frame */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +010090 llc.append_frame(data, llc_remaining_space(&llc) - 1);
91 OSMO_ASSERT(llc_fits_in_current_frame(&llc, 1));
92 OSMO_ASSERT(!llc_fits_in_current_frame(&llc, 2));
Pau Espin Pedrol488aa292019-09-25 17:48:35 +020093 }
Holger Hans Peter Freyther60582202013-11-21 21:30:23 +010094}
95
Holger Hans Peter Freytherc6382dd2013-11-21 21:42:20 +010096static void test_rlc()
97{
98 {
99 struct gprs_rlc_data rlc = { 0, };
100 memset(rlc.block, 0x23, RLC_MAX_LEN);
Pau Espin Pedrol5bb87b82020-05-18 11:02:39 +0200101 uint8_t *p = prepare(&rlc, 20);
Holger Hans Peter Freytherc6382dd2013-11-21 21:42:20 +0100102 OSMO_ASSERT(p == rlc.block);
103 for (int i = 0; i < 20; ++i)
104 OSMO_ASSERT(p[i] == 0x2B);
105 for (int i = 20; i < RLC_MAX_LEN; ++i)
106 OSMO_ASSERT(p[i] == 0x0);
107 }
108}
109
Holger Hans Peter Freyther95255672013-11-23 16:18:18 +0100110static void test_rlc_v_b()
111{
112 {
113 gprs_rlc_v_b vb;
114 vb.reset();
115
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100116 for (size_t i = 0; i < RLC_MAX_SNS; ++i)
Holger Hans Peter Freyther95255672013-11-23 16:18:18 +0100117 OSMO_ASSERT(vb.is_invalid(i));
118
119 vb.mark_unacked(23);
120 OSMO_ASSERT(vb.is_unacked(23));
121
122 vb.mark_nacked(23);
123 OSMO_ASSERT(vb.is_nacked(23));
124
125 vb.mark_acked(23);
126 OSMO_ASSERT(vb.is_acked(23));
127
128 vb.mark_resend(23);
129 OSMO_ASSERT(vb.is_resend(23));
130
131 vb.mark_invalid(23);
132 OSMO_ASSERT(vb.is_invalid(23));
133 }
134}
135
Holger Hans Peter Freythere9b1ebb2013-11-24 22:00:43 +0100136static void test_rlc_v_n()
137{
138 {
139 gprs_rlc_v_n vn;
140 vn.reset();
141
142 OSMO_ASSERT(!vn.is_received(0x23));
Daniel Willmannd54d9f52013-12-28 21:16:13 +0100143 OSMO_ASSERT(vn.state(0x23) == GPRS_RLC_UL_BSN_INVALID);
Holger Hans Peter Freythere9b1ebb2013-11-24 22:00:43 +0100144
145 vn.mark_received(0x23);
146 OSMO_ASSERT(vn.is_received(0x23));
Daniel Willmannd54d9f52013-12-28 21:16:13 +0100147 OSMO_ASSERT(vn.state(0x23) == GPRS_RLC_UL_BSN_RECEIVED);
Holger Hans Peter Freythere9b1ebb2013-11-24 22:00:43 +0100148
149 vn.mark_missing(0x23);
150 OSMO_ASSERT(!vn.is_received(0x23));
Daniel Willmannd54d9f52013-12-28 21:16:13 +0100151 OSMO_ASSERT(vn.state(0x23) == GPRS_RLC_UL_BSN_MISSING);
Holger Hans Peter Freythere9b1ebb2013-11-24 22:00:43 +0100152 }
153}
154
Holger Hans Peter Freytherfaf3ef42013-11-24 22:17:40 +0100155static void test_rlc_dl_ul_basic()
156{
157 {
Jacob Erlbecka3a567e2015-12-28 13:46:32 +0100158 gprs_rlc_dl_window dl_win;
Holger Hans Peter Freytherfaf3ef42013-11-24 22:17:40 +0100159 OSMO_ASSERT(dl_win.window_empty());
160 OSMO_ASSERT(!dl_win.window_stalled());
161 OSMO_ASSERT(dl_win.distance() == 0);
162
163 dl_win.increment_send();
164 OSMO_ASSERT(!dl_win.window_empty());
165 OSMO_ASSERT(!dl_win.window_stalled());
166 OSMO_ASSERT(dl_win.distance() == 1);
167
168 for (int i = 1; i < 64; ++i) {
169 dl_win.increment_send();
170 OSMO_ASSERT(!dl_win.window_empty());
171 OSMO_ASSERT(dl_win.distance() == i + 1);
172 }
173
174 OSMO_ASSERT(dl_win.distance() == 64);
175 OSMO_ASSERT(dl_win.window_stalled());
176
177 dl_win.raise(1);
178 OSMO_ASSERT(dl_win.distance() == 63);
179 OSMO_ASSERT(!dl_win.window_stalled());
180 for (int i = 62; i >= 0; --i) {
181 dl_win.raise(1);
182 OSMO_ASSERT(dl_win.distance() == i);
183 }
184
185 OSMO_ASSERT(dl_win.distance() == 0);
186 OSMO_ASSERT(dl_win.window_empty());
187
188 dl_win.increment_send();
189 dl_win.increment_send();
190 dl_win.increment_send();
191 dl_win.increment_send();
192 OSMO_ASSERT(dl_win.distance() == 4);
193
194 for (int i = 0; i < 128; ++i) {
195 dl_win.increment_send();
196 dl_win.increment_send();
197 dl_win.raise(2);
198 OSMO_ASSERT(dl_win.distance() == 4);
199 }
200 }
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100201
202 {
Jacob Erlbecka3a567e2015-12-28 13:46:32 +0100203 gprs_rlc_ul_window ul_win;
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100204 int count;
Daniel Willmannf86fb7a2013-11-27 17:56:02 +0100205 const char *rbb;
Daniel Willmannc3f43302013-12-11 16:47:19 +0100206 char win_rbb[65];
Daniel Willmann0f2b5fc2013-12-11 16:49:43 +0100207 uint8_t bin_rbb[8];
Daniel Willmannc3f43302013-12-11 16:47:19 +0100208 win_rbb[64] = '\0';
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100209
Daniel Willmann7c3751b2013-12-28 13:59:24 +0100210 ul_win.m_v_n.reset();
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100211
212 OSMO_ASSERT(ul_win.is_in_window(0));
213 OSMO_ASSERT(ul_win.is_in_window(63));
214 OSMO_ASSERT(!ul_win.is_in_window(64));
215
Daniel Willmann7c3751b2013-12-28 13:59:24 +0100216 OSMO_ASSERT(!ul_win.m_v_n.is_received(0));
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100217
Daniel Willmannf86fb7a2013-11-27 17:56:02 +0100218 rbb = "IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII";
219 OSMO_ASSERT(ul_win.ssn() == 0);
Daniel Willmann7c3751b2013-12-28 13:59:24 +0100220 ul_win.update_rbb(win_rbb);
Daniel Willmannc3f43302013-12-11 16:47:19 +0100221 OSMO_ASSERT_STR_EQ(win_rbb, rbb);
Daniel Willmann0f2b5fc2013-12-11 16:49:43 +0100222 Encoding::encode_rbb(win_rbb, bin_rbb);
223 printf("rbb: %s\n", osmo_hexdump(bin_rbb, sizeof(bin_rbb)));
Daniel Willmannf1786a32013-12-11 18:44:49 +0100224 Decoding::extract_rbb(bin_rbb, win_rbb);
225 OSMO_ASSERT_STR_EQ(win_rbb, rbb);
Daniel Willmannf86fb7a2013-11-27 17:56:02 +0100226
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100227 /* simulate to have received 0, 1 and 5 */
228 OSMO_ASSERT(ul_win.is_in_window(0));
Jacob Erlbeckd87e1d62015-12-14 11:43:04 +0100229 ul_win.receive_bsn(0);
230 count = ul_win.raise_v_q();
Daniel Willmann7c3751b2013-12-28 13:59:24 +0100231 OSMO_ASSERT(ul_win.m_v_n.is_received(0));
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100232 OSMO_ASSERT(ul_win.v_q() == 1);
233 OSMO_ASSERT(ul_win.v_r() == 1);
234 OSMO_ASSERT(count == 1);
235
Daniel Willmannf86fb7a2013-11-27 17:56:02 +0100236 rbb = "IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIR";
237 OSMO_ASSERT(ul_win.ssn() == 1);
Daniel Willmann7c3751b2013-12-28 13:59:24 +0100238 ul_win.update_rbb(win_rbb);
Daniel Willmannc3f43302013-12-11 16:47:19 +0100239 OSMO_ASSERT_STR_EQ(win_rbb, rbb);
Daniel Willmann0f2b5fc2013-12-11 16:49:43 +0100240 Encoding::encode_rbb(win_rbb, bin_rbb);
241 printf("rbb: %s\n", osmo_hexdump(bin_rbb, sizeof(bin_rbb)));
Daniel Willmannf1786a32013-12-11 18:44:49 +0100242 Decoding::extract_rbb(bin_rbb, win_rbb);
243 OSMO_ASSERT_STR_EQ(win_rbb, rbb);
Daniel Willmannf86fb7a2013-11-27 17:56:02 +0100244
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100245 OSMO_ASSERT(ul_win.is_in_window(1));
Jacob Erlbeckd87e1d62015-12-14 11:43:04 +0100246 ul_win.receive_bsn(1);
247 count = ul_win.raise_v_q();
Daniel Willmann7c3751b2013-12-28 13:59:24 +0100248 OSMO_ASSERT(ul_win.m_v_n.is_received(0));
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100249 OSMO_ASSERT(ul_win.v_q() == 2);
250 OSMO_ASSERT(ul_win.v_r() == 2);
251 OSMO_ASSERT(count == 1);
252
Daniel Willmannf86fb7a2013-11-27 17:56:02 +0100253 rbb = "IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIRR";
254 OSMO_ASSERT(ul_win.ssn() == 2);
Daniel Willmann7c3751b2013-12-28 13:59:24 +0100255 ul_win.update_rbb(win_rbb);
Daniel Willmannc3f43302013-12-11 16:47:19 +0100256 OSMO_ASSERT_STR_EQ(win_rbb, rbb);
Daniel Willmann0f2b5fc2013-12-11 16:49:43 +0100257 Encoding::encode_rbb(win_rbb, bin_rbb);
258 printf("rbb: %s\n", osmo_hexdump(bin_rbb, sizeof(bin_rbb)));
Daniel Willmannf1786a32013-12-11 18:44:49 +0100259 Decoding::extract_rbb(bin_rbb, win_rbb);
260 OSMO_ASSERT_STR_EQ(win_rbb, rbb);
Daniel Willmannf86fb7a2013-11-27 17:56:02 +0100261
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100262 OSMO_ASSERT(ul_win.is_in_window(5));
Jacob Erlbeckd87e1d62015-12-14 11:43:04 +0100263 ul_win.receive_bsn(5);
264 count = ul_win.raise_v_q();
Daniel Willmann7c3751b2013-12-28 13:59:24 +0100265 OSMO_ASSERT(ul_win.m_v_n.is_received(0));
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100266 OSMO_ASSERT(ul_win.v_q() == 2);
267 OSMO_ASSERT(ul_win.v_r() == 6);
268 OSMO_ASSERT(count == 0);
269
Daniel Willmannf86fb7a2013-11-27 17:56:02 +0100270 rbb = "IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIRRIIIR";
271 OSMO_ASSERT(ul_win.ssn() == 6);
Daniel Willmann7c3751b2013-12-28 13:59:24 +0100272 ul_win.update_rbb(win_rbb);
Daniel Willmannc3f43302013-12-11 16:47:19 +0100273 OSMO_ASSERT_STR_EQ(win_rbb, rbb);
Daniel Willmann0f2b5fc2013-12-11 16:49:43 +0100274 Encoding::encode_rbb(win_rbb, bin_rbb);
275 printf("rbb: %s\n", osmo_hexdump(bin_rbb, sizeof(bin_rbb)));
Daniel Willmannf1786a32013-12-11 18:44:49 +0100276 Decoding::extract_rbb(bin_rbb, win_rbb);
277 OSMO_ASSERT_STR_EQ(win_rbb, rbb);
Daniel Willmannf86fb7a2013-11-27 17:56:02 +0100278
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100279 OSMO_ASSERT(ul_win.is_in_window(65));
280 OSMO_ASSERT(ul_win.is_in_window(2));
Daniel Willmann7c3751b2013-12-28 13:59:24 +0100281 OSMO_ASSERT(ul_win.m_v_n.is_received(5));
Jacob Erlbeckd87e1d62015-12-14 11:43:04 +0100282 ul_win.receive_bsn(65);
283 count = ul_win.raise_v_q();
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100284 OSMO_ASSERT(count == 0);
Daniel Willmann7c3751b2013-12-28 13:59:24 +0100285 OSMO_ASSERT(ul_win.m_v_n.is_received(5));
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100286 OSMO_ASSERT(ul_win.v_q() == 2);
287 OSMO_ASSERT(ul_win.v_r() == 66);
288
Daniel Willmannf86fb7a2013-11-27 17:56:02 +0100289 rbb = "IIIRIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIR";
290 OSMO_ASSERT(ul_win.ssn() == 66);
Daniel Willmann7c3751b2013-12-28 13:59:24 +0100291 ul_win.update_rbb(win_rbb);
Daniel Willmannc3f43302013-12-11 16:47:19 +0100292 OSMO_ASSERT_STR_EQ(win_rbb, rbb);
Daniel Willmann0f2b5fc2013-12-11 16:49:43 +0100293 Encoding::encode_rbb(win_rbb, bin_rbb);
294 printf("rbb: %s\n", osmo_hexdump(bin_rbb, sizeof(bin_rbb)));
Daniel Willmannf1786a32013-12-11 18:44:49 +0100295 Decoding::extract_rbb(bin_rbb, win_rbb);
296 OSMO_ASSERT_STR_EQ(win_rbb, rbb);
Daniel Willmannf86fb7a2013-11-27 17:56:02 +0100297
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100298 OSMO_ASSERT(ul_win.is_in_window(2));
299 OSMO_ASSERT(!ul_win.is_in_window(66));
Jacob Erlbeckd87e1d62015-12-14 11:43:04 +0100300 ul_win.receive_bsn(2);
301 count = ul_win.raise_v_q();
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100302 OSMO_ASSERT(count == 1);
303 OSMO_ASSERT(ul_win.v_q() == 3);
304 OSMO_ASSERT(ul_win.v_r() == 66);
305
306 OSMO_ASSERT(ul_win.is_in_window(66));
Jacob Erlbeckd87e1d62015-12-14 11:43:04 +0100307 ul_win.receive_bsn(66);
308 count = ul_win.raise_v_q();
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100309 OSMO_ASSERT(count == 0);
310 OSMO_ASSERT(ul_win.v_q() == 3);
311 OSMO_ASSERT(ul_win.v_r() == 67);
312
313 for (int i = 3; i <= 67; ++i) {
Daniel Willmann55844792013-12-28 14:41:00 +0100314 ul_win.receive_bsn(i);
Jacob Erlbeckd87e1d62015-12-14 11:43:04 +0100315 ul_win.raise_v_q();
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100316 }
317
318 OSMO_ASSERT(ul_win.v_q() == 68);
319 OSMO_ASSERT(ul_win.v_r() == 68);
320
Jacob Erlbeckd87e1d62015-12-14 11:43:04 +0100321 ul_win.receive_bsn(68);
322 count = ul_win.raise_v_q();
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100323 OSMO_ASSERT(ul_win.v_q() == 69);
324 OSMO_ASSERT(ul_win.v_r() == 69);
325 OSMO_ASSERT(count == 1);
326
327 /* now test the wrapping */
328 OSMO_ASSERT(ul_win.is_in_window(4));
329 OSMO_ASSERT(!ul_win.is_in_window(5));
Jacob Erlbeckd87e1d62015-12-14 11:43:04 +0100330 ul_win.receive_bsn(4);
331 count = ul_win.raise_v_q();
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100332 OSMO_ASSERT(count == 0);
Aravind Sirsikara35c9112016-08-30 13:00:14 +0530333
334 /*
335 * SSN wrap around case
Aravind Sirsikar7c7a86c2016-08-30 13:08:28 +0530336 * Should not expect any BSN as nacked.
Aravind Sirsikara35c9112016-08-30 13:00:14 +0530337 */
Aravind Sirsikar7c7a86c2016-08-30 13:08:28 +0530338 rbb = "RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR";
Aravind Sirsikara35c9112016-08-30 13:00:14 +0530339 for (int i = 0; i < 128; ++i) {
340 ul_win.receive_bsn(i);
341 ul_win.raise_v_q();
342 }
343 ul_win.receive_bsn(0);
344 ul_win.raise_v_q();
345 ul_win.receive_bsn(1);
346 ul_win.raise_v_q();
347 ul_win.update_rbb(win_rbb);
348 OSMO_ASSERT_STR_EQ(win_rbb, rbb);
349 OSMO_ASSERT(ul_win.ssn() == 2);
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100350 }
Daniel Willmann48df40d2013-12-11 16:51:26 +0100351
352 {
Daniel Willmann48df40d2013-12-11 16:51:26 +0100353 uint16_t lost = 0, recv = 0;
354 char show_rbb[65];
Jacob Erlbeck419b0342016-01-14 13:40:01 +0100355 uint8_t bits_data[8];
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +0100356 struct gprs_rlcmac_bts *dummy_bts = bts_alloc(the_pcu, 0);
Jacob Erlbecka3a567e2015-12-28 13:46:32 +0100357 gprs_rlc_dl_window dl_win;
Jacob Erlbeck419b0342016-01-14 13:40:01 +0100358 bitvec bits;
359 int bsn_begin, bsn_end, num_blocks;
360 Ack_Nack_Description_t desc;
Daniel Willmann48df40d2013-12-11 16:51:26 +0100361
Daniel Willmann146514e2013-12-28 18:24:42 +0100362 dl_win.m_v_b.reset();
Daniel Willmann48df40d2013-12-11 16:51:26 +0100363
364 OSMO_ASSERT(dl_win.window_empty());
365 OSMO_ASSERT(!dl_win.window_stalled());
366 OSMO_ASSERT(dl_win.distance() == 0);
367
368 dl_win.increment_send();
369 OSMO_ASSERT(!dl_win.window_empty());
370 OSMO_ASSERT(!dl_win.window_stalled());
371 OSMO_ASSERT(dl_win.distance() == 1);
372
373 for (int i = 0; i < 35; ++i) {
374 dl_win.increment_send();
375 OSMO_ASSERT(!dl_win.window_empty());
376 OSMO_ASSERT(dl_win.distance() == i + 2);
377 }
378
379 uint8_t rbb_cmp[8] = { 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff };
Jacob Erlbeck419b0342016-01-14 13:40:01 +0100380 bits.data = bits_data;
381 bits.data_len = sizeof(bits_data);
382 bits.cur_bit = 0;
383
384 memcpy(desc.RECEIVED_BLOCK_BITMAP, rbb_cmp,
385 sizeof(desc.RECEIVED_BLOCK_BITMAP));
386 desc.FINAL_ACK_INDICATION = 0;
387 desc.STARTING_SEQUENCE_NUMBER = 35;
388
389 num_blocks = Decoding::decode_gprs_acknack_bits(
390 &desc, &bits,
391 &bsn_begin, &bsn_end, &dl_win);
392 Decoding::extract_rbb(&bits, show_rbb);
Daniel Willmann48df40d2013-12-11 16:51:26 +0100393 printf("show_rbb: %s\n", show_rbb);
394
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100395 dl_win.update(dummy_bts, &bits, 0, &lost, &recv);
Daniel Willmann48df40d2013-12-11 16:51:26 +0100396 OSMO_ASSERT(lost == 0);
397 OSMO_ASSERT(recv == 35);
Jacob Erlbeck419b0342016-01-14 13:40:01 +0100398 OSMO_ASSERT(bsn_begin == 0);
399 OSMO_ASSERT(bsn_end == 35);
400 OSMO_ASSERT(num_blocks == 35);
Daniel Willmann48df40d2013-12-11 16:51:26 +0100401
Jacob Erlbeck419b0342016-01-14 13:40:01 +0100402 dl_win.raise(dl_win.move_window());
403
404 for (int i = 0; i < 8; ++i) {
405 dl_win.increment_send();
406 OSMO_ASSERT(!dl_win.window_empty());
407 OSMO_ASSERT(dl_win.distance() == 2 + i);
408 }
409
410 uint8_t rbb_cmp2[8] = { 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0x31 };
411 bits.data = bits_data;
412 bits.data_len = sizeof(bits_data);
413 bits.cur_bit = 0;
414
415 memcpy(desc.RECEIVED_BLOCK_BITMAP, rbb_cmp2,
416 sizeof(desc.RECEIVED_BLOCK_BITMAP));
417 desc.FINAL_ACK_INDICATION = 0;
418 desc.STARTING_SEQUENCE_NUMBER = 35 + 8;
419
420 num_blocks = Decoding::decode_gprs_acknack_bits(
421 &desc, &bits,
422 &bsn_begin, &bsn_end, &dl_win);
423 Decoding::extract_rbb(&bits, show_rbb);
424 printf("show_rbb: %s\n", show_rbb);
425
426 lost = recv = 0;
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100427 dl_win.update(dummy_bts, &bits, 0, &lost, &recv);
Jacob Erlbeck419b0342016-01-14 13:40:01 +0100428 OSMO_ASSERT(lost == 5);
429 OSMO_ASSERT(recv == 3);
430 OSMO_ASSERT(bitvec_get_bit_pos(&bits, 0) == 0);
431 OSMO_ASSERT(bitvec_get_bit_pos(&bits, 7) == 1);
432 OSMO_ASSERT(bsn_begin == 35);
433 OSMO_ASSERT(bsn_end == 43);
434 OSMO_ASSERT(num_blocks == 8);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100435 talloc_free(dummy_bts);
Daniel Willmann48df40d2013-12-11 16:51:26 +0100436 }
Holger Hans Peter Freytherfaf3ef42013-11-24 22:17:40 +0100437}
438
Alexander Couzens25854512019-06-17 01:50:33 +0200439struct crbb_test {
440 bool has_crbb;
441 bitvec *crbb;
442 uint8_t length;
443 bool color_code;
444};
445
446static void extract_egprs_ul_ack_nack(
447 struct gprs_rlcmac_ul_tbf *tbf,
448 struct bitvec *dest,
449 uint16_t *ssn,
450 struct crbb_test *crbb_test,
451 struct bitvec **urbb,
452 bool is_final)
453{
454 uint8_t bytelength;
455
456 /* Start of Ack/Nack Description struct */
457 uint8_t startbit_ack_nack = 0;
458
459 bool has_length = false;
460 uint8_t length = 0;
461
462 bool bow = false;
463 uint8_t urbb_length = 0;
464 dest->cur_bit = 0;
465
466 /* ignore the first 8 bit */
467 bitvec_get_uint(dest, 8);
468
469 /* uplink ack/nack message content */
470 OSMO_ASSERT(bitvec_get_uint(dest, 6) == 0b001001);
471
472 /* ignore page mode*/
473 bitvec_get_uint(dest, 2);
474
475 /* fix 00 */
476 OSMO_ASSERT(bitvec_get_uint(dest, 2) == 0);
477
478 OSMO_ASSERT(bitvec_get_uint(dest, 5) == tbf->tfi());
479
480 /* egprs ack/nack */
481 OSMO_ASSERT(bitvec_get_uint(dest, 1) == 1);
482
483 /* fix 00 */
484 OSMO_ASSERT(bitvec_get_uint(dest, 2) == 0);
485
486 /* ignore Channel Coding Command */
487 bitvec_get_uint(dest, 4);
488
489 /* we always allow resegmentation */
490 OSMO_ASSERT(bitvec_get_uint(dest, 1) == 1);
491
492 /* ignore pre emptive transmission */
493 bitvec_get_uint(dest, 1);
494
495 /* ignore PRR retransmission request */
496 bitvec_get_uint(dest, 1);
497
498 /* ignore ARAC retransmission request */
499 bitvec_get_uint(dest, 1);
500
501 if (bitvec_get_uint(dest, 1)) {
502 OSMO_ASSERT((uint32_t) bitvec_get_uint(dest, 32) == tbf->tlli());
503 }
504
505 /* ignore TBF_EST */
506 bitvec_get_uint(dest, 1);
507
508 /* Timing Advance */
509 if (bitvec_get_uint(dest, 1)) {
510 /* Timing Advance Value */
511 if (bitvec_get_uint(dest, 1))
512 bitvec_get_uint(dest, 6);
513
514 /* Timing Advance Index*/
515 if (bitvec_get_uint(dest, 1))
516 bitvec_get_uint(dest, 6);
517 /* Timing Advance Timeslot Number */
518 bitvec_get_uint(dest, 3);
519 }
520
521 /* Packet Extended Timing Advance */
522 if (bitvec_get_uint(dest, 1))
523 bitvec_get_uint(dest, 2);
524
525 /* Power Control Parameters */
526 if (bitvec_get_uint(dest, 1)) {
527 /* Alpha */
528 bitvec_get_uint(dest, 4);
529 for (int i=0; i<8 ; i++) {
530 /* Gamma */
531 if (bitvec_get_uint(dest, 1))
532 bitvec_get_uint(dest, 5);
533 }
534 }
535
536 /* Extension Bits */
537 if (bitvec_get_uint(dest, 1)) {
538 int length = bitvec_get_uint(dest, 6);
539 bitvec_get_uint(dest, length);
540 }
541
542 /* Beging of the EGPRS Ack/Nack */
543 has_length = bitvec_get_uint(dest, 1);
544 if (has_length) {
545 length = bitvec_get_uint(dest, 8);
546 } else {
547 /* remaining bits is the length */
548 length = dest->data_len * 8 - dest->cur_bit;
549 }
550 startbit_ack_nack = dest->cur_bit;
551
552 OSMO_ASSERT(bitvec_get_uint(dest, 1) == is_final);
553
554 /* bow Begin Of Window */
555 bow = bitvec_get_uint(dest, 1);
556 /* TODO: check if bow is always present in our implementation */
557
558 /* eow End Of Window */
559 /* TODO: eow checking */
560 bitvec_get_uint(dest, 1);
561
562 *ssn = bitvec_get_uint(dest, 11);
563 if (bow) {
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +0200564 OSMO_ASSERT(*ssn == static_cast<gprs_rlc_ul_window *>(tbf->window())->v_q() + 1);
Alexander Couzens25854512019-06-17 01:50:33 +0200565 }
566
567 crbb_test->has_crbb = bitvec_get_uint(dest, 1);
568 if (crbb_test->has_crbb) {
569 crbb_test->length = bitvec_get_uint(dest, 7);
570 crbb_test->color_code = bitvec_get_uint(dest, 1);
571 if (crbb_test->length % 8)
572 bytelength = crbb_test->length * 8 + 1;
573 else
574 bytelength = crbb_test->length * 8;
575
576 crbb_test->crbb = bitvec_alloc(bytelength, tall_pcu_ctx);
577 for (int i=0; i<crbb_test->length; i++)
578 bitvec_set_bit(crbb_test->crbb, bitvec_get_bit_pos(dest, dest->cur_bit + i));
579
580 dest->cur_bit += crbb_test->length;
581 }
582
583 OSMO_ASSERT(dest->cur_bit < dest->data_len * 8);
584 urbb_length = length - (dest->cur_bit - startbit_ack_nack);
585
586 if (urbb_length > 0) {
587 if (urbb_length % 8)
588 bytelength = urbb_length / 8 + 1;
589 else
590 bytelength = urbb_length / 8;
591
592 *urbb = bitvec_alloc(bytelength, tall_pcu_ctx);
593 for (int i=urbb_length; i>0; i--) {
594 bitvec_set_bit(*urbb, bitvec_get_bit_pos(dest, dest->cur_bit + i - 1));
595 }
596 }
597}
598
599static void check_egprs_bitmap(struct gprs_rlcmac_ul_tbf *tbf, uint16_t ssn, struct crbb_test *crbb_test, bitvec *urbb, unsigned int *rbb_size)
600{
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +0200601 gprs_rlc_ul_window *win = static_cast<gprs_rlc_ul_window *>(tbf->window());
Alexander Couzens25854512019-06-17 01:50:33 +0200602 uint8_t rbb_should[RLC_EGPRS_MAX_WS] = {0};
603 bitvec rbb_should_bv;
604 rbb_should_bv.data = rbb_should;
605 rbb_should_bv.data_len = RLC_EGPRS_MAX_WS;
606 rbb_should_bv.cur_bit = 0;
607
608 /* rbb starting at ssn without mod */
609 bitvec *rbb_ssn_bv = bitvec_alloc(RLC_EGPRS_MAX_WS, tall_pcu_ctx);
610
611 /* even any ssn is allowed, pcu should only use v_q() at least for now */
612 OSMO_ASSERT(ssn == (win->v_q() + 1));
613
614 if (crbb_test->has_crbb) {
615 OSMO_ASSERT(0 == egprs_compress::decompress_crbb(
616 crbb_test->length,
617 crbb_test->color_code,
618 crbb_test->crbb->data,
619 rbb_ssn_bv));
620 }
621
622 if (urbb && urbb->cur_bit > 0) {
623 for (unsigned int i=0; i<urbb->cur_bit; i++) {
624 bitvec_set_bit(rbb_ssn_bv, bitvec_get_bit_pos(urbb, i));
625 }
626 }
627
628 /* check our rbb is equal the decompressed */
629 rbb_should_bv.cur_bit = win->update_egprs_rbb(rbb_should);
630
631 bool failed = false;
632 for (unsigned int i=0; i < rbb_ssn_bv->cur_bit; i++) {
633 if (bitvec_get_bit_pos(&rbb_should_bv, i) !=
634 bitvec_get_bit_pos(rbb_ssn_bv, i))
635 failed = true;
636 }
637 if (failed) {
638 fprintf(stderr, "SSN %d\n", ssn);
639 for (int i=win->v_q(); i<win->ws(); i++) {
640 fprintf(stderr, "bsn %d is %s\n", i, win->is_received( i) ? "received" : "MISS");
641 }
642 char to_dump[256] = { 0 };
643 bitvec_to_string_r(&rbb_should_bv, to_dump);
644 fprintf(stderr, "should: %s\n", to_dump);
645 memset(to_dump, 0x0, 256);
646 bitvec_to_string_r(rbb_ssn_bv, to_dump);
647 fprintf(stderr, "is : %s\n", to_dump);
648 OSMO_ASSERT(false);
649 }
650
651 if (rbb_size)
652 *rbb_size = rbb_ssn_bv->cur_bit;
653}
654
655static void free_egprs_ul_ack_nack(bitvec **rbb, struct crbb_test *crbb_test)
656{
657 if (*rbb) {
658 bitvec_free(*rbb);
659 *rbb = NULL;
660 }
661
662 if (crbb_test->crbb) {
663 bitvec_free(crbb_test->crbb);
664 crbb_test->crbb = NULL;
665 }
666}
667
668static void test_egprs_ul_ack_nack()
669{
670 bitvec *dest = bitvec_alloc(23, tall_pcu_ctx);
671
672 fprintf(stderr, "############## test_egprs_ul_ack_nack\n");
673
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +0100674 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100675 the_pcu->alloc_algorithm = alloc_algorithm_a;
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100676 bts->trx[0].pdch[4].enable();
Alexander Couzens25854512019-06-17 01:50:33 +0200677
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100678 GprsMs *ms = bts_alloc_ms(bts, 1, 1);
679 struct gprs_rlcmac_ul_tbf *tbf = tbf_alloc_ul_tbf(bts, ms, 0, true);
Alexander Couzens25854512019-06-17 01:50:33 +0200680 struct crbb_test crbb_test = {0};
681 bitvec *rbb = NULL;
682 unsigned int rbb_size;
683 uint16_t ssn = 0;
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +0200684 gprs_rlc_ul_window *win = static_cast<gprs_rlc_ul_window *>(tbf->window());
Alexander Couzens25854512019-06-17 01:50:33 +0200685
686 fprintf(stderr, "************** Test with empty window\n");
687 win->reset_state();
688 win->set_ws(256);
689
690 Encoding::write_packet_uplink_ack(dest, tbf, false, 0);
691 extract_egprs_ul_ack_nack(tbf, dest, &ssn, &crbb_test, &rbb, false);
692 check_egprs_bitmap(tbf, ssn, &crbb_test, rbb, &rbb_size);
693 free_egprs_ul_ack_nack(&rbb, &crbb_test);
694 OSMO_ASSERT(rbb_size == 0);
695
696 fprintf(stderr, "************** Test with 1 lost packet\n");
697 win->reset_state();
698 win->set_ws(256);
699 win->receive_bsn(1);
700
701 Encoding::write_packet_uplink_ack(dest, tbf, false, 0);
702 extract_egprs_ul_ack_nack(tbf, dest, &ssn, &crbb_test, &rbb, false);
703 check_egprs_bitmap(tbf, ssn, &crbb_test, rbb, &rbb_size);
704 free_egprs_ul_ack_nack(&rbb, &crbb_test);
705 OSMO_ASSERT(rbb_size == 1);
706
707 fprintf(stderr, "************** Test with compressed window\n");
708 win->reset_state();
709 win->set_ws(128);
710 win->receive_bsn(127);
711
712 Encoding::write_packet_uplink_ack(dest, tbf, false, 0);
713 extract_egprs_ul_ack_nack(tbf, dest, &ssn, &crbb_test, &rbb, false);
714 check_egprs_bitmap(tbf, ssn, &crbb_test, rbb, &rbb_size);
715 free_egprs_ul_ack_nack(&rbb, &crbb_test);
716
717 fprintf(stderr, "************** Provoke an uncompressed ACK without EOW\n");
718 win->reset_state();
719 win->set_ws(384);
720 for (uint16_t i=1; i<384/2; i++)
721 win->receive_bsn(i*2);
722
723 Encoding::write_packet_uplink_ack(dest, tbf, false, 0);
724 extract_egprs_ul_ack_nack(tbf, dest, &ssn, &crbb_test, &rbb, false);
725 check_egprs_bitmap(tbf, ssn, &crbb_test, rbb, &rbb_size);
726 free_egprs_ul_ack_nack(&rbb, &crbb_test);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100727 talloc_free(bts);
Alexander Couzens25854512019-06-17 01:50:33 +0200728}
729
Max81b58cc2019-02-18 20:46:47 +0100730static void check_imm_ass(struct gprs_rlcmac_tbf *tbf, bool dl, enum ph_burst_type bt, const uint8_t *exp, uint8_t len,
731 const char *kind)
732{
Vadim Yanitskiy11567762020-07-18 23:34:17 +0700733 uint8_t alpha = 7, gamma = 8, ta = 35, usf = 1, sz = sizeof(DUMMY_VEC) / 2, plen;
Max81b58cc2019-02-18 20:46:47 +0100734 bitvec *immediate_assignment = bitvec_alloc(sz, tall_pcu_ctx);
735 struct msgb *m = msgb_alloc(80, "test");
736 bool poll = true;
Vadim Yanitskiy11567762020-07-18 23:34:17 +0700737 uint16_t ra = 13;
Max81b58cc2019-02-18 20:46:47 +0100738 uint32_t ref_fn = 24, fn = 11;
739 int8_t ta_idx = 0;
740
Vadim Yanitskiy11567762020-07-18 23:34:17 +0700741 /* HACK: tbf can be NULL, so we cannot use tbf->trx here */
742 struct gprs_rlcmac_trx trx = { };
743 trx.pdch[5].trx = &trx;
744 trx.pdch[5].ts_no = 5;
745 trx.pdch[5].tsc = 1;
746 trx.arfcn = 877;
747
Max81b58cc2019-02-18 20:46:47 +0100748 bitvec_unhex(immediate_assignment, DUMMY_VEC);
Vadim Yanitskiy11567762020-07-18 23:34:17 +0700749 plen = Encoding::write_immediate_assignment(&trx.pdch[5], tbf,
750 immediate_assignment,
751 dl, ra, ref_fn, ta, usf,
Max81b58cc2019-02-18 20:46:47 +0100752 poll, fn, alpha, gamma, ta_idx, bt);
753 printf("[%u] %s Immediate Assignment <%s>:\n\t%s\n", plen, dl ? "DL" : "UL", kind,
754 osmo_hexdump(immediate_assignment->data, sz));
755
756 memcpy(msgb_put(m, sz), immediate_assignment->data, sz);
757 if (!msgb_eq_data_print(m, exp, len))
758 printf("%s(%s, %s) failed!\n", __func__, dl ? "DL" : "UL", kind);
759
760 msgb_free(m);
761}
762
763void test_immediate_assign_dl()
764{
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +0100765 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100766 the_pcu->alloc_algorithm = alloc_algorithm_a;
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100767 bts->trx[0].pdch[2].enable();
768 bts->trx[0].pdch[3].enable();
769 GprsMs *ms = bts_alloc_ms(bts, 1, 0);
Max81b58cc2019-02-18 20:46:47 +0100770
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100771 struct gprs_rlcmac_tbf *tbf = tbf_alloc_dl_tbf(bts, ms, 0, false);
Max81b58cc2019-02-18 20:46:47 +0100772 static uint8_t res[] = { 0x06,
773 0x3f, /* Immediate Assignment Message Type */
774 0x30, /* §10.5.2.26 Page Mode and §10.5.2.25b Dedicated mode/TBF */
775 0x0d, 0x23, 0x6d, /* §10.5.2.25a Packet Channel Description */
776 /* ETSI TS 44.018 §10.5.2.30 Request Reference */
777 0x7f, /* RA */
778 0x03, 0x18, /* T1'-T3 */
779 0x23, /* TA */
780 0x00, /* 0-length §10.5.2.21 Mobile Allocation */
781 /* ETSI TS 44.018 §10.5.2.16 IA Rest Octets */
Vadim Yanitskiycb988942020-11-08 13:27:35 +0700782 0xdf, 0xff, 0xff, 0xff, 0xf8, 0x17, 0x47, 0x08, 0x0b, 0x5b, 0x2b, 0x2b, };
Max81b58cc2019-02-18 20:46:47 +0100783
784 check_imm_ass(tbf, true, GSM_L1_BURST_TYPE_ACCESS_2, res, sizeof(res), "ia_rest_downlink");
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100785 talloc_free(bts);
Max81b58cc2019-02-18 20:46:47 +0100786}
787
788void test_immediate_assign_ul0m()
789{
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +0100790 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100791 the_pcu->alloc_algorithm = alloc_algorithm_a;
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100792 bts->trx[0].pdch[4].enable();
793 bts->trx[0].pdch[5].enable();
Max81b58cc2019-02-18 20:46:47 +0100794
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100795 GprsMs *ms = bts_alloc_ms(bts, 1, 0);
796 struct gprs_rlcmac_tbf *tbf = tbf_alloc_ul_tbf(bts, ms, 0, false);
Max81b58cc2019-02-18 20:46:47 +0100797 static uint8_t res[] = { 0x06,
798 0x3f, /* Immediate Assignment Message Type */
799 0x10, /* §10.5.2.26 Page Mode and §10.5.2.25b Dedicated mode/TBF */
800 0x0d, 0x23, 0x6d, /* §10.5.2.25a Packet Channel Description */
801 /* ETSI TS 44.018 §10.5.2.30 Request Reference */
802 0x0d, /* RA */
803 0x03, 0x18, /* T1'-T3 */
804 0x23, /* TA */
805 0x00, /* 0-length §10.5.2.21 Mobile Allocation */
806 /* ETSI TS 44.018 §10.5.2.16 IA Rest Octets */
Maxe742cc02019-03-12 18:42:09 +0100807 0xc8, 0x02, 0x1b, 0xa2, 0x0b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, };
Max81b58cc2019-02-18 20:46:47 +0100808
809 check_imm_ass(tbf, false, GSM_L1_BURST_TYPE_ACCESS_0, res, sizeof(res), "ia_rest_uplink(MBA)");
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100810 talloc_free(bts);
Max81b58cc2019-02-18 20:46:47 +0100811}
812
813void test_immediate_assign_ul0s()
814{
815 static uint8_t res[] = { 0x06,
816 0x3f, /* Immediate Assignment Message Type */
817 0x10, /* §10.5.2.26 Page Mode and §10.5.2.25b Dedicated mode/TBF */
818 0x0d, 0x23, 0x6d, /* §10.5.2.25a Packet Channel Description */
819 /* ETSI TS 44.018 §10.5.2.30 Request Reference */
820 0x0d, /* RA */
821 0x03, 0x18, /* T1'-T3 */
822 0x23, /* TA */
823 0x00, /* 0-length §10.5.2.21 Mobile Allocation */
824 /* ETSI TS 44.018 §10.5.2.16 IA Rest Octets */
Max3eb47362019-02-19 18:41:22 +0100825 0xc5, 0xd0, 0x80, 0xb5, 0xab, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, };
Max81b58cc2019-02-18 20:46:47 +0100826
827 check_imm_ass(NULL, false, GSM_L1_BURST_TYPE_ACCESS_0, res, sizeof(res), "ia_rest_uplink(SBA)");
828}
829
830void test_immediate_assign_ul1s()
831{
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +0100832 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100833 the_pcu->alloc_algorithm = alloc_algorithm_a;
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100834 bts->trx[0].pdch[1].enable();
835 bts->trx[0].pdch[2].enable();
Max81b58cc2019-02-18 20:46:47 +0100836
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100837 GprsMs *ms = bts_alloc_ms(bts, 1, 1);
838 struct gprs_rlcmac_tbf *tbf = tbf_alloc_ul_tbf(bts, ms, 0, false);
Max81b58cc2019-02-18 20:46:47 +0100839 static uint8_t res[] = { 0x06,
840 0x3f, /* Immediate Assignment Message Type */
841 0x10, /* §10.5.2.26 Page Mode and §10.5.2.25b Dedicated mode/TBF */
842 0x0d, 0x23, 0x6d, /* §10.5.2.25a Packet Channel Description */
843 /* ETSI TS 44.018 §10.5.2.30 Request Reference */
844 0x7f, /* RA */
845 0x03, 0x18, /* T1'-T3 */
846 0x23, /* TA */
847 0x00, /* 0-length §10.5.2.21 Mobile Allocation */
848 /* ETSI TS 44.018 §10.5.2.16 IA Rest Octets */
Maxe742cc02019-03-12 18:42:09 +0100849 0x46, 0xa0, 0x08, 0x00, 0x17, 0x44, 0x0b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, };
Max81b58cc2019-02-18 20:46:47 +0100850
851 check_imm_ass(tbf, false, GSM_L1_BURST_TYPE_ACCESS_1, res, sizeof(res), "ia_rest_egprs_uplink(SBA)");
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100852 talloc_free(bts);
Max81b58cc2019-02-18 20:46:47 +0100853}
854
855void test_immediate_assign_ul1m()
856{
857 static uint8_t res[] = { 0x06,
858 0x3f, /* Immediate Assignment Message Type */
859 0x10, /* §10.5.2.26 Page Mode and §10.5.2.25b Dedicated mode/TBF */
860 0x0d, 0x23, 0x6d, /* §10.5.2.25a Packet Channel Description */
861 /* ETSI TS 44.018 §10.5.2.30 Request Reference */
862 0x7f, /* RA */
863 0x03, 0x18, /* T1'-T3 */
864 0x23, /* TA */
865 0x00, /* 0-length §10.5.2.21 Mobile Allocation */
866 /* ETSI TS 44.018 §10.5.2.16 IA Rest Octets */
867 0x46, 0x97, 0x40, 0x0b, 0x58, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, };
868
869 check_imm_ass(NULL, false, GSM_L1_BURST_TYPE_ACCESS_1, res, sizeof(res), "ia_rest_egprs_uplink(MBA)");
870}
871
aravind sirsikarc0c3afd2016-11-09 16:27:00 +0530872void test_immediate_assign_rej()
873{
874 uint8_t plen;
Alexander Couzensccde5c92017-02-04 03:10:08 +0100875 bitvec *immediate_assignment_rej = bitvec_alloc(22, tall_pcu_ctx);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +0530876
Max7426c5f2019-02-18 20:42:42 +0100877 bitvec_unhex(immediate_assignment_rej, DUMMY_VEC);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +0530878 plen = Encoding::write_immediate_assignment_reject(
879 immediate_assignment_rej, 112, 100,
880 GSM_L1_BURST_TYPE_ACCESS_1);
881
882 printf("assignment reject: %s\n",
883 osmo_hexdump(immediate_assignment_rej->data, 22));
884
885 OSMO_ASSERT(plen == 19);
886 /* RA value */
887 OSMO_ASSERT(immediate_assignment_rej->data[3] == 0x7f);
888 /* Extended RA value */
889 OSMO_ASSERT(immediate_assignment_rej->data[19] == 0xc0);
890
Max7426c5f2019-02-18 20:42:42 +0100891 bitvec_unhex(immediate_assignment_rej, DUMMY_VEC);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +0530892
893 plen = Encoding::write_immediate_assignment_reject(
894 immediate_assignment_rej, 112, 100,
895 GSM_L1_BURST_TYPE_ACCESS_0);
896
897 printf("assignment reject: %s\n",
898 osmo_hexdump(immediate_assignment_rej->data, 22));
899
900 OSMO_ASSERT(plen == 19);
901 /* RA value */
902 OSMO_ASSERT(immediate_assignment_rej->data[3] == 0x70);
903
904}
905
Max20c7c462017-12-22 14:20:05 +0100906static void test_lsb()
907{
908 uint8_t u = 0;
909
910 printf("Testing LBS utility...\n");
911
912 do {
913 uint8_t x = pcu_lsb(u); /* equivalent of (1 << ffs(u)) / 2 */
914 printf("%2X " OSMO_BIT_SPEC ": {%d} %3d\n",
915 u, OSMO_BIT_PRINT(u), pcu_bitcount(u), x);
916 u++;
917 } while (u);
918}
919
Holger Hans Peter Freyther60582202013-11-21 21:30:23 +0100920int main(int argc, char **argv)
921{
Max71affce2018-01-15 11:03:00 +0100922 tall_pcu_ctx = talloc_named_const(NULL, 1, "types test context");
923 if (!tall_pcu_ctx)
924 abort();
925
926 msgb_talloc_ctx_init(tall_pcu_ctx, 0);
Neels Hofmeyr42f2d612018-04-01 16:54:40 +0200927 osmo_init_logging2(tall_pcu_ctx, &gprs_log_info);
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100928 log_set_use_color(osmo_stderr_target, 0);
929 log_set_print_filename(osmo_stderr_target, 0);
930
Philipp Maierde0e5582020-03-25 12:23:52 +0100931 log_set_category_filter(osmo_stderr_target, DTBF, 1, LOGL_INFO);
932 log_set_category_filter(osmo_stderr_target, DTBFUL, 1, LOGL_INFO);
933
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100934 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
935
Holger Hans Peter Freyther60582202013-11-21 21:30:23 +0100936 printf("Making some basic type testing.\n");
Alexander Couzens25854512019-06-17 01:50:33 +0200937
Holger Hans Peter Freyther60582202013-11-21 21:30:23 +0100938 test_llc();
Holger Hans Peter Freytherc6382dd2013-11-21 21:42:20 +0100939 test_rlc();
Holger Hans Peter Freyther95255672013-11-23 16:18:18 +0100940 test_rlc_v_b();
Holger Hans Peter Freythere9b1ebb2013-11-24 22:00:43 +0100941 test_rlc_v_n();
Holger Hans Peter Freytherfaf3ef42013-11-24 22:17:40 +0100942 test_rlc_dl_ul_basic();
Max81b58cc2019-02-18 20:46:47 +0100943 test_immediate_assign_dl();
944 test_immediate_assign_ul0m();
945 test_immediate_assign_ul0s();
946 test_immediate_assign_ul1m();
947 test_immediate_assign_ul1s();
aravind sirsikarc0c3afd2016-11-09 16:27:00 +0530948 test_immediate_assign_rej();
Max20c7c462017-12-22 14:20:05 +0100949 test_lsb();
Alexander Couzens25854512019-06-17 01:50:33 +0200950 test_egprs_ul_ack_nack();
Max20c7c462017-12-22 14:20:05 +0100951
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100952 talloc_free(the_pcu);
953
Holger Hans Peter Freyther60582202013-11-21 21:30:23 +0100954 return EXIT_SUCCESS;
955}
956
957/*
958 * stubs that should not be reached
959 */
960extern "C" {
961void l1if_pdch_req() { abort(); }
962void l1if_connect_pdch() { abort(); }
963void l1if_close_pdch() { abort(); }
964void l1if_open_pdch() { abort(); }
965}