blob: c35da9191ebc0e5a3dc7e024e6c3b2cca32e284e [file] [log] [blame]
Harald Welte56db5fd2017-07-14 18:25:59 +02001module Test {
Harald Welteaf549412017-07-15 21:33:21 +02002 import from GSM_Types all;
Harald Weltef0a49972017-07-16 03:55:20 +02003 import from Osmocom_Types all;
Harald Welte56db5fd2017-07-14 18:25:59 +02004 import from GSM_SystemInformation all;
Harald Weltef9764922017-08-20 22:47:44 +02005 import from GSM_RR_Types all;
Harald Welteb622a3d2017-07-14 22:26:33 +02006 import from GSMTAP_Types all;
7 import from GSMTAP_PortType all;
8 import from IPL4_GSMTAP_CtrlFunct all;
Harald Welte9a907b32017-07-15 10:34:27 +02009 import from TELNETasp_PortType all;
Harald Welte8542cef2017-07-19 20:06:26 +020010 import from Osmocom_VTY_Functions all;
Harald Welte56db5fd2017-07-14 18:25:59 +020011
12 const octetstring si1 := '5506198fb38000000000000000000000000000e504002b'O;
13 const octetstring si2 := '59061a00000000000000000000000000000000ffe50400'O;
14 const octetstring si3 := '49061b000062f22404d2490301275d40e50400392b2b2b'O;
15 const octetstring si4 := '31061c62f22404d25d40e504002b2b2b2b2b2b2b2b2b2b'O;
Harald Weltebdc5dbd2017-07-16 00:00:43 +020016 const octetstring c_si2bis := '550602bfe809b3ff00000000000000000000007900002b'O;
17 const octetstring c_si2ter := '010603bf66b0aa0a00000002000000000000002b2b2b2b'O;
18 const octetstring c_si2quater := '050607a8a0364aa698d72ff424feee0506d5e7fff02043'O;
Harald Welte56db5fd2017-07-14 18:25:59 +020019
20 type component dummy_CT {
Harald Welteb622a3d2017-07-14 22:26:33 +020021 port GSMTAP_PT GSMTAP;
Harald Welte9a907b32017-07-15 10:34:27 +020022 port TELNETasp_PT BSCVTY;
Harald Weltebdc5dbd2017-07-16 00:00:43 +020023 var boolean initialized := false;
24 var SystemInformationConfig si_cfg := {
25 bcch_extended := false,
26 si1_present := true,
27 si2bis_present := false,
28 si2ter_present := false,
29 si2quater_present := false,
30 si7_present := false,
31 si8_present := false,
32 si9_present := false,
33 si13_present := false,
34 si13alt_present := false,
35 si15_present := false,
36 si16_present := false,
37 si17_present := false,
38 si2n_present := false,
39 si21_present := false,
40 si22_present := false
41 };
Harald Welte56db5fd2017-07-14 18:25:59 +020042 };
43
44 testcase TC_si1() runs on dummy_CT {
Harald Welte56db5fd2017-07-14 18:25:59 +020045 log("SI: ", dec_SystemInformation(si1));
46 log("SI: ", dec_SystemInformation(si2));
47 log("SI: ", dec_SystemInformation(si3));
48 log("SI: ", dec_SystemInformation(si4));
Harald Weltebdc5dbd2017-07-16 00:00:43 +020049 setverdict(pass);
Harald Welte56db5fd2017-07-14 18:25:59 +020050 }
51
Harald Welteb622a3d2017-07-14 22:26:33 +020052 template GsmtapHeader t_GsmtapHeader := {
53 version := GSMTAP_VERSION,
54 hdr_len := 4,
55 msg_type := ?,
56 timeslot := ?,
57 arfcn := ?,
58 signal_dbm := ?,
59 snr_db := ?,
60 frame_number := ?,
61 sub_type := ?,
62 antenna_nr := ?,
63 sub_slot := ?,
64 res := ?
65 }
66
67 template GsmtapHeader t_GsmtapHeaderUm(template GsmtapChannel ch) modifies t_GsmtapHeader := {
68 msg_type := GSMTAP_TYPE_UM,
69 sub_type := ch
70 }
71
Harald Welteb622a3d2017-07-14 22:26:33 +020072 template GsmtapMessage t_bcch := {
73 header := t_GsmtapHeaderUm(GSMTAP_CHANNEL_BCCH),
74 payload := ?
75 }
76
77 template GSMTAP_RecvFrom t_recvfrom(template GsmtapChannel ch) := {
78 connId := ?,
79 remName := ?,
80 remPort := ?,
81 locName := ?,
82 locPort := GSMTAP_PORT,
83 proto := {udp:={}},
84 userData := ?,
85 msg := { header := t_GsmtapHeaderUm(ch), payload := ?}
86 }
87
Harald Welteaf549412017-07-15 21:33:21 +020088 /* tuple of gsmtap header + decoded SI */
89 type record SystemInformationGsmtap {
90 GsmtapHeader gsmtap,
91 SystemInformation si
92 }
93
94 /* an arbitrary-length vector of decoded SI + gsmtap header */
95 type record of SystemInformationGsmtap SystemInformationVector;
96
97 /* an array of SI-vectors indexed by TC value */
98 type SystemInformationVector SystemInformationVectorPerTc[8];
99
100 type record of integer IntegerRecord;
101
Harald Weltef0a49972017-07-16 03:55:20 +0200102 function int2bool(integer int) return boolean {
103 if (int != 0) {
104 return true;
105 } else {
106 return false;
107 }
108 }
109
Harald Welteaf549412017-07-15 21:33:21 +0200110 function f_array_contains(IntegerRecord arr, integer key) return boolean {
111 for (var integer i:= 0; i< sizeof(arr); i := i + 1) {
112 if (arr[i] == key) {
113 return true;
114 }
115 }
116 return false;
117 }
118
119
120 /* compute TC as per 45.002 6.3.1.3 */
121 function f_gsm_compute_tc(integer fn) return integer {
122 return (fn / 51) mod 8;
123 }
124
125 /* determine if a given SI vector contains given SI type at least once */
126 function f_si_vecslot_contains(SystemInformationVector arr, RrMessageType key, boolean bcch_ext := false) return boolean {
127 for (var integer i:= 0; i< sizeof(arr); i := i + 1) {
128 var integer fn_mod51 := arr[i].gsmtap.frame_number mod 51;
129 if (not bcch_ext and fn_mod51 == 2 or
130 bcch_ext and fn_mod51 == 6) {
131 if (arr[i].si.header.message_type == key) {
132 return true;
133 }
134 }
135 }
136 return false;
137 }
138
Harald Welte39276772017-07-16 01:07:42 +0200139 /* ensure a given TC slot of the SI vector contains given SI type at least once at TC */
140 function f_ensure_si_vec_contains(SystemInformationVectorPerTc arr, integer tc, RrMessageType key, boolean ext_bcch := false) {
141 if (not f_si_vecslot_contains(arr[tc], key, ext_bcch)) {
Daniel Willmannafce8662018-07-06 23:11:32 +0200142 setverdict(fail, "Fail: No ", key, " in TC=", tc, "!");
143 mtc.stop;
Harald Welte39276772017-07-16 01:07:42 +0200144 }
145 }
146
Harald Welteaf549412017-07-15 21:33:21 +0200147 /* check if a given SI vector contains given SI type at least once on any TC */
148 function f_si_vec_contains(SystemInformationVectorPerTc arr, RrMessageType key) return boolean {
149 for (var integer tc:= 0; tc < sizeof(arr); tc := tc + 1) {
150 if (f_si_vecslot_contains(arr[tc], key) or
151 f_si_vecslot_contains(arr[tc], key, true)) {
152 return true;
153 }
154 }
155 return false;
156 }
157
Harald Welte39276772017-07-16 01:07:42 +0200158 /* determine if a given SI vector contains given SI type at least N of M times */
159 function f_si_vecslot_contains_n_of_m(SystemInformationVector arr, RrMessageType key, boolean bcch_ext := false, integer n := 1, integer m := 4) return boolean {
160 var integer count := 0;
161 if (sizeof(arr) < m) {
Harald Welte75f761f2017-07-16 03:05:31 +0200162 testcase.stop("Error: Insufficient SI in array");
Harald Welte39276772017-07-16 01:07:42 +0200163 }
164 for (var integer i:= 0; i < m; i := i + 1) {
165 var integer fn_mod51 := arr[i].gsmtap.frame_number mod 51;
166 if (not bcch_ext and fn_mod51 == 2 or
167 bcch_ext and fn_mod51 == 6) {
168 if (arr[i].si.header.message_type == key) {
169 count := count + 1;
170 }
171 }
172 }
173 if (count >= n) {
174 return true;
175 } else {
176 return false;
177 }
178 }
179
180 /* ensure a given TC slot of the SI vector contains given SI type at least N out of M times at TC */
181 function f_ensure_si_vec_contains_n_of_m(SystemInformationVectorPerTc arr, integer tc, RrMessageType key, boolean ext_bcch := false, integer n, integer m) {
182 if (not f_si_vecslot_contains_n_of_m(arr[tc], key, ext_bcch, n, m)) {
Daniel Willmannafce8662018-07-06 23:11:32 +0200183 setverdict(fail, "Fail: Not ", n, "/", m, " of ", key, " in TC=", tc, "!");
184 mtc.stop;
Harald Welte39276772017-07-16 01:07:42 +0200185 }
186 }
187
188 /* determine if a given SI vector contains given SI type at least once */
189 function f_si_vecslot_contains_only(SystemInformationVector arr, RrMessageType key, boolean bcch_ext := false) return boolean {
190 for (var integer i:= 0; i< sizeof(arr); i := i + 1) {
191 var integer fn_mod51 := arr[i].gsmtap.frame_number mod 51;
192 if (not bcch_ext and fn_mod51 == 2 or
193 bcch_ext and fn_mod51 == 6) {
194 if (arr[i].si.header.message_type != key) {
195 return false;
196 }
197 }
198 }
199 return true;
200 }
201
202 /* ensure a given TC slot of the SI vector contains only given SI type */
203 function f_ensure_si_vec_contains_only(SystemInformationVectorPerTc arr, integer tc, RrMessageType key, boolean ext_bcch := false) {
204 if (not f_si_vecslot_contains_only(arr[tc], key, ext_bcch)) {
Daniel Willmannafce8662018-07-06 23:11:32 +0200205 setverdict(fail, "Fail: Not all ", key, " in TC=", tc, "!");
206 mtc.stop;
Harald Welteaf549412017-07-15 21:33:21 +0200207 }
208 }
209
210 /* SI configuration of cell, against which we validate actual SI messages */
211 type set SystemInformationConfig {
212 boolean bcch_extended,
213 boolean si1_present,
214 boolean si2bis_present,
215 boolean si2ter_present,
216 boolean si2quater_present,
217 boolean si7_present,
218 boolean si8_present,
219 boolean si9_present,
220 boolean si13_present,
221 boolean si13alt_present,
222 boolean si15_present,
223 boolean si16_present,
224 boolean si17_present,
225 boolean si2n_present,
226 boolean si21_present,
227 boolean si22_present
228 }
229
230 /* validate the SI scheduling according to TS 45.002 version 14.1.0 Release 14, Section 6.3.1.3 */
231 function f_validate_si_scheduling(SystemInformationConfig cfg, SystemInformationVectorPerTc si_per_tc) {
232 var integer i;
233 for (i := 0; i < sizeof(si_per_tc); i := i + 1) {
234 if (sizeof(si_per_tc[i]) == 0) {
235 setverdict(fail, "No SI messages for TC=0!");
Daniel Willmannafce8662018-07-06 23:11:32 +0200236 mtc.stop;
Harald Welteaf549412017-07-15 21:33:21 +0200237 }
238 }
239 if (cfg.si1_present) {
240 /* ii) System Information Type 1 needs to be sent if frequency hopping is in use or
241 * when the NCH is present in a cell. If the MS finds another message on BCCH Norm
242 * when TC = 0, it can assume that System Information Type 1 is not in use. */
243 f_ensure_si_vec_contains(si_per_tc, 0, SYSTEM_INFORMATION_TYPE_1);
Harald Welte39276772017-07-16 01:07:42 +0200244 /* make sure *ALL* contain SI1 */
245 f_ensure_si_vec_contains_only(si_per_tc, 0, SYSTEM_INFORMATION_TYPE_1);
Harald Welteaf549412017-07-15 21:33:21 +0200246 }
247 f_ensure_si_vec_contains(si_per_tc, 1, SYSTEM_INFORMATION_TYPE_2);
248 /* iii) A SI 2 message will be sent at least every time TC = 1 */
249 f_ensure_si_vec_contains(si_per_tc, 2, SYSTEM_INFORMATION_TYPE_3);
250 f_ensure_si_vec_contains(si_per_tc, 6, SYSTEM_INFORMATION_TYPE_3);
251 f_ensure_si_vec_contains(si_per_tc, 3, SYSTEM_INFORMATION_TYPE_4);
252 f_ensure_si_vec_contains(si_per_tc, 7, SYSTEM_INFORMATION_TYPE_4);
253
254 /* iii) System information type 2 bis or 2 ter messages are sent if needed, as determined by the
255 * system operator. If only one of them is needed, it is sent when TC = 5. If both are
256 * needed, 2bis is sent when TC = 5 and 2ter is sent at least once within any of 4
257 * consecutive occurrences of TC = 4. */
258 if (cfg.si2bis_present and not cfg.si2ter_present) {
259 f_ensure_si_vec_contains(si_per_tc, 5, SYSTEM_INFORMATION_TYPE_2bis);
260 } else if (cfg.si2ter_present and not cfg.si2bis_present) {
261 f_ensure_si_vec_contains(si_per_tc, 5, SYSTEM_INFORMATION_TYPE_2ter);
262 } else if (cfg.si2ter_present and cfg.si2bis_present) {
263 f_ensure_si_vec_contains(si_per_tc, 5, SYSTEM_INFORMATION_TYPE_2bis);
Harald Welte39276772017-07-16 01:07:42 +0200264 f_ensure_si_vec_contains_n_of_m(si_per_tc, 4, SYSTEM_INFORMATION_TYPE_2ter, false, 1, 4);
Harald Welteaf549412017-07-15 21:33:21 +0200265 }
266
267 if (cfg.si7_present or cfg.si8_present) {
268 /* vi) Use of System Information type 7 and 8 is not always necessary. It is necessary
269 * if System Information type 4 does not contain all information needed for cell
270 * selection and reselection. */
271 if (not cfg.bcch_extended) {
Harald Welte75f761f2017-07-16 03:05:31 +0200272 testcase.stop("Error: SI7/SI8 require BCCH Extd.");
Harald Welteaf549412017-07-15 21:33:21 +0200273 }
274 if (cfg.si7_present) {
275 f_ensure_si_vec_contains(si_per_tc, 7, SYSTEM_INFORMATION_TYPE_7, true);
276 }
277 if (cfg.si8_present) {
278 f_ensure_si_vec_contains(si_per_tc, 3, SYSTEM_INFORMATION_TYPE_8, true);
279 }
280 }
281
282 if (cfg.si2quater_present) {
283 /* iii) System information type 2 quater is sent if needed, as determined by the system
284 * operator. If sent on BCCH Norm, it shall be sent when TC = 5 if neither of 2bis
285 * and 2ter are used, otherwise it shall be sent at least once within any of 4
286 * consecutive occurrences of TC = 4. If sent on BCCH Ext, it is sent at least once
287 * within any of 4 consecutive occurrences of TC = 5. */
288 if (not (cfg.bcch_extended)) {
289 if (not (cfg.si2bis_present or cfg.si2ter_present)) {
290 f_ensure_si_vec_contains(si_per_tc, 5, SYSTEM_INFORMATION_TYPE_2quater);
291 } else {
Harald Welte39276772017-07-16 01:07:42 +0200292 f_ensure_si_vec_contains_n_of_m(si_per_tc, 4, SYSTEM_INFORMATION_TYPE_2quater, false, 1, 4);
Harald Welteaf549412017-07-15 21:33:21 +0200293 }
294 } else {
Harald Welte39276772017-07-16 01:07:42 +0200295 f_ensure_si_vec_contains_n_of_m(si_per_tc, 5, SYSTEM_INFORMATION_TYPE_2quater, true, 1, 4);
Harald Welteaf549412017-07-15 21:33:21 +0200296 }
297 }
298 if (cfg.si9_present) {
299 /* vi) System Information type 9 is sent in those blocks with TC = 4 which are specified
300 * in system information type 3 as defined in 3GPP TS 44.018. */
301 f_ensure_si_vec_contains(si_per_tc, 4, SYSTEM_INFORMATION_TYPE_9); // FIXME SI3
302 }
303 if (cfg.si13_present) {
304 /* vii) System Information type 13 is only related to the GPRS service. System Information
305 * Type 13 need only be sent if GPRS support is indicated in one or more of System
306 * Information Type 3 or 4 or 7 or 8 messages. These messages also indicate if the
307 * message is sent on the BCCH Norm or if the message is transmitted on the BCCH Ext.
308 * In the case that the message is sent on the BCCH Norm, it is sent at least once
309 * within any of 4 consecutive occurrences of TC=4. */
310 if (not cfg.bcch_extended) {
Harald Welte39276772017-07-16 01:07:42 +0200311 f_ensure_si_vec_contains_n_of_m(si_per_tc, 4, SYSTEM_INFORMATION_TYPE_13, false, 1, 4);
Harald Welteaf549412017-07-15 21:33:21 +0200312 } else {
313 f_ensure_si_vec_contains(si_per_tc, 0, SYSTEM_INFORMATION_TYPE_13, true);
314 }
315 if (f_si_vec_contains(si_per_tc, SYSTEM_INFORMATION_TYPE_13alt)) {
316 setverdict(fail, "Cannot have SI13alt and SI13");
Daniel Willmannafce8662018-07-06 23:11:32 +0200317 mtc.stop;
Harald Welteaf549412017-07-15 21:33:21 +0200318 }
319 }
320 if (cfg.si16_present or cfg.si17_present) {
321 /* viii) System Information type 16 and 17 are only related to the SoLSA service. They
322 * should not be sent in a cell where network sharing is used (see rule xv). */
323 if (cfg.si22_present) {
Harald Welte75f761f2017-07-16 03:05:31 +0200324 testcase.stop("Error: Cannot have SI16/SI17 and SI22!");
Harald Welteaf549412017-07-15 21:33:21 +0200325 }
326 if (f_si_vec_contains(si_per_tc, SYSTEM_INFORMATION_TYPE_22)) {
327 setverdict(fail, "Cannot have SI16/SI17 and SI22!");
Daniel Willmannafce8662018-07-06 23:11:32 +0200328 mtc.stop;
Harald Welteaf549412017-07-15 21:33:21 +0200329 }
330 if (not cfg.bcch_extended) {
Harald Welte75f761f2017-07-16 03:05:31 +0200331 testcase.stop("Error: SI16/SI17 requires BCCH Extd!");
Harald Welteaf549412017-07-15 21:33:21 +0200332 }
333 if (cfg.si16_present) {
334 f_ensure_si_vec_contains(si_per_tc, 6, SYSTEM_INFORMATION_TYPE_16, true);
335 }
336 if (cfg.si17_present) {
337 f_ensure_si_vec_contains(si_per_tc, 2, SYSTEM_INFORMATION_TYPE_17, true);
338 }
339 }
340
341 /* ix) System Information type 18 and 20 are sent in order to transmit non-GSM
342 * broadcast information. The frequency with which they are sent is determined by the
343 * system operator. System Information type 9 identifies the scheduling of System
344 * Information type 18 and 20 messages. */
345
346 /* x) System Information Type 19 is sent if COMPACT neighbours exist. If System
347 * Information Type 19 is present, then its scheduling shall be indicated in System
348 * Information Type 9. */
349
350 if (cfg.si15_present) {
351 /* xi) System Information Type 15 is broadcast if dynamic ARFCN mapping is used in the
352 * PLMN. If sent on BCCH Norm, it is sent at least once within any of 4 consecutive
353 * occurrences of TC = 4. If sent on BCCH Ext, it is sent at least once within any of
354 * 4 consecutive occurrences of TC = 1. */
355 if (not cfg.bcch_extended) {
Harald Welte39276772017-07-16 01:07:42 +0200356 f_ensure_si_vec_contains_n_of_m(si_per_tc, 4, SYSTEM_INFORMATION_TYPE_15, false, 1, 4);
Harald Welteaf549412017-07-15 21:33:21 +0200357 } else {
Harald Welte39276772017-07-16 01:07:42 +0200358 f_ensure_si_vec_contains_n_of_m(si_per_tc, 1, SYSTEM_INFORMATION_TYPE_15, true, 1, 4);
Harald Welteaf549412017-07-15 21:33:21 +0200359 }
360 }
361 if (cfg.si13alt_present) {
362 /* xii) System Information type 13 alt is only related to the GERAN Iu mode. System
363 * Information Type 13 alt need only be sent if GERAN Iu mode support is indicated in
364 * one or more of System Information Type 3 or 4 or 7 or 8 messages and SI 13 is not
365 * broadcast. These messages also indicate if the message is sent on the BCCH Norm or
366 * if the message is transmitted on the BCCH Ext. In the case that the message is sent
367 * on the BCCH Norm, it is sent at least once within any of 4 consecutive occurrences
368 * of TC = 4. */
369 if (cfg.si13_present) {
Harald Welte75f761f2017-07-16 03:05:31 +0200370 testcase.stop("Error: Cannot have SI13alt and SI13");
Harald Welteaf549412017-07-15 21:33:21 +0200371 }
372 if (f_si_vec_contains(si_per_tc, SYSTEM_INFORMATION_TYPE_13)) {
373 setverdict(fail, "Cannot have SI13alt and SI13");
Daniel Willmannafce8662018-07-06 23:11:32 +0200374 mtc.stop;
Harald Welteaf549412017-07-15 21:33:21 +0200375 }
376 if (not cfg.bcch_extended) {
Harald Welte39276772017-07-16 01:07:42 +0200377 f_ensure_si_vec_contains_n_of_m(si_per_tc, 4, SYSTEM_INFORMATION_TYPE_13alt, false, 1, 4);
Harald Welteaf549412017-07-15 21:33:21 +0200378 } else {
379 f_ensure_si_vec_contains(si_per_tc, 0, SYSTEM_INFORMATION_TYPE_13alt, true);
380 }
381 }
382 if (cfg.si2n_present) {
383 /* xiii) System Information Type 2n is optionally sent on BCCH Norm or BCCH Ext if needed,
384 * as determined by the system operator. In the case that the message is sent on the
385 * BCCH Norm, it is sent at least once within any of 4 consecutive occurrences of TC =
386 * 4. If the message is sent on BCCH Ext, it is sent at least once within any of 2
387 * consecutive occurrences of TC = 4. */
388 if (not cfg.bcch_extended) {
Harald Welte39276772017-07-16 01:07:42 +0200389 f_ensure_si_vec_contains_n_of_m(si_per_tc, 4, SYSTEM_INFORMATION_TYPE_2n, false, 1, 4);
Harald Welteaf549412017-07-15 21:33:21 +0200390 } else {
Harald Welte39276772017-07-16 01:07:42 +0200391 f_ensure_si_vec_contains_n_of_m(si_per_tc, 4, SYSTEM_INFORMATION_TYPE_2n, true, 2, 4);
Harald Welteaf549412017-07-15 21:33:21 +0200392 }
393 }
394 if (cfg.si21_present) {
395 /* xiv) System Information Type 21 is optionally sent on BCCH Norm or BCCH Ext, as
396 * determined by the system operator. If Extended Access Barring is in use in the cell
397 * then this message is sent at least once within any of 4 consecutive occurrences of
398 * TC = 4 regardless if it is sent on BCCH Norm or BCCH Ext. If BCCH Ext is used in a
399 * cell then this message shall only be sent on BCCH Ext. */
400 if (not cfg.bcch_extended) {
Harald Welte39276772017-07-16 01:07:42 +0200401 f_ensure_si_vec_contains_n_of_m(si_per_tc, 4, SYSTEM_INFORMATION_TYPE_21, false, 1, 4);
Harald Welteaf549412017-07-15 21:33:21 +0200402 } else {
Harald Welte39276772017-07-16 01:07:42 +0200403 f_ensure_si_vec_contains_n_of_m(si_per_tc, 4, SYSTEM_INFORMATION_TYPE_21, true, 1, 4);
Harald Welteaf549412017-07-15 21:33:21 +0200404 if (f_si_vecslot_contains(si_per_tc[4], SYSTEM_INFORMATION_TYPE_21)) {
405 setverdict(fail, "Cannot have SI21 on BCCH Norm if BCCH Extd enabled!");
Daniel Willmannafce8662018-07-06 23:11:32 +0200406 mtc.stop;
Harald Welteaf549412017-07-15 21:33:21 +0200407 }
408 }
409 }
410 if (cfg.si22_present) {
411 /* xv) System Information Type 22 is sent if network sharing is in use in the cell. It
412 * should not be sent in a cell where SoLSA is used (see rule viii). System
413 * Information Type 22 instances shall be sent on BCCH Ext within any occurrence of TC
414 * =2 and TC=6. */
415 if (cfg.si16_present or cfg.si17_present) {
Harald Welte75f761f2017-07-16 03:05:31 +0200416 testcase.stop("Error: Cannot have SI16/SI17 and SI22!");
Harald Welteaf549412017-07-15 21:33:21 +0200417 }
418 if (f_si_vec_contains(si_per_tc, SYSTEM_INFORMATION_TYPE_16) or
419 f_si_vec_contains(si_per_tc, SYSTEM_INFORMATION_TYPE_17)) {
420 setverdict(fail, "Cannot have SI16/SI17 and SI22!");
Daniel Willmannafce8662018-07-06 23:11:32 +0200421 mtc.stop;
Harald Welteaf549412017-07-15 21:33:21 +0200422 }
423 if (not cfg.bcch_extended) {
Harald Welte75f761f2017-07-16 03:05:31 +0200424 testcase.stop("Error: SI22 requires BCCH Extd!");
Harald Welte39276772017-07-16 01:07:42 +0200425 } else {
426 f_ensure_si_vec_contains_only(si_per_tc, 2, SYSTEM_INFORMATION_TYPE_22, true);
427 f_ensure_si_vec_contains_only(si_per_tc, 6, SYSTEM_INFORMATION_TYPE_22, true);
Harald Welteaf549412017-07-15 21:33:21 +0200428 }
429 }
430 }
431
432
Harald Welte39276772017-07-16 01:07:42 +0200433 function f_gsmtap_sample_si(GSMTAP_PT pt, float duration := 8.0) return SystemInformationVectorPerTc {
Harald Welteaf549412017-07-15 21:33:21 +0200434 timer T := duration;
435 var SystemInformationVectorPerTc si_per_tc;
436 var GSMTAP_RecvFrom rf;
437
438 /* initialize all per-TC vectors empty */
439 for (var integer i := 0; i < sizeof(si_per_tc); i := i + 1) {
440 si_per_tc[i] := {};
441 }
442
Harald Weltebdc5dbd2017-07-16 00:00:43 +0200443 /* flush all previous/buffered elements */
444 pt.clear
445
Harald Welteaf549412017-07-15 21:33:21 +0200446 T.start;
447 alt {
448 [] pt.receive(t_recvfrom(GSMTAP_CHANNEL_BCCH)) -> value rf {
449 var SystemInformation si := dec_SystemInformation(rf.msg.payload);
450 var SystemInformationGsmtap sig := { rf.msg.header, si };
451 var integer tc := f_gsm_compute_tc(rf.msg.header.frame_number);
452 log("SI received at TC=", tc, ": ", si);
453 /* append to the per-TC bucket */
454 si_per_tc[tc] := si_per_tc[tc] & { sig };
455 repeat;
456 }
457 [] pt.receive { repeat; };
458 [] T.timeout { };
459 }
Harald Welte39276772017-07-16 01:07:42 +0200460 for (var integer i := 0; i < sizeof(si_per_tc); i := i + 1) {
461 log(testcasename(), ": TC=", i, " has #of SI=", sizeof(si_per_tc[i]));
462 }
Harald Welteaf549412017-07-15 21:33:21 +0200463 return si_per_tc;
464 }
465
Harald Weltef0a49972017-07-16 03:55:20 +0200466 function f_gsmtap_get_si(GSMTAP_PT pt, RrMessageType msg_type) return SystemInformation {
467 timer T := 10.0;
468 var GSMTAP_RecvFrom rf;
469 var SystemInformation si;
470
471 /* flush all previous/buffered elements */
472 pt.clear
473
474 T.start;
475 alt {
476 [] pt.receive(t_recvfrom(GSMTAP_CHANNEL_BCCH)) -> value rf {
477 si := dec_SystemInformation(rf.msg.payload);
478 if (si.header.message_type == msg_type) {
479 return si;
480 }
481 repeat;
482 }
483 [] pt.receive { repeat; };
484 [] T.timeout { testcase.stop("Error waiting for SI on GSMTAP"); };
485 }
486 return si;
487 }
488
489 function f_gsmtap_match_si(GSMTAP_PT pt, RrMessageType msg_type, template SystemInformation t) {
490 var SystemInformation si := f_gsmtap_get_si(pt, msg_type);
491 if (not match(si, t)) {
492 setverdict(fail, "SI ", si, " doesn't match ", t);
Daniel Willmannafce8662018-07-06 23:11:32 +0200493 mtc.stop;
Harald Weltef0a49972017-07-16 03:55:20 +0200494 } else {
495 setverdict(pass);
496 }
497 }
498
Harald Weltebdc5dbd2017-07-16 00:00:43 +0200499 function f_init() runs on dummy_CT {
500 if (initialized) {
501 return;
502 }
503 /* GSMTAP initialization */
Harald Welteb622a3d2017-07-14 22:26:33 +0200504 map(self:GSMTAP, system:GSMTAP);
505 IPL4_GSMTAP_CtrlFunct.f_IPL4_listen(GSMTAP, "0.0.0.0", GSMTAP_PORT, {udp := {}});
506
Harald Weltebdc5dbd2017-07-16 00:00:43 +0200507 /* VTY initialization */
508 map(self:BSCVTY, system:BSCVTY);
509 f_vty_set_prompts(BSCVTY)
Harald Weltefd512cb2017-07-16 01:34:15 +0200510 f_vty_transceive(BSCVTY, "enable");
Harald Weltebdc5dbd2017-07-16 00:00:43 +0200511
512 initialized := true;
513 }
514
515 testcase TC_si_default() runs on dummy_CT {
516 var SystemInformationVectorPerTc si_per_tc;
517
518 f_init();
519
Harald Welteaf549412017-07-15 21:33:21 +0200520 si_per_tc := f_gsmtap_sample_si(GSMTAP);
Harald Welteaf549412017-07-15 21:33:21 +0200521 f_validate_si_scheduling(si_cfg, si_per_tc);
Harald Weltebdc5dbd2017-07-16 00:00:43 +0200522
Harald Welteaf549412017-07-15 21:33:21 +0200523 setverdict(pass);
Harald Welteb622a3d2017-07-14 22:26:33 +0200524 }
525
Harald Weltebdc5dbd2017-07-16 00:00:43 +0200526 testcase TC_si_sched_2bis() runs on dummy_CT {
527 var SystemInformationVectorPerTc si_per_tc;
528 f_init();
529
530 /* Enable SI2bis + validate scheduling */
Harald Weltebdc5dbd2017-07-16 00:00:43 +0200531 si_cfg.si2bis_present := true;
Harald Weltefe1052d2017-07-16 01:24:01 +0200532 f_si_cfg_to_vty();
Harald Weltebdc5dbd2017-07-16 00:00:43 +0200533 si_per_tc := f_gsmtap_sample_si(GSMTAP);
534 f_validate_si_scheduling(si_cfg, si_per_tc);
535
536 /* cleanup */
Harald Weltebdc5dbd2017-07-16 00:00:43 +0200537 si_cfg.si2bis_present := false;
Harald Weltefe1052d2017-07-16 01:24:01 +0200538 f_si_cfg_to_vty();
Harald Weltebdc5dbd2017-07-16 00:00:43 +0200539
540 setverdict(pass);
541 }
542
543 testcase TC_si_sched_2ter() runs on dummy_CT {
544 var SystemInformationVectorPerTc si_per_tc;
545 f_init();
546
547 /* Enable SI2ter + validate scheduling */
Harald Weltebdc5dbd2017-07-16 00:00:43 +0200548 si_cfg.si2ter_present := true;
Harald Weltefe1052d2017-07-16 01:24:01 +0200549 f_si_cfg_to_vty();
Harald Weltebdc5dbd2017-07-16 00:00:43 +0200550 si_per_tc := f_gsmtap_sample_si(GSMTAP);
551 f_validate_si_scheduling(si_cfg, si_per_tc);
552
553 /* cleanup */
Harald Weltebdc5dbd2017-07-16 00:00:43 +0200554 si_cfg.si2ter_present := false;
Harald Weltefe1052d2017-07-16 01:24:01 +0200555 f_si_cfg_to_vty();
Harald Weltebdc5dbd2017-07-16 00:00:43 +0200556
557 setverdict(pass);
558 }
559
560 testcase TC_si_sched_2ter_2bis() runs on dummy_CT {
561 var SystemInformationVectorPerTc si_per_tc;
562 f_init();
563
564 /* Enable SI2bis + SI2ter + validate scheduling */
Harald Weltebdc5dbd2017-07-16 00:00:43 +0200565 si_cfg.si2bis_present := true;
566 si_cfg.si2ter_present := true;
Harald Weltefe1052d2017-07-16 01:24:01 +0200567 f_si_cfg_to_vty();
Harald Weltebdc5dbd2017-07-16 00:00:43 +0200568 si_per_tc := f_gsmtap_sample_si(GSMTAP);
569 f_validate_si_scheduling(si_cfg, si_per_tc);
570
571 /* cleanup */
Harald Weltebdc5dbd2017-07-16 00:00:43 +0200572 si_cfg.si2bis_present := false;
573 si_cfg.si2ter_present := false;
Harald Weltefe1052d2017-07-16 01:24:01 +0200574 f_si_cfg_to_vty();
Harald Weltebdc5dbd2017-07-16 00:00:43 +0200575
576 setverdict(pass);
577 }
578
579 testcase TC_si_sched_2quater() runs on dummy_CT {
580 var SystemInformationVectorPerTc si_per_tc;
581 f_init();
582
583 /* Enable SI2quater + validate scheduling */
Harald Weltebdc5dbd2017-07-16 00:00:43 +0200584 si_cfg.si2quater_present := true;
Harald Weltefe1052d2017-07-16 01:24:01 +0200585 f_si_cfg_to_vty();
Harald Weltebdc5dbd2017-07-16 00:00:43 +0200586
587 /* cleanup */
Harald Weltebdc5dbd2017-07-16 00:00:43 +0200588 si_cfg.si2quater_present := false;
Harald Weltefe1052d2017-07-16 01:24:01 +0200589 f_si_cfg_to_vty();
Harald Weltebdc5dbd2017-07-16 00:00:43 +0200590
591 setverdict(pass);
592 }
593
594 testcase TC_si_sched_13() runs on dummy_CT {
595 var SystemInformationVectorPerTc si_per_tc;
596 f_init();
597
598 /* Enable SI2ter + validate scheduling */
Harald Weltebdc5dbd2017-07-16 00:00:43 +0200599 si_cfg.si13_present := true;
Harald Weltefe1052d2017-07-16 01:24:01 +0200600 f_si_cfg_to_vty();
Harald Weltebdc5dbd2017-07-16 00:00:43 +0200601 si_per_tc := f_gsmtap_sample_si(GSMTAP);
602 f_validate_si_scheduling(si_cfg, si_per_tc);
603
604 /* cleanup */
Harald Weltebdc5dbd2017-07-16 00:00:43 +0200605 si_cfg.si13_present := false;
Harald Weltefe1052d2017-07-16 01:24:01 +0200606 f_si_cfg_to_vty();
Harald Weltebdc5dbd2017-07-16 00:00:43 +0200607
608 setverdict(pass);
609 }
Harald Welte9a907b32017-07-15 10:34:27 +0200610
Harald Weltefe1052d2017-07-16 01:24:01 +0200611 testcase TC_si_sched_13_2bis_2ter_2quater() runs on dummy_CT {
612 var SystemInformationVectorPerTc si_per_tc;
613 f_init();
614
615 si_cfg.si2bis_present := true;
616 si_cfg.si2ter_present := true;
617 si_cfg.si2quater_present := true;
618 si_cfg.si13_present := true;
619 f_si_cfg_to_vty();
620 si_per_tc := f_gsmtap_sample_si(GSMTAP);
621 f_validate_si_scheduling(si_cfg, si_per_tc);
622
623 /* cleanup */
624 si_cfg.si2bis_present := false;
625 si_cfg.si2ter_present := false;
626 si_cfg.si2quater_present := false;
627 si_cfg.si13_present := false;
628 f_si_cfg_to_vty();
629
630 setverdict(pass);
631 }
632
633 function f_si_cfg_to_vty() runs on dummy_CT {
634 if (si_cfg.si2bis_present) {
635 f_vty_si_static(BSCVTY, 0, "2bis", c_si2bis);
636 } else {
637 f_vty_si_computed(BSCVTY, 0, "2bis");
638 }
639 if (si_cfg.si2ter_present) {
640 f_vty_si_static(BSCVTY, 0, "2ter", c_si2ter);
641 } else {
642 f_vty_si_computed(BSCVTY, 0, "2ter");
643 }
644 if (si_cfg.si13_present) {
645 f_vty_gprs_mode(BSCVTY, 0, "gprs");
646 } else {
647 f_vty_gprs_mode(BSCVTY, 0, "none");
648 }
649 if (si_cfg.si2quater_present) {
650 f_vty_si2q_add_uarfcn(BSCVTY, 0, 23, 42);
651 } else {
652 f_vty_si2q_del_uarfcn(BSCVTY, 0, 23, 42);
653 }
654 /* for debugging */
655 f_vty_transceive(BSCVTY, "write terminal");
656 /* actually commit the changes from BSC -> BTS */
657 f_vty_si_resend(BSCVTY, 0);
658 }
Harald Welte9a907b32017-07-15 10:34:27 +0200659
Harald Weltebdc5dbd2017-07-16 00:00:43 +0200660 function f_vty_si_static(TELNETasp_PT pt, BtsNr bts, charstring si, octetstring bytes) {
661 f_vty_enter_cfg_bts(pt, bts);
662 f_vty_transceive(pt, "system-information " & si & " mode static");
663 f_vty_transceive(pt, "system-information " & si & " static " & hex2str(oct2hex(bytes)));
664 f_vty_transceive(pt, "end");
665 }
666
667 function f_vty_si_computed(TELNETasp_PT pt, BtsNr bts, charstring si) {
668 f_vty_enter_cfg_bts(pt, bts);
669 f_vty_transceive(pt, "system-information " & si & " mode computed");
670 f_vty_transceive(pt, "end");
671 }
672
673 function f_vty_si_resend(TELNETasp_PT pt, BtsNr bts := 0) {
674 f_vty_transceive(pt, "bts " & int2str(bts) & " resend-system-information");
Harald Weltec17c88e2017-07-16 00:39:59 +0200675 /* wait for 1s until changes propagate */
676 timer T := 1.0;
Harald Weltebdc5dbd2017-07-16 00:00:43 +0200677 T.start;
678 T.timeout;
679 }
680
681 function f_vty_gprs_mode(TELNETasp_PT pt, integer bts, BtsGprsMode mode) {
682 f_vty_enter_cfg_bts(pt, bts);
683 f_vty_transceive(pt, "gprs mode " & mode);
684 f_vty_transceive(pt, "end");
685 }
686
687 function f_vty_si2q_add_uarfcn(TELNETasp_PT pt, BtsNr bts, UmtsArfcn uarfcn, UmtsScramblingCode sc, integer diversity := 0) {
688 f_vty_enter_cfg_bts(pt, bts);
689 f_vty_transceive(pt, "si2quater neighbor-list add uarfcn " & int2str(uarfcn) & " " & int2str(sc) & " " & int2str(diversity));
690 f_vty_transceive(pt, "end");
691 }
692
693 function f_vty_si2q_del_uarfcn(TELNETasp_PT pt, BtsNr bts, UmtsArfcn uarfcn, UmtsScramblingCode sc) {
694 f_vty_enter_cfg_bts(pt, bts);
695 f_vty_transceive(pt, "si2quater neighbor-list del uarfcn " & int2str(uarfcn) & " " & int2str(sc));
696 f_vty_transceive(pt, "end");
697 }
698
699 testcase TC_telnet() runs on dummy_CT {
700 f_init();
Harald Welte9a907b32017-07-15 10:34:27 +0200701 f_vty_transceive(BSCVTY, "show network")
Harald Welte244cd8a2017-08-26 09:25:20 +0200702 f_vty_enter_config(BSCVTY);
Harald Welte9a907b32017-07-15 10:34:27 +0200703 f_vty_transceive(BSCVTY, "network")
704 f_vty_transceive(BSCVTY, "bts 0")
Harald Weltebdc5dbd2017-07-16 00:00:43 +0200705 f_vty_transceive(BSCVTY, "end")
706 setverdict(pass);
Harald Welte9a907b32017-07-15 10:34:27 +0200707 }
708
Harald Weltef0a49972017-07-16 03:55:20 +0200709 template SystemInformation t_SI_SI3 := {
Harald Welted2e342f2017-07-16 07:34:13 +0200710 header := t_RrHeader(SYSTEM_INFORMATION_TYPE_3, ?),
Harald Weltef0a49972017-07-16 03:55:20 +0200711 payload := { si3 := t_SI3 }
712 }
713
714 testcase TC_cellid() runs on dummy_CT {
715 var CellIdentity cid := float2int(rnd() * 65535.0);
716 var template SystemInformation t := t_SI_SI3;
717 t.payload.si3.cell_id := cid;
718
719 f_init();
720 f_vty_enter_cfg_bts(BSCVTY, 0);
721 f_vty_transceive(BSCVTY, "cell_identity " & int2str(cid));
722 f_vty_transceive(BSCVTY, "end")
723 f_vty_si_resend(BSCVTY, 0);
724
725 f_gsmtap_match_si(GSMTAP, SYSTEM_INFORMATION_TYPE_3, t);
726 }
727
728 testcase TC_lac() runs on dummy_CT {
729 var uint16_t lac := float2int(rnd() * 65535.0);
730
731 var template SystemInformation t := t_SI_SI3;
732 t.payload.si3.lai.lac := lac;
733
734 f_init();
735 f_vty_enter_cfg_bts(BSCVTY, 0);
736 f_vty_transceive(BSCVTY, "location_area_code " & int2str(lac));
737 f_vty_transceive(BSCVTY, "end")
738 f_vty_si_resend(BSCVTY, 0);
739
740 f_gsmtap_match_si(GSMTAP, SYSTEM_INFORMATION_TYPE_3, t);
741 }
742
743 testcase TC_rach_tx_int() runs on dummy_CT {
744 var uint16_t rach_tx_int := float2int(rnd() * 15.0);
745
746 var template SystemInformation t := t_SI_SI3;
747 t.payload.si3.rach_control.tx_integer := int2bit(rach_tx_int, 4);
748
749 f_init();
750 f_vty_enter_cfg_bts(BSCVTY, 0);
751 f_vty_transceive(BSCVTY, "rach tx integer " & int2str(rach_tx_int));
752 f_vty_transceive(BSCVTY, "end")
753 f_vty_si_resend(BSCVTY, 0);
754
755 f_gsmtap_match_si(GSMTAP, SYSTEM_INFORMATION_TYPE_3, t);
756 }
757
758 testcase TC_rach_max_tx() runs on dummy_CT {
759 var uint16_t r := float2int(rnd() * 3.0);
760 const integer max_tx_map[4] := { 1, 2, 4, 7 };
Harald Welte82ccef72018-02-25 16:17:33 +0100761 const RachCtrlPar_MR max_tx_map2[4] := { RACH_MAX_RETRANS_1,
762 RACH_MAX_RETRANS_2,
763 RACH_MAX_RETRANS_4,
764 RACH_MAX_RETRANS_7 };
Harald Weltef0a49972017-07-16 03:55:20 +0200765 var template SystemInformation t := t_SI_SI3;
Harald Welte82ccef72018-02-25 16:17:33 +0100766 t.payload.si3.rach_control.max_retrans := max_tx_map2[r];
Harald Weltef0a49972017-07-16 03:55:20 +0200767
768 f_init();
769 f_vty_enter_cfg_bts(BSCVTY, 0);
770 f_vty_transceive(BSCVTY, "rach max transmission " & int2str(max_tx_map[r]));
771 f_vty_transceive(BSCVTY, "end")
772 f_vty_si_resend(BSCVTY, 0);
773
774 f_gsmtap_match_si(GSMTAP, SYSTEM_INFORMATION_TYPE_3, t);
775 }
776
777 testcase TC_dtx_ul() runs on dummy_CT {
Harald Welte82ccef72018-02-25 16:17:33 +0100778 var integer i := float2int(rnd() * 3.0);
Harald Weltef0a49972017-07-16 03:55:20 +0200779 var template SystemInformation t := t_SI_SI3;
Harald Welte82ccef72018-02-25 16:17:33 +0100780 var CellOptions_DTX dtx_map[3] := { MS_MAY_USE_UL_DTX,
781 MS_SHALL_USE_UL_DTX,
782 MS_SHALL_NOT_USE_UL_DTX };
783 t.payload.si3.cell_options.dtx := dtx_map[i];
Harald Weltef0a49972017-07-16 03:55:20 +0200784
785 f_init();
786 f_vty_enter_cfg_bts(BSCVTY, 0);
787 if (i == 0) {
788 f_vty_transceive(BSCVTY, "dtx uplink");
789 } else if (i == 1) {
790 f_vty_transceive(BSCVTY, "dtx uplink force");
791 } else {
792 f_vty_transceive(BSCVTY, "no dtx uplink");
793 }
794
795 f_gsmtap_match_si(GSMTAP, SYSTEM_INFORMATION_TYPE_3, t);
796 }
797
798 testcase TC_attach() runs on dummy_CT {
799 var integer i := float2int(rnd());
800 var template SystemInformation t := t_SI_SI3;
801 t.payload.si3.ctrl_chan_desc.att := int2bool(i);
802
803 f_init();
804 f_vty_enter_cfg_bts(BSCVTY, 0);
805 f_vty_transceive(BSCVTY, "channel-descrption attach " & int2str(i));
806 f_vty_transceive(BSCVTY, "end")
807 f_vty_si_resend(BSCVTY, 0);
808
809 f_gsmtap_match_si(GSMTAP, SYSTEM_INFORMATION_TYPE_3, t);
810 }
811
812 testcase TC_bs_pa_mfrms() runs on dummy_CT {
813 var integer i := 2 + float2int(rnd() * 7.0);
814 var template SystemInformation t := t_SI_SI3;
815 t.payload.si3.ctrl_chan_desc.bs_pa_mfrms := i - 2;
816
817 f_init();
818 f_vty_enter_cfg_bts(BSCVTY, 0);
819 f_vty_transceive(BSCVTY, "channel-descrption bs-pa-mfrms " & int2str(i));
820 f_vty_transceive(BSCVTY, "end")
821 f_vty_si_resend(BSCVTY, 0);
822
823 f_gsmtap_match_si(GSMTAP, SYSTEM_INFORMATION_TYPE_3, t);
824 }
825
826 testcase TC_bs_ag_blks_res() runs on dummy_CT {
827 var integer i := float2int(rnd() * 7.0);
828 var template SystemInformation t := t_SI_SI3;
829 t.payload.si3.ctrl_chan_desc.bs_ag_blks_res := i;
830
831 f_init();
832 f_vty_enter_cfg_bts(BSCVTY, 0);
833 f_vty_transceive(BSCVTY, "channel-descrption bs-ag-blks-res " & int2str(i));
834 f_vty_transceive(BSCVTY, "end")
835 f_vty_si_resend(BSCVTY, 0);
836
837 f_gsmtap_match_si(GSMTAP, SYSTEM_INFORMATION_TYPE_3, t);
838 }
839
840 testcase TC_radio_link_timeout() runs on dummy_CT {
841 var integer i := float2int(rnd() * 15.0);
842 var template SystemInformation t := t_SI_SI3;
Harald Welte82ccef72018-02-25 16:17:33 +0100843 t.payload.si3.cell_options.radio_link_tout_div4 := i;
Harald Weltef0a49972017-07-16 03:55:20 +0200844
845 f_init();
846 f_vty_enter_cfg_bts(BSCVTY, 0);
847 f_vty_transceive(BSCVTY, "radio-link-timeout " & int2str(4 + i*4));
848 f_vty_transceive(BSCVTY, "end")
849 f_vty_si_resend(BSCVTY, 0);
850
851 f_gsmtap_match_si(GSMTAP, SYSTEM_INFORMATION_TYPE_3, t);
852 }
853
854 testcase TC_cell_resel_hyst() runs on dummy_CT {
855 var integer i := float2int(rnd() * 7.0);
856 var template SystemInformation t := t_SI_SI3;
Harald Welte82ccef72018-02-25 16:17:33 +0100857 t.payload.si3.cell_sel_par.cell_resel_hyst_2dB := i;
Harald Weltef0a49972017-07-16 03:55:20 +0200858
859 f_init();
860 f_vty_enter_cfg_bts(BSCVTY, 0);
861 f_vty_transceive(BSCVTY, "cell reselection hysteresis " & int2str(i*2));
862 f_vty_transceive(BSCVTY, "end")
863 f_vty_si_resend(BSCVTY, 0);
864
865 f_gsmtap_match_si(GSMTAP, SYSTEM_INFORMATION_TYPE_3, t);
866 }
867
868 testcase TC_rxlev_acc_min() runs on dummy_CT {
869 var integer i := float2int(rnd() * 63.0);
870 var template SystemInformation t := t_SI_SI3;
871 t.payload.si3.cell_sel_par.rxlev_access_min := i;
872
873 f_init();
874 f_vty_enter_cfg_bts(BSCVTY, 0);
875 f_vty_transceive(BSCVTY, "rxlev access min " & int2str(i));
876 f_vty_transceive(BSCVTY, "end")
877 f_vty_si_resend(BSCVTY, 0);
878
879 f_gsmtap_match_si(GSMTAP, SYSTEM_INFORMATION_TYPE_3, t);
880 }
881
882 testcase TC_neci() runs on dummy_CT {
883 var integer i := float2int(rnd() * 1.0);
884 var template SystemInformation t := t_SI_SI3;
885 t.payload.si3.cell_sel_par.neci := int2bool(i);
886
887 f_init();
888 f_vty_enter_cfg_network(BSCVTY);
889 f_vty_transceive(BSCVTY, "neci " & int2str(i));
890 f_vty_transceive(BSCVTY, "end")
891 f_vty_si_resend(BSCVTY, 0);
892
893 f_gsmtap_match_si(GSMTAP, SYSTEM_INFORMATION_TYPE_3, t);
894 }
895
896 testcase TC_emerg_allowed() runs on dummy_CT {
897 var integer i := float2int(rnd());
898 var template SystemInformation t := t_SI_SI3;
899 if (i == 1) {
Harald Welte82ccef72018-02-25 16:17:33 +0100900 t.payload.si3.rach_control.acc := '?????0??????????'B;
Harald Weltef0a49972017-07-16 03:55:20 +0200901 } else {
Harald Welte82ccef72018-02-25 16:17:33 +0100902 t.payload.si3.rach_control.acc := '?????1??????????'B;
Harald Weltef0a49972017-07-16 03:55:20 +0200903 }
904
905 f_init();
906 f_vty_enter_cfg_bts(BSCVTY, 0);
907 f_vty_transceive(BSCVTY, "rach emergency call allowed " & int2str(i));
908 f_vty_transceive(BSCVTY, "end")
909 f_vty_si_resend(BSCVTY, 0);
910
911 f_gsmtap_match_si(GSMTAP, SYSTEM_INFORMATION_TYPE_3, t);
912 }
913
914 /* TODO:
915 * * don't only validate SI3 but check all other SI with same IE?
916 * * parse + validate rest octets somehow
917 * * validate contents/encoding of neighbor channel lists
918 * * validate si2quater sub-mux scheduling
919 */
920
921
Harald Welte56db5fd2017-07-14 18:25:59 +0200922 control {
923 execute(TC_si1());
Harald Welte9a907b32017-07-15 10:34:27 +0200924 execute(TC_telnet());
Harald Weltebdc5dbd2017-07-16 00:00:43 +0200925 execute(TC_si_default());
926 execute(TC_si_sched_2bis());
927 execute(TC_si_sched_2ter());
928 execute(TC_si_sched_2ter_2bis());
929 execute(TC_si_sched_2quater());
930 execute(TC_si_sched_13());
Harald Weltefe1052d2017-07-16 01:24:01 +0200931 execute(TC_si_sched_13_2bis_2ter_2quater());
Harald Weltef0a49972017-07-16 03:55:20 +0200932 execute(TC_neci());
933 execute(TC_cell_resel_hyst());
934 execute(TC_rxlev_acc_min());
935 execute(TC_cellid());
936 execute(TC_lac());
937 execute(TC_rach_tx_int());
938 execute(TC_rach_max_tx());
939 execute(TC_attach());
940 execute(TC_dtx_ul());
941 execute(TC_emerg_allowed());
942 execute(TC_bs_pa_mfrms());
943 execute(TC_bs_ag_blks_res());
944 execute(TC_radio_link_timeout());
Harald Welte56db5fd2017-07-14 18:25:59 +0200945 }
946}