blob: 01bcb9af0d9da6646936055e3ad445bba31b162f [file] [log] [blame]
Daniel Willmann423d8f42020-09-08 18:58:22 +02001module GBProxy_Tests {
2
3/* Osmocom GBProxy test suite in TTCN-3
4 * (C) 2020 sysmocom - s.f.m.c. GmbH
5 * All rights reserved.
6 *
7 * Author: Daniel Willmann <dwillmann@sysmocom.de>
8
9 * Released under the terms of GNU General Public License, Version 2 or
10 * (at your option) any later version.
11 *
12 * SPDX-License-Identifier: GPL-2.0-or-later
13 */
14
15import from General_Types all;
16import from Osmocom_Types all;
17import from GSM_Types all;
18import from Native_Functions all;
19import from NS_Types all;
20import from NS_Emulation all;
21import from BSSGP_Types all;
22import from BSSGP_Emulation all;
23import from SCCPasp_Types all;
24import from Osmocom_Gb_Types all;
25
26import from MobileL3_CommonIE_Types all;
27import from MobileL3_GMM_SM_Types all;
28import from MobileL3_Types all;
29import from L3_Templates all;
30import from L3_Common all;
31
32import from TELNETasp_PortType all;
33import from Osmocom_VTY_Functions all;
34
35import from LLC_Types all;
36import from LLC_Templates all;
37
38import from GSM_RR_Types all;
39
Harald Welte6d63f742020-11-15 19:44:04 +010040/* mcc_mnc is 24.008 10.5.5.15 encoded. 262 42 */
41const BcdMccMnc c_mcc_mnc := '262F42'H;
42
Harald Welte0d5fceb2020-11-29 16:04:07 +010043/* 48.016 section 6.1.4.2: The default maximum information field size of 1600 octets shall be supported on the Gb interface */
44const integer max_fr_info_size := 1600;
45
Daniel Willmann423d8f42020-09-08 18:58:22 +020046modulepar {
Daniel Willmann2c9300f2020-12-01 10:54:08 +010047 /* SGSN NS configuration */
Harald Welte6d63f742020-11-15 19:44:04 +010048 NSConfigurations mp_nsconfig_sgsn := {
Daniel Willmann423d8f42020-09-08 18:58:22 +020049 {
Daniel Willmann423d8f42020-09-08 18:58:22 +020050 nsei := 101,
51 role_sgsn := true,
Harald Welte90f19742020-11-06 19:34:40 +010052 handle_sns := false,
53 nsvc := {
54 {
55 provider := {
56 ip := {
57 address_family := AF_INET,
58 local_udp_port := 7777,
59 local_ip := "127.0.0.1",
60 remote_udp_port := 23000,
61 remote_ip := "127.0.0.1"
62 }
63 },
64 nsvci := 101
65 }
66 }
Daniel Willmann423d8f42020-09-08 18:58:22 +020067 }
68 };
Daniel Willmann2c9300f2020-12-01 10:54:08 +010069 /* BSS NSEI start at 2000 + x
70 * NSVCI start from value of NSEI + 100
71 * UDP port is NSVCI * 10 */
Harald Welte6d63f742020-11-15 19:44:04 +010072 NSConfigurations mp_nsconfig_pcu := {
Daniel Willmann423d8f42020-09-08 18:58:22 +020073 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +010074 nsei := 2001,
Daniel Willmann423d8f42020-09-08 18:58:22 +020075 role_sgsn := false,
Harald Welte90f19742020-11-06 19:34:40 +010076 handle_sns := false,
77 nsvc := {
78 {
79 provider := {
80 ip := {
81 address_family := AF_INET,
82 local_udp_port := 21010,
83 local_ip := "127.0.0.1",
84 remote_udp_port := 23000,
85 remote_ip := "127.0.0.1"
86 }
87 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +010088 nsvci := 2101
Harald Welte90f19742020-11-06 19:34:40 +010089 }
90 }
Daniel Willmann423d8f42020-09-08 18:58:22 +020091 },
92 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +010093 nsei := 2002,
Daniel Willmann423d8f42020-09-08 18:58:22 +020094 role_sgsn := false,
Harald Welte90f19742020-11-06 19:34:40 +010095 handle_sns := false,
96 nsvc := {
97 {
98 provider := {
99 ip := {
100 address_family := AF_INET,
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100101 local_udp_port := 21020,
Harald Welte90f19742020-11-06 19:34:40 +0100102 local_ip := "127.0.0.1",
103 remote_udp_port := 23000,
104 remote_ip := "127.0.0.1"
105 }
106 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100107 nsvci := 2102
Harald Welte90f19742020-11-06 19:34:40 +0100108 }
109 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200110 },
111 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100112 nsei := 2003,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200113 role_sgsn := false,
Harald Welte90f19742020-11-06 19:34:40 +0100114 handle_sns := false,
115 nsvc := {
116 {
117 provider := {
118 ip := {
119 address_family := AF_INET,
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100120 local_udp_port := 21030,
Harald Welte90f19742020-11-06 19:34:40 +0100121 local_ip := "127.0.0.1",
122 remote_udp_port := 23000,
123 remote_ip := "127.0.0.1"
124 }
125 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100126 nsvci := 2103
Harald Welte90f19742020-11-06 19:34:40 +0100127 }
128 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200129 }
130 };
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100131 /* BVCI are NSEI*10 + x
132 * The first NSE only has one BVC, the second one 2 and so on
133 * The Cell ID is BVCI + 10000
134 * LAC/RAC are configured in such a way that:
135 * LAC 13135 is present once in NSE(2001), twice in NSE(2002) and once in NSE(2003)
136 * LAC 13300 is present twice in NSE(2003)
137 * RAI 13135-1 is present in NSE(2002) and NSE(2003)
138 * RAI 13300-0 is present twice in NSE(2003)
139 */
Harald Welte6d63f742020-11-15 19:44:04 +0100140 BssgpConfigs mp_gbconfigs := {
141 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100142 nsei := 2001,
Harald Welte6d63f742020-11-15 19:44:04 +0100143 sgsn_role := false,
144 bvc := {
145 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100146 bvci := 20011,
Harald Welte6d63f742020-11-15 19:44:04 +0100147 cell_id := {
148 ra_id := {
149 lai := {
150 mcc_mnc := c_mcc_mnc,
151 lac := 13135
152 },
153 rac := 0
154 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100155 cell_id := 30011
Harald Welte6d63f742020-11-15 19:44:04 +0100156 },
157 depth := BSSGP_DECODE_DEPTH_BSSGP,
158 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
159 }
160 }
161 }, {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100162 nsei := 2002,
Harald Welte6d63f742020-11-15 19:44:04 +0100163 sgsn_role := false,
164 bvc := {
165 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100166 bvci := 20021,
Harald Welte6d63f742020-11-15 19:44:04 +0100167 cell_id := {
168 ra_id := {
169 lai := {
170 mcc_mnc := c_mcc_mnc,
Harald Welte0e188242020-11-22 21:46:48 +0100171 lac := 13135
Harald Welte6d63f742020-11-15 19:44:04 +0100172 },
Harald Welte0e188242020-11-22 21:46:48 +0100173 rac := 1
Harald Welte6d63f742020-11-15 19:44:04 +0100174 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100175 cell_id := 30021
176 },
177 depth := BSSGP_DECODE_DEPTH_BSSGP,
178 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
179 },
180 {
181 bvci := 20022,
182 cell_id := {
183 ra_id := {
184 lai := {
185 mcc_mnc := c_mcc_mnc,
186 lac := 13135
187 },
188 rac := 2
189 },
190 cell_id := 30022
Harald Welte6d63f742020-11-15 19:44:04 +0100191 },
192 depth := BSSGP_DECODE_DEPTH_BSSGP,
193 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
194 }
195 }
196 }, {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100197 nsei := 2003,
Harald Welte6d63f742020-11-15 19:44:04 +0100198 sgsn_role := false,
199 bvc := {
200 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100201 bvci := 20031,
202 cell_id := {
203 ra_id := {
204 lai := {
205 mcc_mnc := c_mcc_mnc,
206 lac := 13135
207 },
208 rac := 1
209 },
210 cell_id := 30031
211 },
212 depth := BSSGP_DECODE_DEPTH_BSSGP,
213 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
214 },
215 {
216 bvci := 20032,
Harald Welte6d63f742020-11-15 19:44:04 +0100217 cell_id := {
218 ra_id := {
219 lai := {
220 mcc_mnc := c_mcc_mnc,
221 lac := 13300
222 },
223 rac := 0
224 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100225 cell_id := 30032
226 },
227 depth := BSSGP_DECODE_DEPTH_BSSGP,
228 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
229 },
230 {
231 bvci := 20033,
232 cell_id := {
233 ra_id := {
234 lai := {
235 mcc_mnc := c_mcc_mnc,
236 lac := 13300
237 },
238 rac := 0
239 },
240 cell_id := 30033
Harald Welte6d63f742020-11-15 19:44:04 +0100241 },
242 depth := BSSGP_DECODE_DEPTH_BSSGP,
243 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
244 }
245 }
246 }
247 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200248};
249
Daniel Willmann423d8f42020-09-08 18:58:22 +0200250type record GbInstance {
251 NS_CT vc_NS,
252 BSSGP_CT vc_BSSGP,
Harald Welte67dc8c22020-11-17 18:32:29 +0100253 BSSGP_BVC_CTs vc_BSSGP_BVC,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200254 BssgpConfig cfg
255};
Harald Welte67dc8c22020-11-17 18:32:29 +0100256type record of BSSGP_BVC_CT BSSGP_BVC_CTs
Daniel Willmann423d8f42020-09-08 18:58:22 +0200257
258const integer NUM_PCU := 3;
Harald Welte6d63f742020-11-15 19:44:04 +0100259type record of GbInstance GbInstances;
260type record of BssgpConfig BssgpConfigs;
261type record of NSConfiguration NSConfigurations;
262type record of BssgpCellId BssgpCellIds;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200263
264const integer NUM_SGSN := 1;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200265
266type component test_CT {
Harald Welte6d63f742020-11-15 19:44:04 +0100267 var GbInstances g_pcu;
268 var GbInstances g_sgsn;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200269
270 port BSSGP_CT_PROC_PT PROC;
271
Harald Weltefbae83f2020-11-15 23:25:55 +0100272 port BSSGP_BVC_MGMT_PT SGSN_MGMT;
273 port BSSGP_BVC_MGMT_PT PCU_MGMT;
274
Daniel Willmann423d8f42020-09-08 18:58:22 +0200275 port TELNETasp_PT GBPVTY;
276
277 var boolean g_initialized := false;
278 var boolean g_use_echo := false;
Harald Welte16786e92020-11-27 19:11:56 +0100279
280 var ro_integer g_roi := {};
Daniel Willmann423d8f42020-09-08 18:58:22 +0200281};
282
283type component BSSGP_ConnHdlr {
Harald Welte3dd21b32020-11-17 19:21:00 +0100284 /* array of per-BVC ports on the PCU side */
Daniel Willmann423d8f42020-09-08 18:58:22 +0200285 port BSSGP_PT PCU[NUM_PCU];
286 port BSSGP_PT PCU_SIG[NUM_PCU];
287 port BSSGP_PROC_PT PCU_PROC[NUM_PCU];
Harald Welte3dd21b32020-11-17 19:21:00 +0100288 /* component reference to the component to which we're currently connected */
289 var BSSGP_BVC_CT pcu_ct[NUM_PCU];
Harald Welte0e188242020-11-22 21:46:48 +0100290 /* BSSGP BVC configuration of the component to which we're currently connected */
291 var BssgpBvcConfig pcu_bvc_cfg[NUM_PCU];
Harald Welte3dd21b32020-11-17 19:21:00 +0100292
293 /* array of per-BVC ports on the SGSN side */
Daniel Willmann423d8f42020-09-08 18:58:22 +0200294 port BSSGP_PT SGSN[NUM_SGSN];
295 port BSSGP_PT SGSN_SIG[NUM_SGSN];
296 port BSSGP_PROC_PT SGSN_PROC[NUM_SGSN];
Harald Welte3dd21b32020-11-17 19:21:00 +0100297 /* component reference to the component to which we're currently connected */
298 var BSSGP_BVC_CT sgsn_ct[NUM_PCU];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200299
300 var BSSGP_ConnHdlrPars g_pars;
301 timer g_Tguard;
302 var LLC_Entities llc;
Harald Welte0e188242020-11-22 21:46:48 +0100303
304 var ro_integer g_roi := {};
Daniel Willmann423d8f42020-09-08 18:58:22 +0200305}
306
307type record SGSN_ConnHdlrNetworkPars {
308 boolean expect_ptmsi,
309 boolean expect_auth,
310 boolean expect_ciph
311};
312
313type record BSSGP_ConnHdlrPars {
314 /* IMEI of the simulated ME */
315 hexstring imei,
316 /* IMSI of the simulated MS */
317 hexstring imsi,
318 /* MSISDN of the simulated MS (probably unused) */
319 hexstring msisdn,
320 /* P-TMSI allocated to the simulated MS */
321 OCT4 p_tmsi optional,
322 OCT3 p_tmsi_sig optional,
323 /* TLLI of the simulated MS */
324 OCT4 tlli,
325 OCT4 tlli_old optional,
326 RoutingAreaIdentificationV ra optional,
Harald Welte16357a92020-11-17 18:20:00 +0100327 GbInstances pcu,
Harald Welte3dd21b32020-11-17 19:21:00 +0100328 GbInstances sgsn,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200329 float t_guard
330};
331
332private function f_cellid_to_RAI(in BssgpCellId cell_id) return RoutingAreaIdentificationV {
333 /* mcc_mnc is encoded as of 24.008 10.5.5.15 */
334 var BcdMccMnc mcc_mnc := cell_id.ra_id.lai.mcc_mnc;
335
336 var RoutingAreaIdentificationV ret := {
337 mccDigit1 := mcc_mnc[0],
338 mccDigit2 := mcc_mnc[1],
339 mccDigit3 := mcc_mnc[2],
340 mncDigit3 := mcc_mnc[3],
341 mncDigit1 := mcc_mnc[4],
342 mncDigit2 := mcc_mnc[5],
343 lac := int2oct(cell_id.ra_id.lai.lac, 16),
344 rac := int2oct(cell_id.ra_id.rac, 8)
345 }
346 return ret;
347};
348
Harald Welte95339432020-12-02 18:50:52 +0100349private function f_fix_create_cb(inout BssgpConfig cfg)
350{
351 for (var integer i := 0; i < lengthof(cfg.bvc); i := i + 1) {
352 if (not isbound(cfg.bvc[i].create_cb)) {
353 cfg.bvc[i].create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
354 }
355 }
356}
357
Daniel Willmann423d8f42020-09-08 18:58:22 +0200358private function f_init_gb_pcu(inout GbInstance gb, charstring id, integer offset) runs on test_CT {
Harald Welteb419d0e2020-11-16 16:45:05 +0100359 var charstring ns_id := id & "-NS(PCU[" & int2str(offset) & "])";
360 var charstring bssgp_id := id & "-BSSGP(PCU[" & int2str(offset) & "])";
361 gb.vc_NS := NS_CT.create(ns_id);
362 gb.vc_BSSGP := BSSGP_CT.create(bssgp_id);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200363 /* connect lower end of BSSGP emulation with NS upper port */
364 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
365
Harald Welteb419d0e2020-11-16 16:45:05 +0100366 gb.vc_NS.start(NSStart(mp_nsconfig_pcu[offset], ns_id));
367 gb.vc_BSSGP.start(BssgpStart(gb.cfg, bssgp_id));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200368
369 for (var integer i := 0; i < lengthof(gb.cfg.bvc); i := i + 1) {
370 connect(self:PROC, gb.vc_BSSGP:PROC);
371 gb.vc_BSSGP_BVC[i] := f_bssgp_get_bvci_ct(gb.cfg.bvc[i].bvci, PROC);
372 disconnect(self:PROC, gb.vc_BSSGP:PROC);
Harald Weltefbae83f2020-11-15 23:25:55 +0100373 connect(self:PCU_MGMT, gb.vc_BSSGP_BVC[i]:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200374 }
Harald Welte16786e92020-11-27 19:11:56 +0100375 connect(self:PCU_MGMT, gb.vc_BSSGP:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200376}
377
378private function f_init_gb_sgsn(inout GbInstance gb, charstring id, integer offset) runs on test_CT {
Harald Welteb419d0e2020-11-16 16:45:05 +0100379 var charstring ns_id := id & "-NS(SGSN[" & int2str(offset) & "])";
380 var charstring bssgp_id := id & "-BSSGP(SGSN[" & int2str(offset) & "])";
381 gb.vc_NS := NS_CT.create(ns_id);
382 gb.vc_BSSGP := BSSGP_CT.create(bssgp_id);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200383 /* connect lower end of BSSGP emulation with NS upper port */
384 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
385
Harald Welteb419d0e2020-11-16 16:45:05 +0100386 gb.vc_NS.start(NSStart(mp_nsconfig_sgsn[offset], ns_id));
387 gb.vc_BSSGP.start(BssgpStart(gb.cfg, bssgp_id));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200388
389 for (var integer i := 0; i < lengthof(gb.cfg.bvc); i := i + 1) {
390 connect(self:PROC, gb.vc_BSSGP:PROC);
391 gb.vc_BSSGP_BVC[i] := f_bssgp_get_bvci_ct(gb.cfg.bvc[i].bvci, PROC);
392 disconnect(self:PROC, gb.vc_BSSGP:PROC);
Harald Weltefbae83f2020-11-15 23:25:55 +0100393 connect(self:SGSN_MGMT, gb.vc_BSSGP_BVC[i]:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200394 }
Harald Welte16786e92020-11-27 19:11:56 +0100395 connect(self:SGSN_MGMT, gb.vc_BSSGP:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200396}
397
398
399private function f_init_vty() runs on test_CT {
400 map(self:GBPVTY, system:GBPVTY);
401 f_vty_set_prompts(GBPVTY);
402 f_vty_transceive(GBPVTY, "enable");
403}
404
Harald Weltefbae83f2020-11-15 23:25:55 +0100405type record of integer ro_integer;
406
407private function ro_integer_contains(ro_integer r, integer x) return boolean {
408 for (var integer j := 0; j < lengthof(r); j := j+1) {
409 if (r[j] == x) {
410 return true;
411 }
412 }
413 return false;
414}
415
Harald Welte6d63f742020-11-15 19:44:04 +0100416function f_init() runs on test_CT {
Harald Weltefbae83f2020-11-15 23:25:55 +0100417 var ro_integer bvci_unblocked := {};
418 var BssgpStatusIndication bsi;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200419 var integer i;
420
421 if (g_initialized == true) {
422 return;
423 }
424 g_initialized := true;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200425
426 g_sgsn[0].cfg := {
Harald Welte6d63f742020-11-15 19:44:04 +0100427 nsei := mp_nsconfig_sgsn[0].nsei,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200428 sgsn_role := true,
Harald Welte6d63f742020-11-15 19:44:04 +0100429 bvc := { }
430 }
431 for (i := 0; i < lengthof(mp_gbconfigs); i := i+1) {
432 g_pcu[i].cfg := mp_gbconfigs[i];
Harald Welte95339432020-12-02 18:50:52 +0100433 /* make sure all have a proper crate_cb, which cannot be specified in config file */
434 f_fix_create_cb(g_pcu[i].cfg);
Harald Welte6d63f742020-11-15 19:44:04 +0100435 /* concatenate all the PCU-side BVCs for the SGSN side */
Harald Welte95339432020-12-02 18:50:52 +0100436 g_sgsn[0].cfg.bvc := g_sgsn[0].cfg.bvc & g_pcu[i].cfg.bvc;
Harald Welte6d63f742020-11-15 19:44:04 +0100437 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200438
439 f_init_vty();
Harald Welte6d63f742020-11-15 19:44:04 +0100440 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
Daniel Willmann443fc572020-11-18 13:26:57 +0100441 f_vty_transceive(GBPVTY, "nsvc nsei " & int2str(g_sgsn[i].cfg.nsei) & " force-unconfigured");
Daniel Willmannad93c052020-12-04 14:14:38 +0100442 }
443 for (i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
444 f_vty_transceive(GBPVTY, "nsvc nsei " & int2str(g_pcu[i].cfg.nsei) & " force-unconfigured");
445 f_vty_transceive(GBPVTY, "delete-gbproxy-peer " & int2str(g_pcu[i].cfg.nsei) & " only-bvc");
446 }
447
448 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
Harald Welteea1ba592020-11-17 18:05:13 +0100449 f_init_gb_sgsn(g_sgsn[i], "GbProxy_Test", i);
Harald Welte6d63f742020-11-15 19:44:04 +0100450 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200451 f_sleep(4.0);
Harald Welte6d63f742020-11-15 19:44:04 +0100452 for (i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
Harald Welteb419d0e2020-11-16 16:45:05 +0100453 f_init_gb_pcu(g_pcu[i], "GbProxy_Test", i);
Harald Welte6d63f742020-11-15 19:44:04 +0100454 }
Harald Weltefbae83f2020-11-15 23:25:55 +0100455
456 /* wait until all BVC are unblocked on both sides */
Harald Welted2801272020-11-17 19:22:58 +0100457 timer T := 15.0;
Harald Weltefbae83f2020-11-15 23:25:55 +0100458 T.start;
459 alt {
460 [] SGSN_MGMT.receive(BssgpStatusIndication:{*, ?, BVC_S_UNBLOCKED}) -> value bsi {
461 bvci_unblocked := bvci_unblocked & { bsi.bvci };
462 if (lengthof(bvci_unblocked) != lengthof(g_sgsn[0].cfg.bvc)) {
463 repeat;
464 }
465 }
466 [] SGSN_MGMT.receive(BssgpStatusIndication:{*, ?, ?}) {
467 repeat;
468 }
Harald Welte3c905152020-11-26 20:56:09 +0100469 [] SGSN_MGMT.receive(BssgpResetIndication:?) {
470 repeat;
471 }
Harald Weltefbae83f2020-11-15 23:25:55 +0100472 [] SGSN_MGMT.receive {
473 setverdict(fail, "Received unexpected message on SGSN_MGMT");
474 mtc.stop;
475 }
476
477 [] PCU_MGMT.receive(BssgpStatusIndication:{*, ?, BVC_S_UNBLOCKED}) -> value bsi {
478 repeat;
479 }
480 [] PCU_MGMT.receive(BssgpStatusIndication:{*, ?, ?}) {
481 repeat;
482 }
483 [] PCU_MGMT.receive(BssgpResetIndication:{0}) {
484 repeat;
485 }
486 [] PCU_MGMT.receive {
487 setverdict(fail, "Received unexpected message on PCU_MGMT");
488 mtc.stop;
489 }
490
491 [] T.timeout {
492 setverdict(fail, "Timeout waiting for unblock of all BVCs");
493 mtc.stop;
494 }
495 }
496
497 /* iterate over list and check all BVCI */
498 for (i := 0; i < lengthof(g_sgsn[0].cfg.bvc); i := i+1) {
499 var BssgpBvci bvci := g_sgsn[0].cfg.bvc[i].bvci;
500 if (not ro_integer_contains(bvci_unblocked, bvci)) {
501 setverdict(fail, "BVCI=", bvci, " was not unblocked during start-up");
502 mtc.stop;
503 }
504 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200505}
506
507function f_cleanup() runs on test_CT {
508 self.stop;
509}
510
511type function void_fn(charstring id) runs on BSSGP_ConnHdlr;
512
513/* helper function to create, connect and start a BSSGP_ConnHdlr component */
Harald Welte6d63f742020-11-15 19:44:04 +0100514function f_start_handler(void_fn fn, charstring id, GbInstances pcu, GbInstances sgsn, integer imsi_suffix,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200515 float t_guard := 30.0)
516runs on test_CT return BSSGP_ConnHdlr {
517 var BSSGP_ConnHdlr vc_conn;
518
519 var BSSGP_ConnHdlrPars pars := {
520 imei := f_gen_imei(imsi_suffix),
521 imsi := f_gen_imsi(imsi_suffix),
522 msisdn := f_gen_msisdn(imsi_suffix),
523 p_tmsi := omit,
524 p_tmsi_sig := omit,
525 tlli := f_gprs_tlli_random(),
526 tlli_old := omit,
527 ra := omit,
Harald Welte16357a92020-11-17 18:20:00 +0100528 pcu := g_pcu,
Harald Welte3dd21b32020-11-17 19:21:00 +0100529 sgsn := g_sgsn,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200530 t_guard := t_guard
531 };
532
533 vc_conn := BSSGP_ConnHdlr.create(id);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200534
535 vc_conn.start(f_handler_init(fn, id, pars));
536 return vc_conn;
537}
538
Harald Welte3dd21b32020-11-17 19:21:00 +0100539/* Connect the PCU-side per-BVC ports (PCU/PCU_SIG/PCU_PROC) array slot 'port_idx' to specified per-BVC component */
Harald Welte0e188242020-11-22 21:46:48 +0100540private function f_connect_to_pcu_bvc(integer port_idx, integer nse_idx, integer bvc_idx)
541runs on BSSGP_ConnHdlr {
542 var BSSGP_BVC_CT bvc_ct := g_pars.pcu[nse_idx].vc_BSSGP_BVC[bvc_idx]
Harald Welte3dd21b32020-11-17 19:21:00 +0100543 if (PCU[port_idx].checkstate("Connected")) {
544 /* unregister + disconnect from old BVC */
545 f_client_unregister(g_pars.imsi, PCU_PROC[port_idx]);
546 disconnect(self:PCU[port_idx], pcu_ct[port_idx]:BSSGP_SP);
547 disconnect(self:PCU_SIG[port_idx], pcu_ct[port_idx]:BSSGP_SP_SIG);
548 disconnect(self:PCU_PROC[port_idx], pcu_ct[port_idx]:BSSGP_PROC);
549 }
550 /* connect to new BVC and register us */
551 connect(self:PCU[port_idx], bvc_ct:BSSGP_SP);
552 connect(self:PCU_SIG[port_idx], bvc_ct:BSSGP_SP_SIG);
553 connect(self:PCU_PROC[port_idx], bvc_ct:BSSGP_PROC);
554 f_client_register(g_pars.imsi, g_pars.tlli, PCU_PROC[port_idx]);
555 pcu_ct[port_idx] := bvc_ct;
Harald Welte0e188242020-11-22 21:46:48 +0100556 pcu_bvc_cfg[port_idx] := g_pars.pcu[nse_idx].cfg.bvc[bvc_idx];
Harald Welte3dd21b32020-11-17 19:21:00 +0100557}
558
559/* Connect the SGSN-side per-BVC ports (SGSN/SGSN_SIG/SGSN_PROC) array slot 'port_idx' to specified per-BVC component */
560private function f_connect_to_sgsn_bvc(integer port_idx, BSSGP_BVC_CT bvc_ct) runs on BSSGP_ConnHdlr {
561 if (SGSN[port_idx].checkstate("Connected")) {
562 /* unregister + disconnect from old BVC */
563 f_client_unregister(g_pars.imsi, SGSN_PROC[port_idx]);
564 disconnect(self:SGSN[port_idx], sgsn_ct[port_idx]:BSSGP_SP);
565 disconnect(self:SGSN_SIG[port_idx], sgsn_ct[port_idx]:BSSGP_SP_SIG);
566 disconnect(self:SGSN_PROC[port_idx], sgsn_ct[port_idx]:BSSGP_PROC);
567 }
568 /* connect to new BVC and register us */
569 connect(self:SGSN[port_idx], bvc_ct:BSSGP_SP);
570 connect(self:SGSN_SIG[port_idx], bvc_ct:BSSGP_SP_SIG);
571 connect(self:SGSN_PROC[port_idx], bvc_ct:BSSGP_PROC);
572 f_client_register(g_pars.imsi, g_pars.tlli, SGSN_PROC[port_idx]);
573 sgsn_ct[port_idx] := bvc_ct;
574}
575
Daniel Willmann423d8f42020-09-08 18:58:22 +0200576private altstep as_Tguard() runs on BSSGP_ConnHdlr {
577 [] g_Tguard.timeout {
578 setverdict(fail, "Tguard timeout");
579 mtc.stop;
580 }
581}
582
583/* first function called in every ConnHdlr */
584private function f_handler_init(void_fn fn, charstring id, BSSGP_ConnHdlrPars pars)
585runs on BSSGP_ConnHdlr {
Harald Welte1e834f32020-11-15 20:02:59 +0100586 var integer i;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200587 /* do some common stuff like setting up g_pars */
588 g_pars := pars;
589
590 llc := f_llc_create(false);
591
Harald Welte3dd21b32020-11-17 19:21:00 +0100592 /* default connections on PCU side: First BVC of each NSE/PCU */
593 for (i := 0; i < lengthof(g_pars.pcu); i := i+1) {
Harald Welte0e188242020-11-22 21:46:48 +0100594 f_connect_to_pcu_bvc(port_idx := i, nse_idx := i, bvc_idx := 0);
Harald Welte1e834f32020-11-15 20:02:59 +0100595 }
Harald Welte3dd21b32020-11-17 19:21:00 +0100596
597 /* default connections on SGSN side: First BVC of each NSE/SGSN */
598 for (i := 0; i < lengthof(g_pars.sgsn); i := i+1) {
599 f_connect_to_sgsn_bvc(i, g_pars.sgsn[i].vc_BSSGP_BVC[0]);
Harald Welte1e834f32020-11-15 20:02:59 +0100600 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200601
602 g_Tguard.start(pars.t_guard);
603 activate(as_Tguard());
604
605 /* call the user-supplied test case function */
606 fn.apply(id);
607}
608
Harald Welte1e834f32020-11-15 20:02:59 +0100609private function f_client_register(hexstring imsi, OCT4 tlli, BSSGP_PROC_PT PT)
610runs on BSSGP_ConnHdlr {
611 PT.call(BSSGP_register_client:{imsi, tlli}) {
612 [] PT.getreply(BSSGP_register_client:{imsi, tlli}) {};
613 }
614}
615
616private function f_client_unregister(hexstring imsi, BSSGP_PROC_PT PT)
617runs on BSSGP_ConnHdlr {
618 PT.call(BSSGP_unregister_client:{imsi}) {
619 [] PT.getreply(BSSGP_unregister_client:{imsi}) {};
620 }
621}
622
Harald Welte22ef5d92020-11-16 13:35:14 +0100623/* Send 'tx' on PTP-BVCI from PCU; expect 'rx' on SGSN */
624friend function f_pcu2sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
Daniel Willmann4798fd72020-11-24 16:23:29 +0100625 integer pcu_idx := 0, integer sgsn_idx := 0, boolean use_sig := false) runs on BSSGP_ConnHdlr {
Harald Welte22ef5d92020-11-16 13:35:14 +0100626 var PDU_BSSGP rx;
627 timer T := 1.0;
628
Daniel Willmann4798fd72020-11-24 16:23:29 +0100629 if (use_sig) {
630 PCU_SIG[pcu_idx].send(tx);
631 } else {
632 PCU[pcu_idx].send(tx);
633 }
634
Harald Welte22ef5d92020-11-16 13:35:14 +0100635 T.start;
636 alt {
Daniel Willmann4798fd72020-11-24 16:23:29 +0100637 [use_sig] SGSN_SIG[sgsn_idx].receive(exp_rx) {
638 setverdict(pass);
639 }
640 [not use_sig] SGSN[sgsn_idx].receive(exp_rx) {
Harald Welte22ef5d92020-11-16 13:35:14 +0100641 setverdict(pass);
642 }
643 [] SGSN[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
644 setverdict(fail, "Unexpected BSSGP on SGSN side: ", rx);
645 mtc.stop;
646 }
Daniel Willmann4798fd72020-11-24 16:23:29 +0100647 [] SGSN_SIG[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
648 setverdict(fail, "Unexpected SIG BSSGP on SGSN side: ", rx);
649 mtc.stop;
650 }
Harald Welte22ef5d92020-11-16 13:35:14 +0100651 [] T.timeout {
Harald Welte8b326412020-11-29 16:05:38 +0100652 setverdict(fail, "Timeout waiting for BSSGP on SGSN side: ", exp_rx);
Harald Welte22ef5d92020-11-16 13:35:14 +0100653 mtc.stop;
654 }
655 }
656}
657
658/* Send 'tx' on PTP-BVCI from SGSN; expect 'rx' on PCU */
659friend function f_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
Daniel Willmann4798fd72020-11-24 16:23:29 +0100660 integer sgsn_idx:= 0, integer pcu_idx := 0, boolean use_sig := false) runs on BSSGP_ConnHdlr {
Harald Welte22ef5d92020-11-16 13:35:14 +0100661 var PDU_BSSGP rx;
662 timer T := 1.0;
663
Daniel Willmann4798fd72020-11-24 16:23:29 +0100664 if (use_sig) {
665 SGSN_SIG[sgsn_idx].send(tx);
666 } else {
667 SGSN[sgsn_idx].send(tx);
668 }
669
Harald Welte22ef5d92020-11-16 13:35:14 +0100670 T.start;
671 alt {
Daniel Willmann4798fd72020-11-24 16:23:29 +0100672 [use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
673 setverdict(pass);
674 }
675 [not use_sig] PCU[pcu_idx].receive(exp_rx) {
Harald Welte22ef5d92020-11-16 13:35:14 +0100676 setverdict(pass);
677 }
678 [] PCU[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
679 setverdict(fail, "Unexpected BSSGP on PCU side: ", rx);
680 mtc.stop;
681 }
Daniel Willmann4798fd72020-11-24 16:23:29 +0100682 [] PCU_SIG[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
683 setverdict(fail, "Unexpected SIG BSSGP on PCU side: ", rx);
684 mtc.stop;
685 }
Harald Welte22ef5d92020-11-16 13:35:14 +0100686 [] T.timeout {
Harald Welte8b326412020-11-29 16:05:38 +0100687 setverdict(fail, "Timeout waiting for BSSGP on PCU side: ", exp_rx);
Harald Welte22ef5d92020-11-16 13:35:14 +0100688 mtc.stop;
689 }
690 }
691}
Harald Welte1e834f32020-11-15 20:02:59 +0100692
Harald Welte3807ed12020-11-24 19:05:22 +0100693/***********************************************************************
694 * GlobaLTest_CT: Using the per-NSE GLOBAL ports on PCU + SGSN side
695 ***********************************************************************/
696
697type component GlobalTest_CT extends test_CT {
698 port BSSGP_PT G_PCU[NUM_PCU];
699 port BSSGP_PT G_SGSN[NUM_SGSN];
700};
701
702private function f_global_init() runs on GlobalTest_CT {
703 var integer i;
704 for (i := 0; i < lengthof(g_sgsn); i := i+1) {
705 connect(self:G_SGSN[i], g_sgsn[i].vc_BSSGP:GLOBAL);
706 }
707 for (i := 0; i < lengthof(g_pcu); i := i+1) {
708 connect(self:G_PCU[i], g_pcu[i].vc_BSSGP:GLOBAL);
709 }
710}
711
712/* Send 'tx' on PTP-BVCI from PCU; expect 'rx' on SGSN */
713friend function f_global_pcu2sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
714 integer pcu_idx := 0, integer sgsn_idx := 0) runs on GlobalTest_CT {
715 var PDU_BSSGP rx;
716 timer T := 1.0;
717
718 G_PCU[pcu_idx].send(tx);
719 T.start;
720 alt {
721 [] G_SGSN[sgsn_idx].receive(exp_rx) {
722 setverdict(pass);
723 }
724 [] G_SGSN[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
725 setverdict(fail, "Unexpected BSSGP on SGSN side: ", rx);
726 mtc.stop;
727 }
728 [] T.timeout {
729 setverdict(fail, "Timeout waiting for BSSGP on SGSN side: ", rx);
730 mtc.stop;
731 }
732 }
733}
734
735/* Send 'tx' on PTP-BVCI from SGSN; expect 'rx' on PCU */
736friend function f_global_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
737 integer sgsn_idx := 0, integer pcu_idx := 0) runs on GlobalTest_CT {
738 var PDU_BSSGP rx;
739 timer T := 1.0;
740
741 G_SGSN[sgsn_idx].send(tx);
742 T.start;
743 alt {
744 [] G_PCU[pcu_idx].receive(exp_rx) {
745 setverdict(pass);
746 }
747 [] G_PCU[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
748 setverdict(fail, "Unexpected BSSGP on PCU side: ", rx);
749 mtc.stop;
750 }
751 [] T.timeout {
752 setverdict(fail, "Timeout waiting for BSSGP on PCU side: ", rx);
753 mtc.stop;
754 }
755 }
756}
757
758
Daniel Willmann423d8f42020-09-08 18:58:22 +0200759/* TODO:
760 * Detach without Attach
761 * SM procedures without attach / RAU
762 * ATTACH / RAU
763 ** with / without authentication
764 ** with / without P-TMSI allocation
765 * re-transmissions of LLC frames
766 * PDP Context activation
767 ** with different GGSN config in SGSN VTY
768 ** with different PDP context type (v4/v6/v46)
769 ** timeout from GGSN
770 ** multiple / secondary PDP context
771 */
772
773private function f_TC_BVC_bringup(charstring id) runs on BSSGP_ConnHdlr {
774 f_sleep(5.0);
775 setverdict(pass);
776}
777
778testcase TC_BVC_bringup() runs on test_CT {
779 var BSSGP_ConnHdlr vc_conn;
780 f_init();
781
782 vc_conn := f_start_handler(refers(f_TC_BVC_bringup), testcasename(), g_pcu, g_sgsn, 51);
783 vc_conn.done;
784
785 f_cleanup();
786}
787
788friend function f_bssgp_suspend(integer ran_idx := 0) runs on BSSGP_ConnHdlr return OCT1 {
Harald Welte16357a92020-11-17 18:20:00 +0100789 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200790 timer T := 5.0;
791 var PDU_BSSGP rx_pdu;
Harald Welte16357a92020-11-17 18:20:00 +0100792 PCU_SIG[ran_idx].send(ts_BSSGP_SUSPEND(g_pars.tlli, bvcc.cell_id.ra_id));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200793 T.start;
794 alt {
Harald Welte16357a92020-11-17 18:20:00 +0100795 [] PCU_SIG[ran_idx].receive(tr_BSSGP_SUSPEND_ACK(g_pars.tlli, bvcc.cell_id.ra_id, ?)) -> value rx_pdu {
Daniel Willmann423d8f42020-09-08 18:58:22 +0200796 return rx_pdu.pDU_BSSGP_SUSPEND_ACK.suspend_Reference_Number.suspend_Reference_Number_value;
797 }
Harald Welte16357a92020-11-17 18:20:00 +0100798 [] PCU_SIG[ran_idx].receive(tr_BSSGP_SUSPEND_NACK(g_pars.tlli, bvcc.cell_id.ra_id, ?)) -> value rx_pdu {
Daniel Willmann423d8f42020-09-08 18:58:22 +0200799 setverdict(fail, "SUSPEND-NACK in response to SUSPEND for TLLI ", g_pars.tlli);
800 mtc.stop;
801 }
802 [] T.timeout {
803 setverdict(fail, "No SUSPEND-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
804 mtc.stop;
805 }
806 }
807 return '00'O;
808}
809
810friend function f_bssgp_resume(OCT1 susp_ref, integer ran_idx := 0) runs on BSSGP_ConnHdlr {
Harald Welte16357a92020-11-17 18:20:00 +0100811 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200812 timer T := 5.0;
Harald Welte16357a92020-11-17 18:20:00 +0100813 PCU_SIG[ran_idx].send(ts_BSSGP_RESUME(g_pars.tlli, bvcc.cell_id.ra_id, susp_ref));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200814 T.start;
815 alt {
Harald Welte16357a92020-11-17 18:20:00 +0100816 [] PCU_SIG[ran_idx].receive(tr_BSSGP_RESUME_ACK(g_pars.tlli, bvcc.cell_id.ra_id));
817 [] PCU_SIG[ran_idx].receive(tr_BSSGP_RESUME_NACK(g_pars.tlli, bvcc.cell_id.ra_id, ?)) {
Daniel Willmann423d8f42020-09-08 18:58:22 +0200818 setverdict(fail, "RESUME-NACK in response to RESUME for TLLI ", g_pars.tlli);
819 mtc.stop;
820 }
821 [] T.timeout {
822 setverdict(fail, "No RESUME-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
823 mtc.stop;
824 }
825 }
826}
827
828
Harald Welte92686012020-11-15 21:45:49 +0100829/* send uplink-unitdata of a variety of different sizes; expect it to show up on SGSN */
830private function f_TC_ul_unitdata(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte16357a92020-11-17 18:20:00 +0100831 var integer ran_idx := 0;
832 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Harald Welte92686012020-11-15 21:45:49 +0100833 var integer i;
834
Harald Welte0d5fceb2020-11-29 16:04:07 +0100835 for (i := 0; i < max_fr_info_size-4; i := i+4) {
Harald Welte92686012020-11-15 21:45:49 +0100836 var octetstring payload := f_rnd_octstring(i);
Harald Welte16357a92020-11-17 18:20:00 +0100837 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_UL_UD(g_pars.tlli, bvcc.cell_id, payload);
Harald Welte92686012020-11-15 21:45:49 +0100838 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte16357a92020-11-17 18:20:00 +0100839 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_UL_UD(g_pars.tlli, bvcc.cell_id, payload);
Harald Welte92686012020-11-15 21:45:49 +0100840
Harald Welte0d5fceb2020-11-29 16:04:07 +0100841 log("UL-UNITDATA(payload_size=", i);
Harald Welte22ef5d92020-11-16 13:35:14 +0100842 f_pcu2sgsn(pdu_tx, pdu_rx);
Harald Welte92686012020-11-15 21:45:49 +0100843 }
844 setverdict(pass);
845}
846
847testcase TC_ul_unitdata() runs on test_CT
848{
849 var BSSGP_ConnHdlr vc_conn;
850 f_init();
851
852 vc_conn := f_start_handler(refers(f_TC_ul_unitdata), testcasename(), g_pcu, g_sgsn, 1);
853 vc_conn.done;
854 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
855
856 f_cleanup();
857}
858
Harald Welte78d8db92020-11-15 23:27:27 +0100859/* send downlink-unitdata of a variety of different sizes; expect it to show up on PCU */
860private function f_TC_dl_unitdata(charstring id) runs on BSSGP_ConnHdlr {
861 var integer i;
862
Harald Welte0d5fceb2020-11-29 16:04:07 +0100863 for (i := 0; i < max_fr_info_size-4; i := i+4) {
Harald Welte78d8db92020-11-15 23:27:27 +0100864 var octetstring payload := f_rnd_octstring(i);
865 var template (value) PDU_BSSGP pdu_tx :=
866 ts_BSSGP_DL_UD(g_pars.tlli, payload, omit, ts_BSSGP_IMSI(g_pars.imsi));
867 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
868 var template (present) PDU_BSSGP pdu_rx :=
869 tr_BSSGP_DL_UD(g_pars.tlli, payload, tr_BSSGP_IMSI(g_pars.imsi));
870
Harald Welte0d5fceb2020-11-29 16:04:07 +0100871 log("DL-UNITDATA(payload_size=", i);
Harald Welte22ef5d92020-11-16 13:35:14 +0100872 f_sgsn2pcu(pdu_tx, pdu_rx);
Harald Welte78d8db92020-11-15 23:27:27 +0100873 }
874 setverdict(pass);
875}
876
877testcase TC_dl_unitdata() runs on test_CT
878{
879 var BSSGP_ConnHdlr vc_conn;
880 f_init();
881
882 vc_conn := f_start_handler(refers(f_TC_dl_unitdata), testcasename(), g_pcu, g_sgsn, 2);
883 vc_conn.done;
884 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
885
886 f_cleanup();
887}
Harald Welte92686012020-11-15 21:45:49 +0100888
Harald Welte6dc2ac42020-11-16 09:16:17 +0100889private function f_TC_ra_capability(charstring id) runs on BSSGP_ConnHdlr {
890 var integer i;
891
892 for (i := 0; i < 10; i := i+1) {
893 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RA_CAP(g_pars.tlli, { ts_RaCapRec_BSSGP });
894 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
895 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RA_CAP(g_pars.tlli, { tr_RaCapRec_BSSGP })
896
Harald Welte22ef5d92020-11-16 13:35:14 +0100897 f_sgsn2pcu(pdu_tx, pdu_rx);
Harald Welte6dc2ac42020-11-16 09:16:17 +0100898 }
899 setverdict(pass);
900}
901testcase TC_ra_capability() runs on test_CT
902{
903 var BSSGP_ConnHdlr vc_conn;
904 f_init();
905
906 vc_conn := f_start_handler(refers(f_TC_ra_capability), testcasename(), g_pcu, g_sgsn, 3);
907 vc_conn.done;
908 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
909
910 f_cleanup();
911}
912
Daniel Willmannace3ece2020-11-16 19:53:26 +0100913private function f_TC_ra_capability_upd(charstring id) runs on BSSGP_ConnHdlr {
914 var integer i;
915 var OCT1 tag;
916 for (i := 0; i < 10; i := i+1) {
917 tag := int2oct(23 + i, 1);
918 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RA_CAP_UPD(g_pars.tlli, tag);
919 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
920 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RA_CAP_UPD(g_pars.tlli, tag)
921
922 f_pcu2sgsn(pdu_tx, pdu_rx);
923
924 pdu_tx := ts_BSSGP_RA_CAP_UPD_ACK(g_pars.tlli, tag, '42'O);
925 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
926 pdu_rx := tr_BSSGP_RA_CAP_UPD_ACK(g_pars.tlli, tag, '42'O)
927
928 f_sgsn2pcu(pdu_tx, pdu_rx);
929 }
930 setverdict(pass);
931}
932testcase TC_ra_capability_upd() runs on test_CT
933{
934 var BSSGP_ConnHdlr vc_conn;
935 f_init();
936
Daniel Willmann54833f22020-11-19 15:43:52 +0100937 vc_conn := f_start_handler(refers(f_TC_ra_capability_upd), testcasename(), g_pcu, g_sgsn, 4);
Daniel Willmannace3ece2020-11-16 19:53:26 +0100938 vc_conn.done;
939 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
940
941 f_cleanup();
942}
943
Daniel Willmann165d6612020-11-19 14:27:29 +0100944private function f_TC_radio_status(charstring id) runs on BSSGP_ConnHdlr {
945 var integer i;
946 var BssgpRadioCause cause := BSSGP_RADIO_CAUSE_CONTACT_LOST;
947 for (i := 0; i < 10; i := i+1) {
948 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RADIO_STATUS(g_pars.tlli, cause);
949 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
950 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RADIO_STATUS(g_pars.tlli, cause)
951
952 f_pcu2sgsn(pdu_tx, pdu_rx);
953 }
954 setverdict(pass);
955}
956testcase TC_radio_status() runs on test_CT
957{
958 var BSSGP_ConnHdlr vc_conn;
959 f_init();
960
Daniel Willmann54833f22020-11-19 15:43:52 +0100961 vc_conn := f_start_handler(refers(f_TC_radio_status), testcasename(), g_pcu, g_sgsn, 5);
Daniel Willmann165d6612020-11-19 14:27:29 +0100962 vc_conn.done;
963 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
964
965 f_cleanup();
966}
967
Harald Welte3807ed12020-11-24 19:05:22 +0100968private function f_TC_suspend() runs on GlobalTest_CT {
Daniel Willmannfa67f492020-11-19 15:48:05 +0100969 var integer i;
Daniel Willmann165d6612020-11-19 14:27:29 +0100970
Daniel Willmannfa67f492020-11-19 15:48:05 +0100971 /* TODO: Generate RA ID for each ConnHdlr */
Harald Welte3807ed12020-11-24 19:05:22 +0100972 var RoutingAreaIdentification ra_id := g_pcu[0].cfg.bvc[0].cell_id.ra_id;
Daniel Willmannfa67f492020-11-19 15:48:05 +0100973 for (i := 0; i < 10; i := i+1) {
Harald Welte3807ed12020-11-24 19:05:22 +0100974 var OCT4 tlli := f_gprs_tlli_random();
975 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_SUSPEND(tlli, ra_id);
Daniel Willmannfa67f492020-11-19 15:48:05 +0100976 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +0100977 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_SUSPEND(tlli, ra_id);
Daniel Willmannfa67f492020-11-19 15:48:05 +0100978
Harald Welte3807ed12020-11-24 19:05:22 +0100979 f_global_pcu2sgsn(pdu_tx, pdu_rx);
Daniel Willmannfa67f492020-11-19 15:48:05 +0100980
Harald Welte3807ed12020-11-24 19:05:22 +0100981 pdu_tx := ts_BSSGP_SUSPEND_ACK(tlli, ra_id, int2oct(i, 1));
Daniel Willmannfa67f492020-11-19 15:48:05 +0100982 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +0100983 pdu_rx := tr_BSSGP_SUSPEND_ACK(tlli, ra_id, int2oct(i, 1));
Daniel Willmannfa67f492020-11-19 15:48:05 +0100984
Harald Welte3807ed12020-11-24 19:05:22 +0100985 f_global_sgsn2pcu(pdu_tx, pdu_rx);
Daniel Willmannfa67f492020-11-19 15:48:05 +0100986
987 /* These messages are simple passed through so just also test sending NACK */
Harald Welte3807ed12020-11-24 19:05:22 +0100988 pdu_tx := ts_BSSGP_SUSPEND_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
Daniel Willmannfa67f492020-11-19 15:48:05 +0100989 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +0100990 pdu_rx := tr_BSSGP_SUSPEND_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
Daniel Willmannfa67f492020-11-19 15:48:05 +0100991
Harald Welte3807ed12020-11-24 19:05:22 +0100992 f_global_sgsn2pcu(pdu_tx, pdu_rx);
Daniel Willmannfa67f492020-11-19 15:48:05 +0100993 }
994 setverdict(pass);
995}
Harald Welte3807ed12020-11-24 19:05:22 +0100996testcase TC_suspend() runs on GlobalTest_CT
Daniel Willmannfa67f492020-11-19 15:48:05 +0100997{
Daniel Willmannfa67f492020-11-19 15:48:05 +0100998 f_init();
Harald Welte3807ed12020-11-24 19:05:22 +0100999 f_global_init();
1000 f_TC_suspend();
Daniel Willmannfa67f492020-11-19 15:48:05 +01001001 f_cleanup();
1002}
Harald Welte6dc2ac42020-11-16 09:16:17 +01001003
Harald Welte3807ed12020-11-24 19:05:22 +01001004private function f_TC_resume() runs on GlobalTest_CT {
Daniel Willmann087a33d2020-11-19 15:58:43 +01001005 var integer i;
1006
1007 /* TODO: Generate RA ID for each ConnHdlr */
Harald Welte3807ed12020-11-24 19:05:22 +01001008 var RoutingAreaIdentification ra_id := g_pcu[0].cfg.bvc[0].cell_id.ra_id;
Daniel Willmann087a33d2020-11-19 15:58:43 +01001009 for (i := 0; i < 10; i := i+1) {
Harald Welte3807ed12020-11-24 19:05:22 +01001010 var OCT4 tlli := f_gprs_tlli_random();
1011 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RESUME(tlli, ra_id, int2oct(i, 1));
Daniel Willmann087a33d2020-11-19 15:58:43 +01001012 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +01001013 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RESUME(tlli, ra_id, int2oct(i, 1));
Daniel Willmann087a33d2020-11-19 15:58:43 +01001014
Harald Welte3807ed12020-11-24 19:05:22 +01001015 f_global_pcu2sgsn(pdu_tx, pdu_rx);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001016
Harald Welte3807ed12020-11-24 19:05:22 +01001017 pdu_tx := ts_BSSGP_RESUME_ACK(tlli, ra_id);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001018 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +01001019 pdu_rx := tr_BSSGP_RESUME_ACK(tlli, ra_id);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001020
Harald Welte3807ed12020-11-24 19:05:22 +01001021 f_global_sgsn2pcu(pdu_tx, pdu_rx);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001022
1023 /* These messages are simple passed through so just also test sending NACK */
Harald Welte3807ed12020-11-24 19:05:22 +01001024 pdu_tx := ts_BSSGP_RESUME_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001025 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +01001026 pdu_rx := tr_BSSGP_RESUME_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001027
Harald Welte3807ed12020-11-24 19:05:22 +01001028 f_global_sgsn2pcu(pdu_tx, pdu_rx);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001029 }
1030 setverdict(pass);
1031}
Harald Welte3807ed12020-11-24 19:05:22 +01001032testcase TC_resume() runs on GlobalTest_CT
Daniel Willmann087a33d2020-11-19 15:58:43 +01001033{
Daniel Willmann087a33d2020-11-19 15:58:43 +01001034 f_init();
Harald Welte3807ed12020-11-24 19:05:22 +01001035 f_global_init();
1036 f_TC_resume();
Daniel Willmann087a33d2020-11-19 15:58:43 +01001037 f_cleanup();
1038}
1039
Harald Weltef8ef0282020-11-18 12:16:59 +01001040/* test the load-sharing between multiple NS-VC on the BSS side */
1041private function f_TC_dl_ud_unidir(charstring id) runs on BSSGP_ConnHdlr {
1042 var integer i;
1043
1044 for (i := 0; i < 10; i := i+1) {
1045 var octetstring payload := f_rnd_octstring(i);
1046 var template (value) PDU_BSSGP pdu_tx :=
1047 ts_BSSGP_DL_UD(g_pars.tlli, payload, omit, ts_BSSGP_IMSI(g_pars.imsi));
1048 SGSN[0].send(pdu_tx);
1049 }
1050 setverdict(pass);
1051}
1052testcase TC_load_sharing_dl() runs on test_CT_NS
1053{
1054 const integer num_ue := 10;
1055 var BSSGP_ConnHdlr vc_conn[num_ue];
1056 f_init();
1057
1058 /* all BVC are now fully brought up. We disconnect BSSGP from NS on the BSS
1059 * side so we get the raw NsUnitdataIndication and hence observe different
1060 * NSVCI */
1061 disconnect(g_pcu[0].vc_NS:NS_SP, g_pcu[0].vc_BSSGP:BSCP);
1062 connect(g_pcu[0].vc_NS:NS_SP, self:NS);
1063
1064 /* there may still be some NS-VCs coming up? After all, the BVC-RESET succeeds after the first
1065 * of the NS-VC is ALIVE/UNBLOCKED */
1066 f_sleep(3.0);
1067
1068 /* start parallel components generating DL-UNITDATA from the SGSN side */
1069 for (var integer i:= 0; i < num_ue; i := i+1) {
1070 vc_conn[i] := f_start_handler(refers(f_TC_dl_ud_unidir), testcasename(), g_pcu, g_sgsn, 5+i);
1071 }
1072
1073 /* now start counting all the messages that were queued before */
1074 /* TODO: We have a hard-coded assumption of 4 NS-VC in one NSE/NS-VCG here! */
1075 var ro_integer rx_count := { 0, 0, 0, 0 };
1076 timer T := 2.0;
1077 T.start;
1078 alt {
1079 [] as_NsUdiCount(0, rx_count);
1080 [] as_NsUdiCount(1, rx_count);
1081 [] as_NsUdiCount(2, rx_count);
1082 [] as_NsUdiCount(3, rx_count);
1083 [] NS.receive(NsUnitdataIndication:{0,?,?,*,*}) { repeat; } /* signaling BVC */
1084 [] NS.receive(NsStatusIndication:?) { repeat; }
1085 [] NS.receive {
1086 setverdict(fail, "Rx unexpected NS");
1087 mtc.stop;
1088 }
1089 [] T.timeout {
1090 }
1091 }
1092 for (var integer i := 0; i < lengthof(rx_count); i := i+1) {
1093 log("Rx on NSVCI ", mp_nsconfig_pcu[0].nsvc[i].nsvci, ": ", rx_count[i]);
1094 if (rx_count[i] == 0) {
1095 setverdict(fail, "Data not shared over all NSVC");
1096 }
1097 }
1098 setverdict(pass);
1099}
1100private altstep as_NsUdiCount(integer nsvc_idx, inout ro_integer roi) runs on test_CT_NS {
1101 var NsUnitdataIndication udi;
1102 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[0];
1103 [] NS.receive(NsUnitdataIndication:{bvcc.bvci, g_pcu[0].cfg.nsei, mp_nsconfig_pcu[0].nsvc[nsvc_idx].nsvci, *, *}) -> value udi {
1104 roi[nsvc_idx] := roi[nsvc_idx] + 1;
1105 repeat;
1106 }
1107}
1108type component test_CT_NS extends test_CT {
1109 port NS_PT NS;
1110};
1111
1112
Harald Welte0e188242020-11-22 21:46:48 +01001113/***********************************************************************
1114 * PAGING PS procedure
1115 ***********************************************************************/
1116
1117private function f_send_paging_ps(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1118 boolean use_sig := false)
1119runs on BSSGP_ConnHdlr return template (present) PDU_BSSGP {
1120 var template (value) PDU_BSSGP pdu_tx;
1121 var template (present) PDU_BSSGP pdu_rx;
1122 /* we always specify '0' as BVCI in the templates below, as we override it with
1123 * 'p4' later anyway */
1124 pdu_rx := tr_BSSGP_PS_PAGING(0);
1125 pdu_rx.pDU_BSSGP_PAGING_PS.iMSI := tr_BSSGP_IMSI(g_pars.imsi);
1126 if (ispresent(g_pars.p_tmsi)) {
1127 pdu_tx := ts_BSSGP_PS_PAGING_PTMSI(0, g_pars.imsi, oct2int(g_pars.p_tmsi));
1128 pdu_rx.pDU_BSSGP_PAGING_PS.pTMSI := tr_BSSGP_TMSI(oct2int(g_pars.p_tmsi));
1129 } else {
1130 pdu_tx := ts_BSSGP_PS_PAGING_IMSI(0, g_pars.imsi);
1131 pdu_rx.pDU_BSSGP_PAGING_PS.pTMSI := omit;
1132 }
1133 pdu_tx.pDU_BSSGP_PAGING_PS.paging_Field4 := p4;
1134 pdu_rx.pDU_BSSGP_PAGING_PS.paging_Field4 := p4;
1135 if (use_sig == false) {
1136 SGSN[sgsn_idx].send(pdu_tx);
1137 } else {
1138 SGSN_SIG[sgsn_idx].send(pdu_tx);
1139 }
1140 return pdu_rx;
1141}
1142
1143/* send paging defined by 'p4' on given SGSN-side index (ptp or signaling) and expect one paging to arrive on
1144 * specified PCU index */
1145private function f_send_paging_ps_exp_one_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1146 boolean use_sig := false,integer pcu_idx := 0)
1147runs on BSSGP_ConnHdlr {
1148 var template (present) PDU_BSSGP exp_rx;
Daniel Willmann1a859712020-12-04 00:59:45 +01001149 var boolean test_done := false;
Harald Welte0e188242020-11-22 21:46:48 +01001150 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1151 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1152 exp_rx := f_send_paging_ps(p4, sgsn_idx, use_sig);
1153 /* Expect paging to propagate to the one BSS addressed by the BVCI only */
1154 timer T := 2.0;
1155 T.start;
1156 alt {
Daniel Willmann1a859712020-12-04 00:59:45 +01001157 [not use_sig and not test_done] PCU[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001158 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001159 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001160 repeat;
1161 }
1162 [not use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
1163 setverdict(fail, "Received paging on SIGNALING BVC, expected PTP BVC");
1164 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001165 [use_sig and not test_done] PCU_SIG[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001166 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001167 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001168 repeat;
1169 }
1170 [use_sig] PCU[pcu_idx].receive(exp_rx) {
1171 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1172 }
1173 [] any from PCU.receive(exp_rx) {
1174 setverdict(fail, "Paging received on unexpected BVC");
1175 }
1176 [] any from PCU_SIG.receive(exp_rx) {
1177 setverdict(fail, "Paging received on unexpected BVC");
1178 }
1179 [] any from PCU.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1180 setverdict(fail, "Different Paging than expected received PTP BVC");
1181 }
1182 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1183 setverdict(fail, "Different Paging than expected on SIGNALING BVC");
1184 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001185 [not test_done] T.timeout {
1186 setverdict(fail, "Timeout waiting for paging");
1187 }
1188 [test_done] T.timeout;
Harald Welte0e188242020-11-22 21:46:48 +01001189 }
1190}
1191
Harald Welte7462a592020-11-23 22:07:07 +01001192/* send a PS-PAGING but don't expect it to show up on any PTP or SIG BVC */
1193private function f_send_paging_ps_exp_no_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1194 boolean use_sig := false)
1195runs on BSSGP_ConnHdlr {
1196 var template (present) PDU_BSSGP exp_rx;
1197 exp_rx := f_send_paging_ps(p4, sgsn_idx, use_sig);
1198 /* Expect paging to propagate to no BSS */
1199 timer T := 2.0;
1200 T.start;
1201 alt {
1202 [] any from PCU.receive(exp_rx) {
1203 setverdict(fail, "Paging received on unexpected BVC");
1204 }
1205 [] any from PCU_SIG.receive(exp_rx) {
1206 setverdict(fail, "Paging received on unexpected BVC");
1207 }
1208 [] any from PCU.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1209 setverdict(fail, "Different Paging received on PTP BVC");
1210 }
1211 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1212 setverdict(fail, "Different Paging received on SIGNALING BVC");
1213 }
1214 [] T.timeout {
1215 setverdict(pass);
1216 }
1217 }
1218}
1219
Harald Welte0e188242020-11-22 21:46:48 +01001220private function f_TC_paging_ps_ptp_bss(charstring id) runs on BSSGP_ConnHdlr
1221{
1222 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1223 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1224 f_send_paging_ps_exp_one_bss(ts_BssgpP4BssArea, 0, false, 0);
1225}
1226testcase TC_paging_ps_ptp_bss() runs on test_CT {
1227 var BSSGP_ConnHdlr vc_conn;
1228 f_init();
1229
1230 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_bss), testcasename(), g_pcu, g_sgsn, 9);
1231 vc_conn.done;
1232
1233 f_cleanup();
1234}
1235
1236/* PS-PAGING on PTP-BVC for Location Area */
1237private function f_TC_paging_ps_ptp_lac(charstring id) runs on BSSGP_ConnHdlr
1238{
1239 var template (present) PDU_BSSGP exp_rx;
1240 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1241 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1242 f_send_paging_ps_exp_one_bss(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, false, 0);
1243}
1244testcase TC_paging_ps_ptp_lac() runs on test_CT {
1245 var BSSGP_ConnHdlr vc_conn;
1246 f_init();
1247
1248 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_lac), testcasename(), g_pcu, g_sgsn, 10);
1249 vc_conn.done;
1250
1251 f_cleanup();
1252}
1253
Harald Welte7462a592020-11-23 22:07:07 +01001254/* PS-PAGING on PTP-BVC for unknown Location Area */
1255private function f_TC_paging_ps_ptp_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1256{
1257 var GSM_Types.LocationAreaIdentification unknown_la := {
1258 mcc_mnc := '567F99'H,
1259 lac := 33333
1260 };
1261 /* as it's sent on the PTP BVC, we expect it to pass even for unknown LAC */
1262 f_send_paging_ps_exp_one_bss(ts_BssgpP4LAC(unknown_la), 0, false, 0);
1263}
1264testcase TC_paging_ps_ptp_lac_unknown() runs on test_CT {
1265 var BSSGP_ConnHdlr vc_conn;
1266 f_init();
1267
1268 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_lac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1269 vc_conn.done;
1270
1271 f_cleanup();
1272}
1273
Harald Welte0e188242020-11-22 21:46:48 +01001274/* PS-PAGING on PTP-BVC for Routeing Area */
1275private function f_TC_paging_ps_ptp_rac(charstring id) runs on BSSGP_ConnHdlr
1276{
1277 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1278 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1279 f_send_paging_ps_exp_one_bss(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, false, 0);
1280}
1281testcase TC_paging_ps_ptp_rac() runs on test_CT {
1282 var BSSGP_ConnHdlr vc_conn;
1283 f_init();
1284
1285 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_rac), testcasename(), g_pcu, g_sgsn, 11);
1286 vc_conn.done;
1287
1288 f_cleanup();
1289}
1290
Harald Welte7462a592020-11-23 22:07:07 +01001291/* PS-PAGING on PTP-BVC for unknown Routeing Area */
1292private function f_TC_paging_ps_ptp_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1293{
1294 var RoutingAreaIdentification unknown_ra := {
1295 lai := {
1296 mcc_mnc := '567F99'H,
1297 lac := 33333
1298 },
1299 rac := 254
1300 };
1301 /* as it's sent on the PTP BVC, we expect it to pass even for unknown RAC */
1302 f_send_paging_ps_exp_one_bss(ts_BssgpP4RAC(unknown_ra), 0, false, 0);
1303}
1304testcase TC_paging_ps_ptp_rac_unknown() runs on test_CT {
1305 var BSSGP_ConnHdlr vc_conn;
1306 f_init();
1307
1308 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_rac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1309 vc_conn.done;
1310
1311 f_cleanup();
1312}
1313
Harald Welte0e188242020-11-22 21:46:48 +01001314/* PS-PAGING on PTP-BVC for BVCI (one cell) */
1315private function f_TC_paging_ps_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
1316{
1317 /* this should be the normal case for MS in READY MM state after a lower layer failure */
1318 f_send_paging_ps_exp_one_bss(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, false, 0);
1319}
1320testcase TC_paging_ps_ptp_bvci() runs on test_CT {
1321 var BSSGP_ConnHdlr vc_conn;
1322 f_init();
1323
1324 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_bvci), testcasename(), g_pcu, g_sgsn, 12);
1325 vc_conn.done;
1326
1327 f_cleanup();
1328}
1329
Harald Welte7462a592020-11-23 22:07:07 +01001330/* PS-PAGING on PTP-BVC for unknown BVCI */
1331private function f_TC_paging_ps_ptp_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1332{
1333 /* as it's sent on the PTP BVC, we expect it to pass even for unknown BVCI */
1334 f_send_paging_ps_exp_one_bss(ts_BssgpP4Bvci(33333), 0, false, 0);
1335}
1336testcase TC_paging_ps_ptp_bvci_unknown() runs on test_CT {
1337 var BSSGP_ConnHdlr vc_conn;
1338 f_init();
1339
1340 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
1341 vc_conn.done;
1342
1343 f_cleanup();
1344}
1345
Harald Welte0e188242020-11-22 21:46:48 +01001346/* altstep for expecting BSSGP PDU on signaling BVC of given pcu_idx + storing in 'roi' */
1347private altstep as_paging_sig_pcu(integer pcu_idx, template (present) PDU_BSSGP exp_rx, inout ro_integer roi)
1348runs on BSSGP_ConnHdlr {
1349[] PCU_SIG[pcu_idx].receive(exp_rx) {
1350 if (ro_integer_contains(roi, pcu_idx)) {
1351 setverdict(fail, "Received multiple paging on same SIG BVC");
1352 }
1353 roi := roi & { pcu_idx };
1354 repeat;
1355 }
1356[] PCU[pcu_idx].receive(exp_rx) {
1357 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1358 }
1359[] PCU_SIG[pcu_idx].receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1360 setverdict(fail, "Different Paging than expected received SIGNALING BVC");
1361 }
1362[] PCU[pcu_idx].receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1363 setverdict(fail, "Different Paging than expected received PTP BVC");
1364 }
1365}
1366
1367type record of default ro_default;
1368
1369/* send PS-PAGING on SIG BVC, expect it to arrive on given list of PCU indexes */
1370private function f_send_paging_ps_exp_multi(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1371 ro_integer exp_on_pcu_idx) runs on BSSGP_ConnHdlr
1372{
1373 var template (present) PDU_BSSGP exp_rx;
1374 exp_rx := f_send_paging_ps(p4, 0, true);
1375
1376 /* FIXME: make sure the relevant BVCs/BSS are connected to the ports! */
1377 var ro_default defaults := {};
1378 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1379 var default d := activate(as_paging_sig_pcu(i, exp_rx, g_roi));
1380 defaults := defaults & { d };
1381 }
1382 f_sleep(2.0);
1383 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
1384 deactivate(defaults[i]);
1385 }
1386 log("Paging received on PCU ", g_roi);
1387
1388 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1389 var boolean rx_on_i := ro_integer_contains(g_roi, i);
1390 var boolean exp_on_i := ro_integer_contains(exp_on_pcu_idx, i);
1391 if (exp_on_i and not rx_on_i) {
1392 setverdict(fail, "PS-PAGING not received on ", mp_nsconfig_pcu[i].nsei);
1393 }
1394 if (not exp_on_i and rx_on_i) {
1395 setverdict(fail, "PS-PAGING not expected but received on ", mp_nsconfig_pcu[i].nsei);
1396 }
1397 }
1398 setverdict(pass);
1399}
1400
1401/* PS-PAGING on SIG-BVC for BSS Area */
1402private function f_TC_paging_ps_sig_bss(charstring id) runs on BSSGP_ConnHdlr
1403{
1404 /* we expect the paging to arrive on all three NSE */
1405 f_send_paging_ps_exp_multi(ts_BssgpP4BssArea, 0, {0, 1, 2});
1406}
1407testcase TC_paging_ps_sig_bss() runs on test_CT {
1408 var BSSGP_ConnHdlr vc_conn;
1409 f_init();
1410
1411 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_bss), testcasename(), g_pcu, g_sgsn, 13);
1412 vc_conn.done;
1413
1414 f_cleanup();
1415}
1416
1417/* PS-PAGING on SIG-BVC for Location Area */
1418private function f_TC_paging_ps_sig_lac(charstring id) runs on BSSGP_ConnHdlr
1419{
Daniel Willmann2c9300f2020-12-01 10:54:08 +01001420 /* The first LAC (13135) is shared by all three NSEs */
1421 f_send_paging_ps_exp_multi(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, {0, 1, 2});
1422 /* Reset state */
1423 g_roi := {};
1424 /* Make LAC (13300) available on pcu index 2 */
1425 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
1426 f_send_paging_ps_exp_multi(ts_BssgpP4LAC(pcu_bvc_cfg[2].cell_id.ra_id.lai), 0, {2});
Harald Welte0e188242020-11-22 21:46:48 +01001427}
1428testcase TC_paging_ps_sig_lac() runs on test_CT {
1429 var BSSGP_ConnHdlr vc_conn;
1430 f_init();
1431
1432 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_lac), testcasename(), g_pcu, g_sgsn, 14);
1433 vc_conn.done;
1434
1435 f_cleanup();
1436}
1437
Harald Welte7462a592020-11-23 22:07:07 +01001438/* PS-PAGING on SIG-BVC for unknown Location Area */
1439private function f_TC_paging_ps_sig_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1440{
1441 var GSM_Types.LocationAreaIdentification unknown_la := {
1442 mcc_mnc := '567F99'H,
1443 lac := 33333
1444 };
1445 f_send_paging_ps_exp_no_bss(ts_BssgpP4LAC(unknown_la), 0, true);
1446}
1447testcase TC_paging_ps_sig_lac_unknown() runs on test_CT {
1448 var BSSGP_ConnHdlr vc_conn;
1449 f_init();
1450
1451 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_lac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1452 vc_conn.done;
1453
1454 f_cleanup();
1455}
1456
Harald Welte0e188242020-11-22 21:46:48 +01001457/* PS-PAGING on SIG-BVC for Routeing Area */
1458private function f_TC_paging_ps_sig_rac(charstring id) runs on BSSGP_ConnHdlr
1459{
Daniel Willmann2c9300f2020-12-01 10:54:08 +01001460 /* Only PCU index 0 has a matching BVC with the RA ID */
Harald Welte0e188242020-11-22 21:46:48 +01001461 f_send_paging_ps_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, {0});
Daniel Willmann2c9300f2020-12-01 10:54:08 +01001462 g_roi := {};
1463 /* PCU index 1 and 2 have a matching BVC with the RA ID */
1464 f_send_paging_ps_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[2].cell_id.ra_id), 0, {1, 2});
1465 g_roi := {};
1466 /* PCU index 2 has two matching BVCs with the RA ID */
1467 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
1468 f_send_paging_ps_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[2].cell_id.ra_id), 0, {2});
Harald Welte0e188242020-11-22 21:46:48 +01001469}
1470testcase TC_paging_ps_sig_rac() runs on test_CT {
1471 var BSSGP_ConnHdlr vc_conn;
1472 f_init();
1473
1474 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_rac), testcasename(), g_pcu, g_sgsn, 15);
1475 vc_conn.done;
1476
1477 f_cleanup();
1478}
1479
Harald Welte7462a592020-11-23 22:07:07 +01001480/* PS-PAGING on SIG-BVC for unknown Routeing Area */
1481private function f_TC_paging_ps_sig_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1482{
1483 var RoutingAreaIdentification unknown_ra := {
1484 lai := {
1485 mcc_mnc := '567F99'H,
1486 lac := 33333
1487 },
1488 rac := 254
1489 };
1490 f_send_paging_ps_exp_no_bss(ts_BssgpP4RAC(unknown_ra), 0, true);
1491}
1492testcase TC_paging_ps_sig_rac_unknown() runs on test_CT {
1493 var BSSGP_ConnHdlr vc_conn;
1494 f_init();
1495
1496 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_rac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1497 vc_conn.done;
1498
1499 f_cleanup();
1500}
1501
Harald Welte0e188242020-11-22 21:46:48 +01001502/* PS-PAGING on SIG-BVC for BVCI (one cell) */
1503private function f_TC_paging_ps_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
1504{
1505 f_send_paging_ps_exp_multi(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, {0});
1506}
1507testcase TC_paging_ps_sig_bvci() runs on test_CT {
1508 var BSSGP_ConnHdlr vc_conn;
1509 f_init();
1510
1511 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_bvci), testcasename(), g_pcu, g_sgsn, 16);
1512 vc_conn.done;
1513
1514 f_cleanup();
1515}
1516
Harald Welte7462a592020-11-23 22:07:07 +01001517/* PS-PAGING on SIG-BVC for unknown BVCI */
1518private function f_TC_paging_ps_sig_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1519{
1520 f_send_paging_ps_exp_no_bss(ts_BssgpP4Bvci(33333), 0, true);
1521}
1522testcase TC_paging_ps_sig_bvci_unknown() runs on test_CT {
1523 var BSSGP_ConnHdlr vc_conn;
1524 f_init();
1525
1526 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
1527 vc_conn.done;
1528
1529 f_cleanup();
1530}
1531
1532
Harald Welte0e188242020-11-22 21:46:48 +01001533
1534/***********************************************************************
1535 * PAGING CS procedure
1536 ***********************************************************************/
1537
1538private function f_send_paging_cs(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1539 boolean use_sig := false)
1540runs on BSSGP_ConnHdlr return template (present) PDU_BSSGP {
1541 var template (value) PDU_BSSGP pdu_tx;
1542 var template (present) PDU_BSSGP pdu_rx;
1543 /* we always specify '0' as BVCI in the templates below, as we override it with
1544 * 'p4' later anyway */
1545 pdu_rx := tr_BSSGP_CS_PAGING(0);
1546 pdu_rx.pDU_BSSGP_PAGING_CS.iMSI := tr_BSSGP_IMSI(g_pars.imsi);
1547 if (ispresent(g_pars.p_tmsi)) {
1548 pdu_tx := ts_BSSGP_CS_PAGING_PTMSI(0, g_pars.imsi, oct2int(g_pars.p_tmsi));
1549 pdu_rx.pDU_BSSGP_PAGING_CS.tMSI := tr_BSSGP_TMSI(oct2int(g_pars.p_tmsi));
1550 } else {
1551 pdu_tx := ts_BSSGP_CS_PAGING_IMSI(0, g_pars.imsi);
1552 pdu_rx.pDU_BSSGP_PAGING_CS.tMSI := omit;
1553 }
1554 pdu_tx.pDU_BSSGP_PAGING_CS.paging_Field4 := p4;
1555 pdu_rx.pDU_BSSGP_PAGING_CS.paging_Field4 := p4;
1556 if (use_sig == false) {
1557 SGSN[sgsn_idx].send(pdu_tx);
1558 } else {
1559 SGSN_SIG[sgsn_idx].send(pdu_tx);
1560 }
1561 return pdu_rx;
1562}
1563
1564/* send paging defined by 'p4' on given SGSN-side index (ptp or signaling) and expect one paging to arrive on
1565 * specified PCU index */
1566private function f_send_paging_cs_exp_one_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1567 boolean use_sig := false,integer pcu_idx := 0)
1568runs on BSSGP_ConnHdlr {
1569 var template (present) PDU_BSSGP exp_rx;
Daniel Willmann1a859712020-12-04 00:59:45 +01001570 var boolean test_done := false;
Harald Welte0e188242020-11-22 21:46:48 +01001571 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1572 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1573 exp_rx := f_send_paging_cs(p4, sgsn_idx, use_sig);
1574 /* Expect paging to propagate to the one BSS addressed by the BVCI only */
1575 timer T := 2.0;
1576 T.start;
1577 alt {
Daniel Willmann1a859712020-12-04 00:59:45 +01001578 [not use_sig and not test_done] PCU[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001579 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001580 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001581 repeat;
1582 }
1583 [not use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
1584 setverdict(fail, "Received paging on SIGNALING BVC, expected PTP BVC");
1585 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001586 [use_sig and not test_done] PCU_SIG[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001587 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001588 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001589 repeat;
1590 }
1591 [use_sig] PCU[pcu_idx].receive(exp_rx) {
1592 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1593 }
1594 [] any from PCU.receive(exp_rx) {
1595 setverdict(fail, "Paging received on unexpected BVC");
1596 }
1597 [] any from PCU_SIG.receive(exp_rx) {
1598 setverdict(fail, "Paging received on unexpected BVC");
1599 }
1600 [] any from PCU.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
1601 setverdict(fail, "Different Paging than expected received PTP BVC");
1602 }
1603 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
1604 setverdict(fail, "Different Paging than expected on SIGNALING BVC");
1605 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001606 [not test_done] T.timeout {
1607 setverdict(fail, "Timeout while waiting for paging")
1608 }
1609 [test_done] T.timeout;
Harald Welte0e188242020-11-22 21:46:48 +01001610 }
1611}
1612
Harald Welte7462a592020-11-23 22:07:07 +01001613/* send a CS-PAGING but don't expect it to show up on any PTP or SIG BVC */
1614private function f_send_paging_cs_exp_no_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1615 boolean use_sig := false)
1616runs on BSSGP_ConnHdlr {
1617 var template (present) PDU_BSSGP exp_rx;
1618 exp_rx := f_send_paging_cs(p4, sgsn_idx, use_sig);
1619 /* Expect paging to propagate to no BSS */
1620 timer T := 2.0;
1621 T.start;
1622 alt {
1623 [] any from PCU.receive(exp_rx) {
1624 setverdict(fail, "Paging received on unexpected BVC");
1625 }
1626 [] any from PCU_SIG.receive(exp_rx) {
1627 setverdict(fail, "Paging received on unexpected BVC");
1628 }
1629 [] any from PCU.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
1630 setverdict(fail, "Different Paging received on PTP BVC");
1631 }
1632 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
1633 setverdict(fail, "Different Paging received on SIGNALING BVC");
1634 }
1635 [] T.timeout {
1636 setverdict(pass);
1637 }
1638 }
1639}
1640
Harald Welte0e188242020-11-22 21:46:48 +01001641private function f_TC_paging_cs_ptp_bss(charstring id) runs on BSSGP_ConnHdlr
1642{
1643 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1644 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1645 f_send_paging_cs_exp_one_bss(ts_BssgpP4BssArea, 0, false, 0);
1646}
1647testcase TC_paging_cs_ptp_bss() runs on test_CT {
1648 var BSSGP_ConnHdlr vc_conn;
1649 f_init();
1650
1651 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_bss), testcasename(), g_pcu, g_sgsn, 17);
1652 vc_conn.done;
1653
1654 f_cleanup();
1655}
1656
1657/* CS-PAGING on PTP-BVC for Location Area */
1658private function f_TC_paging_cs_ptp_lac(charstring id) runs on BSSGP_ConnHdlr
1659{
1660 var template (present) PDU_BSSGP exp_rx;
1661 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1662 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1663 f_send_paging_cs_exp_one_bss(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, false, 0);
1664}
1665testcase TC_paging_cs_ptp_lac() runs on test_CT {
1666 var BSSGP_ConnHdlr vc_conn;
1667 f_init();
1668
1669 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_lac), testcasename(), g_pcu, g_sgsn, 18);
1670 vc_conn.done;
1671
1672 f_cleanup();
1673}
1674
Harald Welte7462a592020-11-23 22:07:07 +01001675/* CS-PAGING on PTP-BVC for unknown Location Area */
1676private function f_TC_paging_cs_ptp_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1677{
1678 var GSM_Types.LocationAreaIdentification unknown_la := {
1679 mcc_mnc := '567F99'H,
1680 lac := 33333
1681 };
1682 /* as it's sent on the PTP BVC, we expect it to pass even for unknown LAC */
1683 f_send_paging_cs_exp_one_bss(ts_BssgpP4LAC(unknown_la), 0, false, 0);
1684}
1685testcase TC_paging_cs_ptp_lac_unknown() runs on test_CT {
1686 var BSSGP_ConnHdlr vc_conn;
1687 f_init();
1688
1689 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_lac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1690 vc_conn.done;
1691
1692 f_cleanup();
1693}
1694
Harald Welte0e188242020-11-22 21:46:48 +01001695/* CS-PAGING on PTP-BVC for Routeing Area */
1696private function f_TC_paging_cs_ptp_rac(charstring id) runs on BSSGP_ConnHdlr
1697{
1698 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1699 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1700 f_send_paging_cs_exp_one_bss(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, false, 0);
1701}
1702testcase TC_paging_cs_ptp_rac() runs on test_CT {
1703 var BSSGP_ConnHdlr vc_conn;
1704 f_init();
1705
1706 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_rac), testcasename(), g_pcu, g_sgsn, 19);
1707 vc_conn.done;
1708
1709 f_cleanup();
1710}
1711
Harald Welte7462a592020-11-23 22:07:07 +01001712/* CS-PAGING on PTP-BVC for unknown Routeing Area */
1713private function f_TC_paging_cs_ptp_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1714{
1715 var RoutingAreaIdentification unknown_ra := {
1716 lai := {
1717 mcc_mnc := '567F99'H,
1718 lac := 33333
1719 },
1720 rac := 254
1721 };
1722 /* as it's sent on the PTP BVC, we expect it to pass even for unknown RAC */
1723 f_send_paging_cs_exp_one_bss(ts_BssgpP4RAC(unknown_ra), 0, false, 0);
1724}
1725testcase TC_paging_cs_ptp_rac_unknown() runs on test_CT {
1726 var BSSGP_ConnHdlr vc_conn;
1727 f_init();
1728
1729 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_rac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1730 vc_conn.done;
1731
1732 f_cleanup();
1733}
1734
Harald Welte0e188242020-11-22 21:46:48 +01001735/* CS-PAGING on PTP-BVC for BVCI (one cell) */
1736private function f_TC_paging_cs_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
1737{
1738 /* this should be the normal case for MS in READY MM state after a lower layer failure */
1739 f_send_paging_cs_exp_one_bss(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, false, 0);
1740}
1741testcase TC_paging_cs_ptp_bvci() runs on test_CT {
1742 var BSSGP_ConnHdlr vc_conn;
1743 f_init();
1744
1745 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_bvci), testcasename(), g_pcu, g_sgsn, 20);
1746 vc_conn.done;
1747
1748 f_cleanup();
1749}
1750
Harald Welte7462a592020-11-23 22:07:07 +01001751/* CS-PAGING on PTP-BVC for unknown BVCI */
1752private function f_TC_paging_cs_ptp_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1753{
1754 /* as it's sent on the PTP BVC, we expect it to pass even for unknown BVCI */
1755 f_send_paging_cs_exp_one_bss(ts_BssgpP4Bvci(33333), 0, false, 0);
1756}
1757testcase TC_paging_cs_ptp_bvci_unknown() runs on test_CT {
1758 var BSSGP_ConnHdlr vc_conn;
1759 f_init();
1760
1761 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
1762 vc_conn.done;
1763
1764 f_cleanup();
1765}
1766
Harald Welte0e188242020-11-22 21:46:48 +01001767/* send CS-PAGING on SIG BVC, expect it to arrive on given list of PCU indexes */
1768private function f_send_paging_cs_exp_multi(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1769 ro_integer exp_on_pcu_idx) runs on BSSGP_ConnHdlr
1770{
1771 var template (present) PDU_BSSGP exp_rx;
1772 exp_rx := f_send_paging_cs(p4, 0, true);
1773
1774 /* FIXME: make sure the relevant BVCs/BSS are connected to the ports! */
1775 var ro_default defaults := {};
1776 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1777 var default d := activate(as_paging_sig_pcu(i, exp_rx, g_roi));
1778 defaults := defaults & { d };
1779 }
1780 f_sleep(2.0);
1781 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
1782 deactivate(defaults[i]);
1783 }
1784 log("Paging received on PCU ", g_roi);
1785
1786 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1787 var boolean rx_on_i := ro_integer_contains(g_roi, i);
1788 var boolean exp_on_i := ro_integer_contains(exp_on_pcu_idx, i);
1789 if (exp_on_i and not rx_on_i) {
1790 setverdict(fail, "PS-PAGING not received on ", mp_nsconfig_pcu[i].nsei);
1791 }
1792 if (not exp_on_i and rx_on_i) {
1793 setverdict(fail, "PS-PAGING not expected but received on ", mp_nsconfig_pcu[i].nsei);
1794 }
1795 }
1796 setverdict(pass);
1797}
1798
1799/* CS-PAGING on SIG-BVC for BSS Area */
1800private function f_TC_paging_cs_sig_bss(charstring id) runs on BSSGP_ConnHdlr
1801{
1802 /* we expect the paging to arrive on all three NSE */
1803 f_send_paging_cs_exp_multi(ts_BssgpP4BssArea, 0, {0, 1, 2});
1804}
1805testcase TC_paging_cs_sig_bss() runs on test_CT {
1806 var BSSGP_ConnHdlr vc_conn;
1807 f_init();
1808
1809 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_bss), testcasename(), g_pcu, g_sgsn, 13);
1810 vc_conn.done;
1811
1812 f_cleanup();
1813}
1814
1815/* CS-PAGING on SIG-BVC for Location Area */
1816private function f_TC_paging_cs_sig_lac(charstring id) runs on BSSGP_ConnHdlr
1817{
Daniel Willmannd4fb73c2020-12-07 13:57:17 +01001818 /* The first LAC (13135) is shared by all three NSEs */
1819 f_send_paging_cs_exp_multi(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, {0, 1, 2});
1820 /* Reset state */
1821 g_roi := {};
1822 /* Make LAC (13300) available on pcu index 2 */
1823 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
1824 f_send_paging_cs_exp_multi(ts_BssgpP4LAC(pcu_bvc_cfg[2].cell_id.ra_id.lai), 0, {2});
Harald Welte0e188242020-11-22 21:46:48 +01001825}
1826testcase TC_paging_cs_sig_lac() runs on test_CT {
1827 var BSSGP_ConnHdlr vc_conn;
1828 f_init();
1829
1830 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_lac), testcasename(), g_pcu, g_sgsn, 14);
1831 vc_conn.done;
1832
1833 f_cleanup();
1834}
1835
Harald Welte7462a592020-11-23 22:07:07 +01001836/* CS-PAGING on SIG-BVC for unknown Location Area */
1837private function f_TC_paging_cs_sig_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1838{
1839 var GSM_Types.LocationAreaIdentification unknown_la := {
1840 mcc_mnc := '567F99'H,
1841 lac := 33333
1842 };
1843 f_send_paging_cs_exp_no_bss(ts_BssgpP4LAC(unknown_la), 0, true);
1844}
1845testcase TC_paging_cs_sig_lac_unknown() runs on test_CT {
1846 var BSSGP_ConnHdlr vc_conn;
1847 f_init();
1848
1849 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_lac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1850 vc_conn.done;
1851
1852 f_cleanup();
1853}
1854
Harald Welte0e188242020-11-22 21:46:48 +01001855/* CS-PAGING on SIG-BVC for Routeing Area */
1856private function f_TC_paging_cs_sig_rac(charstring id) runs on BSSGP_ConnHdlr
1857{
Daniel Willmannd4fb73c2020-12-07 13:57:17 +01001858 /* Only PCU index 0 has a matching BVC with the RA ID */
Harald Welte0e188242020-11-22 21:46:48 +01001859 f_send_paging_cs_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, {0});
Daniel Willmannd4fb73c2020-12-07 13:57:17 +01001860 g_roi := {};
1861 /* PCU index 1 and 2 have a matching BVC with the RA ID */
1862 f_send_paging_cs_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[2].cell_id.ra_id), 0, {1, 2});
1863 g_roi := {};
1864 /* PCU index 2 has two matching BVCs with the RA ID */
1865 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
1866 f_send_paging_cs_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[2].cell_id.ra_id), 0, {2});
Harald Welte0e188242020-11-22 21:46:48 +01001867}
1868testcase TC_paging_cs_sig_rac() runs on test_CT {
1869 var BSSGP_ConnHdlr vc_conn;
1870 f_init();
1871
1872 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_rac), testcasename(), g_pcu, g_sgsn, 15);
1873 vc_conn.done;
1874
1875 f_cleanup();
1876}
1877
Harald Welte7462a592020-11-23 22:07:07 +01001878/* CS-PAGING on SIG-BVC for unknown Routeing Area */
1879private function f_TC_paging_cs_sig_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1880{
1881 var RoutingAreaIdentification unknown_ra := {
1882 lai := {
1883 mcc_mnc := '567F99'H,
1884 lac := 33333
1885 },
1886 rac := 254
1887 };
1888 f_send_paging_cs_exp_no_bss(ts_BssgpP4RAC(unknown_ra), 0, true);
1889}
1890testcase TC_paging_cs_sig_rac_unknown() runs on test_CT {
1891 var BSSGP_ConnHdlr vc_conn;
1892 f_init();
1893
1894 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_rac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1895 vc_conn.done;
1896
1897 f_cleanup();
1898}
1899
Harald Welte0e188242020-11-22 21:46:48 +01001900/* CS-PAGING on SIG-BVC for BVCI (one cell) */
1901private function f_TC_paging_cs_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
1902{
1903 f_send_paging_cs_exp_multi(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, {0});
1904}
1905testcase TC_paging_cs_sig_bvci() runs on test_CT {
1906 var BSSGP_ConnHdlr vc_conn;
1907 f_init();
1908
1909 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_bvci), testcasename(), g_pcu, g_sgsn, 16);
1910 vc_conn.done;
1911
1912 f_cleanup();
1913}
1914
Harald Welte7462a592020-11-23 22:07:07 +01001915/* CS-PAGING on SIG-BVC for unknown BVCI */
1916private function f_TC_paging_cs_sig_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1917{
1918 f_send_paging_cs_exp_no_bss(ts_BssgpP4Bvci(33333), 0, true);
1919}
1920testcase TC_paging_cs_sig_bvci_unknown() runs on test_CT {
1921 var BSSGP_ConnHdlr vc_conn;
1922 f_init();
1923
1924 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
1925 vc_conn.done;
1926
1927 f_cleanup();
1928}
1929
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01001930private function f_TC_flush_ll(charstring id) runs on BSSGP_ConnHdlr {
1931 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
1932 var integer i;
1933 for (i := 0; i < 10; i := i+1) {
1934 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_FLUSH_LL(g_pars.tlli, bvci, bvci_new := bvci);
1935 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1936 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_FLUSH_LL(g_pars.tlli, bvci, bvci_new := bvci);
1937
1938 f_sgsn2pcu(pdu_tx, pdu_rx, use_sig := true);
1939
1940 pdu_tx := ts_BSSGP_FLUSH_LL_ACK(g_pars.tlli, int2oct(0, 1), 23, bvci_new := bvci);
1941 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1942 pdu_rx := tr_BSSGP_FLUSH_LL_ACK(g_pars.tlli, int2oct(0, 1), 23, bvci_new := bvci);
1943
1944 f_pcu2sgsn(pdu_tx, pdu_rx, use_sig := true);
1945 }
1946 setverdict(pass);
1947}
1948testcase TC_flush_ll() runs on test_CT
1949{
1950 var BSSGP_ConnHdlr vc_conn;
1951 f_init();
1952
1953 vc_conn := f_start_handler(refers(f_TC_flush_ll), testcasename(), g_pcu, g_sgsn, 6);
1954 vc_conn.done;
1955 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
1956
1957 f_cleanup();
1958}
Harald Welte6dc2ac42020-11-16 09:16:17 +01001959
Harald Weltef8e5c5d2020-11-27 22:37:23 +01001960private altstep as_bssgp_g_pcu_count(integer pcu_idx, template (present) PDU_BSSGP exp_rx, inout ro_integer roi)
1961runs on GlobalTest_CT {
1962[] G_PCU[pcu_idx].receive(exp_rx) from g_pcu[pcu_idx].vc_BSSGP {
1963 if (ro_integer_contains(roi, pcu_idx)) {
1964 setverdict(fail, "Received multiple on same SIG BVC");
1965 }
1966 roi := roi & { pcu_idx };
1967 repeat;
1968 }
1969}
1970/* send a INVOKE-TRACE from SGSN and expect to receive a copy on each NSE */
1971testcase TC_trace() runs on GlobalTest_CT
1972{
1973 var BSSGP_ConnHdlr vc_conn;
1974 f_init();
1975 f_global_init();
1976
1977 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_INVOKE_TRACE('23'O, '4321'O);
1978 var template (present) PDU_BSSGP exp_rx := ts_BSSGP_INVOKE_TRACE('23'O, '4321'O);
1979
1980 var ro_default defaults := {};
1981 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
1982 activate(as_bssgp_g_pcu_count(i, exp_rx, g_roi));
1983 }
1984 G_SGSN[0].send(pdu_tx);
1985 f_sleep(2.0);
1986 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
1987 deactivate(defaults[i]);
1988 }
1989
1990 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
1991 if (not ro_integer_contains(g_roi, i)) {
1992 setverdict(fail, "Failed to receive TRACE on PCU index ", i);
1993 }
1994 }
1995 setverdict(pass);
1996
1997 f_cleanup();
1998}
1999
Harald Weltec0351d12020-11-27 22:49:02 +01002000private function f_TC_llc_discarded(charstring id) runs on BSSGP_ConnHdlr {
2001 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
2002
2003 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_LLC_DISCARDED(g_pars.tlli, 23, bvci, 2342);
2004 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2005 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_LLC_DISCARDED(g_pars.tlli, 23, bvci, 2342);
2006
2007 f_pcu2sgsn(pdu_tx, pdu_rx, use_sig := true);
2008
2009 setverdict(pass);
2010}
2011/* Send a LLC-DISCARDED from BSS side and expect it to show up on SGSN (SIG BVC) */
2012testcase TC_llc_discarded() runs on test_CT
2013{
2014 var BSSGP_ConnHdlr vc_conn;
2015 f_init();
2016
2017 vc_conn := f_start_handler(refers(f_TC_llc_discarded), testcasename(), g_pcu, g_sgsn, 6);
2018 vc_conn.done;
2019 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
2020
2021 f_cleanup();
2022}
2023
Harald Weltef20af412020-11-28 16:11:11 +01002024/* Send an OVERLOAD from SGSN side and expect it to show up on each PCU (SIG BVC) */
2025testcase TC_overload() runs on GlobalTest_CT
2026{
2027 f_init();
2028 f_global_init();
2029
2030 var template (value) PDU_BSSGP pdu_tx := ts_OVERLOAD('1'B);
2031 var template (present) PDU_BSSGP exp_rx := tr_OVERLOAD('1'B);
2032
2033 var ro_default defaults := {};
2034 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2035 activate(as_bssgp_g_pcu_count(i, exp_rx, g_roi));
2036 }
2037 G_SGSN[0].send(pdu_tx);
2038 f_sleep(2.0);
2039 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2040 deactivate(defaults[i]);
2041 }
2042
2043 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2044 if (not ro_integer_contains(g_roi, i)) {
2045 setverdict(fail, "Failed to receive OVERLOAD on PCU index ", i);
2046 }
2047 }
2048 setverdict(pass);
2049
2050 f_cleanup();
2051}
2052
Harald Welte239aa502020-11-24 23:14:20 +01002053private function f_block_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2054{
2055 var BSSGP_BVC_CT bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2056 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2057 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2058
2059 SGSN_MGMT.clear;
2060 PCU_MGMT.clear;
2061
2062 /* block the PTP BVC from the PCU side */
2063 PCU_MGMT.send(BssgpBlockRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to bvc_ct;
2064 /* expect state on both PCU and SGSN side to change */
2065 interleave {
2066 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_BLOCKED)) from bvc_ct;
2067 [] SGSN_MGMT.receive(tr_BssgpStsInd(*, bvc_cfg.bvci, BVC_S_BLOCKED));
2068 }
2069 setverdict(pass);
2070}
2071testcase TC_bvc_block_ptp() runs on test_CT
2072{
2073 f_init();
2074 f_sleep(1.0);
2075 f_block_ptp_bvc_from_pcu(0, 0);
2076 f_cleanup();
2077}
2078
2079private function f_unblock_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2080{
2081 var BSSGP_BVC_CT bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2082 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2083 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2084
2085 SGSN_MGMT.clear;
2086 PCU_MGMT.clear;
2087
2088 /* block the PTP BVC from the PCU side */
2089 PCU_MGMT.send(BssgpUnblockRequest:{}) to bvc_ct;
2090 /* expect state on both PCU and SGSN side to change */
2091 interleave {
2092 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_UNBLOCKED)) from bvc_ct;
2093 [] SGSN_MGMT.receive(tr_BssgpStsInd(*, bvc_cfg.bvci, BVC_S_UNBLOCKED));
2094 }
2095 setverdict(pass);
2096}
2097testcase TC_bvc_unblock_ptp() runs on test_CT
2098{
2099 f_init();
2100 f_sleep(1.0);
2101 f_block_ptp_bvc_from_pcu(0, 0);
2102 f_sleep(1.0);
2103 f_unblock_ptp_bvc_from_pcu(0, 0);
2104 f_cleanup();
2105}
2106
Harald Welte60a8ec72020-11-25 17:12:53 +01002107private altstep as_ignore_status(BSSGP_BVC_MGMT_PT pt) {
2108[] pt.receive(BssgpStatusIndication:?) { repeat; }
2109}
2110private function f_get_sgsn_bvc_ct(integer sgsn_idx, BssgpBvci bvci) runs on test_CT return BSSGP_BVC_CT {
2111 for (var integer i := 0; i < lengthof(g_sgsn[sgsn_idx].cfg.bvc); i := i+1) {
2112 if (g_sgsn[sgsn_idx].cfg.bvc[i].bvci == bvci) {
2113 return g_sgsn[sgsn_idx].vc_BSSGP_BVC[i];
2114 }
2115 }
2116 return null;
2117}
2118private function f_reset_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2119{
2120 var BSSGP_BVC_CT pcu_bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2121 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2122 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2123 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(0, bvc_cfg.bvci);
2124 var default d;
2125
2126 SGSN_MGMT.clear;
2127 PCU_MGMT.clear;
2128
2129 /* block the PTP BVC from the PCU side */
2130 PCU_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to pcu_bvc_ct;
2131 /* expect state on both PCU and SGSN side to change */
2132 d := activate(as_ignore_status(SGSN_MGMT));
2133 interleave {
2134 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_BLOCKED)) from pcu_bvc_ct;
2135 [] SGSN_MGMT.receive(BssgpResetIndication:{bvc_cfg.bvci}) from sgsn_bvc_ct;
2136 }
2137 deactivate(d);
2138 setverdict(pass);
2139}
2140/* Send a BVC-RESET for a PTP BVC from the BSS side: expect it to propagate */
2141testcase TC_bvc_reset_ptp_from_bss() runs on test_CT
2142{
2143 f_init();
2144 f_sleep(3.0);
2145 f_reset_ptp_bvc_from_pcu(0, 0);
2146 f_cleanup();
2147}
2148
Harald Welte16786e92020-11-27 19:11:56 +01002149private altstep as_count_bvc_block(integer sgsn_idx, BssgpBvci bvci, inout ro_integer roi)
2150runs on test_CT {
2151 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(sgsn_idx, bvci);
2152 [] SGSN_MGMT.receive(tr_BssgpStsInd(?, bvci, BVC_S_BLOCKED)) from sgsn_bvc_ct {
2153 roi := roi & { bvci };
Harald Welteb2647f72020-12-07 14:36:35 +01002154 repeat;
Harald Welte16786e92020-11-27 19:11:56 +01002155 }
2156}
2157/* reset the signaling BVC from one BSS; expect no signaling BVC reset on SGSN; but BVC-BLOCK for PTP */
2158testcase TC_bvc_reset_sig_from_bss() runs on test_CT {
2159
2160 f_init();
2161 f_sleep(3.0);
2162
2163 /* Start BVC-RESET procedure for BVCI=0 */
2164 PCU_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to g_pcu[0].vc_BSSGP;
2165
2166 /* Activate altsteps: One for each PTP BVC within that PCUs NSE */
2167 var ro_default defaults := {};
2168 for (var integer i := 0; i < lengthof(g_pcu[0].cfg.bvc); i := i+1) {
2169 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[i];
2170 var default d := activate(as_count_bvc_block(0, bvcc.bvci, g_roi));
2171 defaults := defaults & { d };
2172 }
2173
2174 timer T := 3.0;
2175 T.start;
2176 alt {
2177 [] SGSN_MGMT.receive(BssgpResetIndication:{0}) {
2178 setverdict(fail, "BSS-side Reset of BVCI=0 should not propagate");
2179 }
2180 [] T.timeout;
2181 }
2182
2183 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2184 deactivate(defaults[i]);
2185 }
2186
2187 /* check if BVC-block was received on all expected BVC */
2188 for (var integer i := 0; i < lengthof(g_pcu[0].cfg.bvc); i := i+1) {
2189 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[i];
2190 if (not ro_integer_contains(g_roi, bvcc.bvci)) {
2191 setverdict(fail, "Missing SGSN-side BVC-BLOCK of BVCI=", bvcc.bvci);
2192 }
2193 }
2194
2195 /* check if BVC-block was not received on any unexpected BVC is not required as
2196 * such a message would basically run into 'no matching clause' */
Daniel Willmannf2590212020-12-04 14:20:50 +01002197 setverdict(pass);
Harald Welte16786e92020-11-27 19:11:56 +01002198 f_cleanup();
2199}
2200
Harald Welte60a8ec72020-11-25 17:12:53 +01002201private function f_reset_ptp_bvc_from_sgsn(integer pcu_idx, integer bvc_idx) runs on test_CT
2202{
2203 var BSSGP_BVC_CT pcu_bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2204 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2205 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2206 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(0, bvc_cfg.bvci);
2207 var default d;
2208
2209 SGSN_MGMT.clear;
2210 PCU_MGMT.clear;
2211
2212 /* block the PTP BVC from the PCU side */
2213 SGSN_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to sgsn_bvc_ct;
2214 /* expect state on both PCU and SGSN side to change */
2215 d := activate(as_ignore_status(PCU_MGMT));
2216 interleave {
2217 [] SGSN_MGMT.receive(tr_BssgpStsInd(?, bvc_cfg.bvci, BVC_S_BLOCKED)) from sgsn_bvc_ct;
2218 [] PCU_MGMT.receive(BssgpResetIndication:{bvc_cfg.bvci}) from pcu_bvc_ct;
2219 }
2220 deactivate(d);
2221 setverdict(pass);
2222}
2223/* Send a BVC-RESET for a PTP BVC from the SGSN side: expect it to propagate */
2224testcase TC_bvc_reset_ptp_from_sgsn() runs on test_CT
2225{
2226 f_init();
2227 f_sleep(3.0);
2228 f_reset_ptp_bvc_from_sgsn(0, 0);
2229 f_cleanup();
2230}
2231
Harald Welte16786e92020-11-27 19:11:56 +01002232private altstep as_count_bvc0_block(integer pcu_idx, Nsei nsei, inout ro_integer roi)
2233runs on test_CT {
2234 var BSSGP_CT pcu_ct := g_pcu[pcu_idx].vc_BSSGP;
2235 [] PCU_MGMT.receive(BssgpResetIndication:{0}) from pcu_ct {
2236 roi := roi & { nsei };
2237 }
2238}
2239/* reset the signaling BVC from the SGSN; expect all signaling BVC on all BSS to be reset */
2240testcase TC_bvc_reset_sig_from_sgsn() runs on test_CT {
2241
2242 f_init();
2243 f_sleep(3.0);
2244
2245 /* Start BVC-RESET procedure for BVCI=0 */
2246 SGSN_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to g_sgsn[0].vc_BSSGP;
2247
2248 /* Activate altsteps: One for each PCU NSE */
2249 var ro_default defaults := {};
2250 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2251 var NSConfiguration nscfg := mp_nsconfig_pcu[i];
2252 var default d := activate(as_count_bvc0_block(i, nscfg.nsei, g_roi));
2253 defaults := defaults & { d };
2254 }
2255
2256 f_sleep(3.0);
2257
2258 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2259 deactivate(defaults[i]);
2260 }
2261
2262 /* check if BVC-block was received on all expected BVC */
2263 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2264 var NSConfiguration nscfg := mp_nsconfig_pcu[i];
2265 if (not ro_integer_contains(g_roi, nscfg.nsei)) {
2266 setverdict(fail, "Missing PCU-side BVC-RESET of BVCI=0 on PCU index ", i);
2267 }
2268 }
2269
2270 /* check if BVC-block was not received on any unexpected BVC is not required as
2271 * such a message would basically run into 'no matching clause' */
2272
2273 f_cleanup();
2274}
2275
Daniel Willmann423d8f42020-09-08 18:58:22 +02002276control {
2277 execute( TC_BVC_bringup() );
Harald Welte92686012020-11-15 21:45:49 +01002278 execute( TC_ul_unitdata() );
Harald Welte78d8db92020-11-15 23:27:27 +01002279 execute( TC_dl_unitdata() );
Harald Welte6dc2ac42020-11-16 09:16:17 +01002280 execute( TC_ra_capability() );
Daniel Willmannace3ece2020-11-16 19:53:26 +01002281 execute( TC_ra_capability_upd() );
Daniel Willmann165d6612020-11-19 14:27:29 +01002282 execute( TC_radio_status() );
Daniel Willmannfa67f492020-11-19 15:48:05 +01002283 execute( TC_suspend() );
Daniel Willmann087a33d2020-11-19 15:58:43 +01002284 execute( TC_resume() );
Harald Weltef8e5c5d2020-11-27 22:37:23 +01002285 execute( TC_trace() );
Harald Weltec0351d12020-11-27 22:49:02 +01002286 execute( TC_llc_discarded() );
Harald Weltef20af412020-11-28 16:11:11 +01002287 execute( TC_overload() );
Harald Welte239aa502020-11-24 23:14:20 +01002288 execute( TC_bvc_block_ptp() );
2289 execute( TC_bvc_unblock_ptp() );
Harald Welte60a8ec72020-11-25 17:12:53 +01002290 execute( TC_bvc_reset_ptp_from_bss() );
Harald Welte16786e92020-11-27 19:11:56 +01002291 execute( TC_bvc_reset_sig_from_bss() );
Harald Welte60a8ec72020-11-25 17:12:53 +01002292 execute( TC_bvc_reset_ptp_from_sgsn() );
Harald Welte16786e92020-11-27 19:11:56 +01002293 execute( TC_bvc_reset_sig_from_sgsn() );
Harald Weltef8ef0282020-11-18 12:16:59 +01002294 if (false) {
2295 /* don't enable this by default, as we don't yet have any automatic test setup for FR with 4 NS-VC */
2296 execute( TC_load_sharing_dl() );
2297 }
Harald Welte0e188242020-11-22 21:46:48 +01002298
2299 /* PAGING-PS over PTP BVC */
2300 execute( TC_paging_ps_ptp_bss() );
2301 execute( TC_paging_ps_ptp_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002302 execute( TC_paging_ps_ptp_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002303 execute( TC_paging_ps_ptp_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002304 execute( TC_paging_ps_ptp_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002305 execute( TC_paging_ps_ptp_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002306 execute( TC_paging_ps_ptp_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002307
2308 /* PAGING-PS over SIG BVC */
2309 execute( TC_paging_ps_sig_bss() );
2310 execute( TC_paging_ps_sig_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002311 execute( TC_paging_ps_sig_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002312 execute( TC_paging_ps_sig_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002313 execute( TC_paging_ps_sig_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002314 execute( TC_paging_ps_sig_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002315 execute( TC_paging_ps_sig_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002316
2317 /* PAGING-CS over PTP BVC */
2318 execute( TC_paging_cs_ptp_bss() );
2319 execute( TC_paging_cs_ptp_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002320 execute( TC_paging_cs_ptp_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002321 execute( TC_paging_cs_ptp_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002322 execute( TC_paging_cs_ptp_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002323 execute( TC_paging_cs_ptp_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002324 execute( TC_paging_cs_ptp_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002325
2326 /* PAGING-CS over SIG BVC */
2327 execute( TC_paging_cs_sig_bss() );
2328 execute( TC_paging_cs_sig_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002329 execute( TC_paging_cs_sig_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002330 execute( TC_paging_cs_sig_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002331 execute( TC_paging_cs_sig_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002332 execute( TC_paging_cs_sig_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002333 execute( TC_paging_cs_sig_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002334
2335
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002336 execute( TC_flush_ll() );
Daniel Willmann423d8f42020-09-08 18:58:22 +02002337}
2338
2339
2340}