blob: d3c6df6bf4972e167f97e45166c7837e87ced1b2 [file] [log] [blame]
Daniel Willmann423d8f42020-09-08 18:58:22 +02001module GBProxy_Tests {
2
3/* Osmocom GBProxy test suite in TTCN-3
Harald Welte207166c2021-01-16 12:52:30 +01004 * (C) 2020-2021 Harald Welte <laforge@osmocom.org>
Daniel Willmann423d8f42020-09-08 18:58:22 +02005 * (C) 2020 sysmocom - s.f.m.c. GmbH
6 * All rights reserved.
7 *
8 * Author: Daniel Willmann <dwillmann@sysmocom.de>
9
10 * Released under the terms of GNU General Public License, Version 2 or
11 * (at your option) any later version.
12 *
13 * SPDX-License-Identifier: GPL-2.0-or-later
14 */
15
16import from General_Types all;
17import from Osmocom_Types all;
Harald Welteb9f0fdc2020-12-09 14:44:50 +010018import from Misc_Helpers all;
Daniel Willmann423d8f42020-09-08 18:58:22 +020019import from GSM_Types all;
20import from Native_Functions all;
21import from NS_Types all;
22import from NS_Emulation all;
23import from BSSGP_Types all;
24import from BSSGP_Emulation all;
25import from SCCPasp_Types all;
26import from Osmocom_Gb_Types all;
27
28import from MobileL3_CommonIE_Types all;
29import from MobileL3_GMM_SM_Types all;
30import from MobileL3_Types all;
31import from L3_Templates all;
32import from L3_Common all;
33
34import from TELNETasp_PortType all;
35import from Osmocom_VTY_Functions all;
Harald Welteb5688f22021-03-30 16:28:04 +020036import from Osmocom_CTRL_Adapter all;
Daniel Willmann423d8f42020-09-08 18:58:22 +020037
38import from LLC_Types all;
39import from LLC_Templates all;
40
41import from GSM_RR_Types all;
42
Harald Welte6d63f742020-11-15 19:44:04 +010043/* mcc_mnc is 24.008 10.5.5.15 encoded. 262 42 */
44const BcdMccMnc c_mcc_mnc := '262F42'H;
45
Harald Welte0d5fceb2020-11-29 16:04:07 +010046/* 48.016 section 6.1.4.2: The default maximum information field size of 1600 octets shall be supported on the Gb interface */
47const integer max_fr_info_size := 1600;
48
Daniel Willmann423d8f42020-09-08 18:58:22 +020049modulepar {
Harald Welteb5688f22021-03-30 16:28:04 +020050 charstring mp_gbproxy_ip := "127.0.0.1";
51 integer mp_gbproxy_ctrl_port := 4263;
Harald Welte77218d02021-01-15 19:59:15 +010052 /* NRI bit-length. 0 for no pooling */
53 integer mp_nri_bitlength := 5;
54 roro_integer mp_sgsn_nri := {
55 { 3 }, /* list of NRIs of first SGSN */
56 { 4 } /* list of NRIs of second SGSN */
57 };
Harald Weltef6e59b02020-12-08 08:29:09 +010058 boolean mp_enable_bss_load_sharing := false;
Daniel Willmann2c9300f2020-12-01 10:54:08 +010059 /* SGSN NS configuration */
Harald Welte6d63f742020-11-15 19:44:04 +010060 NSConfigurations mp_nsconfig_sgsn := {
Daniel Willmann423d8f42020-09-08 18:58:22 +020061 {
Daniel Willmann423d8f42020-09-08 18:58:22 +020062 nsei := 101,
63 role_sgsn := true,
Harald Welte90f19742020-11-06 19:34:40 +010064 handle_sns := false,
65 nsvc := {
66 {
67 provider := {
68 ip := {
69 address_family := AF_INET,
70 local_udp_port := 7777,
Harald Welted05a4a92021-01-18 12:03:53 +010071 local_ip := "127.0.0.10",
Harald Welte90f19742020-11-06 19:34:40 +010072 remote_udp_port := 23000,
Harald Weltebe7afce2021-01-17 22:04:36 +010073 remote_ip := "127.0.0.1",
Harald Welte388057d2021-01-18 18:52:49 +010074 data_weight := 0,
Harald Weltebe7afce2021-01-17 22:04:36 +010075 signalling_weight := 1
Harald Welte90f19742020-11-06 19:34:40 +010076 }
77 },
78 nsvci := 101
Harald Welte388057d2021-01-18 18:52:49 +010079 }, {
80 provider := {
81 ip := {
82 address_family := AF_INET,
83 local_udp_port := 7770,
84 local_ip := "127.0.0.10",
85 remote_udp_port := 23000,
86 remote_ip := "127.0.0.1",
87 data_weight := 1,
88 signalling_weight := 0
89 }
90 },
91 nsvci := 201
Harald Welte90f19742020-11-06 19:34:40 +010092 }
Harald Weltebe7afce2021-01-17 22:04:36 +010093
Harald Welte90f19742020-11-06 19:34:40 +010094 }
Harald Welteb978ed62020-12-12 14:01:11 +010095 }, {
96 nsei := 102,
97 role_sgsn := true,
98 handle_sns := false,
99 nsvc := {
100 {
101 provider := {
102 ip := {
103 address_family := AF_INET,
104 local_udp_port := 8888,
Harald Welted05a4a92021-01-18 12:03:53 +0100105 local_ip := "127.0.0.11",
Harald Welteb978ed62020-12-12 14:01:11 +0100106 remote_udp_port := 23000,
Harald Weltebe7afce2021-01-17 22:04:36 +0100107 remote_ip := "127.0.0.1",
Harald Welte388057d2021-01-18 18:52:49 +0100108 data_weight := 0,
Harald Weltebe7afce2021-01-17 22:04:36 +0100109 signalling_weight := 1
Harald Welteb978ed62020-12-12 14:01:11 +0100110 }
111 },
112 nsvci := 102
Harald Welte388057d2021-01-18 18:52:49 +0100113 }, {
114 provider := {
115 ip := {
116 address_family := AF_INET,
117 local_udp_port := 8880,
118 local_ip := "127.0.0.11",
119 remote_udp_port := 23000,
120 remote_ip := "127.0.0.1",
121 data_weight := 1,
122 signalling_weight := 0
123 }
124 },
125 nsvci := 202
Harald Welteb978ed62020-12-12 14:01:11 +0100126 }
127 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200128 }
129 };
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100130 /* BSS NSEI start at 2000 + x
131 * NSVCI start from value of NSEI + 100
132 * UDP port is NSVCI * 10 */
Harald Welte6d63f742020-11-15 19:44:04 +0100133 NSConfigurations mp_nsconfig_pcu := {
Daniel Willmann423d8f42020-09-08 18:58:22 +0200134 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100135 nsei := 2001,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200136 role_sgsn := false,
Harald Welte90f19742020-11-06 19:34:40 +0100137 handle_sns := false,
138 nsvc := {
139 {
140 provider := {
141 ip := {
142 address_family := AF_INET,
143 local_udp_port := 21010,
Harald Welted05a4a92021-01-18 12:03:53 +0100144 local_ip := "127.0.1.1",
Harald Welte90f19742020-11-06 19:34:40 +0100145 remote_udp_port := 23000,
Harald Weltebe7afce2021-01-17 22:04:36 +0100146 remote_ip := "127.0.0.1",
147 data_weight := 1,
148 signalling_weight := 1
Harald Welte90f19742020-11-06 19:34:40 +0100149 }
150 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100151 nsvci := 2101
Harald Welte90f19742020-11-06 19:34:40 +0100152 }
153 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200154 },
155 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100156 nsei := 2002,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200157 role_sgsn := false,
Harald Welte90f19742020-11-06 19:34:40 +0100158 handle_sns := false,
159 nsvc := {
160 {
161 provider := {
162 ip := {
163 address_family := AF_INET,
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100164 local_udp_port := 21020,
Harald Welted05a4a92021-01-18 12:03:53 +0100165 local_ip := "127.0.2.1",
Harald Welte90f19742020-11-06 19:34:40 +0100166 remote_udp_port := 23000,
Harald Weltebe7afce2021-01-17 22:04:36 +0100167 remote_ip := "127.0.0.1",
168 data_weight := 1,
169 signalling_weight := 1
Harald Welte90f19742020-11-06 19:34:40 +0100170 }
171 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100172 nsvci := 2102
Harald Welte90f19742020-11-06 19:34:40 +0100173 }
174 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200175 },
176 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100177 nsei := 2003,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200178 role_sgsn := false,
Harald Welte90f19742020-11-06 19:34:40 +0100179 handle_sns := false,
180 nsvc := {
181 {
182 provider := {
183 ip := {
184 address_family := AF_INET,
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100185 local_udp_port := 21030,
Harald Welted05a4a92021-01-18 12:03:53 +0100186 local_ip := "127.0.3.1",
Harald Welte90f19742020-11-06 19:34:40 +0100187 remote_udp_port := 23000,
Harald Weltebe7afce2021-01-17 22:04:36 +0100188 remote_ip := "127.0.0.1",
189 data_weight := 1,
190 signalling_weight := 1
Harald Welte90f19742020-11-06 19:34:40 +0100191 }
192 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100193 nsvci := 2103
Harald Welte90f19742020-11-06 19:34:40 +0100194 }
195 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200196 }
197 };
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100198 /* BVCI are NSEI*10 + x
199 * The first NSE only has one BVC, the second one 2 and so on
200 * The Cell ID is BVCI + 10000
201 * LAC/RAC are configured in such a way that:
202 * LAC 13135 is present once in NSE(2001), twice in NSE(2002) and once in NSE(2003)
203 * LAC 13300 is present twice in NSE(2003)
204 * RAI 13135-1 is present in NSE(2002) and NSE(2003)
205 * RAI 13300-0 is present twice in NSE(2003)
206 */
Harald Welte6d63f742020-11-15 19:44:04 +0100207 BssgpConfigs mp_gbconfigs := {
208 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100209 nsei := 2001,
Harald Welte6d63f742020-11-15 19:44:04 +0100210 sgsn_role := false,
211 bvc := {
212 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100213 bvci := 20011,
Harald Welte6d63f742020-11-15 19:44:04 +0100214 cell_id := {
215 ra_id := {
216 lai := {
217 mcc_mnc := c_mcc_mnc,
218 lac := 13135
219 },
220 rac := 0
221 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100222 cell_id := 30011
Harald Welte6d63f742020-11-15 19:44:04 +0100223 },
224 depth := BSSGP_DECODE_DEPTH_BSSGP,
225 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
226 }
227 }
228 }, {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100229 nsei := 2002,
Harald Welte6d63f742020-11-15 19:44:04 +0100230 sgsn_role := false,
231 bvc := {
232 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100233 bvci := 20021,
Harald Welte6d63f742020-11-15 19:44:04 +0100234 cell_id := {
235 ra_id := {
236 lai := {
237 mcc_mnc := c_mcc_mnc,
Harald Welte0e188242020-11-22 21:46:48 +0100238 lac := 13135
Harald Welte6d63f742020-11-15 19:44:04 +0100239 },
Harald Welte0e188242020-11-22 21:46:48 +0100240 rac := 1
Harald Welte6d63f742020-11-15 19:44:04 +0100241 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100242 cell_id := 30021
243 },
244 depth := BSSGP_DECODE_DEPTH_BSSGP,
245 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
246 },
247 {
248 bvci := 20022,
249 cell_id := {
250 ra_id := {
251 lai := {
252 mcc_mnc := c_mcc_mnc,
253 lac := 13135
254 },
255 rac := 2
256 },
257 cell_id := 30022
Harald Welte6d63f742020-11-15 19:44:04 +0100258 },
259 depth := BSSGP_DECODE_DEPTH_BSSGP,
260 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
261 }
262 }
263 }, {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100264 nsei := 2003,
Harald Welte6d63f742020-11-15 19:44:04 +0100265 sgsn_role := false,
266 bvc := {
267 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100268 bvci := 20031,
269 cell_id := {
270 ra_id := {
271 lai := {
272 mcc_mnc := c_mcc_mnc,
273 lac := 13135
274 },
275 rac := 1
276 },
277 cell_id := 30031
278 },
279 depth := BSSGP_DECODE_DEPTH_BSSGP,
280 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
281 },
282 {
283 bvci := 20032,
Harald Welte6d63f742020-11-15 19:44:04 +0100284 cell_id := {
285 ra_id := {
286 lai := {
287 mcc_mnc := c_mcc_mnc,
288 lac := 13300
289 },
290 rac := 0
291 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100292 cell_id := 30032
293 },
294 depth := BSSGP_DECODE_DEPTH_BSSGP,
295 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
296 },
297 {
298 bvci := 20033,
299 cell_id := {
300 ra_id := {
301 lai := {
302 mcc_mnc := c_mcc_mnc,
303 lac := 13300
304 },
305 rac := 0
306 },
307 cell_id := 30033
Harald Welte6d63f742020-11-15 19:44:04 +0100308 },
309 depth := BSSGP_DECODE_DEPTH_BSSGP,
310 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
311 }
312 }
313 }
314 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200315};
316
Daniel Willmann423d8f42020-09-08 18:58:22 +0200317type record GbInstance {
318 NS_CT vc_NS,
319 BSSGP_CT vc_BSSGP,
Harald Welte67dc8c22020-11-17 18:32:29 +0100320 BSSGP_BVC_CTs vc_BSSGP_BVC,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200321 BssgpConfig cfg
322};
Harald Welte67dc8c22020-11-17 18:32:29 +0100323type record of BSSGP_BVC_CT BSSGP_BVC_CTs
Daniel Willmann423d8f42020-09-08 18:58:22 +0200324
325const integer NUM_PCU := 3;
Harald Welte6d63f742020-11-15 19:44:04 +0100326type record of GbInstance GbInstances;
327type record of BssgpConfig BssgpConfigs;
328type record of NSConfiguration NSConfigurations;
329type record of BssgpCellId BssgpCellIds;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200330
Harald Welte572b0172021-03-30 13:19:56 +0200331/* you cannot simply change this to any larger number of SGSNs and expect all test
332 * cases to work. This would have overly complicated the code. Check below for
333 * tests that use interleave on SGSN_MGMT.receive() for each SGSN NSEI for example */
Harald Welteb978ed62020-12-12 14:01:11 +0100334const integer NUM_SGSN := 2;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200335
Harald Welteb5688f22021-03-30 16:28:04 +0200336type component test_CT extends CTRL_Adapter_CT {
Harald Welte6d63f742020-11-15 19:44:04 +0100337 var GbInstances g_pcu;
338 var GbInstances g_sgsn;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200339
340 port BSSGP_CT_PROC_PT PROC;
341
Harald Weltefbae83f2020-11-15 23:25:55 +0100342 port BSSGP_BVC_MGMT_PT SGSN_MGMT;
343 port BSSGP_BVC_MGMT_PT PCU_MGMT;
344
Daniel Willmann423d8f42020-09-08 18:58:22 +0200345 port TELNETasp_PT GBPVTY;
346
347 var boolean g_initialized := false;
348 var boolean g_use_echo := false;
Harald Welte16786e92020-11-27 19:11:56 +0100349
350 var ro_integer g_roi := {};
Daniel Willmannc38c85d2021-01-21 18:11:12 +0100351 var roro_integer g_roroi := {};
Harald Welte425d3762020-12-09 14:33:18 +0100352 timer g_Tguard;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200353};
354
355type component BSSGP_ConnHdlr {
Harald Welte3dd21b32020-11-17 19:21:00 +0100356 /* array of per-BVC ports on the PCU side */
Harald Welte158becf2020-12-09 12:32:32 +0100357 port BSSGP_PT PCU_PTP[NUM_PCU];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200358 port BSSGP_PT PCU_SIG[NUM_PCU];
359 port BSSGP_PROC_PT PCU_PROC[NUM_PCU];
Harald Welte3dd21b32020-11-17 19:21:00 +0100360 /* component reference to the component to which we're currently connected */
361 var BSSGP_BVC_CT pcu_ct[NUM_PCU];
Harald Welte0e188242020-11-22 21:46:48 +0100362 /* BSSGP BVC configuration of the component to which we're currently connected */
363 var BssgpBvcConfig pcu_bvc_cfg[NUM_PCU];
Harald Welte3dd21b32020-11-17 19:21:00 +0100364
365 /* array of per-BVC ports on the SGSN side */
Harald Welte158becf2020-12-09 12:32:32 +0100366 port BSSGP_PT SGSN_PTP[NUM_SGSN];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200367 port BSSGP_PT SGSN_SIG[NUM_SGSN];
368 port BSSGP_PROC_PT SGSN_PROC[NUM_SGSN];
Harald Welte3dd21b32020-11-17 19:21:00 +0100369 /* component reference to the component to which we're currently connected */
370 var BSSGP_BVC_CT sgsn_ct[NUM_PCU];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200371
372 var BSSGP_ConnHdlrPars g_pars;
373 timer g_Tguard;
374 var LLC_Entities llc;
Harald Welte0e188242020-11-22 21:46:48 +0100375
376 var ro_integer g_roi := {};
Daniel Willmann423d8f42020-09-08 18:58:22 +0200377}
378
379type record SGSN_ConnHdlrNetworkPars {
380 boolean expect_ptmsi,
381 boolean expect_auth,
382 boolean expect_ciph
383};
384
385type record BSSGP_ConnHdlrPars {
386 /* IMEI of the simulated ME */
387 hexstring imei,
388 /* IMSI of the simulated MS */
389 hexstring imsi,
390 /* MSISDN of the simulated MS (probably unused) */
391 hexstring msisdn,
392 /* P-TMSI allocated to the simulated MS */
393 OCT4 p_tmsi optional,
394 OCT3 p_tmsi_sig optional,
395 /* TLLI of the simulated MS */
396 OCT4 tlli,
397 OCT4 tlli_old optional,
398 RoutingAreaIdentificationV ra optional,
Harald Welte16357a92020-11-17 18:20:00 +0100399 GbInstances pcu,
Harald Welte3dd21b32020-11-17 19:21:00 +0100400 GbInstances sgsn,
Harald Weltec5f486b2021-01-16 11:07:01 +0100401 /* The SGSN index to be used within the test */
402 integer sgsn_idx,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200403 float t_guard
404};
405
Harald Welte04358652021-01-17 13:48:13 +0100406private function get_bvc_idx_for_bvci(GbInstance gbi, BssgpBvci bvci) return integer
407{
408 var integer i;
409
410 for (i := 0; i < lengthof(gbi.cfg.bvc); i := i + 1) {
411 if (gbi.cfg.bvc[i].bvci == bvci) {
412 return i;
413 }
414 }
415 setverdict(fail, "Could not find BVC Index for BVCI ", bvci);
416 return -1;
417}
418
Daniel Willmann423d8f42020-09-08 18:58:22 +0200419private function f_cellid_to_RAI(in BssgpCellId cell_id) return RoutingAreaIdentificationV {
420 /* mcc_mnc is encoded as of 24.008 10.5.5.15 */
421 var BcdMccMnc mcc_mnc := cell_id.ra_id.lai.mcc_mnc;
422
423 var RoutingAreaIdentificationV ret := {
424 mccDigit1 := mcc_mnc[0],
425 mccDigit2 := mcc_mnc[1],
426 mccDigit3 := mcc_mnc[2],
427 mncDigit3 := mcc_mnc[3],
428 mncDigit1 := mcc_mnc[4],
429 mncDigit2 := mcc_mnc[5],
430 lac := int2oct(cell_id.ra_id.lai.lac, 16),
431 rac := int2oct(cell_id.ra_id.rac, 8)
432 }
433 return ret;
434};
435
Harald Welte95339432020-12-02 18:50:52 +0100436private function f_fix_create_cb(inout BssgpConfig cfg)
437{
438 for (var integer i := 0; i < lengthof(cfg.bvc); i := i + 1) {
439 if (not isbound(cfg.bvc[i].create_cb)) {
440 cfg.bvc[i].create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
441 }
442 }
443}
444
Daniel Willmann423d8f42020-09-08 18:58:22 +0200445private function f_init_gb_pcu(inout GbInstance gb, charstring id, integer offset) runs on test_CT {
Harald Welteb419d0e2020-11-16 16:45:05 +0100446 var charstring ns_id := id & "-NS(PCU[" & int2str(offset) & "])";
447 var charstring bssgp_id := id & "-BSSGP(PCU[" & int2str(offset) & "])";
448 gb.vc_NS := NS_CT.create(ns_id);
449 gb.vc_BSSGP := BSSGP_CT.create(bssgp_id);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200450 /* connect lower end of BSSGP emulation with NS upper port */
451 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
452
Harald Welteb419d0e2020-11-16 16:45:05 +0100453 gb.vc_NS.start(NSStart(mp_nsconfig_pcu[offset], ns_id));
454 gb.vc_BSSGP.start(BssgpStart(gb.cfg, bssgp_id));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200455
456 for (var integer i := 0; i < lengthof(gb.cfg.bvc); i := i + 1) {
Harald Welteb978ed62020-12-12 14:01:11 +0100457 /* obtain the component reference of the BSSGP_BVC_CT for each PTP BVC */
Daniel Willmann423d8f42020-09-08 18:58:22 +0200458 connect(self:PROC, gb.vc_BSSGP:PROC);
459 gb.vc_BSSGP_BVC[i] := f_bssgp_get_bvci_ct(gb.cfg.bvc[i].bvci, PROC);
460 disconnect(self:PROC, gb.vc_BSSGP:PROC);
Harald Welteb978ed62020-12-12 14:01:11 +0100461 /* connect all of the per-BVC MGMT ports to our PCU_MGMT port (1:N) */
Harald Weltefbae83f2020-11-15 23:25:55 +0100462 connect(self:PCU_MGMT, gb.vc_BSSGP_BVC[i]:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200463 }
Harald Welteb978ed62020-12-12 14:01:11 +0100464 /* connect all of the BSSGP/NSE global MGMT port to our PCU_MGMT port (1:N) */
Harald Welte16786e92020-11-27 19:11:56 +0100465 connect(self:PCU_MGMT, gb.vc_BSSGP:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200466}
467
468private function f_init_gb_sgsn(inout GbInstance gb, charstring id, integer offset) runs on test_CT {
Harald Welteb419d0e2020-11-16 16:45:05 +0100469 var charstring ns_id := id & "-NS(SGSN[" & int2str(offset) & "])";
470 var charstring bssgp_id := id & "-BSSGP(SGSN[" & int2str(offset) & "])";
471 gb.vc_NS := NS_CT.create(ns_id);
472 gb.vc_BSSGP := BSSGP_CT.create(bssgp_id);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200473 /* connect lower end of BSSGP emulation with NS upper port */
474 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
475
Harald Welteb419d0e2020-11-16 16:45:05 +0100476 gb.vc_NS.start(NSStart(mp_nsconfig_sgsn[offset], ns_id));
477 gb.vc_BSSGP.start(BssgpStart(gb.cfg, bssgp_id));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200478
479 for (var integer i := 0; i < lengthof(gb.cfg.bvc); i := i + 1) {
Harald Welteb978ed62020-12-12 14:01:11 +0100480 /* obtain the component reference of the BSSGP_BVC_CT for each PTP BVC */
Daniel Willmann423d8f42020-09-08 18:58:22 +0200481 connect(self:PROC, gb.vc_BSSGP:PROC);
482 gb.vc_BSSGP_BVC[i] := f_bssgp_get_bvci_ct(gb.cfg.bvc[i].bvci, PROC);
483 disconnect(self:PROC, gb.vc_BSSGP:PROC);
Harald Welteb978ed62020-12-12 14:01:11 +0100484 /* connect all of the per-BVC MGMT ports to our SGSN_MGMT port (1:N) */
Harald Weltefbae83f2020-11-15 23:25:55 +0100485 connect(self:SGSN_MGMT, gb.vc_BSSGP_BVC[i]:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200486 }
Harald Welteb978ed62020-12-12 14:01:11 +0100487 /* connect all of the BSSGP/NSE global MGMT port to our SGSN_MGMT port (1:N) */
Harald Welte16786e92020-11-27 19:11:56 +0100488 connect(self:SGSN_MGMT, gb.vc_BSSGP:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200489}
490
491
Harald Welteb9f0fdc2020-12-09 14:44:50 +0100492private function f_destroy_gb(inout GbInstance gb) runs on test_CT {
493 gb.vc_NS.stop;
494 gb.vc_BSSGP.stop;
495
496 for (var integer i := 0; i < lengthof(gb.cfg.bvc); i := i + 1) {
497 gb.vc_BSSGP_BVC[i].stop;
498 }
499}
500
Daniel Willmann423d8f42020-09-08 18:58:22 +0200501private function f_init_vty() runs on test_CT {
502 map(self:GBPVTY, system:GBPVTY);
503 f_vty_set_prompts(GBPVTY);
504 f_vty_transceive(GBPVTY, "enable");
505}
506
Harald Welteb978ed62020-12-12 14:01:11 +0100507/* count the number of unblocked BVCI for each SGSN NSE */
508private altstep as_count_unblocked4nse(integer sgsn_idx, inout roro_integer bvci_unblocked)
509runs on test_CT {
510 var BssgpStatusIndication bsi;
511 [] SGSN_MGMT.receive(BssgpStatusIndication:{g_sgsn[sgsn_idx].cfg.nsei, ?, BVC_S_UNBLOCKED}) -> value bsi {
512 bvci_unblocked[sgsn_idx] := bvci_unblocked[sgsn_idx] & { bsi.bvci };
513 /* 'repeat' until sufficient number of BVC-rest has been received on all SGSNs */
514 for (var integer i := 0; i < lengthof(bvci_unblocked); i := i+1) {
515 if (lengthof(bvci_unblocked[i]) < lengthof(g_sgsn[i].cfg.bvc)) {
516 repeat;
517 }
518 }
519 }
520}
521
Harald Welteb5688f22021-03-30 16:28:04 +0200522private template (value) charstring ts_pcu_bvc_fsm_id(uint16_t nsei, uint16_t bvci) :=
523 "NSE" & f_int2str(nsei, 5) & "-BVC" & f_int2str(bvci, 5);
524
525function f_bvc_fsm_ensure_state(uint16_t nsei, uint16_t bvci, template (present) charstring exp)
526runs on CTRL_Adapter_CT {
527 f_ctrl_get_exp_inst_state(IPA_CTRL, "BSSGP-BVC", ts_pcu_bvc_fsm_id(nsei, bvci), exp);
528}
529
Harald Welte425d3762020-12-09 14:33:18 +0100530function f_init(float t_guard := 30.0) runs on test_CT {
Harald Welteb978ed62020-12-12 14:01:11 +0100531 var roro_integer bvci_unblocked;
Harald Weltefbae83f2020-11-15 23:25:55 +0100532 var BssgpStatusIndication bsi;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200533 var integer i;
534
535 if (g_initialized == true) {
536 return;
537 }
538 g_initialized := true;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200539
Harald Welte425d3762020-12-09 14:33:18 +0100540 g_Tguard.start(t_guard);
541 activate(as_gTguard(g_Tguard));
542
Harald Welteb5688f22021-03-30 16:28:04 +0200543 f_ipa_ctrl_start_client(mp_gbproxy_ip, mp_gbproxy_ctrl_port);
544
Harald Welteb978ed62020-12-12 14:01:11 +0100545 var BssgpBvcConfigs bvcs := { };
Harald Welte6d63f742020-11-15 19:44:04 +0100546 for (i := 0; i < lengthof(mp_gbconfigs); i := i+1) {
547 g_pcu[i].cfg := mp_gbconfigs[i];
Harald Welte95339432020-12-02 18:50:52 +0100548 /* make sure all have a proper crate_cb, which cannot be specified in config file */
549 f_fix_create_cb(g_pcu[i].cfg);
Harald Welte6d63f742020-11-15 19:44:04 +0100550 /* concatenate all the PCU-side BVCs for the SGSN side */
Harald Welteb978ed62020-12-12 14:01:11 +0100551 bvcs := bvcs & g_pcu[i].cfg.bvc;
552 }
553
554 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
555 g_sgsn[i].cfg := {
556 nsei := mp_nsconfig_sgsn[i].nsei,
557 sgsn_role := true,
558 bvc := bvcs
559 }
Harald Welte6d63f742020-11-15 19:44:04 +0100560 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200561
562 f_init_vty();
Harald Welte6d63f742020-11-15 19:44:04 +0100563 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
Daniel Willmann443fc572020-11-18 13:26:57 +0100564 f_vty_transceive(GBPVTY, "nsvc nsei " & int2str(g_sgsn[i].cfg.nsei) & " force-unconfigured");
Daniel Willmannad93c052020-12-04 14:14:38 +0100565 }
566 for (i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
567 f_vty_transceive(GBPVTY, "nsvc nsei " & int2str(g_pcu[i].cfg.nsei) & " force-unconfigured");
568 f_vty_transceive(GBPVTY, "delete-gbproxy-peer " & int2str(g_pcu[i].cfg.nsei) & " only-bvc");
569 }
570
571 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
Harald Welteea1ba592020-11-17 18:05:13 +0100572 f_init_gb_sgsn(g_sgsn[i], "GbProxy_Test", i);
Harald Welte6d63f742020-11-15 19:44:04 +0100573 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200574 f_sleep(4.0);
Harald Welte6d63f742020-11-15 19:44:04 +0100575 for (i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
Harald Welteb419d0e2020-11-16 16:45:05 +0100576 f_init_gb_pcu(g_pcu[i], "GbProxy_Test", i);
Harald Welte6d63f742020-11-15 19:44:04 +0100577 }
Harald Weltefbae83f2020-11-15 23:25:55 +0100578
Harald Welteb978ed62020-12-12 14:01:11 +0100579 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
580 bvci_unblocked[i] := {};
581 }
582
Harald Weltefbae83f2020-11-15 23:25:55 +0100583 /* wait until all BVC are unblocked on both sides */
Harald Welted2801272020-11-17 19:22:58 +0100584 timer T := 15.0;
Harald Weltefbae83f2020-11-15 23:25:55 +0100585 T.start;
586 alt {
Harald Welteb978ed62020-12-12 14:01:11 +0100587 /* TODO: We need to add more lines if NUM_SGSN increases. Activating default altsteps
588 * unfortunately doesn't work as we want to access the local variable bvci_unblocked. */
589 [] as_count_unblocked4nse(0, bvci_unblocked);
590 [lengthof(g_sgsn) > 1] as_count_unblocked4nse(1, bvci_unblocked);
Harald Weltefbae83f2020-11-15 23:25:55 +0100591 [] SGSN_MGMT.receive(BssgpStatusIndication:{*, ?, ?}) {
592 repeat;
593 }
Harald Welte3c905152020-11-26 20:56:09 +0100594 [] SGSN_MGMT.receive(BssgpResetIndication:?) {
595 repeat;
596 }
Harald Weltefbae83f2020-11-15 23:25:55 +0100597 [] SGSN_MGMT.receive {
Harald Welted5b7e742021-01-27 10:50:24 +0100598 f_shutdown(__FILE__, __LINE__, fail, "Received unexpected message on SGSN_MGMT");
Harald Weltefbae83f2020-11-15 23:25:55 +0100599 }
600
601 [] PCU_MGMT.receive(BssgpStatusIndication:{*, ?, BVC_S_UNBLOCKED}) -> value bsi {
602 repeat;
603 }
604 [] PCU_MGMT.receive(BssgpStatusIndication:{*, ?, ?}) {
605 repeat;
606 }
607 [] PCU_MGMT.receive(BssgpResetIndication:{0}) {
608 repeat;
609 }
610 [] PCU_MGMT.receive {
Harald Welted5b7e742021-01-27 10:50:24 +0100611 f_shutdown(__FILE__, __LINE__, fail, "Received unexpected message on PCU_MGMT");
Harald Weltefbae83f2020-11-15 23:25:55 +0100612 }
613
614 [] T.timeout {
Harald Welte6929e322020-12-12 13:10:45 +0100615 setverdict(fail, "Timeout waiting for unblock of all BVCs on SGSN side; ",
Harald Welteb978ed62020-12-12 14:01:11 +0100616 "unblocked so far: ", bvci_unblocked);
Harald Welte6929e322020-12-12 13:10:45 +0100617 /* don't stop here but print below analysis */
Harald Weltefbae83f2020-11-15 23:25:55 +0100618 }
619 }
620
Harald Welteb978ed62020-12-12 14:01:11 +0100621 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
622 /* iterate over list and check all BVCI */
623 for (var integer j := 0; j < lengthof(g_sgsn[i].cfg.bvc); j := j+1) {
624 var BssgpBvci bvci := g_sgsn[i].cfg.bvc[j].bvci;
625 if (not ro_integer_contains(bvci_unblocked[i], bvci)) {
Harald Welted5b7e742021-01-27 10:50:24 +0100626 f_shutdown(__FILE__, __LINE__, fail,
627 log2str("SGSN ", i, " BVCI=", bvci, " was not unblocked during start-up"));
Harald Welteb978ed62020-12-12 14:01:11 +0100628 }
Harald Weltefbae83f2020-11-15 23:25:55 +0100629 }
630 }
Harald Welte425d3762020-12-09 14:33:18 +0100631
Harald Welteb5688f22021-03-30 16:28:04 +0200632 /* verify all SGSN-side BVC FSM in IUT are UNBLOCKED */
633 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
634 f_bvc_fsm_ensure_state(mp_nsconfig_sgsn[i].nsei, 0, "UNBLOCKED");
635 /* iterate over list and check all BVCI */
636 for (var integer j := 0; j < lengthof(g_sgsn[i].cfg.bvc); j := j+1) {
637 var BssgpBvci bvci := g_sgsn[i].cfg.bvc[j].bvci;
638 f_bvc_fsm_ensure_state(mp_nsconfig_sgsn[i].nsei, bvci, "UNBLOCKED");
639 }
640 }
641 /* verify all PCU-side BVC FSM in IUT are UNBLOCKED */
642 for (i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
643 f_bvc_fsm_ensure_state(mp_nsconfig_pcu[i].nsei, 0, "UNBLOCKED");
644 /* iterate over list and check all BVCI */
645 for (var integer j := 0; j < lengthof(g_pcu[i].cfg.bvc); j := j+1) {
646 var BssgpBvci bvci := g_pcu[i].cfg.bvc[j].bvci;
647 f_bvc_fsm_ensure_state(mp_nsconfig_pcu[i].nsei, bvci, "UNBLOCKED");
648 }
649 }
650
Harald Welte425d3762020-12-09 14:33:18 +0100651 /* re-start guard timer after all BVCs are up, so it only counts the actual test case */
652 g_Tguard.start(t_guard);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200653}
654
655function f_cleanup() runs on test_CT {
Harald Welteb9f0fdc2020-12-09 14:44:50 +0100656 var integer i;
657
Daniel Willmann491af2a2021-01-08 01:32:51 +0100658 /* To avoid a dynamic test case error we need to prevent messages arriving on unconnected
659 * ports. Waiting here ensures that any messages "in flight" will be delivered to the port
660 * before the component is shutdown and disconnected. */
661 f_sleep(0.2);
662
Harald Welteb9f0fdc2020-12-09 14:44:50 +0100663 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
664 f_destroy_gb(g_sgsn[i]);
665 }
666 for (i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
667 f_destroy_gb(g_pcu[i]);
668 }
669
670 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, pass);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200671}
672
673type function void_fn(charstring id) runs on BSSGP_ConnHdlr;
674
675/* helper function to create, connect and start a BSSGP_ConnHdlr component */
Harald Welte207166c2021-01-16 12:52:30 +0100676function f_start_handler(void_fn fn, charstring id, integer imsi_suffix, float t_guard := 30.0,
677 integer sgsn_idx := 0, integer nri_idx := 0, boolean have_ptmsi := true)
Daniel Willmann423d8f42020-09-08 18:58:22 +0200678runs on test_CT return BSSGP_ConnHdlr {
679 var BSSGP_ConnHdlr vc_conn;
Harald Weltec5f486b2021-01-16 11:07:01 +0100680 var integer nri := mp_sgsn_nri[sgsn_idx][nri_idx];
Harald Welte77218d02021-01-15 19:59:15 +0100681 var OCT4 p_tmsi := f_gen_tmsi(imsi_suffix, nri_v := nri, nri_bitlen := mp_nri_bitlength);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200682
683 var BSSGP_ConnHdlrPars pars := {
684 imei := f_gen_imei(imsi_suffix),
685 imsi := f_gen_imsi(imsi_suffix),
686 msisdn := f_gen_msisdn(imsi_suffix),
Harald Weltedbd5e672021-01-14 21:03:14 +0100687 p_tmsi := p_tmsi,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200688 p_tmsi_sig := omit,
Harald Weltedbd5e672021-01-14 21:03:14 +0100689 tlli := f_gprs_tlli_from_tmsi(p_tmsi, TLLI_LOCAL),
Daniel Willmann423d8f42020-09-08 18:58:22 +0200690 tlli_old := omit,
691 ra := omit,
Harald Welte2ecbca82021-01-16 11:23:09 +0100692 pcu := g_pcu,
693 sgsn := g_sgsn,
Harald Weltec5f486b2021-01-16 11:07:01 +0100694 sgsn_idx := sgsn_idx,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200695 t_guard := t_guard
696 };
Harald Welte207166c2021-01-16 12:52:30 +0100697 if (not have_ptmsi) {
698 pars.p_tmsi := omit;
699 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200700
701 vc_conn := BSSGP_ConnHdlr.create(id);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200702
Harald Welte25a04b12021-01-17 11:09:49 +0100703 log("Starting ", id, " for SGSN[", sgsn_idx, "], NRI=", nri, ", P-TMSI=", pars.p_tmsi,
704 ", TLLI=", pars.tlli, ", IMSI=", pars.imsi, " on component=", vc_conn);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200705 vc_conn.start(f_handler_init(fn, id, pars));
706 return vc_conn;
707}
708
Harald Welte207166c2021-01-16 12:52:30 +0100709function f_start_handlers(void_fn fn, charstring id, integer imsi_suffix, float t_guard := 30.0,
710 boolean have_ptmsi := true)
Harald Weltec5f486b2021-01-16 11:07:01 +0100711runs on test_CT
712{
713 var integer sgsn_idx, nri_idx;
714 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx:=sgsn_idx+1) {
715 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx:=nri_idx+1) {
716 var integer extd_imsi_suffix := 1000*sgsn_idx + 100*nri_idx;
717 var BSSGP_ConnHdlr vc_conn;
Harald Welte207166c2021-01-16 12:52:30 +0100718 vc_conn := f_start_handler(fn, id, extd_imsi_suffix, t_guard, sgsn_idx, nri_idx,
719 have_ptmsi);
Harald Weltec5f486b2021-01-16 11:07:01 +0100720 /* Idea: we could also run them in parallel ? */
721 vc_conn.done;
722 }
723 }
724}
725
Harald Welte3dd21b32020-11-17 19:21:00 +0100726/* 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 +0100727private function f_connect_to_pcu_bvc(integer port_idx, integer nse_idx, integer bvc_idx)
728runs on BSSGP_ConnHdlr {
729 var BSSGP_BVC_CT bvc_ct := g_pars.pcu[nse_idx].vc_BSSGP_BVC[bvc_idx]
Harald Welte158becf2020-12-09 12:32:32 +0100730 if (PCU_PTP[port_idx].checkstate("Connected")) {
Harald Welte3dd21b32020-11-17 19:21:00 +0100731 /* unregister + disconnect from old BVC */
732 f_client_unregister(g_pars.imsi, PCU_PROC[port_idx]);
Harald Welte158becf2020-12-09 12:32:32 +0100733 disconnect(self:PCU_PTP[port_idx], pcu_ct[port_idx]:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100734 disconnect(self:PCU_SIG[port_idx], pcu_ct[port_idx]:BSSGP_SP_SIG);
735 disconnect(self:PCU_PROC[port_idx], pcu_ct[port_idx]:BSSGP_PROC);
736 }
737 /* connect to new BVC and register us */
Harald Welte158becf2020-12-09 12:32:32 +0100738 connect(self:PCU_PTP[port_idx], bvc_ct:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100739 connect(self:PCU_SIG[port_idx], bvc_ct:BSSGP_SP_SIG);
740 connect(self:PCU_PROC[port_idx], bvc_ct:BSSGP_PROC);
741 f_client_register(g_pars.imsi, g_pars.tlli, PCU_PROC[port_idx]);
742 pcu_ct[port_idx] := bvc_ct;
Harald Welte0e188242020-11-22 21:46:48 +0100743 pcu_bvc_cfg[port_idx] := g_pars.pcu[nse_idx].cfg.bvc[bvc_idx];
Harald Welte3dd21b32020-11-17 19:21:00 +0100744}
745
746/* Connect the SGSN-side per-BVC ports (SGSN/SGSN_SIG/SGSN_PROC) array slot 'port_idx' to specified per-BVC component */
747private function f_connect_to_sgsn_bvc(integer port_idx, BSSGP_BVC_CT bvc_ct) runs on BSSGP_ConnHdlr {
Harald Welte158becf2020-12-09 12:32:32 +0100748 if (SGSN_PTP[port_idx].checkstate("Connected")) {
Harald Welte3dd21b32020-11-17 19:21:00 +0100749 /* unregister + disconnect from old BVC */
750 f_client_unregister(g_pars.imsi, SGSN_PROC[port_idx]);
Harald Welte158becf2020-12-09 12:32:32 +0100751 disconnect(self:SGSN_PTP[port_idx], sgsn_ct[port_idx]:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100752 disconnect(self:SGSN_SIG[port_idx], sgsn_ct[port_idx]:BSSGP_SP_SIG);
753 disconnect(self:SGSN_PROC[port_idx], sgsn_ct[port_idx]:BSSGP_PROC);
754 }
755 /* connect to new BVC and register us */
Harald Welte158becf2020-12-09 12:32:32 +0100756 connect(self:SGSN_PTP[port_idx], bvc_ct:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100757 connect(self:SGSN_SIG[port_idx], bvc_ct:BSSGP_SP_SIG);
758 connect(self:SGSN_PROC[port_idx], bvc_ct:BSSGP_PROC);
759 f_client_register(g_pars.imsi, g_pars.tlli, SGSN_PROC[port_idx]);
760 sgsn_ct[port_idx] := bvc_ct;
761}
762
Harald Welte425d3762020-12-09 14:33:18 +0100763private altstep as_gTguard(timer Tguard) {
764 [] Tguard.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +0100765 f_shutdown(__FILE__, __LINE__, fail, "Tguard timeout");
Daniel Willmann423d8f42020-09-08 18:58:22 +0200766 }
767}
768
769/* first function called in every ConnHdlr */
770private function f_handler_init(void_fn fn, charstring id, BSSGP_ConnHdlrPars pars)
771runs on BSSGP_ConnHdlr {
Harald Welte1e834f32020-11-15 20:02:59 +0100772 var integer i;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200773 /* do some common stuff like setting up g_pars */
774 g_pars := pars;
775
776 llc := f_llc_create(false);
777
Harald Welte3dd21b32020-11-17 19:21:00 +0100778 /* default connections on PCU side: First BVC of each NSE/PCU */
779 for (i := 0; i < lengthof(g_pars.pcu); i := i+1) {
Harald Welte0e188242020-11-22 21:46:48 +0100780 f_connect_to_pcu_bvc(port_idx := i, nse_idx := i, bvc_idx := 0);
Harald Welte1e834f32020-11-15 20:02:59 +0100781 }
Harald Welte3dd21b32020-11-17 19:21:00 +0100782
783 /* default connections on SGSN side: First BVC of each NSE/SGSN */
784 for (i := 0; i < lengthof(g_pars.sgsn); i := i+1) {
785 f_connect_to_sgsn_bvc(i, g_pars.sgsn[i].vc_BSSGP_BVC[0]);
Harald Welte1e834f32020-11-15 20:02:59 +0100786 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200787
788 g_Tguard.start(pars.t_guard);
Harald Welte425d3762020-12-09 14:33:18 +0100789 activate(as_gTguard(g_Tguard));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200790
791 /* call the user-supplied test case function */
792 fn.apply(id);
Harald Welteb33fb592021-01-16 12:50:56 +0100793
794 for (i := 0; i < NUM_SGSN; i := i+1) {
795 if (SGSN_PROC[i].checkstate("Connected")) {
796 f_client_unregister(g_pars.imsi, SGSN_PROC[i])
797 }
798 }
799
800 for (i := 0; i < NUM_PCU; i := i+1) {
801 if (PCU_PROC[i].checkstate("Connected")) {
802 f_client_unregister(g_pars.imsi, PCU_PROC[i])
803 }
804 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200805}
806
Harald Welte1e834f32020-11-15 20:02:59 +0100807private function f_client_register(hexstring imsi, OCT4 tlli, BSSGP_PROC_PT PT)
808runs on BSSGP_ConnHdlr {
809 PT.call(BSSGP_register_client:{imsi, tlli}) {
810 [] PT.getreply(BSSGP_register_client:{imsi, tlli}) {};
811 }
812}
813
814private function f_client_unregister(hexstring imsi, BSSGP_PROC_PT PT)
815runs on BSSGP_ConnHdlr {
816 PT.call(BSSGP_unregister_client:{imsi}) {
817 [] PT.getreply(BSSGP_unregister_client:{imsi}) {};
818 }
819}
820
Harald Welte22ef5d92020-11-16 13:35:14 +0100821/* Send 'tx' on PTP-BVCI from PCU; expect 'rx' on SGSN */
822friend function f_pcu2sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
Harald Weltec5f486b2021-01-16 11:07:01 +0100823 integer pcu_idx := 0, boolean use_sig := false) runs on BSSGP_ConnHdlr {
824 var integer sgsn_idx := g_pars.sgsn_idx;
Harald Welte22ef5d92020-11-16 13:35:14 +0100825 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +0100826 timer T := 2.0;
Harald Welte22ef5d92020-11-16 13:35:14 +0100827
Daniel Willmann4798fd72020-11-24 16:23:29 +0100828 if (use_sig) {
829 PCU_SIG[pcu_idx].send(tx);
830 } else {
Harald Welte158becf2020-12-09 12:32:32 +0100831 PCU_PTP[pcu_idx].send(tx);
Daniel Willmann4798fd72020-11-24 16:23:29 +0100832 }
833
Harald Welte22ef5d92020-11-16 13:35:14 +0100834 T.start;
835 alt {
Daniel Willmann4798fd72020-11-24 16:23:29 +0100836 [use_sig] SGSN_SIG[sgsn_idx].receive(exp_rx) {
837 setverdict(pass);
838 }
Harald Welte158becf2020-12-09 12:32:32 +0100839 [not use_sig] SGSN_PTP[sgsn_idx].receive(exp_rx) {
Harald Welte22ef5d92020-11-16 13:35:14 +0100840 setverdict(pass);
841 }
Harald Welte158becf2020-12-09 12:32:32 +0100842 [] SGSN_PTP[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +0100843 f_shutdown(__FILE__, __LINE__, fail,
844 log2str("Unexpected BSSGP on SGSN[", sgsn_idx, "] side: ", rx));
Harald Welte22ef5d92020-11-16 13:35:14 +0100845 }
Daniel Willmann4798fd72020-11-24 16:23:29 +0100846 [] SGSN_SIG[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +0100847 f_shutdown(__FILE__, __LINE__, fail,
848 log2str("Unexpected SIG BSSGP on SGSN[", sgsn_idx, "] side: ", rx));
Daniel Willmann4798fd72020-11-24 16:23:29 +0100849 }
Harald Welte22ef5d92020-11-16 13:35:14 +0100850 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +0100851 f_shutdown(__FILE__, __LINE__, fail,
852 log2str("Timeout waiting for BSSGP on SGSN[", sgsn_idx, "] side: ", exp_rx));
Harald Welte22ef5d92020-11-16 13:35:14 +0100853 }
854 }
855}
856
Harald Welte3148a962021-01-17 11:15:28 +0100857/* Send 'tx' from PCU; expect 'exp_rx' on _any_ SGSN */
858friend function f_pcu2any_sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
859 integer pcu_idx := 0, boolean use_sig := false)
860runs on BSSGP_ConnHdlr return integer {
861 var integer rx_idx := -1;
862 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +0100863 timer T := 2.0;
Harald Welte3148a962021-01-17 11:15:28 +0100864
865 if (use_sig) {
866 PCU_SIG[pcu_idx].send(tx);
867 } else {
868 PCU_PTP[pcu_idx].send(tx);
869 }
870
871 T.start;
872 alt {
873 [use_sig] any from SGSN_SIG.receive(exp_rx) -> @index value rx_idx {
874 setverdict(pass);
875 }
876 [not use_sig] any from SGSN_PTP.receive(exp_rx) -> @index value rx_idx {
877 setverdict(pass);
878 }
879 [] any from SGSN_PTP.receive(PDU_BSSGP:?) -> value rx @index value rx_idx {
Harald Welted5b7e742021-01-27 10:50:24 +0100880 f_shutdown(__FILE__, __LINE__, fail,
881 log2str("Unexpected BSSGP on SGSN[", rx_idx, "] side: ", rx));
Harald Welte3148a962021-01-17 11:15:28 +0100882 }
883 [] any from SGSN_SIG.receive(PDU_BSSGP:?) -> value rx @index value rx_idx {
Harald Welted5b7e742021-01-27 10:50:24 +0100884 f_shutdown(__FILE__, __LINE__, fail,
885 log2str("Unexpected SIG BSSGP on SGSN[", rx_idx, "] side: ", rx));
Harald Welte3148a962021-01-17 11:15:28 +0100886 }
887 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +0100888 f_shutdown(__FILE__, __LINE__, fail,
889 log2str("Timeout waiting for BSSGP on SGSN side: ", exp_rx));
Harald Welte3148a962021-01-17 11:15:28 +0100890 }
891 }
892 return rx_idx;
893}
894
Harald Welte22ef5d92020-11-16 13:35:14 +0100895/* Send 'tx' on PTP-BVCI from SGSN; expect 'rx' on PCU */
896friend function f_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
Harald Weltec5f486b2021-01-16 11:07:01 +0100897 integer pcu_idx := 0, boolean use_sig := false) runs on BSSGP_ConnHdlr {
898 var integer sgsn_idx := g_pars.sgsn_idx;
Harald Welte22ef5d92020-11-16 13:35:14 +0100899 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +0100900 timer T := 2.0;
Harald Welte22ef5d92020-11-16 13:35:14 +0100901
Daniel Willmann4798fd72020-11-24 16:23:29 +0100902 if (use_sig) {
903 SGSN_SIG[sgsn_idx].send(tx);
904 } else {
Harald Welte158becf2020-12-09 12:32:32 +0100905 SGSN_PTP[sgsn_idx].send(tx);
Daniel Willmann4798fd72020-11-24 16:23:29 +0100906 }
907
Harald Welte22ef5d92020-11-16 13:35:14 +0100908 T.start;
909 alt {
Daniel Willmann4798fd72020-11-24 16:23:29 +0100910 [use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
911 setverdict(pass);
912 }
Harald Welte158becf2020-12-09 12:32:32 +0100913 [not use_sig] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte22ef5d92020-11-16 13:35:14 +0100914 setverdict(pass);
915 }
Harald Welte158becf2020-12-09 12:32:32 +0100916 [] PCU_PTP[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +0100917 f_shutdown(__FILE__, __LINE__, fail, log2str("Unexpected BSSGP on PCU side: ", rx));
Harald Welte22ef5d92020-11-16 13:35:14 +0100918 }
Daniel Willmann4798fd72020-11-24 16:23:29 +0100919 [] PCU_SIG[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +0100920 f_shutdown(__FILE__, __LINE__, fail, log2str("Unexpected SIG BSSGP on PCU side: ", rx));
Daniel Willmann4798fd72020-11-24 16:23:29 +0100921 }
Harald Welte22ef5d92020-11-16 13:35:14 +0100922 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +0100923 f_shutdown(__FILE__, __LINE__, fail,
924 log2str("Timeout waiting for BSSGP on PCU side: ", exp_rx));
Harald Welte22ef5d92020-11-16 13:35:14 +0100925 }
926 }
927}
Harald Welte1e834f32020-11-15 20:02:59 +0100928
Harald Welte3807ed12020-11-24 19:05:22 +0100929/***********************************************************************
930 * GlobaLTest_CT: Using the per-NSE GLOBAL ports on PCU + SGSN side
931 ***********************************************************************/
932
933type component GlobalTest_CT extends test_CT {
934 port BSSGP_PT G_PCU[NUM_PCU];
Harald Welte04358652021-01-17 13:48:13 +0100935 var integer g_pcu_idx[NUM_PCU]; /* BVC index currently connected to G_PCU */
Harald Welte3807ed12020-11-24 19:05:22 +0100936 port BSSGP_PT G_SGSN[NUM_SGSN];
Harald Welte04358652021-01-17 13:48:13 +0100937 var integer g_sgsn_idx[NUM_SGSN]; /* BVC index currently connected to G_SGSN */
Harald Weltef86f1852021-01-16 21:56:17 +0100938 port BSSGP_PT RIM_PCU[NUM_PCU];
939 port BSSGP_PT RIM_SGSN[NUM_SGSN];
Harald Welte3807ed12020-11-24 19:05:22 +0100940};
941
Harald Welte299aa482020-12-09 15:10:55 +0100942/* connect the signaling BVC of each NSE to the G_PCU / G_SGSN ports */
Harald Welte3807ed12020-11-24 19:05:22 +0100943private function f_global_init() runs on GlobalTest_CT {
944 var integer i;
945 for (i := 0; i < lengthof(g_sgsn); i := i+1) {
946 connect(self:G_SGSN[i], g_sgsn[i].vc_BSSGP:GLOBAL);
Harald Weltef86f1852021-01-16 21:56:17 +0100947 connect(self:RIM_SGSN[i], g_sgsn[i].vc_BSSGP:RIM);
Harald Welte3807ed12020-11-24 19:05:22 +0100948 }
949 for (i := 0; i < lengthof(g_pcu); i := i+1) {
950 connect(self:G_PCU[i], g_pcu[i].vc_BSSGP:GLOBAL);
Harald Weltef86f1852021-01-16 21:56:17 +0100951 connect(self:RIM_PCU[i], g_pcu[i].vc_BSSGP:RIM);
Harald Welte3807ed12020-11-24 19:05:22 +0100952 }
953}
954
Harald Welte299aa482020-12-09 15:10:55 +0100955/* connect the first PTP BVC of each NSE to the G_PCU / G_SGSN ports */
956private function f_global_init_ptp() runs on GlobalTest_CT {
957 var integer i;
958 for (i := 0; i < lengthof(g_sgsn); i := i+1) {
Harald Welte04358652021-01-17 13:48:13 +0100959 log("Connecting G_SGSN[", i, "] to BVCI=", g_sgsn[i].cfg.bvc[0].bvci);
Harald Welte299aa482020-12-09 15:10:55 +0100960 connect(self:G_SGSN[i], g_sgsn[i].vc_BSSGP_BVC[0]:GLOBAL);
Harald Welte04358652021-01-17 13:48:13 +0100961 g_sgsn_idx[i] := 0;
Harald Welte299aa482020-12-09 15:10:55 +0100962 }
963 for (i := 0; i < lengthof(g_pcu); i := i+1) {
Harald Welte04358652021-01-17 13:48:13 +0100964 log("Connecting G_PCU[", i, "] to BVCI=", g_pcu[i].cfg.bvc[0].bvci);
Harald Welte299aa482020-12-09 15:10:55 +0100965 connect(self:G_PCU[i], g_pcu[i].vc_BSSGP_BVC[0]:GLOBAL);
Harald Welte04358652021-01-17 13:48:13 +0100966 g_pcu_idx[i] := 0;
Harald Welte299aa482020-12-09 15:10:55 +0100967 }
968}
969
Harald Welte04358652021-01-17 13:48:13 +0100970/* (re)connect G_SGSN[sgsn_idx] to a specific PTP BVCI */
971private function f_global_ptp_connect_sgsn_bvci(integer sgsn_idx, BssgpBvci bvci) runs on GlobalTest_CT
972{
973 var integer sgsn_bvc_idx := get_bvc_idx_for_bvci(g_sgsn[sgsn_idx], bvci);
974 var integer old_sgsn_bvc_idx := g_sgsn_idx[sgsn_idx];
975 disconnect(self:G_SGSN[sgsn_idx], g_sgsn[sgsn_idx].vc_BSSGP_BVC[old_sgsn_bvc_idx]:GLOBAL);
976 connect(self:G_SGSN[sgsn_idx], g_sgsn[sgsn_idx].vc_BSSGP_BVC[sgsn_bvc_idx]:GLOBAL);
977 g_sgsn_idx[sgsn_idx] := sgsn_bvc_idx;
978}
979
980/* (re)connect G_PCU[pcu_idx] to a specific PTP BVCI */
981private function f_global_ptp_connect_pcu_bvci(integer pcu_idx, BssgpBvci bvci) runs on GlobalTest_CT
982{
983 var integer pcu_bvc_idx := get_bvc_idx_for_bvci(g_pcu[pcu_idx], bvci);
984 var integer old_pcu_bvc_idx := g_pcu_idx[pcu_idx];
985 disconnect(self:G_PCU[pcu_idx], g_pcu[pcu_idx].vc_BSSGP_BVC[old_pcu_bvc_idx]:GLOBAL);
986 connect(self:G_PCU[pcu_idx], g_pcu[pcu_idx].vc_BSSGP_BVC[pcu_bvc_idx]:GLOBAL);
987 g_pcu_idx[pcu_idx] := pcu_bvc_idx;
988}
989
Harald Welte3807ed12020-11-24 19:05:22 +0100990/* Send 'tx' on PTP-BVCI from PCU; expect 'rx' on SGSN */
991friend function f_global_pcu2sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
992 integer pcu_idx := 0, integer sgsn_idx := 0) runs on GlobalTest_CT {
Harald Welte04358652021-01-17 13:48:13 +0100993 var integer rx_idx;
Harald Welte3807ed12020-11-24 19:05:22 +0100994 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +0100995 timer T := 2.0;
Harald Welte3807ed12020-11-24 19:05:22 +0100996
997 G_PCU[pcu_idx].send(tx);
998 T.start;
999 alt {
1000 [] G_SGSN[sgsn_idx].receive(exp_rx) {
1001 setverdict(pass);
1002 }
Harald Welte04358652021-01-17 13:48:13 +01001003 [] any from G_SGSN.receive(exp_rx) -> @index value rx_idx {
1004 setverdict(fail, "BSSGP arrived on wrong SGSN[", rx_idx, "] instead of SGSN[", sgsn_idx, "]");
1005 }
Harald Welte3807ed12020-11-24 19:05:22 +01001006 [] G_SGSN[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +01001007 f_shutdown(__FILE__, __LINE__, fail, log2str("Unexpected BSSGP on SGSN side: ", rx));
Harald Welte3807ed12020-11-24 19:05:22 +01001008 }
1009 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +01001010 f_shutdown(__FILE__, __LINE__, fail, log2str("Timeout waiting for BSSGP on SGSN side: ", exp_rx));
Harald Welte3807ed12020-11-24 19:05:22 +01001011 }
1012 }
1013}
1014
1015/* Send 'tx' on PTP-BVCI from SGSN; expect 'rx' on PCU */
1016friend function f_global_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
1017 integer sgsn_idx := 0, integer pcu_idx := 0) runs on GlobalTest_CT {
Harald Welte04358652021-01-17 13:48:13 +01001018 var integer rx_idx;
Harald Welte3807ed12020-11-24 19:05:22 +01001019 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +01001020 timer T := 2.0;
Harald Welte3807ed12020-11-24 19:05:22 +01001021
1022 G_SGSN[sgsn_idx].send(tx);
1023 T.start;
1024 alt {
1025 [] G_PCU[pcu_idx].receive(exp_rx) {
1026 setverdict(pass);
1027 }
Harald Welte04358652021-01-17 13:48:13 +01001028 [] any from G_PCU.receive(exp_rx) -> @index value rx_idx {
1029 setverdict(fail, "BSSGP arrived on wrong PCU[", rx_idx, "] instead of PCU[", pcu_idx, "]");
1030 }
Harald Welte3807ed12020-11-24 19:05:22 +01001031 [] G_PCU[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +01001032 f_shutdown(__FILE__, __LINE__, fail, log2str("Unexpected BSSGP on PCU side: ", rx));
Harald Welte3807ed12020-11-24 19:05:22 +01001033 }
1034 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +01001035 f_shutdown(__FILE__, __LINE__, fail, log2str("Timeout waiting for BSSGP on PCU side: ", exp_rx));
Harald Welte3807ed12020-11-24 19:05:22 +01001036 }
1037 }
1038}
1039
1040
Daniel Willmann423d8f42020-09-08 18:58:22 +02001041/* TODO:
1042 * Detach without Attach
1043 * SM procedures without attach / RAU
1044 * ATTACH / RAU
1045 ** with / without authentication
1046 ** with / without P-TMSI allocation
1047 * re-transmissions of LLC frames
1048 * PDP Context activation
1049 ** with different GGSN config in SGSN VTY
1050 ** with different PDP context type (v4/v6/v46)
1051 ** timeout from GGSN
1052 ** multiple / secondary PDP context
1053 */
1054
1055private function f_TC_BVC_bringup(charstring id) runs on BSSGP_ConnHdlr {
1056 f_sleep(5.0);
1057 setverdict(pass);
1058}
1059
1060testcase TC_BVC_bringup() runs on test_CT {
Daniel Willmann423d8f42020-09-08 18:58:22 +02001061 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001062 f_start_handlers(refers(f_TC_BVC_bringup), testcasename(), 51);
Daniel Willmann423d8f42020-09-08 18:58:22 +02001063 f_cleanup();
1064}
1065
1066friend function f_bssgp_suspend(integer ran_idx := 0) runs on BSSGP_ConnHdlr return OCT1 {
Harald Welte16357a92020-11-17 18:20:00 +01001067 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Daniel Willmann423d8f42020-09-08 18:58:22 +02001068 timer T := 5.0;
1069 var PDU_BSSGP rx_pdu;
Harald Welte16357a92020-11-17 18:20:00 +01001070 PCU_SIG[ran_idx].send(ts_BSSGP_SUSPEND(g_pars.tlli, bvcc.cell_id.ra_id));
Daniel Willmann423d8f42020-09-08 18:58:22 +02001071 T.start;
1072 alt {
Harald Welte16357a92020-11-17 18:20:00 +01001073 [] 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 +02001074 return rx_pdu.pDU_BSSGP_SUSPEND_ACK.suspend_Reference_Number.suspend_Reference_Number_value;
1075 }
Harald Welte16357a92020-11-17 18:20:00 +01001076 [] PCU_SIG[ran_idx].receive(tr_BSSGP_SUSPEND_NACK(g_pars.tlli, bvcc.cell_id.ra_id, ?)) -> value rx_pdu {
Harald Welted5b7e742021-01-27 10:50:24 +01001077 f_shutdown(__FILE__, __LINE__, fail,
1078 log2str("SUSPEND-NACK in response to SUSPEND for TLLI ", g_pars.tlli));
Daniel Willmann423d8f42020-09-08 18:58:22 +02001079 }
1080 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +01001081 f_shutdown(__FILE__, __LINE__, fail,
1082 log2str("No SUSPEND-ACK in response to SUSPEND for TLLI ", g_pars.tlli));
Daniel Willmann423d8f42020-09-08 18:58:22 +02001083 }
1084 }
1085 return '00'O;
1086}
1087
1088friend function f_bssgp_resume(OCT1 susp_ref, integer ran_idx := 0) runs on BSSGP_ConnHdlr {
Harald Welte16357a92020-11-17 18:20:00 +01001089 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Daniel Willmann423d8f42020-09-08 18:58:22 +02001090 timer T := 5.0;
Harald Welte16357a92020-11-17 18:20:00 +01001091 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 +02001092 T.start;
1093 alt {
Harald Welte16357a92020-11-17 18:20:00 +01001094 [] PCU_SIG[ran_idx].receive(tr_BSSGP_RESUME_ACK(g_pars.tlli, bvcc.cell_id.ra_id));
1095 [] PCU_SIG[ran_idx].receive(tr_BSSGP_RESUME_NACK(g_pars.tlli, bvcc.cell_id.ra_id, ?)) {
Harald Welted5b7e742021-01-27 10:50:24 +01001096 f_shutdown(__FILE__, __LINE__, fail,
1097 log2str("RESUME-NACK in response to RESUME for TLLI ", g_pars.tlli));
Daniel Willmann423d8f42020-09-08 18:58:22 +02001098 }
1099 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +01001100 f_shutdown(__FILE__, __LINE__, fail,
1101 log2str("No RESUME-ACK in response to SUSPEND for TLLI ", g_pars.tlli));
Daniel Willmann423d8f42020-09-08 18:58:22 +02001102 }
1103 }
1104}
1105
1106
Harald Welte92686012020-11-15 21:45:49 +01001107/* send uplink-unitdata of a variety of different sizes; expect it to show up on SGSN */
1108private function f_TC_ul_unitdata(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte16357a92020-11-17 18:20:00 +01001109 var integer ran_idx := 0;
1110 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Harald Welte92686012020-11-15 21:45:49 +01001111 var integer i;
1112
Harald Welte0d5fceb2020-11-29 16:04:07 +01001113 for (i := 0; i < max_fr_info_size-4; i := i+4) {
Harald Welte92686012020-11-15 21:45:49 +01001114 var octetstring payload := f_rnd_octstring(i);
Harald Welte16357a92020-11-17 18:20:00 +01001115 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 +01001116 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte16357a92020-11-17 18:20:00 +01001117 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 +01001118
Harald Welte0d5fceb2020-11-29 16:04:07 +01001119 log("UL-UNITDATA(payload_size=", i);
Harald Welte22ef5d92020-11-16 13:35:14 +01001120 f_pcu2sgsn(pdu_tx, pdu_rx);
Harald Welte92686012020-11-15 21:45:49 +01001121 }
1122 setverdict(pass);
1123}
1124
1125testcase TC_ul_unitdata() runs on test_CT
1126{
Daniel Willmannc879f342021-02-11 14:28:01 +01001127 f_init(60.0);
Harald Welte2ecbca82021-01-16 11:23:09 +01001128 f_start_handlers(refers(f_TC_ul_unitdata), testcasename(), 1);
Harald Welte92686012020-11-15 21:45:49 +01001129 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Welte92686012020-11-15 21:45:49 +01001130 f_cleanup();
1131}
1132
Harald Welte78d8db92020-11-15 23:27:27 +01001133/* send downlink-unitdata of a variety of different sizes; expect it to show up on PCU */
1134private function f_TC_dl_unitdata(charstring id) runs on BSSGP_ConnHdlr {
1135 var integer i;
1136
Harald Welte0d5fceb2020-11-29 16:04:07 +01001137 for (i := 0; i < max_fr_info_size-4; i := i+4) {
Harald Welte78d8db92020-11-15 23:27:27 +01001138 var octetstring payload := f_rnd_octstring(i);
1139 var template (value) PDU_BSSGP pdu_tx :=
1140 ts_BSSGP_DL_UD(g_pars.tlli, payload, omit, ts_BSSGP_IMSI(g_pars.imsi));
1141 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1142 var template (present) PDU_BSSGP pdu_rx :=
Daniel Willmann325458d2021-02-11 14:22:42 +01001143 tr_BSSGP_DL_UD(g_pars.tlli, payload, tr_BSSGP_IMSI(g_pars.imsi));
Harald Welte78d8db92020-11-15 23:27:27 +01001144
Harald Welte0d5fceb2020-11-29 16:04:07 +01001145 log("DL-UNITDATA(payload_size=", i);
Harald Welte22ef5d92020-11-16 13:35:14 +01001146 f_sgsn2pcu(pdu_tx, pdu_rx);
Harald Welte78d8db92020-11-15 23:27:27 +01001147 }
1148 setverdict(pass);
1149}
1150
1151testcase TC_dl_unitdata() runs on test_CT
1152{
Daniel Willmannc879f342021-02-11 14:28:01 +01001153 f_init(60.0);
Harald Welte2ecbca82021-01-16 11:23:09 +01001154 f_start_handlers(refers(f_TC_dl_unitdata), testcasename(), 2);
Harald Welte78d8db92020-11-15 23:27:27 +01001155 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Welte78d8db92020-11-15 23:27:27 +01001156 f_cleanup();
1157}
Harald Welte92686012020-11-15 21:45:49 +01001158
Harald Welte6dc2ac42020-11-16 09:16:17 +01001159private function f_TC_ra_capability(charstring id) runs on BSSGP_ConnHdlr {
1160 var integer i;
1161
1162 for (i := 0; i < 10; i := i+1) {
1163 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RA_CAP(g_pars.tlli, { ts_RaCapRec_BSSGP });
1164 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1165 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RA_CAP(g_pars.tlli, { tr_RaCapRec_BSSGP })
1166
Harald Welte22ef5d92020-11-16 13:35:14 +01001167 f_sgsn2pcu(pdu_tx, pdu_rx);
Harald Welte6dc2ac42020-11-16 09:16:17 +01001168 }
1169 setverdict(pass);
1170}
1171testcase TC_ra_capability() runs on test_CT
1172{
Harald Welte6dc2ac42020-11-16 09:16:17 +01001173 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001174 f_start_handlers(refers(f_TC_ra_capability), testcasename(), 3);
Harald Welte6dc2ac42020-11-16 09:16:17 +01001175 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Welte6dc2ac42020-11-16 09:16:17 +01001176 f_cleanup();
1177}
1178
Daniel Willmannace3ece2020-11-16 19:53:26 +01001179private function f_TC_ra_capability_upd(charstring id) runs on BSSGP_ConnHdlr {
1180 var integer i;
1181 var OCT1 tag;
1182 for (i := 0; i < 10; i := i+1) {
1183 tag := int2oct(23 + i, 1);
1184 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RA_CAP_UPD(g_pars.tlli, tag);
1185 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1186 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RA_CAP_UPD(g_pars.tlli, tag)
1187
1188 f_pcu2sgsn(pdu_tx, pdu_rx);
1189
1190 pdu_tx := ts_BSSGP_RA_CAP_UPD_ACK(g_pars.tlli, tag, '42'O);
1191 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1192 pdu_rx := tr_BSSGP_RA_CAP_UPD_ACK(g_pars.tlli, tag, '42'O)
1193
1194 f_sgsn2pcu(pdu_tx, pdu_rx);
1195 }
1196 setverdict(pass);
1197}
1198testcase TC_ra_capability_upd() runs on test_CT
1199{
Daniel Willmannace3ece2020-11-16 19:53:26 +01001200 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001201 f_start_handlers(refers(f_TC_ra_capability_upd), testcasename(), 4);
Daniel Willmannace3ece2020-11-16 19:53:26 +01001202 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Daniel Willmannace3ece2020-11-16 19:53:26 +01001203 f_cleanup();
1204}
1205
Daniel Willmann165d6612020-11-19 14:27:29 +01001206private function f_TC_radio_status(charstring id) runs on BSSGP_ConnHdlr {
1207 var integer i;
1208 var BssgpRadioCause cause := BSSGP_RADIO_CAUSE_CONTACT_LOST;
1209 for (i := 0; i < 10; i := i+1) {
1210 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RADIO_STATUS(g_pars.tlli, cause);
1211 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1212 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RADIO_STATUS(g_pars.tlli, cause)
1213
1214 f_pcu2sgsn(pdu_tx, pdu_rx);
1215 }
1216 setverdict(pass);
1217}
1218testcase TC_radio_status() runs on test_CT
1219{
Daniel Willmann165d6612020-11-19 14:27:29 +01001220 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001221 f_start_handlers(refers(f_TC_radio_status), testcasename(), 5);
Daniel Willmann165d6612020-11-19 14:27:29 +01001222 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Daniel Willmann165d6612020-11-19 14:27:29 +01001223 f_cleanup();
1224}
1225
Harald Welte3148a962021-01-17 11:15:28 +01001226private function f_TC_radio_status_tmsi(charstring id) runs on BSSGP_ConnHdlr {
1227 var integer i;
1228 var BssgpRadioCause cause := BSSGP_RADIO_CAUSE_CONTACT_LOST;
1229 for (i := 0; i < 10; i := i+1) {
1230 var integer tmsi_int := oct2int(g_pars.p_tmsi);
1231 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RADIO_STATUS(omit, cause, tmsi_int);
1232 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1233 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RADIO_STATUS(omit, cause, tmsi_int);
1234 f_pcu2sgsn(pdu_tx, pdu_rx);
1235 }
1236 setverdict(pass);
1237}
1238testcase TC_radio_status_tmsi() runs on test_CT
1239{
1240 f_init();
1241 f_start_handlers(refers(f_TC_radio_status_tmsi), testcasename(), 5);
1242 f_cleanup();
1243}
1244
1245private function f_TC_radio_status_imsi(charstring id) runs on BSSGP_ConnHdlr {
1246 var integer i;
1247 var BssgpRadioCause cause := BSSGP_RADIO_CAUSE_CONTACT_LOST;
1248 for (i := 0; i < 10; i := i+1) {
1249 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RADIO_STATUS(omit, cause, imsi := g_pars.imsi);
1250 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1251 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RADIO_STATUS(omit, cause, imsi := g_pars.imsi);
1252 f_pcu2any_sgsn(pdu_tx, pdu_rx);
1253 }
1254 setverdict(pass);
1255}
1256testcase TC_radio_status_imsi() runs on test_CT
1257{
1258 f_init();
1259 f_start_handlers(refers(f_TC_radio_status_imsi), testcasename(), 5);
1260 f_cleanup();
1261}
1262
1263
1264
Harald Welte99ed5072021-01-15 20:38:58 +01001265private function f_suspend_one(integer sgsn_idx, integer nri_idx, integer pcu_idx, integer bvc_idx,
1266 integer suffix)
Harald Welte00963752021-01-15 20:33:11 +01001267runs on GlobalTest_CT
1268{
1269 var RoutingAreaIdentification ra_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id.ra_id;
Harald Welte99ed5072021-01-15 20:38:58 +01001270 var OCT4 p_tmsi := f_gen_tmsi(suffix, nri_v := mp_sgsn_nri[sgsn_idx][nri_idx],
1271 nri_bitlen := mp_nri_bitlength);
1272 var OCT4 tlli := f_gprs_tlli_from_tmsi(p_tmsi, TLLI_LOCAL);
Harald Welte00963752021-01-15 20:33:11 +01001273 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_SUSPEND(tlli, ra_id);
1274 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1275 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_SUSPEND(tlli, ra_id);
1276 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1277
1278 pdu_tx := ts_BSSGP_SUSPEND_ACK(tlli, ra_id, int2oct(suffix, 1));
1279 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1280 pdu_rx := tr_BSSGP_SUSPEND_ACK(tlli, ra_id, int2oct(suffix, 1));
1281 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1282
1283 pdu_tx := ts_BSSGP_SUSPEND(tlli, ra_id);
1284 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1285 pdu_rx := tr_BSSGP_SUSPEND(tlli, ra_id);
1286 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1287
1288 /* These messages are simple passed through so just also test sending NACK */
1289 pdu_tx := ts_BSSGP_SUSPEND_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1290 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1291 pdu_rx := tr_BSSGP_SUSPEND_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1292 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1293}
1294
Harald Weltec5c33732021-01-15 21:04:35 +01001295private function f_TC_suspend(integer sgsn_idx, integer nri_idx, integer pcu_idx, integer bvc_idx)
1296runs on GlobalTest_CT {
Daniel Willmannfa67f492020-11-19 15:48:05 +01001297 var integer i;
Daniel Willmann165d6612020-11-19 14:27:29 +01001298
Daniel Willmannfa67f492020-11-19 15:48:05 +01001299 for (i := 0; i < 10; i := i+1) {
Harald Weltec5c33732021-01-15 21:04:35 +01001300 f_suspend_one(sgsn_idx, nri_idx, pcu_idx, bvc_idx, suffix := i);
Daniel Willmannfa67f492020-11-19 15:48:05 +01001301 }
1302 setverdict(pass);
1303}
Harald Welte3807ed12020-11-24 19:05:22 +01001304testcase TC_suspend() runs on GlobalTest_CT
Daniel Willmannfa67f492020-11-19 15:48:05 +01001305{
Harald Weltec5c33732021-01-15 21:04:35 +01001306 var integer sgsn_idx, nri_idx;
Daniel Willmannfa67f492020-11-19 15:48:05 +01001307 f_init();
Harald Welte3807ed12020-11-24 19:05:22 +01001308 f_global_init();
Harald Weltec5c33732021-01-15 21:04:35 +01001309 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx+1) {
1310 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx+1) {
1311 f_TC_suspend(sgsn_idx, nri_idx, pcu_idx:=0, bvc_idx:=0);
1312 }
1313 }
Daniel Willmannfa67f492020-11-19 15:48:05 +01001314 f_cleanup();
1315}
Harald Welte6dc2ac42020-11-16 09:16:17 +01001316
Harald Welte99ed5072021-01-15 20:38:58 +01001317private function f_resume_one(integer sgsn_idx, integer nri_idx, integer pcu_idx, integer bvc_idx,
1318 integer suffix)
Harald Welte00963752021-01-15 20:33:11 +01001319runs on GlobalTest_CT
1320{
1321 var RoutingAreaIdentification ra_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id.ra_id;
Harald Welte99ed5072021-01-15 20:38:58 +01001322 var OCT4 p_tmsi := f_gen_tmsi(suffix, nri_v := mp_sgsn_nri[sgsn_idx][nri_idx],
1323 nri_bitlen := mp_nri_bitlength);
1324 var OCT4 tlli := f_gprs_tlli_from_tmsi(p_tmsi, TLLI_LOCAL);
Harald Welte00963752021-01-15 20:33:11 +01001325 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1326 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1327 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1328 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1329
1330 pdu_tx := ts_BSSGP_RESUME_ACK(tlli, ra_id);
1331 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1332 pdu_rx := tr_BSSGP_RESUME_ACK(tlli, ra_id);
1333 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1334
1335 pdu_tx := ts_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1336 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1337 pdu_rx := tr_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1338 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1339
1340 /* These messages are simple passed through so just also test sending NACK */
1341 pdu_tx := ts_BSSGP_RESUME_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1342 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1343 pdu_rx := tr_BSSGP_RESUME_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1344 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1345}
1346
Harald Weltec5c33732021-01-15 21:04:35 +01001347private function f_TC_resume(integer sgsn_idx, integer nri_idx, integer pcu_idx, integer bvc_idx)
1348runs on GlobalTest_CT {
Daniel Willmann087a33d2020-11-19 15:58:43 +01001349 var integer i;
1350
Daniel Willmann087a33d2020-11-19 15:58:43 +01001351 for (i := 0; i < 10; i := i+1) {
Harald Weltec5c33732021-01-15 21:04:35 +01001352 f_resume_one(sgsn_idx, nri_idx, pcu_idx, bvc_idx, suffix := i);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001353 }
1354 setverdict(pass);
1355}
Harald Welte3807ed12020-11-24 19:05:22 +01001356testcase TC_resume() runs on GlobalTest_CT
Daniel Willmann087a33d2020-11-19 15:58:43 +01001357{
Harald Weltec5c33732021-01-15 21:04:35 +01001358 var integer sgsn_idx, nri_idx;
Daniel Willmann087a33d2020-11-19 15:58:43 +01001359 f_init();
Harald Welte3807ed12020-11-24 19:05:22 +01001360 f_global_init();
Harald Weltec5c33732021-01-15 21:04:35 +01001361 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx+1) {
1362 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx+1) {
1363 f_TC_resume(sgsn_idx, nri_idx, pcu_idx:=0, bvc_idx:=0);
1364 }
1365 }
Daniel Willmann087a33d2020-11-19 15:58:43 +01001366 f_cleanup();
1367}
1368
Harald Weltef8ef0282020-11-18 12:16:59 +01001369/* test the load-sharing between multiple NS-VC on the BSS side */
1370private function f_TC_dl_ud_unidir(charstring id) runs on BSSGP_ConnHdlr {
1371 var integer i;
1372
1373 for (i := 0; i < 10; i := i+1) {
1374 var octetstring payload := f_rnd_octstring(i);
1375 var template (value) PDU_BSSGP pdu_tx :=
1376 ts_BSSGP_DL_UD(g_pars.tlli, payload, omit, ts_BSSGP_IMSI(g_pars.imsi));
Harald Welte09a1ce42021-01-16 11:18:38 +01001377 SGSN_PTP[g_pars.sgsn_idx].send(pdu_tx);
Harald Weltef8ef0282020-11-18 12:16:59 +01001378 }
1379 setverdict(pass);
1380}
Harald Welte09a1ce42021-01-16 11:18:38 +01001381
1382private function f_TC_load_sharing_dl(integer sgsn_idx) runs on test_CT_NS
Harald Weltef8ef0282020-11-18 12:16:59 +01001383{
1384 const integer num_ue := 10;
1385 var BSSGP_ConnHdlr vc_conn[num_ue];
Harald Weltef8ef0282020-11-18 12:16:59 +01001386 /* all BVC are now fully brought up. We disconnect BSSGP from NS on the BSS
1387 * side so we get the raw NsUnitdataIndication and hence observe different
1388 * NSVCI */
1389 disconnect(g_pcu[0].vc_NS:NS_SP, g_pcu[0].vc_BSSGP:BSCP);
1390 connect(g_pcu[0].vc_NS:NS_SP, self:NS);
1391
1392 /* there may still be some NS-VCs coming up? After all, the BVC-RESET succeeds after the first
1393 * of the NS-VC is ALIVE/UNBLOCKED */
1394 f_sleep(3.0);
1395
1396 /* start parallel components generating DL-UNITDATA from the SGSN side */
1397 for (var integer i:= 0; i < num_ue; i := i+1) {
Harald Welte2ecbca82021-01-16 11:23:09 +01001398 vc_conn[i] := f_start_handler(refers(f_TC_dl_ud_unidir), testcasename(),
Harald Welte09a1ce42021-01-16 11:18:38 +01001399 5+i, 30.0, sgsn_idx);
Harald Weltef8ef0282020-11-18 12:16:59 +01001400 }
1401
1402 /* now start counting all the messages that were queued before */
1403 /* TODO: We have a hard-coded assumption of 4 NS-VC in one NSE/NS-VCG here! */
1404 var ro_integer rx_count := { 0, 0, 0, 0 };
1405 timer T := 2.0;
1406 T.start;
1407 alt {
1408 [] as_NsUdiCount(0, rx_count);
1409 [] as_NsUdiCount(1, rx_count);
1410 [] as_NsUdiCount(2, rx_count);
1411 [] as_NsUdiCount(3, rx_count);
1412 [] NS.receive(NsUnitdataIndication:{0,?,?,*,*}) { repeat; } /* signaling BVC */
1413 [] NS.receive(NsStatusIndication:?) { repeat; }
1414 [] NS.receive {
Harald Welted5b7e742021-01-27 10:50:24 +01001415 f_shutdown(__FILE__, __LINE__, fail, "Rx unexpected NS");
Harald Weltef8ef0282020-11-18 12:16:59 +01001416 }
1417 [] T.timeout {
1418 }
1419 }
1420 for (var integer i := 0; i < lengthof(rx_count); i := i+1) {
1421 log("Rx on NSVCI ", mp_nsconfig_pcu[0].nsvc[i].nsvci, ": ", rx_count[i]);
1422 if (rx_count[i] == 0) {
1423 setverdict(fail, "Data not shared over all NSVC");
1424 }
1425 }
Harald Welte09a1ce42021-01-16 11:18:38 +01001426}
1427
1428testcase TC_load_sharing_dl() runs on test_CT_NS
1429{
1430 var integer sgsn_idx, nri_idx;
1431 f_init();
1432 for (sgsn_idx:=0; sgsn_idx < NUM_SGSN; sgsn_idx:=sgsn_idx+1) {
1433 f_TC_load_sharing_dl(sgsn_idx);
1434 }
Harald Weltef8ef0282020-11-18 12:16:59 +01001435 setverdict(pass);
1436}
1437private altstep as_NsUdiCount(integer nsvc_idx, inout ro_integer roi) runs on test_CT_NS {
1438 var NsUnitdataIndication udi;
1439 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[0];
1440 [] NS.receive(NsUnitdataIndication:{bvcc.bvci, g_pcu[0].cfg.nsei, mp_nsconfig_pcu[0].nsvc[nsvc_idx].nsvci, *, *}) -> value udi {
1441 roi[nsvc_idx] := roi[nsvc_idx] + 1;
1442 repeat;
1443 }
1444}
1445type component test_CT_NS extends test_CT {
1446 port NS_PT NS;
1447};
1448
1449
Harald Welte0e188242020-11-22 21:46:48 +01001450/***********************************************************************
1451 * PAGING PS procedure
1452 ***********************************************************************/
1453
1454private function f_send_paging_ps(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1455 boolean use_sig := false)
1456runs on BSSGP_ConnHdlr return template (present) PDU_BSSGP {
1457 var template (value) PDU_BSSGP pdu_tx;
1458 var template (present) PDU_BSSGP pdu_rx;
1459 /* we always specify '0' as BVCI in the templates below, as we override it with
1460 * 'p4' later anyway */
1461 pdu_rx := tr_BSSGP_PS_PAGING(0);
1462 pdu_rx.pDU_BSSGP_PAGING_PS.iMSI := tr_BSSGP_IMSI(g_pars.imsi);
1463 if (ispresent(g_pars.p_tmsi)) {
1464 pdu_tx := ts_BSSGP_PS_PAGING_PTMSI(0, g_pars.imsi, oct2int(g_pars.p_tmsi));
1465 pdu_rx.pDU_BSSGP_PAGING_PS.pTMSI := tr_BSSGP_TMSI(oct2int(g_pars.p_tmsi));
1466 } else {
1467 pdu_tx := ts_BSSGP_PS_PAGING_IMSI(0, g_pars.imsi);
1468 pdu_rx.pDU_BSSGP_PAGING_PS.pTMSI := omit;
1469 }
1470 pdu_tx.pDU_BSSGP_PAGING_PS.paging_Field4 := p4;
1471 pdu_rx.pDU_BSSGP_PAGING_PS.paging_Field4 := p4;
1472 if (use_sig == false) {
Harald Welte158becf2020-12-09 12:32:32 +01001473 SGSN_PTP[sgsn_idx].send(pdu_tx);
Harald Welte0e188242020-11-22 21:46:48 +01001474 } else {
1475 SGSN_SIG[sgsn_idx].send(pdu_tx);
1476 }
1477 return pdu_rx;
1478}
1479
1480/* send paging defined by 'p4' on given SGSN-side index (ptp or signaling) and expect one paging to arrive on
1481 * specified PCU index */
1482private function f_send_paging_ps_exp_one_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1483 boolean use_sig := false,integer pcu_idx := 0)
1484runs on BSSGP_ConnHdlr {
1485 var template (present) PDU_BSSGP exp_rx;
Daniel Willmann1a859712020-12-04 00:59:45 +01001486 var boolean test_done := false;
Harald Welte0e188242020-11-22 21:46:48 +01001487 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1488 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1489 exp_rx := f_send_paging_ps(p4, sgsn_idx, use_sig);
1490 /* Expect paging to propagate to the one BSS addressed by the BVCI only */
1491 timer T := 2.0;
1492 T.start;
1493 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001494 [not use_sig and not test_done] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001495 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001496 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001497 repeat;
1498 }
1499 [not use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
1500 setverdict(fail, "Received paging on SIGNALING BVC, expected PTP BVC");
1501 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001502 [use_sig and not test_done] PCU_SIG[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001503 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001504 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001505 repeat;
1506 }
Harald Welte158becf2020-12-09 12:32:32 +01001507 [use_sig] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001508 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1509 }
Harald Welte158becf2020-12-09 12:32:32 +01001510 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001511 setverdict(fail, "Paging received on unexpected BVC");
1512 }
1513 [] any from PCU_SIG.receive(exp_rx) {
1514 setverdict(fail, "Paging received on unexpected BVC");
1515 }
Harald Welte158becf2020-12-09 12:32:32 +01001516 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01001517 setverdict(fail, "Different Paging than expected received PTP BVC");
1518 }
1519 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1520 setverdict(fail, "Different Paging than expected on SIGNALING BVC");
1521 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001522 [not test_done] T.timeout {
1523 setverdict(fail, "Timeout waiting for paging");
1524 }
1525 [test_done] T.timeout;
Harald Welte0e188242020-11-22 21:46:48 +01001526 }
1527}
1528
Harald Welte7462a592020-11-23 22:07:07 +01001529/* send a PS-PAGING but don't expect it to show up on any PTP or SIG BVC */
1530private function f_send_paging_ps_exp_no_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1531 boolean use_sig := false)
1532runs on BSSGP_ConnHdlr {
1533 var template (present) PDU_BSSGP exp_rx;
1534 exp_rx := f_send_paging_ps(p4, sgsn_idx, use_sig);
1535 /* Expect paging to propagate to no BSS */
1536 timer T := 2.0;
1537 T.start;
1538 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001539 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte7462a592020-11-23 22:07:07 +01001540 setverdict(fail, "Paging received on unexpected BVC");
1541 }
1542 [] any from PCU_SIG.receive(exp_rx) {
1543 setverdict(fail, "Paging received on unexpected BVC");
1544 }
Harald Welte158becf2020-12-09 12:32:32 +01001545 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte7462a592020-11-23 22:07:07 +01001546 setverdict(fail, "Different Paging received on PTP BVC");
1547 }
1548 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1549 setverdict(fail, "Different Paging received on SIGNALING BVC");
1550 }
1551 [] T.timeout {
1552 setverdict(pass);
1553 }
1554 }
1555}
1556
Harald Welte0e188242020-11-22 21:46:48 +01001557private function f_TC_paging_ps_ptp_bss(charstring id) runs on BSSGP_ConnHdlr
1558{
1559 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1560 * at that BVC (cell) only, and paging all over the BSS area is not possible */
Daniel Willmann2a330672021-01-18 18:50:02 +01001561 f_send_paging_ps_exp_one_bss(ts_BssgpP4BssArea, g_pars.sgsn_idx, false, 0);
Harald Welte0e188242020-11-22 21:46:48 +01001562}
1563testcase TC_paging_ps_ptp_bss() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001564 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001565 f_start_handlers(refers(f_TC_paging_ps_ptp_bss), testcasename(), 9);
Harald Welte0e188242020-11-22 21:46:48 +01001566 f_cleanup();
1567}
1568
1569/* PS-PAGING on PTP-BVC for Location Area */
1570private function f_TC_paging_ps_ptp_lac(charstring id) runs on BSSGP_ConnHdlr
1571{
1572 var template (present) PDU_BSSGP exp_rx;
1573 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1574 * at that BVC (cell) only, and paging all over the BSS area is not possible */
Daniel Willmann2a330672021-01-18 18:50:02 +01001575 f_send_paging_ps_exp_one_bss(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), g_pars.sgsn_idx, false, 0);
Harald Welte0e188242020-11-22 21:46:48 +01001576}
1577testcase TC_paging_ps_ptp_lac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001578 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001579 f_start_handlers(refers(f_TC_paging_ps_ptp_lac), testcasename(), 10);
Harald Welte0e188242020-11-22 21:46:48 +01001580 f_cleanup();
1581}
1582
Harald Welte7462a592020-11-23 22:07:07 +01001583/* PS-PAGING on PTP-BVC for unknown Location Area */
1584private function f_TC_paging_ps_ptp_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1585{
1586 var GSM_Types.LocationAreaIdentification unknown_la := {
1587 mcc_mnc := '567F99'H,
1588 lac := 33333
1589 };
1590 /* as it's sent on the PTP BVC, we expect it to pass even for unknown LAC */
Daniel Willmann2a330672021-01-18 18:50:02 +01001591 f_send_paging_ps_exp_one_bss(ts_BssgpP4LAC(unknown_la), g_pars.sgsn_idx, false, 0);
Harald Welte7462a592020-11-23 22:07:07 +01001592}
1593testcase TC_paging_ps_ptp_lac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001594 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001595 f_start_handlers(refers(f_TC_paging_ps_ptp_lac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001596 f_cleanup();
1597}
1598
Harald Welte0e188242020-11-22 21:46:48 +01001599/* PS-PAGING on PTP-BVC for Routeing Area */
1600private function f_TC_paging_ps_ptp_rac(charstring id) runs on BSSGP_ConnHdlr
1601{
1602 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1603 * at that BVC (cell) only, and paging all over the BSS area is not possible */
Daniel Willmann2a330672021-01-18 18:50:02 +01001604 f_send_paging_ps_exp_one_bss(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), g_pars.sgsn_idx, false, 0);
Harald Welte0e188242020-11-22 21:46:48 +01001605}
1606testcase TC_paging_ps_ptp_rac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001607 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001608 f_start_handlers(refers(f_TC_paging_ps_ptp_rac), testcasename(), 11);
Harald Welte0e188242020-11-22 21:46:48 +01001609 f_cleanup();
1610}
1611
Harald Welte7462a592020-11-23 22:07:07 +01001612/* PS-PAGING on PTP-BVC for unknown Routeing Area */
1613private function f_TC_paging_ps_ptp_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1614{
1615 var RoutingAreaIdentification unknown_ra := {
1616 lai := {
1617 mcc_mnc := '567F99'H,
1618 lac := 33333
1619 },
1620 rac := 254
1621 };
1622 /* as it's sent on the PTP BVC, we expect it to pass even for unknown RAC */
Daniel Willmann2a330672021-01-18 18:50:02 +01001623 f_send_paging_ps_exp_one_bss(ts_BssgpP4RAC(unknown_ra), g_pars.sgsn_idx, false, 0);
Harald Welte7462a592020-11-23 22:07:07 +01001624}
1625testcase TC_paging_ps_ptp_rac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001626 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001627 f_start_handlers(refers(f_TC_paging_ps_ptp_rac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001628 f_cleanup();
1629}
1630
Harald Welte0e188242020-11-22 21:46:48 +01001631/* PS-PAGING on PTP-BVC for BVCI (one cell) */
1632private function f_TC_paging_ps_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
1633{
1634 /* this should be the normal case for MS in READY MM state after a lower layer failure */
Daniel Willmann2a330672021-01-18 18:50:02 +01001635 f_send_paging_ps_exp_one_bss(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), g_pars.sgsn_idx, false, 0);
Harald Welte0e188242020-11-22 21:46:48 +01001636}
1637testcase TC_paging_ps_ptp_bvci() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001638 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001639 f_start_handlers(refers(f_TC_paging_ps_ptp_bvci), testcasename(), 12);
Harald Welte0e188242020-11-22 21:46:48 +01001640 f_cleanup();
1641}
1642
Harald Welteb5a04aa2021-01-16 13:04:40 +01001643
1644/* PS-PAGING on PTP-BVC for BVCI (one cell) using IMSI only (no P-TMSI allocated) */
1645testcase TC_paging_ps_ptp_bvci_imsi() runs on test_CT {
1646 f_init();
1647 f_start_handlers(refers(f_TC_paging_ps_ptp_bvci), testcasename(), 12, have_ptmsi:=false);
1648 f_cleanup();
1649}
1650
Harald Weltecf200072021-01-16 15:20:46 +01001651/* Rejected PS-PAGING on PTP-BVC for BVCI (one cell) */
1652testcase TC_paging_ps_reject_ptp_bvci() runs on test_CT {
1653 f_init();
1654 f_start_handlers(refers(f_TC_paging_ps_reject_ptp_bvci), testcasename(), 16);
1655 f_cleanup();
1656}
1657
1658/* Rejected PS-PAGING on PTP-BVC for BVCI (one cell) using IMSI only (no P-TMSI allocated) */
1659private function f_TC_paging_ps_reject_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
1660{
1661 /* first send the PS-PAGING from SGSN -> PCU */
Daniel Willmann2a330672021-01-18 18:50:02 +01001662 f_send_paging_ps_exp_one_bss(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), g_pars.sgsn_idx, false, 0);
Harald Weltecf200072021-01-16 15:20:46 +01001663 /* then simulate the PS-PAGING-REJECT from the PCU */
1664 f_send_paging_ps_rej(use_sig:=false);
1665}
1666testcase TC_paging_ps_reject_ptp_bvci_imsi() runs on test_CT {
1667 f_init();
1668 f_start_handlers(refers(f_TC_paging_ps_reject_ptp_bvci), testcasename(), 16, have_ptmsi:=false);
1669 f_cleanup();
1670}
Harald Welteb5a04aa2021-01-16 13:04:40 +01001671
Harald Welte7462a592020-11-23 22:07:07 +01001672/* PS-PAGING on PTP-BVC for unknown BVCI */
1673private function f_TC_paging_ps_ptp_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1674{
1675 /* as it's sent on the PTP BVC, we expect it to pass even for unknown BVCI */
Daniel Willmann2a330672021-01-18 18:50:02 +01001676 f_send_paging_ps_exp_one_bss(ts_BssgpP4Bvci(33333), g_pars.sgsn_idx, false, 0);
Harald Welte7462a592020-11-23 22:07:07 +01001677}
1678testcase TC_paging_ps_ptp_bvci_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001679 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001680 f_start_handlers(refers(f_TC_paging_ps_ptp_bvci_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001681 f_cleanup();
1682}
1683
Harald Welte7595d562021-01-16 19:09:20 +01001684/* DUMMY PAGING PS on PTP BVC */
1685private function f_TC_dummy_paging_ps_ptp(charstring id) runs on BSSGP_ConnHdlr
1686{
1687 f_sgsn2pcu(ts_BSSGP_DUMMY_PAGING_PS(g_pars.imsi, omit),
1688 tr_BSSGP_DUMMY_PAGING_PS(g_pars.imsi, omit), use_sig := false);
1689 f_pcu2sgsn(ts_BSSGP_DUMMY_PAGING_PS_RESP(g_pars.imsi, 1, 5),
1690 tr_BSSGP_DUMMY_PAGING_PS_RESP(g_pars.imsi, 1, 5), use_sig := false)
1691}
1692testcase TC_dummy_paging_ps_ptp() runs on test_CT {
1693 f_init();
1694 f_start_handlers(refers(f_TC_dummy_paging_ps_ptp), testcasename(), 11);
1695 f_cleanup();
1696}
1697
Harald Welte0e188242020-11-22 21:46:48 +01001698/* altstep for expecting BSSGP PDU on signaling BVC of given pcu_idx + storing in 'roi' */
1699private altstep as_paging_sig_pcu(integer pcu_idx, template (present) PDU_BSSGP exp_rx, inout ro_integer roi)
1700runs on BSSGP_ConnHdlr {
1701[] PCU_SIG[pcu_idx].receive(exp_rx) {
1702 if (ro_integer_contains(roi, pcu_idx)) {
1703 setverdict(fail, "Received multiple paging on same SIG BVC");
1704 }
1705 roi := roi & { pcu_idx };
1706 repeat;
1707 }
Harald Welte158becf2020-12-09 12:32:32 +01001708[] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001709 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1710 }
1711[] PCU_SIG[pcu_idx].receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1712 setverdict(fail, "Different Paging than expected received SIGNALING BVC");
1713 }
Harald Welte158becf2020-12-09 12:32:32 +01001714[] PCU_PTP[pcu_idx].receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01001715 setverdict(fail, "Different Paging than expected received PTP BVC");
1716 }
1717}
1718
1719type record of default ro_default;
1720
1721/* send PS-PAGING on SIG BVC, expect it to arrive on given list of PCU indexes */
1722private function f_send_paging_ps_exp_multi(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1723 ro_integer exp_on_pcu_idx) runs on BSSGP_ConnHdlr
1724{
1725 var template (present) PDU_BSSGP exp_rx;
Daniel Willmann193e1a02021-01-17 12:55:53 +01001726 exp_rx := f_send_paging_ps(p4, sgsn_idx, true);
Harald Welte0e188242020-11-22 21:46:48 +01001727
1728 /* FIXME: make sure the relevant BVCs/BSS are connected to the ports! */
1729 var ro_default defaults := {};
1730 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1731 var default d := activate(as_paging_sig_pcu(i, exp_rx, g_roi));
1732 defaults := defaults & { d };
1733 }
1734 f_sleep(2.0);
1735 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
1736 deactivate(defaults[i]);
1737 }
1738 log("Paging received on PCU ", g_roi);
1739
1740 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1741 var boolean rx_on_i := ro_integer_contains(g_roi, i);
1742 var boolean exp_on_i := ro_integer_contains(exp_on_pcu_idx, i);
1743 if (exp_on_i and not rx_on_i) {
1744 setverdict(fail, "PS-PAGING not received on ", mp_nsconfig_pcu[i].nsei);
1745 }
1746 if (not exp_on_i and rx_on_i) {
1747 setverdict(fail, "PS-PAGING not expected but received on ", mp_nsconfig_pcu[i].nsei);
1748 }
1749 }
1750 setverdict(pass);
1751}
1752
Harald Weltecf200072021-01-16 15:20:46 +01001753/* Send PAGING-PS-REJECT on SIG BVC, expect it to arrive on the "right" SGSN */
1754private function f_send_paging_ps_rej(boolean use_sig := true, integer pcu_idx := 0) runs on BSSGP_ConnHdlr
1755{
1756 var template (value) PDU_BSSGP pdu_tx;
1757 var template (present) PDU_BSSGP exp_rx;
1758 var PDU_BSSGP pdu_rx;
1759 timer T := 5.0;
1760 var template (omit) GsmTmsi tmsi_int := omit;
1761
1762 if (ispresent(g_pars.p_tmsi)) {
1763 tmsi_int := oct2int(g_pars.p_tmsi);
1764 }
1765
1766 pdu_tx := ts_BSSGP_PAGING_PS_REJ(g_pars.imsi, 23, 42, tmsi_int);
1767 exp_rx := tr_BSSGP_PAGING_PS_REJ(g_pars.imsi, 23, 42, tmsi_int);
1768
1769 if (use_sig) {
1770 PCU_SIG[pcu_idx].send(pdu_tx);
1771 } else {
1772 PCU_PTP[pcu_idx].send(pdu_tx);
1773 }
1774 T.start;
1775 alt {
1776 [use_sig] SGSN_SIG[g_pars.sgsn_idx].receive(exp_rx) -> value pdu_rx {
1777 setverdict(pass);
1778 }
1779 [use_sig] SGSN_SIG[g_pars.sgsn_idx].receive {
1780 setverdict(fail, "Unexpected PDU on SGSN");
1781 }
1782 [use_sig] any from SGSN_SIG.receive(exp_rx) -> value pdu_rx {
1783 setverdict(fail, "PAGING-PS-REJECT arrived on wrong SGSN");
1784 }
1785 [not use_sig] SGSN_PTP[g_pars.sgsn_idx].receive(exp_rx) -> value pdu_rx {
1786 setverdict(pass);
1787 }
1788 [not use_sig] SGSN_PTP[g_pars.sgsn_idx].receive {
1789 setverdict(fail, "Unexpected PDU on SGSN");
1790 }
1791 [not use_sig] any from SGSN_PTP.receive(exp_rx) -> value pdu_rx {
1792 setverdict(fail, "PAGING-PS-REJECT arrived on wrong SGSN");
1793 }
1794 [] T.timeout {
1795 setverdict(fail, "Timeout waiting for PAGING-PS-REJECT");
1796 }
1797 }
1798}
1799
Harald Welte0e188242020-11-22 21:46:48 +01001800/* PS-PAGING on SIG-BVC for BSS Area */
1801private function f_TC_paging_ps_sig_bss(charstring id) runs on BSSGP_ConnHdlr
1802{
1803 /* we expect the paging to arrive on all three NSE */
Daniel Willmann43320442021-01-17 14:07:05 +01001804 f_send_paging_ps_exp_multi(ts_BssgpP4BssArea, g_pars.sgsn_idx, {0, 1, 2});
Harald Welte0e188242020-11-22 21:46:48 +01001805}
1806testcase TC_paging_ps_sig_bss() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001807 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001808 f_start_handlers(refers(f_TC_paging_ps_sig_bss), testcasename(), 13);
Harald Welte0e188242020-11-22 21:46:48 +01001809 f_cleanup();
1810}
1811
1812/* PS-PAGING on SIG-BVC for Location Area */
1813private function f_TC_paging_ps_sig_lac(charstring id) runs on BSSGP_ConnHdlr
1814{
Daniel Willmann2c9300f2020-12-01 10:54:08 +01001815 /* The first LAC (13135) is shared by all three NSEs */
Daniel Willmann43320442021-01-17 14:07:05 +01001816 f_send_paging_ps_exp_multi(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), g_pars.sgsn_idx, {0, 1, 2});
Daniel Willmann2c9300f2020-12-01 10:54:08 +01001817 /* Reset state */
1818 g_roi := {};
1819 /* Make LAC (13300) available on pcu index 2 */
1820 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
Daniel Willmann43320442021-01-17 14:07:05 +01001821 f_send_paging_ps_exp_multi(ts_BssgpP4LAC(pcu_bvc_cfg[2].cell_id.ra_id.lai), g_pars.sgsn_idx, {2});
Harald Welte0e188242020-11-22 21:46:48 +01001822}
1823testcase TC_paging_ps_sig_lac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001824 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001825 f_start_handlers(refers(f_TC_paging_ps_sig_lac), testcasename(), 14);
Harald Welte0e188242020-11-22 21:46:48 +01001826 f_cleanup();
1827}
1828
Harald Welte7462a592020-11-23 22:07:07 +01001829/* PS-PAGING on SIG-BVC for unknown Location Area */
1830private function f_TC_paging_ps_sig_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1831{
1832 var GSM_Types.LocationAreaIdentification unknown_la := {
1833 mcc_mnc := '567F99'H,
1834 lac := 33333
1835 };
Daniel Willmann2a330672021-01-18 18:50:02 +01001836 f_send_paging_ps_exp_no_bss(ts_BssgpP4LAC(unknown_la), g_pars.sgsn_idx, true);
Harald Welte7462a592020-11-23 22:07:07 +01001837}
1838testcase TC_paging_ps_sig_lac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001839 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001840 f_start_handlers(refers(f_TC_paging_ps_sig_lac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001841 f_cleanup();
1842}
1843
Harald Welte0e188242020-11-22 21:46:48 +01001844/* PS-PAGING on SIG-BVC for Routeing Area */
1845private function f_TC_paging_ps_sig_rac(charstring id) runs on BSSGP_ConnHdlr
1846{
Daniel Willmann2c9300f2020-12-01 10:54:08 +01001847 /* Only PCU index 0 has a matching BVC with the RA ID */
Daniel Willmann43320442021-01-17 14:07:05 +01001848 f_send_paging_ps_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), g_pars.sgsn_idx, {0});
Daniel Willmann2c9300f2020-12-01 10:54:08 +01001849 g_roi := {};
1850 /* PCU index 1 and 2 have a matching BVC with the RA ID */
Daniel Willmann43320442021-01-17 14:07:05 +01001851 f_send_paging_ps_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[2].cell_id.ra_id), g_pars.sgsn_idx, {1, 2});
Daniel Willmann2c9300f2020-12-01 10:54:08 +01001852 g_roi := {};
1853 /* PCU index 2 has two matching BVCs with the RA ID */
1854 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
Daniel Willmann43320442021-01-17 14:07:05 +01001855 f_send_paging_ps_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[2].cell_id.ra_id), g_pars.sgsn_idx, {2});
Harald Welte0e188242020-11-22 21:46:48 +01001856}
1857testcase TC_paging_ps_sig_rac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001858 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001859 f_start_handlers(refers(f_TC_paging_ps_sig_rac), testcasename(), 15);
Harald Welte0e188242020-11-22 21:46:48 +01001860 f_cleanup();
1861}
1862
Harald Welte7462a592020-11-23 22:07:07 +01001863/* PS-PAGING on SIG-BVC for unknown Routeing Area */
1864private function f_TC_paging_ps_sig_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1865{
1866 var RoutingAreaIdentification unknown_ra := {
1867 lai := {
1868 mcc_mnc := '567F99'H,
1869 lac := 33333
1870 },
1871 rac := 254
1872 };
Daniel Willmann2a330672021-01-18 18:50:02 +01001873 f_send_paging_ps_exp_no_bss(ts_BssgpP4RAC(unknown_ra), g_pars.sgsn_idx, true);
Harald Welte7462a592020-11-23 22:07:07 +01001874}
1875testcase TC_paging_ps_sig_rac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001876 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001877 f_start_handlers(refers(f_TC_paging_ps_sig_rac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001878 f_cleanup();
1879}
1880
Harald Welte0e188242020-11-22 21:46:48 +01001881/* PS-PAGING on SIG-BVC for BVCI (one cell) */
1882private function f_TC_paging_ps_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
1883{
Daniel Willmann43320442021-01-17 14:07:05 +01001884 f_send_paging_ps_exp_multi(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), g_pars.sgsn_idx, {0});
Harald Welte0e188242020-11-22 21:46:48 +01001885}
1886testcase TC_paging_ps_sig_bvci() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001887 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001888 f_start_handlers(refers(f_TC_paging_ps_sig_bvci), testcasename(), 16);
Harald Welte0e188242020-11-22 21:46:48 +01001889 f_cleanup();
1890}
1891
Harald Welteb5a04aa2021-01-16 13:04:40 +01001892/* PS-PAGING on SIG-BVC for BVCI (one cell) using IMSI only (no P-TMSI allocated) */
1893testcase TC_paging_ps_sig_bvci_imsi() runs on test_CT {
1894 f_init();
1895 f_start_handlers(refers(f_TC_paging_ps_sig_bvci), testcasename(), 16, have_ptmsi:=false);
1896 f_cleanup();
1897}
1898
Harald Weltecf200072021-01-16 15:20:46 +01001899/* Rejected PS-PAGING on SIG-BVC for BVCI (one cell) */
1900private function f_TC_paging_ps_reject_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
1901{
1902 /* first send the PS-PAGING from SGSN -> PCU */
Daniel Willmann43320442021-01-17 14:07:05 +01001903 f_send_paging_ps_exp_multi(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), g_pars.sgsn_idx, {0});
Harald Weltecf200072021-01-16 15:20:46 +01001904 /* then simulate the PS-PAGING-REJECT from the PCU */
1905 f_send_paging_ps_rej(use_sig:=true);
1906
1907}
1908testcase TC_paging_ps_reject_sig_bvci() runs on test_CT {
1909 f_init();
1910 f_start_handlers(refers(f_TC_paging_ps_reject_sig_bvci), testcasename(), 16);
1911 f_cleanup();
1912}
1913
1914/* Rejected PS-PAGING on SIG-BVC for BVCI (one cell) using IMSI only (no P-TMSI allocated) */
1915testcase TC_paging_ps_reject_sig_bvci_imsi() runs on test_CT {
1916 f_init();
1917 f_start_handlers(refers(f_TC_paging_ps_reject_sig_bvci), testcasename(), 16, have_ptmsi:=false);
1918 f_cleanup();
1919}
1920
Harald Welte7462a592020-11-23 22:07:07 +01001921/* PS-PAGING on SIG-BVC for unknown BVCI */
1922private function f_TC_paging_ps_sig_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1923{
Daniel Willmann2a330672021-01-18 18:50:02 +01001924 f_send_paging_ps_exp_no_bss(ts_BssgpP4Bvci(33333), g_pars.sgsn_idx, true);
Harald Welte7462a592020-11-23 22:07:07 +01001925}
1926testcase TC_paging_ps_sig_bvci_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001927 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001928 f_start_handlers(refers(f_TC_paging_ps_sig_bvci_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001929 f_cleanup();
1930}
1931
Harald Welte7595d562021-01-16 19:09:20 +01001932/* DUMMY PAGING PS on SIG BVC */
1933private function f_TC_dummy_paging_ps_sig(charstring id) runs on BSSGP_ConnHdlr
1934{
1935 f_sgsn2pcu(ts_BSSGP_DUMMY_PAGING_PS(g_pars.imsi, omit),
1936 tr_BSSGP_DUMMY_PAGING_PS(g_pars.imsi, omit), use_sig := true);
1937 f_pcu2sgsn(ts_BSSGP_DUMMY_PAGING_PS_RESP(g_pars.imsi, 1, 5),
1938 tr_BSSGP_DUMMY_PAGING_PS_RESP(g_pars.imsi, 1, 5), use_sig := true)
1939}
1940testcase TC_dummy_paging_ps_sig() runs on test_CT {
1941 f_init();
1942 f_start_handlers(refers(f_TC_dummy_paging_ps_sig), testcasename(), 11);
1943 f_cleanup();
1944}
1945
Harald Welte7462a592020-11-23 22:07:07 +01001946
Harald Welte0e188242020-11-22 21:46:48 +01001947
1948/***********************************************************************
1949 * PAGING CS procedure
1950 ***********************************************************************/
1951
1952private function f_send_paging_cs(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1953 boolean use_sig := false)
1954runs on BSSGP_ConnHdlr return template (present) PDU_BSSGP {
1955 var template (value) PDU_BSSGP pdu_tx;
1956 var template (present) PDU_BSSGP pdu_rx;
1957 /* we always specify '0' as BVCI in the templates below, as we override it with
1958 * 'p4' later anyway */
1959 pdu_rx := tr_BSSGP_CS_PAGING(0);
1960 pdu_rx.pDU_BSSGP_PAGING_CS.iMSI := tr_BSSGP_IMSI(g_pars.imsi);
1961 if (ispresent(g_pars.p_tmsi)) {
1962 pdu_tx := ts_BSSGP_CS_PAGING_PTMSI(0, g_pars.imsi, oct2int(g_pars.p_tmsi));
1963 pdu_rx.pDU_BSSGP_PAGING_CS.tMSI := tr_BSSGP_TMSI(oct2int(g_pars.p_tmsi));
1964 } else {
1965 pdu_tx := ts_BSSGP_CS_PAGING_IMSI(0, g_pars.imsi);
1966 pdu_rx.pDU_BSSGP_PAGING_CS.tMSI := omit;
1967 }
1968 pdu_tx.pDU_BSSGP_PAGING_CS.paging_Field4 := p4;
1969 pdu_rx.pDU_BSSGP_PAGING_CS.paging_Field4 := p4;
1970 if (use_sig == false) {
Harald Welte158becf2020-12-09 12:32:32 +01001971 SGSN_PTP[sgsn_idx].send(pdu_tx);
Harald Welte0e188242020-11-22 21:46:48 +01001972 } else {
1973 SGSN_SIG[sgsn_idx].send(pdu_tx);
1974 }
1975 return pdu_rx;
1976}
1977
1978/* send paging defined by 'p4' on given SGSN-side index (ptp or signaling) and expect one paging to arrive on
1979 * specified PCU index */
1980private function f_send_paging_cs_exp_one_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1981 boolean use_sig := false,integer pcu_idx := 0)
1982runs on BSSGP_ConnHdlr {
1983 var template (present) PDU_BSSGP exp_rx;
Daniel Willmann1a859712020-12-04 00:59:45 +01001984 var boolean test_done := false;
Harald Welte0e188242020-11-22 21:46:48 +01001985 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1986 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1987 exp_rx := f_send_paging_cs(p4, sgsn_idx, use_sig);
1988 /* Expect paging to propagate to the one BSS addressed by the BVCI only */
1989 timer T := 2.0;
1990 T.start;
1991 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001992 [not use_sig and not test_done] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001993 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001994 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001995 repeat;
1996 }
1997 [not use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
1998 setverdict(fail, "Received paging on SIGNALING BVC, expected PTP BVC");
1999 }
Daniel Willmann1a859712020-12-04 00:59:45 +01002000 [use_sig and not test_done] PCU_SIG[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01002001 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01002002 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01002003 repeat;
2004 }
Harald Welte158becf2020-12-09 12:32:32 +01002005 [use_sig] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01002006 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
2007 }
Harald Welte158becf2020-12-09 12:32:32 +01002008 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01002009 setverdict(fail, "Paging received on unexpected BVC");
2010 }
2011 [] any from PCU_SIG.receive(exp_rx) {
2012 setverdict(fail, "Paging received on unexpected BVC");
2013 }
Harald Welte158becf2020-12-09 12:32:32 +01002014 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01002015 setverdict(fail, "Different Paging than expected received PTP BVC");
2016 }
2017 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
2018 setverdict(fail, "Different Paging than expected on SIGNALING BVC");
2019 }
Daniel Willmann1a859712020-12-04 00:59:45 +01002020 [not test_done] T.timeout {
2021 setverdict(fail, "Timeout while waiting for paging")
2022 }
2023 [test_done] T.timeout;
Harald Welte0e188242020-11-22 21:46:48 +01002024 }
2025}
2026
Harald Welte7462a592020-11-23 22:07:07 +01002027/* send a CS-PAGING but don't expect it to show up on any PTP or SIG BVC */
2028private function f_send_paging_cs_exp_no_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
2029 boolean use_sig := false)
2030runs on BSSGP_ConnHdlr {
2031 var template (present) PDU_BSSGP exp_rx;
2032 exp_rx := f_send_paging_cs(p4, sgsn_idx, use_sig);
2033 /* Expect paging to propagate to no BSS */
2034 timer T := 2.0;
2035 T.start;
2036 alt {
Harald Welte158becf2020-12-09 12:32:32 +01002037 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte7462a592020-11-23 22:07:07 +01002038 setverdict(fail, "Paging received on unexpected BVC");
2039 }
2040 [] any from PCU_SIG.receive(exp_rx) {
2041 setverdict(fail, "Paging received on unexpected BVC");
2042 }
Harald Welte158becf2020-12-09 12:32:32 +01002043 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
Harald Welte7462a592020-11-23 22:07:07 +01002044 setverdict(fail, "Different Paging received on PTP BVC");
2045 }
2046 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
2047 setverdict(fail, "Different Paging received on SIGNALING BVC");
2048 }
2049 [] T.timeout {
2050 setverdict(pass);
2051 }
2052 }
2053}
2054
Harald Welte0e188242020-11-22 21:46:48 +01002055private function f_TC_paging_cs_ptp_bss(charstring id) runs on BSSGP_ConnHdlr
2056{
2057 /* doesn't really make sense: Sending to a single BVCI means the message ends up
2058 * at that BVC (cell) only, and paging all over the BSS area is not possible */
2059 f_send_paging_cs_exp_one_bss(ts_BssgpP4BssArea, 0, false, 0);
2060}
2061testcase TC_paging_cs_ptp_bss() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002062 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002063 f_start_handlers(refers(f_TC_paging_cs_ptp_bss), testcasename(), 17);
Harald Welte0e188242020-11-22 21:46:48 +01002064 f_cleanup();
2065}
2066
2067/* CS-PAGING on PTP-BVC for Location Area */
2068private function f_TC_paging_cs_ptp_lac(charstring id) runs on BSSGP_ConnHdlr
2069{
2070 var template (present) PDU_BSSGP exp_rx;
2071 /* doesn't really make sense: Sending to a single BVCI means the message ends up
2072 * at that BVC (cell) only, and paging all over the BSS area is not possible */
2073 f_send_paging_cs_exp_one_bss(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, false, 0);
2074}
2075testcase TC_paging_cs_ptp_lac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002076 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002077 f_start_handlers(refers(f_TC_paging_cs_ptp_lac), testcasename(), 18);
Harald Welte0e188242020-11-22 21:46:48 +01002078 f_cleanup();
2079}
2080
Harald Welte7462a592020-11-23 22:07:07 +01002081/* CS-PAGING on PTP-BVC for unknown Location Area */
2082private function f_TC_paging_cs_ptp_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
2083{
2084 var GSM_Types.LocationAreaIdentification unknown_la := {
2085 mcc_mnc := '567F99'H,
2086 lac := 33333
2087 };
2088 /* as it's sent on the PTP BVC, we expect it to pass even for unknown LAC */
2089 f_send_paging_cs_exp_one_bss(ts_BssgpP4LAC(unknown_la), 0, false, 0);
2090}
2091testcase TC_paging_cs_ptp_lac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002092 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002093 f_start_handlers(refers(f_TC_paging_cs_ptp_lac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002094 f_cleanup();
2095}
2096
Harald Welte0e188242020-11-22 21:46:48 +01002097/* CS-PAGING on PTP-BVC for Routeing Area */
2098private function f_TC_paging_cs_ptp_rac(charstring id) runs on BSSGP_ConnHdlr
2099{
2100 /* doesn't really make sense: Sending to a single BVCI means the message ends up
2101 * at that BVC (cell) only, and paging all over the BSS area is not possible */
2102 f_send_paging_cs_exp_one_bss(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, false, 0);
2103}
2104testcase TC_paging_cs_ptp_rac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002105 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002106 f_start_handlers(refers(f_TC_paging_cs_ptp_rac), testcasename(), 19);
Harald Welte0e188242020-11-22 21:46:48 +01002107 f_cleanup();
2108}
2109
Harald Welte7462a592020-11-23 22:07:07 +01002110/* CS-PAGING on PTP-BVC for unknown Routeing Area */
2111private function f_TC_paging_cs_ptp_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
2112{
2113 var RoutingAreaIdentification unknown_ra := {
2114 lai := {
2115 mcc_mnc := '567F99'H,
2116 lac := 33333
2117 },
2118 rac := 254
2119 };
2120 /* as it's sent on the PTP BVC, we expect it to pass even for unknown RAC */
2121 f_send_paging_cs_exp_one_bss(ts_BssgpP4RAC(unknown_ra), 0, false, 0);
2122}
2123testcase TC_paging_cs_ptp_rac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002124 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002125 f_start_handlers(refers(f_TC_paging_cs_ptp_rac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002126 f_cleanup();
2127}
2128
Harald Welte0e188242020-11-22 21:46:48 +01002129/* CS-PAGING on PTP-BVC for BVCI (one cell) */
2130private function f_TC_paging_cs_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
2131{
2132 /* this should be the normal case for MS in READY MM state after a lower layer failure */
2133 f_send_paging_cs_exp_one_bss(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, false, 0);
2134}
2135testcase TC_paging_cs_ptp_bvci() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002136 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002137 f_start_handlers(refers(f_TC_paging_cs_ptp_bvci), testcasename(), 20);
Harald Welte0e188242020-11-22 21:46:48 +01002138 f_cleanup();
2139}
2140
Harald Welte7462a592020-11-23 22:07:07 +01002141/* CS-PAGING on PTP-BVC for unknown BVCI */
2142private function f_TC_paging_cs_ptp_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
2143{
2144 /* as it's sent on the PTP BVC, we expect it to pass even for unknown BVCI */
2145 f_send_paging_cs_exp_one_bss(ts_BssgpP4Bvci(33333), 0, false, 0);
2146}
2147testcase TC_paging_cs_ptp_bvci_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002148 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002149 f_start_handlers(refers(f_TC_paging_cs_ptp_bvci_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002150 f_cleanup();
2151}
2152
Harald Welte0e188242020-11-22 21:46:48 +01002153/* send CS-PAGING on SIG BVC, expect it to arrive on given list of PCU indexes */
2154private function f_send_paging_cs_exp_multi(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
2155 ro_integer exp_on_pcu_idx) runs on BSSGP_ConnHdlr
2156{
2157 var template (present) PDU_BSSGP exp_rx;
2158 exp_rx := f_send_paging_cs(p4, 0, true);
2159
2160 /* FIXME: make sure the relevant BVCs/BSS are connected to the ports! */
2161 var ro_default defaults := {};
2162 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
2163 var default d := activate(as_paging_sig_pcu(i, exp_rx, g_roi));
2164 defaults := defaults & { d };
2165 }
2166 f_sleep(2.0);
2167 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2168 deactivate(defaults[i]);
2169 }
2170 log("Paging received on PCU ", g_roi);
2171
2172 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
2173 var boolean rx_on_i := ro_integer_contains(g_roi, i);
2174 var boolean exp_on_i := ro_integer_contains(exp_on_pcu_idx, i);
2175 if (exp_on_i and not rx_on_i) {
2176 setverdict(fail, "PS-PAGING not received on ", mp_nsconfig_pcu[i].nsei);
2177 }
2178 if (not exp_on_i and rx_on_i) {
2179 setverdict(fail, "PS-PAGING not expected but received on ", mp_nsconfig_pcu[i].nsei);
2180 }
2181 }
2182 setverdict(pass);
2183}
2184
2185/* CS-PAGING on SIG-BVC for BSS Area */
2186private function f_TC_paging_cs_sig_bss(charstring id) runs on BSSGP_ConnHdlr
2187{
2188 /* we expect the paging to arrive on all three NSE */
2189 f_send_paging_cs_exp_multi(ts_BssgpP4BssArea, 0, {0, 1, 2});
2190}
2191testcase TC_paging_cs_sig_bss() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002192 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002193 f_start_handlers(refers(f_TC_paging_cs_sig_bss), testcasename(), 13);
Harald Welte0e188242020-11-22 21:46:48 +01002194 f_cleanup();
2195}
2196
2197/* CS-PAGING on SIG-BVC for Location Area */
2198private function f_TC_paging_cs_sig_lac(charstring id) runs on BSSGP_ConnHdlr
2199{
Daniel Willmannd4fb73c2020-12-07 13:57:17 +01002200 /* The first LAC (13135) is shared by all three NSEs */
2201 f_send_paging_cs_exp_multi(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, {0, 1, 2});
2202 /* Reset state */
2203 g_roi := {};
2204 /* Make LAC (13300) available on pcu index 2 */
2205 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
2206 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 +01002207}
2208testcase TC_paging_cs_sig_lac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002209 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002210 f_start_handlers(refers(f_TC_paging_cs_sig_lac), testcasename(), 14);
Harald Welte0e188242020-11-22 21:46:48 +01002211 f_cleanup();
2212}
2213
Harald Welte7462a592020-11-23 22:07:07 +01002214/* CS-PAGING on SIG-BVC for unknown Location Area */
2215private function f_TC_paging_cs_sig_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
2216{
2217 var GSM_Types.LocationAreaIdentification unknown_la := {
2218 mcc_mnc := '567F99'H,
2219 lac := 33333
2220 };
2221 f_send_paging_cs_exp_no_bss(ts_BssgpP4LAC(unknown_la), 0, true);
2222}
2223testcase TC_paging_cs_sig_lac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002224 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002225 f_start_handlers(refers(f_TC_paging_cs_sig_lac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002226 f_cleanup();
2227}
2228
Harald Welte0e188242020-11-22 21:46:48 +01002229/* CS-PAGING on SIG-BVC for Routeing Area */
2230private function f_TC_paging_cs_sig_rac(charstring id) runs on BSSGP_ConnHdlr
2231{
Daniel Willmannd4fb73c2020-12-07 13:57:17 +01002232 /* Only PCU index 0 has a matching BVC with the RA ID */
Harald Welte0e188242020-11-22 21:46:48 +01002233 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 +01002234 g_roi := {};
2235 /* PCU index 1 and 2 have a matching BVC with the RA ID */
2236 f_send_paging_cs_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[2].cell_id.ra_id), 0, {1, 2});
2237 g_roi := {};
2238 /* PCU index 2 has two matching BVCs with the RA ID */
2239 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
2240 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 +01002241}
2242testcase TC_paging_cs_sig_rac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002243 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002244 f_start_handlers(refers(f_TC_paging_cs_sig_rac), testcasename(), 15);
Harald Welte0e188242020-11-22 21:46:48 +01002245 f_cleanup();
2246}
2247
Harald Welte7462a592020-11-23 22:07:07 +01002248/* CS-PAGING on SIG-BVC for unknown Routeing Area */
2249private function f_TC_paging_cs_sig_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
2250{
2251 var RoutingAreaIdentification unknown_ra := {
2252 lai := {
2253 mcc_mnc := '567F99'H,
2254 lac := 33333
2255 },
2256 rac := 254
2257 };
2258 f_send_paging_cs_exp_no_bss(ts_BssgpP4RAC(unknown_ra), 0, true);
2259}
2260testcase TC_paging_cs_sig_rac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002261 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002262 f_start_handlers(refers(f_TC_paging_cs_sig_rac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002263 f_cleanup();
2264}
2265
Harald Welte0e188242020-11-22 21:46:48 +01002266/* CS-PAGING on SIG-BVC for BVCI (one cell) */
2267private function f_TC_paging_cs_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
2268{
2269 f_send_paging_cs_exp_multi(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, {0});
2270}
2271testcase TC_paging_cs_sig_bvci() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002272 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002273 f_start_handlers(refers(f_TC_paging_cs_sig_bvci), testcasename(), 16);
Harald Welte0e188242020-11-22 21:46:48 +01002274 f_cleanup();
2275}
2276
Harald Welte7462a592020-11-23 22:07:07 +01002277/* CS-PAGING on SIG-BVC for unknown BVCI */
2278private function f_TC_paging_cs_sig_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
2279{
2280 f_send_paging_cs_exp_no_bss(ts_BssgpP4Bvci(33333), 0, true);
2281}
2282testcase TC_paging_cs_sig_bvci_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002283 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002284 f_start_handlers(refers(f_TC_paging_cs_sig_bvci_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002285 f_cleanup();
2286}
2287
Harald Welte4f91c3b2020-12-09 12:25:51 +01002288/***********************************************************************
2289 * FLUSH-LL procedure
2290 ***********************************************************************/
2291
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002292private function f_TC_flush_ll(charstring id) runs on BSSGP_ConnHdlr {
2293 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
2294 var integer i;
2295 for (i := 0; i < 10; i := i+1) {
2296 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_FLUSH_LL(g_pars.tlli, bvci, bvci_new := bvci);
2297 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2298 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_FLUSH_LL(g_pars.tlli, bvci, bvci_new := bvci);
2299
2300 f_sgsn2pcu(pdu_tx, pdu_rx, use_sig := true);
2301
2302 pdu_tx := ts_BSSGP_FLUSH_LL_ACK(g_pars.tlli, int2oct(0, 1), 23, bvci_new := bvci);
2303 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2304 pdu_rx := tr_BSSGP_FLUSH_LL_ACK(g_pars.tlli, int2oct(0, 1), 23, bvci_new := bvci);
2305
2306 f_pcu2sgsn(pdu_tx, pdu_rx, use_sig := true);
2307 }
2308 setverdict(pass);
2309}
2310testcase TC_flush_ll() runs on test_CT
2311{
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002312 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002313 f_start_handlers(refers(f_TC_flush_ll), testcasename(), 6);
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002314 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002315 f_cleanup();
2316}
Harald Welte6dc2ac42020-11-16 09:16:17 +01002317
Harald Welte4f91c3b2020-12-09 12:25:51 +01002318/***********************************************************************
2319 * SGSN-INVOKE-TRACE procedure
2320 ***********************************************************************/
2321
Harald Weltef8e5c5d2020-11-27 22:37:23 +01002322private altstep as_bssgp_g_pcu_count(integer pcu_idx, template (present) PDU_BSSGP exp_rx, inout ro_integer roi)
2323runs on GlobalTest_CT {
2324[] G_PCU[pcu_idx].receive(exp_rx) from g_pcu[pcu_idx].vc_BSSGP {
2325 if (ro_integer_contains(roi, pcu_idx)) {
2326 setverdict(fail, "Received multiple on same SIG BVC");
2327 }
2328 roi := roi & { pcu_idx };
2329 repeat;
2330 }
2331}
2332/* send a INVOKE-TRACE from SGSN and expect to receive a copy on each NSE */
2333testcase TC_trace() runs on GlobalTest_CT
2334{
2335 var BSSGP_ConnHdlr vc_conn;
2336 f_init();
2337 f_global_init();
2338
2339 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_INVOKE_TRACE('23'O, '4321'O);
2340 var template (present) PDU_BSSGP exp_rx := ts_BSSGP_INVOKE_TRACE('23'O, '4321'O);
2341
2342 var ro_default defaults := {};
2343 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2344 activate(as_bssgp_g_pcu_count(i, exp_rx, g_roi));
2345 }
2346 G_SGSN[0].send(pdu_tx);
2347 f_sleep(2.0);
2348 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2349 deactivate(defaults[i]);
2350 }
2351
2352 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2353 if (not ro_integer_contains(g_roi, i)) {
2354 setverdict(fail, "Failed to receive TRACE on PCU index ", i);
2355 }
2356 }
2357 setverdict(pass);
2358
2359 f_cleanup();
2360}
2361
Harald Welte4f91c3b2020-12-09 12:25:51 +01002362/***********************************************************************
2363 * LLC-DISCARDED procedure
2364 ***********************************************************************/
2365
Harald Weltec0351d12020-11-27 22:49:02 +01002366private function f_TC_llc_discarded(charstring id) runs on BSSGP_ConnHdlr {
2367 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
2368
2369 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_LLC_DISCARDED(g_pars.tlli, 23, bvci, 2342);
2370 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2371 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_LLC_DISCARDED(g_pars.tlli, 23, bvci, 2342);
2372
2373 f_pcu2sgsn(pdu_tx, pdu_rx, use_sig := true);
2374
2375 setverdict(pass);
2376}
2377/* Send a LLC-DISCARDED from BSS side and expect it to show up on SGSN (SIG BVC) */
2378testcase TC_llc_discarded() runs on test_CT
2379{
Harald Weltec0351d12020-11-27 22:49:02 +01002380 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002381 f_start_handlers(refers(f_TC_llc_discarded), testcasename(), 6);
Harald Weltec0351d12020-11-27 22:49:02 +01002382 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Weltec0351d12020-11-27 22:49:02 +01002383 f_cleanup();
2384}
2385
Harald Welte4f91c3b2020-12-09 12:25:51 +01002386/***********************************************************************
2387 * OVERLOAD procedure
2388 ***********************************************************************/
2389
Harald Weltef20af412020-11-28 16:11:11 +01002390/* Send an OVERLOAD from SGSN side and expect it to show up on each PCU (SIG BVC) */
2391testcase TC_overload() runs on GlobalTest_CT
2392{
2393 f_init();
2394 f_global_init();
2395
2396 var template (value) PDU_BSSGP pdu_tx := ts_OVERLOAD('1'B);
2397 var template (present) PDU_BSSGP exp_rx := tr_OVERLOAD('1'B);
2398
2399 var ro_default defaults := {};
2400 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2401 activate(as_bssgp_g_pcu_count(i, exp_rx, g_roi));
2402 }
2403 G_SGSN[0].send(pdu_tx);
2404 f_sleep(2.0);
2405 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2406 deactivate(defaults[i]);
2407 }
2408
2409 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2410 if (not ro_integer_contains(g_roi, i)) {
2411 setverdict(fail, "Failed to receive OVERLOAD on PCU index ", i);
2412 }
2413 }
2414 setverdict(pass);
2415
2416 f_cleanup();
2417}
2418
Harald Welte4f91c3b2020-12-09 12:25:51 +01002419/***********************************************************************
2420 * BVC-BLOCK / BVC-UNBLOCK procedure
2421 ***********************************************************************/
2422
Harald Welte239aa502020-11-24 23:14:20 +01002423private function f_block_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2424{
2425 var BSSGP_BVC_CT bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2426 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2427 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2428
2429 SGSN_MGMT.clear;
2430 PCU_MGMT.clear;
2431
2432 /* block the PTP BVC from the PCU side */
2433 PCU_MGMT.send(BssgpBlockRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to bvc_ct;
2434 /* expect state on both PCU and SGSN side to change */
2435 interleave {
2436 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_BLOCKED)) from bvc_ct;
Harald Welte572b0172021-03-30 13:19:56 +02002437 [] SGSN_MGMT.receive(tr_BssgpStsInd(mp_nsconfig_sgsn[0].nsei, bvc_cfg.bvci, BVC_S_BLOCKED));
2438 [] SGSN_MGMT.receive(tr_BssgpStsInd(mp_nsconfig_sgsn[1].nsei, bvc_cfg.bvci, BVC_S_BLOCKED));
2439 /* Doesn't auto-scale with NUM_SGSN */
Harald Welte239aa502020-11-24 23:14:20 +01002440 }
2441 setverdict(pass);
2442}
2443testcase TC_bvc_block_ptp() runs on test_CT
2444{
2445 f_init();
2446 f_sleep(1.0);
2447 f_block_ptp_bvc_from_pcu(0, 0);
2448 f_cleanup();
2449}
2450
2451private function f_unblock_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2452{
2453 var BSSGP_BVC_CT bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2454 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2455 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2456
2457 SGSN_MGMT.clear;
2458 PCU_MGMT.clear;
2459
2460 /* block the PTP BVC from the PCU side */
2461 PCU_MGMT.send(BssgpUnblockRequest:{}) to bvc_ct;
2462 /* expect state on both PCU and SGSN side to change */
2463 interleave {
2464 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_UNBLOCKED)) from bvc_ct;
Harald Welte572b0172021-03-30 13:19:56 +02002465 [] SGSN_MGMT.receive(tr_BssgpStsInd(mp_nsconfig_sgsn[0].nsei, bvc_cfg.bvci, BVC_S_UNBLOCKED));
2466 [] SGSN_MGMT.receive(tr_BssgpStsInd(mp_nsconfig_sgsn[1].nsei, bvc_cfg.bvci, BVC_S_UNBLOCKED));
2467 /* Doesn't auto-scale with NUM_SGSN */
Harald Welte239aa502020-11-24 23:14:20 +01002468 }
2469 setverdict(pass);
2470}
2471testcase TC_bvc_unblock_ptp() runs on test_CT
2472{
2473 f_init();
2474 f_sleep(1.0);
2475 f_block_ptp_bvc_from_pcu(0, 0);
2476 f_sleep(1.0);
2477 f_unblock_ptp_bvc_from_pcu(0, 0);
2478 f_cleanup();
2479}
2480
Harald Welte4f91c3b2020-12-09 12:25:51 +01002481/***********************************************************************
2482 * BVC-RESET procedure
2483 ***********************************************************************/
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002484private altstep as_count_bvc_reset(integer sgsn_idx, BssgpBvci bvci, inout roro_integer roroi)
2485runs on test_CT {
2486 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(sgsn_idx, bvci);
2487 [] SGSN_MGMT.receive(BssgpResetIndication:{bvci}) from sgsn_bvc_ct {
2488 roroi[sgsn_idx] := roroi[sgsn_idx] & { bvci };
2489 repeat;
2490 }
2491}
Harald Welte60a8ec72020-11-25 17:12:53 +01002492private altstep as_ignore_status(BSSGP_BVC_MGMT_PT pt) {
2493[] pt.receive(BssgpStatusIndication:?) { repeat; }
2494}
2495private function f_get_sgsn_bvc_ct(integer sgsn_idx, BssgpBvci bvci) runs on test_CT return BSSGP_BVC_CT {
2496 for (var integer i := 0; i < lengthof(g_sgsn[sgsn_idx].cfg.bvc); i := i+1) {
2497 if (g_sgsn[sgsn_idx].cfg.bvc[i].bvci == bvci) {
2498 return g_sgsn[sgsn_idx].vc_BSSGP_BVC[i];
2499 }
2500 }
2501 return null;
2502}
2503private function f_reset_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2504{
2505 var BSSGP_BVC_CT pcu_bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2506 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2507 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002508 var ro_default defaults;
2509 var integer i;
Harald Welte60a8ec72020-11-25 17:12:53 +01002510
2511 SGSN_MGMT.clear;
2512 PCU_MGMT.clear;
2513
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002514 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
2515 g_roroi[i] := {};
2516 }
2517
Harald Welte60a8ec72020-11-25 17:12:53 +01002518 /* block the PTP BVC from the PCU side */
2519 PCU_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to pcu_bvc_ct;
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002520
Harald Welte60a8ec72020-11-25 17:12:53 +01002521 /* expect state on both PCU and SGSN side to change */
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002522 defaults := { activate(as_ignore_status(SGSN_MGMT)) };
2523
2524 /* Activate altsteps: One for each SGSN */
2525 for (i := 0; i < lengthof(g_sgsn); i := i+1) {
2526 var default d := activate(as_count_bvc_reset(i, bvc_cfg.bvci, g_roroi));
2527 defaults := defaults & { d };
Harald Welte60a8ec72020-11-25 17:12:53 +01002528 }
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002529
2530 timer T := 3.0;
2531 T.start;
2532 alt {
2533 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_BLOCKED)) from pcu_bvc_ct {
2534 g_roi := g_roi & { bvc_cfg.bvci };
2535 repeat;
2536 }
2537 [] T.timeout;
2538 }
2539
2540 for (i := 0; i < lengthof(defaults); i := i+1) {
2541 deactivate(defaults[i]);
2542 }
2543
2544 /* Check if BVC-RESET was received at all SGSNs */
2545 for (i := 0; i < lengthof(g_sgsn); i := i+1) {
2546 if (not ro_integer_contains(g_roroi[i], bvc_cfg.bvci)) {
2547 setverdict(fail, "Missing SGSN[", i, "] BVC-BLOCK of BVCI=", bvc_cfg.bvci);
2548 }
2549 }
2550
Harald Welte60a8ec72020-11-25 17:12:53 +01002551 setverdict(pass);
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002552 f_cleanup();
Harald Welte60a8ec72020-11-25 17:12:53 +01002553}
2554/* Send a BVC-RESET for a PTP BVC from the BSS side: expect it to propagate */
2555testcase TC_bvc_reset_ptp_from_bss() runs on test_CT
2556{
2557 f_init();
2558 f_sleep(3.0);
2559 f_reset_ptp_bvc_from_pcu(0, 0);
2560 f_cleanup();
2561}
2562
Harald Welteb1cc0b22021-03-30 12:16:36 +02002563private altstep as_count_bvc_sts(integer sgsn_idx, BssgpBvci bvci,
2564 template (present) BvcState exp_bvc_state, inout roro_integer roroi)
Harald Welte16786e92020-11-27 19:11:56 +01002565runs on test_CT {
2566 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(sgsn_idx, bvci);
Harald Welteb1cc0b22021-03-30 12:16:36 +02002567 [] SGSN_MGMT.receive(tr_BssgpStsInd(?, bvci, exp_bvc_state)) from sgsn_bvc_ct {
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002568 roroi[sgsn_idx] := roroi[sgsn_idx] & { bvci };
Harald Welteb2647f72020-12-07 14:36:35 +01002569 repeat;
Harald Welte16786e92020-11-27 19:11:56 +01002570 }
2571}
Harald Welteb1cc0b22021-03-30 12:16:36 +02002572
2573private altstep as_count_bvc_block(integer sgsn_idx, BssgpBvci bvci, inout roro_integer roroi)
2574runs on test_CT {
2575 [] as_count_bvc_sts(sgsn_idx, bvci, BVC_S_BLOCKED, roroi);
2576}
2577
2578private altstep as_count_bvc_unblock(integer sgsn_idx, BssgpBvci bvci, inout roro_integer roroi)
2579runs on test_CT {
2580 [] as_count_bvc_sts(sgsn_idx, bvci, BVC_S_UNBLOCKED, roroi);
2581}
2582
Harald Welte16786e92020-11-27 19:11:56 +01002583/* reset the signaling BVC from one BSS; expect no signaling BVC reset on SGSN; but BVC-BLOCK for PTP */
2584testcase TC_bvc_reset_sig_from_bss() runs on test_CT {
2585
2586 f_init();
2587 f_sleep(3.0);
2588
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002589 for (var integer i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
2590 g_roroi[i] := {};
2591 }
2592
Harald Welte16786e92020-11-27 19:11:56 +01002593 /* Start BVC-RESET procedure for BVCI=0 */
2594 PCU_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to g_pcu[0].vc_BSSGP;
2595
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002596 /* Activate altsteps: One for each PTP BVC and SGSN within that PCUs NSE */
Harald Welte16786e92020-11-27 19:11:56 +01002597 var ro_default defaults := {};
2598 for (var integer i := 0; i < lengthof(g_pcu[0].cfg.bvc); i := i+1) {
2599 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[i];
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002600 for (var integer j := 0; j < lengthof(g_sgsn); j := j+1) {
2601 var default d := activate(as_count_bvc_block(j, bvcc.bvci, g_roroi));
2602 defaults := defaults & { d };
2603 }
Harald Welte16786e92020-11-27 19:11:56 +01002604 }
2605
2606 timer T := 3.0;
2607 T.start;
2608 alt {
2609 [] SGSN_MGMT.receive(BssgpResetIndication:{0}) {
2610 setverdict(fail, "BSS-side Reset of BVCI=0 should not propagate");
2611 }
2612 [] T.timeout;
2613 }
2614
2615 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2616 deactivate(defaults[i]);
2617 }
2618
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002619 /* check if BVC-block was received on all expected BVC/SGSN */
Harald Welte16786e92020-11-27 19:11:56 +01002620 for (var integer i := 0; i < lengthof(g_pcu[0].cfg.bvc); i := i+1) {
2621 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[i];
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002622 for (var integer j := 0; j < lengthof(g_sgsn); j := j+1) {
2623 if (not ro_integer_contains(g_roroi[j], bvcc.bvci)) {
2624 setverdict(fail, "Missing SGSN[", j, "] BVC-BLOCK of BVCI=", bvcc.bvci);
2625 }
Harald Welte16786e92020-11-27 19:11:56 +01002626 }
2627 }
2628
2629 /* check if BVC-block was not received on any unexpected BVC is not required as
2630 * such a message would basically run into 'no matching clause' */
Daniel Willmannf2590212020-12-04 14:20:50 +01002631 setverdict(pass);
Harald Welte16786e92020-11-27 19:11:56 +01002632 f_cleanup();
2633}
2634
Harald Welte60a8ec72020-11-25 17:12:53 +01002635private function f_reset_ptp_bvc_from_sgsn(integer pcu_idx, integer bvc_idx) runs on test_CT
2636{
2637 var BSSGP_BVC_CT pcu_bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2638 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2639 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2640 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(0, bvc_cfg.bvci);
2641 var default d;
2642
2643 SGSN_MGMT.clear;
2644 PCU_MGMT.clear;
2645
2646 /* block the PTP BVC from the PCU side */
2647 SGSN_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to sgsn_bvc_ct;
2648 /* expect state on both PCU and SGSN side to change */
2649 d := activate(as_ignore_status(PCU_MGMT));
2650 interleave {
2651 [] SGSN_MGMT.receive(tr_BssgpStsInd(?, bvc_cfg.bvci, BVC_S_BLOCKED)) from sgsn_bvc_ct;
2652 [] PCU_MGMT.receive(BssgpResetIndication:{bvc_cfg.bvci}) from pcu_bvc_ct;
2653 }
2654 deactivate(d);
2655 setverdict(pass);
2656}
2657/* Send a BVC-RESET for a PTP BVC from the SGSN side: expect it to propagate */
2658testcase TC_bvc_reset_ptp_from_sgsn() runs on test_CT
2659{
2660 f_init();
2661 f_sleep(3.0);
2662 f_reset_ptp_bvc_from_sgsn(0, 0);
2663 f_cleanup();
2664}
2665
Daniel Willmannef7015f2021-01-08 00:43:56 +01002666private altstep as_ignore_mgmt(BSSGP_BVC_MGMT_PT pt) {
2667 [] pt.receive {repeat; }
2668}
2669
Harald Welte16786e92020-11-27 19:11:56 +01002670private altstep as_count_bvc0_block(integer pcu_idx, Nsei nsei, inout ro_integer roi)
2671runs on test_CT {
2672 var BSSGP_CT pcu_ct := g_pcu[pcu_idx].vc_BSSGP;
2673 [] PCU_MGMT.receive(BssgpResetIndication:{0}) from pcu_ct {
2674 roi := roi & { nsei };
Daniel Willmannef7015f2021-01-08 00:43:56 +01002675 repeat;
Harald Welte16786e92020-11-27 19:11:56 +01002676 }
2677}
Daniel Willmannef7015f2021-01-08 00:43:56 +01002678
Harald Welte16786e92020-11-27 19:11:56 +01002679/* reset the signaling BVC from the SGSN; expect all signaling BVC on all BSS to be reset */
2680testcase TC_bvc_reset_sig_from_sgsn() runs on test_CT {
2681
2682 f_init();
2683 f_sleep(3.0);
2684
Daniel Willmannef7015f2021-01-08 00:43:56 +01002685 SGSN_MGMT.clear;
2686 PCU_MGMT.clear;
2687
Harald Welte16786e92020-11-27 19:11:56 +01002688 /* Start BVC-RESET procedure for BVCI=0 */
2689 SGSN_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to g_sgsn[0].vc_BSSGP;
2690
Daniel Willmannef7015f2021-01-08 00:43:56 +01002691 /* Defaults match in reverse activation order, this one is a catch-all for Status indications
2692 * and reset indications sent from other components (like the ptp_bvcs). If we don't drain
2693 * the port and a different message sits at the front we wait forever and fail the test.
2694 */
2695 var ro_default defaults := { activate(as_ignore_mgmt(PCU_MGMT)) };
2696
Harald Welte16786e92020-11-27 19:11:56 +01002697 /* Activate altsteps: One for each PCU NSE */
Harald Welte16786e92020-11-27 19:11:56 +01002698 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2699 var NSConfiguration nscfg := mp_nsconfig_pcu[i];
2700 var default d := activate(as_count_bvc0_block(i, nscfg.nsei, g_roi));
2701 defaults := defaults & { d };
2702 }
2703
2704 f_sleep(3.0);
2705
2706 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2707 deactivate(defaults[i]);
2708 }
2709
2710 /* check if BVC-block was received on all expected BVC */
2711 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2712 var NSConfiguration nscfg := mp_nsconfig_pcu[i];
2713 if (not ro_integer_contains(g_roi, nscfg.nsei)) {
2714 setverdict(fail, "Missing PCU-side BVC-RESET of BVCI=0 on PCU index ", i);
2715 }
2716 }
2717
2718 /* check if BVC-block was not received on any unexpected BVC is not required as
2719 * such a message would basically run into 'no matching clause' */
2720
2721 f_cleanup();
2722}
2723
Harald Welte299aa482020-12-09 15:10:55 +01002724/***********************************************************************
2725 * FLOW-CONTROL-BVC procedure
2726 ***********************************************************************/
2727
2728private altstep as_g_count_sgsn(integer sgsn_idx, inout ro_integer roi,
2729 template PDU_BSSGP exp_rx, template (omit) PDU_BSSGP tx_reply)
2730runs on GlobalTest_CT {
2731 [] G_SGSN[sgsn_idx].receive(exp_rx) {
2732 roi := roi & { sgsn_idx };
2733 if (ispresent(tx_reply)) {
2734 G_SGSN[sgsn_idx].send(tx_reply);
2735 }
Harald Welte5fb01742021-01-15 21:07:52 +01002736 repeat;
Harald Welte299aa482020-12-09 15:10:55 +01002737 }
2738}
2739/* Send FC-BVC from simulated PCU; expect each SGSN to receive it; expect PCU to receive ACK */
2740testcase TC_fc_bvc() runs on GlobalTest_CT
2741{
2742 f_init();
2743 f_global_init_ptp();
2744
Pau Espin Pedrol6ee01262021-02-05 13:05:06 +01002745 var template (value) PDU_BSSGP pdu_tx := ts_BVC_FC_BVC(10240, 2000, 1024, 1000, '01'O);
Harald Welte299aa482020-12-09 15:10:55 +01002746 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2747 var template (present) PDU_BSSGP pdu_rx := tr_BVC_FC_BVC(10240, 2000, 1024, 1000, '01'O);
Pau Espin Pedrol6ee01262021-02-05 13:05:06 +01002748 var template (value) PDU_BSSGP ack_tx :=
2749 ts_BVC_FC_BVC_ACK(pdu_tx.pDU_BSSGP_FLOW_CONTROL_BVC.tag.unstructured_Value);
Harald Welte299aa482020-12-09 15:10:55 +01002750
2751 /* Send a FC-BVC from BSS to gbproxy, expect an ACK in response */
2752 G_PCU[0].send(pdu_tx);
2753
2754 /* Activate altsteps: One for each SGSN-side PTP BVC port */
2755 var ro_default defaults := {};
2756 for (var integer i := 0; i < lengthof(g_sgsn); i := i+1) {
2757 var default d := activate(as_g_count_sgsn(i, g_roi, pdu_rx, ack_tx));
2758 defaults := defaults & { d };
2759 }
2760
2761 f_sleep(3.0);
2762
2763 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2764 deactivate(defaults[i]);
2765 }
2766
2767 /* check if BVC-block was received on all expected BVC */
2768 for (var integer i := 0; i < lengthof(g_sgsn); i := i+1) {
2769 if (not ro_integer_contains(g_roi, i)) {
2770 setverdict(fail, "Missing BVC-FLOW-CONTROL on SGSN index ", i);
2771 }
2772 }
2773
2774 /* Expect ACK on PCU side */
2775 G_PCU[0].receive(ack_tx);
2776
2777 setverdict(pass);
2778
2779 f_cleanup();
2780}
2781
Harald Weltecc3894b2020-12-09 16:50:12 +01002782/***********************************************************************
2783 * FLOW-CONTROL-MS procedure
2784 ***********************************************************************/
2785
2786private function f_TC_fc_ms(charstring id) runs on BSSGP_ConnHdlr {
2787 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
2788
2789 var template (value) PDU_BSSGP fc_tx := ts_BVC_FC_MS(g_pars.tlli, 100, 200, '12'O);
2790 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2791 var template (present) PDU_BSSGP fc_rx := tr_BVC_FC_MS(g_pars.tlli, 100, 200, '12'O);
2792 var template (value) PDU_BSSGP ack_tx := ts_BVC_FC_MS_ACK(g_pars.tlli, '12'O);
2793
2794 f_pcu2sgsn(fc_tx, fc_rx, use_sig := false);
2795 f_sgsn2pcu(ack_tx, ack_tx, use_sig := false);
2796
2797 setverdict(pass);
2798}
2799/* Send a FLOW-CONTROL-MS from BSS side and expect it to show up on SGSN (PTP BVC) */
2800testcase TC_fc_ms() runs on test_CT
2801{
Harald Weltecc3894b2020-12-09 16:50:12 +01002802 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002803 f_start_handlers(refers(f_TC_fc_ms), testcasename(), 21);
Harald Weltecc3894b2020-12-09 16:50:12 +01002804 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Weltecc3894b2020-12-09 16:50:12 +01002805 f_cleanup();
2806}
2807
Harald Welted6f89812021-01-16 18:57:49 +01002808/***********************************************************************
2809 * MS-REGISTRATION ENQUIRY procedure
2810 ***********************************************************************/
Harald Weltecc3894b2020-12-09 16:50:12 +01002811
Harald Welted6f89812021-01-16 18:57:49 +01002812private function f_TC_ms_reg_enq(charstring id) runs on BSSGP_ConnHdlr
2813{
2814 f_pcu2sgsn(ts_BSSGP_MS_REG_ENQ(g_pars.imsi), tr_BSSGP_MS_REG_ENQ(g_pars.imsi), use_sig := true);
2815 f_sgsn2pcu(ts_BSSGP_MS_REW_ENQ_RESP(g_pars.imsi, omit), tr_BSSGP_MS_REW_ENQ_RESP(g_pars.imsi, omit), use_sig := true);
2816}
2817testcase TC_ms_reg_enq() runs on test_CT
2818{
2819 f_init();
2820 f_start_handlers(refers(f_TC_ms_reg_enq), testcasename(), 22);
2821 f_cleanup();
2822}
Harald Welte299aa482020-12-09 15:10:55 +01002823
Harald Weltef86f1852021-01-16 21:56:17 +01002824/***********************************************************************
2825 * RIM (RAN Information Management)
2826 ***********************************************************************/
2827
2828/* Our tests here are rather synthetic, as they don't reflect normal message flows
2829 as they would be observed in a live network. However, for testing gbproxy, this shouldn't
2830 matter as gbproxy is not concerned with anything but the source / destination routing
2831 information */
2832
2833/* gbproxy must route all unknown RIM Routing Info (Cell Id) to the SGSN. We just define
2834 one here of which we know it is not used among the [simulated] PCUs */
2835const BssgpCellId cell_id_sgsn := {
2836 ra_id := {
2837 lai := {
2838 mcc_mnc := c_mcc_mnc,
2839 lac := 65534
2840 },
2841 rac := 0
2842 },
2843 cell_id := 65533
2844};
2845
2846/* Send 'tx' on PTP-BVCI from PCU; expect 'rx' on any of our SGSN (RIM can be routed anywhere) */
2847friend function f_rim_pcu2sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
2848 integer pcu_idx := 0) runs on GlobalTest_CT {
2849 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +01002850 timer T := 2.0;
Harald Weltef86f1852021-01-16 21:56:17 +01002851
2852 RIM_PCU[pcu_idx].send(tx);
2853 T.start;
2854 alt {
2855 [] any from RIM_SGSN.receive(exp_rx) {
2856 setverdict(pass);
2857 }
2858 [] any from RIM_SGSN.receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +01002859 f_shutdown(__FILE__, __LINE__, fail, log2str("Unexpected BSSGP on SGSN side: ", rx));
Harald Weltef86f1852021-01-16 21:56:17 +01002860 }
2861 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +01002862 f_shutdown(__FILE__, __LINE__, fail,
2863 log2str("Timeout waiting for BSSGP on SGSN side: ", exp_rx));
Harald Weltef86f1852021-01-16 21:56:17 +01002864 }
2865 }
2866}
2867
2868/* Send 'tx' on PTP-BVCI from SGSN; expect 'rx' on PCU */
2869friend function f_rim_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
2870 integer sgsn_idx := 0, integer pcu_idx := 0) runs on GlobalTest_CT {
2871 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +01002872 timer T := 2.0;
Harald Weltef86f1852021-01-16 21:56:17 +01002873
2874 RIM_SGSN[sgsn_idx].send(tx);
2875 T.start;
2876 alt {
2877 [] RIM_PCU[pcu_idx].receive(exp_rx) {
2878 setverdict(pass);
2879 }
2880 [] RIM_PCU[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +01002881 f_shutdown(__FILE__, __LINE__, fail, log2str("Unexpected BSSGP on PCU side: ", rx));
Harald Weltef86f1852021-01-16 21:56:17 +01002882 }
2883 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +01002884 f_shutdown(__FILE__, __LINE__, fail,
2885 log2str("Timeout waiting for BSSGP on PCU side: ", exp_rx));
Harald Weltef86f1852021-01-16 21:56:17 +01002886 }
2887 }
2888}
2889
2890/* Send 'tx' on PTP-BVCI from SRC-PCU; expect 'rx' on DST-PCU */
2891friend function f_rim_pcu2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
2892 integer src_pcu_idx, integer dst_pcu_idx) runs on GlobalTest_CT {
2893 var integer rx_idx;
2894 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +01002895 timer T := 2.0;
Harald Weltef86f1852021-01-16 21:56:17 +01002896
2897 RIM_PCU[src_pcu_idx].send(tx);
2898 T.start;
2899 alt {
2900 [] RIM_PCU[dst_pcu_idx].receive(exp_rx) -> value rx{
2901 setverdict(pass);
2902 }
2903 [] any from RIM_PCU.receive(exp_rx) -> @index value rx_idx {
2904 setverdict(fail, "Received RIM on wrong PCU[", rx_idx ,"], expected on PCU[", dst_pcu_idx, "]");
2905 }
2906 [] any from RIM_SGSN.receive(exp_rx) {
2907 setverdict(fail, "Received RIM on SGSN but expected it on other PCU");
2908 }
2909 [] any from RIM_SGSN.receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +01002910 f_shutdown(__FILE__, __LINE__, fail, log2str("Unexpected BSSGP on SGSN side: ", rx));
Harald Weltef86f1852021-01-16 21:56:17 +01002911 }
2912 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +01002913 f_shutdown(__FILE__, __LINE__, fail,
2914 log2str("Timeout waiting for BSSGP on SGSN side: ", exp_rx));
Harald Weltef86f1852021-01-16 21:56:17 +01002915 }
2916 }
2917}
2918
2919
2920type function rim_fn(integer sgsn_idx, integer pcu_idx, integer bvc_idx) runs on GlobalTest_CT;
2921
2922/* helper function for the RIM test cases: Execute 'fn' for each BVC on each PCU for
2923 each SGSN */
2924private function f_rim_iterator(rim_fn fn) runs on GlobalTest_CT
2925{
2926 var integer sgsn_idx, pcu_idx, bvc_idx;
2927 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx+1) {
2928 for (pcu_idx := 0; pcu_idx < lengthof(g_pcu); pcu_idx := pcu_idx+1) {
2929 for (bvc_idx := 0; bvc_idx < lengthof(g_pcu[pcu_idx].cfg.bvc); bvc_idx := bvc_idx+1) {
2930 log("Testing RIM SGSN[", sgsn_idx, "] <-> PCU[", pcu_idx, "][", bvc_idx, "]");
2931 fn.apply(sgsn_idx, pcu_idx, bvc_idx);
2932 }
2933 }
2934 }
2935}
2936
2937/* RAN-INFORMATION-REQUEST */
2938private function f_TC_rim_info_req(integer sgsn_idx, integer pcu_idx, integer bvc_idx := 0)
2939runs on GlobalTest_CT
2940{
2941 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
Philipp Maier14d3a8e2021-01-28 21:43:16 +01002942 var template (value) RAN_Information_Request_RIM_Container cont_tx;
2943 var template RAN_Information_Request_RIM_Container cont_rx;
2944 var template RIM_Routing_Address ra_pcu;
2945 var template RIM_Routing_Address ra_sgsn;
Harald Weltef86f1852021-01-16 21:56:17 +01002946
Philipp Maier14d3a8e2021-01-28 21:43:16 +01002947 ra_pcu := t_RIM_Routing_Address_cid(cell_id);
2948 ra_sgsn := t_RIM_Routing_Address_cid(cell_id_sgsn);
2949
2950 cont_tx := ts_RAN_Information_Request_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
2951 ts_RIM_Sequence_Number(0),
2952 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
2953 cont_rx := tr_RAN_Information_Request_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
2954 tr_RIM_Sequence_Number(0),
2955 tr_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
2956
2957 f_rim_pcu2sgsn(ts_RAN_INFORMATION_REQUEST(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
2958 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
2959 cont := cont_tx),
2960 tr_RAN_INFORMATION_REQUEST(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
2961 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
2962 cont := cont_rx),
2963 pcu_idx);
2964
2965 f_rim_sgsn2pcu(ts_RAN_INFORMATION_REQUEST(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
2966 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
2967 cont := cont_tx),
2968 tr_RAN_INFORMATION_REQUEST(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
2969 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
2970 cont := cont_rx),
Harald Weltef86f1852021-01-16 21:56:17 +01002971 sgsn_idx, pcu_idx);
2972}
2973testcase TC_rim_info_req() runs on GlobalTest_CT
2974{
2975 f_init();
2976 f_global_init();
2977 f_rim_iterator(refers(f_TC_rim_info_req));
2978 f_cleanup();
2979}
2980
2981/* RAN-INFORMATION */
2982private function f_TC_rim_info(integer sgsn_idx, integer pcu_idx, integer bvc_idx := 0)
2983runs on GlobalTest_CT
2984{
2985 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
Philipp Maier14d3a8e2021-01-28 21:43:16 +01002986 var template (value) RAN_Information_RIM_Container cont_tx;
2987 var template RAN_Information_RIM_Container cont_rx;
2988 var template RIM_Routing_Address ra_pcu;
2989 var template RIM_Routing_Address ra_sgsn;
Harald Weltef86f1852021-01-16 21:56:17 +01002990
Philipp Maier14d3a8e2021-01-28 21:43:16 +01002991 ra_pcu := t_RIM_Routing_Address_cid(cell_id);
2992 ra_sgsn := t_RIM_Routing_Address_cid(cell_id_sgsn);
2993
2994 cont_tx := ts_RAN_Information_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
2995 ts_RIM_Sequence_Number(0),
2996 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
2997
2998 cont_rx := tr_RAN_Information_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
2999 tr_RIM_Sequence_Number(0),
3000 tr_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
3001
3002 f_rim_pcu2sgsn(ts_PDU_BSSGP_RAN_INFORMATION(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3003 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3004 cont := cont_tx),
3005 tr_PDU_BSSGP_RAN_INFORMATION(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3006 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3007 cont := cont_rx),
3008 pcu_idx);
3009
3010 f_rim_sgsn2pcu(ts_PDU_BSSGP_RAN_INFORMATION(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3011 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3012 cont := cont_tx),
3013 tr_PDU_BSSGP_RAN_INFORMATION(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3014 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3015 cont := cont_rx),
Harald Weltef86f1852021-01-16 21:56:17 +01003016 sgsn_idx, pcu_idx);
3017}
3018testcase TC_rim_info() runs on GlobalTest_CT
3019{
3020 f_init();
3021 f_global_init();
3022 f_rim_iterator(refers(f_TC_rim_info));
3023 f_cleanup();
3024}
3025
3026/* RAN-INFORMATION-ACK */
3027private function f_TC_rim_info_ack(integer sgsn_idx, integer pcu_idx, integer bvc_idx := 0)
3028runs on GlobalTest_CT
3029{
3030 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003031 var template (value) RAN_Information_Ack_RIM_Container cont_tx;
3032 var template RAN_Information_Ack_RIM_Container cont_rx;
3033 var template RIM_Routing_Address ra_pcu;
3034 var template RIM_Routing_Address ra_sgsn;
Harald Weltef86f1852021-01-16 21:56:17 +01003035
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003036 ra_pcu := t_RIM_Routing_Address_cid(cell_id);
3037 ra_sgsn := t_RIM_Routing_Address_cid(cell_id_sgsn);
3038
3039 cont_tx := ts_RAN_Information_Ack_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3040 ts_RIM_Sequence_Number(0));
3041
3042 cont_rx := tr_RAN_Information_Ack_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
3043 tr_RIM_Sequence_Number(0));
3044
3045 f_rim_pcu2sgsn(ts_PDU_BSSGP_RAN_INFORMATION_ACK(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3046 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3047 cont := cont_tx),
3048 tr_PDU_BSSGP_RAN_INFORMATION_ACK(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3049 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3050 cont := cont_rx),
3051 pcu_idx);
3052
3053 f_rim_sgsn2pcu(ts_PDU_BSSGP_RAN_INFORMATION_ACK(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3054 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3055 cont := cont_tx),
3056 tr_PDU_BSSGP_RAN_INFORMATION_ACK(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3057 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3058 cont := cont_rx),
Harald Weltef86f1852021-01-16 21:56:17 +01003059 sgsn_idx, pcu_idx);
3060}
3061testcase TC_rim_info_ack() runs on GlobalTest_CT
3062{
3063 f_init();
3064 f_global_init();
3065 f_rim_iterator(refers(f_TC_rim_info_ack));
3066 f_cleanup();
3067}
3068
3069/* RAN-INFORMATION-ERROR */
3070private function f_TC_rim_info_error(integer sgsn_idx, integer pcu_idx, integer bvc_idx := 0)
3071runs on GlobalTest_CT
3072{
3073 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003074 var template (value) RAN_Information_Error_RIM_Container cont_tx;
3075 var template RAN_Information_Error_RIM_Container cont_rx;
3076 var template RIM_Routing_Address ra_pcu;
3077 var template RIM_Routing_Address ra_sgsn;
Harald Weltef86f1852021-01-16 21:56:17 +01003078
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003079 ra_pcu := t_RIM_Routing_Address_cid(cell_id);
3080 ra_sgsn := t_RIM_Routing_Address_cid(cell_id_sgsn);
3081
3082 cont_tx := ts_RAN_Information_Error_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3083 ts_BSSGP_CAUSE(BSSGP_CAUSE_EQUIMENT_FAILURE),
Pau Espin Pedrol6ee01262021-02-05 13:05:06 +01003084 omit, valueof(ts_BVC_UNBLOCK(23)));
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003085
3086 cont_rx := tr_RAN_Information_Error_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
Pau Espin Pedrol6ee01262021-02-05 13:05:06 +01003087 ts_BSSGP_CAUSE(BSSGP_CAUSE_EQUIMENT_FAILURE),
3088 omit, enc_PDU_BSSGP(valueof(tr_BVC_UNBLOCK(23))));
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003089
3090 f_rim_pcu2sgsn(ts_PDU_BSSGP_RAN_INFORMATION_ERROR(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3091 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3092 cont := cont_tx),
3093 tr_PDU_BSSGP_RAN_INFORMATION_ERROR(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3094 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3095 cont := cont_rx),
3096 pcu_idx);
3097
3098 f_rim_sgsn2pcu(ts_PDU_BSSGP_RAN_INFORMATION_ERROR(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3099 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3100 cont := cont_tx),
3101 tr_PDU_BSSGP_RAN_INFORMATION_ERROR(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3102 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3103 cont := cont_rx),
Harald Weltef86f1852021-01-16 21:56:17 +01003104 sgsn_idx, pcu_idx);
3105}
3106testcase TC_rim_info_error() runs on GlobalTest_CT
3107{
3108 f_init();
3109 f_global_init();
3110 f_rim_iterator(refers(f_TC_rim_info_error));
3111 f_cleanup();
3112}
3113
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003114//////////////////
Harald Weltef86f1852021-01-16 21:56:17 +01003115/* RAN-INFORMATION-APPLICATION-ERROR */
3116private function f_TC_rim_info_app_error(integer sgsn_idx, integer pcu_idx, integer bvc_idx := 0)
3117runs on GlobalTest_CT
3118{
3119 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003120 var template (value) Application_Error_Container app_cont_tx;
3121 var template Application_Error_Container app_cont_rx;
3122 var template (value) RAN_Information_Application_Error_RIM_Container cont_tx;
3123 var template RAN_Information_Application_Error_RIM_Container cont_rx;
3124 var template RIM_Routing_Address ra_pcu;
3125 var template RIM_Routing_Address ra_sgsn;
Harald Weltef86f1852021-01-16 21:56:17 +01003126
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003127 ra_pcu := t_RIM_Routing_Address_cid(cell_id);
3128 ra_sgsn := t_RIM_Routing_Address_cid(cell_id_sgsn);
3129
3130 app_cont_tx := tsu_Application_Error_Container_NACC(cell_id, 23,
3131 tsu_Application_Container_IE_NACC_req(cell_id));
3132
3133 app_cont_rx := rsu_Application_Error_Container_NACC(cell_id, 23,
3134 rsu_Application_Container_IE_NACC_req(cell_id));
3135
3136 cont_tx := ts_RAN_Information_Application_Error_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3137 ts_RIM_Sequence_Number(0),
3138 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP),
3139 omit, app_cont_tx);
3140 cont_rx := tr_RAN_Information_Application_Error_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
3141 tr_RIM_Sequence_Number(0),
3142 tr_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP),
3143 omit, app_cont_rx);
3144
3145 f_rim_pcu2sgsn(ts_PDU_BSSGP_RAN_INFORMATION_APPLICATION_ERROR(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3146 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3147 cont := cont_tx),
3148 tr_PDU_BSSGP_RAN_INFORMATION_APPLICATION_ERROR(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3149 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3150 cont := cont_rx),
3151 pcu_idx);
3152
3153 f_rim_sgsn2pcu(ts_PDU_BSSGP_RAN_INFORMATION_APPLICATION_ERROR(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3154 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3155 cont := cont_tx),
3156 tr_PDU_BSSGP_RAN_INFORMATION_APPLICATION_ERROR(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3157 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3158 cont := cont_rx),
Harald Weltef86f1852021-01-16 21:56:17 +01003159 sgsn_idx, pcu_idx);
3160}
3161testcase TC_rim_info_app_error() runs on GlobalTest_CT
3162{
3163 f_init();
3164 f_global_init();
3165 f_rim_iterator(refers(f_TC_rim_info_app_error));
3166 f_cleanup();
3167}
3168
3169/* RAN-INFORMATION routing directly between PCUs, without SGSN involvement */
3170private function f_TC_rim_info_pcu2pcu(integer src_pcu_idx, integer src_bvc_idx,
3171 integer dst_pcu_idx, integer dst_bvc_idx)
3172runs on GlobalTest_CT
3173{
3174 var BssgpCellId cell_id_src := g_pcu[src_pcu_idx].cfg.bvc[src_bvc_idx].cell_id;
3175 var BssgpCellId cell_id_dst := g_pcu[dst_pcu_idx].cfg.bvc[dst_bvc_idx].cell_id;
Philipp Maier1bd60ce2021-02-10 18:25:50 +01003176 var template (value) RIM_Routing_Information ri_pcu_src_tx;
3177 var template (value) RIM_Routing_Information ri_pcu_dst_tx;
3178 var template RIM_Routing_Information ri_pcu_src_rx;
3179 var template RIM_Routing_Information ri_pcu_dst_rx;
3180 var template (value) RAN_Information_RIM_Container cont_tx;
3181 var template RAN_Information_RIM_Container cont_rx;
Harald Weltef86f1852021-01-16 21:56:17 +01003182
3183 log("Testing RIM PCU2PCU from PCU[", src_pcu_idx, "][", src_bvc_idx, "] to PCU[",
3184 dst_pcu_idx, "][", dst_bvc_idx, "]");
3185
Philipp Maier1bd60ce2021-02-10 18:25:50 +01003186 ri_pcu_src_tx := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID,
Harald Weltef86f1852021-01-16 21:56:17 +01003187 t_RIM_Routing_Address_cid(cell_id_src));
Philipp Maier1bd60ce2021-02-10 18:25:50 +01003188 ri_pcu_dst_tx := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID,
Harald Weltef86f1852021-01-16 21:56:17 +01003189 t_RIM_Routing_Address_cid(cell_id_dst));
Philipp Maier1bd60ce2021-02-10 18:25:50 +01003190 ri_pcu_src_rx := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID,
3191 t_RIM_Routing_Address_cid(cell_id_src));
3192 ri_pcu_dst_rx := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID,
3193 t_RIM_Routing_Address_cid(cell_id_dst));
3194
3195 cont_tx := ts_RAN_Information_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3196 ts_RIM_Sequence_Number(0),
3197 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
3198 cont_rx := tr_RAN_Information_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
3199 tr_RIM_Sequence_Number(0),
3200 tr_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
3201
3202 f_rim_pcu2pcu(ts_PDU_BSSGP_RAN_INFORMATION(dst := ri_pcu_dst_tx, src := ri_pcu_src_tx, cont := cont_tx),
3203 tr_PDU_BSSGP_RAN_INFORMATION(dst := ri_pcu_dst_rx, src := ri_pcu_src_rx, cont := cont_rx),
Harald Weltef86f1852021-01-16 21:56:17 +01003204 src_pcu_idx, dst_pcu_idx);
3205}
3206testcase TC_rim_info_pcu2pcu() runs on GlobalTest_CT
3207{
3208 var integer src_pcu_idx, dst_pcu_idx;
3209 var integer src_bvc_idx, dst_bvc_idx;
3210 f_init();
3211 f_global_init();
3212
3213 for (src_pcu_idx := 0; src_pcu_idx < lengthof(g_pcu); src_pcu_idx := src_pcu_idx + 1) {
3214 for (src_bvc_idx := 0; src_bvc_idx < lengthof(g_pcu[src_pcu_idx].cfg.bvc); src_bvc_idx := src_bvc_idx + 1) {
3215 for (dst_pcu_idx := 0; dst_pcu_idx < lengthof(g_pcu); dst_pcu_idx := dst_pcu_idx + 1) {
3216 if (dst_pcu_idx == src_pcu_idx) {
3217 continue;
3218 }
3219
3220 for (dst_bvc_idx := 0; dst_bvc_idx < lengthof(g_pcu[dst_pcu_idx].cfg.bvc);
3221dst_bvc_idx := dst_bvc_idx + 1) {
3222 f_TC_rim_info_pcu2pcu(src_pcu_idx, src_bvc_idx, dst_pcu_idx, dst_bvc_idx);
3223 }
3224 }
3225 }
3226 }
3227
3228 f_cleanup();
3229}
3230
Harald Welte04358652021-01-17 13:48:13 +01003231/***********************************************************************
3232 * STATUS handling
3233 ***********************************************************************/
3234
3235/* BSSGP STATUS PDU must be routed based on inner "PDU In Error" message */
3236
3237/* generate a TMSI with NRI matching sgsn_idx + nri_idx */
3238private function f_gen_tmsi_for_sgsn_nri(integer sgsn_idx, integer nri_idx) runs on test_CT return OCT4
3239{
3240 var integer nri := mp_sgsn_nri[sgsn_idx][nri_idx];
3241 return f_gen_tmsi(0, nri_v := nri, nri_bitlen := mp_nri_bitlength);
3242}
3243
3244/* generate a TLLI with NRI matching sgsn_idx + nri_idx */
3245private function f_gen_tlli_for_sgsn_nri(integer sgsn_idx, integer nri_idx) runs on test_CT return OCT4
3246{
3247 var OCT4 p_tmsi := f_gen_tmsi_for_sgsn_nri(sgsn_idx, nri_idx);
3248 return f_gprs_tlli_from_tmsi(p_tmsi, TLLI_LOCAL);
3249}
3250
3251/* STATUS in uplink direction; expect routing by its NRI */
3252private function f_TC_status_ul(integer pcu_idx, integer sgsn_idx, PDU_BSSGP inner)
3253runs on GlobalTest_CT
3254{
3255 var template (value) PDU_BSSGP tx := ts_BSSGP_STATUS(omit, BSSGP_CAUSE_EQUIMENT_FAILURE, inner);
3256 var template (present) PDU_BSSGP exp_rx :=
3257 tr_BSSGP_STATUS(omit, BSSGP_CAUSE_EQUIMENT_FAILURE,
3258 tx.pDU_BSSGP_STATUS.pDU_in_Error.erroneous_BSSGP_PDU);
3259
3260 f_global_pcu2sgsn(tx, exp_rx, pcu_idx, sgsn_idx);
3261}
3262
3263/* STATUS in uplink direction; expect routing by its NRI */
3264private function f_TC_status_dl(integer sgsn_idx, integer pcu_idx, PDU_BSSGP inner)
3265runs on GlobalTest_CT
3266{
3267 var template (value) PDU_BSSGP tx := ts_BSSGP_STATUS(omit, BSSGP_CAUSE_EQUIMENT_FAILURE, inner);
3268 var template (present) PDU_BSSGP exp_rx :=
3269 tr_BSSGP_STATUS(omit, BSSGP_CAUSE_EQUIMENT_FAILURE,
3270 tx.pDU_BSSGP_STATUS.pDU_in_Error.erroneous_BSSGP_PDU);
3271
3272 f_global_sgsn2pcu(tx, exp_rx, sgsn_idx, pcu_idx);
3273}
3274
3275/* STATUS in uplink direction on SIG-BVC containing a TLLI; expect routing by its NRI */
3276testcase TC_status_sig_ul_tlli() runs on GlobalTest_CT
3277{
3278 var integer sgsn_idx, nri_idx;
3279
3280 f_init();
3281 f_global_init();
3282
3283 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3284 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx + 1) {
3285 /* some downlink PDU occurring on SIG-BVC with a TLLI */
3286 var OCT4 tlli := f_gen_tlli_for_sgsn_nri(sgsn_idx, nri_idx);
3287 var PDU_BSSGP inner := valueof(ts_BSSGP_FLUSH_LL(tlli, 2342));
3288
3289 f_TC_status_ul(0, sgsn_idx, inner);
3290 }
3291 }
3292
3293 f_cleanup();
3294}
3295
3296/* STATUS in uplink direction on SIG-BVC containing a TMSI; expect routing by its NRI */
3297testcase TC_status_sig_ul_tmsi() runs on GlobalTest_CT
3298{
3299 var integer sgsn_idx, nri_idx;
3300
3301 f_init();
3302 f_global_init();
3303
3304 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3305 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx + 1) {
3306 /* some downlink PDU occurring on SIG-BVC with a TMSI */
3307 const hexstring imsi := '001010123456789'H
3308 var OCT4 tmsi := f_gen_tmsi_for_sgsn_nri(sgsn_idx, nri_idx);
3309 var BssgpBvci bvci := g_pcu[0].cfg.bvc[0].bvci;
3310 var PDU_BSSGP inner := valueof(ts_BSSGP_CS_PAGING_PTMSI(bvci, imsi, oct2int(tmsi)));
3311 f_TC_status_ul(0, sgsn_idx, inner);
3312 }
3313 }
3314
3315 f_cleanup();
3316}
3317
3318
3319/* STATUS in uplink direction on PTP-BVC containing a TLLI; expect routing by its NRI */
3320testcase TC_status_ptp_ul_tlli() runs on GlobalTest_CT
3321{
3322 var integer sgsn_idx, nri_idx;
3323
3324 f_init();
3325 f_global_init_ptp();
3326
3327 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3328 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx + 1) {
3329 /* some downlink PDU occurring on PTP-BVC with a TLLI */
3330 var OCT4 tlli := f_gen_tlli_for_sgsn_nri(sgsn_idx, nri_idx);
3331 var PDU_BSSGP inner := valueof(ts_BSSGP_DL_UD(tlli, '2342'O));
3332
3333 f_TC_status_ul(0, sgsn_idx, inner);
3334 }
3335 }
3336
3337 f_cleanup();
3338}
3339
3340/* STATUS in uplink direction on PTP-BVC containing a TMSI; expect routing by its NRI */
3341testcase TC_status_ptp_ul_tmsi() runs on GlobalTest_CT
3342{
3343 var integer sgsn_idx, nri_idx;
3344
3345 f_init();
3346 f_global_init_ptp();
3347
3348 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3349 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx + 1) {
3350 /* some downlink PDU occurring on PTP-BVC with a TMSI */
3351 const hexstring imsi := '001010123456789'H
3352 var OCT4 tmsi := f_gen_tmsi_for_sgsn_nri(sgsn_idx, nri_idx);
3353 var BssgpBvci bvci := g_pcu[0].cfg.bvc[0].bvci;
3354 var PDU_BSSGP inner := valueof(ts_BSSGP_CS_PAGING_PTMSI(bvci, imsi, oct2int(tmsi)));
3355 f_TC_status_ul(0, sgsn_idx, inner);
3356 }
3357 }
3358
3359 f_cleanup();
3360}
3361
3362/* STATUS in downlink direction in SIG-BVC containing a BVCI; expect routing by it */
3363testcase TC_status_sig_dl_bvci() runs on GlobalTest_CT
3364{
3365 var integer sgsn_idx, pcu_idx, bvc_idx;
3366
3367 f_init();
3368 f_global_init();
3369
3370 /* test each BVC in each PCU from each SGSN */
3371 for (pcu_idx := 0; pcu_idx < lengthof(g_pcu); pcu_idx := pcu_idx + 1) {
3372 for (bvc_idx := 0; bvc_idx < lengthof(g_pcu[pcu_idx].cfg.bvc); bvc_idx := bvc_idx + 1) {
3373 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3374 /* some uplink PDU occurring on SIG-BVC containing a BVCI */
3375 var BssgpBvci bvci := g_pcu[pcu_idx].cfg.bvc[bvc_idx].bvci;
3376 var PDU_BSSGP inner := valueof(ts_BSSGP_LLC_DISCARDED('12345678'O, 1, bvci, 23));
3377 f_TC_status_dl(sgsn_idx, pcu_idx, inner);
3378 }
3379 }
3380 }
3381
3382 f_cleanup();
3383}
3384
3385/* STATUS in downlink direction in PTP-BVC; expect routing by BVCI */
3386testcase TC_status_ptp_dl_bvci() runs on GlobalTest_CT
3387{
3388 var integer sgsn_idx, pcu_idx, bvc_idx;
3389
3390 f_init();
3391 f_global_init_ptp();
3392
3393 /* test each BVC in each PCU from each SGSN */
3394 for (pcu_idx := 0; pcu_idx < lengthof(g_pcu); pcu_idx := pcu_idx + 1) {
3395 for (bvc_idx := 0; bvc_idx < lengthof(g_pcu[pcu_idx].cfg.bvc); bvc_idx := bvc_idx + 1) {
3396 var BssgpBvci bvci := g_pcu[pcu_idx].cfg.bvc[bvc_idx].bvci;
3397 f_global_ptp_connect_pcu_bvci(pcu_idx, bvci);
3398 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3399 f_global_ptp_connect_sgsn_bvci(sgsn_idx, bvci);
3400
3401 /* some uplink PDU occurring on PTP-BVC */
3402 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
3403 var PDU_BSSGP inner := valueof(ts_BSSGP_UL_UD('12345678'O, cell_id, '4223'O));
3404 f_TC_status_dl(sgsn_idx, pcu_idx, inner);
3405 }
3406 }
3407 }
3408
3409 f_cleanup();
3410}
3411
3412/* TODO: test case for DL-STATUS(SUSPEND/RESUME) containing RA-ID; expect routing by RA-ID */
3413/* TODO: test case for UL-STATUS(PAGING-by-IMSI) after sending an actual PAGIN-by-IMSI in DL first */
Harald Weltef86f1852021-01-16 21:56:17 +01003414
Daniel Willmann423d8f42020-09-08 18:58:22 +02003415control {
3416 execute( TC_BVC_bringup() );
Harald Welte92686012020-11-15 21:45:49 +01003417 execute( TC_ul_unitdata() );
Harald Welte78d8db92020-11-15 23:27:27 +01003418 execute( TC_dl_unitdata() );
Harald Welte6dc2ac42020-11-16 09:16:17 +01003419 execute( TC_ra_capability() );
Daniel Willmannace3ece2020-11-16 19:53:26 +01003420 execute( TC_ra_capability_upd() );
Daniel Willmann165d6612020-11-19 14:27:29 +01003421 execute( TC_radio_status() );
Harald Welte3148a962021-01-17 11:15:28 +01003422 execute( TC_radio_status_tmsi() );
3423 execute( TC_radio_status_imsi() );
Daniel Willmannfa67f492020-11-19 15:48:05 +01003424 execute( TC_suspend() );
Daniel Willmann087a33d2020-11-19 15:58:43 +01003425 execute( TC_resume() );
Harald Weltef8e5c5d2020-11-27 22:37:23 +01003426 execute( TC_trace() );
Harald Weltec0351d12020-11-27 22:49:02 +01003427 execute( TC_llc_discarded() );
Harald Weltef20af412020-11-28 16:11:11 +01003428 execute( TC_overload() );
Harald Welte239aa502020-11-24 23:14:20 +01003429 execute( TC_bvc_block_ptp() );
3430 execute( TC_bvc_unblock_ptp() );
Harald Welte60a8ec72020-11-25 17:12:53 +01003431 execute( TC_bvc_reset_ptp_from_bss() );
Harald Welte16786e92020-11-27 19:11:56 +01003432 execute( TC_bvc_reset_sig_from_bss() );
Harald Welte60a8ec72020-11-25 17:12:53 +01003433 execute( TC_bvc_reset_ptp_from_sgsn() );
Harald Welte16786e92020-11-27 19:11:56 +01003434 execute( TC_bvc_reset_sig_from_sgsn() );
Harald Weltef6e59b02020-12-08 08:29:09 +01003435 if (mp_enable_bss_load_sharing) {
Harald Weltef8ef0282020-11-18 12:16:59 +01003436 /* don't enable this by default, as we don't yet have any automatic test setup for FR with 4 NS-VC */
3437 execute( TC_load_sharing_dl() );
3438 }
Harald Welte0e188242020-11-22 21:46:48 +01003439
3440 /* PAGING-PS over PTP BVC */
3441 execute( TC_paging_ps_ptp_bss() );
3442 execute( TC_paging_ps_ptp_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01003443 execute( TC_paging_ps_ptp_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003444 execute( TC_paging_ps_ptp_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01003445 execute( TC_paging_ps_ptp_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003446 execute( TC_paging_ps_ptp_bvci() );
Harald Welteb5a04aa2021-01-16 13:04:40 +01003447 execute( TC_paging_ps_ptp_bvci_imsi() );
Harald Welte7462a592020-11-23 22:07:07 +01003448 execute( TC_paging_ps_ptp_bvci_unknown() );
Harald Weltecf200072021-01-16 15:20:46 +01003449 execute( TC_paging_ps_reject_ptp_bvci() );
3450 execute( TC_paging_ps_reject_ptp_bvci_imsi() );
Harald Welte7595d562021-01-16 19:09:20 +01003451 execute( TC_dummy_paging_ps_ptp() );
Harald Welte0e188242020-11-22 21:46:48 +01003452
3453 /* PAGING-PS over SIG BVC */
3454 execute( TC_paging_ps_sig_bss() );
3455 execute( TC_paging_ps_sig_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01003456 execute( TC_paging_ps_sig_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003457 execute( TC_paging_ps_sig_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01003458 execute( TC_paging_ps_sig_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003459 execute( TC_paging_ps_sig_bvci() );
Harald Welteb5a04aa2021-01-16 13:04:40 +01003460 execute( TC_paging_ps_sig_bvci_imsi() );
Harald Welte7462a592020-11-23 22:07:07 +01003461 execute( TC_paging_ps_sig_bvci_unknown() );
Harald Weltecf200072021-01-16 15:20:46 +01003462 execute( TC_paging_ps_reject_sig_bvci() );
3463 execute( TC_paging_ps_reject_sig_bvci_imsi() );
Harald Welte7595d562021-01-16 19:09:20 +01003464 execute( TC_dummy_paging_ps_sig() );
Harald Welte0e188242020-11-22 21:46:48 +01003465
3466 /* PAGING-CS over PTP BVC */
3467 execute( TC_paging_cs_ptp_bss() );
3468 execute( TC_paging_cs_ptp_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01003469 execute( TC_paging_cs_ptp_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003470 execute( TC_paging_cs_ptp_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01003471 execute( TC_paging_cs_ptp_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003472 execute( TC_paging_cs_ptp_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01003473 execute( TC_paging_cs_ptp_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003474
3475 /* PAGING-CS over SIG BVC */
3476 execute( TC_paging_cs_sig_bss() );
3477 execute( TC_paging_cs_sig_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01003478 execute( TC_paging_cs_sig_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003479 execute( TC_paging_cs_sig_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01003480 execute( TC_paging_cs_sig_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003481 execute( TC_paging_cs_sig_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01003482 execute( TC_paging_cs_sig_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003483
Harald Weltef86f1852021-01-16 21:56:17 +01003484 /* RAN Information Management */
3485 execute( TC_rim_info_req() );
3486 execute( TC_rim_info() );
3487 execute( TC_rim_info_ack() );
3488 execute( TC_rim_info_error() );
3489 execute( TC_rim_info_app_error() );
3490 execute( TC_rim_info_pcu2pcu() );
3491
Harald Welte0e188242020-11-22 21:46:48 +01003492
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01003493 execute( TC_flush_ll() );
Harald Welte299aa482020-12-09 15:10:55 +01003494 execute( TC_fc_bvc() );
Harald Weltecc3894b2020-12-09 16:50:12 +01003495 execute( TC_fc_ms() );
Harald Welted6f89812021-01-16 18:57:49 +01003496 execute( TC_ms_reg_enq() );
Harald Welte04358652021-01-17 13:48:13 +01003497
3498 /* Uplink STATUS */
3499 execute( TC_status_sig_ul_tlli() );
3500 execute( TC_status_sig_ul_tmsi() );
3501 execute( TC_status_ptp_ul_tlli() );
3502 execute( TC_status_ptp_ul_tmsi() );
3503
3504 /* Downlink STATUS */
3505 execute( TC_status_sig_dl_bvci() );
3506 execute( TC_status_ptp_dl_bvci() );
Daniel Willmann423d8f42020-09-08 18:58:22 +02003507}
3508
3509
3510}