blob: 27b9fa8a31b928ed9bb0c151eef43678c801d287 [file] [log] [blame]
Pau Espin Pedroldeaa6fd2020-07-16 20:53:21 +02001/*
2 * (C) 2020 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
3 * All Rights Reserved
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU Affero General Public License as published by
7 * the Free Software Foundation; either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU Affero General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 */
19
20#include <stdio.h>
21#include <stdlib.h>
22#include <inttypes.h>
23
24#include <osmocom/core/application.h>
25#include <osmocom/core/utils.h>
26#include <osmocom/gsm/protocol/gsm_12_21.h>
27#include <osmocom/gsm/gsm23003.h>
28
29#include <osmocom/bsc/gsm_data.h>
30#include <osmocom/bsc/bts.h>
31#include <osmocom/bsc/abis_nm.h>
32#include <osmocom/bsc/debug.h>
33
34static void clock_debug(char* str)
35{
36 struct timespec ts;
37 struct timeval tv;
38 osmo_clock_gettime(CLOCK_MONOTONIC, &ts);
39 osmo_gettimeofday(&tv, NULL);
40 fprintf(stderr, "sys={%lu.%06lu}: %s\n",
41 tv.tv_sec, tv.tv_usec, str);
42}
43
44#define bts_init(net) _bts_init(net, __func__)
45static inline struct gsm_bts *_bts_init(struct gsm_network *net, const char *msg)
46{
47 struct gsm_bts *bts = gsm_bts_alloc(net, 0);
48 if (!bts) {
49 fprintf(stderr, "BTS allocation failure in %s()\n", msg);
50 exit(1);
51 }
52 fprintf(stderr, "BTS allocation OK in %s()\n", msg);
53
54 bts->network = net;
55
56 return bts;
57}
58
59#define bts_del(bts) _bts_del(bts, __func__)
60static inline void _bts_del(struct gsm_bts *bts, const char *msg)
61{
62 osmo_stat_item_group_free(bts->bts_statg);
63 rate_ctr_group_free(bts->bts_ctrs);
64 if (osmo_timer_pending(&bts->acc_mgr.rotate_timer))
65 osmo_timer_del(&bts->acc_mgr.rotate_timer);
Pau Espin Pedrol1e5e7002020-07-23 19:13:56 +020066 if (osmo_timer_pending(&bts->acc_ramp.step_timer))
67 osmo_timer_del(&bts->acc_ramp.step_timer);
Pau Espin Pedroldeaa6fd2020-07-16 20:53:21 +020068 /* no need to llist_del(&bts->list), we never registered the bts there. */
69 talloc_free(bts);
70 fprintf(stderr, "BTS deallocated OK in %s()\n", msg);
71}
72
73static void do_allowed_len_adm_loop(struct acc_mgr *acc_mgr, uint8_t jump)
74{
75 int i;
76 fprintf(stderr, "%s(%" PRIu8 ")\n", __func__, jump);
77 /* Test decreasing the administrative (VTY) max subset size */
78 for (i = 10; i >= 0; i -= jump) {
79 acc_mgr_set_len_allowed_adm(acc_mgr, i);
80 }
81 if (i != 0)
82 acc_mgr_set_len_allowed_adm(acc_mgr, 0);
83 /* Test increasing the administrative (VTY) max subset size */
84 for (i = 0; i <= 10; i += jump) {
85 acc_mgr_set_len_allowed_adm(acc_mgr, i);
86 }
87 if (i != 10)
88 acc_mgr_set_len_allowed_adm(acc_mgr, 10);
89}
90
91static void do_allowed_len_ramp_loop(struct acc_mgr *acc_mgr, uint8_t jump)
92{
93 int i;
94 fprintf(stderr, "%s(%" PRIu8 ")\n", __func__, jump);
95 /* Test decreasing the administrative (VTY) max subset size */
96 for (i = 10; i >= 0; i -= jump) {
97 acc_mgr_set_len_allowed_ramp(acc_mgr, i);
98 }
99 if (i != 0)
100 acc_mgr_set_len_allowed_ramp(acc_mgr, 0);
101 /* Test increasing the administrative (VTY) max subset size */
102 for (i = 0; i <= 10; i += jump) {
103 acc_mgr_set_len_allowed_ramp(acc_mgr, i);
104 }
105 if (i != 10)
106 acc_mgr_set_len_allowed_ramp(acc_mgr, 10);
107}
108
109static void test_acc_mgr_no_ramp(struct gsm_network *net)
110{
111 fprintf(stderr, "===%s===\n", __func__);
112 struct gsm_bts *bts = bts_init(net);
113 struct acc_mgr *acc_mgr = &bts->acc_mgr;
114
115 /* Validate are all allowed by default after allocation: */
116 OSMO_ASSERT(acc_mgr_get_len_allowed_adm(acc_mgr) == 10);
117 OSMO_ASSERT(acc_mgr_get_len_allowed_ramp(acc_mgr) == 10);
118 OSMO_ASSERT(acc_mgr->rotation_time_sec == ACC_MGR_QUANTUM_DEFAULT);
119 OSMO_ASSERT(acc_mgr->allowed_subset_mask == 0x3ff);
120 OSMO_ASSERT(acc_mgr->allowed_subset_mask_count == 10);
121 OSMO_ASSERT(acc_mgr->allowed_permanent_count == 10);
122
123
124 do_allowed_len_adm_loop(acc_mgr, 1);
125 do_allowed_len_adm_loop(acc_mgr, 4);
126
127 /* Now permantenly barr some ACC */
128 fprintf(stderr, "*** Barring some ACCs ***\n");
129 bts->si_common.rach_control.t2 |= 0x02;
130 bts->si_common.rach_control.t3 |= 0xa5;
131 acc_mgr_perm_subset_changed(acc_mgr, &bts->si_common.rach_control);
132
133 do_allowed_len_adm_loop(acc_mgr, 1);
134 do_allowed_len_adm_loop(acc_mgr, 4);
135
136 fprintf(stderr, "*** Barring ALL ACCs ***\n");
137 bts->si_common.rach_control.t2 |= 0x03;
138 bts->si_common.rach_control.t3 |= 0xff;
139 acc_mgr_perm_subset_changed(acc_mgr, &bts->si_common.rach_control);
140
141 fprintf(stderr, "*** Barring zero ACCs ***\n");
142 bts->si_common.rach_control.t2 = 0xfc;
143 bts->si_common.rach_control.t3 = 0x00;
144 acc_mgr_perm_subset_changed(acc_mgr, &bts->si_common.rach_control);
145
146 bts_del(bts);
147}
148
149static void test_acc_mgr_manual_ramp(struct gsm_network *net)
150{
151 fprintf(stderr, "===%s===\n", __func__);
152 struct gsm_bts *bts = bts_init(net);
153 struct acc_mgr *acc_mgr = &bts->acc_mgr;
154
155 /* Validate are all allowed by default after allocation: */
156 OSMO_ASSERT(acc_mgr_get_len_allowed_adm(acc_mgr) == 10);
157 OSMO_ASSERT(acc_mgr_get_len_allowed_ramp(acc_mgr) == 10);
158 OSMO_ASSERT(acc_mgr->rotation_time_sec == ACC_MGR_QUANTUM_DEFAULT);
159 OSMO_ASSERT(acc_mgr->allowed_subset_mask == 0x3ff);
160 OSMO_ASSERT(acc_mgr->allowed_subset_mask_count == 10);
161 OSMO_ASSERT(acc_mgr->allowed_permanent_count == 10);
162
163 do_allowed_len_ramp_loop(acc_mgr, 1);
164 do_allowed_len_ramp_loop(acc_mgr, 4);
165
166 /* Now permantenly barr some ACC */
167 fprintf(stderr, "*** Barring some ACCs ***\n");
168 bts->si_common.rach_control.t2 |= 0x01;
169 bts->si_common.rach_control.t3 |= 0xb3;
170 acc_mgr_perm_subset_changed(acc_mgr, &bts->si_common.rach_control);
171
172 do_allowed_len_ramp_loop(acc_mgr, 1);
173 do_allowed_len_ramp_loop(acc_mgr, 4);
174
175 fprintf(stderr, "*** Barring ALL ACCs ***\n");
176 bts->si_common.rach_control.t2 |= 0x03;
177 bts->si_common.rach_control.t3 |= 0xff;
178 acc_mgr_perm_subset_changed(acc_mgr, &bts->si_common.rach_control);
179 do_allowed_len_ramp_loop(acc_mgr, 1);
180 do_allowed_len_ramp_loop(acc_mgr, 4);
181
182 fprintf(stderr, "*** Barring zero ACCs ***\n");
183 bts->si_common.rach_control.t2 = 0xfc;
184 bts->si_common.rach_control.t3 = 0x00;
185 acc_mgr_perm_subset_changed(acc_mgr, &bts->si_common.rach_control);
186 do_allowed_len_ramp_loop(acc_mgr, 1);
187 do_allowed_len_ramp_loop(acc_mgr, 4);
188
189 fprintf(stderr, "*** Barring some ACCs + adm len 4 ***\n");
190 acc_mgr_set_len_allowed_adm(acc_mgr, 4);
191 bts->si_common.rach_control.t2 = 0xfd;
192 bts->si_common.rach_control.t3 = 0xb3;
193 acc_mgr_perm_subset_changed(acc_mgr, &bts->si_common.rach_control);
194 do_allowed_len_ramp_loop(acc_mgr, 1);
195 do_allowed_len_ramp_loop(acc_mgr, 4);
196
197 bts_del(bts);
198}
199
200static void test_acc_mgr_rotate(struct gsm_network *net)
201{
202 fprintf(stderr, "===%s===\n", __func__);
203 int i;
204 struct gsm_bts *bts = bts_init(net);
205 struct acc_mgr *acc_mgr = &bts->acc_mgr;
206
207 osmo_gettimeofday_override_time = (struct timeval) {0, 0};
208
209 /* Validate are all allowed by default after allocation: */
210 OSMO_ASSERT(acc_mgr_get_len_allowed_adm(acc_mgr) == 10);
211 OSMO_ASSERT(acc_mgr_get_len_allowed_ramp(acc_mgr) == 10);
212 OSMO_ASSERT(acc_mgr->rotation_time_sec == ACC_MGR_QUANTUM_DEFAULT);
213 OSMO_ASSERT(acc_mgr->allowed_subset_mask == 0x3ff);
214 OSMO_ASSERT(acc_mgr->allowed_subset_mask_count == 10);
215 OSMO_ASSERT(acc_mgr->allowed_permanent_count == 10);
216
217 /* Test that rotation won't go over permanently barred ACC*/
218 fprintf(stderr, "*** Barring one ACC ***\n");
219 bts->si_common.rach_control.t2 |= 0x02;
220 acc_mgr_perm_subset_changed(acc_mgr, &bts->si_common.rach_control);
221
222
223 acc_mgr_set_rotation_time(acc_mgr, 2);
224 acc_mgr_set_len_allowed_adm(acc_mgr, 4);
225
226 for (i = 0; i < 20; i++) {
227 osmo_gettimeofday_override_time.tv_sec += 2;
228 clock_debug("select()");
229 osmo_select_main(0);
230 }
231
232 bts_del(bts);
233}
234
Pau Espin Pedrol1e5e7002020-07-23 19:13:56 +0200235static void test_acc_ramp(struct gsm_network *net)
Pau Espin Pedroldeaa6fd2020-07-16 20:53:21 +0200236{
237 fprintf(stderr, "===%s===\n", __func__);
238 int i;
239 struct gsm_bts *bts = bts_init(net);
240 struct acc_mgr *acc_mgr = &bts->acc_mgr;
241 struct acc_ramp *acc_ramp = &bts->acc_ramp;
242
243 /* Validate are all allowed by default after allocation: */
244 OSMO_ASSERT(acc_ramp_is_enabled(acc_ramp) == false);
245 OSMO_ASSERT(acc_ramp_get_step_size(acc_ramp) == ACC_RAMP_STEP_SIZE_DEFAULT);
246 OSMO_ASSERT(acc_ramp_get_step_interval(acc_ramp) == ACC_RAMP_STEP_INTERVAL_MIN);
Pau Espin Pedroldeaa6fd2020-07-16 20:53:21 +0200247
248 /* Set super high rotation time so it doesn't interfer here: */
249 acc_mgr_set_rotation_time(acc_mgr, 5000);
250
Pau Espin Pedroldeaa6fd2020-07-16 20:53:21 +0200251 OSMO_ASSERT(acc_ramp_set_step_interval(acc_ramp, 1) == -ERANGE);
252 OSMO_ASSERT(acc_ramp_set_step_interval(acc_ramp, 50) == 0);
Pau Espin Pedrol1e5e7002020-07-23 19:13:56 +0200253 OSMO_ASSERT(acc_ramp_set_chan_load_thresholds(acc_ramp, 100, 100) == 0);
Pau Espin Pedroldeaa6fd2020-07-16 20:53:21 +0200254 acc_ramp_set_step_size(acc_ramp, 1);
255 acc_ramp_set_enabled(acc_ramp, true);
256
257 osmo_gettimeofday_override_time = (struct timeval) {0, 0};
258 acc_ramp_trigger(acc_ramp);
259
260 for (i = 0; i < 9; i++) {
261 osmo_gettimeofday_override_time.tv_sec += 50;
262 clock_debug("select()");
263 osmo_select_main(0);
264 }
265
266 bts_del(bts);
267}
268
Pau Espin Pedrol1e5e7002020-07-23 19:13:56 +0200269static void test_acc_ramp2(struct gsm_network *net)
Pau Espin Pedroldeaa6fd2020-07-16 20:53:21 +0200270{
271 fprintf(stderr, "===%s===\n", __func__);
272 int i;
273 struct gsm_bts *bts = bts_init(net);
274 struct acc_mgr *acc_mgr = &bts->acc_mgr;
275 struct acc_ramp *acc_ramp = &bts->acc_ramp;
276
277 /* Validate are all allowed by default after allocation: */
278 OSMO_ASSERT(acc_ramp_is_enabled(acc_ramp) == false);
279 OSMO_ASSERT(acc_ramp_get_step_size(acc_ramp) == ACC_RAMP_STEP_SIZE_DEFAULT);
280 OSMO_ASSERT(acc_ramp_get_step_interval(acc_ramp) == ACC_RAMP_STEP_INTERVAL_MIN);
Pau Espin Pedroldeaa6fd2020-07-16 20:53:21 +0200281
282 /* Set super high rotation time so it doesn't interfer here: */
283 acc_mgr_set_rotation_time(acc_mgr, 5000);
284 /* Set adm len to test that ramping won't go over it */
285 acc_mgr_set_len_allowed_adm(acc_mgr, 7);
286
287 acc_ramp_set_step_size(acc_ramp, 3);
288 acc_ramp_set_enabled(acc_ramp, true);
289
290 osmo_gettimeofday_override_time = (struct timeval) {0, 0};
291 acc_ramp_trigger(acc_ramp);
292
293 for (i = 0; i < 3; i++) {
294 osmo_gettimeofday_override_time.tv_sec += ACC_RAMP_STEP_INTERVAL_MIN;
295 clock_debug("select()");
296 osmo_select_main(0);
297 }
298
299 bts_del(bts);
300}
301
Pau Espin Pedrol1e5e7002020-07-23 19:13:56 +0200302static void test_acc_ramp3(struct gsm_network *net)
Pau Espin Pedroldeaa6fd2020-07-16 20:53:21 +0200303{
304 fprintf(stderr, "===%s===\n", __func__);
305 int i;
306 struct gsm_bts *bts = bts_init(net);
307 struct acc_mgr *acc_mgr = &bts->acc_mgr;
308 struct acc_ramp *acc_ramp = &bts->acc_ramp;
309
310 /* Validate are all allowed by default after allocation: */
311 OSMO_ASSERT(acc_ramp_is_enabled(acc_ramp) == false);
312 OSMO_ASSERT(acc_ramp_get_step_size(acc_ramp) == ACC_RAMP_STEP_SIZE_DEFAULT);
313 OSMO_ASSERT(acc_ramp_get_step_interval(acc_ramp) == ACC_RAMP_STEP_INTERVAL_MIN);
Pau Espin Pedroldeaa6fd2020-07-16 20:53:21 +0200314
315 /* Set super high rotation time so it doesn't interfer here: */
316 acc_mgr_set_rotation_time(acc_mgr, 5000);
317 /* Test that ramping won't go over permanently barred ACC*/
318 fprintf(stderr, "*** Barring some ACCs ***\n");
319 bts->si_common.rach_control.t2 |= 0x02;
320 bts->si_common.rach_control.t3 |= 0xa5;
321 acc_mgr_perm_subset_changed(acc_mgr, &bts->si_common.rach_control);
322
323 acc_ramp_set_step_size(acc_ramp, 1);
324 acc_ramp_set_enabled(acc_ramp, true);
325
326 osmo_gettimeofday_override_time = (struct timeval) {0, 0};
327 acc_ramp_trigger(acc_ramp);
328
329 for (i = 0; i < 9; i++) {
330 osmo_gettimeofday_override_time.tv_sec += ACC_RAMP_STEP_INTERVAL_MIN;
331 clock_debug("select()");
332 osmo_select_main(0);
333 }
334
335 bts_del(bts);
336}
337
Pau Espin Pedrol1e5e7002020-07-23 19:13:56 +0200338static void test_acc_ramp_up_rotate(struct gsm_network *net, unsigned int chan_load, unsigned int low_threshold, unsigned int up_threshold)
Pau Espin Pedroldeaa6fd2020-07-16 20:53:21 +0200339{
Pau Espin Pedrol1e5e7002020-07-23 19:13:56 +0200340 fprintf(stderr, "===%s(%u, %u, %u)===\n",
341 __func__, chan_load, low_threshold, up_threshold);
Pau Espin Pedroldeaa6fd2020-07-16 20:53:21 +0200342 struct gsm_bts *bts = bts_init(net);
343 struct acc_mgr *acc_mgr = &bts->acc_mgr;
344 struct acc_ramp *acc_ramp = &bts->acc_ramp;
Pau Espin Pedrol1e5e7002020-07-23 19:13:56 +0200345 int n;
Pau Espin Pedroldeaa6fd2020-07-16 20:53:21 +0200346
347 /* Validate are all allowed by default after allocation: */
348 OSMO_ASSERT(acc_ramp_is_enabled(acc_ramp) == false);
349 OSMO_ASSERT(acc_ramp_get_step_size(acc_ramp) == ACC_RAMP_STEP_SIZE_DEFAULT);
350 OSMO_ASSERT(acc_ramp_get_step_interval(acc_ramp) == ACC_RAMP_STEP_INTERVAL_MIN);
Pau Espin Pedroldeaa6fd2020-07-16 20:53:21 +0200351
352 OSMO_ASSERT(acc_ramp_set_step_interval(acc_ramp, 250) == 0);
353 acc_mgr_set_rotation_time(acc_mgr, 100);
354 /* Test that ramping + rotation won't go over permanently barred ACC*/
355 fprintf(stderr, "*** Barring one ACC ***\n");
356 bts->si_common.rach_control.t2 |= 0x02;
357 acc_mgr_perm_subset_changed(acc_mgr, &bts->si_common.rach_control);
358
Pau Espin Pedrol1e5e7002020-07-23 19:13:56 +0200359 OSMO_ASSERT(acc_ramp_set_step_size(acc_ramp, 1) == 0);
360 OSMO_ASSERT(acc_ramp_set_chan_load_thresholds(acc_ramp, low_threshold, up_threshold) == 0);
Pau Espin Pedroldeaa6fd2020-07-16 20:53:21 +0200361 acc_ramp_set_enabled(acc_ramp, true);
362
Pau Espin Pedrol1e5e7002020-07-23 19:13:56 +0200363 bts->chan_load_avg = chan_load; /*set % channel load */
364
Pau Espin Pedroldeaa6fd2020-07-16 20:53:21 +0200365 osmo_gettimeofday_override_time = (struct timeval) {0, 0};
366 acc_ramp_trigger(acc_ramp);
367
Pau Espin Pedrol1e5e7002020-07-23 19:13:56 +0200368 n = 5;
Pau Espin Pedroldeaa6fd2020-07-16 20:53:21 +0200369 while (true) {
Pau Espin Pedrol1e5e7002020-07-23 19:13:56 +0200370 OSMO_ASSERT(osmo_timer_pending(&acc_ramp->step_timer));
Pau Espin Pedroldeaa6fd2020-07-16 20:53:21 +0200371 if (osmo_timer_pending(&acc_mgr->rotate_timer)) {
372 if ((osmo_gettimeofday_override_time.tv_sec + 50) % 250 == 0)
373 osmo_gettimeofday_override_time.tv_sec += 50;
374 else
375 osmo_gettimeofday_override_time.tv_sec += 100;
Pau Espin Pedroldeaa6fd2020-07-16 20:53:21 +0200376 } else {
377 /* Once ramping is done, adm level is big enough and hence
Pau Espin Pedrol1e5e7002020-07-23 19:13:56 +0200378 * rotation is not needed and will be disabled. Run
379 * ramping a bit more and we are then done */
380 osmo_gettimeofday_override_time.tv_sec -= osmo_gettimeofday_override_time.tv_sec % 250;
381 osmo_gettimeofday_override_time.tv_sec += 250;
382 if (n-- == 0)
383 break;
Pau Espin Pedroldeaa6fd2020-07-16 20:53:21 +0200384 }
385 clock_debug("select()");
386 osmo_select_main(0);
387 }
388
389 bts_del(bts);
390}
391
Pau Espin Pedrol1e5e7002020-07-23 19:13:56 +0200392static void test_acc_ramp_updown_rotate(struct gsm_network *net, unsigned int low_threshold, unsigned int up_threshold,
393 unsigned int min_load, unsigned int max_load, unsigned load_step)
394{
395 fprintf(stderr, "===%s(%u, %u, %u, %u, %u)===\n",
396 __func__, low_threshold, up_threshold,
397 min_load, max_load, load_step);
398 struct gsm_bts *bts = bts_init(net);
399 struct acc_mgr *acc_mgr = &bts->acc_mgr;
400 struct acc_ramp *acc_ramp = &bts->acc_ramp;
401 int i;
402 char buf[256];
403 bool up = true;
404
405 /* Validate are all allowed by default after allocation: */
406 OSMO_ASSERT(acc_ramp_is_enabled(acc_ramp) == false);
407 OSMO_ASSERT(acc_ramp_get_step_size(acc_ramp) == ACC_RAMP_STEP_SIZE_DEFAULT);
408 OSMO_ASSERT(acc_ramp_get_step_interval(acc_ramp) == ACC_RAMP_STEP_INTERVAL_MIN);
409
410 OSMO_ASSERT(acc_ramp_set_step_interval(acc_ramp, 250) == 0);
411 acc_mgr_set_rotation_time(acc_mgr, 100);
412 /* Test that ramping + rotation won't go over permanently barred ACC*/
413 fprintf(stderr, "*** Barring one ACC ***\n");
414 bts->si_common.rach_control.t2 |= 0x02;
415 acc_mgr_perm_subset_changed(acc_mgr, &bts->si_common.rach_control);
416
417 OSMO_ASSERT(acc_ramp_set_step_size(acc_ramp, 1) == 0);
418 OSMO_ASSERT(acc_ramp_set_chan_load_thresholds(acc_ramp, low_threshold, up_threshold) == 0);
419 acc_ramp_set_enabled(acc_ramp, true);
420
421 bts->chan_load_avg = min_load; /* set % channel load */
422
423 osmo_gettimeofday_override_time = (struct timeval) {0, 0};
424 acc_ramp_trigger(acc_ramp);
425
426 /* 50 ev loop iterations */
427 for (i = 0; i < 50; i++) {
428 OSMO_ASSERT(osmo_timer_pending(&acc_ramp->step_timer));
429 if (osmo_timer_pending(&acc_mgr->rotate_timer)) {
430 if ((osmo_gettimeofday_override_time.tv_sec + 50) % 250 == 0)
431 osmo_gettimeofday_override_time.tv_sec += 50;
432 else
433 osmo_gettimeofday_override_time.tv_sec += 100;
434 } else {
435 /* Once ramping is done, adm level is big enough and hence
436 * rotation is not needed and will be disabled. */
437 osmo_gettimeofday_override_time.tv_sec -= osmo_gettimeofday_override_time.tv_sec % 250;
438 osmo_gettimeofday_override_time.tv_sec += 250;
439 }
440 snprintf(buf, sizeof(buf), "select(%d): chan_load_avg=%" PRIu8, i, bts->chan_load_avg);
441 clock_debug(buf);
442 osmo_select_main(0);
443
444 if (up) {
445 bts->chan_load_avg += load_step;
446 if (bts->chan_load_avg >= max_load)
447 up = false;
448 if (bts->chan_load_avg > max_load)
449 bts->chan_load_avg = max_load;
450 } else {
451 bts->chan_load_avg = (uint8_t)OSMO_MAX((int)(bts->chan_load_avg - load_step), 0);
452 if (bts->chan_load_avg <= min_load)
453 up = true;
454 if (bts->chan_load_avg < min_load)
455 bts->chan_load_avg = max_load;
456 }
457 }
458
459 bts_del(bts);
460}
461
Pau Espin Pedroldeaa6fd2020-07-16 20:53:21 +0200462static const struct log_info_cat log_categories[] = {
463 [DRSL] = {
464 .name = "DRSL",
465 .description = "A-bis Radio Signalling Link (RSL)",
466 .enabled = 1, .loglevel = LOGL_NOTICE,
467 },
468};
469
470static const struct log_info log_info = {
471 .cat = log_categories,
472 .num_cat = ARRAY_SIZE(log_categories),
473};
474
475int main(int argc, char **argv)
476{
477 struct gsm_network *net;
478
479 osmo_gettimeofday_override = true;
480 osmo_gettimeofday_override_time = (struct timeval) {0, 0};
481
482 tall_bsc_ctx = talloc_named_const(NULL, 0, "gsm0408_test");
483 osmo_init_logging2(tall_bsc_ctx, &log_info);
484 log_set_log_level(osmo_stderr_target, LOGL_INFO);
485 log_set_print_category_hex(osmo_stderr_target, false);
486 log_set_print_filename2(osmo_stderr_target, LOG_FILENAME_NONE);
487 log_set_use_color(osmo_stderr_target, 0);
488
489 net = gsm_network_init(tall_bsc_ctx);
490 if (!net) {
491 fprintf(stderr, "Network init failure.\n");
492 return EXIT_FAILURE;
493 }
494
495 test_acc_mgr_no_ramp(net);
496 test_acc_mgr_manual_ramp(net);
497 test_acc_mgr_rotate(net);
Pau Espin Pedrol1e5e7002020-07-23 19:13:56 +0200498 test_acc_ramp(net);
499 test_acc_ramp2(net);
500 test_acc_ramp3(net);
501 test_acc_ramp_up_rotate(net, 0, 100, 100);
502 test_acc_ramp_up_rotate(net, 0, 20, 50);
503 test_acc_ramp_up_rotate(net, 70, 80, 90);
504 test_acc_ramp_updown_rotate(net, 80, 90, 0, 100, 15);
505 test_acc_ramp_updown_rotate(net, 30, 50, 10, 100, 15);
506 test_acc_ramp_updown_rotate(net, 50, 49, 0, 100, 10);
507 test_acc_ramp_updown_rotate(net, 30, 80, 30, 80, 5);
Pau Espin Pedroldeaa6fd2020-07-16 20:53:21 +0200508
509 return EXIT_SUCCESS;
510}
511
512/* Whenever ACC code changes the set of barred ACCs, gsm_bts_set_system_infos()
513 * is called which ends up calling pcu_info_update */
514void pcu_info_update(struct gsm_bts *bts) {
515 struct gsm48_rach_control rach_control = {0};
516
517 acc_mgr_apply_acc(&bts->acc_mgr, &rach_control);
Pau Espin Pedrolc7b85d32020-08-27 13:07:44 +0200518 fprintf(stderr, "%s(): t2=0x%02" PRIx8 " t3=0x%02" PRIx8 ", allowed:%s%s%s%s%s%s%s%s%s%s\n",
519 __func__, rach_control.t2, rach_control.t3,
520 rach_control.t3 & (1 << 0) ? "" : " 0",
521 rach_control.t3 & (1 << 1) ? "" : " 1",
522 rach_control.t3 & (1 << 2) ? "" : " 2",
523 rach_control.t3 & (1 << 3) ? "" : " 3",
524 rach_control.t3 & (1 << 4) ? "" : " 4",
525 rach_control.t3 & (1 << 5) ? "" : " 5",
526 rach_control.t3 & (1 << 6) ? "" : " 6",
527 rach_control.t3 & (1 << 7) ? "" : " 7",
528 rach_control.t2 & (1 << 0) ? "" : " 8",
529 rach_control.t2 & (1 << 1) ? "" : " 9"
530 );
Pau Espin Pedroldeaa6fd2020-07-16 20:53:21 +0200531}
532
533
534struct gsm_subscriber_connection *bsc_subscr_con_allocate(struct gsm_network *net) {
535 OSMO_ASSERT(0);
536}
537
538bool on_gsm_ts_init(struct gsm_bts_trx_ts *ts) { return true; }
539void ts_fsm_alloc(struct gsm_bts_trx_ts *ts) {}
540int rsl_chan_ms_power_ctrl(struct gsm_lchan *lchan) { return 0; }
541int rsl_sacch_filling(struct gsm_bts_trx *trx, uint8_t type, const uint8_t *data, int len) { return 0; }
542int rsl_bcch_info(const struct gsm_bts_trx *trx, enum osmo_sysinfo_type si_type, const uint8_t *data, int len)
543{ return 0; }
544int gsm_generate_si(struct gsm_bts *bts, enum osmo_sysinfo_type si_type) { return 0; }