blob: 1e3ff113e480c0f0e44d6cd8a8a08217f8c02115 [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
39static uint32_t calc_fn(BTS * bts, uint32_t rfn)
40{
41 uint32_t fn;
42 fn = bts->rfn_to_fn(rfn);
43 printf("rfn=%i ==> fn=%i\n", rfn, fn);
44 return fn;
45}
46
47static void set_fn(BTS * bts, uint32_t fn)
48{
49 printf("\n");
50 bts->set_current_frame_number(fn);
51 printf("bts: fn=%i\n", fn);
52}
53
54static void run_test()
55{
56 BTS bts;
57 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 */
66 set_fn(&bts, 1320462);
67 fn = calc_fn(&bts, 5066);
68 OSMO_ASSERT(fn == 1320458);
69
70 set_fn(&bts, 8246);
71 fn = calc_fn(&bts, 8244);
72 OSMO_ASSERT(fn == 8244);
73
74 set_fn(&bts, 10270);
75 fn = calc_fn(&bts, 10269);
76 OSMO_ASSERT(fn == 10269);
77
78 set_fn(&bts, 311276);
79 fn = calc_fn(&bts, 14250);
80 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 */
87 set_fn(&bts, RFN_MODULUS + 30);
88 fn = calc_fn(&bts, RFN_MODULUS - 10);
89 OSMO_ASSERT(fn == 42422);
90
91 set_fn(&bts, RFN_MODULUS + 1);
92 fn = calc_fn(&bts, RFN_MODULUS - 1);
93 OSMO_ASSERT(fn == 42431);
94
95 set_fn(&bts, RFN_MODULUS * 123 + 16);
96 fn = calc_fn(&bts, RFN_MODULUS - 4);
97 OSMO_ASSERT(fn == 5219132);
98
99 set_fn(&bts, RFN_MODULUS * 123 + 451);
100 fn = calc_fn(&bts, RFN_MODULUS - 175);
101 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. */
108 set_fn(&bts, 0);
109 fn = calc_fn(&bts, RFN_MODULUS - 13);
110 OSMO_ASSERT(fn == 2715635);
111
112 set_fn(&bts, 453);
113 fn = calc_fn(&bts, RFN_MODULUS - 102);
114 OSMO_ASSERT(fn == 2715546);
115
116 set_fn(&bts, 10);
117 fn = calc_fn(&bts, RFN_MODULUS - 10);
118 OSMO_ASSERT(fn == 2715638);
119
120 set_fn(&bts, 23);
121 fn = calc_fn(&bts, RFN_MODULUS - 42);
122 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 */
128 set_fn(&bts, GSM_MAX_FN);
129 fn = calc_fn(&bts, RFN_MODULUS-1);
130 OSMO_ASSERT(fn == GSM_MAX_FN-1);
131
132 set_fn(&bts, 0);
133 fn = calc_fn(&bts, RFN_MODULUS-1);
134 OSMO_ASSERT(fn == GSM_MAX_FN-1);
135
136 set_fn(&bts, GSM_MAX_FN);
137 fn = calc_fn(&bts, 0);
138 OSMO_ASSERT(fn == GSM_MAX_FN);
139
140 set_fn(&bts, 0);
141 fn = calc_fn(&bts, 0);
142 OSMO_ASSERT(fn == 0);
143}
144
145int main(int argc, char **argv)
146{
147 tall_pcu_ctx = talloc_named_const(NULL, 1, "fn test context");
148 if (!tall_pcu_ctx)
149 abort();
150
151 msgb_talloc_ctx_init(tall_pcu_ctx, 0);
152 osmo_init_logging(&gprs_log_info);
153 log_set_use_color(osmo_stderr_target, 0);
154 log_set_print_filename(osmo_stderr_target, 0);
155 log_set_log_level(osmo_stderr_target, LOGL_DEBUG);
156
157 run_test();
158 return EXIT_SUCCESS;
159}
160
161/*
162 * stubs that should not be reached
163 */
164extern "C" {
165 void l1if_pdch_req() {
166 abort();
167 } void l1if_connect_pdch() {
168 abort();
169 }
170 void l1if_close_pdch() {
171 abort();
172 }
173 void l1if_open_pdch() {
174 abort();
175 }
176}