blob: 91b7ce4f736308b5d6b940abf614f0f65210d6af [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"
Pau Espin Pedrolff7c5812022-12-14 18:49:06 +010033#include "alloc_algo.h"
Pau Espin Pedrolbfc97562023-04-17 14:49:29 +020034#include "gprs_ms.h"
Holger Hans Peter Freyther60582202013-11-21 21:30:23 +010035
36extern "C" {
37#include <osmocom/core/application.h>
38#include <osmocom/core/msgb.h>
39#include <osmocom/core/talloc.h>
40#include <osmocom/core/utils.h>
Max20c7c462017-12-22 14:20:05 +010041#include <osmocom/core/bits.h>
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +020042#include <osmocom/core/fsm.h>
Holger Hans Peter Freyther60582202013-11-21 21:30:23 +010043}
44
Daniel Willmannc3f43302013-12-11 16:47:19 +010045#define OSMO_ASSERT_STR_EQ(a, b) \
46 do { \
47 if (strcmp(a, b)) { \
48 printf("String mismatch:\nGot:\t%s\nWant:\t%s\n", a, b); \
49 OSMO_ASSERT(false); \
50 } \
51 } while (0)
52
Holger Hans Peter Freyther60582202013-11-21 21:30:23 +010053void *tall_pcu_ctx;
54int16_t spoof_mnc = 0, spoof_mcc = 0;
Neels Hofmeyrbdc55fa2018-02-21 00:39:07 +010055bool spoof_mnc_3_digits = false;
Holger Hans Peter Freyther60582202013-11-21 21:30:23 +010056
57static void test_llc(void)
58{
59 {
60 uint8_t data[LLC_MAX_LEN] = {1, 2, 3, 4, };
61 uint8_t out;
62 gprs_llc llc;
Pau Espin Pedrol4f8384b2022-03-31 19:36:12 +020063 llc_init(&llc);
Holger Hans Peter Freyther60582202013-11-21 21:30:23 +010064
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +010065 OSMO_ASSERT(llc_chunk_size(&llc) == 0);
66 OSMO_ASSERT(llc_remaining_space(&llc) == LLC_MAX_LEN);
67 OSMO_ASSERT(llc_frame_length(&llc) == 0);
Holger Hans Peter Freyther60582202013-11-21 21:30:23 +010068
Pau Espin Pedrol4f8384b2022-03-31 19:36:12 +020069 llc_put_frame(&llc, data, 2);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +010070 OSMO_ASSERT(llc_remaining_space(&llc) == LLC_MAX_LEN - 2);
71 OSMO_ASSERT(llc_frame_length(&llc) == 2);
72 OSMO_ASSERT(llc_chunk_size(&llc) == 2);
Holger Hans Peter Freyther60582202013-11-21 21:30:23 +010073 OSMO_ASSERT(llc.frame[0] == 1);
74 OSMO_ASSERT(llc.frame[1] == 2);
75
Pau Espin Pedrol4f8384b2022-03-31 19:36:12 +020076 llc_append_frame(&llc, &data[3], 1);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +010077 OSMO_ASSERT(llc_remaining_space(&llc) == LLC_MAX_LEN - 3);
78 OSMO_ASSERT(llc_frame_length(&llc) == 3);
79 OSMO_ASSERT(llc_chunk_size(&llc) == 3);
Holger Hans Peter Freyther60582202013-11-21 21:30:23 +010080
81 /* consume two bytes */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +010082 llc_consume_data(&llc, &out, 1);
83 OSMO_ASSERT(llc_remaining_space(&llc) == LLC_MAX_LEN - 3);
84 OSMO_ASSERT(llc_frame_length(&llc) == 3);
85 OSMO_ASSERT(llc_chunk_size(&llc) == 2);
Holger Hans Peter Freyther60582202013-11-21 21:30:23 +010086
87 /* check that the bytes are as we expected */
88 OSMO_ASSERT(llc.frame[0] == 1);
89 OSMO_ASSERT(llc.frame[1] == 2);
90 OSMO_ASSERT(llc.frame[2] == 4);
91
92 /* now fill the frame */
Pau Espin Pedrol4f8384b2022-03-31 19:36:12 +020093 llc_append_frame(&llc, data, llc_remaining_space(&llc) - 1);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +010094 OSMO_ASSERT(llc_fits_in_current_frame(&llc, 1));
95 OSMO_ASSERT(!llc_fits_in_current_frame(&llc, 2));
Pau Espin Pedrol488aa292019-09-25 17:48:35 +020096 }
Holger Hans Peter Freyther60582202013-11-21 21:30:23 +010097}
98
Holger Hans Peter Freytherc6382dd2013-11-21 21:42:20 +010099static void test_rlc()
100{
101 {
102 struct gprs_rlc_data rlc = { 0, };
103 memset(rlc.block, 0x23, RLC_MAX_LEN);
Pau Espin Pedrol5bb87b82020-05-18 11:02:39 +0200104 uint8_t *p = prepare(&rlc, 20);
Holger Hans Peter Freytherc6382dd2013-11-21 21:42:20 +0100105 OSMO_ASSERT(p == rlc.block);
106 for (int i = 0; i < 20; ++i)
107 OSMO_ASSERT(p[i] == 0x2B);
108 for (int i = 20; i < RLC_MAX_LEN; ++i)
109 OSMO_ASSERT(p[i] == 0x0);
110 }
111}
112
Holger Hans Peter Freyther95255672013-11-23 16:18:18 +0100113static void test_rlc_v_b()
114{
115 {
116 gprs_rlc_v_b vb;
117 vb.reset();
118
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100119 for (size_t i = 0; i < RLC_MAX_SNS; ++i)
Holger Hans Peter Freyther95255672013-11-23 16:18:18 +0100120 OSMO_ASSERT(vb.is_invalid(i));
121
122 vb.mark_unacked(23);
123 OSMO_ASSERT(vb.is_unacked(23));
124
125 vb.mark_nacked(23);
126 OSMO_ASSERT(vb.is_nacked(23));
127
128 vb.mark_acked(23);
129 OSMO_ASSERT(vb.is_acked(23));
130
131 vb.mark_resend(23);
132 OSMO_ASSERT(vb.is_resend(23));
133
134 vb.mark_invalid(23);
135 OSMO_ASSERT(vb.is_invalid(23));
136 }
137}
138
Holger Hans Peter Freythere9b1ebb2013-11-24 22:00:43 +0100139static void test_rlc_v_n()
140{
141 {
142 gprs_rlc_v_n vn;
143 vn.reset();
144
145 OSMO_ASSERT(!vn.is_received(0x23));
Daniel Willmannd54d9f52013-12-28 21:16:13 +0100146 OSMO_ASSERT(vn.state(0x23) == GPRS_RLC_UL_BSN_INVALID);
Holger Hans Peter Freythere9b1ebb2013-11-24 22:00:43 +0100147
148 vn.mark_received(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_RECEIVED);
Holger Hans Peter Freythere9b1ebb2013-11-24 22:00:43 +0100151
152 vn.mark_missing(0x23);
153 OSMO_ASSERT(!vn.is_received(0x23));
Daniel Willmannd54d9f52013-12-28 21:16:13 +0100154 OSMO_ASSERT(vn.state(0x23) == GPRS_RLC_UL_BSN_MISSING);
Holger Hans Peter Freythere9b1ebb2013-11-24 22:00:43 +0100155 }
156}
157
Holger Hans Peter Freytherfaf3ef42013-11-24 22:17:40 +0100158static void test_rlc_dl_ul_basic()
159{
160 {
Jacob Erlbecka3a567e2015-12-28 13:46:32 +0100161 gprs_rlc_dl_window dl_win;
Holger Hans Peter Freytherfaf3ef42013-11-24 22:17:40 +0100162 OSMO_ASSERT(dl_win.window_empty());
163 OSMO_ASSERT(!dl_win.window_stalled());
164 OSMO_ASSERT(dl_win.distance() == 0);
165
166 dl_win.increment_send();
167 OSMO_ASSERT(!dl_win.window_empty());
168 OSMO_ASSERT(!dl_win.window_stalled());
169 OSMO_ASSERT(dl_win.distance() == 1);
170
171 for (int i = 1; i < 64; ++i) {
172 dl_win.increment_send();
173 OSMO_ASSERT(!dl_win.window_empty());
174 OSMO_ASSERT(dl_win.distance() == i + 1);
175 }
176
177 OSMO_ASSERT(dl_win.distance() == 64);
178 OSMO_ASSERT(dl_win.window_stalled());
179
180 dl_win.raise(1);
181 OSMO_ASSERT(dl_win.distance() == 63);
182 OSMO_ASSERT(!dl_win.window_stalled());
183 for (int i = 62; i >= 0; --i) {
184 dl_win.raise(1);
185 OSMO_ASSERT(dl_win.distance() == i);
186 }
187
188 OSMO_ASSERT(dl_win.distance() == 0);
189 OSMO_ASSERT(dl_win.window_empty());
190
191 dl_win.increment_send();
192 dl_win.increment_send();
193 dl_win.increment_send();
194 dl_win.increment_send();
195 OSMO_ASSERT(dl_win.distance() == 4);
196
197 for (int i = 0; i < 128; ++i) {
198 dl_win.increment_send();
199 dl_win.increment_send();
200 dl_win.raise(2);
201 OSMO_ASSERT(dl_win.distance() == 4);
202 }
203 }
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100204
205 {
Jacob Erlbecka3a567e2015-12-28 13:46:32 +0100206 gprs_rlc_ul_window ul_win;
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100207 int count;
Daniel Willmannf86fb7a2013-11-27 17:56:02 +0100208 const char *rbb;
Daniel Willmannc3f43302013-12-11 16:47:19 +0100209 char win_rbb[65];
Pau Espin Pedrolafe189e2021-07-28 21:48:26 +0200210 uint8_t bin_rbb[RLC_GPRS_WS/8];
211 bitvec bits;
Daniel Willmannc3f43302013-12-11 16:47:19 +0100212 win_rbb[64] = '\0';
Pau Espin Pedrolafe189e2021-07-28 21:48:26 +0200213 bits.data = bin_rbb;
214 bits.data_len = sizeof(bin_rbb);
215 bits.cur_bit = 0;
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100216
Daniel Willmann7c3751b2013-12-28 13:59:24 +0100217 ul_win.m_v_n.reset();
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100218
219 OSMO_ASSERT(ul_win.is_in_window(0));
220 OSMO_ASSERT(ul_win.is_in_window(63));
221 OSMO_ASSERT(!ul_win.is_in_window(64));
222
Daniel Willmann7c3751b2013-12-28 13:59:24 +0100223 OSMO_ASSERT(!ul_win.m_v_n.is_received(0));
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100224
Daniel Willmannf86fb7a2013-11-27 17:56:02 +0100225 rbb = "IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII";
226 OSMO_ASSERT(ul_win.ssn() == 0);
Daniel Willmann7c3751b2013-12-28 13:59:24 +0100227 ul_win.update_rbb(win_rbb);
Daniel Willmannc3f43302013-12-11 16:47:19 +0100228 OSMO_ASSERT_STR_EQ(win_rbb, rbb);
Pau Espin Pedrolafe189e2021-07-28 21:48:26 +0200229 bits.cur_bit = 0;
230 Encoding::encode_rbb(win_rbb, &bits);
Daniel Willmann0f2b5fc2013-12-11 16:49:43 +0100231 printf("rbb: %s\n", osmo_hexdump(bin_rbb, sizeof(bin_rbb)));
Pau Espin Pedrolafe189e2021-07-28 21:48:26 +0200232 Decoding::extract_rbb(&bits, win_rbb);
233 //printf("win_rbb: %s\n", win_rbb);
Daniel Willmannf1786a32013-12-11 18:44:49 +0100234 OSMO_ASSERT_STR_EQ(win_rbb, rbb);
Daniel Willmannf86fb7a2013-11-27 17:56:02 +0100235
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100236 /* simulate to have received 0, 1 and 5 */
237 OSMO_ASSERT(ul_win.is_in_window(0));
Jacob Erlbeckd87e1d62015-12-14 11:43:04 +0100238 ul_win.receive_bsn(0);
239 count = ul_win.raise_v_q();
Daniel Willmann7c3751b2013-12-28 13:59:24 +0100240 OSMO_ASSERT(ul_win.m_v_n.is_received(0));
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100241 OSMO_ASSERT(ul_win.v_q() == 1);
242 OSMO_ASSERT(ul_win.v_r() == 1);
243 OSMO_ASSERT(count == 1);
244
Daniel Willmannf86fb7a2013-11-27 17:56:02 +0100245 rbb = "IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIR";
246 OSMO_ASSERT(ul_win.ssn() == 1);
Daniel Willmann7c3751b2013-12-28 13:59:24 +0100247 ul_win.update_rbb(win_rbb);
Daniel Willmannc3f43302013-12-11 16:47:19 +0100248 OSMO_ASSERT_STR_EQ(win_rbb, rbb);
Pau Espin Pedrolafe189e2021-07-28 21:48:26 +0200249 bits.cur_bit = 0;
250 Encoding::encode_rbb(win_rbb, &bits);
Daniel Willmann0f2b5fc2013-12-11 16:49:43 +0100251 printf("rbb: %s\n", osmo_hexdump(bin_rbb, sizeof(bin_rbb)));
Pau Espin Pedrolafe189e2021-07-28 21:48:26 +0200252 Decoding::extract_rbb(&bits, win_rbb);
Daniel Willmannf1786a32013-12-11 18:44:49 +0100253 OSMO_ASSERT_STR_EQ(win_rbb, rbb);
Daniel Willmannf86fb7a2013-11-27 17:56:02 +0100254
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100255 OSMO_ASSERT(ul_win.is_in_window(1));
Jacob Erlbeckd87e1d62015-12-14 11:43:04 +0100256 ul_win.receive_bsn(1);
257 count = ul_win.raise_v_q();
Daniel Willmann7c3751b2013-12-28 13:59:24 +0100258 OSMO_ASSERT(ul_win.m_v_n.is_received(0));
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100259 OSMO_ASSERT(ul_win.v_q() == 2);
260 OSMO_ASSERT(ul_win.v_r() == 2);
261 OSMO_ASSERT(count == 1);
262
Daniel Willmannf86fb7a2013-11-27 17:56:02 +0100263 rbb = "IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIRR";
264 OSMO_ASSERT(ul_win.ssn() == 2);
Daniel Willmann7c3751b2013-12-28 13:59:24 +0100265 ul_win.update_rbb(win_rbb);
Daniel Willmannc3f43302013-12-11 16:47:19 +0100266 OSMO_ASSERT_STR_EQ(win_rbb, rbb);
Pau Espin Pedrolafe189e2021-07-28 21:48:26 +0200267 bits.cur_bit = 0;
268 Encoding::encode_rbb(win_rbb, &bits);
Daniel Willmann0f2b5fc2013-12-11 16:49:43 +0100269 printf("rbb: %s\n", osmo_hexdump(bin_rbb, sizeof(bin_rbb)));
Pau Espin Pedrolafe189e2021-07-28 21:48:26 +0200270 Decoding::extract_rbb(&bits, win_rbb);
Daniel Willmannf1786a32013-12-11 18:44:49 +0100271 OSMO_ASSERT_STR_EQ(win_rbb, rbb);
Daniel Willmannf86fb7a2013-11-27 17:56:02 +0100272
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100273 OSMO_ASSERT(ul_win.is_in_window(5));
Jacob Erlbeckd87e1d62015-12-14 11:43:04 +0100274 ul_win.receive_bsn(5);
275 count = ul_win.raise_v_q();
Daniel Willmann7c3751b2013-12-28 13:59:24 +0100276 OSMO_ASSERT(ul_win.m_v_n.is_received(0));
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100277 OSMO_ASSERT(ul_win.v_q() == 2);
278 OSMO_ASSERT(ul_win.v_r() == 6);
279 OSMO_ASSERT(count == 0);
280
Daniel Willmannf86fb7a2013-11-27 17:56:02 +0100281 rbb = "IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIRRIIIR";
282 OSMO_ASSERT(ul_win.ssn() == 6);
Daniel Willmann7c3751b2013-12-28 13:59:24 +0100283 ul_win.update_rbb(win_rbb);
Daniel Willmannc3f43302013-12-11 16:47:19 +0100284 OSMO_ASSERT_STR_EQ(win_rbb, rbb);
Pau Espin Pedrolafe189e2021-07-28 21:48:26 +0200285 bits.cur_bit = 0;
286 Encoding::encode_rbb(win_rbb, &bits);
Daniel Willmann0f2b5fc2013-12-11 16:49:43 +0100287 printf("rbb: %s\n", osmo_hexdump(bin_rbb, sizeof(bin_rbb)));
Pau Espin Pedrolafe189e2021-07-28 21:48:26 +0200288 Decoding::extract_rbb(&bits, win_rbb);
Daniel Willmannf1786a32013-12-11 18:44:49 +0100289 OSMO_ASSERT_STR_EQ(win_rbb, rbb);
Daniel Willmannf86fb7a2013-11-27 17:56:02 +0100290
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100291 OSMO_ASSERT(ul_win.is_in_window(65));
292 OSMO_ASSERT(ul_win.is_in_window(2));
Daniel Willmann7c3751b2013-12-28 13:59:24 +0100293 OSMO_ASSERT(ul_win.m_v_n.is_received(5));
Jacob Erlbeckd87e1d62015-12-14 11:43:04 +0100294 ul_win.receive_bsn(65);
295 count = ul_win.raise_v_q();
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100296 OSMO_ASSERT(count == 0);
Daniel Willmann7c3751b2013-12-28 13:59:24 +0100297 OSMO_ASSERT(ul_win.m_v_n.is_received(5));
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100298 OSMO_ASSERT(ul_win.v_q() == 2);
299 OSMO_ASSERT(ul_win.v_r() == 66);
300
Daniel Willmannf86fb7a2013-11-27 17:56:02 +0100301 rbb = "IIIRIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIR";
302 OSMO_ASSERT(ul_win.ssn() == 66);
Daniel Willmann7c3751b2013-12-28 13:59:24 +0100303 ul_win.update_rbb(win_rbb);
Daniel Willmannc3f43302013-12-11 16:47:19 +0100304 OSMO_ASSERT_STR_EQ(win_rbb, rbb);
Pau Espin Pedrolafe189e2021-07-28 21:48:26 +0200305 bits.cur_bit = 0;
306 Encoding::encode_rbb(win_rbb, &bits);
Daniel Willmann0f2b5fc2013-12-11 16:49:43 +0100307 printf("rbb: %s\n", osmo_hexdump(bin_rbb, sizeof(bin_rbb)));
Pau Espin Pedrolafe189e2021-07-28 21:48:26 +0200308 Decoding::extract_rbb(&bits, win_rbb);
Daniel Willmannf1786a32013-12-11 18:44:49 +0100309 OSMO_ASSERT_STR_EQ(win_rbb, rbb);
Daniel Willmannf86fb7a2013-11-27 17:56:02 +0100310
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100311 OSMO_ASSERT(ul_win.is_in_window(2));
312 OSMO_ASSERT(!ul_win.is_in_window(66));
Jacob Erlbeckd87e1d62015-12-14 11:43:04 +0100313 ul_win.receive_bsn(2);
314 count = ul_win.raise_v_q();
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100315 OSMO_ASSERT(count == 1);
316 OSMO_ASSERT(ul_win.v_q() == 3);
317 OSMO_ASSERT(ul_win.v_r() == 66);
318
319 OSMO_ASSERT(ul_win.is_in_window(66));
Jacob Erlbeckd87e1d62015-12-14 11:43:04 +0100320 ul_win.receive_bsn(66);
321 count = ul_win.raise_v_q();
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100322 OSMO_ASSERT(count == 0);
323 OSMO_ASSERT(ul_win.v_q() == 3);
324 OSMO_ASSERT(ul_win.v_r() == 67);
325
326 for (int i = 3; i <= 67; ++i) {
Daniel Willmann55844792013-12-28 14:41:00 +0100327 ul_win.receive_bsn(i);
Jacob Erlbeckd87e1d62015-12-14 11:43:04 +0100328 ul_win.raise_v_q();
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100329 }
330
331 OSMO_ASSERT(ul_win.v_q() == 68);
332 OSMO_ASSERT(ul_win.v_r() == 68);
333
Jacob Erlbeckd87e1d62015-12-14 11:43:04 +0100334 ul_win.receive_bsn(68);
335 count = ul_win.raise_v_q();
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100336 OSMO_ASSERT(ul_win.v_q() == 69);
337 OSMO_ASSERT(ul_win.v_r() == 69);
338 OSMO_ASSERT(count == 1);
339
340 /* now test the wrapping */
341 OSMO_ASSERT(ul_win.is_in_window(4));
342 OSMO_ASSERT(!ul_win.is_in_window(5));
Jacob Erlbeckd87e1d62015-12-14 11:43:04 +0100343 ul_win.receive_bsn(4);
344 count = ul_win.raise_v_q();
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100345 OSMO_ASSERT(count == 0);
Aravind Sirsikara35c9112016-08-30 13:00:14 +0530346
347 /*
348 * SSN wrap around case
Aravind Sirsikar7c7a86c2016-08-30 13:08:28 +0530349 * Should not expect any BSN as nacked.
Aravind Sirsikara35c9112016-08-30 13:00:14 +0530350 */
Aravind Sirsikar7c7a86c2016-08-30 13:08:28 +0530351 rbb = "RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR";
Aravind Sirsikara35c9112016-08-30 13:00:14 +0530352 for (int i = 0; i < 128; ++i) {
353 ul_win.receive_bsn(i);
354 ul_win.raise_v_q();
355 }
356 ul_win.receive_bsn(0);
357 ul_win.raise_v_q();
358 ul_win.receive_bsn(1);
359 ul_win.raise_v_q();
360 ul_win.update_rbb(win_rbb);
361 OSMO_ASSERT_STR_EQ(win_rbb, rbb);
362 OSMO_ASSERT(ul_win.ssn() == 2);
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100363 }
Daniel Willmann48df40d2013-12-11 16:51:26 +0100364
365 {
Daniel Willmann48df40d2013-12-11 16:51:26 +0100366 uint16_t lost = 0, recv = 0;
367 char show_rbb[65];
Jacob Erlbeck419b0342016-01-14 13:40:01 +0100368 uint8_t bits_data[8];
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +0100369 struct gprs_rlcmac_bts *dummy_bts = bts_alloc(the_pcu, 0);
Jacob Erlbecka3a567e2015-12-28 13:46:32 +0100370 gprs_rlc_dl_window dl_win;
Jacob Erlbeck419b0342016-01-14 13:40:01 +0100371 bitvec bits;
372 int bsn_begin, bsn_end, num_blocks;
373 Ack_Nack_Description_t desc;
Daniel Willmann48df40d2013-12-11 16:51:26 +0100374
Daniel Willmann146514e2013-12-28 18:24:42 +0100375 dl_win.m_v_b.reset();
Daniel Willmann48df40d2013-12-11 16:51:26 +0100376
377 OSMO_ASSERT(dl_win.window_empty());
378 OSMO_ASSERT(!dl_win.window_stalled());
379 OSMO_ASSERT(dl_win.distance() == 0);
380
381 dl_win.increment_send();
382 OSMO_ASSERT(!dl_win.window_empty());
383 OSMO_ASSERT(!dl_win.window_stalled());
384 OSMO_ASSERT(dl_win.distance() == 1);
385
386 for (int i = 0; i < 35; ++i) {
387 dl_win.increment_send();
388 OSMO_ASSERT(!dl_win.window_empty());
389 OSMO_ASSERT(dl_win.distance() == i + 2);
390 }
391
392 uint8_t rbb_cmp[8] = { 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff };
Jacob Erlbeck419b0342016-01-14 13:40:01 +0100393 bits.data = bits_data;
394 bits.data_len = sizeof(bits_data);
395 bits.cur_bit = 0;
396
397 memcpy(desc.RECEIVED_BLOCK_BITMAP, rbb_cmp,
398 sizeof(desc.RECEIVED_BLOCK_BITMAP));
399 desc.FINAL_ACK_INDICATION = 0;
400 desc.STARTING_SEQUENCE_NUMBER = 35;
401
402 num_blocks = Decoding::decode_gprs_acknack_bits(
403 &desc, &bits,
404 &bsn_begin, &bsn_end, &dl_win);
405 Decoding::extract_rbb(&bits, show_rbb);
Daniel Willmann48df40d2013-12-11 16:51:26 +0100406 printf("show_rbb: %s\n", show_rbb);
407
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100408 dl_win.update(dummy_bts, &bits, 0, &lost, &recv);
Daniel Willmann48df40d2013-12-11 16:51:26 +0100409 OSMO_ASSERT(lost == 0);
410 OSMO_ASSERT(recv == 35);
Jacob Erlbeck419b0342016-01-14 13:40:01 +0100411 OSMO_ASSERT(bsn_begin == 0);
412 OSMO_ASSERT(bsn_end == 35);
413 OSMO_ASSERT(num_blocks == 35);
Daniel Willmann48df40d2013-12-11 16:51:26 +0100414
Jacob Erlbeck419b0342016-01-14 13:40:01 +0100415 dl_win.raise(dl_win.move_window());
416
417 for (int i = 0; i < 8; ++i) {
418 dl_win.increment_send();
419 OSMO_ASSERT(!dl_win.window_empty());
420 OSMO_ASSERT(dl_win.distance() == 2 + i);
421 }
422
423 uint8_t rbb_cmp2[8] = { 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0x31 };
424 bits.data = bits_data;
425 bits.data_len = sizeof(bits_data);
426 bits.cur_bit = 0;
427
428 memcpy(desc.RECEIVED_BLOCK_BITMAP, rbb_cmp2,
429 sizeof(desc.RECEIVED_BLOCK_BITMAP));
430 desc.FINAL_ACK_INDICATION = 0;
431 desc.STARTING_SEQUENCE_NUMBER = 35 + 8;
432
433 num_blocks = Decoding::decode_gprs_acknack_bits(
434 &desc, &bits,
435 &bsn_begin, &bsn_end, &dl_win);
436 Decoding::extract_rbb(&bits, show_rbb);
437 printf("show_rbb: %s\n", show_rbb);
438
439 lost = recv = 0;
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100440 dl_win.update(dummy_bts, &bits, 0, &lost, &recv);
Jacob Erlbeck419b0342016-01-14 13:40:01 +0100441 OSMO_ASSERT(lost == 5);
442 OSMO_ASSERT(recv == 3);
443 OSMO_ASSERT(bitvec_get_bit_pos(&bits, 0) == 0);
444 OSMO_ASSERT(bitvec_get_bit_pos(&bits, 7) == 1);
445 OSMO_ASSERT(bsn_begin == 35);
446 OSMO_ASSERT(bsn_end == 43);
447 OSMO_ASSERT(num_blocks == 8);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100448 talloc_free(dummy_bts);
Daniel Willmann48df40d2013-12-11 16:51:26 +0100449 }
Holger Hans Peter Freytherfaf3ef42013-11-24 22:17:40 +0100450}
451
Alexander Couzens25854512019-06-17 01:50:33 +0200452struct crbb_test {
453 bool has_crbb;
454 bitvec *crbb;
455 uint8_t length;
456 bool color_code;
457};
458
459static void extract_egprs_ul_ack_nack(
460 struct gprs_rlcmac_ul_tbf *tbf,
461 struct bitvec *dest,
462 uint16_t *ssn,
463 struct crbb_test *crbb_test,
464 struct bitvec **urbb,
465 bool is_final)
466{
467 uint8_t bytelength;
468
469 /* Start of Ack/Nack Description struct */
470 uint8_t startbit_ack_nack = 0;
471
472 bool has_length = false;
473 uint8_t length = 0;
474
475 bool bow = false;
476 uint8_t urbb_length = 0;
477 dest->cur_bit = 0;
478
479 /* ignore the first 8 bit */
480 bitvec_get_uint(dest, 8);
481
482 /* uplink ack/nack message content */
483 OSMO_ASSERT(bitvec_get_uint(dest, 6) == 0b001001);
484
485 /* ignore page mode*/
486 bitvec_get_uint(dest, 2);
487
488 /* fix 00 */
489 OSMO_ASSERT(bitvec_get_uint(dest, 2) == 0);
490
491 OSMO_ASSERT(bitvec_get_uint(dest, 5) == tbf->tfi());
492
493 /* egprs ack/nack */
494 OSMO_ASSERT(bitvec_get_uint(dest, 1) == 1);
495
496 /* fix 00 */
497 OSMO_ASSERT(bitvec_get_uint(dest, 2) == 0);
498
499 /* ignore Channel Coding Command */
500 bitvec_get_uint(dest, 4);
501
502 /* we always allow resegmentation */
503 OSMO_ASSERT(bitvec_get_uint(dest, 1) == 1);
504
505 /* ignore pre emptive transmission */
506 bitvec_get_uint(dest, 1);
507
508 /* ignore PRR retransmission request */
509 bitvec_get_uint(dest, 1);
510
511 /* ignore ARAC retransmission request */
512 bitvec_get_uint(dest, 1);
513
514 if (bitvec_get_uint(dest, 1)) {
515 OSMO_ASSERT((uint32_t) bitvec_get_uint(dest, 32) == tbf->tlli());
516 }
517
518 /* ignore TBF_EST */
519 bitvec_get_uint(dest, 1);
520
521 /* Timing Advance */
522 if (bitvec_get_uint(dest, 1)) {
523 /* Timing Advance Value */
524 if (bitvec_get_uint(dest, 1))
525 bitvec_get_uint(dest, 6);
526
527 /* Timing Advance Index*/
528 if (bitvec_get_uint(dest, 1))
529 bitvec_get_uint(dest, 6);
530 /* Timing Advance Timeslot Number */
531 bitvec_get_uint(dest, 3);
532 }
533
534 /* Packet Extended Timing Advance */
535 if (bitvec_get_uint(dest, 1))
536 bitvec_get_uint(dest, 2);
537
538 /* Power Control Parameters */
539 if (bitvec_get_uint(dest, 1)) {
540 /* Alpha */
541 bitvec_get_uint(dest, 4);
542 for (int i=0; i<8 ; i++) {
543 /* Gamma */
544 if (bitvec_get_uint(dest, 1))
545 bitvec_get_uint(dest, 5);
546 }
547 }
548
549 /* Extension Bits */
550 if (bitvec_get_uint(dest, 1)) {
551 int length = bitvec_get_uint(dest, 6);
552 bitvec_get_uint(dest, length);
553 }
554
555 /* Beging of the EGPRS Ack/Nack */
556 has_length = bitvec_get_uint(dest, 1);
557 if (has_length) {
558 length = bitvec_get_uint(dest, 8);
559 } else {
560 /* remaining bits is the length */
561 length = dest->data_len * 8 - dest->cur_bit;
562 }
563 startbit_ack_nack = dest->cur_bit;
564
565 OSMO_ASSERT(bitvec_get_uint(dest, 1) == is_final);
566
567 /* bow Begin Of Window */
568 bow = bitvec_get_uint(dest, 1);
569 /* TODO: check if bow is always present in our implementation */
570
571 /* eow End Of Window */
572 /* TODO: eow checking */
573 bitvec_get_uint(dest, 1);
574
575 *ssn = bitvec_get_uint(dest, 11);
576 if (bow) {
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +0200577 OSMO_ASSERT(*ssn == static_cast<gprs_rlc_ul_window *>(tbf->window())->v_q() + 1);
Alexander Couzens25854512019-06-17 01:50:33 +0200578 }
579
580 crbb_test->has_crbb = bitvec_get_uint(dest, 1);
581 if (crbb_test->has_crbb) {
582 crbb_test->length = bitvec_get_uint(dest, 7);
583 crbb_test->color_code = bitvec_get_uint(dest, 1);
584 if (crbb_test->length % 8)
585 bytelength = crbb_test->length * 8 + 1;
586 else
587 bytelength = crbb_test->length * 8;
588
589 crbb_test->crbb = bitvec_alloc(bytelength, tall_pcu_ctx);
590 for (int i=0; i<crbb_test->length; i++)
591 bitvec_set_bit(crbb_test->crbb, bitvec_get_bit_pos(dest, dest->cur_bit + i));
592
593 dest->cur_bit += crbb_test->length;
594 }
595
596 OSMO_ASSERT(dest->cur_bit < dest->data_len * 8);
597 urbb_length = length - (dest->cur_bit - startbit_ack_nack);
598
599 if (urbb_length > 0) {
600 if (urbb_length % 8)
601 bytelength = urbb_length / 8 + 1;
602 else
603 bytelength = urbb_length / 8;
604
605 *urbb = bitvec_alloc(bytelength, tall_pcu_ctx);
606 for (int i=urbb_length; i>0; i--) {
607 bitvec_set_bit(*urbb, bitvec_get_bit_pos(dest, dest->cur_bit + i - 1));
608 }
609 }
610}
611
612static void check_egprs_bitmap(struct gprs_rlcmac_ul_tbf *tbf, uint16_t ssn, struct crbb_test *crbb_test, bitvec *urbb, unsigned int *rbb_size)
613{
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +0200614 gprs_rlc_ul_window *win = static_cast<gprs_rlc_ul_window *>(tbf->window());
Alexander Couzens25854512019-06-17 01:50:33 +0200615 uint8_t rbb_should[RLC_EGPRS_MAX_WS] = {0};
616 bitvec rbb_should_bv;
617 rbb_should_bv.data = rbb_should;
618 rbb_should_bv.data_len = RLC_EGPRS_MAX_WS;
619 rbb_should_bv.cur_bit = 0;
620
621 /* rbb starting at ssn without mod */
622 bitvec *rbb_ssn_bv = bitvec_alloc(RLC_EGPRS_MAX_WS, tall_pcu_ctx);
623
624 /* even any ssn is allowed, pcu should only use v_q() at least for now */
625 OSMO_ASSERT(ssn == (win->v_q() + 1));
626
627 if (crbb_test->has_crbb) {
628 OSMO_ASSERT(0 == egprs_compress::decompress_crbb(
629 crbb_test->length,
630 crbb_test->color_code,
631 crbb_test->crbb->data,
632 rbb_ssn_bv));
633 }
634
635 if (urbb && urbb->cur_bit > 0) {
636 for (unsigned int i=0; i<urbb->cur_bit; i++) {
637 bitvec_set_bit(rbb_ssn_bv, bitvec_get_bit_pos(urbb, i));
638 }
639 }
640
641 /* check our rbb is equal the decompressed */
642 rbb_should_bv.cur_bit = win->update_egprs_rbb(rbb_should);
643
644 bool failed = false;
645 for (unsigned int i=0; i < rbb_ssn_bv->cur_bit; i++) {
646 if (bitvec_get_bit_pos(&rbb_should_bv, i) !=
647 bitvec_get_bit_pos(rbb_ssn_bv, i))
648 failed = true;
649 }
650 if (failed) {
651 fprintf(stderr, "SSN %d\n", ssn);
652 for (int i=win->v_q(); i<win->ws(); i++) {
653 fprintf(stderr, "bsn %d is %s\n", i, win->is_received( i) ? "received" : "MISS");
654 }
655 char to_dump[256] = { 0 };
656 bitvec_to_string_r(&rbb_should_bv, to_dump);
657 fprintf(stderr, "should: %s\n", to_dump);
658 memset(to_dump, 0x0, 256);
659 bitvec_to_string_r(rbb_ssn_bv, to_dump);
660 fprintf(stderr, "is : %s\n", to_dump);
661 OSMO_ASSERT(false);
662 }
663
664 if (rbb_size)
665 *rbb_size = rbb_ssn_bv->cur_bit;
666}
667
668static void free_egprs_ul_ack_nack(bitvec **rbb, struct crbb_test *crbb_test)
669{
670 if (*rbb) {
671 bitvec_free(*rbb);
672 *rbb = NULL;
673 }
674
675 if (crbb_test->crbb) {
676 bitvec_free(crbb_test->crbb);
677 crbb_test->crbb = NULL;
678 }
679}
680
681static void test_egprs_ul_ack_nack()
682{
683 bitvec *dest = bitvec_alloc(23, tall_pcu_ctx);
684
685 fprintf(stderr, "############## test_egprs_ul_ack_nack\n");
686
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +0100687 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100688 the_pcu->alloc_algorithm = alloc_algorithm_a;
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100689 bts->trx[0].pdch[4].enable();
Alexander Couzens25854512019-06-17 01:50:33 +0200690
Pau Espin Pedrol9da06862023-04-17 19:00:04 +0200691 GprsMs *ms = ms_alloc(bts);
Pau Espin Pedrolbfc97562023-04-17 14:49:29 +0200692 ms_set_ms_class(ms, 1);
693 ms_set_egprs_ms_class(ms, 1);
Pau Espin Pedrolbda7bb72022-10-31 14:33:09 +0100694 struct gprs_rlcmac_ul_tbf *tbf = ul_tbf_alloc(bts, ms, 0, true);
Alexander Couzens25854512019-06-17 01:50:33 +0200695 struct crbb_test crbb_test = {0};
696 bitvec *rbb = NULL;
697 unsigned int rbb_size;
698 uint16_t ssn = 0;
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +0200699 gprs_rlc_ul_window *win = static_cast<gprs_rlc_ul_window *>(tbf->window());
Alexander Couzens25854512019-06-17 01:50:33 +0200700
701 fprintf(stderr, "************** Test with empty window\n");
702 win->reset_state();
703 win->set_ws(256);
704
Pau Espin Pedrolea8dbdd2021-07-29 18:39:16 +0200705 write_packet_uplink_ack(dest, tbf, false, 0);
Alexander Couzens25854512019-06-17 01:50:33 +0200706 extract_egprs_ul_ack_nack(tbf, dest, &ssn, &crbb_test, &rbb, false);
707 check_egprs_bitmap(tbf, ssn, &crbb_test, rbb, &rbb_size);
708 free_egprs_ul_ack_nack(&rbb, &crbb_test);
709 OSMO_ASSERT(rbb_size == 0);
710
711 fprintf(stderr, "************** Test with 1 lost packet\n");
712 win->reset_state();
713 win->set_ws(256);
714 win->receive_bsn(1);
715
Pau Espin Pedrolea8dbdd2021-07-29 18:39:16 +0200716 write_packet_uplink_ack(dest, tbf, false, 0);
Alexander Couzens25854512019-06-17 01:50:33 +0200717 extract_egprs_ul_ack_nack(tbf, dest, &ssn, &crbb_test, &rbb, false);
718 check_egprs_bitmap(tbf, ssn, &crbb_test, rbb, &rbb_size);
719 free_egprs_ul_ack_nack(&rbb, &crbb_test);
720 OSMO_ASSERT(rbb_size == 1);
721
722 fprintf(stderr, "************** Test with compressed window\n");
723 win->reset_state();
724 win->set_ws(128);
725 win->receive_bsn(127);
726
Pau Espin Pedrolea8dbdd2021-07-29 18:39:16 +0200727 write_packet_uplink_ack(dest, tbf, false, 0);
Alexander Couzens25854512019-06-17 01:50:33 +0200728 extract_egprs_ul_ack_nack(tbf, dest, &ssn, &crbb_test, &rbb, false);
729 check_egprs_bitmap(tbf, ssn, &crbb_test, rbb, &rbb_size);
730 free_egprs_ul_ack_nack(&rbb, &crbb_test);
731
732 fprintf(stderr, "************** Provoke an uncompressed ACK without EOW\n");
733 win->reset_state();
734 win->set_ws(384);
735 for (uint16_t i=1; i<384/2; i++)
736 win->receive_bsn(i*2);
737
Pau Espin Pedrolea8dbdd2021-07-29 18:39:16 +0200738 write_packet_uplink_ack(dest, tbf, false, 0);
Alexander Couzens25854512019-06-17 01:50:33 +0200739 extract_egprs_ul_ack_nack(tbf, dest, &ssn, &crbb_test, &rbb, false);
740 check_egprs_bitmap(tbf, ssn, &crbb_test, rbb, &rbb_size);
741 free_egprs_ul_ack_nack(&rbb, &crbb_test);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100742 talloc_free(bts);
Alexander Couzens25854512019-06-17 01:50:33 +0200743}
744
Max81b58cc2019-02-18 20:46:47 +0100745static void check_imm_ass(struct gprs_rlcmac_tbf *tbf, bool dl, enum ph_burst_type bt, const uint8_t *exp, uint8_t len,
746 const char *kind)
747{
Vadim Yanitskiy11567762020-07-18 23:34:17 +0700748 uint8_t alpha = 7, gamma = 8, ta = 35, usf = 1, sz = sizeof(DUMMY_VEC) / 2, plen;
Max81b58cc2019-02-18 20:46:47 +0100749 bitvec *immediate_assignment = bitvec_alloc(sz, tall_pcu_ctx);
750 struct msgb *m = msgb_alloc(80, "test");
751 bool poll = true;
Vadim Yanitskiy11567762020-07-18 23:34:17 +0700752 uint16_t ra = 13;
Max81b58cc2019-02-18 20:46:47 +0100753 uint32_t ref_fn = 24, fn = 11;
754 int8_t ta_idx = 0;
755
Vadim Yanitskiy11567762020-07-18 23:34:17 +0700756 /* HACK: tbf can be NULL, so we cannot use tbf->trx here */
757 struct gprs_rlcmac_trx trx = { };
758 trx.pdch[5].trx = &trx;
759 trx.pdch[5].ts_no = 5;
760 trx.pdch[5].tsc = 1;
761 trx.arfcn = 877;
762
Max81b58cc2019-02-18 20:46:47 +0100763 bitvec_unhex(immediate_assignment, DUMMY_VEC);
Vadim Yanitskiy11567762020-07-18 23:34:17 +0700764 plen = Encoding::write_immediate_assignment(&trx.pdch[5], tbf,
765 immediate_assignment,
766 dl, ra, ref_fn, ta, usf,
Max81b58cc2019-02-18 20:46:47 +0100767 poll, fn, alpha, gamma, ta_idx, bt);
768 printf("[%u] %s Immediate Assignment <%s>:\n\t%s\n", plen, dl ? "DL" : "UL", kind,
769 osmo_hexdump(immediate_assignment->data, sz));
770
771 memcpy(msgb_put(m, sz), immediate_assignment->data, sz);
772 if (!msgb_eq_data_print(m, exp, len))
773 printf("%s(%s, %s) failed!\n", __func__, dl ? "DL" : "UL", kind);
774
775 msgb_free(m);
776}
777
778void test_immediate_assign_dl()
779{
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +0100780 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100781 the_pcu->alloc_algorithm = alloc_algorithm_a;
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100782 bts->trx[0].pdch[2].enable();
783 bts->trx[0].pdch[3].enable();
Pau Espin Pedrol9da06862023-04-17 19:00:04 +0200784 GprsMs *ms = ms_alloc(bts);
Pau Espin Pedrolbfc97562023-04-17 14:49:29 +0200785 ms_set_ms_class(ms, 1);
Max81b58cc2019-02-18 20:46:47 +0100786
Pau Espin Pedrol87573842022-10-26 20:23:45 +0200787 struct gprs_rlcmac_tbf *tbf = dl_tbf_alloc(bts, ms, 0, false);
Max81b58cc2019-02-18 20:46:47 +0100788 static uint8_t res[] = { 0x06,
Pau Espin Pedrolf510f5b2022-10-14 16:37:18 +0200789 0x3f, /* Immediate Assignment Message Type (GSM48_MT_RR_IMM_ASS) */
Max81b58cc2019-02-18 20:46:47 +0100790 0x30, /* §10.5.2.26 Page Mode and §10.5.2.25b Dedicated mode/TBF */
791 0x0d, 0x23, 0x6d, /* §10.5.2.25a Packet Channel Description */
792 /* ETSI TS 44.018 §10.5.2.30 Request Reference */
793 0x7f, /* RA */
794 0x03, 0x18, /* T1'-T3 */
795 0x23, /* TA */
796 0x00, /* 0-length §10.5.2.21 Mobile Allocation */
797 /* ETSI TS 44.018 §10.5.2.16 IA Rest Octets */
Vadim Yanitskiycb988942020-11-08 13:27:35 +0700798 0xdf, 0xff, 0xff, 0xff, 0xf8, 0x17, 0x47, 0x08, 0x0b, 0x5b, 0x2b, 0x2b, };
Max81b58cc2019-02-18 20:46:47 +0100799
800 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 +0100801 talloc_free(bts);
Max81b58cc2019-02-18 20:46:47 +0100802}
803
804void test_immediate_assign_ul0m()
805{
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +0100806 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100807 the_pcu->alloc_algorithm = alloc_algorithm_a;
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100808 bts->trx[0].pdch[4].enable();
809 bts->trx[0].pdch[5].enable();
Max81b58cc2019-02-18 20:46:47 +0100810
Pau Espin Pedrol9da06862023-04-17 19:00:04 +0200811 GprsMs *ms = ms_alloc(bts);
Pau Espin Pedrolbfc97562023-04-17 14:49:29 +0200812 ms_set_ms_class(ms, 1);
Pau Espin Pedrolbda7bb72022-10-31 14:33:09 +0100813 struct gprs_rlcmac_tbf *tbf = ul_tbf_alloc(bts, ms, 0, false);
Max81b58cc2019-02-18 20:46:47 +0100814 static uint8_t res[] = { 0x06,
Pau Espin Pedrolf510f5b2022-10-14 16:37:18 +0200815 0x3f, /* Immediate Assignment Message Type (GSM48_MT_RR_IMM_ASS) */
Max81b58cc2019-02-18 20:46:47 +0100816 0x10, /* §10.5.2.26 Page Mode and §10.5.2.25b Dedicated mode/TBF */
817 0x0d, 0x23, 0x6d, /* §10.5.2.25a Packet Channel Description */
818 /* ETSI TS 44.018 §10.5.2.30 Request Reference */
819 0x0d, /* RA */
820 0x03, 0x18, /* T1'-T3 */
821 0x23, /* TA */
822 0x00, /* 0-length §10.5.2.21 Mobile Allocation */
823 /* ETSI TS 44.018 §10.5.2.16 IA Rest Octets */
Maxe742cc02019-03-12 18:42:09 +0100824 0xc8, 0x02, 0x1b, 0xa2, 0x0b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, };
Max81b58cc2019-02-18 20:46:47 +0100825
826 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 +0100827 talloc_free(bts);
Max81b58cc2019-02-18 20:46:47 +0100828}
829
830void test_immediate_assign_ul0s()
831{
832 static uint8_t res[] = { 0x06,
Pau Espin Pedrolf510f5b2022-10-14 16:37:18 +0200833 0x3f, /* Immediate Assignment Message Type (GSM48_MT_RR_IMM_ASS) */
Max81b58cc2019-02-18 20:46:47 +0100834 0x10, /* §10.5.2.26 Page Mode and §10.5.2.25b Dedicated mode/TBF */
835 0x0d, 0x23, 0x6d, /* §10.5.2.25a Packet Channel Description */
836 /* ETSI TS 44.018 §10.5.2.30 Request Reference */
837 0x0d, /* RA */
838 0x03, 0x18, /* T1'-T3 */
839 0x23, /* TA */
840 0x00, /* 0-length §10.5.2.21 Mobile Allocation */
841 /* ETSI TS 44.018 §10.5.2.16 IA Rest Octets */
Max3eb47362019-02-19 18:41:22 +0100842 0xc5, 0xd0, 0x80, 0xb5, 0xab, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, };
Max81b58cc2019-02-18 20:46:47 +0100843
844 check_imm_ass(NULL, false, GSM_L1_BURST_TYPE_ACCESS_0, res, sizeof(res), "ia_rest_uplink(SBA)");
845}
846
847void test_immediate_assign_ul1s()
848{
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +0100849 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100850 the_pcu->alloc_algorithm = alloc_algorithm_a;
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100851 bts->trx[0].pdch[1].enable();
852 bts->trx[0].pdch[2].enable();
Max81b58cc2019-02-18 20:46:47 +0100853
Pau Espin Pedrol9da06862023-04-17 19:00:04 +0200854 GprsMs *ms = ms_alloc(bts);
Pau Espin Pedrolbfc97562023-04-17 14:49:29 +0200855 ms_set_ms_class(ms, 1);
856 ms_set_egprs_ms_class(ms, 1);
Pau Espin Pedrolbda7bb72022-10-31 14:33:09 +0100857 struct gprs_rlcmac_tbf *tbf = ul_tbf_alloc(bts, ms, 0, false);
Max81b58cc2019-02-18 20:46:47 +0100858 static uint8_t res[] = { 0x06,
Pau Espin Pedrolf510f5b2022-10-14 16:37:18 +0200859 0x3f, /* Immediate Assignment Message Type (GSM48_MT_RR_IMM_ASS) */
Max81b58cc2019-02-18 20:46:47 +0100860 0x10, /* §10.5.2.26 Page Mode and §10.5.2.25b Dedicated mode/TBF */
861 0x0d, 0x23, 0x6d, /* §10.5.2.25a Packet Channel Description */
862 /* ETSI TS 44.018 §10.5.2.30 Request Reference */
863 0x7f, /* RA */
864 0x03, 0x18, /* T1'-T3 */
865 0x23, /* TA */
866 0x00, /* 0-length §10.5.2.21 Mobile Allocation */
867 /* ETSI TS 44.018 §10.5.2.16 IA Rest Octets */
Maxe742cc02019-03-12 18:42:09 +0100868 0x46, 0xa0, 0x08, 0x00, 0x17, 0x44, 0x0b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, };
Max81b58cc2019-02-18 20:46:47 +0100869
870 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 +0100871 talloc_free(bts);
Max81b58cc2019-02-18 20:46:47 +0100872}
873
874void test_immediate_assign_ul1m()
875{
876 static uint8_t res[] = { 0x06,
Pau Espin Pedrolf510f5b2022-10-14 16:37:18 +0200877 0x3f, /* Immediate Assignment Message Type (GSM48_MT_RR_IMM_ASS) */
Max81b58cc2019-02-18 20:46:47 +0100878 0x10, /* §10.5.2.26 Page Mode and §10.5.2.25b Dedicated mode/TBF */
879 0x0d, 0x23, 0x6d, /* §10.5.2.25a Packet Channel Description */
880 /* ETSI TS 44.018 §10.5.2.30 Request Reference */
881 0x7f, /* RA */
882 0x03, 0x18, /* T1'-T3 */
883 0x23, /* TA */
884 0x00, /* 0-length §10.5.2.21 Mobile Allocation */
885 /* ETSI TS 44.018 §10.5.2.16 IA Rest Octets */
886 0x46, 0x97, 0x40, 0x0b, 0x58, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, };
887
888 check_imm_ass(NULL, false, GSM_L1_BURST_TYPE_ACCESS_1, res, sizeof(res), "ia_rest_egprs_uplink(MBA)");
889}
890
aravind sirsikarc0c3afd2016-11-09 16:27:00 +0530891void test_immediate_assign_rej()
892{
893 uint8_t plen;
Alexander Couzensccde5c92017-02-04 03:10:08 +0100894 bitvec *immediate_assignment_rej = bitvec_alloc(22, tall_pcu_ctx);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +0530895
Max7426c5f2019-02-18 20:42:42 +0100896 bitvec_unhex(immediate_assignment_rej, DUMMY_VEC);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +0530897 plen = Encoding::write_immediate_assignment_reject(
898 immediate_assignment_rej, 112, 100,
Pau Espin Pedrol25ebf3c2021-04-26 13:36:16 +0200899 GSM_L1_BURST_TYPE_ACCESS_1, 20);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +0530900
901 printf("assignment reject: %s\n",
902 osmo_hexdump(immediate_assignment_rej->data, 22));
903
904 OSMO_ASSERT(plen == 19);
905 /* RA value */
906 OSMO_ASSERT(immediate_assignment_rej->data[3] == 0x7f);
907 /* Extended RA value */
908 OSMO_ASSERT(immediate_assignment_rej->data[19] == 0xc0);
909
Max7426c5f2019-02-18 20:42:42 +0100910 bitvec_unhex(immediate_assignment_rej, DUMMY_VEC);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +0530911
912 plen = Encoding::write_immediate_assignment_reject(
913 immediate_assignment_rej, 112, 100,
Pau Espin Pedrol25ebf3c2021-04-26 13:36:16 +0200914 GSM_L1_BURST_TYPE_ACCESS_0, 20);
aravind sirsikarc0c3afd2016-11-09 16:27:00 +0530915
916 printf("assignment reject: %s\n",
917 osmo_hexdump(immediate_assignment_rej->data, 22));
918
919 OSMO_ASSERT(plen == 19);
920 /* RA value */
921 OSMO_ASSERT(immediate_assignment_rej->data[3] == 0x70);
922
923}
924
Max20c7c462017-12-22 14:20:05 +0100925static void test_lsb()
926{
927 uint8_t u = 0;
928
929 printf("Testing LBS utility...\n");
930
931 do {
932 uint8_t x = pcu_lsb(u); /* equivalent of (1 << ffs(u)) / 2 */
933 printf("%2X " OSMO_BIT_SPEC ": {%d} %3d\n",
934 u, OSMO_BIT_PRINT(u), pcu_bitcount(u), x);
935 u++;
936 } while (u);
937}
938
Holger Hans Peter Freyther60582202013-11-21 21:30:23 +0100939int main(int argc, char **argv)
940{
Max71affce2018-01-15 11:03:00 +0100941 tall_pcu_ctx = talloc_named_const(NULL, 1, "types test context");
942 if (!tall_pcu_ctx)
943 abort();
944
945 msgb_talloc_ctx_init(tall_pcu_ctx, 0);
Neels Hofmeyr42f2d612018-04-01 16:54:40 +0200946 osmo_init_logging2(tall_pcu_ctx, &gprs_log_info);
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100947 log_set_use_color(osmo_stderr_target, 0);
Pau Espin Pedrol00f52cc2021-02-19 14:01:52 +0100948 log_set_print_filename2(osmo_stderr_target, LOG_FILENAME_NONE);
Pau Espin Pedrolb18d2a52021-02-19 14:00:48 +0100949 log_set_print_category(osmo_stderr_target, 0);
950 log_set_print_category_hex(osmo_stderr_target, 0);
Holger Hans Peter Freyther11f2d582013-11-26 23:32:49 +0100951
Philipp Maierde0e5582020-03-25 12:23:52 +0100952 log_set_category_filter(osmo_stderr_target, DTBF, 1, LOGL_INFO);
953 log_set_category_filter(osmo_stderr_target, DTBFUL, 1, LOGL_INFO);
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +0200954 osmo_fsm_log_addr(false);
Philipp Maierde0e5582020-03-25 12:23:52 +0100955
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100956 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
957
Holger Hans Peter Freyther60582202013-11-21 21:30:23 +0100958 printf("Making some basic type testing.\n");
Alexander Couzens25854512019-06-17 01:50:33 +0200959
Holger Hans Peter Freyther60582202013-11-21 21:30:23 +0100960 test_llc();
Holger Hans Peter Freytherc6382dd2013-11-21 21:42:20 +0100961 test_rlc();
Holger Hans Peter Freyther95255672013-11-23 16:18:18 +0100962 test_rlc_v_b();
Holger Hans Peter Freythere9b1ebb2013-11-24 22:00:43 +0100963 test_rlc_v_n();
Holger Hans Peter Freytherfaf3ef42013-11-24 22:17:40 +0100964 test_rlc_dl_ul_basic();
Max81b58cc2019-02-18 20:46:47 +0100965 test_immediate_assign_dl();
966 test_immediate_assign_ul0m();
967 test_immediate_assign_ul0s();
968 test_immediate_assign_ul1m();
969 test_immediate_assign_ul1s();
aravind sirsikarc0c3afd2016-11-09 16:27:00 +0530970 test_immediate_assign_rej();
Max20c7c462017-12-22 14:20:05 +0100971 test_lsb();
Alexander Couzens25854512019-06-17 01:50:33 +0200972 test_egprs_ul_ack_nack();
Max20c7c462017-12-22 14:20:05 +0100973
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100974 talloc_free(the_pcu);
975
Holger Hans Peter Freyther60582202013-11-21 21:30:23 +0100976 return EXIT_SUCCESS;
977}
978
979/*
980 * stubs that should not be reached
981 */
982extern "C" {
983void l1if_pdch_req() { abort(); }
984void l1if_connect_pdch() { abort(); }
Philipp Maier72ed3332023-02-27 15:32:00 +0100985void l1if_disconnect_pdch() { abort(); }
Holger Hans Peter Freyther60582202013-11-21 21:30:23 +0100986void l1if_close_pdch() { abort(); }
987void l1if_open_pdch() { abort(); }
988}