blob: 279903c8f9f8be8644e83291c664a9c1bf88e676 [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;
37
38static uint32_t calc_fn(BTS * bts, uint32_t rfn)
39{
40 uint32_t fn;
41 fn = bts->rfn_to_fn(rfn);
42 printf("rfn=%i ==> fn=%i\n", rfn, fn);
43 return fn;
44}
45
46static void set_fn(BTS * bts, uint32_t fn)
47{
48 printf("\n");
49 bts->set_current_frame_number(fn);
50 printf("bts: fn=%i\n", fn);
51}
52
53static void run_test()
54{
55 BTS bts;
56 uint32_t fn;
57
58 printf("RFN_MODULUS=%i\n",RFN_MODULUS);
59 printf("GSM_MAX_FN=%i\n",GSM_MAX_FN);
60
61
62 /* Test with a collection of real world examples,
63 * all all of them are not critical and do not
64 * assume the occurence of any race contions */
65 set_fn(&bts, 1320462);
66 fn = calc_fn(&bts, 5066);
67 OSMO_ASSERT(fn == 1320458);
68
69 set_fn(&bts, 8246);
70 fn = calc_fn(&bts, 8244);
71 OSMO_ASSERT(fn == 8244);
72
73 set_fn(&bts, 10270);
74 fn = calc_fn(&bts, 10269);
75 OSMO_ASSERT(fn == 10269);
76
77 set_fn(&bts, 311276);
78 fn = calc_fn(&bts, 14250);
79 OSMO_ASSERT(fn == 311274);
80
81
82 /* Now lets assume a case where the frame number
83 * just wrapped over a little bit above the
84 * modulo 42432 raster, but the rach request
85 * occurred before the wrapping */
86 set_fn(&bts, RFN_MODULUS + 30);
87 fn = calc_fn(&bts, RFN_MODULUS - 10);
88 OSMO_ASSERT(fn == 42422);
89
90 set_fn(&bts, RFN_MODULUS + 1);
91 fn = calc_fn(&bts, RFN_MODULUS - 1);
92 OSMO_ASSERT(fn == 42431);
93
94 set_fn(&bts, RFN_MODULUS * 123 + 16);
95 fn = calc_fn(&bts, RFN_MODULUS - 4);
96 OSMO_ASSERT(fn == 5219132);
97
98 set_fn(&bts, RFN_MODULUS * 123 + 451);
99 fn = calc_fn(&bts, RFN_MODULUS - 175);
100 OSMO_ASSERT(fn == 5218961);
101
102
103 /* Lets check a special cornercase. We assume that
104 * the BTS just wrapped its internal frame number
105 * but we still get rach requests with high relative
106 * frame numbers. */
107 set_fn(&bts, 0);
108 fn = calc_fn(&bts, RFN_MODULUS - 13);
109 OSMO_ASSERT(fn == 2715635);
110
111 set_fn(&bts, 453);
112 fn = calc_fn(&bts, RFN_MODULUS - 102);
113 OSMO_ASSERT(fn == 2715546);
114
115 set_fn(&bts, 10);
116 fn = calc_fn(&bts, RFN_MODULUS - 10);
117 OSMO_ASSERT(fn == 2715638);
118
119 set_fn(&bts, 23);
120 fn = calc_fn(&bts, RFN_MODULUS - 42);
121 OSMO_ASSERT(fn == 2715606);
122
123
124 /* Also check with some corner case
125 * values where Fn and RFn reach its
126 * maximum/minimum valid range */
127 set_fn(&bts, GSM_MAX_FN);
128 fn = calc_fn(&bts, RFN_MODULUS-1);
129 OSMO_ASSERT(fn == GSM_MAX_FN-1);
130
131 set_fn(&bts, 0);
132 fn = calc_fn(&bts, RFN_MODULUS-1);
133 OSMO_ASSERT(fn == GSM_MAX_FN-1);
134
135 set_fn(&bts, GSM_MAX_FN);
136 fn = calc_fn(&bts, 0);
137 OSMO_ASSERT(fn == GSM_MAX_FN);
138
139 set_fn(&bts, 0);
140 fn = calc_fn(&bts, 0);
141 OSMO_ASSERT(fn == 0);
142}
143
144int main(int argc, char **argv)
145{
146 tall_pcu_ctx = talloc_named_const(NULL, 1, "fn test context");
147 if (!tall_pcu_ctx)
148 abort();
149
150 msgb_talloc_ctx_init(tall_pcu_ctx, 0);
151 osmo_init_logging(&gprs_log_info);
152 log_set_use_color(osmo_stderr_target, 0);
153 log_set_print_filename(osmo_stderr_target, 0);
154 log_set_log_level(osmo_stderr_target, LOGL_DEBUG);
155
156 run_test();
157 return EXIT_SUCCESS;
158}
159
160/*
161 * stubs that should not be reached
162 */
163extern "C" {
164 void l1if_pdch_req() {
165 abort();
166 } void l1if_connect_pdch() {
167 abort();
168 }
169 void l1if_close_pdch() {
170 abort();
171 }
172 void l1if_open_pdch() {
173 abort();
174 }
175}