blob: d6c8f183a8670b9f021903a8c925daa9d446d137 [file] [log] [blame]
Jacob Erlbecke04e0b02015-05-06 18:30:48 +02001/*
2 * MsTest.cpp
3 *
4 * Copyright (C) 2015 by Sysmocom s.f.m.c. GmbH
5 *
6 * All Rights Reserved
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU Affero General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU Affero General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 *
21 */
22
23#include "tbf.h"
Pau Espin Pedrol9d1cdb12019-09-25 17:47:02 +020024#include "tbf_ul.h"
Jacob Erlbecke04e0b02015-05-06 18:30:48 +020025#include "gprs_debug.h"
26#include "gprs_ms.h"
Jacob Erlbeck53670862015-05-12 17:54:33 +020027#include "gprs_ms_storage.h"
Jacob Erlbeck70b96aa2015-06-12 10:52:34 +020028#include "bts.h"
Jacob Erlbecke04e0b02015-05-06 18:30:48 +020029
30extern "C" {
31#include "pcu_vty.h"
32
33#include <osmocom/core/application.h>
34#include <osmocom/core/msgb.h>
35#include <osmocom/core/talloc.h>
36#include <osmocom/core/utils.h>
37#include <osmocom/vty/vty.h>
38}
39
40#include <errno.h>
Jacob Erlbeckd9e10242015-05-28 15:43:53 +020041#include <unistd.h>
Jacob Erlbecke04e0b02015-05-06 18:30:48 +020042
Pau Espin Pedrola0cbde72020-03-26 15:56:15 +010043#include <new>
44
Jacob Erlbecke04e0b02015-05-06 18:30:48 +020045void *tall_pcu_ctx;
46int16_t spoof_mnc = 0, spoof_mcc = 0;
Neels Hofmeyrbdc55fa2018-02-21 00:39:07 +010047bool spoof_mnc_3_digits = false;
Jacob Erlbecke04e0b02015-05-06 18:30:48 +020048
49static void test_ms_state()
50{
51 uint32_t tlli = 0xffeeddbb;
52 gprs_rlcmac_dl_tbf *dl_tbf;
53 gprs_rlcmac_ul_tbf *ul_tbf;
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +010054 BTS the_bts(the_pcu);
Jacob Erlbecke04e0b02015-05-06 18:30:48 +020055 GprsMs *ms;
56
57 printf("=== start %s ===\n", __func__);
58
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +010059 ms = ms_alloc(&the_bts, tlli);
60 OSMO_ASSERT(ms_is_idle(ms));
Jacob Erlbecke04e0b02015-05-06 18:30:48 +020061
62 dl_tbf = talloc_zero(tall_pcu_ctx, struct gprs_rlcmac_dl_tbf);
Pau Espin Pedrole9f77d32020-10-23 18:41:40 +020063 new (dl_tbf) gprs_rlcmac_dl_tbf(&the_bts, ms);
Jacob Erlbecke04e0b02015-05-06 18:30:48 +020064 ul_tbf = talloc_zero(tall_pcu_ctx, struct gprs_rlcmac_ul_tbf);
Pau Espin Pedrole9f77d32020-10-23 18:41:40 +020065 new (ul_tbf) gprs_rlcmac_ul_tbf(&the_bts, ms);
Jacob Erlbecke04e0b02015-05-06 18:30:48 +020066
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +010067 ms_attach_tbf(ms, ul_tbf);
68 OSMO_ASSERT(!ms_is_idle(ms));
69 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
70 OSMO_ASSERT(ms_dl_tbf(ms) == NULL);
Jacob Erlbecke04e0b02015-05-06 18:30:48 +020071
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +010072 ms_attach_tbf(ms, dl_tbf);
73 OSMO_ASSERT(!ms_is_idle(ms));
74 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
75 OSMO_ASSERT(ms_dl_tbf(ms) == dl_tbf);
Jacob Erlbecke04e0b02015-05-06 18:30:48 +020076
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +010077 OSMO_ASSERT(ms_tbf(ms, GPRS_RLCMAC_UL_TBF) == ul_tbf);
78 OSMO_ASSERT(ms_tbf(ms, GPRS_RLCMAC_DL_TBF) == dl_tbf);
Jacob Erlbeckac89a552015-06-29 14:18:46 +020079
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +010080 ms_detach_tbf(ms, ul_tbf);
81 OSMO_ASSERT(!ms_is_idle(ms));
82 OSMO_ASSERT(ms_ul_tbf(ms) == NULL);
83 OSMO_ASSERT(ms_dl_tbf(ms) == dl_tbf);
Jacob Erlbecke04e0b02015-05-06 18:30:48 +020084
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +010085 ms_detach_tbf(ms, dl_tbf);
Jacob Erlbecke04e0b02015-05-06 18:30:48 +020086 /* The ms object is freed now */
87 ms = NULL;
88
89 talloc_free(dl_tbf);
90 talloc_free(ul_tbf);
91
92 printf("=== end %s ===\n", __func__);
93}
94
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +010095static enum {CB_UNKNOWN, CB_IS_IDLE, CB_IS_ACTIVE} last_cb = CB_UNKNOWN;
96static void ms_idle_cb(struct GprsMs *ms)
97{
98 OSMO_ASSERT(ms_is_idle(ms));
99 printf(" ms_idle() was called\n");
100 last_cb = CB_IS_IDLE;
101}
102static void ms_active_cb(struct GprsMs *ms)
103{
104 OSMO_ASSERT(!ms_is_idle(ms));
105 printf(" ms_active() was called\n");
106 last_cb = CB_IS_ACTIVE;
107}
108static struct gpr_ms_callback ms_cb = {
109 .ms_idle = ms_idle_cb,
110 .ms_active = ms_active_cb
111};
Jacob Erlbecke04e0b02015-05-06 18:30:48 +0200112static void test_ms_callback()
113{
114 uint32_t tlli = 0xffeeddbb;
115 gprs_rlcmac_dl_tbf *dl_tbf;
116 gprs_rlcmac_ul_tbf *ul_tbf;
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100117 BTS the_bts(the_pcu);
Jacob Erlbecke04e0b02015-05-06 18:30:48 +0200118 GprsMs *ms;
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100119 last_cb = CB_UNKNOWN;
Jacob Erlbecke04e0b02015-05-06 18:30:48 +0200120
121 printf("=== start %s ===\n", __func__);
122
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100123 ms = ms_alloc(&the_bts, tlli);
124 ms_set_callback(ms, &ms_cb);
Jacob Erlbecke04e0b02015-05-06 18:30:48 +0200125
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100126 OSMO_ASSERT(ms_is_idle(ms));
Jacob Erlbecke04e0b02015-05-06 18:30:48 +0200127
128 dl_tbf = talloc_zero(tall_pcu_ctx, struct gprs_rlcmac_dl_tbf);
Pau Espin Pedrole9f77d32020-10-23 18:41:40 +0200129 new (dl_tbf) gprs_rlcmac_dl_tbf(&the_bts, ms);
Jacob Erlbecke04e0b02015-05-06 18:30:48 +0200130 ul_tbf = talloc_zero(tall_pcu_ctx, struct gprs_rlcmac_ul_tbf);
Pau Espin Pedrole9f77d32020-10-23 18:41:40 +0200131 new (ul_tbf) gprs_rlcmac_ul_tbf(&the_bts, ms);
Jacob Erlbecke04e0b02015-05-06 18:30:48 +0200132
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100133 OSMO_ASSERT(last_cb == CB_UNKNOWN);
Jacob Erlbecke04e0b02015-05-06 18:30:48 +0200134
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100135 ms_attach_tbf(ms, ul_tbf);
136 OSMO_ASSERT(!ms_is_idle(ms));
137 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
138 OSMO_ASSERT(ms_dl_tbf(ms) == NULL);
139 OSMO_ASSERT(last_cb == CB_IS_ACTIVE);
Jacob Erlbecke04e0b02015-05-06 18:30:48 +0200140
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100141 last_cb = CB_UNKNOWN;
Jacob Erlbecke04e0b02015-05-06 18:30:48 +0200142
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100143 ms_attach_tbf(ms, dl_tbf);
144 OSMO_ASSERT(!ms_is_idle(ms));
145 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
146 OSMO_ASSERT(ms_dl_tbf(ms) == dl_tbf);
147 OSMO_ASSERT(last_cb == CB_UNKNOWN);
Jacob Erlbecke04e0b02015-05-06 18:30:48 +0200148
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100149 ms_detach_tbf(ms, ul_tbf);
150 OSMO_ASSERT(!ms_is_idle(ms));
151 OSMO_ASSERT(ms_ul_tbf(ms) == NULL);
152 OSMO_ASSERT(ms_dl_tbf(ms) == dl_tbf);
153 OSMO_ASSERT(last_cb == CB_UNKNOWN);
Jacob Erlbecke04e0b02015-05-06 18:30:48 +0200154
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100155 ms_detach_tbf(ms, dl_tbf);
156 OSMO_ASSERT(ms_is_idle(ms));
157 OSMO_ASSERT(ms_ul_tbf(ms) == NULL);
158 OSMO_ASSERT(ms_dl_tbf(ms) == NULL);
159 OSMO_ASSERT(last_cb == CB_IS_IDLE);
Jacob Erlbecke04e0b02015-05-06 18:30:48 +0200160
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100161 last_cb = CB_UNKNOWN;
162 talloc_free(ms);
Jacob Erlbecke04e0b02015-05-06 18:30:48 +0200163
164 talloc_free(dl_tbf);
165 talloc_free(ul_tbf);
166
167 printf("=== end %s ===\n", __func__);
168}
169
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100170static bool was_idle;
171static void ms_replace_tbf_idle_cb(struct GprsMs *ms)
172{
173 OSMO_ASSERT(ms_is_idle(ms));
174 printf(" ms_idle() was called\n");
175 was_idle = true;
176}
177static void ms_replace_tbf_active_cb(struct GprsMs *ms)
178{
179 OSMO_ASSERT(!ms_is_idle(ms));
180 printf(" ms_active() was called\n");
181}
182static struct gpr_ms_callback ms_replace_tbf_cb = {
183 .ms_idle = ms_replace_tbf_idle_cb,
184 .ms_active = ms_replace_tbf_active_cb
185};
Jacob Erlbecke04e0b02015-05-06 18:30:48 +0200186static void test_ms_replace_tbf()
187{
188 uint32_t tlli = 0xffeeddbb;
189 gprs_rlcmac_dl_tbf *dl_tbf[2];
190 gprs_rlcmac_ul_tbf *ul_tbf;
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100191 BTS the_bts(the_pcu);
Jacob Erlbecke04e0b02015-05-06 18:30:48 +0200192 GprsMs *ms;
Jacob Erlbecke04e0b02015-05-06 18:30:48 +0200193
194 printf("=== start %s ===\n", __func__);
195
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100196 ms = ms_alloc(&the_bts, tlli);
197 ms_set_callback(ms, &ms_replace_tbf_cb);
Jacob Erlbecke04e0b02015-05-06 18:30:48 +0200198
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100199 OSMO_ASSERT(ms_is_idle(ms));
Jacob Erlbecke04e0b02015-05-06 18:30:48 +0200200 was_idle = false;
201
202 dl_tbf[0] = talloc_zero(tall_pcu_ctx, struct gprs_rlcmac_dl_tbf);
Pau Espin Pedrole9f77d32020-10-23 18:41:40 +0200203 new (dl_tbf[0]) gprs_rlcmac_dl_tbf(&the_bts, ms);
Jacob Erlbecke04e0b02015-05-06 18:30:48 +0200204 dl_tbf[1] = talloc_zero(tall_pcu_ctx, struct gprs_rlcmac_dl_tbf);
Pau Espin Pedrole9f77d32020-10-23 18:41:40 +0200205 new (dl_tbf[1]) gprs_rlcmac_dl_tbf(&the_bts, ms);
Jacob Erlbecke04e0b02015-05-06 18:30:48 +0200206 ul_tbf = talloc_zero(tall_pcu_ctx, struct gprs_rlcmac_ul_tbf);
Pau Espin Pedrole9f77d32020-10-23 18:41:40 +0200207 new (ul_tbf) gprs_rlcmac_ul_tbf(&the_bts, ms);
Jacob Erlbecke04e0b02015-05-06 18:30:48 +0200208
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100209 ms_attach_tbf(ms, dl_tbf[0]);
210 OSMO_ASSERT(!ms_is_idle(ms));
211 OSMO_ASSERT(ms_ul_tbf(ms) == NULL);
212 OSMO_ASSERT(ms_dl_tbf(ms) == dl_tbf[0]);
213 OSMO_ASSERT(llist_empty(&ms->old_tbfs));
Jacob Erlbecke04e0b02015-05-06 18:30:48 +0200214 OSMO_ASSERT(!was_idle);
215
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100216 ms_attach_tbf(ms, dl_tbf[1]);
217 OSMO_ASSERT(!ms_is_idle(ms));
218 OSMO_ASSERT(ms_ul_tbf(ms) == NULL);
219 OSMO_ASSERT(ms_dl_tbf(ms) == dl_tbf[1]);
220 OSMO_ASSERT(!llist_empty(&ms->old_tbfs));
Jacob Erlbecke04e0b02015-05-06 18:30:48 +0200221 OSMO_ASSERT(!was_idle);
222
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100223 ms_attach_tbf(ms, ul_tbf);
224 OSMO_ASSERT(!ms_is_idle(ms));
225 OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
226 OSMO_ASSERT(ms_dl_tbf(ms) == dl_tbf[1]);
227 OSMO_ASSERT(!llist_empty(&ms->old_tbfs));
Jacob Erlbecke04e0b02015-05-06 18:30:48 +0200228 OSMO_ASSERT(!was_idle);
229
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100230 ms_detach_tbf(ms, ul_tbf);
231 OSMO_ASSERT(!ms_is_idle(ms));
232 OSMO_ASSERT(ms_ul_tbf(ms) == NULL);
233 OSMO_ASSERT(ms_dl_tbf(ms) == dl_tbf[1]);
234 OSMO_ASSERT(!llist_empty(&ms->old_tbfs));
Jacob Erlbecke04e0b02015-05-06 18:30:48 +0200235 OSMO_ASSERT(!was_idle);
236
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100237 ms_detach_tbf(ms, dl_tbf[0]);
238 OSMO_ASSERT(!ms_is_idle(ms));
239 OSMO_ASSERT(ms_ul_tbf(ms) == NULL);
240 OSMO_ASSERT(ms_dl_tbf(ms) == dl_tbf[1]);
241 OSMO_ASSERT(llist_empty(&ms->old_tbfs));
Jacob Erlbecke04e0b02015-05-06 18:30:48 +0200242 OSMO_ASSERT(!was_idle);
243
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100244 ms_detach_tbf(ms, dl_tbf[1]);
245 OSMO_ASSERT(ms_is_idle(ms));
246 OSMO_ASSERT(ms_ul_tbf(ms) == NULL);
247 OSMO_ASSERT(ms_dl_tbf(ms) == NULL);
248 OSMO_ASSERT(llist_empty(&ms->old_tbfs));
Jacob Erlbecke04e0b02015-05-06 18:30:48 +0200249 OSMO_ASSERT(was_idle);
250
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100251 talloc_free(ms);
Jacob Erlbecke04e0b02015-05-06 18:30:48 +0200252
253 talloc_free(dl_tbf[0]);
254 talloc_free(dl_tbf[1]);
255 talloc_free(ul_tbf);
256
257 printf("=== end %s ===\n", __func__);
258}
259
Jacob Erlbeck93990462015-05-15 15:50:43 +0200260static void test_ms_change_tlli()
261{
262 uint32_t start_tlli = 0xaa000000;
263 uint32_t new_ms_tlli = 0xff001111;
264 uint32_t other_sgsn_tlli = 0xff00eeee;
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100265 BTS the_bts(the_pcu);
Jacob Erlbeck93990462015-05-15 15:50:43 +0200266 GprsMs *ms;
267
268 printf("=== start %s ===\n", __func__);
269
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100270 ms = ms_alloc(&the_bts, start_tlli);
Jacob Erlbeck93990462015-05-15 15:50:43 +0200271
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100272 OSMO_ASSERT(ms_is_idle(ms));
Jacob Erlbeck93990462015-05-15 15:50:43 +0200273
274 /* MS announces TLLI, SGSN uses it immediately */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100275 ms_set_tlli(ms, new_ms_tlli);
276 OSMO_ASSERT(ms_tlli(ms) == new_ms_tlli);
277 OSMO_ASSERT(ms_check_tlli(ms, new_ms_tlli));
278 OSMO_ASSERT(ms_check_tlli(ms, start_tlli));
Jacob Erlbeck93990462015-05-15 15:50:43 +0200279
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100280 ms_confirm_tlli(ms, new_ms_tlli);
281 OSMO_ASSERT(ms_tlli(ms) == new_ms_tlli);
282 OSMO_ASSERT(ms_check_tlli(ms, new_ms_tlli));
283 OSMO_ASSERT(!ms_check_tlli(ms, start_tlli));
Jacob Erlbeck93990462015-05-15 15:50:43 +0200284
285 /* MS announces TLLI, SGSN uses it later */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100286 ms_set_tlli(ms, start_tlli);
287 ms_confirm_tlli(ms, start_tlli);
Jacob Erlbeck93990462015-05-15 15:50:43 +0200288
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100289 ms_set_tlli(ms, new_ms_tlli);
290 OSMO_ASSERT(ms_tlli(ms) == new_ms_tlli);
291 OSMO_ASSERT(ms_check_tlli(ms, new_ms_tlli));
292 OSMO_ASSERT(ms_check_tlli(ms, start_tlli));
Jacob Erlbeck93990462015-05-15 15:50:43 +0200293
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100294 ms_confirm_tlli(ms, start_tlli);
295 OSMO_ASSERT(ms_tlli(ms) == new_ms_tlli);
296 OSMO_ASSERT(ms_check_tlli(ms, new_ms_tlli));
297 OSMO_ASSERT(ms_check_tlli(ms, start_tlli));
Jacob Erlbeck93990462015-05-15 15:50:43 +0200298
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100299 ms_set_tlli(ms, new_ms_tlli);
300 OSMO_ASSERT(ms_tlli(ms) == new_ms_tlli);
301 OSMO_ASSERT(ms_check_tlli(ms, new_ms_tlli));
302 OSMO_ASSERT(ms_check_tlli(ms, start_tlli));
Jacob Erlbeck93990462015-05-15 15:50:43 +0200303
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100304 ms_confirm_tlli(ms, new_ms_tlli);
305 OSMO_ASSERT(ms_tlli(ms) == new_ms_tlli);
306 OSMO_ASSERT(ms_check_tlli(ms, new_ms_tlli));
307 OSMO_ASSERT(!ms_check_tlli(ms, start_tlli));
Jacob Erlbeck93990462015-05-15 15:50:43 +0200308
309 /* MS announces TLLI, SGSN uses it later after another new TLLI */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100310 ms_set_tlli(ms, start_tlli);
311 ms_confirm_tlli(ms, start_tlli);
Jacob Erlbeck93990462015-05-15 15:50:43 +0200312
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100313 ms_set_tlli(ms, new_ms_tlli);
314 OSMO_ASSERT(ms_tlli(ms) == new_ms_tlli);
315 OSMO_ASSERT(ms_check_tlli(ms, new_ms_tlli));
316 OSMO_ASSERT(ms_check_tlli(ms, start_tlli));
Jacob Erlbeck93990462015-05-15 15:50:43 +0200317
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100318 ms_confirm_tlli(ms, other_sgsn_tlli);
319 OSMO_ASSERT(ms_tlli(ms) == new_ms_tlli);
320 OSMO_ASSERT(ms_check_tlli(ms, new_ms_tlli));
321 OSMO_ASSERT(ms_check_tlli(ms, other_sgsn_tlli));
Jacob Erlbeck93990462015-05-15 15:50:43 +0200322
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100323 ms_set_tlli(ms, new_ms_tlli);
324 OSMO_ASSERT(ms_tlli(ms) == new_ms_tlli);
325 OSMO_ASSERT(ms_check_tlli(ms, new_ms_tlli));
326 OSMO_ASSERT(ms_check_tlli(ms, other_sgsn_tlli));
Jacob Erlbeck93990462015-05-15 15:50:43 +0200327
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100328 ms_confirm_tlli(ms, new_ms_tlli);
329 OSMO_ASSERT(ms_tlli(ms) == new_ms_tlli);
330 OSMO_ASSERT(ms_check_tlli(ms, new_ms_tlli));
331 OSMO_ASSERT(!ms_check_tlli(ms, start_tlli));
332 OSMO_ASSERT(!ms_check_tlli(ms, other_sgsn_tlli));
Jacob Erlbeck93990462015-05-15 15:50:43 +0200333
334 /* SGSN uses the new TLLI before it is announced by the MS (shouldn't
335 * happen in normal use) */
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100336 ms_set_tlli(ms, start_tlli);
337 ms_confirm_tlli(ms, start_tlli);
Jacob Erlbeck93990462015-05-15 15:50:43 +0200338
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100339 ms_confirm_tlli(ms, new_ms_tlli);
340 OSMO_ASSERT(ms_tlli(ms) == start_tlli);
341 OSMO_ASSERT(ms_check_tlli(ms, new_ms_tlli));
342 OSMO_ASSERT(ms_check_tlli(ms, start_tlli));
Jacob Erlbeck93990462015-05-15 15:50:43 +0200343
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100344 ms_set_tlli(ms, new_ms_tlli);
345 OSMO_ASSERT(ms_tlli(ms) == new_ms_tlli);
346 OSMO_ASSERT(ms_check_tlli(ms, new_ms_tlli));
347 OSMO_ASSERT(!ms_check_tlli(ms, start_tlli));
Jacob Erlbeck93990462015-05-15 15:50:43 +0200348
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100349 talloc_free(ms);
Jacob Erlbeck93990462015-05-15 15:50:43 +0200350
351 printf("=== end %s ===\n", __func__);
352}
353
Maxf4d39732019-03-12 12:53:27 +0100354static GprsMs *prepare_ms(GprsMsStorage *st, uint32_t tlli, enum gprs_rlcmac_tbf_direction dir)
355{
356 GprsMs *ms = st->get_ms(tlli);
357 if (ms)
358 return ms;
359
360 ms = st->create_ms();
361
362 if (dir == GPRS_RLCMAC_UL_TBF)
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100363 ms_set_tlli(ms, tlli);
Maxf4d39732019-03-12 12:53:27 +0100364 else
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100365 ms_confirm_tlli(ms, tlli);
Maxf4d39732019-03-12 12:53:27 +0100366
367 return ms;
368}
369
Jacob Erlbeck53670862015-05-12 17:54:33 +0200370static void test_ms_storage()
371{
372 uint32_t tlli = 0xffeeddbb;
Jacob Erlbeck7b9f8252015-05-21 11:07:53 +0200373 const char *imsi1 = "001001987654321";
374 const char *imsi2 = "001001987654322";
375
Jacob Erlbeck53670862015-05-12 17:54:33 +0200376 gprs_rlcmac_ul_tbf *ul_tbf;
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100377 BTS the_bts(the_pcu);
Jacob Erlbeck0e50ce62015-05-21 16:58:22 +0200378 GprsMs *ms, *ms_tmp;
Pau Espin Pedrol38de84c2020-10-26 13:46:30 +0100379 GprsMsStorage store(&the_bts);
Jacob Erlbeck53670862015-05-12 17:54:33 +0200380
381 printf("=== start %s ===\n", __func__);
382
Jacob Erlbeck53670862015-05-12 17:54:33 +0200383 ms = store.get_ms(tlli + 0);
384 OSMO_ASSERT(ms == NULL);
385
Maxf4d39732019-03-12 12:53:27 +0100386 ms = prepare_ms(&store, tlli + 0, GPRS_RLCMAC_UL_TBF);
Jacob Erlbeck53670862015-05-12 17:54:33 +0200387 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100388 OSMO_ASSERT(ms_tlli(ms) == tlli + 0);
389 ms_set_imsi(ms, imsi1);
390 OSMO_ASSERT(strcmp(ms_imsi(ms), imsi1) == 0);
Jacob Erlbeck53670862015-05-12 17:54:33 +0200391
Jacob Erlbeck0e50ce62015-05-21 16:58:22 +0200392 ms_tmp = store.get_ms(tlli + 0);
393 OSMO_ASSERT(ms == ms_tmp);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100394 OSMO_ASSERT(ms_tlli(ms) == tlli + 0);
Jacob Erlbeck0e50ce62015-05-21 16:58:22 +0200395
Jacob Erlbeck7b9f8252015-05-21 11:07:53 +0200396 ms_tmp = store.get_ms(0, 0, imsi1);
397 OSMO_ASSERT(ms == ms_tmp);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100398 OSMO_ASSERT(strcmp(ms_imsi(ms), imsi1) == 0);
Jacob Erlbeck7b9f8252015-05-21 11:07:53 +0200399 ms_tmp = store.get_ms(0, 0, imsi2);
400 OSMO_ASSERT(ms_tmp == NULL);
401
Maxf4d39732019-03-12 12:53:27 +0100402 ms = prepare_ms(&store, tlli + 1, GPRS_RLCMAC_UL_TBF);
Jacob Erlbeck0e50ce62015-05-21 16:58:22 +0200403 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100404 OSMO_ASSERT(ms_tlli(ms) == tlli + 1);
405 ms_set_imsi(ms, imsi2);
406 OSMO_ASSERT(strcmp(ms_imsi(ms), imsi2) == 0);
Jacob Erlbeck53670862015-05-12 17:54:33 +0200407
Jacob Erlbeck0e50ce62015-05-21 16:58:22 +0200408 ms_tmp = store.get_ms(tlli + 1);
409 OSMO_ASSERT(ms == ms_tmp);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100410 OSMO_ASSERT(ms_tlli(ms) == tlli + 1);
Jacob Erlbeck53670862015-05-12 17:54:33 +0200411
Jacob Erlbeck7b9f8252015-05-21 11:07:53 +0200412 ms_tmp = store.get_ms(0, 0, imsi1);
413 OSMO_ASSERT(ms_tmp != NULL);
414 OSMO_ASSERT(ms_tmp != ms);
415 ms_tmp = store.get_ms(0, 0, imsi2);
416 OSMO_ASSERT(ms == ms_tmp);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100417 OSMO_ASSERT(strcmp(ms_imsi(ms), imsi2) == 0);
Jacob Erlbeck7b9f8252015-05-21 11:07:53 +0200418
Jacob Erlbeck53670862015-05-12 17:54:33 +0200419 /* delete ms */
420 ms = store.get_ms(tlli + 0);
421 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrole9f77d32020-10-23 18:41:40 +0200422 ul_tbf = talloc_zero(tall_pcu_ctx, struct gprs_rlcmac_ul_tbf);
423 new (ul_tbf) gprs_rlcmac_ul_tbf(&the_bts, ms);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100424 ms_attach_tbf(ms, ul_tbf);
425 ms_detach_tbf(ms, ul_tbf);
Jacob Erlbeck53670862015-05-12 17:54:33 +0200426 ms = store.get_ms(tlli + 0);
427 OSMO_ASSERT(ms == NULL);
428 ms = store.get_ms(tlli + 1);
429 OSMO_ASSERT(ms != NULL);
430
431 /* delete ms */
432 ms = store.get_ms(tlli + 1);
433 OSMO_ASSERT(ms != NULL);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100434 ms_attach_tbf(ms, ul_tbf);
435 ms_detach_tbf(ms, ul_tbf);
Jacob Erlbeck53670862015-05-12 17:54:33 +0200436 ms = store.get_ms(tlli + 1);
437 OSMO_ASSERT(ms == NULL);
438
439 talloc_free(ul_tbf);
440
441 printf("=== end %s ===\n", __func__);
442}
443
Jacob Erlbeckd9e10242015-05-28 15:43:53 +0200444static void test_ms_timeout()
445{
446 uint32_t tlli = 0xffeeddbb;
447 gprs_rlcmac_dl_tbf *dl_tbf;
448 gprs_rlcmac_ul_tbf *ul_tbf;
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100449 BTS the_bts(the_pcu);
Jacob Erlbeckd9e10242015-05-28 15:43:53 +0200450 GprsMs *ms;
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100451 last_cb = CB_UNKNOWN;
Jacob Erlbeckd9e10242015-05-28 15:43:53 +0200452
453 printf("=== start %s ===\n", __func__);
454
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100455 ms = ms_alloc(&the_bts, tlli);
456 ms_set_callback(ms, &ms_cb);
457 ms_set_timeout(ms, 1);
Jacob Erlbeckd9e10242015-05-28 15:43:53 +0200458
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100459 OSMO_ASSERT(ms_is_idle(ms));
Jacob Erlbeckd9e10242015-05-28 15:43:53 +0200460
461 dl_tbf = talloc_zero(tall_pcu_ctx, struct gprs_rlcmac_dl_tbf);
Pau Espin Pedrole9f77d32020-10-23 18:41:40 +0200462 new (dl_tbf) gprs_rlcmac_dl_tbf(&the_bts, ms);
Jacob Erlbeckd9e10242015-05-28 15:43:53 +0200463 ul_tbf = talloc_zero(tall_pcu_ctx, struct gprs_rlcmac_ul_tbf);
Pau Espin Pedrole9f77d32020-10-23 18:41:40 +0200464 new (ul_tbf) gprs_rlcmac_ul_tbf(&the_bts, ms);
Jacob Erlbeckd9e10242015-05-28 15:43:53 +0200465
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100466 OSMO_ASSERT(last_cb == CB_UNKNOWN);
Jacob Erlbeckd9e10242015-05-28 15:43:53 +0200467
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100468 ms_attach_tbf(ms, ul_tbf);
469 OSMO_ASSERT(!ms_is_idle(ms));
470 OSMO_ASSERT(last_cb == CB_IS_ACTIVE);
Jacob Erlbeckd9e10242015-05-28 15:43:53 +0200471
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100472 last_cb = CB_UNKNOWN;
Jacob Erlbeckd9e10242015-05-28 15:43:53 +0200473
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100474 ms_attach_tbf(ms, dl_tbf);
475 OSMO_ASSERT(!ms_is_idle(ms));
476 OSMO_ASSERT(last_cb == CB_UNKNOWN);
Jacob Erlbeckd9e10242015-05-28 15:43:53 +0200477
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100478 ms_detach_tbf(ms, ul_tbf);
479 OSMO_ASSERT(!ms_is_idle(ms));
480 OSMO_ASSERT(last_cb == CB_UNKNOWN);
Jacob Erlbeckd9e10242015-05-28 15:43:53 +0200481
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100482 ms_detach_tbf(ms, dl_tbf);
483 OSMO_ASSERT(!ms_is_idle(ms));
484 OSMO_ASSERT(last_cb == CB_UNKNOWN);
Jacob Erlbeckd9e10242015-05-28 15:43:53 +0200485
486 usleep(1100000);
487 osmo_timers_update();
488
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100489 OSMO_ASSERT(ms_is_idle(ms));
490 OSMO_ASSERT(last_cb == CB_IS_IDLE);
Jacob Erlbeckd9e10242015-05-28 15:43:53 +0200491
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100492 last_cb = CB_UNKNOWN;
493 talloc_free(ms);
Jacob Erlbeckd9e10242015-05-28 15:43:53 +0200494 talloc_free(dl_tbf);
495 talloc_free(ul_tbf);
496
497 printf("=== end %s ===\n", __func__);
498}
499
Jacob Erlbeck70b96aa2015-06-12 10:52:34 +0200500static void test_ms_cs_selection()
501{
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100502 BTS the_bts(the_pcu);
Jacob Erlbeck70b96aa2015-06-12 10:52:34 +0200503 gprs_rlcmac_bts *bts = the_bts.bts_data();
504 uint32_t tlli = 0xffeeddbb;
505
506 gprs_rlcmac_dl_tbf *dl_tbf;
507 GprsMs *ms;
508
509 printf("=== start %s ===\n", __func__);
510
511 bts->initial_cs_dl = 4;
512 bts->initial_cs_ul = 1;
Pau Espin Pedrolad79b852021-01-14 13:20:55 +0100513 the_pcu->vty.cs_downgrade_threshold = 0;
Pau Espin Pedrole8dcf642021-01-14 13:17:01 +0100514 the_pcu->vty.cs_adj_lower_limit = 0;
Jacob Erlbeck70b96aa2015-06-12 10:52:34 +0200515
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100516 ms = ms_alloc(&the_bts, tlli);
Jacob Erlbeck70b96aa2015-06-12 10:52:34 +0200517
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100518 OSMO_ASSERT(ms_is_idle(ms));
Jacob Erlbeck70b96aa2015-06-12 10:52:34 +0200519
520 dl_tbf = talloc_zero(tall_pcu_ctx, struct gprs_rlcmac_dl_tbf);
Pau Espin Pedrole9f77d32020-10-23 18:41:40 +0200521 new (dl_tbf) gprs_rlcmac_dl_tbf(&the_bts, ms);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100522 ms_attach_tbf(ms, dl_tbf);
Jacob Erlbeck70b96aa2015-06-12 10:52:34 +0200523
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100524 OSMO_ASSERT(!ms_is_idle(ms));
Jacob Erlbeck70b96aa2015-06-12 10:52:34 +0200525
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100526 OSMO_ASSERT(mcs_chan_code(ms_current_cs_dl(ms)) == 3);
Jacob Erlbeck70b96aa2015-06-12 10:52:34 +0200527
Pau Espin Pedrolad79b852021-01-14 13:20:55 +0100528 the_pcu->vty.cs_downgrade_threshold = 200;
Jacob Erlbeck70b96aa2015-06-12 10:52:34 +0200529
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100530 OSMO_ASSERT(mcs_chan_code(ms_current_cs_dl(ms)) == 2);
Jacob Erlbeck70b96aa2015-06-12 10:52:34 +0200531
532 talloc_free(dl_tbf);
533
534 printf("=== end %s ===\n", __func__);
535}
536
Max41d6b352019-03-06 15:59:09 +0100537static void dump_ms(const GprsMs *ms, const char *pref)
538{
539 printf("%s MS DL %s/%s, UL %s/%s, mode %s, <%s>\n", pref,
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100540 mcs_name(ms_current_cs_dl(ms)), mcs_name(ms_max_cs_dl(ms)),
541 mcs_name(ms_current_cs_ul(ms)), mcs_name(ms_max_cs_ul(ms)),
542 mode_name(ms_mode(ms)),
543 ms_is_idle(ms) ? "IDLE" : "ACTIVE");
Max41d6b352019-03-06 15:59:09 +0100544}
545
546static void test_ms_mcs_mode()
547{
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100548 BTS the_bts(the_pcu);
Max41d6b352019-03-06 15:59:09 +0100549 gprs_rlcmac_bts *bts = the_bts.bts_data();
550 uint32_t tlli = 0xdeadbeef;
551
552 gprs_rlcmac_dl_tbf *dl_tbf;
553 GprsMs *ms1, *ms2;
554
555 printf("=== start %s ===\n", __func__);
556
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100557 ms1 = ms_alloc(&the_bts, tlli);
Max41d6b352019-03-06 15:59:09 +0100558 dump_ms(ms1, "1: no BTS defaults ");
559
560 bts->initial_cs_dl = 4;
561 bts->initial_cs_ul = 1;
Pau Espin Pedrolad79b852021-01-14 13:20:55 +0100562 the_pcu->vty.cs_downgrade_threshold = 0;
Max41d6b352019-03-06 15:59:09 +0100563
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100564 ms2 = ms_alloc(&the_bts, tlli + 1);
Max41d6b352019-03-06 15:59:09 +0100565 dump_ms(ms2, "2: with BTS defaults");
566
567 dl_tbf = talloc_zero(tall_pcu_ctx, struct gprs_rlcmac_dl_tbf);
Pau Espin Pedrole9f77d32020-10-23 18:41:40 +0200568 new (dl_tbf) gprs_rlcmac_dl_tbf(&the_bts, ms2);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100569 ms_attach_tbf(ms2, dl_tbf);
Max41d6b352019-03-06 15:59:09 +0100570
Max41d6b352019-03-06 15:59:09 +0100571 dump_ms(ms2, "2: after TBF attach ");
572
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100573 ms_set_mode(ms1, EGPRS);
Max41d6b352019-03-06 15:59:09 +0100574 dump_ms(ms1, "1: after mode set ");
575
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100576 ms_set_mode(ms2, EGPRS);
Max41d6b352019-03-06 15:59:09 +0100577 dump_ms(ms2, "2: after mode set ");
578
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100579 ms_set_current_cs_dl(ms1, MCS7);
Max41d6b352019-03-06 15:59:09 +0100580 dump_ms(ms1, "1: after MCS set ");
581
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100582 ms_set_current_cs_dl(ms2, MCS8);
Max41d6b352019-03-06 15:59:09 +0100583 dump_ms(ms2, "2: after MCS set ");
584
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100585 ms_set_mode(ms1, EGPRS_GMSK);
Max41d6b352019-03-06 15:59:09 +0100586 dump_ms(ms1, "1: after mode set ");
587
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100588 ms_set_mode(ms2, EGPRS_GMSK);
Max41d6b352019-03-06 15:59:09 +0100589 dump_ms(ms2, "2: after mode set ");
590
591 // FIXME: following code triggers ASAN failure:
592 // ms2->detach_tbf(dl_tbf);
593 // dump_ms(ms2, "2: after TBF detach ");
594
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100595 ms_set_mode(ms1, GPRS);
Max41d6b352019-03-06 15:59:09 +0100596 dump_ms(ms1, "1: after mode set ");
597
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100598 ms_set_mode(ms2, GPRS);
Max41d6b352019-03-06 15:59:09 +0100599 dump_ms(ms2, "2: after mode set ");
600
601 talloc_free(dl_tbf);
602
603 printf("=== end %s ===\n", __func__);
604}
605
Jacob Erlbecke04e0b02015-05-06 18:30:48 +0200606int main(int argc, char **argv)
607{
608 struct vty_app_info pcu_vty_info = {0};
609
610 tall_pcu_ctx = talloc_named_const(NULL, 1, "MsTest context");
611 if (!tall_pcu_ctx)
612 abort();
613
Neels Hofmeyr78ce5912017-02-08 17:07:31 +0100614 msgb_talloc_ctx_init(tall_pcu_ctx, 0);
Neels Hofmeyr42f2d612018-04-01 16:54:40 +0200615 osmo_init_logging2(tall_pcu_ctx, &gprs_log_info);
Jacob Erlbecke04e0b02015-05-06 18:30:48 +0200616 log_set_use_color(osmo_stderr_target, 0);
617 log_set_print_filename(osmo_stderr_target, 0);
618 log_set_log_level(osmo_stderr_target, LOGL_INFO);
Harald Welteac0490a2017-10-29 10:39:32 +0100619 log_parse_category_mask(osmo_stderr_target, "DPCU,3:DRLCMAC,3");
Jacob Erlbecke04e0b02015-05-06 18:30:48 +0200620
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100621 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
622
Jacob Erlbecke04e0b02015-05-06 18:30:48 +0200623 vty_init(&pcu_vty_info);
Pau Espin Pedrolcd2ac562019-08-05 14:30:44 +0200624 pcu_vty_init();
Jacob Erlbecke04e0b02015-05-06 18:30:48 +0200625
626 test_ms_state();
627 test_ms_callback();
628 test_ms_replace_tbf();
Jacob Erlbeck93990462015-05-15 15:50:43 +0200629 test_ms_change_tlli();
Jacob Erlbeck53670862015-05-12 17:54:33 +0200630 test_ms_storage();
Jacob Erlbeckd9e10242015-05-28 15:43:53 +0200631 test_ms_timeout();
Jacob Erlbeck70b96aa2015-06-12 10:52:34 +0200632 test_ms_cs_selection();
Max41d6b352019-03-06 15:59:09 +0100633 test_ms_mcs_mode();
Jacob Erlbecke04e0b02015-05-06 18:30:48 +0200634
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100635 talloc_free(the_pcu);
636
Jacob Erlbecke04e0b02015-05-06 18:30:48 +0200637 if (getenv("TALLOC_REPORT_FULL"))
638 talloc_report_full(tall_pcu_ctx, stderr);
639
640 return EXIT_SUCCESS;
641}
642
643extern "C" {
644void l1if_pdch_req() { abort(); }
645void l1if_connect_pdch() { abort(); }
646void l1if_close_pdch() { abort(); }
647void l1if_open_pdch() { abort(); }
648}