blob: e5ac46d4942d223e49142053e6ebc49890181a29 [file] [log] [blame]
Philipp Maier1275a3f2017-02-21 19:35:23 +01001/* Frame number calculation test */
2
3/* (C) 2016 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
4 * All Rights Reserved
5 *
6 * Author: Philipp Maier
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 Affero 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#include "bts.h"
23#include <string.h>
24#include <stdio.h>
25
26extern "C" {
27#include <osmocom/core/application.h>
28#include <osmocom/gsm/gsm_utils.h>
29#include <osmocom/core/talloc.h>
30#include <osmocom/core/utils.h>
31}
32
33#define RFN_MODULUS 42432
34
35/* globals used by the code */ void *tall_pcu_ctx;
36int16_t spoof_mnc = 0, spoof_mcc = 0;
Neels Hofmeyrbdc55fa2018-02-21 00:39:07 +010037bool spoof_mnc_3_digits = false;
Philipp Maier1275a3f2017-02-21 19:35:23 +010038
Pau Espin Pedrol2182e622021-01-14 16:48:38 +010039static uint32_t calc_fn(struct gprs_rlcmac_bts * bts, uint32_t rfn)
Philipp Maier1275a3f2017-02-21 19:35:23 +010040{
41 uint32_t fn;
Pau Espin Pedrol2182e622021-01-14 16:48:38 +010042 fn = bts_rfn_to_fn(bts, rfn);
Philipp Maier1275a3f2017-02-21 19:35:23 +010043 printf("rfn=%i ==> fn=%i\n", rfn, fn);
44 return fn;
45}
46
Pau Espin Pedrol2182e622021-01-14 16:48:38 +010047static void set_fn(struct gprs_rlcmac_bts * bts, uint32_t fn)
Philipp Maier1275a3f2017-02-21 19:35:23 +010048{
49 printf("\n");
Pau Espin Pedrol2182e622021-01-14 16:48:38 +010050 bts_set_current_frame_number(bts, fn);
Philipp Maier1275a3f2017-02-21 19:35:23 +010051 printf("bts: fn=%i\n", fn);
52}
53
54static void run_test()
55{
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +010056 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Philipp Maier1275a3f2017-02-21 19:35:23 +010057 uint32_t fn;
58
59 printf("RFN_MODULUS=%i\n",RFN_MODULUS);
60 printf("GSM_MAX_FN=%i\n",GSM_MAX_FN);
61
62
63 /* Test with a collection of real world examples,
64 * all all of them are not critical and do not
65 * assume the occurence of any race contions */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +010066 set_fn(bts, 1320462);
67 fn = calc_fn(bts, 5066);
Philipp Maier1275a3f2017-02-21 19:35:23 +010068 OSMO_ASSERT(fn == 1320458);
69
Pau Espin Pedrol2182e622021-01-14 16:48:38 +010070 set_fn(bts, 8246);
71 fn = calc_fn(bts, 8244);
Philipp Maier1275a3f2017-02-21 19:35:23 +010072 OSMO_ASSERT(fn == 8244);
73
Pau Espin Pedrol2182e622021-01-14 16:48:38 +010074 set_fn(bts, 10270);
75 fn = calc_fn(bts, 10269);
Philipp Maier1275a3f2017-02-21 19:35:23 +010076 OSMO_ASSERT(fn == 10269);
77
Pau Espin Pedrol2182e622021-01-14 16:48:38 +010078 set_fn(bts, 311276);
79 fn = calc_fn(bts, 14250);
Philipp Maier1275a3f2017-02-21 19:35:23 +010080 OSMO_ASSERT(fn == 311274);
81
82
83 /* Now lets assume a case where the frame number
84 * just wrapped over a little bit above the
85 * modulo 42432 raster, but the rach request
86 * occurred before the wrapping */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +010087 set_fn(bts, RFN_MODULUS + 30);
88 fn = calc_fn(bts, RFN_MODULUS - 10);
Philipp Maier1275a3f2017-02-21 19:35:23 +010089 OSMO_ASSERT(fn == 42422);
90
Pau Espin Pedrol2182e622021-01-14 16:48:38 +010091 set_fn(bts, RFN_MODULUS + 1);
92 fn = calc_fn(bts, RFN_MODULUS - 1);
Philipp Maier1275a3f2017-02-21 19:35:23 +010093 OSMO_ASSERT(fn == 42431);
94
Pau Espin Pedrol2182e622021-01-14 16:48:38 +010095 set_fn(bts, RFN_MODULUS * 123 + 16);
96 fn = calc_fn(bts, RFN_MODULUS - 4);
Philipp Maier1275a3f2017-02-21 19:35:23 +010097 OSMO_ASSERT(fn == 5219132);
98
Pau Espin Pedrol2182e622021-01-14 16:48:38 +010099 set_fn(bts, RFN_MODULUS * 123 + 451);
100 fn = calc_fn(bts, RFN_MODULUS - 175);
Philipp Maier1275a3f2017-02-21 19:35:23 +0100101 OSMO_ASSERT(fn == 5218961);
102
103
104 /* Lets check a special cornercase. We assume that
105 * the BTS just wrapped its internal frame number
106 * but we still get rach requests with high relative
107 * frame numbers. */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100108 set_fn(bts, 0);
109 fn = calc_fn(bts, RFN_MODULUS - 13);
Philipp Maier1275a3f2017-02-21 19:35:23 +0100110 OSMO_ASSERT(fn == 2715635);
111
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100112 set_fn(bts, 453);
113 fn = calc_fn(bts, RFN_MODULUS - 102);
Philipp Maier1275a3f2017-02-21 19:35:23 +0100114 OSMO_ASSERT(fn == 2715546);
115
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100116 set_fn(bts, 10);
117 fn = calc_fn(bts, RFN_MODULUS - 10);
Philipp Maier1275a3f2017-02-21 19:35:23 +0100118 OSMO_ASSERT(fn == 2715638);
119
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100120 set_fn(bts, 23);
121 fn = calc_fn(bts, RFN_MODULUS - 42);
Philipp Maier1275a3f2017-02-21 19:35:23 +0100122 OSMO_ASSERT(fn == 2715606);
123
124
125 /* Also check with some corner case
126 * values where Fn and RFn reach its
127 * maximum/minimum valid range */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100128 set_fn(bts, GSM_MAX_FN);
129 fn = calc_fn(bts, RFN_MODULUS-1);
Philipp Maier1275a3f2017-02-21 19:35:23 +0100130 OSMO_ASSERT(fn == GSM_MAX_FN-1);
131
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100132 set_fn(bts, 0);
133 fn = calc_fn(bts, RFN_MODULUS-1);
Philipp Maier1275a3f2017-02-21 19:35:23 +0100134 OSMO_ASSERT(fn == GSM_MAX_FN-1);
135
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100136 set_fn(bts, GSM_MAX_FN);
137 fn = calc_fn(bts, 0);
Philipp Maier1275a3f2017-02-21 19:35:23 +0100138 OSMO_ASSERT(fn == GSM_MAX_FN);
139
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100140 set_fn(bts, 0);
141 fn = calc_fn(bts, 0);
Philipp Maier1275a3f2017-02-21 19:35:23 +0100142 OSMO_ASSERT(fn == 0);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100143 talloc_free(bts);
Philipp Maier1275a3f2017-02-21 19:35:23 +0100144}
145
146int main(int argc, char **argv)
147{
148 tall_pcu_ctx = talloc_named_const(NULL, 1, "fn test context");
149 if (!tall_pcu_ctx)
150 abort();
151
152 msgb_talloc_ctx_init(tall_pcu_ctx, 0);
Neels Hofmeyr42f2d612018-04-01 16:54:40 +0200153 osmo_init_logging2(tall_pcu_ctx, &gprs_log_info);
Philipp Maier1275a3f2017-02-21 19:35:23 +0100154 log_set_use_color(osmo_stderr_target, 0);
Pau Espin Pedrol00f52cc2021-02-19 14:01:52 +0100155 log_set_print_filename2(osmo_stderr_target, LOG_FILENAME_NONE);
Philipp Maier1275a3f2017-02-21 19:35:23 +0100156 log_set_log_level(osmo_stderr_target, LOGL_DEBUG);
157
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100158 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
159
Philipp Maier1275a3f2017-02-21 19:35:23 +0100160 run_test();
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +0100161
162 talloc_free(the_pcu);
Philipp Maier1275a3f2017-02-21 19:35:23 +0100163 return EXIT_SUCCESS;
164}
165
166/*
167 * stubs that should not be reached
168 */
169extern "C" {
170 void l1if_pdch_req() {
171 abort();
172 } void l1if_connect_pdch() {
173 abort();
174 }
175 void l1if_close_pdch() {
176 abort();
177 }
178 void l1if_open_pdch() {
179 abort();
180 }
181}