blob: b9bb62d65ed2817c92630472f220adf73ff00929 [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 Welteb622a3d2017-07-14 22:26:33 +02005 import from GSMTAP_Types all;
6 import from GSMTAP_PortType all;
7 import from IPL4_GSMTAP_CtrlFunct all;
Harald Welte9a907b32017-07-15 10:34:27 +02008 import from TELNETasp_PortType all;
Harald Welte56db5fd2017-07-14 18:25:59 +02009
10 const octetstring si1 := '5506198fb38000000000000000000000000000e504002b'O;
11 const octetstring si2 := '59061a00000000000000000000000000000000ffe50400'O;
12 const octetstring si3 := '49061b000062f22404d2490301275d40e50400392b2b2b'O;
13 const octetstring si4 := '31061c62f22404d25d40e504002b2b2b2b2b2b2b2b2b2b'O;
Harald Weltebdc5dbd2017-07-16 00:00:43 +020014 const octetstring c_si2bis := '550602bfe809b3ff00000000000000000000007900002b'O;
15 const octetstring c_si2ter := '010603bf66b0aa0a00000002000000000000002b2b2b2b'O;
16 const octetstring c_si2quater := '050607a8a0364aa698d72ff424feee0506d5e7fff02043'O;
Harald Welte56db5fd2017-07-14 18:25:59 +020017
18 type component dummy_CT {
Harald Welteb622a3d2017-07-14 22:26:33 +020019 port GSMTAP_PT GSMTAP;
Harald Welte9a907b32017-07-15 10:34:27 +020020 port TELNETasp_PT BSCVTY;
Harald Weltebdc5dbd2017-07-16 00:00:43 +020021 var boolean initialized := false;
22 var SystemInformationConfig si_cfg := {
23 bcch_extended := false,
24 si1_present := true,
25 si2bis_present := false,
26 si2ter_present := false,
27 si2quater_present := false,
28 si7_present := false,
29 si8_present := false,
30 si9_present := false,
31 si13_present := false,
32 si13alt_present := false,
33 si15_present := false,
34 si16_present := false,
35 si17_present := false,
36 si2n_present := false,
37 si21_present := false,
38 si22_present := false
39 };
Harald Welte56db5fd2017-07-14 18:25:59 +020040 };
41
42 testcase TC_si1() runs on dummy_CT {
Harald Welte56db5fd2017-07-14 18:25:59 +020043 log("SI: ", dec_SystemInformation(si1));
44 log("SI: ", dec_SystemInformation(si2));
45 log("SI: ", dec_SystemInformation(si3));
46 log("SI: ", dec_SystemInformation(si4));
Harald Weltebdc5dbd2017-07-16 00:00:43 +020047 setverdict(pass);
Harald Welte56db5fd2017-07-14 18:25:59 +020048 }
49
Harald Welteb622a3d2017-07-14 22:26:33 +020050 template GsmtapHeader t_GsmtapHeader := {
51 version := GSMTAP_VERSION,
52 hdr_len := 4,
53 msg_type := ?,
54 timeslot := ?,
55 arfcn := ?,
56 signal_dbm := ?,
57 snr_db := ?,
58 frame_number := ?,
59 sub_type := ?,
60 antenna_nr := ?,
61 sub_slot := ?,
62 res := ?
63 }
64
65 template GsmtapHeader t_GsmtapHeaderUm(template GsmtapChannel ch) modifies t_GsmtapHeader := {
66 msg_type := GSMTAP_TYPE_UM,
67 sub_type := ch
68 }
69
Harald Welteb622a3d2017-07-14 22:26:33 +020070 template GsmtapMessage t_bcch := {
71 header := t_GsmtapHeaderUm(GSMTAP_CHANNEL_BCCH),
72 payload := ?
73 }
74
75 template GSMTAP_RecvFrom t_recvfrom(template GsmtapChannel ch) := {
76 connId := ?,
77 remName := ?,
78 remPort := ?,
79 locName := ?,
80 locPort := GSMTAP_PORT,
81 proto := {udp:={}},
82 userData := ?,
83 msg := { header := t_GsmtapHeaderUm(ch), payload := ?}
84 }
85
Harald Welteaf549412017-07-15 21:33:21 +020086 /* tuple of gsmtap header + decoded SI */
87 type record SystemInformationGsmtap {
88 GsmtapHeader gsmtap,
89 SystemInformation si
90 }
91
92 /* an arbitrary-length vector of decoded SI + gsmtap header */
93 type record of SystemInformationGsmtap SystemInformationVector;
94
95 /* an array of SI-vectors indexed by TC value */
96 type SystemInformationVector SystemInformationVectorPerTc[8];
97
98 type record of integer IntegerRecord;
99
Harald Weltef0a49972017-07-16 03:55:20 +0200100 function int2bool(integer int) return boolean {
101 if (int != 0) {
102 return true;
103 } else {
104 return false;
105 }
106 }
107
Harald Welteaf549412017-07-15 21:33:21 +0200108 function f_array_contains(IntegerRecord arr, integer key) return boolean {
109 for (var integer i:= 0; i< sizeof(arr); i := i + 1) {
110 if (arr[i] == key) {
111 return true;
112 }
113 }
114 return false;
115 }
116
117
118 /* compute TC as per 45.002 6.3.1.3 */
119 function f_gsm_compute_tc(integer fn) return integer {
120 return (fn / 51) mod 8;
121 }
122
123 /* determine if a given SI vector contains given SI type at least once */
124 function f_si_vecslot_contains(SystemInformationVector arr, RrMessageType key, boolean bcch_ext := false) return boolean {
125 for (var integer i:= 0; i< sizeof(arr); i := i + 1) {
126 var integer fn_mod51 := arr[i].gsmtap.frame_number mod 51;
127 if (not bcch_ext and fn_mod51 == 2 or
128 bcch_ext and fn_mod51 == 6) {
129 if (arr[i].si.header.message_type == key) {
130 return true;
131 }
132 }
133 }
134 return false;
135 }
136
Harald Welte39276772017-07-16 01:07:42 +0200137 /* ensure a given TC slot of the SI vector contains given SI type at least once at TC */
138 function f_ensure_si_vec_contains(SystemInformationVectorPerTc arr, integer tc, RrMessageType key, boolean ext_bcch := false) {
139 if (not f_si_vecslot_contains(arr[tc], key, ext_bcch)) {
140 log("Fail: No ", key, " in TC=", tc, "!");
141 setverdict(fail);
142 }
143 }
144
Harald Welteaf549412017-07-15 21:33:21 +0200145 /* check if a given SI vector contains given SI type at least once on any TC */
146 function f_si_vec_contains(SystemInformationVectorPerTc arr, RrMessageType key) return boolean {
147 for (var integer tc:= 0; tc < sizeof(arr); tc := tc + 1) {
148 if (f_si_vecslot_contains(arr[tc], key) or
149 f_si_vecslot_contains(arr[tc], key, true)) {
150 return true;
151 }
152 }
153 return false;
154 }
155
Harald Welte39276772017-07-16 01:07:42 +0200156 /* determine if a given SI vector contains given SI type at least N of M times */
157 function f_si_vecslot_contains_n_of_m(SystemInformationVector arr, RrMessageType key, boolean bcch_ext := false, integer n := 1, integer m := 4) return boolean {
158 var integer count := 0;
159 if (sizeof(arr) < m) {
Harald Welte75f761f2017-07-16 03:05:31 +0200160 testcase.stop("Error: Insufficient SI in array");
Harald Welte39276772017-07-16 01:07:42 +0200161 }
162 for (var integer i:= 0; i < m; i := i + 1) {
163 var integer fn_mod51 := arr[i].gsmtap.frame_number mod 51;
164 if (not bcch_ext and fn_mod51 == 2 or
165 bcch_ext and fn_mod51 == 6) {
166 if (arr[i].si.header.message_type == key) {
167 count := count + 1;
168 }
169 }
170 }
171 if (count >= n) {
172 return true;
173 } else {
174 return false;
175 }
176 }
177
178 /* ensure a given TC slot of the SI vector contains given SI type at least N out of M times at TC */
179 function f_ensure_si_vec_contains_n_of_m(SystemInformationVectorPerTc arr, integer tc, RrMessageType key, boolean ext_bcch := false, integer n, integer m) {
180 if (not f_si_vecslot_contains_n_of_m(arr[tc], key, ext_bcch, n, m)) {
181 log("Fail: Not ", n, "/", m, " of ", key, " in TC=", tc, "!");
182 setverdict(fail);
183 }
184 }
185
186 /* determine if a given SI vector contains given SI type at least once */
187 function f_si_vecslot_contains_only(SystemInformationVector arr, RrMessageType key, boolean bcch_ext := false) return boolean {
188 for (var integer i:= 0; i< sizeof(arr); i := i + 1) {
189 var integer fn_mod51 := arr[i].gsmtap.frame_number mod 51;
190 if (not bcch_ext and fn_mod51 == 2 or
191 bcch_ext and fn_mod51 == 6) {
192 if (arr[i].si.header.message_type != key) {
193 return false;
194 }
195 }
196 }
197 return true;
198 }
199
200 /* ensure a given TC slot of the SI vector contains only given SI type */
201 function f_ensure_si_vec_contains_only(SystemInformationVectorPerTc arr, integer tc, RrMessageType key, boolean ext_bcch := false) {
202 if (not f_si_vecslot_contains_only(arr[tc], key, ext_bcch)) {
203 log("Fail: Not all ", key, " in TC=", tc, "!");
Harald Welteaf549412017-07-15 21:33:21 +0200204 setverdict(fail);
205 }
206 }
207
208 /* SI configuration of cell, against which we validate actual SI messages */
209 type set SystemInformationConfig {
210 boolean bcch_extended,
211 boolean si1_present,
212 boolean si2bis_present,
213 boolean si2ter_present,
214 boolean si2quater_present,
215 boolean si7_present,
216 boolean si8_present,
217 boolean si9_present,
218 boolean si13_present,
219 boolean si13alt_present,
220 boolean si15_present,
221 boolean si16_present,
222 boolean si17_present,
223 boolean si2n_present,
224 boolean si21_present,
225 boolean si22_present
226 }
227
228 /* validate the SI scheduling according to TS 45.002 version 14.1.0 Release 14, Section 6.3.1.3 */
229 function f_validate_si_scheduling(SystemInformationConfig cfg, SystemInformationVectorPerTc si_per_tc) {
230 var integer i;
231 for (i := 0; i < sizeof(si_per_tc); i := i + 1) {
232 if (sizeof(si_per_tc[i]) == 0) {
233 setverdict(fail, "No SI messages for TC=0!");
234 }
235 }
236 if (cfg.si1_present) {
237 /* ii) System Information Type 1 needs to be sent if frequency hopping is in use or
238 * when the NCH is present in a cell. If the MS finds another message on BCCH Norm
239 * when TC = 0, it can assume that System Information Type 1 is not in use. */
240 f_ensure_si_vec_contains(si_per_tc, 0, SYSTEM_INFORMATION_TYPE_1);
Harald Welte39276772017-07-16 01:07:42 +0200241 /* make sure *ALL* contain SI1 */
242 f_ensure_si_vec_contains_only(si_per_tc, 0, SYSTEM_INFORMATION_TYPE_1);
Harald Welteaf549412017-07-15 21:33:21 +0200243 }
244 f_ensure_si_vec_contains(si_per_tc, 1, SYSTEM_INFORMATION_TYPE_2);
245 /* iii) A SI 2 message will be sent at least every time TC = 1 */
246 f_ensure_si_vec_contains(si_per_tc, 2, SYSTEM_INFORMATION_TYPE_3);
247 f_ensure_si_vec_contains(si_per_tc, 6, SYSTEM_INFORMATION_TYPE_3);
248 f_ensure_si_vec_contains(si_per_tc, 3, SYSTEM_INFORMATION_TYPE_4);
249 f_ensure_si_vec_contains(si_per_tc, 7, SYSTEM_INFORMATION_TYPE_4);
250
251 /* iii) System information type 2 bis or 2 ter messages are sent if needed, as determined by the
252 * system operator. If only one of them is needed, it is sent when TC = 5. If both are
253 * needed, 2bis is sent when TC = 5 and 2ter is sent at least once within any of 4
254 * consecutive occurrences of TC = 4. */
255 if (cfg.si2bis_present and not cfg.si2ter_present) {
256 f_ensure_si_vec_contains(si_per_tc, 5, SYSTEM_INFORMATION_TYPE_2bis);
257 } else if (cfg.si2ter_present and not cfg.si2bis_present) {
258 f_ensure_si_vec_contains(si_per_tc, 5, SYSTEM_INFORMATION_TYPE_2ter);
259 } else if (cfg.si2ter_present and cfg.si2bis_present) {
260 f_ensure_si_vec_contains(si_per_tc, 5, SYSTEM_INFORMATION_TYPE_2bis);
Harald Welte39276772017-07-16 01:07:42 +0200261 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 +0200262 }
263
264 if (cfg.si7_present or cfg.si8_present) {
265 /* vi) Use of System Information type 7 and 8 is not always necessary. It is necessary
266 * if System Information type 4 does not contain all information needed for cell
267 * selection and reselection. */
268 if (not cfg.bcch_extended) {
Harald Welte75f761f2017-07-16 03:05:31 +0200269 testcase.stop("Error: SI7/SI8 require BCCH Extd.");
Harald Welteaf549412017-07-15 21:33:21 +0200270 }
271 if (cfg.si7_present) {
272 f_ensure_si_vec_contains(si_per_tc, 7, SYSTEM_INFORMATION_TYPE_7, true);
273 }
274 if (cfg.si8_present) {
275 f_ensure_si_vec_contains(si_per_tc, 3, SYSTEM_INFORMATION_TYPE_8, true);
276 }
277 }
278
279 if (cfg.si2quater_present) {
280 /* iii) System information type 2 quater is sent if needed, as determined by the system
281 * operator. If sent on BCCH Norm, it shall be sent when TC = 5 if neither of 2bis
282 * and 2ter are used, otherwise it shall be sent at least once within any of 4
283 * consecutive occurrences of TC = 4. If sent on BCCH Ext, it is sent at least once
284 * within any of 4 consecutive occurrences of TC = 5. */
285 if (not (cfg.bcch_extended)) {
286 if (not (cfg.si2bis_present or cfg.si2ter_present)) {
287 f_ensure_si_vec_contains(si_per_tc, 5, SYSTEM_INFORMATION_TYPE_2quater);
288 } else {
Harald Welte39276772017-07-16 01:07:42 +0200289 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 +0200290 }
291 } else {
Harald Welte39276772017-07-16 01:07:42 +0200292 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 +0200293 }
294 }
295 if (cfg.si9_present) {
296 /* vi) System Information type 9 is sent in those blocks with TC = 4 which are specified
297 * in system information type 3 as defined in 3GPP TS 44.018. */
298 f_ensure_si_vec_contains(si_per_tc, 4, SYSTEM_INFORMATION_TYPE_9); // FIXME SI3
299 }
300 if (cfg.si13_present) {
301 /* vii) System Information type 13 is only related to the GPRS service. System Information
302 * Type 13 need only be sent if GPRS support is indicated in one or more of System
303 * Information Type 3 or 4 or 7 or 8 messages. These messages also indicate if the
304 * message is sent on the BCCH Norm or if the message is transmitted on the BCCH Ext.
305 * In the case that the message is sent on the BCCH Norm, it is sent at least once
306 * within any of 4 consecutive occurrences of TC=4. */
307 if (not cfg.bcch_extended) {
Harald Welte39276772017-07-16 01:07:42 +0200308 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 +0200309 } else {
310 f_ensure_si_vec_contains(si_per_tc, 0, SYSTEM_INFORMATION_TYPE_13, true);
311 }
312 if (f_si_vec_contains(si_per_tc, SYSTEM_INFORMATION_TYPE_13alt)) {
313 setverdict(fail, "Cannot have SI13alt and SI13");
314 }
315 }
316 if (cfg.si16_present or cfg.si17_present) {
317 /* viii) System Information type 16 and 17 are only related to the SoLSA service. They
318 * should not be sent in a cell where network sharing is used (see rule xv). */
319 if (cfg.si22_present) {
Harald Welte75f761f2017-07-16 03:05:31 +0200320 testcase.stop("Error: Cannot have SI16/SI17 and SI22!");
Harald Welteaf549412017-07-15 21:33:21 +0200321 }
322 if (f_si_vec_contains(si_per_tc, SYSTEM_INFORMATION_TYPE_22)) {
323 setverdict(fail, "Cannot have SI16/SI17 and SI22!");
324 }
325 if (not cfg.bcch_extended) {
Harald Welte75f761f2017-07-16 03:05:31 +0200326 testcase.stop("Error: SI16/SI17 requires BCCH Extd!");
Harald Welteaf549412017-07-15 21:33:21 +0200327 }
328 if (cfg.si16_present) {
329 f_ensure_si_vec_contains(si_per_tc, 6, SYSTEM_INFORMATION_TYPE_16, true);
330 }
331 if (cfg.si17_present) {
332 f_ensure_si_vec_contains(si_per_tc, 2, SYSTEM_INFORMATION_TYPE_17, true);
333 }
334 }
335
336 /* ix) System Information type 18 and 20 are sent in order to transmit non-GSM
337 * broadcast information. The frequency with which they are sent is determined by the
338 * system operator. System Information type 9 identifies the scheduling of System
339 * Information type 18 and 20 messages. */
340
341 /* x) System Information Type 19 is sent if COMPACT neighbours exist. If System
342 * Information Type 19 is present, then its scheduling shall be indicated in System
343 * Information Type 9. */
344
345 if (cfg.si15_present) {
346 /* xi) System Information Type 15 is broadcast if dynamic ARFCN mapping is used in the
347 * PLMN. If sent on BCCH Norm, it is sent at least once within any of 4 consecutive
348 * occurrences of TC = 4. If sent on BCCH Ext, it is sent at least once within any of
349 * 4 consecutive occurrences of TC = 1. */
350 if (not cfg.bcch_extended) {
Harald Welte39276772017-07-16 01:07:42 +0200351 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 +0200352 } else {
Harald Welte39276772017-07-16 01:07:42 +0200353 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 +0200354 }
355 }
356 if (cfg.si13alt_present) {
357 /* xii) System Information type 13 alt is only related to the GERAN Iu mode. System
358 * Information Type 13 alt need only be sent if GERAN Iu mode support is indicated in
359 * one or more of System Information Type 3 or 4 or 7 or 8 messages and SI 13 is not
360 * broadcast. These messages also indicate if the message is sent on the BCCH Norm or
361 * if the message is transmitted on the BCCH Ext. In the case that the message is sent
362 * on the BCCH Norm, it is sent at least once within any of 4 consecutive occurrences
363 * of TC = 4. */
364 if (cfg.si13_present) {
Harald Welte75f761f2017-07-16 03:05:31 +0200365 testcase.stop("Error: Cannot have SI13alt and SI13");
Harald Welteaf549412017-07-15 21:33:21 +0200366 }
367 if (f_si_vec_contains(si_per_tc, SYSTEM_INFORMATION_TYPE_13)) {
368 setverdict(fail, "Cannot have SI13alt and SI13");
369 }
370 if (not cfg.bcch_extended) {
Harald Welte39276772017-07-16 01:07:42 +0200371 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 +0200372 } else {
373 f_ensure_si_vec_contains(si_per_tc, 0, SYSTEM_INFORMATION_TYPE_13alt, true);
374 }
375 }
376 if (cfg.si2n_present) {
377 /* xiii) System Information Type 2n is optionally sent on BCCH Norm or BCCH Ext if needed,
378 * as determined by the system operator. In the case that the message is sent on the
379 * BCCH Norm, it is sent at least once within any of 4 consecutive occurrences of TC =
380 * 4. If the message is sent on BCCH Ext, it is sent at least once within any of 2
381 * consecutive occurrences of TC = 4. */
382 if (not cfg.bcch_extended) {
Harald Welte39276772017-07-16 01:07:42 +0200383 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 +0200384 } else {
Harald Welte39276772017-07-16 01:07:42 +0200385 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 +0200386 }
387 }
388 if (cfg.si21_present) {
389 /* xiv) System Information Type 21 is optionally sent on BCCH Norm or BCCH Ext, as
390 * determined by the system operator. If Extended Access Barring is in use in the cell
391 * then this message is sent at least once within any of 4 consecutive occurrences of
392 * TC = 4 regardless if it is sent on BCCH Norm or BCCH Ext. If BCCH Ext is used in a
393 * cell then this message shall only be sent on BCCH Ext. */
394 if (not cfg.bcch_extended) {
Harald Welte39276772017-07-16 01:07:42 +0200395 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 +0200396 } else {
Harald Welte39276772017-07-16 01:07:42 +0200397 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 +0200398 if (f_si_vecslot_contains(si_per_tc[4], SYSTEM_INFORMATION_TYPE_21)) {
399 setverdict(fail, "Cannot have SI21 on BCCH Norm if BCCH Extd enabled!");
400 }
401 }
402 }
403 if (cfg.si22_present) {
404 /* xv) System Information Type 22 is sent if network sharing is in use in the cell. It
405 * should not be sent in a cell where SoLSA is used (see rule viii). System
406 * Information Type 22 instances shall be sent on BCCH Ext within any occurrence of TC
407 * =2 and TC=6. */
408 if (cfg.si16_present or cfg.si17_present) {
Harald Welte75f761f2017-07-16 03:05:31 +0200409 testcase.stop("Error: Cannot have SI16/SI17 and SI22!");
Harald Welteaf549412017-07-15 21:33:21 +0200410 }
411 if (f_si_vec_contains(si_per_tc, SYSTEM_INFORMATION_TYPE_16) or
412 f_si_vec_contains(si_per_tc, SYSTEM_INFORMATION_TYPE_17)) {
413 setverdict(fail, "Cannot have SI16/SI17 and SI22!");
414 }
415 if (not cfg.bcch_extended) {
Harald Welte75f761f2017-07-16 03:05:31 +0200416 testcase.stop("Error: SI22 requires BCCH Extd!");
Harald Welte39276772017-07-16 01:07:42 +0200417 } else {
418 f_ensure_si_vec_contains_only(si_per_tc, 2, SYSTEM_INFORMATION_TYPE_22, true);
419 f_ensure_si_vec_contains_only(si_per_tc, 6, SYSTEM_INFORMATION_TYPE_22, true);
Harald Welteaf549412017-07-15 21:33:21 +0200420 }
421 }
422 }
423
424
Harald Welte39276772017-07-16 01:07:42 +0200425 function f_gsmtap_sample_si(GSMTAP_PT pt, float duration := 8.0) return SystemInformationVectorPerTc {
Harald Welteaf549412017-07-15 21:33:21 +0200426 timer T := duration;
427 var SystemInformationVectorPerTc si_per_tc;
428 var GSMTAP_RecvFrom rf;
429
430 /* initialize all per-TC vectors empty */
431 for (var integer i := 0; i < sizeof(si_per_tc); i := i + 1) {
432 si_per_tc[i] := {};
433 }
434
Harald Weltebdc5dbd2017-07-16 00:00:43 +0200435 /* flush all previous/buffered elements */
436 pt.clear
437
Harald Welteaf549412017-07-15 21:33:21 +0200438 T.start;
439 alt {
440 [] pt.receive(t_recvfrom(GSMTAP_CHANNEL_BCCH)) -> value rf {
441 var SystemInformation si := dec_SystemInformation(rf.msg.payload);
442 var SystemInformationGsmtap sig := { rf.msg.header, si };
443 var integer tc := f_gsm_compute_tc(rf.msg.header.frame_number);
444 log("SI received at TC=", tc, ": ", si);
445 /* append to the per-TC bucket */
446 si_per_tc[tc] := si_per_tc[tc] & { sig };
447 repeat;
448 }
449 [] pt.receive { repeat; };
450 [] T.timeout { };
451 }
Harald Welte39276772017-07-16 01:07:42 +0200452 for (var integer i := 0; i < sizeof(si_per_tc); i := i + 1) {
453 log(testcasename(), ": TC=", i, " has #of SI=", sizeof(si_per_tc[i]));
454 }
Harald Welteaf549412017-07-15 21:33:21 +0200455 return si_per_tc;
456 }
457
Harald Weltef0a49972017-07-16 03:55:20 +0200458 function f_gsmtap_get_si(GSMTAP_PT pt, RrMessageType msg_type) return SystemInformation {
459 timer T := 10.0;
460 var GSMTAP_RecvFrom rf;
461 var SystemInformation si;
462
463 /* flush all previous/buffered elements */
464 pt.clear
465
466 T.start;
467 alt {
468 [] pt.receive(t_recvfrom(GSMTAP_CHANNEL_BCCH)) -> value rf {
469 si := dec_SystemInformation(rf.msg.payload);
470 if (si.header.message_type == msg_type) {
471 return si;
472 }
473 repeat;
474 }
475 [] pt.receive { repeat; };
476 [] T.timeout { testcase.stop("Error waiting for SI on GSMTAP"); };
477 }
478 return si;
479 }
480
481 function f_gsmtap_match_si(GSMTAP_PT pt, RrMessageType msg_type, template SystemInformation t) {
482 var SystemInformation si := f_gsmtap_get_si(pt, msg_type);
483 if (not match(si, t)) {
484 setverdict(fail, "SI ", si, " doesn't match ", t);
485 } else {
486 setverdict(pass);
487 }
488 }
489
Harald Weltebdc5dbd2017-07-16 00:00:43 +0200490 function f_init() runs on dummy_CT {
491 if (initialized) {
492 return;
493 }
494 /* GSMTAP initialization */
Harald Welteb622a3d2017-07-14 22:26:33 +0200495 map(self:GSMTAP, system:GSMTAP);
496 IPL4_GSMTAP_CtrlFunct.f_IPL4_listen(GSMTAP, "0.0.0.0", GSMTAP_PORT, {udp := {}});
497
Harald Weltebdc5dbd2017-07-16 00:00:43 +0200498 /* VTY initialization */
499 map(self:BSCVTY, system:BSCVTY);
500 f_vty_set_prompts(BSCVTY)
Harald Weltefd512cb2017-07-16 01:34:15 +0200501 f_vty_transceive(BSCVTY, "enable");
Harald Weltebdc5dbd2017-07-16 00:00:43 +0200502
503 initialized := true;
504 }
505
506 testcase TC_si_default() runs on dummy_CT {
507 var SystemInformationVectorPerTc si_per_tc;
508
509 f_init();
510
Harald Welteaf549412017-07-15 21:33:21 +0200511 si_per_tc := f_gsmtap_sample_si(GSMTAP);
Harald Welteaf549412017-07-15 21:33:21 +0200512 f_validate_si_scheduling(si_cfg, si_per_tc);
Harald Weltebdc5dbd2017-07-16 00:00:43 +0200513
Harald Welteaf549412017-07-15 21:33:21 +0200514 setverdict(pass);
Harald Welteb622a3d2017-07-14 22:26:33 +0200515 }
516
Harald Weltebdc5dbd2017-07-16 00:00:43 +0200517 testcase TC_si_sched_2bis() runs on dummy_CT {
518 var SystemInformationVectorPerTc si_per_tc;
519 f_init();
520
521 /* Enable SI2bis + validate scheduling */
Harald Weltebdc5dbd2017-07-16 00:00:43 +0200522 si_cfg.si2bis_present := true;
Harald Weltefe1052d2017-07-16 01:24:01 +0200523 f_si_cfg_to_vty();
Harald Weltebdc5dbd2017-07-16 00:00:43 +0200524 si_per_tc := f_gsmtap_sample_si(GSMTAP);
525 f_validate_si_scheduling(si_cfg, si_per_tc);
526
527 /* cleanup */
Harald Weltebdc5dbd2017-07-16 00:00:43 +0200528 si_cfg.si2bis_present := false;
Harald Weltefe1052d2017-07-16 01:24:01 +0200529 f_si_cfg_to_vty();
Harald Weltebdc5dbd2017-07-16 00:00:43 +0200530
531 setverdict(pass);
532 }
533
534 testcase TC_si_sched_2ter() runs on dummy_CT {
535 var SystemInformationVectorPerTc si_per_tc;
536 f_init();
537
538 /* Enable SI2ter + validate scheduling */
Harald Weltebdc5dbd2017-07-16 00:00:43 +0200539 si_cfg.si2ter_present := true;
Harald Weltefe1052d2017-07-16 01:24:01 +0200540 f_si_cfg_to_vty();
Harald Weltebdc5dbd2017-07-16 00:00:43 +0200541 si_per_tc := f_gsmtap_sample_si(GSMTAP);
542 f_validate_si_scheduling(si_cfg, si_per_tc);
543
544 /* cleanup */
Harald Weltebdc5dbd2017-07-16 00:00:43 +0200545 si_cfg.si2ter_present := false;
Harald Weltefe1052d2017-07-16 01:24:01 +0200546 f_si_cfg_to_vty();
Harald Weltebdc5dbd2017-07-16 00:00:43 +0200547
548 setverdict(pass);
549 }
550
551 testcase TC_si_sched_2ter_2bis() runs on dummy_CT {
552 var SystemInformationVectorPerTc si_per_tc;
553 f_init();
554
555 /* Enable SI2bis + SI2ter + validate scheduling */
Harald Weltebdc5dbd2017-07-16 00:00:43 +0200556 si_cfg.si2bis_present := true;
557 si_cfg.si2ter_present := true;
Harald Weltefe1052d2017-07-16 01:24:01 +0200558 f_si_cfg_to_vty();
Harald Weltebdc5dbd2017-07-16 00:00:43 +0200559 si_per_tc := f_gsmtap_sample_si(GSMTAP);
560 f_validate_si_scheduling(si_cfg, si_per_tc);
561
562 /* cleanup */
Harald Weltebdc5dbd2017-07-16 00:00:43 +0200563 si_cfg.si2bis_present := false;
564 si_cfg.si2ter_present := false;
Harald Weltefe1052d2017-07-16 01:24:01 +0200565 f_si_cfg_to_vty();
Harald Weltebdc5dbd2017-07-16 00:00:43 +0200566
567 setverdict(pass);
568 }
569
570 testcase TC_si_sched_2quater() runs on dummy_CT {
571 var SystemInformationVectorPerTc si_per_tc;
572 f_init();
573
574 /* Enable SI2quater + validate scheduling */
Harald Weltebdc5dbd2017-07-16 00:00:43 +0200575 si_cfg.si2quater_present := true;
Harald Weltefe1052d2017-07-16 01:24:01 +0200576 f_si_cfg_to_vty();
Harald Weltebdc5dbd2017-07-16 00:00:43 +0200577
578 /* cleanup */
Harald Weltebdc5dbd2017-07-16 00:00:43 +0200579 si_cfg.si2quater_present := false;
Harald Weltefe1052d2017-07-16 01:24:01 +0200580 f_si_cfg_to_vty();
Harald Weltebdc5dbd2017-07-16 00:00:43 +0200581
582 setverdict(pass);
583 }
584
585 testcase TC_si_sched_13() runs on dummy_CT {
586 var SystemInformationVectorPerTc si_per_tc;
587 f_init();
588
589 /* Enable SI2ter + validate scheduling */
Harald Weltebdc5dbd2017-07-16 00:00:43 +0200590 si_cfg.si13_present := true;
Harald Weltefe1052d2017-07-16 01:24:01 +0200591 f_si_cfg_to_vty();
Harald Weltebdc5dbd2017-07-16 00:00:43 +0200592 si_per_tc := f_gsmtap_sample_si(GSMTAP);
593 f_validate_si_scheduling(si_cfg, si_per_tc);
594
595 /* cleanup */
Harald Weltebdc5dbd2017-07-16 00:00:43 +0200596 si_cfg.si13_present := false;
Harald Weltefe1052d2017-07-16 01:24:01 +0200597 f_si_cfg_to_vty();
Harald Weltebdc5dbd2017-07-16 00:00:43 +0200598
599 setverdict(pass);
600 }
Harald Welte9a907b32017-07-15 10:34:27 +0200601
Harald Weltefe1052d2017-07-16 01:24:01 +0200602 testcase TC_si_sched_13_2bis_2ter_2quater() runs on dummy_CT {
603 var SystemInformationVectorPerTc si_per_tc;
604 f_init();
605
606 si_cfg.si2bis_present := true;
607 si_cfg.si2ter_present := true;
608 si_cfg.si2quater_present := true;
609 si_cfg.si13_present := true;
610 f_si_cfg_to_vty();
611 si_per_tc := f_gsmtap_sample_si(GSMTAP);
612 f_validate_si_scheduling(si_cfg, si_per_tc);
613
614 /* cleanup */
615 si_cfg.si2bis_present := false;
616 si_cfg.si2ter_present := false;
617 si_cfg.si2quater_present := false;
618 si_cfg.si13_present := false;
619 f_si_cfg_to_vty();
620
621 setverdict(pass);
622 }
623
624 function f_si_cfg_to_vty() runs on dummy_CT {
625 if (si_cfg.si2bis_present) {
626 f_vty_si_static(BSCVTY, 0, "2bis", c_si2bis);
627 } else {
628 f_vty_si_computed(BSCVTY, 0, "2bis");
629 }
630 if (si_cfg.si2ter_present) {
631 f_vty_si_static(BSCVTY, 0, "2ter", c_si2ter);
632 } else {
633 f_vty_si_computed(BSCVTY, 0, "2ter");
634 }
635 if (si_cfg.si13_present) {
636 f_vty_gprs_mode(BSCVTY, 0, "gprs");
637 } else {
638 f_vty_gprs_mode(BSCVTY, 0, "none");
639 }
640 if (si_cfg.si2quater_present) {
641 f_vty_si2q_add_uarfcn(BSCVTY, 0, 23, 42);
642 } else {
643 f_vty_si2q_del_uarfcn(BSCVTY, 0, 23, 42);
644 }
645 /* for debugging */
646 f_vty_transceive(BSCVTY, "write terminal");
647 /* actually commit the changes from BSC -> BTS */
648 f_vty_si_resend(BSCVTY, 0);
649 }
Harald Welte9a907b32017-07-15 10:34:27 +0200650
651 /* permitted prompts on VTY */
652 const charstring NORMAL_PROMPT := "OpenBSC> ";
653 const charstring ENABLE_PROMPT := "OpenBSC# ";
654 const charstring CONFIG_PROMPT := "OpenBSC(*)\#";
Harald Welted1f74c62017-07-16 03:04:37 +0200655 template charstring t_vty_unknown := pattern "*% Unknown command.";
Harald Welte9a907b32017-07-15 10:34:27 +0200656
657 const ASP_TelnetDynamicConfig vty_prompt[3] := {
658 {
659 prompt := {
660 id := 1,
661 prompt := NORMAL_PROMPT,
662 has_wildcards := false
663 }
664 }, {
665 prompt := {
666 id := 2,
667 prompt := ENABLE_PROMPT,
668 has_wildcards := false
669 }
670 }, {
671 prompt := {
672 id := 3,
673 prompt := CONFIG_PROMPT,
674 has_wildcards := true
675 }
676 }
677 };
678
679 /* configure prompts in TELNETasp module */
680 function f_vty_set_prompts(TELNETasp_PT pt) {
681 /* set some configuration that isn't possible to express
682 * in the config file due to syntactic restrictions (Who invents config
683 * files that don't permit regular expressions? */
684 for (var integer i := 0; i < sizeof(vty_prompt); i:= i + 1) {
685 pt.send(vty_prompt[i])
686 }
687 }
688
689 /* wait for any of the permitted prompts; buffer + return all intermediate output */
690 function f_vty_wait_for_prompt(TELNETasp_PT pt) return charstring {
691 template charstring config_pattern := pattern CONFIG_PROMPT;
692 var charstring rx, buf := "";
693 timer T := 2.0;
694
695 T.start;
696 alt {
697 [] pt.receive(NORMAL_PROMPT) { };
698 [] pt.receive(ENABLE_PROMPT) { };
699 [] pt.receive(config_pattern) { };
Harald Welte75f761f2017-07-16 03:05:31 +0200700 [] pt.receive(t_vty_unknown) { testcase.stop(fail, "VTY: Unknown Command") };
Harald Welte9a907b32017-07-15 10:34:27 +0200701 [] pt.receive(charstring:?) -> value rx { buf := buf & rx; repeat };
Harald Weltebdc5dbd2017-07-16 00:00:43 +0200702 [] T.timeout { setverdict(fail, "VTY Timeout for prompt"); return ""};
Harald Welte9a907b32017-07-15 10:34:27 +0200703 }
704 T.stop;
705 return buf;
706 }
707
708 /* send a VTY command and obtain response until prompt is received */
Harald Welted7bd30f2017-07-16 03:54:54 +0200709 function f_vty_transceive_ret(TELNETasp_PT pt, charstring tx) return charstring {
Harald Welte9a907b32017-07-15 10:34:27 +0200710 pt.send(tx);
711 return f_vty_wait_for_prompt(pt);
712 }
713
Harald Welted7bd30f2017-07-16 03:54:54 +0200714 /* send a VTY command and obtain response until prompt is received */
715 function f_vty_transceive(TELNETasp_PT pt, charstring tx) {
716 f_vty_transceive_ret(pt, tx);
717 }
718
Harald Weltebdc5dbd2017-07-16 00:00:43 +0200719 type integer BtsNr (0..255);
720 type integer BtsTrxNr (0..255);
721 type integer BtsTimeslotNr (0..7);
722
723 type charstring BtsGprsMode ("none", "gprs", "egrps");
724
Harald Welte9a907b32017-07-15 10:34:27 +0200725 /* enter the'confiugration' mode of the VTY */
726 function f_vty_enter_config(TELNETasp_PT pt) {
Harald Welte9a907b32017-07-15 10:34:27 +0200727 f_vty_transceive(pt, "configure terminal")
728 }
729
Harald Weltebdc5dbd2017-07-16 00:00:43 +0200730 function f_vty_enter_cfg_network(TELNETasp_PT pt) {
731 f_vty_enter_config(pt);
732 f_vty_transceive(pt, "network")
733 }
Harald Welte9a907b32017-07-15 10:34:27 +0200734
Harald Weltebdc5dbd2017-07-16 00:00:43 +0200735 function f_vty_enter_cfg_bts(TELNETasp_PT pt, BtsNr bts := 0) {
736 f_vty_enter_cfg_network(pt);
737 f_vty_transceive(pt, "bts " & int2str(bts));
738 }
739
740 function f_vty_enter_cfg_trx(TELNETasp_PT pt, BtsNr bts := 0, BtsTrxNr trx := 0) {
741 f_vty_enter_cfg_bts(pt, bts);
742 f_vty_transceive(pt, "trx " & int2str(trx));
743 }
744
745 function f_vty_enter_cfg_ts(TELNETasp_PT pt, BtsNr bts := 0, BtsTrxNr trx := 0, BtsTimeslotNr ts) {
746 f_vty_enter_cfg_trx(pt, bts, trx);
747 f_vty_transceive(pt, "timeslot " & int2str(ts));
748 }
749
750 function f_vty_si_static(TELNETasp_PT pt, BtsNr bts, charstring si, octetstring bytes) {
751 f_vty_enter_cfg_bts(pt, bts);
752 f_vty_transceive(pt, "system-information " & si & " mode static");
753 f_vty_transceive(pt, "system-information " & si & " static " & hex2str(oct2hex(bytes)));
754 f_vty_transceive(pt, "end");
755 }
756
757 function f_vty_si_computed(TELNETasp_PT pt, BtsNr bts, charstring si) {
758 f_vty_enter_cfg_bts(pt, bts);
759 f_vty_transceive(pt, "system-information " & si & " mode computed");
760 f_vty_transceive(pt, "end");
761 }
762
763 function f_vty_si_resend(TELNETasp_PT pt, BtsNr bts := 0) {
764 f_vty_transceive(pt, "bts " & int2str(bts) & " resend-system-information");
Harald Weltec17c88e2017-07-16 00:39:59 +0200765 /* wait for 1s until changes propagate */
766 timer T := 1.0;
Harald Weltebdc5dbd2017-07-16 00:00:43 +0200767 T.start;
768 T.timeout;
769 }
770
771 function f_vty_gprs_mode(TELNETasp_PT pt, integer bts, BtsGprsMode mode) {
772 f_vty_enter_cfg_bts(pt, bts);
773 f_vty_transceive(pt, "gprs mode " & mode);
774 f_vty_transceive(pt, "end");
775 }
776
777 function f_vty_si2q_add_uarfcn(TELNETasp_PT pt, BtsNr bts, UmtsArfcn uarfcn, UmtsScramblingCode sc, integer diversity := 0) {
778 f_vty_enter_cfg_bts(pt, bts);
779 f_vty_transceive(pt, "si2quater neighbor-list add uarfcn " & int2str(uarfcn) & " " & int2str(sc) & " " & int2str(diversity));
780 f_vty_transceive(pt, "end");
781 }
782
783 function f_vty_si2q_del_uarfcn(TELNETasp_PT pt, BtsNr bts, UmtsArfcn uarfcn, UmtsScramblingCode sc) {
784 f_vty_enter_cfg_bts(pt, bts);
785 f_vty_transceive(pt, "si2quater neighbor-list del uarfcn " & int2str(uarfcn) & " " & int2str(sc));
786 f_vty_transceive(pt, "end");
787 }
788
789 testcase TC_telnet() runs on dummy_CT {
790 f_init();
Harald Weltefd512cb2017-07-16 01:34:15 +0200791 f_vty_enter_config(BSCVTY);
Harald Welte9a907b32017-07-15 10:34:27 +0200792 f_vty_transceive(BSCVTY, "show network")
Harald Welte9a907b32017-07-15 10:34:27 +0200793 f_vty_transceive(BSCVTY, "network")
794 f_vty_transceive(BSCVTY, "bts 0")
Harald Weltebdc5dbd2017-07-16 00:00:43 +0200795 f_vty_transceive(BSCVTY, "end")
796 setverdict(pass);
Harald Welte9a907b32017-07-15 10:34:27 +0200797 }
798
Harald Weltef0a49972017-07-16 03:55:20 +0200799 template SystemInformation t_SI_SI3 := {
Harald Welted2e342f2017-07-16 07:34:13 +0200800 header := t_RrHeader(SYSTEM_INFORMATION_TYPE_3, ?),
Harald Weltef0a49972017-07-16 03:55:20 +0200801 payload := { si3 := t_SI3 }
802 }
803
804 testcase TC_cellid() runs on dummy_CT {
805 var CellIdentity cid := float2int(rnd() * 65535.0);
806 var template SystemInformation t := t_SI_SI3;
807 t.payload.si3.cell_id := cid;
808
809 f_init();
810 f_vty_enter_cfg_bts(BSCVTY, 0);
811 f_vty_transceive(BSCVTY, "cell_identity " & int2str(cid));
812 f_vty_transceive(BSCVTY, "end")
813 f_vty_si_resend(BSCVTY, 0);
814
815 f_gsmtap_match_si(GSMTAP, SYSTEM_INFORMATION_TYPE_3, t);
816 }
817
818 testcase TC_lac() runs on dummy_CT {
819 var uint16_t lac := float2int(rnd() * 65535.0);
820
821 var template SystemInformation t := t_SI_SI3;
822 t.payload.si3.lai.lac := lac;
823
824 f_init();
825 f_vty_enter_cfg_bts(BSCVTY, 0);
826 f_vty_transceive(BSCVTY, "location_area_code " & int2str(lac));
827 f_vty_transceive(BSCVTY, "end")
828 f_vty_si_resend(BSCVTY, 0);
829
830 f_gsmtap_match_si(GSMTAP, SYSTEM_INFORMATION_TYPE_3, t);
831 }
832
833 testcase TC_rach_tx_int() runs on dummy_CT {
834 var uint16_t rach_tx_int := float2int(rnd() * 15.0);
835
836 var template SystemInformation t := t_SI_SI3;
837 t.payload.si3.rach_control.tx_integer := int2bit(rach_tx_int, 4);
838
839 f_init();
840 f_vty_enter_cfg_bts(BSCVTY, 0);
841 f_vty_transceive(BSCVTY, "rach tx integer " & int2str(rach_tx_int));
842 f_vty_transceive(BSCVTY, "end")
843 f_vty_si_resend(BSCVTY, 0);
844
845 f_gsmtap_match_si(GSMTAP, SYSTEM_INFORMATION_TYPE_3, t);
846 }
847
848 testcase TC_rach_max_tx() runs on dummy_CT {
849 var uint16_t r := float2int(rnd() * 3.0);
850 const integer max_tx_map[4] := { 1, 2, 4, 7 };
851 var template SystemInformation t := t_SI_SI3;
852 t.payload.si3.rach_control.max_retrans := int2bit(r, 2);
853
854 f_init();
855 f_vty_enter_cfg_bts(BSCVTY, 0);
856 f_vty_transceive(BSCVTY, "rach max transmission " & int2str(max_tx_map[r]));
857 f_vty_transceive(BSCVTY, "end")
858 f_vty_si_resend(BSCVTY, 0);
859
860 f_gsmtap_match_si(GSMTAP, SYSTEM_INFORMATION_TYPE_3, t);
861 }
862
863 testcase TC_dtx_ul() runs on dummy_CT {
864 var integer i := float2int(rnd() * 2.0);
865 var template SystemInformation t := t_SI_SI3;
866 t.payload.si3.cell_options.dtx := int2bit(i, 2);
867
868 f_init();
869 f_vty_enter_cfg_bts(BSCVTY, 0);
870 if (i == 0) {
871 f_vty_transceive(BSCVTY, "dtx uplink");
872 } else if (i == 1) {
873 f_vty_transceive(BSCVTY, "dtx uplink force");
874 } else {
875 f_vty_transceive(BSCVTY, "no dtx uplink");
876 }
877
878 f_gsmtap_match_si(GSMTAP, SYSTEM_INFORMATION_TYPE_3, t);
879 }
880
881 testcase TC_attach() runs on dummy_CT {
882 var integer i := float2int(rnd());
883 var template SystemInformation t := t_SI_SI3;
884 t.payload.si3.ctrl_chan_desc.att := int2bool(i);
885
886 f_init();
887 f_vty_enter_cfg_bts(BSCVTY, 0);
888 f_vty_transceive(BSCVTY, "channel-descrption attach " & int2str(i));
889 f_vty_transceive(BSCVTY, "end")
890 f_vty_si_resend(BSCVTY, 0);
891
892 f_gsmtap_match_si(GSMTAP, SYSTEM_INFORMATION_TYPE_3, t);
893 }
894
895 testcase TC_bs_pa_mfrms() runs on dummy_CT {
896 var integer i := 2 + float2int(rnd() * 7.0);
897 var template SystemInformation t := t_SI_SI3;
898 t.payload.si3.ctrl_chan_desc.bs_pa_mfrms := i - 2;
899
900 f_init();
901 f_vty_enter_cfg_bts(BSCVTY, 0);
902 f_vty_transceive(BSCVTY, "channel-descrption bs-pa-mfrms " & int2str(i));
903 f_vty_transceive(BSCVTY, "end")
904 f_vty_si_resend(BSCVTY, 0);
905
906 f_gsmtap_match_si(GSMTAP, SYSTEM_INFORMATION_TYPE_3, t);
907 }
908
909 testcase TC_bs_ag_blks_res() runs on dummy_CT {
910 var integer i := float2int(rnd() * 7.0);
911 var template SystemInformation t := t_SI_SI3;
912 t.payload.si3.ctrl_chan_desc.bs_ag_blks_res := i;
913
914 f_init();
915 f_vty_enter_cfg_bts(BSCVTY, 0);
916 f_vty_transceive(BSCVTY, "channel-descrption bs-ag-blks-res " & int2str(i));
917 f_vty_transceive(BSCVTY, "end")
918 f_vty_si_resend(BSCVTY, 0);
919
920 f_gsmtap_match_si(GSMTAP, SYSTEM_INFORMATION_TYPE_3, t);
921 }
922
923 testcase TC_radio_link_timeout() runs on dummy_CT {
924 var integer i := float2int(rnd() * 15.0);
925 var template SystemInformation t := t_SI_SI3;
926 t.payload.si3.cell_options.radio_link_timeout := int2bit(i, 4);
927
928 f_init();
929 f_vty_enter_cfg_bts(BSCVTY, 0);
930 f_vty_transceive(BSCVTY, "radio-link-timeout " & int2str(4 + i*4));
931 f_vty_transceive(BSCVTY, "end")
932 f_vty_si_resend(BSCVTY, 0);
933
934 f_gsmtap_match_si(GSMTAP, SYSTEM_INFORMATION_TYPE_3, t);
935 }
936
937 testcase TC_cell_resel_hyst() runs on dummy_CT {
938 var integer i := float2int(rnd() * 7.0);
939 var template SystemInformation t := t_SI_SI3;
940 t.payload.si3.cell_sel_par.cell_resel_hyst := i;
941
942 f_init();
943 f_vty_enter_cfg_bts(BSCVTY, 0);
944 f_vty_transceive(BSCVTY, "cell reselection hysteresis " & int2str(i*2));
945 f_vty_transceive(BSCVTY, "end")
946 f_vty_si_resend(BSCVTY, 0);
947
948 f_gsmtap_match_si(GSMTAP, SYSTEM_INFORMATION_TYPE_3, t);
949 }
950
951 testcase TC_rxlev_acc_min() runs on dummy_CT {
952 var integer i := float2int(rnd() * 63.0);
953 var template SystemInformation t := t_SI_SI3;
954 t.payload.si3.cell_sel_par.rxlev_access_min := i;
955
956 f_init();
957 f_vty_enter_cfg_bts(BSCVTY, 0);
958 f_vty_transceive(BSCVTY, "rxlev access min " & int2str(i));
959 f_vty_transceive(BSCVTY, "end")
960 f_vty_si_resend(BSCVTY, 0);
961
962 f_gsmtap_match_si(GSMTAP, SYSTEM_INFORMATION_TYPE_3, t);
963 }
964
965 testcase TC_neci() runs on dummy_CT {
966 var integer i := float2int(rnd() * 1.0);
967 var template SystemInformation t := t_SI_SI3;
968 t.payload.si3.cell_sel_par.neci := int2bool(i);
969
970 f_init();
971 f_vty_enter_cfg_network(BSCVTY);
972 f_vty_transceive(BSCVTY, "neci " & int2str(i));
973 f_vty_transceive(BSCVTY, "end")
974 f_vty_si_resend(BSCVTY, 0);
975
976 f_gsmtap_match_si(GSMTAP, SYSTEM_INFORMATION_TYPE_3, t);
977 }
978
979 testcase TC_emerg_allowed() runs on dummy_CT {
980 var integer i := float2int(rnd());
981 var template SystemInformation t := t_SI_SI3;
982 if (i == 1) {
983 t.payload.si3.rach_control.ac := '?????0??????????'B;
984 } else {
985 t.payload.si3.rach_control.ac := '?????1??????????'B;
986 }
987
988 f_init();
989 f_vty_enter_cfg_bts(BSCVTY, 0);
990 f_vty_transceive(BSCVTY, "rach emergency call allowed " & int2str(i));
991 f_vty_transceive(BSCVTY, "end")
992 f_vty_si_resend(BSCVTY, 0);
993
994 f_gsmtap_match_si(GSMTAP, SYSTEM_INFORMATION_TYPE_3, t);
995 }
996
997 /* TODO:
998 * * don't only validate SI3 but check all other SI with same IE?
999 * * parse + validate rest octets somehow
1000 * * validate contents/encoding of neighbor channel lists
1001 * * validate si2quater sub-mux scheduling
1002 */
1003
1004
Harald Welte56db5fd2017-07-14 18:25:59 +02001005 control {
1006 execute(TC_si1());
Harald Welte9a907b32017-07-15 10:34:27 +02001007 execute(TC_telnet());
Harald Weltebdc5dbd2017-07-16 00:00:43 +02001008 execute(TC_si_default());
1009 execute(TC_si_sched_2bis());
1010 execute(TC_si_sched_2ter());
1011 execute(TC_si_sched_2ter_2bis());
1012 execute(TC_si_sched_2quater());
1013 execute(TC_si_sched_13());
Harald Weltefe1052d2017-07-16 01:24:01 +02001014 execute(TC_si_sched_13_2bis_2ter_2quater());
Harald Weltef0a49972017-07-16 03:55:20 +02001015 execute(TC_neci());
1016 execute(TC_cell_resel_hyst());
1017 execute(TC_rxlev_acc_min());
1018 execute(TC_cellid());
1019 execute(TC_lac());
1020 execute(TC_rach_tx_int());
1021 execute(TC_rach_max_tx());
1022 execute(TC_attach());
1023 execute(TC_dtx_ul());
1024 execute(TC_emerg_allowed());
1025 execute(TC_bs_pa_mfrms());
1026 execute(TC_bs_ag_blks_res());
1027 execute(TC_radio_link_timeout());
Harald Welte56db5fd2017-07-14 18:25:59 +02001028 }
1029}