blob: 7a6572a374277c172ec01c122954a46093ab7edd [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
Harald Welte6d63f742020-11-15 19:44:04 +010041/* mcc_mnc is 24.008 10.5.5.15 encoded. 262 42 */
42const BcdMccMnc c_mcc_mnc := '262F42'H;
43
Harald Welte0d5fceb2020-11-29 16:04:07 +010044/* 48.016 section 6.1.4.2: The default maximum information field size of 1600 octets shall be supported on the Gb interface */
45const integer max_fr_info_size := 1600;
46
Daniel Willmann423d8f42020-09-08 18:58:22 +020047modulepar {
Harald Welteb5688f22021-03-30 16:28:04 +020048 charstring mp_gbproxy_ip := "127.0.0.1";
49 integer mp_gbproxy_ctrl_port := 4263;
Harald Welte77218d02021-01-15 19:59:15 +010050 /* NRI bit-length. 0 for no pooling */
51 integer mp_nri_bitlength := 5;
52 roro_integer mp_sgsn_nri := {
53 { 3 }, /* list of NRIs of first SGSN */
54 { 4 } /* list of NRIs of second SGSN */
55 };
Harald Weltef6e59b02020-12-08 08:29:09 +010056 boolean mp_enable_bss_load_sharing := false;
Daniel Willmann2c9300f2020-12-01 10:54:08 +010057 /* SGSN NS configuration */
Harald Welte6d63f742020-11-15 19:44:04 +010058 NSConfigurations mp_nsconfig_sgsn := {
Daniel Willmann423d8f42020-09-08 18:58:22 +020059 {
Daniel Willmann423d8f42020-09-08 18:58:22 +020060 nsei := 101,
61 role_sgsn := true,
Harald Welte90f19742020-11-06 19:34:40 +010062 handle_sns := false,
63 nsvc := {
64 {
65 provider := {
66 ip := {
67 address_family := AF_INET,
68 local_udp_port := 7777,
Harald Welted05a4a92021-01-18 12:03:53 +010069 local_ip := "127.0.0.10",
Harald Welte90f19742020-11-06 19:34:40 +010070 remote_udp_port := 23000,
Harald Weltebe7afce2021-01-17 22:04:36 +010071 remote_ip := "127.0.0.1",
Harald Welte388057d2021-01-18 18:52:49 +010072 data_weight := 0,
Harald Weltebe7afce2021-01-17 22:04:36 +010073 signalling_weight := 1
Harald Welte90f19742020-11-06 19:34:40 +010074 }
75 },
76 nsvci := 101
Harald Welte388057d2021-01-18 18:52:49 +010077 }, {
78 provider := {
79 ip := {
80 address_family := AF_INET,
81 local_udp_port := 7770,
82 local_ip := "127.0.0.10",
83 remote_udp_port := 23000,
84 remote_ip := "127.0.0.1",
85 data_weight := 1,
86 signalling_weight := 0
87 }
88 },
89 nsvci := 201
Harald Welte90f19742020-11-06 19:34:40 +010090 }
Harald Weltebe7afce2021-01-17 22:04:36 +010091
Harald Welte90f19742020-11-06 19:34:40 +010092 }
Harald Welteb978ed62020-12-12 14:01:11 +010093 }, {
94 nsei := 102,
95 role_sgsn := true,
96 handle_sns := false,
97 nsvc := {
98 {
99 provider := {
100 ip := {
101 address_family := AF_INET,
102 local_udp_port := 8888,
Harald Welted05a4a92021-01-18 12:03:53 +0100103 local_ip := "127.0.0.11",
Harald Welteb978ed62020-12-12 14:01:11 +0100104 remote_udp_port := 23000,
Harald Weltebe7afce2021-01-17 22:04:36 +0100105 remote_ip := "127.0.0.1",
Harald Welte388057d2021-01-18 18:52:49 +0100106 data_weight := 0,
Harald Weltebe7afce2021-01-17 22:04:36 +0100107 signalling_weight := 1
Harald Welteb978ed62020-12-12 14:01:11 +0100108 }
109 },
110 nsvci := 102
Harald Welte388057d2021-01-18 18:52:49 +0100111 }, {
112 provider := {
113 ip := {
114 address_family := AF_INET,
115 local_udp_port := 8880,
116 local_ip := "127.0.0.11",
117 remote_udp_port := 23000,
118 remote_ip := "127.0.0.1",
119 data_weight := 1,
120 signalling_weight := 0
121 }
122 },
123 nsvci := 202
Harald Welteb978ed62020-12-12 14:01:11 +0100124 }
125 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200126 }
127 };
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100128 /* BSS NSEI start at 2000 + x
129 * NSVCI start from value of NSEI + 100
130 * UDP port is NSVCI * 10 */
Harald Welte6d63f742020-11-15 19:44:04 +0100131 NSConfigurations mp_nsconfig_pcu := {
Daniel Willmann423d8f42020-09-08 18:58:22 +0200132 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100133 nsei := 2001,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200134 role_sgsn := false,
Harald Welte7079ce82021-04-01 17:38:51 +0200135 handle_sns := true,
Harald Welte90f19742020-11-06 19:34:40 +0100136 nsvc := {
137 {
138 provider := {
139 ip := {
140 address_family := AF_INET,
141 local_udp_port := 21010,
Harald Welted05a4a92021-01-18 12:03:53 +0100142 local_ip := "127.0.1.1",
Harald Welte90f19742020-11-06 19:34:40 +0100143 remote_udp_port := 23000,
Harald Welte7079ce82021-04-01 17:38:51 +0200144 remote_ip := "127.0.0.2",
Harald Weltebe7afce2021-01-17 22:04:36 +0100145 data_weight := 1,
146 signalling_weight := 1
Harald Welte90f19742020-11-06 19:34:40 +0100147 }
148 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100149 nsvci := 2101
Harald Welte90f19742020-11-06 19:34:40 +0100150 }
151 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200152 },
153 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100154 nsei := 2002,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200155 role_sgsn := false,
Harald Welte7079ce82021-04-01 17:38:51 +0200156 handle_sns := true,
Harald Welte90f19742020-11-06 19:34:40 +0100157 nsvc := {
158 {
159 provider := {
160 ip := {
161 address_family := AF_INET,
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100162 local_udp_port := 21020,
Harald Welted05a4a92021-01-18 12:03:53 +0100163 local_ip := "127.0.2.1",
Harald Welte90f19742020-11-06 19:34:40 +0100164 remote_udp_port := 23000,
Harald Welte7079ce82021-04-01 17:38:51 +0200165 remote_ip := "127.0.0.2",
Harald Weltebe7afce2021-01-17 22:04:36 +0100166 data_weight := 1,
167 signalling_weight := 1
Harald Welte90f19742020-11-06 19:34:40 +0100168 }
169 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100170 nsvci := 2102
Harald Welte90f19742020-11-06 19:34:40 +0100171 }
172 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200173 },
174 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100175 nsei := 2003,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200176 role_sgsn := false,
Harald Welte7079ce82021-04-01 17:38:51 +0200177 handle_sns := true,
Harald Welte90f19742020-11-06 19:34:40 +0100178 nsvc := {
179 {
180 provider := {
181 ip := {
182 address_family := AF_INET,
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100183 local_udp_port := 21030,
Harald Welted05a4a92021-01-18 12:03:53 +0100184 local_ip := "127.0.3.1",
Harald Welte90f19742020-11-06 19:34:40 +0100185 remote_udp_port := 23000,
Harald Welte7079ce82021-04-01 17:38:51 +0200186 remote_ip := "127.0.0.2",
Harald Weltebe7afce2021-01-17 22:04:36 +0100187 data_weight := 1,
188 signalling_weight := 1
Harald Welte90f19742020-11-06 19:34:40 +0100189 }
190 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100191 nsvci := 2103
Harald Welte90f19742020-11-06 19:34:40 +0100192 }
193 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200194 }
195 };
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100196 /* BVCI are NSEI*10 + x
197 * The first NSE only has one BVC, the second one 2 and so on
198 * The Cell ID is BVCI + 10000
199 * LAC/RAC are configured in such a way that:
200 * LAC 13135 is present once in NSE(2001), twice in NSE(2002) and once in NSE(2003)
201 * LAC 13300 is present twice in NSE(2003)
202 * RAI 13135-1 is present in NSE(2002) and NSE(2003)
203 * RAI 13300-0 is present twice in NSE(2003)
204 */
Harald Welte6d63f742020-11-15 19:44:04 +0100205 BssgpConfigs mp_gbconfigs := {
206 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100207 nsei := 2001,
Harald Welte6d63f742020-11-15 19:44:04 +0100208 sgsn_role := false,
209 bvc := {
210 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100211 bvci := 20011,
Harald Welte6d63f742020-11-15 19:44:04 +0100212 cell_id := {
213 ra_id := {
214 lai := {
215 mcc_mnc := c_mcc_mnc,
216 lac := 13135
217 },
218 rac := 0
219 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100220 cell_id := 30011
Harald Welte6d63f742020-11-15 19:44:04 +0100221 },
222 depth := BSSGP_DECODE_DEPTH_BSSGP,
223 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
224 }
225 }
226 }, {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100227 nsei := 2002,
Harald Welte6d63f742020-11-15 19:44:04 +0100228 sgsn_role := false,
229 bvc := {
230 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100231 bvci := 20021,
Harald Welte6d63f742020-11-15 19:44:04 +0100232 cell_id := {
233 ra_id := {
234 lai := {
235 mcc_mnc := c_mcc_mnc,
Harald Welte0e188242020-11-22 21:46:48 +0100236 lac := 13135
Harald Welte6d63f742020-11-15 19:44:04 +0100237 },
Harald Welte0e188242020-11-22 21:46:48 +0100238 rac := 1
Harald Welte6d63f742020-11-15 19:44:04 +0100239 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100240 cell_id := 30021
241 },
242 depth := BSSGP_DECODE_DEPTH_BSSGP,
243 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
244 },
245 {
246 bvci := 20022,
247 cell_id := {
248 ra_id := {
249 lai := {
250 mcc_mnc := c_mcc_mnc,
251 lac := 13135
252 },
253 rac := 2
254 },
255 cell_id := 30022
Harald Welte6d63f742020-11-15 19:44:04 +0100256 },
257 depth := BSSGP_DECODE_DEPTH_BSSGP,
258 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
259 }
260 }
261 }, {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100262 nsei := 2003,
Harald Welte6d63f742020-11-15 19:44:04 +0100263 sgsn_role := false,
264 bvc := {
265 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100266 bvci := 20031,
267 cell_id := {
268 ra_id := {
269 lai := {
270 mcc_mnc := c_mcc_mnc,
271 lac := 13135
272 },
273 rac := 1
274 },
275 cell_id := 30031
276 },
277 depth := BSSGP_DECODE_DEPTH_BSSGP,
278 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
279 },
280 {
281 bvci := 20032,
Harald Welte6d63f742020-11-15 19:44:04 +0100282 cell_id := {
283 ra_id := {
284 lai := {
285 mcc_mnc := c_mcc_mnc,
286 lac := 13300
287 },
288 rac := 0
289 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100290 cell_id := 30032
291 },
292 depth := BSSGP_DECODE_DEPTH_BSSGP,
293 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
294 },
295 {
296 bvci := 20033,
297 cell_id := {
298 ra_id := {
299 lai := {
300 mcc_mnc := c_mcc_mnc,
301 lac := 13300
302 },
303 rac := 0
304 },
305 cell_id := 30033
Harald Welte6d63f742020-11-15 19:44:04 +0100306 },
307 depth := BSSGP_DECODE_DEPTH_BSSGP,
308 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
309 }
310 }
311 }
312 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200313};
314
Daniel Willmann423d8f42020-09-08 18:58:22 +0200315type record GbInstance {
316 NS_CT vc_NS,
317 BSSGP_CT vc_BSSGP,
Harald Welte67dc8c22020-11-17 18:32:29 +0100318 BSSGP_BVC_CTs vc_BSSGP_BVC,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200319 BssgpConfig cfg
320};
Harald Welte67dc8c22020-11-17 18:32:29 +0100321type record of BSSGP_BVC_CT BSSGP_BVC_CTs
Daniel Willmann423d8f42020-09-08 18:58:22 +0200322
323const integer NUM_PCU := 3;
Harald Welte6d63f742020-11-15 19:44:04 +0100324type record of GbInstance GbInstances;
325type record of BssgpConfig BssgpConfigs;
326type record of NSConfiguration NSConfigurations;
327type record of BssgpCellId BssgpCellIds;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200328
Harald Welte572b0172021-03-30 13:19:56 +0200329/* you cannot simply change this to any larger number of SGSNs and expect all test
330 * cases to work. This would have overly complicated the code. Check below for
331 * tests that use interleave on SGSN_MGMT.receive() for each SGSN NSEI for example */
Harald Welteb978ed62020-12-12 14:01:11 +0100332const integer NUM_SGSN := 2;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200333
Harald Welteb5688f22021-03-30 16:28:04 +0200334type component test_CT extends CTRL_Adapter_CT {
Harald Welte6d63f742020-11-15 19:44:04 +0100335 var GbInstances g_pcu;
336 var GbInstances g_sgsn;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200337
Daniel Willmann8d9fcf42021-05-28 15:05:41 +0200338 port NS_CTRL_PT NS_CTRL;
339
Daniel Willmann423d8f42020-09-08 18:58:22 +0200340 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) & "])";
Harald Welte71389132021-12-09 21:58:18 +0100448 gb.vc_NS := NS_CT.create(ns_id) alive;
449 gb.vc_BSSGP := BSSGP_CT.create(bssgp_id) alive;
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) & "])";
Harald Welte71389132021-12-09 21:58:18 +0100471 gb.vc_NS := NS_CT.create(ns_id) alive;
472 gb.vc_BSSGP := BSSGP_CT.create(bssgp_id) alive;
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
Daniel Willmannd70d45a2021-07-23 10:23:51 +0200632 /* Wait to ensure the gbproxy processed the RESET_ACK messages from the SGSN.
633 * Otherwise the state might still be WAIT_RESET_ACK */
634 f_sleep(0.2);
635
Harald Welteb5688f22021-03-30 16:28:04 +0200636 /* verify all SGSN-side BVC FSM in IUT are UNBLOCKED */
637 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
638 f_bvc_fsm_ensure_state(mp_nsconfig_sgsn[i].nsei, 0, "UNBLOCKED");
639 /* iterate over list and check all BVCI */
640 for (var integer j := 0; j < lengthof(g_sgsn[i].cfg.bvc); j := j+1) {
641 var BssgpBvci bvci := g_sgsn[i].cfg.bvc[j].bvci;
642 f_bvc_fsm_ensure_state(mp_nsconfig_sgsn[i].nsei, bvci, "UNBLOCKED");
643 }
644 }
645 /* verify all PCU-side BVC FSM in IUT are UNBLOCKED */
646 for (i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
647 f_bvc_fsm_ensure_state(mp_nsconfig_pcu[i].nsei, 0, "UNBLOCKED");
648 /* iterate over list and check all BVCI */
649 for (var integer j := 0; j < lengthof(g_pcu[i].cfg.bvc); j := j+1) {
650 var BssgpBvci bvci := g_pcu[i].cfg.bvc[j].bvci;
651 f_bvc_fsm_ensure_state(mp_nsconfig_pcu[i].nsei, bvci, "UNBLOCKED");
652 }
653 }
654
Harald Welte425d3762020-12-09 14:33:18 +0100655 /* re-start guard timer after all BVCs are up, so it only counts the actual test case */
656 g_Tguard.start(t_guard);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200657}
658
659function f_cleanup() runs on test_CT {
Harald Welteb9f0fdc2020-12-09 14:44:50 +0100660 var integer i;
661
Daniel Willmann491af2a2021-01-08 01:32:51 +0100662 /* To avoid a dynamic test case error we need to prevent messages arriving on unconnected
663 * ports. Waiting here ensures that any messages "in flight" will be delivered to the port
664 * before the component is shutdown and disconnected. */
665 f_sleep(0.2);
666
Harald Welteb9f0fdc2020-12-09 14:44:50 +0100667 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
668 f_destroy_gb(g_sgsn[i]);
669 }
670 for (i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
671 f_destroy_gb(g_pcu[i]);
672 }
673
674 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, pass);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200675}
676
677type function void_fn(charstring id) runs on BSSGP_ConnHdlr;
678
679/* helper function to create, connect and start a BSSGP_ConnHdlr component */
Harald Welte207166c2021-01-16 12:52:30 +0100680function f_start_handler(void_fn fn, charstring id, integer imsi_suffix, float t_guard := 30.0,
681 integer sgsn_idx := 0, integer nri_idx := 0, boolean have_ptmsi := true)
Daniel Willmann423d8f42020-09-08 18:58:22 +0200682runs on test_CT return BSSGP_ConnHdlr {
683 var BSSGP_ConnHdlr vc_conn;
Harald Weltec5f486b2021-01-16 11:07:01 +0100684 var integer nri := mp_sgsn_nri[sgsn_idx][nri_idx];
Harald Welte77218d02021-01-15 19:59:15 +0100685 var OCT4 p_tmsi := f_gen_tmsi(imsi_suffix, nri_v := nri, nri_bitlen := mp_nri_bitlength);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200686
687 var BSSGP_ConnHdlrPars pars := {
688 imei := f_gen_imei(imsi_suffix),
689 imsi := f_gen_imsi(imsi_suffix),
690 msisdn := f_gen_msisdn(imsi_suffix),
Harald Weltedbd5e672021-01-14 21:03:14 +0100691 p_tmsi := p_tmsi,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200692 p_tmsi_sig := omit,
Harald Weltedbd5e672021-01-14 21:03:14 +0100693 tlli := f_gprs_tlli_from_tmsi(p_tmsi, TLLI_LOCAL),
Daniel Willmann423d8f42020-09-08 18:58:22 +0200694 tlli_old := omit,
695 ra := omit,
Harald Welte2ecbca82021-01-16 11:23:09 +0100696 pcu := g_pcu,
697 sgsn := g_sgsn,
Harald Weltec5f486b2021-01-16 11:07:01 +0100698 sgsn_idx := sgsn_idx,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200699 t_guard := t_guard
700 };
Harald Welte207166c2021-01-16 12:52:30 +0100701 if (not have_ptmsi) {
702 pars.p_tmsi := omit;
703 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200704
Daniel Willmann09ed9942023-12-05 15:04:50 +0100705 vc_conn := BSSGP_ConnHdlr.create(id) alive;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200706
Harald Welte25a04b12021-01-17 11:09:49 +0100707 log("Starting ", id, " for SGSN[", sgsn_idx, "], NRI=", nri, ", P-TMSI=", pars.p_tmsi,
708 ", TLLI=", pars.tlli, ", IMSI=", pars.imsi, " on component=", vc_conn);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200709 vc_conn.start(f_handler_init(fn, id, pars));
710 return vc_conn;
711}
712
Harald Welte207166c2021-01-16 12:52:30 +0100713function f_start_handlers(void_fn fn, charstring id, integer imsi_suffix, float t_guard := 30.0,
714 boolean have_ptmsi := true)
Harald Weltec5f486b2021-01-16 11:07:01 +0100715runs on test_CT
716{
717 var integer sgsn_idx, nri_idx;
718 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx:=sgsn_idx+1) {
719 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx:=nri_idx+1) {
720 var integer extd_imsi_suffix := 1000*sgsn_idx + 100*nri_idx;
721 var BSSGP_ConnHdlr vc_conn;
Harald Welte207166c2021-01-16 12:52:30 +0100722 vc_conn := f_start_handler(fn, id, extd_imsi_suffix, t_guard, sgsn_idx, nri_idx,
723 have_ptmsi);
Harald Weltec5f486b2021-01-16 11:07:01 +0100724 /* Idea: we could also run them in parallel ? */
725 vc_conn.done;
726 }
727 }
728}
729
Harald Welte3dd21b32020-11-17 19:21:00 +0100730/* 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 +0100731private function f_connect_to_pcu_bvc(integer port_idx, integer nse_idx, integer bvc_idx)
732runs on BSSGP_ConnHdlr {
733 var BSSGP_BVC_CT bvc_ct := g_pars.pcu[nse_idx].vc_BSSGP_BVC[bvc_idx]
Harald Welte158becf2020-12-09 12:32:32 +0100734 if (PCU_PTP[port_idx].checkstate("Connected")) {
Harald Welte3dd21b32020-11-17 19:21:00 +0100735 /* unregister + disconnect from old BVC */
736 f_client_unregister(g_pars.imsi, PCU_PROC[port_idx]);
Harald Welte158becf2020-12-09 12:32:32 +0100737 disconnect(self:PCU_PTP[port_idx], pcu_ct[port_idx]:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100738 disconnect(self:PCU_SIG[port_idx], pcu_ct[port_idx]:BSSGP_SP_SIG);
739 disconnect(self:PCU_PROC[port_idx], pcu_ct[port_idx]:BSSGP_PROC);
740 }
741 /* connect to new BVC and register us */
Harald Welte158becf2020-12-09 12:32:32 +0100742 connect(self:PCU_PTP[port_idx], bvc_ct:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100743 connect(self:PCU_SIG[port_idx], bvc_ct:BSSGP_SP_SIG);
744 connect(self:PCU_PROC[port_idx], bvc_ct:BSSGP_PROC);
745 f_client_register(g_pars.imsi, g_pars.tlli, PCU_PROC[port_idx]);
746 pcu_ct[port_idx] := bvc_ct;
Harald Welte0e188242020-11-22 21:46:48 +0100747 pcu_bvc_cfg[port_idx] := g_pars.pcu[nse_idx].cfg.bvc[bvc_idx];
Harald Welte3dd21b32020-11-17 19:21:00 +0100748}
749
750/* Connect the SGSN-side per-BVC ports (SGSN/SGSN_SIG/SGSN_PROC) array slot 'port_idx' to specified per-BVC component */
751private 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 +0100752 if (SGSN_PTP[port_idx].checkstate("Connected")) {
Harald Welte3dd21b32020-11-17 19:21:00 +0100753 /* unregister + disconnect from old BVC */
754 f_client_unregister(g_pars.imsi, SGSN_PROC[port_idx]);
Harald Welte158becf2020-12-09 12:32:32 +0100755 disconnect(self:SGSN_PTP[port_idx], sgsn_ct[port_idx]:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100756 disconnect(self:SGSN_SIG[port_idx], sgsn_ct[port_idx]:BSSGP_SP_SIG);
757 disconnect(self:SGSN_PROC[port_idx], sgsn_ct[port_idx]:BSSGP_PROC);
758 }
759 /* connect to new BVC and register us */
Harald Welte158becf2020-12-09 12:32:32 +0100760 connect(self:SGSN_PTP[port_idx], bvc_ct:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100761 connect(self:SGSN_SIG[port_idx], bvc_ct:BSSGP_SP_SIG);
762 connect(self:SGSN_PROC[port_idx], bvc_ct:BSSGP_PROC);
763 f_client_register(g_pars.imsi, g_pars.tlli, SGSN_PROC[port_idx]);
764 sgsn_ct[port_idx] := bvc_ct;
765}
766
Harald Welte425d3762020-12-09 14:33:18 +0100767private altstep as_gTguard(timer Tguard) {
768 [] Tguard.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +0100769 f_shutdown(__FILE__, __LINE__, fail, "Tguard timeout");
Daniel Willmann423d8f42020-09-08 18:58:22 +0200770 }
771}
772
773/* first function called in every ConnHdlr */
774private function f_handler_init(void_fn fn, charstring id, BSSGP_ConnHdlrPars pars)
775runs on BSSGP_ConnHdlr {
Harald Welte1e834f32020-11-15 20:02:59 +0100776 var integer i;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200777 /* do some common stuff like setting up g_pars */
778 g_pars := pars;
779
780 llc := f_llc_create(false);
781
Harald Welte3dd21b32020-11-17 19:21:00 +0100782 /* default connections on PCU side: First BVC of each NSE/PCU */
783 for (i := 0; i < lengthof(g_pars.pcu); i := i+1) {
Harald Welte0e188242020-11-22 21:46:48 +0100784 f_connect_to_pcu_bvc(port_idx := i, nse_idx := i, bvc_idx := 0);
Harald Welte1e834f32020-11-15 20:02:59 +0100785 }
Harald Welte3dd21b32020-11-17 19:21:00 +0100786
787 /* default connections on SGSN side: First BVC of each NSE/SGSN */
788 for (i := 0; i < lengthof(g_pars.sgsn); i := i+1) {
789 f_connect_to_sgsn_bvc(i, g_pars.sgsn[i].vc_BSSGP_BVC[0]);
Harald Welte1e834f32020-11-15 20:02:59 +0100790 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200791
792 g_Tguard.start(pars.t_guard);
Harald Welte425d3762020-12-09 14:33:18 +0100793 activate(as_gTguard(g_Tguard));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200794
795 /* call the user-supplied test case function */
796 fn.apply(id);
Harald Welteb33fb592021-01-16 12:50:56 +0100797
798 for (i := 0; i < NUM_SGSN; i := i+1) {
799 if (SGSN_PROC[i].checkstate("Connected")) {
800 f_client_unregister(g_pars.imsi, SGSN_PROC[i])
801 }
802 }
803
804 for (i := 0; i < NUM_PCU; i := i+1) {
805 if (PCU_PROC[i].checkstate("Connected")) {
806 f_client_unregister(g_pars.imsi, PCU_PROC[i])
807 }
808 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200809}
810
Harald Welte1e834f32020-11-15 20:02:59 +0100811private function f_client_register(hexstring imsi, OCT4 tlli, BSSGP_PROC_PT PT)
812runs on BSSGP_ConnHdlr {
813 PT.call(BSSGP_register_client:{imsi, tlli}) {
814 [] PT.getreply(BSSGP_register_client:{imsi, tlli}) {};
815 }
816}
817
818private function f_client_unregister(hexstring imsi, BSSGP_PROC_PT PT)
819runs on BSSGP_ConnHdlr {
820 PT.call(BSSGP_unregister_client:{imsi}) {
821 [] PT.getreply(BSSGP_unregister_client:{imsi}) {};
822 }
823}
824
Harald Welte22ef5d92020-11-16 13:35:14 +0100825/* Send 'tx' on PTP-BVCI from PCU; expect 'rx' on SGSN */
826friend function f_pcu2sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
Harald Weltec5f486b2021-01-16 11:07:01 +0100827 integer pcu_idx := 0, boolean use_sig := false) runs on BSSGP_ConnHdlr {
828 var integer sgsn_idx := g_pars.sgsn_idx;
Harald Welte22ef5d92020-11-16 13:35:14 +0100829 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +0100830 timer T := 2.0;
Harald Welte22ef5d92020-11-16 13:35:14 +0100831
Daniel Willmann4798fd72020-11-24 16:23:29 +0100832 if (use_sig) {
833 PCU_SIG[pcu_idx].send(tx);
834 } else {
Harald Welte158becf2020-12-09 12:32:32 +0100835 PCU_PTP[pcu_idx].send(tx);
Daniel Willmann4798fd72020-11-24 16:23:29 +0100836 }
837
Harald Welte22ef5d92020-11-16 13:35:14 +0100838 T.start;
839 alt {
Daniel Willmann4798fd72020-11-24 16:23:29 +0100840 [use_sig] SGSN_SIG[sgsn_idx].receive(exp_rx) {
841 setverdict(pass);
842 }
Harald Welte158becf2020-12-09 12:32:32 +0100843 [not use_sig] SGSN_PTP[sgsn_idx].receive(exp_rx) {
Harald Welte22ef5d92020-11-16 13:35:14 +0100844 setverdict(pass);
845 }
Harald Welte158becf2020-12-09 12:32:32 +0100846 [] SGSN_PTP[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +0100847 f_shutdown(__FILE__, __LINE__, fail,
848 log2str("Unexpected BSSGP on SGSN[", sgsn_idx, "] side: ", rx));
Harald Welte22ef5d92020-11-16 13:35:14 +0100849 }
Daniel Willmann4798fd72020-11-24 16:23:29 +0100850 [] SGSN_SIG[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +0100851 f_shutdown(__FILE__, __LINE__, fail,
852 log2str("Unexpected SIG BSSGP on SGSN[", sgsn_idx, "] side: ", rx));
Daniel Willmann4798fd72020-11-24 16:23:29 +0100853 }
Harald Welte22ef5d92020-11-16 13:35:14 +0100854 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +0100855 f_shutdown(__FILE__, __LINE__, fail,
856 log2str("Timeout waiting for BSSGP on SGSN[", sgsn_idx, "] side: ", exp_rx));
Harald Welte22ef5d92020-11-16 13:35:14 +0100857 }
858 }
859}
860
Harald Welte3148a962021-01-17 11:15:28 +0100861/* Send 'tx' from PCU; expect 'exp_rx' on _any_ SGSN */
862friend function f_pcu2any_sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
863 integer pcu_idx := 0, boolean use_sig := false)
864runs on BSSGP_ConnHdlr return integer {
865 var integer rx_idx := -1;
866 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +0100867 timer T := 2.0;
Harald Welte3148a962021-01-17 11:15:28 +0100868
869 if (use_sig) {
870 PCU_SIG[pcu_idx].send(tx);
871 } else {
872 PCU_PTP[pcu_idx].send(tx);
873 }
874
875 T.start;
876 alt {
877 [use_sig] any from SGSN_SIG.receive(exp_rx) -> @index value rx_idx {
878 setverdict(pass);
879 }
880 [not use_sig] any from SGSN_PTP.receive(exp_rx) -> @index value rx_idx {
881 setverdict(pass);
882 }
883 [] any from SGSN_PTP.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 BSSGP on SGSN[", rx_idx, "] side: ", rx));
Harald Welte3148a962021-01-17 11:15:28 +0100886 }
887 [] any from SGSN_SIG.receive(PDU_BSSGP:?) -> value rx @index value rx_idx {
Harald Welted5b7e742021-01-27 10:50:24 +0100888 f_shutdown(__FILE__, __LINE__, fail,
889 log2str("Unexpected SIG BSSGP on SGSN[", rx_idx, "] side: ", rx));
Harald Welte3148a962021-01-17 11:15:28 +0100890 }
891 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +0100892 f_shutdown(__FILE__, __LINE__, fail,
893 log2str("Timeout waiting for BSSGP on SGSN side: ", exp_rx));
Harald Welte3148a962021-01-17 11:15:28 +0100894 }
895 }
896 return rx_idx;
897}
898
Harald Welte22ef5d92020-11-16 13:35:14 +0100899/* Send 'tx' on PTP-BVCI from SGSN; expect 'rx' on PCU */
900friend function f_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
Harald Weltec5f486b2021-01-16 11:07:01 +0100901 integer pcu_idx := 0, boolean use_sig := false) runs on BSSGP_ConnHdlr {
902 var integer sgsn_idx := g_pars.sgsn_idx;
Harald Welte22ef5d92020-11-16 13:35:14 +0100903 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +0100904 timer T := 2.0;
Harald Welte22ef5d92020-11-16 13:35:14 +0100905
Daniel Willmann4798fd72020-11-24 16:23:29 +0100906 if (use_sig) {
907 SGSN_SIG[sgsn_idx].send(tx);
908 } else {
Harald Welte158becf2020-12-09 12:32:32 +0100909 SGSN_PTP[sgsn_idx].send(tx);
Daniel Willmann4798fd72020-11-24 16:23:29 +0100910 }
911
Harald Welte22ef5d92020-11-16 13:35:14 +0100912 T.start;
913 alt {
Daniel Willmann4798fd72020-11-24 16:23:29 +0100914 [use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
915 setverdict(pass);
916 }
Harald Welte158becf2020-12-09 12:32:32 +0100917 [not use_sig] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte22ef5d92020-11-16 13:35:14 +0100918 setverdict(pass);
919 }
Harald Welte158becf2020-12-09 12:32:32 +0100920 [] PCU_PTP[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +0100921 f_shutdown(__FILE__, __LINE__, fail, log2str("Unexpected BSSGP on PCU side: ", rx));
Harald Welte22ef5d92020-11-16 13:35:14 +0100922 }
Daniel Willmann4798fd72020-11-24 16:23:29 +0100923 [] PCU_SIG[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +0100924 f_shutdown(__FILE__, __LINE__, fail, log2str("Unexpected SIG BSSGP on PCU side: ", rx));
Daniel Willmann4798fd72020-11-24 16:23:29 +0100925 }
Harald Welte22ef5d92020-11-16 13:35:14 +0100926 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +0100927 f_shutdown(__FILE__, __LINE__, fail,
928 log2str("Timeout waiting for BSSGP on PCU side: ", exp_rx));
Harald Welte22ef5d92020-11-16 13:35:14 +0100929 }
930 }
931}
Harald Welte1e834f32020-11-15 20:02:59 +0100932
Harald Welte3807ed12020-11-24 19:05:22 +0100933/***********************************************************************
934 * GlobaLTest_CT: Using the per-NSE GLOBAL ports on PCU + SGSN side
935 ***********************************************************************/
936
937type component GlobalTest_CT extends test_CT {
938 port BSSGP_PT G_PCU[NUM_PCU];
Harald Welte04358652021-01-17 13:48:13 +0100939 var integer g_pcu_idx[NUM_PCU]; /* BVC index currently connected to G_PCU */
Harald Welte3807ed12020-11-24 19:05:22 +0100940 port BSSGP_PT G_SGSN[NUM_SGSN];
Harald Welte04358652021-01-17 13:48:13 +0100941 var integer g_sgsn_idx[NUM_SGSN]; /* BVC index currently connected to G_SGSN */
Harald Weltef86f1852021-01-16 21:56:17 +0100942 port BSSGP_PT RIM_PCU[NUM_PCU];
943 port BSSGP_PT RIM_SGSN[NUM_SGSN];
Harald Welte3807ed12020-11-24 19:05:22 +0100944};
945
Harald Welte299aa482020-12-09 15:10:55 +0100946/* connect the signaling BVC of each NSE to the G_PCU / G_SGSN ports */
Harald Welte3807ed12020-11-24 19:05:22 +0100947private function f_global_init() runs on GlobalTest_CT {
948 var integer i;
949 for (i := 0; i < lengthof(g_sgsn); i := i+1) {
950 connect(self:G_SGSN[i], g_sgsn[i].vc_BSSGP:GLOBAL);
Harald Weltef86f1852021-01-16 21:56:17 +0100951 connect(self:RIM_SGSN[i], g_sgsn[i].vc_BSSGP:RIM);
Harald Welte3807ed12020-11-24 19:05:22 +0100952 }
953 for (i := 0; i < lengthof(g_pcu); i := i+1) {
954 connect(self:G_PCU[i], g_pcu[i].vc_BSSGP:GLOBAL);
Harald Weltef86f1852021-01-16 21:56:17 +0100955 connect(self:RIM_PCU[i], g_pcu[i].vc_BSSGP:RIM);
Harald Welte3807ed12020-11-24 19:05:22 +0100956 }
957}
958
Harald Welte299aa482020-12-09 15:10:55 +0100959/* connect the first PTP BVC of each NSE to the G_PCU / G_SGSN ports */
960private function f_global_init_ptp() runs on GlobalTest_CT {
961 var integer i;
962 for (i := 0; i < lengthof(g_sgsn); i := i+1) {
Harald Welte04358652021-01-17 13:48:13 +0100963 log("Connecting G_SGSN[", i, "] to BVCI=", g_sgsn[i].cfg.bvc[0].bvci);
Harald Welte299aa482020-12-09 15:10:55 +0100964 connect(self:G_SGSN[i], g_sgsn[i].vc_BSSGP_BVC[0]:GLOBAL);
Harald Welte04358652021-01-17 13:48:13 +0100965 g_sgsn_idx[i] := 0;
Harald Welte299aa482020-12-09 15:10:55 +0100966 }
967 for (i := 0; i < lengthof(g_pcu); i := i+1) {
Harald Welte04358652021-01-17 13:48:13 +0100968 log("Connecting G_PCU[", i, "] to BVCI=", g_pcu[i].cfg.bvc[0].bvci);
Harald Welte299aa482020-12-09 15:10:55 +0100969 connect(self:G_PCU[i], g_pcu[i].vc_BSSGP_BVC[0]:GLOBAL);
Harald Welte04358652021-01-17 13:48:13 +0100970 g_pcu_idx[i] := 0;
Harald Welte299aa482020-12-09 15:10:55 +0100971 }
972}
973
Harald Welte04358652021-01-17 13:48:13 +0100974/* (re)connect G_SGSN[sgsn_idx] to a specific PTP BVCI */
975private function f_global_ptp_connect_sgsn_bvci(integer sgsn_idx, BssgpBvci bvci) runs on GlobalTest_CT
976{
977 var integer sgsn_bvc_idx := get_bvc_idx_for_bvci(g_sgsn[sgsn_idx], bvci);
978 var integer old_sgsn_bvc_idx := g_sgsn_idx[sgsn_idx];
979 disconnect(self:G_SGSN[sgsn_idx], g_sgsn[sgsn_idx].vc_BSSGP_BVC[old_sgsn_bvc_idx]:GLOBAL);
980 connect(self:G_SGSN[sgsn_idx], g_sgsn[sgsn_idx].vc_BSSGP_BVC[sgsn_bvc_idx]:GLOBAL);
981 g_sgsn_idx[sgsn_idx] := sgsn_bvc_idx;
982}
983
984/* (re)connect G_PCU[pcu_idx] to a specific PTP BVCI */
985private function f_global_ptp_connect_pcu_bvci(integer pcu_idx, BssgpBvci bvci) runs on GlobalTest_CT
986{
987 var integer pcu_bvc_idx := get_bvc_idx_for_bvci(g_pcu[pcu_idx], bvci);
988 var integer old_pcu_bvc_idx := g_pcu_idx[pcu_idx];
989 disconnect(self:G_PCU[pcu_idx], g_pcu[pcu_idx].vc_BSSGP_BVC[old_pcu_bvc_idx]:GLOBAL);
990 connect(self:G_PCU[pcu_idx], g_pcu[pcu_idx].vc_BSSGP_BVC[pcu_bvc_idx]:GLOBAL);
991 g_pcu_idx[pcu_idx] := pcu_bvc_idx;
992}
993
Harald Welte3807ed12020-11-24 19:05:22 +0100994/* Send 'tx' on PTP-BVCI from PCU; expect 'rx' on SGSN */
995friend function f_global_pcu2sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
996 integer pcu_idx := 0, integer sgsn_idx := 0) runs on GlobalTest_CT {
Harald Welte04358652021-01-17 13:48:13 +0100997 var integer rx_idx;
Harald Welte3807ed12020-11-24 19:05:22 +0100998 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +0100999 timer T := 2.0;
Harald Welte3807ed12020-11-24 19:05:22 +01001000
1001 G_PCU[pcu_idx].send(tx);
1002 T.start;
1003 alt {
1004 [] G_SGSN[sgsn_idx].receive(exp_rx) {
1005 setverdict(pass);
1006 }
Harald Welte04358652021-01-17 13:48:13 +01001007 [] any from G_SGSN.receive(exp_rx) -> @index value rx_idx {
1008 setverdict(fail, "BSSGP arrived on wrong SGSN[", rx_idx, "] instead of SGSN[", sgsn_idx, "]");
1009 }
Harald Welte3807ed12020-11-24 19:05:22 +01001010 [] G_SGSN[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +01001011 f_shutdown(__FILE__, __LINE__, fail, log2str("Unexpected BSSGP on SGSN side: ", rx));
Harald Welte3807ed12020-11-24 19:05:22 +01001012 }
1013 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +01001014 f_shutdown(__FILE__, __LINE__, fail, log2str("Timeout waiting for BSSGP on SGSN side: ", exp_rx));
Harald Welte3807ed12020-11-24 19:05:22 +01001015 }
1016 }
1017}
1018
1019/* Send 'tx' on PTP-BVCI from SGSN; expect 'rx' on PCU */
1020friend function f_global_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
1021 integer sgsn_idx := 0, integer pcu_idx := 0) runs on GlobalTest_CT {
Harald Welte04358652021-01-17 13:48:13 +01001022 var integer rx_idx;
Harald Welte3807ed12020-11-24 19:05:22 +01001023 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +01001024 timer T := 2.0;
Harald Welte3807ed12020-11-24 19:05:22 +01001025
1026 G_SGSN[sgsn_idx].send(tx);
1027 T.start;
1028 alt {
1029 [] G_PCU[pcu_idx].receive(exp_rx) {
1030 setverdict(pass);
1031 }
Harald Welte04358652021-01-17 13:48:13 +01001032 [] any from G_PCU.receive(exp_rx) -> @index value rx_idx {
1033 setverdict(fail, "BSSGP arrived on wrong PCU[", rx_idx, "] instead of PCU[", pcu_idx, "]");
1034 }
Harald Welte3807ed12020-11-24 19:05:22 +01001035 [] G_PCU[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +01001036 f_shutdown(__FILE__, __LINE__, fail, log2str("Unexpected BSSGP on PCU side: ", rx));
Harald Welte3807ed12020-11-24 19:05:22 +01001037 }
1038 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +01001039 f_shutdown(__FILE__, __LINE__, fail, log2str("Timeout waiting for BSSGP on PCU side: ", exp_rx));
Harald Welte3807ed12020-11-24 19:05:22 +01001040 }
1041 }
1042}
1043
1044
Daniel Willmann423d8f42020-09-08 18:58:22 +02001045/* TODO:
1046 * Detach without Attach
1047 * SM procedures without attach / RAU
1048 * ATTACH / RAU
1049 ** with / without authentication
1050 ** with / without P-TMSI allocation
1051 * re-transmissions of LLC frames
1052 * PDP Context activation
1053 ** with different GGSN config in SGSN VTY
1054 ** with different PDP context type (v4/v6/v46)
1055 ** timeout from GGSN
1056 ** multiple / secondary PDP context
1057 */
1058
1059private function f_TC_BVC_bringup(charstring id) runs on BSSGP_ConnHdlr {
1060 f_sleep(5.0);
1061 setverdict(pass);
1062}
1063
1064testcase TC_BVC_bringup() runs on test_CT {
Daniel Willmann423d8f42020-09-08 18:58:22 +02001065 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001066 f_start_handlers(refers(f_TC_BVC_bringup), testcasename(), 51);
Daniel Willmann423d8f42020-09-08 18:58:22 +02001067 f_cleanup();
1068}
1069
Daniel Willmann116d8b52021-12-06 16:27:54 +01001070testcase TC_BVC_bringup_conflicting() runs on test_CT {
1071 var float t_guard := 15.0;
1072 var BssgpStatusIndication bsi;
1073 var integer i;
1074
1075
1076 g_Tguard.start(t_guard);
1077 activate(as_gTguard(g_Tguard));
1078
1079 f_ipa_ctrl_start_client(mp_gbproxy_ip, mp_gbproxy_ctrl_port);
1080
1081 var BssgpBvcConfigs bvcs := { };
1082 for (i := 0; i < lengthof(mp_gbconfigs); i := i+1) {
1083 g_pcu[i].cfg := mp_gbconfigs[i];
1084 g_pcu[i].cfg.bvc[0].bvci := 23;
1085 /* make sure all have a proper create_cb, which cannot be specified in config file */
1086 f_fix_create_cb(g_pcu[i].cfg);
1087 /* concatenate all the PCU-side BVCs for the SGSN side */
1088 bvcs := bvcs & g_pcu[i].cfg.bvc;
1089 }
1090
1091 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
1092 g_sgsn[i].cfg := {
1093 nsei := mp_nsconfig_sgsn[i].nsei,
1094 sgsn_role := true,
1095 bvc := bvcs
1096 }
1097 }
1098
1099 f_init_vty();
1100 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
1101 f_vty_transceive(GBPVTY, "nsvc nsei " & int2str(g_sgsn[i].cfg.nsei) & " force-unconfigured");
1102 }
1103 for (i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1104 f_vty_transceive(GBPVTY, "nsvc nsei " & int2str(g_pcu[i].cfg.nsei) & " force-unconfigured");
1105 f_vty_transceive(GBPVTY, "delete-gbproxy-peer " & int2str(g_pcu[i].cfg.nsei) & " only-bvc");
1106 }
1107
1108 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
1109 f_init_gb_sgsn(g_sgsn[i], "GbProxy_Test", i);
1110 }
1111 f_sleep(4.0);
1112 for (i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1113 f_init_gb_pcu(g_pcu[i], "GbProxy_Test", i);
1114 }
1115
1116 /* wait until all BVC are unblocked on both sides */
Daniel Willmann172cd6d2023-05-02 11:37:42 +02001117 timer T := 5.0;
Daniel Willmann116d8b52021-12-06 16:27:54 +01001118 T.start;
1119 alt {
1120 [] SGSN_MGMT.receive(BssgpStatusIndication:{*, ?, ?}) {
1121 repeat;
1122 }
1123 [] SGSN_MGMT.receive(BssgpResetIndication:?) {
1124 repeat;
1125 }
1126 [] SGSN_MGMT.receive {
1127 f_shutdown(__FILE__, __LINE__, fail, "Received unexpected message on SGSN_MGMT");
1128 }
1129 [] PCU_MGMT.receive(BssgpStatusIndication:{*, ?, BVC_S_UNBLOCKED}) -> value bsi {
1130 repeat;
1131 }
1132 [] PCU_MGMT.receive(BssgpStatusIndication:{*, ?, ?}) {
1133 repeat;
1134 }
1135 [] PCU_MGMT.receive(BssgpResetIndication:{0}) {
1136 repeat;
1137 }
1138 [] PCU_MGMT.receive {
1139 f_shutdown(__FILE__, __LINE__, fail, "Received unexpected message on PCU_MGMT");
1140 }
1141 [] T.timeout {
1142 }
1143 }
1144
1145 /* Wait to ensure the gbproxy processed the RESET_ACK messages from the SGSN.
1146 * Otherwise the state might still be WAIT_RESET_ACK */
1147 f_sleep(0.2);
1148
1149 /* Verify BVCs, but ignore conflicting BVCI 23 */
1150 /* verify SGSN-side BVC FSM in IUT are UNBLOCKED */
1151 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
1152 f_bvc_fsm_ensure_state(mp_nsconfig_sgsn[i].nsei, 0, "UNBLOCKED");
1153 /* iterate over list and check all BVCI */
1154 for (var integer j := 0; j < lengthof(g_sgsn[i].cfg.bvc); j := j+1) {
1155 var BssgpBvci bvci := g_sgsn[i].cfg.bvc[j].bvci;
1156 if (bvci == 23) {
1157 continue;
1158 }
1159 f_bvc_fsm_ensure_state(mp_nsconfig_sgsn[i].nsei, bvci, "UNBLOCKED");
1160 }
1161 }
1162 /* verify PCU-side BVC FSM in IUT are UNBLOCKED */
1163 for (i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1164 f_bvc_fsm_ensure_state(mp_nsconfig_pcu[i].nsei, 0, "UNBLOCKED");
1165 /* iterate over list and check all BVCI */
1166 for (var integer j := 0; j < lengthof(g_pcu[i].cfg.bvc); j := j+1) {
1167 var BssgpBvci bvci := g_pcu[i].cfg.bvc[j].bvci;
1168 if (bvci == 23) {
1169 continue;
1170 }
1171 f_bvc_fsm_ensure_state(mp_nsconfig_pcu[i].nsei, bvci, "UNBLOCKED");
1172 }
1173 }
1174
1175 /* re-start guard timer after all BVCs are up, so it only counts the actual test case */
1176 g_Tguard.start(t_guard);
1177 f_start_handlers(refers(f_TC_BVC_bringup), testcasename(), 51);
1178 f_cleanup();
1179}
1180
Daniel Willmann423d8f42020-09-08 18:58:22 +02001181friend function f_bssgp_suspend(integer ran_idx := 0) runs on BSSGP_ConnHdlr return OCT1 {
Harald Welte16357a92020-11-17 18:20:00 +01001182 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Daniel Willmann423d8f42020-09-08 18:58:22 +02001183 timer T := 5.0;
1184 var PDU_BSSGP rx_pdu;
Harald Welte16357a92020-11-17 18:20:00 +01001185 PCU_SIG[ran_idx].send(ts_BSSGP_SUSPEND(g_pars.tlli, bvcc.cell_id.ra_id));
Daniel Willmann423d8f42020-09-08 18:58:22 +02001186 T.start;
1187 alt {
Harald Welte16357a92020-11-17 18:20:00 +01001188 [] 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 +02001189 return rx_pdu.pDU_BSSGP_SUSPEND_ACK.suspend_Reference_Number.suspend_Reference_Number_value;
1190 }
Harald Welte16357a92020-11-17 18:20:00 +01001191 [] 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 +01001192 f_shutdown(__FILE__, __LINE__, fail,
1193 log2str("SUSPEND-NACK in response to SUSPEND for TLLI ", g_pars.tlli));
Daniel Willmann423d8f42020-09-08 18:58:22 +02001194 }
1195 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +01001196 f_shutdown(__FILE__, __LINE__, fail,
1197 log2str("No SUSPEND-ACK in response to SUSPEND for TLLI ", g_pars.tlli));
Daniel Willmann423d8f42020-09-08 18:58:22 +02001198 }
1199 }
1200 return '00'O;
1201}
1202
1203friend function f_bssgp_resume(OCT1 susp_ref, integer ran_idx := 0) runs on BSSGP_ConnHdlr {
Harald Welte16357a92020-11-17 18:20:00 +01001204 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Daniel Willmann423d8f42020-09-08 18:58:22 +02001205 timer T := 5.0;
Harald Welte16357a92020-11-17 18:20:00 +01001206 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 +02001207 T.start;
1208 alt {
Harald Welte16357a92020-11-17 18:20:00 +01001209 [] PCU_SIG[ran_idx].receive(tr_BSSGP_RESUME_ACK(g_pars.tlli, bvcc.cell_id.ra_id));
1210 [] PCU_SIG[ran_idx].receive(tr_BSSGP_RESUME_NACK(g_pars.tlli, bvcc.cell_id.ra_id, ?)) {
Harald Welted5b7e742021-01-27 10:50:24 +01001211 f_shutdown(__FILE__, __LINE__, fail,
1212 log2str("RESUME-NACK in response to RESUME for TLLI ", g_pars.tlli));
Daniel Willmann423d8f42020-09-08 18:58:22 +02001213 }
1214 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +01001215 f_shutdown(__FILE__, __LINE__, fail,
1216 log2str("No RESUME-ACK in response to SUSPEND for TLLI ", g_pars.tlli));
Daniel Willmann423d8f42020-09-08 18:58:22 +02001217 }
1218 }
1219}
1220
1221
Harald Welte92686012020-11-15 21:45:49 +01001222/* send uplink-unitdata of a variety of different sizes; expect it to show up on SGSN */
1223private function f_TC_ul_unitdata(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte16357a92020-11-17 18:20:00 +01001224 var integer ran_idx := 0;
1225 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Harald Welte92686012020-11-15 21:45:49 +01001226 var integer i;
1227
Harald Welte0d5fceb2020-11-29 16:04:07 +01001228 for (i := 0; i < max_fr_info_size-4; i := i+4) {
Harald Welte92686012020-11-15 21:45:49 +01001229 var octetstring payload := f_rnd_octstring(i);
Harald Welte16357a92020-11-17 18:20:00 +01001230 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 +01001231 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte16357a92020-11-17 18:20:00 +01001232 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 +01001233
Harald Welte0d5fceb2020-11-29 16:04:07 +01001234 log("UL-UNITDATA(payload_size=", i);
Harald Welte22ef5d92020-11-16 13:35:14 +01001235 f_pcu2sgsn(pdu_tx, pdu_rx);
Harald Welte92686012020-11-15 21:45:49 +01001236 }
1237 setverdict(pass);
1238}
1239
1240testcase TC_ul_unitdata() runs on test_CT
1241{
Daniel Willmannc879f342021-02-11 14:28:01 +01001242 f_init(60.0);
Harald Welte2ecbca82021-01-16 11:23:09 +01001243 f_start_handlers(refers(f_TC_ul_unitdata), testcasename(), 1);
Harald Welte92686012020-11-15 21:45:49 +01001244 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Welte92686012020-11-15 21:45:49 +01001245 f_cleanup();
1246}
1247
Daniel Willmann8d9fcf42021-05-28 15:05:41 +02001248
1249/* send uplink-unitdata of a variety of different sizes; expect it to show up on the only connected SGSN */
1250private function f_TC_ul_unitdata_pool_failure(charstring id) runs on BSSGP_ConnHdlr {
1251 var integer ran_idx := 0;
1252 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
1253 var integer i;
1254
1255 /* All data should arrive at the one SGSN that is still up */
1256 g_pars.sgsn_idx := 0;
1257
1258 for (i := 0; i < max_fr_info_size-4; i := i+4) {
1259 var octetstring payload := f_rnd_octstring(i);
1260 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_UL_UD(g_pars.tlli, bvcc.cell_id, payload);
1261 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1262 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_UL_UD(g_pars.tlli, bvcc.cell_id, payload);
1263
1264 log("UL-UNITDATA(payload_size=", i);
1265 f_pcu2sgsn(pdu_tx, pdu_rx);
1266 }
1267 setverdict(pass);
1268}
1269
Daniel Willmannc5bbcc62021-09-24 13:17:20 +02001270private function f_disable_ns_pcu(integer pcu_idx) runs on test_CT
1271{
1272 var integer i;
1273
1274 connect(self:NS_CTRL, g_pcu[pcu_idx].vc_NS:NS_CTRL);
1275 for (i := 0; i < lengthof(mp_nsconfig_pcu[pcu_idx].nsvc); i := i + 1) {
1276 var uint16_t nsvci := mp_nsconfig_pcu[pcu_idx].nsvc[i].nsvci;
1277 var NsDisableVcRequest tx_disar;
1278 tx_disar.nsvci := nsvci;
1279 log(tx_disar);
1280 NS_CTRL.send(tx_disar);
1281 }
1282 disconnect(self:NS_CTRL, g_pcu[pcu_idx].vc_NS:NS_CTRL);
1283}
1284
Daniel Willmann8d9fcf42021-05-28 15:05:41 +02001285testcase TC_ul_unitdata_pool_failure() runs on test_CT
1286{
1287 var integer i;
1288 var integer j;
1289
1290 f_init(60.0);
1291
1292 for (i := 1; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
1293 connect(self:NS_CTRL, g_sgsn[i].vc_NS:NS_CTRL);
1294 for (j := 0; j < lengthof(mp_nsconfig_sgsn[i].nsvc); j := j+1) {
1295 var uint16_t nsvci := mp_nsconfig_sgsn[i].nsvc[j].nsvci;
1296 var NsDisableVcRequest tx_disar;
1297 tx_disar.nsvci := nsvci;
1298 NS_CTRL.send(tx_disar);
1299 }
1300 disconnect(self:NS_CTRL, g_sgsn[i].vc_NS:NS_CTRL);
1301 }
1302 /* Wait until gbproxy notices that the NSVCs are down */
1303 f_sleep(15.0);
1304
1305 f_start_handlers(refers(f_TC_ul_unitdata_pool_failure), testcasename(), 1);
1306 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
1307 f_cleanup();
1308}
1309
Harald Welte78d8db92020-11-15 23:27:27 +01001310/* send downlink-unitdata of a variety of different sizes; expect it to show up on PCU */
1311private function f_TC_dl_unitdata(charstring id) runs on BSSGP_ConnHdlr {
1312 var integer i;
1313
Harald Welte0d5fceb2020-11-29 16:04:07 +01001314 for (i := 0; i < max_fr_info_size-4; i := i+4) {
Harald Welte78d8db92020-11-15 23:27:27 +01001315 var octetstring payload := f_rnd_octstring(i);
1316 var template (value) PDU_BSSGP pdu_tx :=
1317 ts_BSSGP_DL_UD(g_pars.tlli, payload, omit, ts_BSSGP_IMSI(g_pars.imsi));
1318 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1319 var template (present) PDU_BSSGP pdu_rx :=
Daniel Willmann325458d2021-02-11 14:22:42 +01001320 tr_BSSGP_DL_UD(g_pars.tlli, payload, tr_BSSGP_IMSI(g_pars.imsi));
Harald Welte78d8db92020-11-15 23:27:27 +01001321
Harald Welted6c07e02023-04-05 21:22:15 +02001322 log("DL-UNITDATA(payload_size=", i, ")");
Harald Welte22ef5d92020-11-16 13:35:14 +01001323 f_sgsn2pcu(pdu_tx, pdu_rx);
Harald Welte78d8db92020-11-15 23:27:27 +01001324 }
1325 setverdict(pass);
1326}
1327
1328testcase TC_dl_unitdata() runs on test_CT
1329{
Daniel Willmannc879f342021-02-11 14:28:01 +01001330 f_init(60.0);
Harald Welte2ecbca82021-01-16 11:23:09 +01001331 f_start_handlers(refers(f_TC_dl_unitdata), testcasename(), 2);
Harald Welte78d8db92020-11-15 23:27:27 +01001332 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Welte78d8db92020-11-15 23:27:27 +01001333 f_cleanup();
1334}
Harald Welte92686012020-11-15 21:45:49 +01001335
Harald Welte6dc2ac42020-11-16 09:16:17 +01001336private function f_TC_ra_capability(charstring id) runs on BSSGP_ConnHdlr {
1337 var integer i;
1338
1339 for (i := 0; i < 10; i := i+1) {
1340 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RA_CAP(g_pars.tlli, { ts_RaCapRec_BSSGP });
1341 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1342 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RA_CAP(g_pars.tlli, { tr_RaCapRec_BSSGP })
1343
Harald Welte22ef5d92020-11-16 13:35:14 +01001344 f_sgsn2pcu(pdu_tx, pdu_rx);
Harald Welte6dc2ac42020-11-16 09:16:17 +01001345 }
1346 setverdict(pass);
1347}
1348testcase TC_ra_capability() runs on test_CT
1349{
Harald Welte6dc2ac42020-11-16 09:16:17 +01001350 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001351 f_start_handlers(refers(f_TC_ra_capability), testcasename(), 3);
Harald Welte6dc2ac42020-11-16 09:16:17 +01001352 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Welte6dc2ac42020-11-16 09:16:17 +01001353 f_cleanup();
1354}
1355
Daniel Willmannace3ece2020-11-16 19:53:26 +01001356private function f_TC_ra_capability_upd(charstring id) runs on BSSGP_ConnHdlr {
1357 var integer i;
1358 var OCT1 tag;
1359 for (i := 0; i < 10; i := i+1) {
1360 tag := int2oct(23 + i, 1);
1361 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RA_CAP_UPD(g_pars.tlli, tag);
1362 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1363 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RA_CAP_UPD(g_pars.tlli, tag)
1364
1365 f_pcu2sgsn(pdu_tx, pdu_rx);
1366
1367 pdu_tx := ts_BSSGP_RA_CAP_UPD_ACK(g_pars.tlli, tag, '42'O);
1368 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1369 pdu_rx := tr_BSSGP_RA_CAP_UPD_ACK(g_pars.tlli, tag, '42'O)
1370
1371 f_sgsn2pcu(pdu_tx, pdu_rx);
1372 }
1373 setverdict(pass);
1374}
1375testcase TC_ra_capability_upd() runs on test_CT
1376{
Daniel Willmannace3ece2020-11-16 19:53:26 +01001377 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001378 f_start_handlers(refers(f_TC_ra_capability_upd), testcasename(), 4);
Daniel Willmannace3ece2020-11-16 19:53:26 +01001379 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Daniel Willmannace3ece2020-11-16 19:53:26 +01001380 f_cleanup();
1381}
1382
Daniel Willmann165d6612020-11-19 14:27:29 +01001383private function f_TC_radio_status(charstring id) runs on BSSGP_ConnHdlr {
1384 var integer i;
1385 var BssgpRadioCause cause := BSSGP_RADIO_CAUSE_CONTACT_LOST;
1386 for (i := 0; i < 10; i := i+1) {
1387 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RADIO_STATUS(g_pars.tlli, cause);
1388 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1389 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RADIO_STATUS(g_pars.tlli, cause)
1390
1391 f_pcu2sgsn(pdu_tx, pdu_rx);
1392 }
1393 setverdict(pass);
1394}
1395testcase TC_radio_status() runs on test_CT
1396{
Daniel Willmann165d6612020-11-19 14:27:29 +01001397 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001398 f_start_handlers(refers(f_TC_radio_status), testcasename(), 5);
Daniel Willmann165d6612020-11-19 14:27:29 +01001399 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Daniel Willmann165d6612020-11-19 14:27:29 +01001400 f_cleanup();
1401}
1402
Harald Welte3148a962021-01-17 11:15:28 +01001403private function f_TC_radio_status_tmsi(charstring id) runs on BSSGP_ConnHdlr {
1404 var integer i;
1405 var BssgpRadioCause cause := BSSGP_RADIO_CAUSE_CONTACT_LOST;
1406 for (i := 0; i < 10; i := i+1) {
1407 var integer tmsi_int := oct2int(g_pars.p_tmsi);
1408 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RADIO_STATUS(omit, cause, tmsi_int);
1409 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1410 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RADIO_STATUS(omit, cause, tmsi_int);
1411 f_pcu2sgsn(pdu_tx, pdu_rx);
1412 }
1413 setverdict(pass);
1414}
1415testcase TC_radio_status_tmsi() runs on test_CT
1416{
1417 f_init();
1418 f_start_handlers(refers(f_TC_radio_status_tmsi), testcasename(), 5);
1419 f_cleanup();
1420}
1421
1422private function f_TC_radio_status_imsi(charstring id) runs on BSSGP_ConnHdlr {
1423 var integer i;
1424 var BssgpRadioCause cause := BSSGP_RADIO_CAUSE_CONTACT_LOST;
1425 for (i := 0; i < 10; i := i+1) {
1426 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RADIO_STATUS(omit, cause, imsi := g_pars.imsi);
1427 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1428 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RADIO_STATUS(omit, cause, imsi := g_pars.imsi);
1429 f_pcu2any_sgsn(pdu_tx, pdu_rx);
1430 }
1431 setverdict(pass);
1432}
1433testcase TC_radio_status_imsi() runs on test_CT
1434{
1435 f_init();
1436 f_start_handlers(refers(f_TC_radio_status_imsi), testcasename(), 5);
1437 f_cleanup();
1438}
1439
1440
1441
Harald Welte99ed5072021-01-15 20:38:58 +01001442private function f_suspend_one(integer sgsn_idx, integer nri_idx, integer pcu_idx, integer bvc_idx,
1443 integer suffix)
Harald Welte00963752021-01-15 20:33:11 +01001444runs on GlobalTest_CT
1445{
1446 var RoutingAreaIdentification ra_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id.ra_id;
Harald Welte99ed5072021-01-15 20:38:58 +01001447 var OCT4 p_tmsi := f_gen_tmsi(suffix, nri_v := mp_sgsn_nri[sgsn_idx][nri_idx],
1448 nri_bitlen := mp_nri_bitlength);
1449 var OCT4 tlli := f_gprs_tlli_from_tmsi(p_tmsi, TLLI_LOCAL);
Harald Welte00963752021-01-15 20:33:11 +01001450 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_SUSPEND(tlli, ra_id);
1451 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1452 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_SUSPEND(tlli, ra_id);
1453 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1454
1455 pdu_tx := ts_BSSGP_SUSPEND_ACK(tlli, ra_id, int2oct(suffix, 1));
1456 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1457 pdu_rx := tr_BSSGP_SUSPEND_ACK(tlli, ra_id, int2oct(suffix, 1));
1458 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1459
1460 pdu_tx := ts_BSSGP_SUSPEND(tlli, ra_id);
1461 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1462 pdu_rx := tr_BSSGP_SUSPEND(tlli, ra_id);
1463 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1464
1465 /* These messages are simple passed through so just also test sending NACK */
1466 pdu_tx := ts_BSSGP_SUSPEND_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1467 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1468 pdu_rx := tr_BSSGP_SUSPEND_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1469 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1470}
1471
Harald Weltec5c33732021-01-15 21:04:35 +01001472private function f_TC_suspend(integer sgsn_idx, integer nri_idx, integer pcu_idx, integer bvc_idx)
1473runs on GlobalTest_CT {
Daniel Willmannfa67f492020-11-19 15:48:05 +01001474 var integer i;
Daniel Willmann165d6612020-11-19 14:27:29 +01001475
Daniel Willmannfa67f492020-11-19 15:48:05 +01001476 for (i := 0; i < 10; i := i+1) {
Harald Weltec5c33732021-01-15 21:04:35 +01001477 f_suspend_one(sgsn_idx, nri_idx, pcu_idx, bvc_idx, suffix := i);
Daniel Willmannfa67f492020-11-19 15:48:05 +01001478 }
1479 setverdict(pass);
1480}
Harald Welte3807ed12020-11-24 19:05:22 +01001481testcase TC_suspend() runs on GlobalTest_CT
Daniel Willmannfa67f492020-11-19 15:48:05 +01001482{
Harald Weltec5c33732021-01-15 21:04:35 +01001483 var integer sgsn_idx, nri_idx;
Daniel Willmannfa67f492020-11-19 15:48:05 +01001484 f_init();
Harald Welte3807ed12020-11-24 19:05:22 +01001485 f_global_init();
Harald Weltec5c33732021-01-15 21:04:35 +01001486 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx+1) {
1487 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx+1) {
1488 f_TC_suspend(sgsn_idx, nri_idx, pcu_idx:=0, bvc_idx:=0);
1489 }
1490 }
Daniel Willmannfa67f492020-11-19 15:48:05 +01001491 f_cleanup();
1492}
Harald Welte6dc2ac42020-11-16 09:16:17 +01001493
Harald Welte99ed5072021-01-15 20:38:58 +01001494private function f_resume_one(integer sgsn_idx, integer nri_idx, integer pcu_idx, integer bvc_idx,
1495 integer suffix)
Harald Welte00963752021-01-15 20:33:11 +01001496runs on GlobalTest_CT
1497{
1498 var RoutingAreaIdentification ra_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id.ra_id;
Harald Welte99ed5072021-01-15 20:38:58 +01001499 var OCT4 p_tmsi := f_gen_tmsi(suffix, nri_v := mp_sgsn_nri[sgsn_idx][nri_idx],
1500 nri_bitlen := mp_nri_bitlength);
1501 var OCT4 tlli := f_gprs_tlli_from_tmsi(p_tmsi, TLLI_LOCAL);
Harald Welte00963752021-01-15 20:33:11 +01001502 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1503 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1504 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1505 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1506
1507 pdu_tx := ts_BSSGP_RESUME_ACK(tlli, ra_id);
1508 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1509 pdu_rx := tr_BSSGP_RESUME_ACK(tlli, ra_id);
1510 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1511
1512 pdu_tx := ts_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1513 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1514 pdu_rx := tr_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1515 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1516
1517 /* These messages are simple passed through so just also test sending NACK */
1518 pdu_tx := ts_BSSGP_RESUME_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1519 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1520 pdu_rx := tr_BSSGP_RESUME_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1521 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1522}
1523
Harald Weltec5c33732021-01-15 21:04:35 +01001524private function f_TC_resume(integer sgsn_idx, integer nri_idx, integer pcu_idx, integer bvc_idx)
1525runs on GlobalTest_CT {
Daniel Willmann087a33d2020-11-19 15:58:43 +01001526 var integer i;
1527
Daniel Willmann087a33d2020-11-19 15:58:43 +01001528 for (i := 0; i < 10; i := i+1) {
Harald Weltec5c33732021-01-15 21:04:35 +01001529 f_resume_one(sgsn_idx, nri_idx, pcu_idx, bvc_idx, suffix := i);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001530 }
1531 setverdict(pass);
1532}
Harald Welte3807ed12020-11-24 19:05:22 +01001533testcase TC_resume() runs on GlobalTest_CT
Daniel Willmann087a33d2020-11-19 15:58:43 +01001534{
Harald Weltec5c33732021-01-15 21:04:35 +01001535 var integer sgsn_idx, nri_idx;
Daniel Willmann087a33d2020-11-19 15:58:43 +01001536 f_init();
Harald Welte3807ed12020-11-24 19:05:22 +01001537 f_global_init();
Harald Weltec5c33732021-01-15 21:04:35 +01001538 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx+1) {
1539 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx+1) {
1540 f_TC_resume(sgsn_idx, nri_idx, pcu_idx:=0, bvc_idx:=0);
1541 }
1542 }
Daniel Willmann087a33d2020-11-19 15:58:43 +01001543 f_cleanup();
1544}
1545
Harald Weltef8ef0282020-11-18 12:16:59 +01001546/* test the load-sharing between multiple NS-VC on the BSS side */
1547private function f_TC_dl_ud_unidir(charstring id) runs on BSSGP_ConnHdlr {
1548 var integer i;
1549
1550 for (i := 0; i < 10; i := i+1) {
1551 var octetstring payload := f_rnd_octstring(i);
1552 var template (value) PDU_BSSGP pdu_tx :=
1553 ts_BSSGP_DL_UD(g_pars.tlli, payload, omit, ts_BSSGP_IMSI(g_pars.imsi));
Harald Welte09a1ce42021-01-16 11:18:38 +01001554 SGSN_PTP[g_pars.sgsn_idx].send(pdu_tx);
Harald Weltef8ef0282020-11-18 12:16:59 +01001555 }
1556 setverdict(pass);
1557}
Harald Welte09a1ce42021-01-16 11:18:38 +01001558
1559private function f_TC_load_sharing_dl(integer sgsn_idx) runs on test_CT_NS
Harald Weltef8ef0282020-11-18 12:16:59 +01001560{
1561 const integer num_ue := 10;
1562 var BSSGP_ConnHdlr vc_conn[num_ue];
Harald Weltef8ef0282020-11-18 12:16:59 +01001563 /* all BVC are now fully brought up. We disconnect BSSGP from NS on the BSS
1564 * side so we get the raw NsUnitdataIndication and hence observe different
1565 * NSVCI */
1566 disconnect(g_pcu[0].vc_NS:NS_SP, g_pcu[0].vc_BSSGP:BSCP);
1567 connect(g_pcu[0].vc_NS:NS_SP, self:NS);
1568
1569 /* there may still be some NS-VCs coming up? After all, the BVC-RESET succeeds after the first
1570 * of the NS-VC is ALIVE/UNBLOCKED */
1571 f_sleep(3.0);
1572
1573 /* start parallel components generating DL-UNITDATA from the SGSN side */
1574 for (var integer i:= 0; i < num_ue; i := i+1) {
Harald Welte2ecbca82021-01-16 11:23:09 +01001575 vc_conn[i] := f_start_handler(refers(f_TC_dl_ud_unidir), testcasename(),
Harald Welte09a1ce42021-01-16 11:18:38 +01001576 5+i, 30.0, sgsn_idx);
Harald Weltef8ef0282020-11-18 12:16:59 +01001577 }
1578
1579 /* now start counting all the messages that were queued before */
1580 /* TODO: We have a hard-coded assumption of 4 NS-VC in one NSE/NS-VCG here! */
1581 var ro_integer rx_count := { 0, 0, 0, 0 };
1582 timer T := 2.0;
1583 T.start;
1584 alt {
1585 [] as_NsUdiCount(0, rx_count);
1586 [] as_NsUdiCount(1, rx_count);
1587 [] as_NsUdiCount(2, rx_count);
1588 [] as_NsUdiCount(3, rx_count);
1589 [] NS.receive(NsUnitdataIndication:{0,?,?,*,*}) { repeat; } /* signaling BVC */
1590 [] NS.receive(NsStatusIndication:?) { repeat; }
1591 [] NS.receive {
Harald Welted5b7e742021-01-27 10:50:24 +01001592 f_shutdown(__FILE__, __LINE__, fail, "Rx unexpected NS");
Harald Weltef8ef0282020-11-18 12:16:59 +01001593 }
1594 [] T.timeout {
1595 }
1596 }
1597 for (var integer i := 0; i < lengthof(rx_count); i := i+1) {
1598 log("Rx on NSVCI ", mp_nsconfig_pcu[0].nsvc[i].nsvci, ": ", rx_count[i]);
1599 if (rx_count[i] == 0) {
1600 setverdict(fail, "Data not shared over all NSVC");
1601 }
1602 }
Harald Welte09a1ce42021-01-16 11:18:38 +01001603}
1604
1605testcase TC_load_sharing_dl() runs on test_CT_NS
1606{
1607 var integer sgsn_idx, nri_idx;
1608 f_init();
1609 for (sgsn_idx:=0; sgsn_idx < NUM_SGSN; sgsn_idx:=sgsn_idx+1) {
1610 f_TC_load_sharing_dl(sgsn_idx);
1611 }
Harald Weltef8ef0282020-11-18 12:16:59 +01001612 setverdict(pass);
1613}
1614private altstep as_NsUdiCount(integer nsvc_idx, inout ro_integer roi) runs on test_CT_NS {
1615 var NsUnitdataIndication udi;
1616 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[0];
1617 [] NS.receive(NsUnitdataIndication:{bvcc.bvci, g_pcu[0].cfg.nsei, mp_nsconfig_pcu[0].nsvc[nsvc_idx].nsvci, *, *}) -> value udi {
1618 roi[nsvc_idx] := roi[nsvc_idx] + 1;
1619 repeat;
1620 }
1621}
1622type component test_CT_NS extends test_CT {
1623 port NS_PT NS;
1624};
1625
1626
Harald Welte0e188242020-11-22 21:46:48 +01001627/***********************************************************************
1628 * PAGING PS procedure
1629 ***********************************************************************/
1630
1631private function f_send_paging_ps(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1632 boolean use_sig := false)
1633runs on BSSGP_ConnHdlr return template (present) PDU_BSSGP {
1634 var template (value) PDU_BSSGP pdu_tx;
1635 var template (present) PDU_BSSGP pdu_rx;
1636 /* we always specify '0' as BVCI in the templates below, as we override it with
1637 * 'p4' later anyway */
1638 pdu_rx := tr_BSSGP_PS_PAGING(0);
1639 pdu_rx.pDU_BSSGP_PAGING_PS.iMSI := tr_BSSGP_IMSI(g_pars.imsi);
1640 if (ispresent(g_pars.p_tmsi)) {
1641 pdu_tx := ts_BSSGP_PS_PAGING_PTMSI(0, g_pars.imsi, oct2int(g_pars.p_tmsi));
1642 pdu_rx.pDU_BSSGP_PAGING_PS.pTMSI := tr_BSSGP_TMSI(oct2int(g_pars.p_tmsi));
1643 } else {
1644 pdu_tx := ts_BSSGP_PS_PAGING_IMSI(0, g_pars.imsi);
1645 pdu_rx.pDU_BSSGP_PAGING_PS.pTMSI := omit;
1646 }
1647 pdu_tx.pDU_BSSGP_PAGING_PS.paging_Field4 := p4;
1648 pdu_rx.pDU_BSSGP_PAGING_PS.paging_Field4 := p4;
1649 if (use_sig == false) {
Harald Welte158becf2020-12-09 12:32:32 +01001650 SGSN_PTP[sgsn_idx].send(pdu_tx);
Harald Welte0e188242020-11-22 21:46:48 +01001651 } else {
1652 SGSN_SIG[sgsn_idx].send(pdu_tx);
1653 }
1654 return pdu_rx;
1655}
1656
1657/* send paging defined by 'p4' on given SGSN-side index (ptp or signaling) and expect one paging to arrive on
1658 * specified PCU index */
1659private function f_send_paging_ps_exp_one_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1660 boolean use_sig := false,integer pcu_idx := 0)
1661runs on BSSGP_ConnHdlr {
1662 var template (present) PDU_BSSGP exp_rx;
Daniel Willmann1a859712020-12-04 00:59:45 +01001663 var boolean test_done := false;
Harald Welte0e188242020-11-22 21:46:48 +01001664 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1665 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1666 exp_rx := f_send_paging_ps(p4, sgsn_idx, use_sig);
1667 /* Expect paging to propagate to the one BSS addressed by the BVCI only */
1668 timer T := 2.0;
1669 T.start;
1670 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001671 [not use_sig and not test_done] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001672 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001673 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001674 repeat;
1675 }
1676 [not use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
1677 setverdict(fail, "Received paging on SIGNALING BVC, expected PTP BVC");
1678 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001679 [use_sig and not test_done] PCU_SIG[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001680 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001681 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001682 repeat;
1683 }
Harald Welte158becf2020-12-09 12:32:32 +01001684 [use_sig] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001685 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1686 }
Harald Welte158becf2020-12-09 12:32:32 +01001687 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001688 setverdict(fail, "Paging received on unexpected BVC");
1689 }
1690 [] any from PCU_SIG.receive(exp_rx) {
1691 setverdict(fail, "Paging received on unexpected BVC");
1692 }
Harald Welte158becf2020-12-09 12:32:32 +01001693 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01001694 setverdict(fail, "Different Paging than expected received PTP BVC");
1695 }
1696 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1697 setverdict(fail, "Different Paging than expected on SIGNALING BVC");
1698 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001699 [not test_done] T.timeout {
1700 setverdict(fail, "Timeout waiting for paging");
1701 }
1702 [test_done] T.timeout;
Harald Welte0e188242020-11-22 21:46:48 +01001703 }
1704}
1705
Harald Welte7462a592020-11-23 22:07:07 +01001706/* send a PS-PAGING but don't expect it to show up on any PTP or SIG BVC */
1707private function f_send_paging_ps_exp_no_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1708 boolean use_sig := false)
1709runs on BSSGP_ConnHdlr {
1710 var template (present) PDU_BSSGP exp_rx;
1711 exp_rx := f_send_paging_ps(p4, sgsn_idx, use_sig);
1712 /* Expect paging to propagate to no BSS */
1713 timer T := 2.0;
1714 T.start;
1715 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001716 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte7462a592020-11-23 22:07:07 +01001717 setverdict(fail, "Paging received on unexpected BVC");
1718 }
1719 [] any from PCU_SIG.receive(exp_rx) {
1720 setverdict(fail, "Paging received on unexpected BVC");
1721 }
Harald Welte158becf2020-12-09 12:32:32 +01001722 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte7462a592020-11-23 22:07:07 +01001723 setverdict(fail, "Different Paging received on PTP BVC");
1724 }
1725 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1726 setverdict(fail, "Different Paging received on SIGNALING BVC");
1727 }
1728 [] T.timeout {
1729 setverdict(pass);
1730 }
1731 }
1732}
1733
Harald Welte0e188242020-11-22 21:46:48 +01001734private function f_TC_paging_ps_ptp_bss(charstring id) runs on BSSGP_ConnHdlr
1735{
1736 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1737 * at that BVC (cell) only, and paging all over the BSS area is not possible */
Daniel Willmann2a330672021-01-18 18:50:02 +01001738 f_send_paging_ps_exp_one_bss(ts_BssgpP4BssArea, g_pars.sgsn_idx, false, 0);
Harald Welte0e188242020-11-22 21:46:48 +01001739}
1740testcase TC_paging_ps_ptp_bss() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001741 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001742 f_start_handlers(refers(f_TC_paging_ps_ptp_bss), testcasename(), 9);
Harald Welte0e188242020-11-22 21:46:48 +01001743 f_cleanup();
1744}
1745
1746/* PS-PAGING on PTP-BVC for Location Area */
1747private function f_TC_paging_ps_ptp_lac(charstring id) runs on BSSGP_ConnHdlr
1748{
1749 var template (present) PDU_BSSGP exp_rx;
1750 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1751 * at that BVC (cell) only, and paging all over the BSS area is not possible */
Daniel Willmann2a330672021-01-18 18:50:02 +01001752 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 +01001753}
1754testcase TC_paging_ps_ptp_lac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001755 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001756 f_start_handlers(refers(f_TC_paging_ps_ptp_lac), testcasename(), 10);
Harald Welte0e188242020-11-22 21:46:48 +01001757 f_cleanup();
1758}
1759
Harald Welte7462a592020-11-23 22:07:07 +01001760/* PS-PAGING on PTP-BVC for unknown Location Area */
1761private function f_TC_paging_ps_ptp_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1762{
1763 var GSM_Types.LocationAreaIdentification unknown_la := {
1764 mcc_mnc := '567F99'H,
1765 lac := 33333
1766 };
1767 /* as it's sent on the PTP BVC, we expect it to pass even for unknown LAC */
Daniel Willmann2a330672021-01-18 18:50:02 +01001768 f_send_paging_ps_exp_one_bss(ts_BssgpP4LAC(unknown_la), g_pars.sgsn_idx, false, 0);
Harald Welte7462a592020-11-23 22:07:07 +01001769}
1770testcase TC_paging_ps_ptp_lac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001771 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001772 f_start_handlers(refers(f_TC_paging_ps_ptp_lac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001773 f_cleanup();
1774}
1775
Harald Welte0e188242020-11-22 21:46:48 +01001776/* PS-PAGING on PTP-BVC for Routeing Area */
1777private function f_TC_paging_ps_ptp_rac(charstring id) runs on BSSGP_ConnHdlr
1778{
1779 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1780 * at that BVC (cell) only, and paging all over the BSS area is not possible */
Daniel Willmann2a330672021-01-18 18:50:02 +01001781 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 +01001782}
1783testcase TC_paging_ps_ptp_rac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001784 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001785 f_start_handlers(refers(f_TC_paging_ps_ptp_rac), testcasename(), 11);
Harald Welte0e188242020-11-22 21:46:48 +01001786 f_cleanup();
1787}
1788
Harald Welte7462a592020-11-23 22:07:07 +01001789/* PS-PAGING on PTP-BVC for unknown Routeing Area */
1790private function f_TC_paging_ps_ptp_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1791{
1792 var RoutingAreaIdentification unknown_ra := {
1793 lai := {
1794 mcc_mnc := '567F99'H,
1795 lac := 33333
1796 },
1797 rac := 254
1798 };
1799 /* as it's sent on the PTP BVC, we expect it to pass even for unknown RAC */
Daniel Willmann2a330672021-01-18 18:50:02 +01001800 f_send_paging_ps_exp_one_bss(ts_BssgpP4RAC(unknown_ra), g_pars.sgsn_idx, false, 0);
Harald Welte7462a592020-11-23 22:07:07 +01001801}
1802testcase TC_paging_ps_ptp_rac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001803 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001804 f_start_handlers(refers(f_TC_paging_ps_ptp_rac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001805 f_cleanup();
1806}
1807
Harald Welte0e188242020-11-22 21:46:48 +01001808/* PS-PAGING on PTP-BVC for BVCI (one cell) */
1809private function f_TC_paging_ps_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
1810{
1811 /* this should be the normal case for MS in READY MM state after a lower layer failure */
Daniel Willmann2a330672021-01-18 18:50:02 +01001812 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 +01001813}
1814testcase TC_paging_ps_ptp_bvci() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001815 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001816 f_start_handlers(refers(f_TC_paging_ps_ptp_bvci), testcasename(), 12);
Harald Welte0e188242020-11-22 21:46:48 +01001817 f_cleanup();
1818}
1819
Harald Welteb5a04aa2021-01-16 13:04:40 +01001820
1821/* PS-PAGING on PTP-BVC for BVCI (one cell) using IMSI only (no P-TMSI allocated) */
1822testcase TC_paging_ps_ptp_bvci_imsi() runs on test_CT {
1823 f_init();
1824 f_start_handlers(refers(f_TC_paging_ps_ptp_bvci), testcasename(), 12, have_ptmsi:=false);
1825 f_cleanup();
1826}
1827
Harald Weltecf200072021-01-16 15:20:46 +01001828/* Rejected PS-PAGING on PTP-BVC for BVCI (one cell) */
1829testcase TC_paging_ps_reject_ptp_bvci() runs on test_CT {
1830 f_init();
1831 f_start_handlers(refers(f_TC_paging_ps_reject_ptp_bvci), testcasename(), 16);
1832 f_cleanup();
1833}
1834
1835/* Rejected PS-PAGING on PTP-BVC for BVCI (one cell) using IMSI only (no P-TMSI allocated) */
1836private function f_TC_paging_ps_reject_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
1837{
1838 /* first send the PS-PAGING from SGSN -> PCU */
Daniel Willmann2a330672021-01-18 18:50:02 +01001839 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 +01001840 /* then simulate the PS-PAGING-REJECT from the PCU */
1841 f_send_paging_ps_rej(use_sig:=false);
1842}
1843testcase TC_paging_ps_reject_ptp_bvci_imsi() runs on test_CT {
1844 f_init();
1845 f_start_handlers(refers(f_TC_paging_ps_reject_ptp_bvci), testcasename(), 16, have_ptmsi:=false);
1846 f_cleanup();
1847}
Harald Welteb5a04aa2021-01-16 13:04:40 +01001848
Harald Welte7462a592020-11-23 22:07:07 +01001849/* PS-PAGING on PTP-BVC for unknown BVCI */
1850private function f_TC_paging_ps_ptp_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1851{
1852 /* as it's sent on the PTP BVC, we expect it to pass even for unknown BVCI */
Daniel Willmann2a330672021-01-18 18:50:02 +01001853 f_send_paging_ps_exp_one_bss(ts_BssgpP4Bvci(33333), g_pars.sgsn_idx, false, 0);
Harald Welte7462a592020-11-23 22:07:07 +01001854}
1855testcase TC_paging_ps_ptp_bvci_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001856 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001857 f_start_handlers(refers(f_TC_paging_ps_ptp_bvci_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001858 f_cleanup();
1859}
1860
Harald Welte7595d562021-01-16 19:09:20 +01001861/* DUMMY PAGING PS on PTP BVC */
1862private function f_TC_dummy_paging_ps_ptp(charstring id) runs on BSSGP_ConnHdlr
1863{
1864 f_sgsn2pcu(ts_BSSGP_DUMMY_PAGING_PS(g_pars.imsi, omit),
1865 tr_BSSGP_DUMMY_PAGING_PS(g_pars.imsi, omit), use_sig := false);
1866 f_pcu2sgsn(ts_BSSGP_DUMMY_PAGING_PS_RESP(g_pars.imsi, 1, 5),
1867 tr_BSSGP_DUMMY_PAGING_PS_RESP(g_pars.imsi, 1, 5), use_sig := false)
1868}
1869testcase TC_dummy_paging_ps_ptp() runs on test_CT {
1870 f_init();
1871 f_start_handlers(refers(f_TC_dummy_paging_ps_ptp), testcasename(), 11);
1872 f_cleanup();
1873}
1874
Harald Welte0e188242020-11-22 21:46:48 +01001875/* altstep for expecting BSSGP PDU on signaling BVC of given pcu_idx + storing in 'roi' */
1876private altstep as_paging_sig_pcu(integer pcu_idx, template (present) PDU_BSSGP exp_rx, inout ro_integer roi)
1877runs on BSSGP_ConnHdlr {
1878[] PCU_SIG[pcu_idx].receive(exp_rx) {
1879 if (ro_integer_contains(roi, pcu_idx)) {
1880 setverdict(fail, "Received multiple paging on same SIG BVC");
1881 }
1882 roi := roi & { pcu_idx };
1883 repeat;
1884 }
Harald Welte158becf2020-12-09 12:32:32 +01001885[] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001886 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1887 }
1888[] PCU_SIG[pcu_idx].receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1889 setverdict(fail, "Different Paging than expected received SIGNALING BVC");
1890 }
Harald Welte158becf2020-12-09 12:32:32 +01001891[] PCU_PTP[pcu_idx].receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01001892 setverdict(fail, "Different Paging than expected received PTP BVC");
1893 }
1894}
1895
1896type record of default ro_default;
1897
1898/* send PS-PAGING on SIG BVC, expect it to arrive on given list of PCU indexes */
1899private function f_send_paging_ps_exp_multi(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1900 ro_integer exp_on_pcu_idx) runs on BSSGP_ConnHdlr
1901{
1902 var template (present) PDU_BSSGP exp_rx;
Daniel Willmann193e1a02021-01-17 12:55:53 +01001903 exp_rx := f_send_paging_ps(p4, sgsn_idx, true);
Harald Welte0e188242020-11-22 21:46:48 +01001904
1905 /* FIXME: make sure the relevant BVCs/BSS are connected to the ports! */
1906 var ro_default defaults := {};
1907 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1908 var default d := activate(as_paging_sig_pcu(i, exp_rx, g_roi));
1909 defaults := defaults & { d };
1910 }
1911 f_sleep(2.0);
1912 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
1913 deactivate(defaults[i]);
1914 }
1915 log("Paging received on PCU ", g_roi);
1916
1917 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1918 var boolean rx_on_i := ro_integer_contains(g_roi, i);
1919 var boolean exp_on_i := ro_integer_contains(exp_on_pcu_idx, i);
1920 if (exp_on_i and not rx_on_i) {
1921 setverdict(fail, "PS-PAGING not received on ", mp_nsconfig_pcu[i].nsei);
1922 }
1923 if (not exp_on_i and rx_on_i) {
1924 setverdict(fail, "PS-PAGING not expected but received on ", mp_nsconfig_pcu[i].nsei);
1925 }
1926 }
1927 setverdict(pass);
1928}
1929
Harald Weltecf200072021-01-16 15:20:46 +01001930/* Send PAGING-PS-REJECT on SIG BVC, expect it to arrive on the "right" SGSN */
1931private function f_send_paging_ps_rej(boolean use_sig := true, integer pcu_idx := 0) runs on BSSGP_ConnHdlr
1932{
1933 var template (value) PDU_BSSGP pdu_tx;
1934 var template (present) PDU_BSSGP exp_rx;
1935 var PDU_BSSGP pdu_rx;
1936 timer T := 5.0;
1937 var template (omit) GsmTmsi tmsi_int := omit;
1938
1939 if (ispresent(g_pars.p_tmsi)) {
1940 tmsi_int := oct2int(g_pars.p_tmsi);
1941 }
1942
1943 pdu_tx := ts_BSSGP_PAGING_PS_REJ(g_pars.imsi, 23, 42, tmsi_int);
1944 exp_rx := tr_BSSGP_PAGING_PS_REJ(g_pars.imsi, 23, 42, tmsi_int);
1945
1946 if (use_sig) {
1947 PCU_SIG[pcu_idx].send(pdu_tx);
1948 } else {
1949 PCU_PTP[pcu_idx].send(pdu_tx);
1950 }
1951 T.start;
1952 alt {
1953 [use_sig] SGSN_SIG[g_pars.sgsn_idx].receive(exp_rx) -> value pdu_rx {
1954 setverdict(pass);
1955 }
1956 [use_sig] SGSN_SIG[g_pars.sgsn_idx].receive {
1957 setverdict(fail, "Unexpected PDU on SGSN");
1958 }
1959 [use_sig] any from SGSN_SIG.receive(exp_rx) -> value pdu_rx {
1960 setverdict(fail, "PAGING-PS-REJECT arrived on wrong SGSN");
1961 }
1962 [not use_sig] SGSN_PTP[g_pars.sgsn_idx].receive(exp_rx) -> value pdu_rx {
1963 setverdict(pass);
1964 }
1965 [not use_sig] SGSN_PTP[g_pars.sgsn_idx].receive {
1966 setverdict(fail, "Unexpected PDU on SGSN");
1967 }
1968 [not use_sig] any from SGSN_PTP.receive(exp_rx) -> value pdu_rx {
1969 setverdict(fail, "PAGING-PS-REJECT arrived on wrong SGSN");
1970 }
1971 [] T.timeout {
1972 setverdict(fail, "Timeout waiting for PAGING-PS-REJECT");
1973 }
1974 }
1975}
1976
Harald Welte0e188242020-11-22 21:46:48 +01001977/* PS-PAGING on SIG-BVC for BSS Area */
1978private function f_TC_paging_ps_sig_bss(charstring id) runs on BSSGP_ConnHdlr
1979{
1980 /* we expect the paging to arrive on all three NSE */
Daniel Willmann43320442021-01-17 14:07:05 +01001981 f_send_paging_ps_exp_multi(ts_BssgpP4BssArea, g_pars.sgsn_idx, {0, 1, 2});
Harald Welte0e188242020-11-22 21:46:48 +01001982}
1983testcase TC_paging_ps_sig_bss() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001984 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001985 f_start_handlers(refers(f_TC_paging_ps_sig_bss), testcasename(), 13);
Harald Welte0e188242020-11-22 21:46:48 +01001986 f_cleanup();
1987}
1988
1989/* PS-PAGING on SIG-BVC for Location Area */
1990private function f_TC_paging_ps_sig_lac(charstring id) runs on BSSGP_ConnHdlr
1991{
Daniel Willmann2c9300f2020-12-01 10:54:08 +01001992 /* The first LAC (13135) is shared by all three NSEs */
Daniel Willmann43320442021-01-17 14:07:05 +01001993 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 +01001994 /* Reset state */
1995 g_roi := {};
1996 /* Make LAC (13300) available on pcu index 2 */
1997 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
Daniel Willmann43320442021-01-17 14:07:05 +01001998 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 +01001999}
2000testcase TC_paging_ps_sig_lac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002001 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002002 f_start_handlers(refers(f_TC_paging_ps_sig_lac), testcasename(), 14);
Harald Welte0e188242020-11-22 21:46:48 +01002003 f_cleanup();
2004}
2005
Harald Welte7462a592020-11-23 22:07:07 +01002006/* PS-PAGING on SIG-BVC for unknown Location Area */
2007private function f_TC_paging_ps_sig_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
2008{
2009 var GSM_Types.LocationAreaIdentification unknown_la := {
2010 mcc_mnc := '567F99'H,
2011 lac := 33333
2012 };
Daniel Willmann2a330672021-01-18 18:50:02 +01002013 f_send_paging_ps_exp_no_bss(ts_BssgpP4LAC(unknown_la), g_pars.sgsn_idx, true);
Harald Welte7462a592020-11-23 22:07:07 +01002014}
2015testcase TC_paging_ps_sig_lac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002016 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002017 f_start_handlers(refers(f_TC_paging_ps_sig_lac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002018 f_cleanup();
2019}
2020
Harald Welte0e188242020-11-22 21:46:48 +01002021/* PS-PAGING on SIG-BVC for Routeing Area */
2022private function f_TC_paging_ps_sig_rac(charstring id) runs on BSSGP_ConnHdlr
2023{
Daniel Willmann2c9300f2020-12-01 10:54:08 +01002024 /* Only PCU index 0 has a matching BVC with the RA ID */
Daniel Willmann43320442021-01-17 14:07:05 +01002025 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 +01002026 g_roi := {};
2027 /* PCU index 1 and 2 have a matching BVC with the RA ID */
Daniel Willmann43320442021-01-17 14:07:05 +01002028 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 +01002029 g_roi := {};
2030 /* PCU index 2 has two matching BVCs with the RA ID */
2031 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
Daniel Willmann43320442021-01-17 14:07:05 +01002032 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 +01002033}
2034testcase TC_paging_ps_sig_rac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002035 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002036 f_start_handlers(refers(f_TC_paging_ps_sig_rac), testcasename(), 15);
Harald Welte0e188242020-11-22 21:46:48 +01002037 f_cleanup();
2038}
2039
Harald Welte7462a592020-11-23 22:07:07 +01002040/* PS-PAGING on SIG-BVC for unknown Routeing Area */
2041private function f_TC_paging_ps_sig_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
2042{
2043 var RoutingAreaIdentification unknown_ra := {
2044 lai := {
2045 mcc_mnc := '567F99'H,
2046 lac := 33333
2047 },
2048 rac := 254
2049 };
Daniel Willmann2a330672021-01-18 18:50:02 +01002050 f_send_paging_ps_exp_no_bss(ts_BssgpP4RAC(unknown_ra), g_pars.sgsn_idx, true);
Harald Welte7462a592020-11-23 22:07:07 +01002051}
2052testcase TC_paging_ps_sig_rac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002053 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002054 f_start_handlers(refers(f_TC_paging_ps_sig_rac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002055 f_cleanup();
2056}
2057
Harald Welte0e188242020-11-22 21:46:48 +01002058/* PS-PAGING on SIG-BVC for BVCI (one cell) */
2059private function f_TC_paging_ps_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
2060{
Daniel Willmann43320442021-01-17 14:07:05 +01002061 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 +01002062}
2063testcase TC_paging_ps_sig_bvci() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002064 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002065 f_start_handlers(refers(f_TC_paging_ps_sig_bvci), testcasename(), 16);
Harald Welte0e188242020-11-22 21:46:48 +01002066 f_cleanup();
2067}
2068
Harald Welteb5a04aa2021-01-16 13:04:40 +01002069/* PS-PAGING on SIG-BVC for BVCI (one cell) using IMSI only (no P-TMSI allocated) */
2070testcase TC_paging_ps_sig_bvci_imsi() runs on test_CT {
2071 f_init();
2072 f_start_handlers(refers(f_TC_paging_ps_sig_bvci), testcasename(), 16, have_ptmsi:=false);
2073 f_cleanup();
2074}
2075
Harald Weltecf200072021-01-16 15:20:46 +01002076/* Rejected PS-PAGING on SIG-BVC for BVCI (one cell) */
2077private function f_TC_paging_ps_reject_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
2078{
2079 /* first send the PS-PAGING from SGSN -> PCU */
Daniel Willmann43320442021-01-17 14:07:05 +01002080 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 +01002081 /* then simulate the PS-PAGING-REJECT from the PCU */
2082 f_send_paging_ps_rej(use_sig:=true);
2083
2084}
2085testcase TC_paging_ps_reject_sig_bvci() runs on test_CT {
2086 f_init();
2087 f_start_handlers(refers(f_TC_paging_ps_reject_sig_bvci), testcasename(), 16);
2088 f_cleanup();
2089}
2090
2091/* Rejected PS-PAGING on SIG-BVC for BVCI (one cell) using IMSI only (no P-TMSI allocated) */
2092testcase TC_paging_ps_reject_sig_bvci_imsi() runs on test_CT {
2093 f_init();
2094 f_start_handlers(refers(f_TC_paging_ps_reject_sig_bvci), testcasename(), 16, have_ptmsi:=false);
2095 f_cleanup();
2096}
2097
Harald Welte7462a592020-11-23 22:07:07 +01002098/* PS-PAGING on SIG-BVC for unknown BVCI */
2099private function f_TC_paging_ps_sig_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
2100{
Daniel Willmann2a330672021-01-18 18:50:02 +01002101 f_send_paging_ps_exp_no_bss(ts_BssgpP4Bvci(33333), g_pars.sgsn_idx, true);
Harald Welte7462a592020-11-23 22:07:07 +01002102}
2103testcase TC_paging_ps_sig_bvci_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002104 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002105 f_start_handlers(refers(f_TC_paging_ps_sig_bvci_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002106 f_cleanup();
2107}
2108
Harald Welte7595d562021-01-16 19:09:20 +01002109/* DUMMY PAGING PS on SIG BVC */
2110private function f_TC_dummy_paging_ps_sig(charstring id) runs on BSSGP_ConnHdlr
2111{
2112 f_sgsn2pcu(ts_BSSGP_DUMMY_PAGING_PS(g_pars.imsi, omit),
2113 tr_BSSGP_DUMMY_PAGING_PS(g_pars.imsi, omit), use_sig := true);
2114 f_pcu2sgsn(ts_BSSGP_DUMMY_PAGING_PS_RESP(g_pars.imsi, 1, 5),
2115 tr_BSSGP_DUMMY_PAGING_PS_RESP(g_pars.imsi, 1, 5), use_sig := true)
2116}
2117testcase TC_dummy_paging_ps_sig() runs on test_CT {
2118 f_init();
2119 f_start_handlers(refers(f_TC_dummy_paging_ps_sig), testcasename(), 11);
2120 f_cleanup();
2121}
2122
Harald Welte7462a592020-11-23 22:07:07 +01002123
Harald Welte0e188242020-11-22 21:46:48 +01002124
2125/***********************************************************************
2126 * PAGING CS procedure
2127 ***********************************************************************/
2128
2129private function f_send_paging_cs(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
2130 boolean use_sig := false)
2131runs on BSSGP_ConnHdlr return template (present) PDU_BSSGP {
2132 var template (value) PDU_BSSGP pdu_tx;
2133 var template (present) PDU_BSSGP pdu_rx;
2134 /* we always specify '0' as BVCI in the templates below, as we override it with
2135 * 'p4' later anyway */
2136 pdu_rx := tr_BSSGP_CS_PAGING(0);
2137 pdu_rx.pDU_BSSGP_PAGING_CS.iMSI := tr_BSSGP_IMSI(g_pars.imsi);
2138 if (ispresent(g_pars.p_tmsi)) {
2139 pdu_tx := ts_BSSGP_CS_PAGING_PTMSI(0, g_pars.imsi, oct2int(g_pars.p_tmsi));
2140 pdu_rx.pDU_BSSGP_PAGING_CS.tMSI := tr_BSSGP_TMSI(oct2int(g_pars.p_tmsi));
2141 } else {
2142 pdu_tx := ts_BSSGP_CS_PAGING_IMSI(0, g_pars.imsi);
2143 pdu_rx.pDU_BSSGP_PAGING_CS.tMSI := omit;
2144 }
2145 pdu_tx.pDU_BSSGP_PAGING_CS.paging_Field4 := p4;
2146 pdu_rx.pDU_BSSGP_PAGING_CS.paging_Field4 := p4;
2147 if (use_sig == false) {
Harald Welte158becf2020-12-09 12:32:32 +01002148 SGSN_PTP[sgsn_idx].send(pdu_tx);
Harald Welte0e188242020-11-22 21:46:48 +01002149 } else {
2150 SGSN_SIG[sgsn_idx].send(pdu_tx);
2151 }
2152 return pdu_rx;
2153}
2154
2155/* send paging defined by 'p4' on given SGSN-side index (ptp or signaling) and expect one paging to arrive on
2156 * specified PCU index */
2157private function f_send_paging_cs_exp_one_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
2158 boolean use_sig := false,integer pcu_idx := 0)
2159runs on BSSGP_ConnHdlr {
2160 var template (present) PDU_BSSGP exp_rx;
Daniel Willmann1a859712020-12-04 00:59:45 +01002161 var boolean test_done := false;
Harald Welte0e188242020-11-22 21:46:48 +01002162 /* doesn't really make sense: Sending to a single BVCI means the message ends up
2163 * at that BVC (cell) only, and paging all over the BSS area is not possible */
2164 exp_rx := f_send_paging_cs(p4, sgsn_idx, use_sig);
2165 /* Expect paging to propagate to the one BSS addressed by the BVCI only */
2166 timer T := 2.0;
2167 T.start;
2168 alt {
Harald Welte158becf2020-12-09 12:32:32 +01002169 [not use_sig and not test_done] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01002170 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01002171 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01002172 repeat;
2173 }
2174 [not use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
2175 setverdict(fail, "Received paging on SIGNALING BVC, expected PTP BVC");
2176 }
Daniel Willmann1a859712020-12-04 00:59:45 +01002177 [use_sig and not test_done] PCU_SIG[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01002178 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01002179 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01002180 repeat;
2181 }
Harald Welte158becf2020-12-09 12:32:32 +01002182 [use_sig] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01002183 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
2184 }
Harald Welte158becf2020-12-09 12:32:32 +01002185 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01002186 setverdict(fail, "Paging received on unexpected BVC");
2187 }
2188 [] any from PCU_SIG.receive(exp_rx) {
2189 setverdict(fail, "Paging received on unexpected BVC");
2190 }
Harald Welte158becf2020-12-09 12:32:32 +01002191 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01002192 setverdict(fail, "Different Paging than expected received PTP BVC");
2193 }
2194 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
2195 setverdict(fail, "Different Paging than expected on SIGNALING BVC");
2196 }
Daniel Willmann1a859712020-12-04 00:59:45 +01002197 [not test_done] T.timeout {
2198 setverdict(fail, "Timeout while waiting for paging")
2199 }
2200 [test_done] T.timeout;
Harald Welte0e188242020-11-22 21:46:48 +01002201 }
2202}
2203
Harald Welte7462a592020-11-23 22:07:07 +01002204/* send a CS-PAGING but don't expect it to show up on any PTP or SIG BVC */
2205private function f_send_paging_cs_exp_no_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
2206 boolean use_sig := false)
2207runs on BSSGP_ConnHdlr {
2208 var template (present) PDU_BSSGP exp_rx;
2209 exp_rx := f_send_paging_cs(p4, sgsn_idx, use_sig);
2210 /* Expect paging to propagate to no BSS */
2211 timer T := 2.0;
2212 T.start;
2213 alt {
Harald Welte158becf2020-12-09 12:32:32 +01002214 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte7462a592020-11-23 22:07:07 +01002215 setverdict(fail, "Paging received on unexpected BVC");
2216 }
2217 [] any from PCU_SIG.receive(exp_rx) {
2218 setverdict(fail, "Paging received on unexpected BVC");
2219 }
Harald Welte158becf2020-12-09 12:32:32 +01002220 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
Harald Welte7462a592020-11-23 22:07:07 +01002221 setverdict(fail, "Different Paging received on PTP BVC");
2222 }
2223 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
2224 setverdict(fail, "Different Paging received on SIGNALING BVC");
2225 }
2226 [] T.timeout {
2227 setverdict(pass);
2228 }
2229 }
2230}
2231
Harald Welte0e188242020-11-22 21:46:48 +01002232private function f_TC_paging_cs_ptp_bss(charstring id) runs on BSSGP_ConnHdlr
2233{
2234 /* doesn't really make sense: Sending to a single BVCI means the message ends up
2235 * at that BVC (cell) only, and paging all over the BSS area is not possible */
2236 f_send_paging_cs_exp_one_bss(ts_BssgpP4BssArea, 0, false, 0);
2237}
2238testcase TC_paging_cs_ptp_bss() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002239 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002240 f_start_handlers(refers(f_TC_paging_cs_ptp_bss), testcasename(), 17);
Harald Welte0e188242020-11-22 21:46:48 +01002241 f_cleanup();
2242}
2243
2244/* CS-PAGING on PTP-BVC for Location Area */
2245private function f_TC_paging_cs_ptp_lac(charstring id) runs on BSSGP_ConnHdlr
2246{
2247 var template (present) PDU_BSSGP exp_rx;
2248 /* doesn't really make sense: Sending to a single BVCI means the message ends up
2249 * at that BVC (cell) only, and paging all over the BSS area is not possible */
2250 f_send_paging_cs_exp_one_bss(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, false, 0);
2251}
2252testcase TC_paging_cs_ptp_lac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002253 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002254 f_start_handlers(refers(f_TC_paging_cs_ptp_lac), testcasename(), 18);
Harald Welte0e188242020-11-22 21:46:48 +01002255 f_cleanup();
2256}
2257
Harald Welte7462a592020-11-23 22:07:07 +01002258/* CS-PAGING on PTP-BVC for unknown Location Area */
2259private function f_TC_paging_cs_ptp_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
2260{
2261 var GSM_Types.LocationAreaIdentification unknown_la := {
2262 mcc_mnc := '567F99'H,
2263 lac := 33333
2264 };
2265 /* as it's sent on the PTP BVC, we expect it to pass even for unknown LAC */
2266 f_send_paging_cs_exp_one_bss(ts_BssgpP4LAC(unknown_la), 0, false, 0);
2267}
2268testcase TC_paging_cs_ptp_lac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002269 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002270 f_start_handlers(refers(f_TC_paging_cs_ptp_lac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002271 f_cleanup();
2272}
2273
Harald Welte0e188242020-11-22 21:46:48 +01002274/* CS-PAGING on PTP-BVC for Routeing Area */
2275private function f_TC_paging_cs_ptp_rac(charstring id) runs on BSSGP_ConnHdlr
2276{
2277 /* doesn't really make sense: Sending to a single BVCI means the message ends up
2278 * at that BVC (cell) only, and paging all over the BSS area is not possible */
2279 f_send_paging_cs_exp_one_bss(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, false, 0);
2280}
2281testcase TC_paging_cs_ptp_rac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002282 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002283 f_start_handlers(refers(f_TC_paging_cs_ptp_rac), testcasename(), 19);
Harald Welte0e188242020-11-22 21:46:48 +01002284 f_cleanup();
2285}
2286
Harald Welte7462a592020-11-23 22:07:07 +01002287/* CS-PAGING on PTP-BVC for unknown Routeing Area */
2288private function f_TC_paging_cs_ptp_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
2289{
2290 var RoutingAreaIdentification unknown_ra := {
2291 lai := {
2292 mcc_mnc := '567F99'H,
2293 lac := 33333
2294 },
2295 rac := 254
2296 };
2297 /* as it's sent on the PTP BVC, we expect it to pass even for unknown RAC */
2298 f_send_paging_cs_exp_one_bss(ts_BssgpP4RAC(unknown_ra), 0, false, 0);
2299}
2300testcase TC_paging_cs_ptp_rac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002301 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002302 f_start_handlers(refers(f_TC_paging_cs_ptp_rac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002303 f_cleanup();
2304}
2305
Harald Welte0e188242020-11-22 21:46:48 +01002306/* CS-PAGING on PTP-BVC for BVCI (one cell) */
2307private function f_TC_paging_cs_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
2308{
2309 /* this should be the normal case for MS in READY MM state after a lower layer failure */
2310 f_send_paging_cs_exp_one_bss(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, false, 0);
2311}
2312testcase TC_paging_cs_ptp_bvci() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002313 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002314 f_start_handlers(refers(f_TC_paging_cs_ptp_bvci), testcasename(), 20);
Harald Welte0e188242020-11-22 21:46:48 +01002315 f_cleanup();
2316}
2317
Harald Welte7462a592020-11-23 22:07:07 +01002318/* CS-PAGING on PTP-BVC for unknown BVCI */
2319private function f_TC_paging_cs_ptp_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
2320{
2321 /* as it's sent on the PTP BVC, we expect it to pass even for unknown BVCI */
2322 f_send_paging_cs_exp_one_bss(ts_BssgpP4Bvci(33333), 0, false, 0);
2323}
2324testcase TC_paging_cs_ptp_bvci_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002325 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002326 f_start_handlers(refers(f_TC_paging_cs_ptp_bvci_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002327 f_cleanup();
2328}
2329
Harald Welte0e188242020-11-22 21:46:48 +01002330/* send CS-PAGING on SIG BVC, expect it to arrive on given list of PCU indexes */
2331private function f_send_paging_cs_exp_multi(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
2332 ro_integer exp_on_pcu_idx) runs on BSSGP_ConnHdlr
2333{
2334 var template (present) PDU_BSSGP exp_rx;
2335 exp_rx := f_send_paging_cs(p4, 0, true);
2336
2337 /* FIXME: make sure the relevant BVCs/BSS are connected to the ports! */
2338 var ro_default defaults := {};
2339 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
2340 var default d := activate(as_paging_sig_pcu(i, exp_rx, g_roi));
2341 defaults := defaults & { d };
2342 }
2343 f_sleep(2.0);
2344 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2345 deactivate(defaults[i]);
2346 }
2347 log("Paging received on PCU ", g_roi);
2348
2349 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
2350 var boolean rx_on_i := ro_integer_contains(g_roi, i);
2351 var boolean exp_on_i := ro_integer_contains(exp_on_pcu_idx, i);
2352 if (exp_on_i and not rx_on_i) {
2353 setverdict(fail, "PS-PAGING not received on ", mp_nsconfig_pcu[i].nsei);
2354 }
2355 if (not exp_on_i and rx_on_i) {
2356 setverdict(fail, "PS-PAGING not expected but received on ", mp_nsconfig_pcu[i].nsei);
2357 }
2358 }
2359 setverdict(pass);
2360}
2361
2362/* CS-PAGING on SIG-BVC for BSS Area */
2363private function f_TC_paging_cs_sig_bss(charstring id) runs on BSSGP_ConnHdlr
2364{
2365 /* we expect the paging to arrive on all three NSE */
2366 f_send_paging_cs_exp_multi(ts_BssgpP4BssArea, 0, {0, 1, 2});
2367}
2368testcase TC_paging_cs_sig_bss() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002369 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002370 f_start_handlers(refers(f_TC_paging_cs_sig_bss), testcasename(), 13);
Harald Welte0e188242020-11-22 21:46:48 +01002371 f_cleanup();
2372}
2373
2374/* CS-PAGING on SIG-BVC for Location Area */
2375private function f_TC_paging_cs_sig_lac(charstring id) runs on BSSGP_ConnHdlr
2376{
Daniel Willmannd4fb73c2020-12-07 13:57:17 +01002377 /* The first LAC (13135) is shared by all three NSEs */
2378 f_send_paging_cs_exp_multi(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, {0, 1, 2});
2379 /* Reset state */
2380 g_roi := {};
2381 /* Make LAC (13300) available on pcu index 2 */
2382 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
2383 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 +01002384}
2385testcase TC_paging_cs_sig_lac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002386 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002387 f_start_handlers(refers(f_TC_paging_cs_sig_lac), testcasename(), 14);
Harald Welte0e188242020-11-22 21:46:48 +01002388 f_cleanup();
2389}
2390
Harald Welte7462a592020-11-23 22:07:07 +01002391/* CS-PAGING on SIG-BVC for unknown Location Area */
2392private function f_TC_paging_cs_sig_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
2393{
2394 var GSM_Types.LocationAreaIdentification unknown_la := {
2395 mcc_mnc := '567F99'H,
2396 lac := 33333
2397 };
2398 f_send_paging_cs_exp_no_bss(ts_BssgpP4LAC(unknown_la), 0, true);
2399}
2400testcase TC_paging_cs_sig_lac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002401 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002402 f_start_handlers(refers(f_TC_paging_cs_sig_lac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002403 f_cleanup();
2404}
2405
Harald Welte0e188242020-11-22 21:46:48 +01002406/* CS-PAGING on SIG-BVC for Routeing Area */
2407private function f_TC_paging_cs_sig_rac(charstring id) runs on BSSGP_ConnHdlr
2408{
Daniel Willmannd4fb73c2020-12-07 13:57:17 +01002409 /* Only PCU index 0 has a matching BVC with the RA ID */
Harald Welte0e188242020-11-22 21:46:48 +01002410 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 +01002411 g_roi := {};
2412 /* PCU index 1 and 2 have a matching BVC with the RA ID */
2413 f_send_paging_cs_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[2].cell_id.ra_id), 0, {1, 2});
2414 g_roi := {};
2415 /* PCU index 2 has two matching BVCs with the RA ID */
2416 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
2417 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 +01002418}
2419testcase TC_paging_cs_sig_rac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002420 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002421 f_start_handlers(refers(f_TC_paging_cs_sig_rac), testcasename(), 15);
Harald Welte0e188242020-11-22 21:46:48 +01002422 f_cleanup();
2423}
2424
Harald Welte7462a592020-11-23 22:07:07 +01002425/* CS-PAGING on SIG-BVC for unknown Routeing Area */
2426private function f_TC_paging_cs_sig_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
2427{
2428 var RoutingAreaIdentification unknown_ra := {
2429 lai := {
2430 mcc_mnc := '567F99'H,
2431 lac := 33333
2432 },
2433 rac := 254
2434 };
2435 f_send_paging_cs_exp_no_bss(ts_BssgpP4RAC(unknown_ra), 0, true);
2436}
2437testcase TC_paging_cs_sig_rac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002438 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002439 f_start_handlers(refers(f_TC_paging_cs_sig_rac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002440 f_cleanup();
2441}
2442
Harald Welte0e188242020-11-22 21:46:48 +01002443/* CS-PAGING on SIG-BVC for BVCI (one cell) */
2444private function f_TC_paging_cs_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
2445{
2446 f_send_paging_cs_exp_multi(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, {0});
2447}
2448testcase TC_paging_cs_sig_bvci() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002449 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002450 f_start_handlers(refers(f_TC_paging_cs_sig_bvci), testcasename(), 16);
Harald Welte0e188242020-11-22 21:46:48 +01002451 f_cleanup();
2452}
2453
Harald Welte7462a592020-11-23 22:07:07 +01002454/* CS-PAGING on SIG-BVC for unknown BVCI */
2455private function f_TC_paging_cs_sig_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
2456{
2457 f_send_paging_cs_exp_no_bss(ts_BssgpP4Bvci(33333), 0, true);
2458}
2459testcase TC_paging_cs_sig_bvci_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002460 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002461 f_start_handlers(refers(f_TC_paging_cs_sig_bvci_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002462 f_cleanup();
2463}
2464
Harald Welte4f91c3b2020-12-09 12:25:51 +01002465/***********************************************************************
2466 * FLUSH-LL procedure
2467 ***********************************************************************/
2468
Daniel Willmannc7c8e322021-11-25 18:13:21 +01002469private function f_TC_flush_ll_bvci_new(charstring id) runs on BSSGP_ConnHdlr {
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002470 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
2471 var integer i;
2472 for (i := 0; i < 10; i := i+1) {
2473 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_FLUSH_LL(g_pars.tlli, bvci, bvci_new := bvci);
2474 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2475 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_FLUSH_LL(g_pars.tlli, bvci, bvci_new := bvci);
2476
2477 f_sgsn2pcu(pdu_tx, pdu_rx, use_sig := true);
2478
Daniel Willmannc7c8e322021-11-25 18:13:21 +01002479 pdu_tx := ts_BSSGP_FLUSH_LL_ACK(g_pars.tlli, int2oct(1, 1), 23, bvci_new := bvci);
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002480 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Daniel Willmannc7c8e322021-11-25 18:13:21 +01002481 pdu_rx := tr_BSSGP_FLUSH_LL_ACK(g_pars.tlli, int2oct(1, 1), 23, bvci_new := bvci);
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002482
2483 f_pcu2sgsn(pdu_tx, pdu_rx, use_sig := true);
2484 }
2485 setverdict(pass);
2486}
Daniel Willmannc7c8e322021-11-25 18:13:21 +01002487
2488testcase TC_flush_ll_bvci_new() runs on test_CT
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002489{
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002490 f_init();
Daniel Willmannc7c8e322021-11-25 18:13:21 +01002491 f_start_handlers(refers(f_TC_flush_ll_bvci_new), testcasename(), 6);
2492 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
2493 f_cleanup();
2494}
2495
2496private function f_TC_flush_ll_no_bvci_new(charstring id) runs on BSSGP_ConnHdlr {
2497 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
2498 var integer i;
2499 for (i := 0; i < 10; i := i+1) {
2500 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_FLUSH_LL(g_pars.tlli, bvci);
2501 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2502 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_FLUSH_LL(g_pars.tlli, bvci);
2503
2504 f_sgsn2pcu(pdu_tx, pdu_rx, use_sig := true);
2505
2506 pdu_tx := ts_BSSGP_FLUSH_LL_ACK(g_pars.tlli, int2oct(0, 1), 23);
2507 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2508 pdu_rx := tr_BSSGP_FLUSH_LL_ACK(g_pars.tlli, int2oct(0, 1), 23);
2509
2510 f_pcu2sgsn(pdu_tx, pdu_rx, use_sig := true);
2511 }
2512 setverdict(pass);
2513}
2514
2515testcase TC_flush_ll_no_bvci_new() runs on test_CT
2516{
2517 f_init();
2518 f_start_handlers(refers(f_TC_flush_ll_no_bvci_new), testcasename(), 6);
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002519 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002520 f_cleanup();
2521}
Harald Welte6dc2ac42020-11-16 09:16:17 +01002522
Harald Welte4f91c3b2020-12-09 12:25:51 +01002523/***********************************************************************
2524 * SGSN-INVOKE-TRACE procedure
2525 ***********************************************************************/
2526
Harald Weltef8e5c5d2020-11-27 22:37:23 +01002527private altstep as_bssgp_g_pcu_count(integer pcu_idx, template (present) PDU_BSSGP exp_rx, inout ro_integer roi)
2528runs on GlobalTest_CT {
2529[] G_PCU[pcu_idx].receive(exp_rx) from g_pcu[pcu_idx].vc_BSSGP {
2530 if (ro_integer_contains(roi, pcu_idx)) {
2531 setverdict(fail, "Received multiple on same SIG BVC");
2532 }
2533 roi := roi & { pcu_idx };
2534 repeat;
2535 }
2536}
2537/* send a INVOKE-TRACE from SGSN and expect to receive a copy on each NSE */
2538testcase TC_trace() runs on GlobalTest_CT
2539{
2540 var BSSGP_ConnHdlr vc_conn;
2541 f_init();
2542 f_global_init();
2543
2544 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_INVOKE_TRACE('23'O, '4321'O);
2545 var template (present) PDU_BSSGP exp_rx := ts_BSSGP_INVOKE_TRACE('23'O, '4321'O);
2546
2547 var ro_default defaults := {};
2548 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2549 activate(as_bssgp_g_pcu_count(i, exp_rx, g_roi));
2550 }
2551 G_SGSN[0].send(pdu_tx);
2552 f_sleep(2.0);
2553 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2554 deactivate(defaults[i]);
2555 }
2556
2557 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2558 if (not ro_integer_contains(g_roi, i)) {
2559 setverdict(fail, "Failed to receive TRACE on PCU index ", i);
2560 }
2561 }
2562 setverdict(pass);
2563
2564 f_cleanup();
2565}
2566
Harald Welte4f91c3b2020-12-09 12:25:51 +01002567/***********************************************************************
2568 * LLC-DISCARDED procedure
2569 ***********************************************************************/
2570
Harald Weltec0351d12020-11-27 22:49:02 +01002571private function f_TC_llc_discarded(charstring id) runs on BSSGP_ConnHdlr {
2572 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
2573
2574 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_LLC_DISCARDED(g_pars.tlli, 23, bvci, 2342);
2575 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2576 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_LLC_DISCARDED(g_pars.tlli, 23, bvci, 2342);
2577
2578 f_pcu2sgsn(pdu_tx, pdu_rx, use_sig := true);
2579
2580 setverdict(pass);
2581}
2582/* Send a LLC-DISCARDED from BSS side and expect it to show up on SGSN (SIG BVC) */
2583testcase TC_llc_discarded() runs on test_CT
2584{
Harald Weltec0351d12020-11-27 22:49:02 +01002585 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002586 f_start_handlers(refers(f_TC_llc_discarded), testcasename(), 6);
Harald Weltec0351d12020-11-27 22:49:02 +01002587 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Weltec0351d12020-11-27 22:49:02 +01002588 f_cleanup();
2589}
2590
Harald Welte4f91c3b2020-12-09 12:25:51 +01002591/***********************************************************************
2592 * OVERLOAD procedure
2593 ***********************************************************************/
2594
Harald Weltef20af412020-11-28 16:11:11 +01002595/* Send an OVERLOAD from SGSN side and expect it to show up on each PCU (SIG BVC) */
2596testcase TC_overload() runs on GlobalTest_CT
2597{
2598 f_init();
2599 f_global_init();
2600
2601 var template (value) PDU_BSSGP pdu_tx := ts_OVERLOAD('1'B);
2602 var template (present) PDU_BSSGP exp_rx := tr_OVERLOAD('1'B);
2603
2604 var ro_default defaults := {};
2605 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2606 activate(as_bssgp_g_pcu_count(i, exp_rx, g_roi));
2607 }
2608 G_SGSN[0].send(pdu_tx);
2609 f_sleep(2.0);
2610 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2611 deactivate(defaults[i]);
2612 }
2613
2614 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2615 if (not ro_integer_contains(g_roi, i)) {
2616 setverdict(fail, "Failed to receive OVERLOAD on PCU index ", i);
2617 }
2618 }
2619 setverdict(pass);
2620
2621 f_cleanup();
2622}
2623
Harald Welte4f91c3b2020-12-09 12:25:51 +01002624/***********************************************************************
2625 * BVC-BLOCK / BVC-UNBLOCK procedure
2626 ***********************************************************************/
2627
Harald Welte239aa502020-11-24 23:14:20 +01002628private function f_block_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2629{
2630 var BSSGP_BVC_CT bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2631 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2632 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2633
2634 SGSN_MGMT.clear;
2635 PCU_MGMT.clear;
2636
2637 /* block the PTP BVC from the PCU side */
2638 PCU_MGMT.send(BssgpBlockRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to bvc_ct;
2639 /* expect state on both PCU and SGSN side to change */
2640 interleave {
2641 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_BLOCKED)) from bvc_ct;
Harald Welte572b0172021-03-30 13:19:56 +02002642 [] SGSN_MGMT.receive(tr_BssgpStsInd(mp_nsconfig_sgsn[0].nsei, bvc_cfg.bvci, BVC_S_BLOCKED));
2643 [] SGSN_MGMT.receive(tr_BssgpStsInd(mp_nsconfig_sgsn[1].nsei, bvc_cfg.bvci, BVC_S_BLOCKED));
2644 /* Doesn't auto-scale with NUM_SGSN */
Harald Welte239aa502020-11-24 23:14:20 +01002645 }
2646 setverdict(pass);
2647}
2648testcase TC_bvc_block_ptp() runs on test_CT
2649{
2650 f_init();
2651 f_sleep(1.0);
2652 f_block_ptp_bvc_from_pcu(0, 0);
2653 f_cleanup();
2654}
2655
2656private function f_unblock_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2657{
2658 var BSSGP_BVC_CT bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2659 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2660 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2661
2662 SGSN_MGMT.clear;
2663 PCU_MGMT.clear;
2664
2665 /* block the PTP BVC from the PCU side */
2666 PCU_MGMT.send(BssgpUnblockRequest:{}) to bvc_ct;
2667 /* expect state on both PCU and SGSN side to change */
2668 interleave {
2669 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_UNBLOCKED)) from bvc_ct;
Harald Welte572b0172021-03-30 13:19:56 +02002670 [] SGSN_MGMT.receive(tr_BssgpStsInd(mp_nsconfig_sgsn[0].nsei, bvc_cfg.bvci, BVC_S_UNBLOCKED));
2671 [] SGSN_MGMT.receive(tr_BssgpStsInd(mp_nsconfig_sgsn[1].nsei, bvc_cfg.bvci, BVC_S_UNBLOCKED));
2672 /* Doesn't auto-scale with NUM_SGSN */
Harald Welte239aa502020-11-24 23:14:20 +01002673 }
2674 setverdict(pass);
2675}
2676testcase TC_bvc_unblock_ptp() runs on test_CT
2677{
2678 f_init();
2679 f_sleep(1.0);
2680 f_block_ptp_bvc_from_pcu(0, 0);
2681 f_sleep(1.0);
2682 f_unblock_ptp_bvc_from_pcu(0, 0);
2683 f_cleanup();
2684}
2685
Harald Welte4f91c3b2020-12-09 12:25:51 +01002686/***********************************************************************
2687 * BVC-RESET procedure
2688 ***********************************************************************/
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002689private altstep as_count_bvc_reset(integer sgsn_idx, BssgpBvci bvci, inout roro_integer roroi)
2690runs on test_CT {
2691 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(sgsn_idx, bvci);
2692 [] SGSN_MGMT.receive(BssgpResetIndication:{bvci}) from sgsn_bvc_ct {
2693 roroi[sgsn_idx] := roroi[sgsn_idx] & { bvci };
2694 repeat;
2695 }
2696}
Harald Welte60a8ec72020-11-25 17:12:53 +01002697private altstep as_ignore_status(BSSGP_BVC_MGMT_PT pt) {
2698[] pt.receive(BssgpStatusIndication:?) { repeat; }
2699}
2700private function f_get_sgsn_bvc_ct(integer sgsn_idx, BssgpBvci bvci) runs on test_CT return BSSGP_BVC_CT {
2701 for (var integer i := 0; i < lengthof(g_sgsn[sgsn_idx].cfg.bvc); i := i+1) {
2702 if (g_sgsn[sgsn_idx].cfg.bvc[i].bvci == bvci) {
2703 return g_sgsn[sgsn_idx].vc_BSSGP_BVC[i];
2704 }
2705 }
2706 return null;
2707}
2708private function f_reset_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2709{
2710 var BSSGP_BVC_CT pcu_bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2711 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2712 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002713 var ro_default defaults;
2714 var integer i;
Harald Welte60a8ec72020-11-25 17:12:53 +01002715
2716 SGSN_MGMT.clear;
2717 PCU_MGMT.clear;
2718
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002719 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
2720 g_roroi[i] := {};
2721 }
2722
Harald Welte60a8ec72020-11-25 17:12:53 +01002723 /* block the PTP BVC from the PCU side */
2724 PCU_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to pcu_bvc_ct;
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002725
Harald Welte60a8ec72020-11-25 17:12:53 +01002726 /* expect state on both PCU and SGSN side to change */
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002727 defaults := { activate(as_ignore_status(SGSN_MGMT)) };
2728
2729 /* Activate altsteps: One for each SGSN */
2730 for (i := 0; i < lengthof(g_sgsn); i := i+1) {
2731 var default d := activate(as_count_bvc_reset(i, bvc_cfg.bvci, g_roroi));
2732 defaults := defaults & { d };
Harald Welte60a8ec72020-11-25 17:12:53 +01002733 }
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002734
2735 timer T := 3.0;
2736 T.start;
2737 alt {
2738 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_BLOCKED)) from pcu_bvc_ct {
2739 g_roi := g_roi & { bvc_cfg.bvci };
2740 repeat;
2741 }
2742 [] T.timeout;
2743 }
2744
2745 for (i := 0; i < lengthof(defaults); i := i+1) {
2746 deactivate(defaults[i]);
2747 }
2748
2749 /* Check if BVC-RESET was received at all SGSNs */
2750 for (i := 0; i < lengthof(g_sgsn); i := i+1) {
2751 if (not ro_integer_contains(g_roroi[i], bvc_cfg.bvci)) {
2752 setverdict(fail, "Missing SGSN[", i, "] BVC-BLOCK of BVCI=", bvc_cfg.bvci);
2753 }
2754 }
2755
Harald Welte60a8ec72020-11-25 17:12:53 +01002756 setverdict(pass);
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002757 f_cleanup();
Harald Welte60a8ec72020-11-25 17:12:53 +01002758}
2759/* Send a BVC-RESET for a PTP BVC from the BSS side: expect it to propagate */
2760testcase TC_bvc_reset_ptp_from_bss() runs on test_CT
2761{
2762 f_init();
2763 f_sleep(3.0);
2764 f_reset_ptp_bvc_from_pcu(0, 0);
2765 f_cleanup();
2766}
2767
Harald Welteb1cc0b22021-03-30 12:16:36 +02002768private altstep as_count_bvc_sts(integer sgsn_idx, BssgpBvci bvci,
2769 template (present) BvcState exp_bvc_state, inout roro_integer roroi)
Harald Welte16786e92020-11-27 19:11:56 +01002770runs on test_CT {
2771 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(sgsn_idx, bvci);
Harald Welteb1cc0b22021-03-30 12:16:36 +02002772 [] SGSN_MGMT.receive(tr_BssgpStsInd(?, bvci, exp_bvc_state)) from sgsn_bvc_ct {
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002773 roroi[sgsn_idx] := roroi[sgsn_idx] & { bvci };
Harald Welteb2647f72020-12-07 14:36:35 +01002774 repeat;
Harald Welte16786e92020-11-27 19:11:56 +01002775 }
2776}
Harald Welteb1cc0b22021-03-30 12:16:36 +02002777
2778private altstep as_count_bvc_block(integer sgsn_idx, BssgpBvci bvci, inout roro_integer roroi)
2779runs on test_CT {
2780 [] as_count_bvc_sts(sgsn_idx, bvci, BVC_S_BLOCKED, roroi);
2781}
2782
2783private altstep as_count_bvc_unblock(integer sgsn_idx, BssgpBvci bvci, inout roro_integer roroi)
2784runs on test_CT {
2785 [] as_count_bvc_sts(sgsn_idx, bvci, BVC_S_UNBLOCKED, roroi);
2786}
2787
Harald Welte16786e92020-11-27 19:11:56 +01002788/* reset the signaling BVC from one BSS; expect no signaling BVC reset on SGSN; but BVC-BLOCK for PTP */
2789testcase TC_bvc_reset_sig_from_bss() runs on test_CT {
2790
2791 f_init();
2792 f_sleep(3.0);
2793
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002794 for (var integer i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
2795 g_roroi[i] := {};
2796 }
2797
Harald Welte16786e92020-11-27 19:11:56 +01002798 /* Start BVC-RESET procedure for BVCI=0 */
2799 PCU_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to g_pcu[0].vc_BSSGP;
2800
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002801 /* Activate altsteps: One for each PTP BVC and SGSN within that PCUs NSE */
Harald Welte16786e92020-11-27 19:11:56 +01002802 var ro_default defaults := {};
2803 for (var integer i := 0; i < lengthof(g_pcu[0].cfg.bvc); i := i+1) {
2804 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[i];
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002805 for (var integer j := 0; j < lengthof(g_sgsn); j := j+1) {
2806 var default d := activate(as_count_bvc_block(j, bvcc.bvci, g_roroi));
2807 defaults := defaults & { d };
2808 }
Harald Welte16786e92020-11-27 19:11:56 +01002809 }
2810
2811 timer T := 3.0;
2812 T.start;
2813 alt {
2814 [] SGSN_MGMT.receive(BssgpResetIndication:{0}) {
2815 setverdict(fail, "BSS-side Reset of BVCI=0 should not propagate");
2816 }
2817 [] T.timeout;
2818 }
2819
2820 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2821 deactivate(defaults[i]);
2822 }
2823
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002824 /* check if BVC-block was received on all expected BVC/SGSN */
Harald Welte16786e92020-11-27 19:11:56 +01002825 for (var integer i := 0; i < lengthof(g_pcu[0].cfg.bvc); i := i+1) {
2826 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[i];
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002827 for (var integer j := 0; j < lengthof(g_sgsn); j := j+1) {
2828 if (not ro_integer_contains(g_roroi[j], bvcc.bvci)) {
2829 setverdict(fail, "Missing SGSN[", j, "] BVC-BLOCK of BVCI=", bvcc.bvci);
2830 }
Harald Welte16786e92020-11-27 19:11:56 +01002831 }
2832 }
2833
2834 /* check if BVC-block was not received on any unexpected BVC is not required as
2835 * such a message would basically run into 'no matching clause' */
Daniel Willmannf2590212020-12-04 14:20:50 +01002836 setverdict(pass);
Harald Welte16786e92020-11-27 19:11:56 +01002837 f_cleanup();
2838}
2839
Harald Welte60a8ec72020-11-25 17:12:53 +01002840private function f_reset_ptp_bvc_from_sgsn(integer pcu_idx, integer bvc_idx) runs on test_CT
2841{
2842 var BSSGP_BVC_CT pcu_bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2843 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2844 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2845 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(0, bvc_cfg.bvci);
2846 var default d;
2847
2848 SGSN_MGMT.clear;
2849 PCU_MGMT.clear;
2850
2851 /* block the PTP BVC from the PCU side */
2852 SGSN_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to sgsn_bvc_ct;
2853 /* expect state on both PCU and SGSN side to change */
2854 d := activate(as_ignore_status(PCU_MGMT));
2855 interleave {
2856 [] SGSN_MGMT.receive(tr_BssgpStsInd(?, bvc_cfg.bvci, BVC_S_BLOCKED)) from sgsn_bvc_ct;
2857 [] PCU_MGMT.receive(BssgpResetIndication:{bvc_cfg.bvci}) from pcu_bvc_ct;
2858 }
2859 deactivate(d);
2860 setverdict(pass);
2861}
Daniel Willmannc5bbcc62021-09-24 13:17:20 +02002862
Harald Welte60a8ec72020-11-25 17:12:53 +01002863/* Send a BVC-RESET for a PTP BVC from the SGSN side: expect it to propagate */
2864testcase TC_bvc_reset_ptp_from_sgsn() runs on test_CT
2865{
2866 f_init();
2867 f_sleep(3.0);
2868 f_reset_ptp_bvc_from_sgsn(0, 0);
2869 f_cleanup();
2870}
2871
Daniel Willmannc5bbcc62021-09-24 13:17:20 +02002872/* Send a BVC-RESET for a blocked PTP BVC from the SGSN side: expect NS-STATUS with cause BVCI unknown */
2873testcase TC_bvc_reset_blocked_ptp_from_sgsn() runs on GlobalTest_CT
2874{
2875 f_init();
2876 f_global_init();
2877 f_sleep(3.0);
2878 /* Make sure NS for BVC is down and try again */
2879 f_disable_ns_pcu(0);
2880 f_sleep(10.0);
2881
2882 var BssgpBvcConfig bvc_cfg := g_pcu[0].cfg.bvc[0];
2883 SGSN_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to f_get_sgsn_bvc_ct(0, bvc_cfg.bvci);
2884
2885 /* Check for NS-STATUS with BVCI unknown, ignore other messages */
2886 var template (present) PDU_BSSGP exp_rx :=
2887 tr_BSSGP_STATUS(bvc_cfg.bvci, BSSGP_CAUSE_BVCI_UNKNOWN, ?);
2888
2889 alt {
2890 [] G_SGSN[0].receive(exp_rx) {
2891 setverdict(pass);
2892 }
2893 [] SGSN_MGMT.receive(BssgpStatusIndication:{*, bvc_cfg.bvci, BVC_S_UNBLOCKED}) {
2894 setverdict(fail, "BVC unblocked that should be gone on BSS side");
2895 }
2896 [] SGSN_MGMT.receive {
2897 repeat;
2898 }
2899 [] G_SGSN[0].receive {
2900 repeat;
2901 }
2902 }
2903
2904 f_cleanup();
2905}
2906
Daniel Willmannef7015f2021-01-08 00:43:56 +01002907private altstep as_ignore_mgmt(BSSGP_BVC_MGMT_PT pt) {
2908 [] pt.receive {repeat; }
2909}
2910
Harald Welte16786e92020-11-27 19:11:56 +01002911private altstep as_count_bvc0_block(integer pcu_idx, Nsei nsei, inout ro_integer roi)
2912runs on test_CT {
2913 var BSSGP_CT pcu_ct := g_pcu[pcu_idx].vc_BSSGP;
2914 [] PCU_MGMT.receive(BssgpResetIndication:{0}) from pcu_ct {
2915 roi := roi & { nsei };
Daniel Willmannef7015f2021-01-08 00:43:56 +01002916 repeat;
Harald Welte16786e92020-11-27 19:11:56 +01002917 }
2918}
Daniel Willmannef7015f2021-01-08 00:43:56 +01002919
Harald Welte16786e92020-11-27 19:11:56 +01002920/* reset the signaling BVC from the SGSN; expect all signaling BVC on all BSS to be reset */
2921testcase TC_bvc_reset_sig_from_sgsn() runs on test_CT {
2922
2923 f_init();
2924 f_sleep(3.0);
2925
Daniel Willmannef7015f2021-01-08 00:43:56 +01002926 SGSN_MGMT.clear;
2927 PCU_MGMT.clear;
2928
Harald Welte16786e92020-11-27 19:11:56 +01002929 /* Start BVC-RESET procedure for BVCI=0 */
2930 SGSN_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to g_sgsn[0].vc_BSSGP;
2931
Daniel Willmannef7015f2021-01-08 00:43:56 +01002932 /* Defaults match in reverse activation order, this one is a catch-all for Status indications
2933 * and reset indications sent from other components (like the ptp_bvcs). If we don't drain
2934 * the port and a different message sits at the front we wait forever and fail the test.
2935 */
2936 var ro_default defaults := { activate(as_ignore_mgmt(PCU_MGMT)) };
2937
Harald Welte16786e92020-11-27 19:11:56 +01002938 /* Activate altsteps: One for each PCU NSE */
Harald Welte16786e92020-11-27 19:11:56 +01002939 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2940 var NSConfiguration nscfg := mp_nsconfig_pcu[i];
2941 var default d := activate(as_count_bvc0_block(i, nscfg.nsei, g_roi));
2942 defaults := defaults & { d };
2943 }
2944
2945 f_sleep(3.0);
2946
2947 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2948 deactivate(defaults[i]);
2949 }
2950
2951 /* check if BVC-block was received on all expected BVC */
2952 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2953 var NSConfiguration nscfg := mp_nsconfig_pcu[i];
2954 if (not ro_integer_contains(g_roi, nscfg.nsei)) {
2955 setverdict(fail, "Missing PCU-side BVC-RESET of BVCI=0 on PCU index ", i);
2956 }
2957 }
2958
2959 /* check if BVC-block was not received on any unexpected BVC is not required as
2960 * such a message would basically run into 'no matching clause' */
2961
2962 f_cleanup();
2963}
2964
Harald Welte299aa482020-12-09 15:10:55 +01002965/***********************************************************************
2966 * FLOW-CONTROL-BVC procedure
2967 ***********************************************************************/
2968
2969private altstep as_g_count_sgsn(integer sgsn_idx, inout ro_integer roi,
2970 template PDU_BSSGP exp_rx, template (omit) PDU_BSSGP tx_reply)
2971runs on GlobalTest_CT {
2972 [] G_SGSN[sgsn_idx].receive(exp_rx) {
2973 roi := roi & { sgsn_idx };
2974 if (ispresent(tx_reply)) {
2975 G_SGSN[sgsn_idx].send(tx_reply);
2976 }
Harald Welte5fb01742021-01-15 21:07:52 +01002977 repeat;
Harald Welte299aa482020-12-09 15:10:55 +01002978 }
2979}
2980/* Send FC-BVC from simulated PCU; expect each SGSN to receive it; expect PCU to receive ACK */
2981testcase TC_fc_bvc() runs on GlobalTest_CT
2982{
2983 f_init();
2984 f_global_init_ptp();
2985
Pau Espin Pedrol6ee01262021-02-05 13:05:06 +01002986 var template (value) PDU_BSSGP pdu_tx := ts_BVC_FC_BVC(10240, 2000, 1024, 1000, '01'O);
Harald Welte299aa482020-12-09 15:10:55 +01002987 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2988 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 +01002989 var template (value) PDU_BSSGP ack_tx :=
2990 ts_BVC_FC_BVC_ACK(pdu_tx.pDU_BSSGP_FLOW_CONTROL_BVC.tag.unstructured_Value);
Harald Welte299aa482020-12-09 15:10:55 +01002991
2992 /* Send a FC-BVC from BSS to gbproxy, expect an ACK in response */
2993 G_PCU[0].send(pdu_tx);
2994
2995 /* Activate altsteps: One for each SGSN-side PTP BVC port */
2996 var ro_default defaults := {};
2997 for (var integer i := 0; i < lengthof(g_sgsn); i := i+1) {
2998 var default d := activate(as_g_count_sgsn(i, g_roi, pdu_rx, ack_tx));
2999 defaults := defaults & { d };
3000 }
3001
3002 f_sleep(3.0);
3003
3004 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
3005 deactivate(defaults[i]);
3006 }
3007
3008 /* check if BVC-block was received on all expected BVC */
3009 for (var integer i := 0; i < lengthof(g_sgsn); i := i+1) {
3010 if (not ro_integer_contains(g_roi, i)) {
3011 setverdict(fail, "Missing BVC-FLOW-CONTROL on SGSN index ", i);
3012 }
3013 }
3014
3015 /* Expect ACK on PCU side */
3016 G_PCU[0].receive(ack_tx);
3017
3018 setverdict(pass);
3019
3020 f_cleanup();
3021}
3022
Harald Weltecc3894b2020-12-09 16:50:12 +01003023/***********************************************************************
3024 * FLOW-CONTROL-MS procedure
3025 ***********************************************************************/
3026
3027private function f_TC_fc_ms(charstring id) runs on BSSGP_ConnHdlr {
3028 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
3029
3030 var template (value) PDU_BSSGP fc_tx := ts_BVC_FC_MS(g_pars.tlli, 100, 200, '12'O);
3031 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
3032 var template (present) PDU_BSSGP fc_rx := tr_BVC_FC_MS(g_pars.tlli, 100, 200, '12'O);
3033 var template (value) PDU_BSSGP ack_tx := ts_BVC_FC_MS_ACK(g_pars.tlli, '12'O);
3034
3035 f_pcu2sgsn(fc_tx, fc_rx, use_sig := false);
3036 f_sgsn2pcu(ack_tx, ack_tx, use_sig := false);
3037
3038 setverdict(pass);
3039}
3040/* Send a FLOW-CONTROL-MS from BSS side and expect it to show up on SGSN (PTP BVC) */
3041testcase TC_fc_ms() runs on test_CT
3042{
Harald Weltecc3894b2020-12-09 16:50:12 +01003043 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01003044 f_start_handlers(refers(f_TC_fc_ms), testcasename(), 21);
Harald Weltecc3894b2020-12-09 16:50:12 +01003045 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Weltecc3894b2020-12-09 16:50:12 +01003046 f_cleanup();
3047}
3048
Harald Welted6f89812021-01-16 18:57:49 +01003049/***********************************************************************
3050 * MS-REGISTRATION ENQUIRY procedure
3051 ***********************************************************************/
Harald Weltecc3894b2020-12-09 16:50:12 +01003052
Harald Welted6f89812021-01-16 18:57:49 +01003053private function f_TC_ms_reg_enq(charstring id) runs on BSSGP_ConnHdlr
3054{
Daniel Willmann04918c02021-07-06 13:59:04 +02003055 f_pcu2any_sgsn(ts_BSSGP_MS_REG_ENQ(g_pars.imsi), tr_BSSGP_MS_REG_ENQ(g_pars.imsi), use_sig := true);
Harald Welted6f89812021-01-16 18:57:49 +01003056 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);
3057}
3058testcase TC_ms_reg_enq() runs on test_CT
3059{
3060 f_init();
3061 f_start_handlers(refers(f_TC_ms_reg_enq), testcasename(), 22);
3062 f_cleanup();
3063}
Harald Welte299aa482020-12-09 15:10:55 +01003064
Harald Weltef86f1852021-01-16 21:56:17 +01003065/***********************************************************************
3066 * RIM (RAN Information Management)
3067 ***********************************************************************/
3068
3069/* Our tests here are rather synthetic, as they don't reflect normal message flows
3070 as they would be observed in a live network. However, for testing gbproxy, this shouldn't
3071 matter as gbproxy is not concerned with anything but the source / destination routing
3072 information */
3073
3074/* gbproxy must route all unknown RIM Routing Info (Cell Id) to the SGSN. We just define
3075 one here of which we know it is not used among the [simulated] PCUs */
3076const BssgpCellId cell_id_sgsn := {
3077 ra_id := {
3078 lai := {
3079 mcc_mnc := c_mcc_mnc,
3080 lac := 65534
3081 },
3082 rac := 0
3083 },
3084 cell_id := 65533
3085};
3086
3087/* Send 'tx' on PTP-BVCI from PCU; expect 'rx' on any of our SGSN (RIM can be routed anywhere) */
3088friend function f_rim_pcu2sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
3089 integer pcu_idx := 0) runs on GlobalTest_CT {
3090 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +01003091 timer T := 2.0;
Harald Weltef86f1852021-01-16 21:56:17 +01003092
3093 RIM_PCU[pcu_idx].send(tx);
3094 T.start;
3095 alt {
3096 [] any from RIM_SGSN.receive(exp_rx) {
3097 setverdict(pass);
3098 }
3099 [] any from RIM_SGSN.receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +01003100 f_shutdown(__FILE__, __LINE__, fail, log2str("Unexpected BSSGP on SGSN side: ", rx));
Harald Weltef86f1852021-01-16 21:56:17 +01003101 }
3102 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +01003103 f_shutdown(__FILE__, __LINE__, fail,
3104 log2str("Timeout waiting for BSSGP on SGSN side: ", exp_rx));
Harald Weltef86f1852021-01-16 21:56:17 +01003105 }
3106 }
3107}
3108
3109/* Send 'tx' on PTP-BVCI from SGSN; expect 'rx' on PCU */
3110friend function f_rim_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
3111 integer sgsn_idx := 0, integer pcu_idx := 0) runs on GlobalTest_CT {
3112 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +01003113 timer T := 2.0;
Harald Weltef86f1852021-01-16 21:56:17 +01003114
3115 RIM_SGSN[sgsn_idx].send(tx);
3116 T.start;
3117 alt {
3118 [] RIM_PCU[pcu_idx].receive(exp_rx) {
3119 setverdict(pass);
3120 }
3121 [] RIM_PCU[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +01003122 f_shutdown(__FILE__, __LINE__, fail, log2str("Unexpected BSSGP on PCU side: ", rx));
Harald Weltef86f1852021-01-16 21:56:17 +01003123 }
3124 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +01003125 f_shutdown(__FILE__, __LINE__, fail,
3126 log2str("Timeout waiting for BSSGP on PCU side: ", exp_rx));
Harald Weltef86f1852021-01-16 21:56:17 +01003127 }
3128 }
3129}
3130
3131/* Send 'tx' on PTP-BVCI from SRC-PCU; expect 'rx' on DST-PCU */
3132friend function f_rim_pcu2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
3133 integer src_pcu_idx, integer dst_pcu_idx) runs on GlobalTest_CT {
3134 var integer rx_idx;
3135 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +01003136 timer T := 2.0;
Harald Weltef86f1852021-01-16 21:56:17 +01003137
3138 RIM_PCU[src_pcu_idx].send(tx);
3139 T.start;
3140 alt {
3141 [] RIM_PCU[dst_pcu_idx].receive(exp_rx) -> value rx{
3142 setverdict(pass);
3143 }
3144 [] any from RIM_PCU.receive(exp_rx) -> @index value rx_idx {
3145 setverdict(fail, "Received RIM on wrong PCU[", rx_idx ,"], expected on PCU[", dst_pcu_idx, "]");
3146 }
3147 [] any from RIM_SGSN.receive(exp_rx) {
3148 setverdict(fail, "Received RIM on SGSN but expected it on other PCU");
3149 }
3150 [] any from RIM_SGSN.receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +01003151 f_shutdown(__FILE__, __LINE__, fail, log2str("Unexpected BSSGP on SGSN side: ", rx));
Harald Weltef86f1852021-01-16 21:56:17 +01003152 }
3153 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +01003154 f_shutdown(__FILE__, __LINE__, fail,
3155 log2str("Timeout waiting for BSSGP on SGSN side: ", exp_rx));
Harald Weltef86f1852021-01-16 21:56:17 +01003156 }
3157 }
3158}
3159
3160
3161type function rim_fn(integer sgsn_idx, integer pcu_idx, integer bvc_idx) runs on GlobalTest_CT;
3162
3163/* helper function for the RIM test cases: Execute 'fn' for each BVC on each PCU for
3164 each SGSN */
3165private function f_rim_iterator(rim_fn fn) runs on GlobalTest_CT
3166{
3167 var integer sgsn_idx, pcu_idx, bvc_idx;
3168 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx+1) {
3169 for (pcu_idx := 0; pcu_idx < lengthof(g_pcu); pcu_idx := pcu_idx+1) {
3170 for (bvc_idx := 0; bvc_idx < lengthof(g_pcu[pcu_idx].cfg.bvc); bvc_idx := bvc_idx+1) {
3171 log("Testing RIM SGSN[", sgsn_idx, "] <-> PCU[", pcu_idx, "][", bvc_idx, "]");
3172 fn.apply(sgsn_idx, pcu_idx, bvc_idx);
3173 }
3174 }
3175 }
3176}
3177
3178/* RAN-INFORMATION-REQUEST */
3179private function f_TC_rim_info_req(integer sgsn_idx, integer pcu_idx, integer bvc_idx := 0)
3180runs on GlobalTest_CT
3181{
3182 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003183 var template (value) RAN_Information_Request_RIM_Container cont_tx;
3184 var template RAN_Information_Request_RIM_Container cont_rx;
3185 var template RIM_Routing_Address ra_pcu;
3186 var template RIM_Routing_Address ra_sgsn;
Harald Weltef86f1852021-01-16 21:56:17 +01003187
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003188 ra_pcu := t_RIM_Routing_Address_cid(cell_id);
3189 ra_sgsn := t_RIM_Routing_Address_cid(cell_id_sgsn);
3190
3191 cont_tx := ts_RAN_Information_Request_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3192 ts_RIM_Sequence_Number(0),
3193 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
3194 cont_rx := tr_RAN_Information_Request_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
3195 tr_RIM_Sequence_Number(0),
3196 tr_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
3197
3198 f_rim_pcu2sgsn(ts_RAN_INFORMATION_REQUEST(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3199 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3200 cont := cont_tx),
3201 tr_RAN_INFORMATION_REQUEST(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3202 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3203 cont := cont_rx),
3204 pcu_idx);
3205
3206 f_rim_sgsn2pcu(ts_RAN_INFORMATION_REQUEST(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3207 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3208 cont := cont_tx),
3209 tr_RAN_INFORMATION_REQUEST(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3210 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3211 cont := cont_rx),
Harald Weltef86f1852021-01-16 21:56:17 +01003212 sgsn_idx, pcu_idx);
3213}
3214testcase TC_rim_info_req() runs on GlobalTest_CT
3215{
3216 f_init();
3217 f_global_init();
3218 f_rim_iterator(refers(f_TC_rim_info_req));
3219 f_cleanup();
3220}
3221
3222/* RAN-INFORMATION */
3223private function f_TC_rim_info(integer sgsn_idx, integer pcu_idx, integer bvc_idx := 0)
3224runs on GlobalTest_CT
3225{
3226 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003227 var template (value) RAN_Information_RIM_Container cont_tx;
3228 var template RAN_Information_RIM_Container cont_rx;
3229 var template RIM_Routing_Address ra_pcu;
3230 var template RIM_Routing_Address ra_sgsn;
Harald Weltef86f1852021-01-16 21:56:17 +01003231
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003232 ra_pcu := t_RIM_Routing_Address_cid(cell_id);
3233 ra_sgsn := t_RIM_Routing_Address_cid(cell_id_sgsn);
3234
3235 cont_tx := ts_RAN_Information_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3236 ts_RIM_Sequence_Number(0),
3237 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
3238
3239 cont_rx := tr_RAN_Information_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
3240 tr_RIM_Sequence_Number(0),
3241 tr_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
3242
3243 f_rim_pcu2sgsn(ts_PDU_BSSGP_RAN_INFORMATION(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3244 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3245 cont := cont_tx),
3246 tr_PDU_BSSGP_RAN_INFORMATION(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3247 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3248 cont := cont_rx),
3249 pcu_idx);
3250
3251 f_rim_sgsn2pcu(ts_PDU_BSSGP_RAN_INFORMATION(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3252 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3253 cont := cont_tx),
3254 tr_PDU_BSSGP_RAN_INFORMATION(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3255 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3256 cont := cont_rx),
Harald Weltef86f1852021-01-16 21:56:17 +01003257 sgsn_idx, pcu_idx);
3258}
3259testcase TC_rim_info() runs on GlobalTest_CT
3260{
3261 f_init();
3262 f_global_init();
3263 f_rim_iterator(refers(f_TC_rim_info));
3264 f_cleanup();
3265}
3266
3267/* RAN-INFORMATION-ACK */
3268private function f_TC_rim_info_ack(integer sgsn_idx, integer pcu_idx, integer bvc_idx := 0)
3269runs on GlobalTest_CT
3270{
3271 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003272 var template (value) RAN_Information_Ack_RIM_Container cont_tx;
3273 var template RAN_Information_Ack_RIM_Container cont_rx;
3274 var template RIM_Routing_Address ra_pcu;
3275 var template RIM_Routing_Address ra_sgsn;
Harald Weltef86f1852021-01-16 21:56:17 +01003276
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003277 ra_pcu := t_RIM_Routing_Address_cid(cell_id);
3278 ra_sgsn := t_RIM_Routing_Address_cid(cell_id_sgsn);
3279
3280 cont_tx := ts_RAN_Information_Ack_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3281 ts_RIM_Sequence_Number(0));
3282
3283 cont_rx := tr_RAN_Information_Ack_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
3284 tr_RIM_Sequence_Number(0));
3285
3286 f_rim_pcu2sgsn(ts_PDU_BSSGP_RAN_INFORMATION_ACK(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3287 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3288 cont := cont_tx),
3289 tr_PDU_BSSGP_RAN_INFORMATION_ACK(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3290 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3291 cont := cont_rx),
3292 pcu_idx);
3293
3294 f_rim_sgsn2pcu(ts_PDU_BSSGP_RAN_INFORMATION_ACK(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3295 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3296 cont := cont_tx),
3297 tr_PDU_BSSGP_RAN_INFORMATION_ACK(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3298 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3299 cont := cont_rx),
Harald Weltef86f1852021-01-16 21:56:17 +01003300 sgsn_idx, pcu_idx);
3301}
3302testcase TC_rim_info_ack() runs on GlobalTest_CT
3303{
3304 f_init();
3305 f_global_init();
3306 f_rim_iterator(refers(f_TC_rim_info_ack));
3307 f_cleanup();
3308}
3309
3310/* RAN-INFORMATION-ERROR */
3311private function f_TC_rim_info_error(integer sgsn_idx, integer pcu_idx, integer bvc_idx := 0)
3312runs on GlobalTest_CT
3313{
3314 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003315 var template (value) RAN_Information_Error_RIM_Container cont_tx;
3316 var template RAN_Information_Error_RIM_Container cont_rx;
3317 var template RIM_Routing_Address ra_pcu;
3318 var template RIM_Routing_Address ra_sgsn;
Harald Weltef86f1852021-01-16 21:56:17 +01003319
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003320 ra_pcu := t_RIM_Routing_Address_cid(cell_id);
3321 ra_sgsn := t_RIM_Routing_Address_cid(cell_id_sgsn);
3322
3323 cont_tx := ts_RAN_Information_Error_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3324 ts_BSSGP_CAUSE(BSSGP_CAUSE_EQUIMENT_FAILURE),
Pau Espin Pedrol6ee01262021-02-05 13:05:06 +01003325 omit, valueof(ts_BVC_UNBLOCK(23)));
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003326
3327 cont_rx := tr_RAN_Information_Error_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
Pau Espin Pedrol6ee01262021-02-05 13:05:06 +01003328 ts_BSSGP_CAUSE(BSSGP_CAUSE_EQUIMENT_FAILURE),
3329 omit, enc_PDU_BSSGP(valueof(tr_BVC_UNBLOCK(23))));
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003330
3331 f_rim_pcu2sgsn(ts_PDU_BSSGP_RAN_INFORMATION_ERROR(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3332 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3333 cont := cont_tx),
3334 tr_PDU_BSSGP_RAN_INFORMATION_ERROR(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3335 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3336 cont := cont_rx),
3337 pcu_idx);
3338
3339 f_rim_sgsn2pcu(ts_PDU_BSSGP_RAN_INFORMATION_ERROR(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3340 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3341 cont := cont_tx),
3342 tr_PDU_BSSGP_RAN_INFORMATION_ERROR(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3343 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3344 cont := cont_rx),
Harald Weltef86f1852021-01-16 21:56:17 +01003345 sgsn_idx, pcu_idx);
3346}
3347testcase TC_rim_info_error() runs on GlobalTest_CT
3348{
3349 f_init();
3350 f_global_init();
3351 f_rim_iterator(refers(f_TC_rim_info_error));
3352 f_cleanup();
3353}
3354
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003355//////////////////
Harald Weltef86f1852021-01-16 21:56:17 +01003356/* RAN-INFORMATION-APPLICATION-ERROR */
3357private function f_TC_rim_info_app_error(integer sgsn_idx, integer pcu_idx, integer bvc_idx := 0)
3358runs on GlobalTest_CT
3359{
3360 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003361 var template (value) Application_Error_Container app_cont_tx;
3362 var template Application_Error_Container app_cont_rx;
3363 var template (value) RAN_Information_Application_Error_RIM_Container cont_tx;
3364 var template RAN_Information_Application_Error_RIM_Container cont_rx;
3365 var template RIM_Routing_Address ra_pcu;
3366 var template RIM_Routing_Address ra_sgsn;
Harald Weltef86f1852021-01-16 21:56:17 +01003367
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003368 ra_pcu := t_RIM_Routing_Address_cid(cell_id);
3369 ra_sgsn := t_RIM_Routing_Address_cid(cell_id_sgsn);
3370
3371 app_cont_tx := tsu_Application_Error_Container_NACC(cell_id, 23,
3372 tsu_Application_Container_IE_NACC_req(cell_id));
3373
3374 app_cont_rx := rsu_Application_Error_Container_NACC(cell_id, 23,
3375 rsu_Application_Container_IE_NACC_req(cell_id));
3376
3377 cont_tx := ts_RAN_Information_Application_Error_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3378 ts_RIM_Sequence_Number(0),
3379 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP),
3380 omit, app_cont_tx);
3381 cont_rx := tr_RAN_Information_Application_Error_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
3382 tr_RIM_Sequence_Number(0),
3383 tr_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP),
3384 omit, app_cont_rx);
3385
3386 f_rim_pcu2sgsn(ts_PDU_BSSGP_RAN_INFORMATION_APPLICATION_ERROR(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3387 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3388 cont := cont_tx),
3389 tr_PDU_BSSGP_RAN_INFORMATION_APPLICATION_ERROR(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3390 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3391 cont := cont_rx),
3392 pcu_idx);
3393
3394 f_rim_sgsn2pcu(ts_PDU_BSSGP_RAN_INFORMATION_APPLICATION_ERROR(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3395 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3396 cont := cont_tx),
3397 tr_PDU_BSSGP_RAN_INFORMATION_APPLICATION_ERROR(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3398 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3399 cont := cont_rx),
Harald Weltef86f1852021-01-16 21:56:17 +01003400 sgsn_idx, pcu_idx);
3401}
3402testcase TC_rim_info_app_error() runs on GlobalTest_CT
3403{
3404 f_init();
3405 f_global_init();
3406 f_rim_iterator(refers(f_TC_rim_info_app_error));
3407 f_cleanup();
3408}
3409
3410/* RAN-INFORMATION routing directly between PCUs, without SGSN involvement */
3411private function f_TC_rim_info_pcu2pcu(integer src_pcu_idx, integer src_bvc_idx,
3412 integer dst_pcu_idx, integer dst_bvc_idx)
3413runs on GlobalTest_CT
3414{
3415 var BssgpCellId cell_id_src := g_pcu[src_pcu_idx].cfg.bvc[src_bvc_idx].cell_id;
3416 var BssgpCellId cell_id_dst := g_pcu[dst_pcu_idx].cfg.bvc[dst_bvc_idx].cell_id;
Philipp Maier1bd60ce2021-02-10 18:25:50 +01003417 var template (value) RIM_Routing_Information ri_pcu_src_tx;
3418 var template (value) RIM_Routing_Information ri_pcu_dst_tx;
3419 var template RIM_Routing_Information ri_pcu_src_rx;
3420 var template RIM_Routing_Information ri_pcu_dst_rx;
3421 var template (value) RAN_Information_RIM_Container cont_tx;
3422 var template RAN_Information_RIM_Container cont_rx;
Harald Weltef86f1852021-01-16 21:56:17 +01003423
3424 log("Testing RIM PCU2PCU from PCU[", src_pcu_idx, "][", src_bvc_idx, "] to PCU[",
3425 dst_pcu_idx, "][", dst_bvc_idx, "]");
3426
Philipp Maier1bd60ce2021-02-10 18:25:50 +01003427 ri_pcu_src_tx := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID,
Harald Weltef86f1852021-01-16 21:56:17 +01003428 t_RIM_Routing_Address_cid(cell_id_src));
Philipp Maier1bd60ce2021-02-10 18:25:50 +01003429 ri_pcu_dst_tx := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID,
Harald Weltef86f1852021-01-16 21:56:17 +01003430 t_RIM_Routing_Address_cid(cell_id_dst));
Philipp Maier1bd60ce2021-02-10 18:25:50 +01003431 ri_pcu_src_rx := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID,
3432 t_RIM_Routing_Address_cid(cell_id_src));
3433 ri_pcu_dst_rx := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID,
3434 t_RIM_Routing_Address_cid(cell_id_dst));
3435
3436 cont_tx := ts_RAN_Information_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3437 ts_RIM_Sequence_Number(0),
3438 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
3439 cont_rx := tr_RAN_Information_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
3440 tr_RIM_Sequence_Number(0),
3441 tr_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
3442
3443 f_rim_pcu2pcu(ts_PDU_BSSGP_RAN_INFORMATION(dst := ri_pcu_dst_tx, src := ri_pcu_src_tx, cont := cont_tx),
3444 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 +01003445 src_pcu_idx, dst_pcu_idx);
3446}
3447testcase TC_rim_info_pcu2pcu() runs on GlobalTest_CT
3448{
3449 var integer src_pcu_idx, dst_pcu_idx;
3450 var integer src_bvc_idx, dst_bvc_idx;
3451 f_init();
3452 f_global_init();
3453
3454 for (src_pcu_idx := 0; src_pcu_idx < lengthof(g_pcu); src_pcu_idx := src_pcu_idx + 1) {
3455 for (src_bvc_idx := 0; src_bvc_idx < lengthof(g_pcu[src_pcu_idx].cfg.bvc); src_bvc_idx := src_bvc_idx + 1) {
3456 for (dst_pcu_idx := 0; dst_pcu_idx < lengthof(g_pcu); dst_pcu_idx := dst_pcu_idx + 1) {
3457 if (dst_pcu_idx == src_pcu_idx) {
3458 continue;
3459 }
3460
3461 for (dst_bvc_idx := 0; dst_bvc_idx < lengthof(g_pcu[dst_pcu_idx].cfg.bvc);
3462dst_bvc_idx := dst_bvc_idx + 1) {
3463 f_TC_rim_info_pcu2pcu(src_pcu_idx, src_bvc_idx, dst_pcu_idx, dst_bvc_idx);
3464 }
3465 }
3466 }
3467 }
3468
3469 f_cleanup();
3470}
3471
Pau Espin Pedrol40778e82021-05-07 13:20:58 +02003472
3473/* Test RIM REQ sent from an MME->SGSN->GBPROXY->PCU and back (eNACC) */
3474private function f_TC_rim_from_eutran(integer sgsn_idx, integer pcu_idx, integer bvc_idx := 0)
3475runs on GlobalTest_CT
3476{
3477 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
3478 var template (value) RAN_Information_Request_RIM_Container cont_tx;
3479 var template RAN_Information_Request_RIM_Container cont_rx;
3480 var template RIM_Routing_Address ra_pcu;
3481 var template RIM_Routing_Address ra_sgsn;
3482
3483 ra_pcu := t_RIM_Routing_Address_cid(cell_id);
3484 ra_sgsn := t_RIM_Routing_Address_enbid(cell_id_sgsn, tac := 3, gnbid := '12345678123456'O);
3485
3486 cont_tx := ts_RAN_Information_Request_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3487 ts_RIM_Sequence_Number(0),
3488 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
3489 cont_rx := tr_RAN_Information_Request_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
3490 tr_RIM_Sequence_Number(0),
3491 tr_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
3492
3493 f_rim_sgsn2pcu(ts_RAN_INFORMATION_REQUEST(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3494 src := ts_RIM_Routing_Information(RIM_ADDR_EUTRAN_NODEB_ID, ra_sgsn),
3495 cont := cont_tx),
3496 tr_RAN_INFORMATION_REQUEST(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3497 src := tr_RIM_Routing_Information(RIM_ADDR_EUTRAN_NODEB_ID, ra_sgsn),
3498 cont := cont_rx),
3499 sgsn_idx, pcu_idx);
3500
3501
3502 f_rim_pcu2sgsn(ts_RAN_INFORMATION_REQUEST(dst := ts_RIM_Routing_Information(RIM_ADDR_EUTRAN_NODEB_ID, ra_sgsn),
3503 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3504 cont := cont_tx),
3505 tr_RAN_INFORMATION_REQUEST(dst := tr_RIM_Routing_Information(RIM_ADDR_EUTRAN_NODEB_ID, ra_sgsn),
3506 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3507 cont := cont_rx),
3508 pcu_idx);
3509}
3510testcase TC_rim_from_eutran() runs on GlobalTest_CT
3511{
3512 f_init();
3513 f_global_init();
3514 f_rim_iterator(refers(f_TC_rim_from_eutran));
3515 f_cleanup();
3516}
3517
Harald Welte04358652021-01-17 13:48:13 +01003518/***********************************************************************
3519 * STATUS handling
3520 ***********************************************************************/
3521
3522/* BSSGP STATUS PDU must be routed based on inner "PDU In Error" message */
3523
3524/* generate a TMSI with NRI matching sgsn_idx + nri_idx */
3525private function f_gen_tmsi_for_sgsn_nri(integer sgsn_idx, integer nri_idx) runs on test_CT return OCT4
3526{
3527 var integer nri := mp_sgsn_nri[sgsn_idx][nri_idx];
3528 return f_gen_tmsi(0, nri_v := nri, nri_bitlen := mp_nri_bitlength);
3529}
3530
3531/* generate a TLLI with NRI matching sgsn_idx + nri_idx */
3532private function f_gen_tlli_for_sgsn_nri(integer sgsn_idx, integer nri_idx) runs on test_CT return OCT4
3533{
3534 var OCT4 p_tmsi := f_gen_tmsi_for_sgsn_nri(sgsn_idx, nri_idx);
3535 return f_gprs_tlli_from_tmsi(p_tmsi, TLLI_LOCAL);
3536}
3537
3538/* STATUS in uplink direction; expect routing by its NRI */
3539private function f_TC_status_ul(integer pcu_idx, integer sgsn_idx, PDU_BSSGP inner)
3540runs on GlobalTest_CT
3541{
3542 var template (value) PDU_BSSGP tx := ts_BSSGP_STATUS(omit, BSSGP_CAUSE_EQUIMENT_FAILURE, inner);
3543 var template (present) PDU_BSSGP exp_rx :=
3544 tr_BSSGP_STATUS(omit, BSSGP_CAUSE_EQUIMENT_FAILURE,
3545 tx.pDU_BSSGP_STATUS.pDU_in_Error.erroneous_BSSGP_PDU);
3546
3547 f_global_pcu2sgsn(tx, exp_rx, pcu_idx, sgsn_idx);
3548}
3549
3550/* STATUS in uplink direction; expect routing by its NRI */
3551private function f_TC_status_dl(integer sgsn_idx, integer pcu_idx, PDU_BSSGP inner)
3552runs on GlobalTest_CT
3553{
3554 var template (value) PDU_BSSGP tx := ts_BSSGP_STATUS(omit, BSSGP_CAUSE_EQUIMENT_FAILURE, inner);
3555 var template (present) PDU_BSSGP exp_rx :=
3556 tr_BSSGP_STATUS(omit, BSSGP_CAUSE_EQUIMENT_FAILURE,
3557 tx.pDU_BSSGP_STATUS.pDU_in_Error.erroneous_BSSGP_PDU);
3558
3559 f_global_sgsn2pcu(tx, exp_rx, sgsn_idx, pcu_idx);
3560}
3561
3562/* STATUS in uplink direction on SIG-BVC containing a TLLI; expect routing by its NRI */
3563testcase TC_status_sig_ul_tlli() runs on GlobalTest_CT
3564{
3565 var integer sgsn_idx, nri_idx;
3566
3567 f_init();
3568 f_global_init();
3569
3570 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3571 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx + 1) {
3572 /* some downlink PDU occurring on SIG-BVC with a TLLI */
3573 var OCT4 tlli := f_gen_tlli_for_sgsn_nri(sgsn_idx, nri_idx);
3574 var PDU_BSSGP inner := valueof(ts_BSSGP_FLUSH_LL(tlli, 2342));
3575
3576 f_TC_status_ul(0, sgsn_idx, inner);
3577 }
3578 }
3579
3580 f_cleanup();
3581}
3582
3583/* STATUS in uplink direction on SIG-BVC containing a TMSI; expect routing by its NRI */
3584testcase TC_status_sig_ul_tmsi() runs on GlobalTest_CT
3585{
3586 var integer sgsn_idx, nri_idx;
3587
3588 f_init();
3589 f_global_init();
3590
3591 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3592 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx + 1) {
3593 /* some downlink PDU occurring on SIG-BVC with a TMSI */
3594 const hexstring imsi := '001010123456789'H
3595 var OCT4 tmsi := f_gen_tmsi_for_sgsn_nri(sgsn_idx, nri_idx);
3596 var BssgpBvci bvci := g_pcu[0].cfg.bvc[0].bvci;
3597 var PDU_BSSGP inner := valueof(ts_BSSGP_CS_PAGING_PTMSI(bvci, imsi, oct2int(tmsi)));
3598 f_TC_status_ul(0, sgsn_idx, inner);
3599 }
3600 }
3601
3602 f_cleanup();
3603}
3604
3605
3606/* STATUS in uplink direction on PTP-BVC containing a TLLI; expect routing by its NRI */
3607testcase TC_status_ptp_ul_tlli() runs on GlobalTest_CT
3608{
3609 var integer sgsn_idx, nri_idx;
3610
3611 f_init();
3612 f_global_init_ptp();
3613
3614 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3615 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx + 1) {
3616 /* some downlink PDU occurring on PTP-BVC with a TLLI */
3617 var OCT4 tlli := f_gen_tlli_for_sgsn_nri(sgsn_idx, nri_idx);
3618 var PDU_BSSGP inner := valueof(ts_BSSGP_DL_UD(tlli, '2342'O));
3619
3620 f_TC_status_ul(0, sgsn_idx, inner);
3621 }
3622 }
3623
3624 f_cleanup();
3625}
3626
3627/* STATUS in uplink direction on PTP-BVC containing a TMSI; expect routing by its NRI */
3628testcase TC_status_ptp_ul_tmsi() runs on GlobalTest_CT
3629{
3630 var integer sgsn_idx, nri_idx;
3631
3632 f_init();
3633 f_global_init_ptp();
3634
3635 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3636 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx + 1) {
3637 /* some downlink PDU occurring on PTP-BVC with a TMSI */
3638 const hexstring imsi := '001010123456789'H
3639 var OCT4 tmsi := f_gen_tmsi_for_sgsn_nri(sgsn_idx, nri_idx);
3640 var BssgpBvci bvci := g_pcu[0].cfg.bvc[0].bvci;
3641 var PDU_BSSGP inner := valueof(ts_BSSGP_CS_PAGING_PTMSI(bvci, imsi, oct2int(tmsi)));
3642 f_TC_status_ul(0, sgsn_idx, inner);
3643 }
3644 }
3645
3646 f_cleanup();
3647}
3648
3649/* STATUS in downlink direction in SIG-BVC containing a BVCI; expect routing by it */
3650testcase TC_status_sig_dl_bvci() runs on GlobalTest_CT
3651{
3652 var integer sgsn_idx, pcu_idx, bvc_idx;
3653
3654 f_init();
3655 f_global_init();
3656
3657 /* test each BVC in each PCU from each SGSN */
3658 for (pcu_idx := 0; pcu_idx < lengthof(g_pcu); pcu_idx := pcu_idx + 1) {
3659 for (bvc_idx := 0; bvc_idx < lengthof(g_pcu[pcu_idx].cfg.bvc); bvc_idx := bvc_idx + 1) {
3660 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3661 /* some uplink PDU occurring on SIG-BVC containing a BVCI */
3662 var BssgpBvci bvci := g_pcu[pcu_idx].cfg.bvc[bvc_idx].bvci;
3663 var PDU_BSSGP inner := valueof(ts_BSSGP_LLC_DISCARDED('12345678'O, 1, bvci, 23));
3664 f_TC_status_dl(sgsn_idx, pcu_idx, inner);
3665 }
3666 }
3667 }
3668
3669 f_cleanup();
3670}
3671
3672/* STATUS in downlink direction in PTP-BVC; expect routing by BVCI */
3673testcase TC_status_ptp_dl_bvci() runs on GlobalTest_CT
3674{
3675 var integer sgsn_idx, pcu_idx, bvc_idx;
3676
3677 f_init();
3678 f_global_init_ptp();
3679
3680 /* test each BVC in each PCU from each SGSN */
3681 for (pcu_idx := 0; pcu_idx < lengthof(g_pcu); pcu_idx := pcu_idx + 1) {
3682 for (bvc_idx := 0; bvc_idx < lengthof(g_pcu[pcu_idx].cfg.bvc); bvc_idx := bvc_idx + 1) {
3683 var BssgpBvci bvci := g_pcu[pcu_idx].cfg.bvc[bvc_idx].bvci;
3684 f_global_ptp_connect_pcu_bvci(pcu_idx, bvci);
3685 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3686 f_global_ptp_connect_sgsn_bvci(sgsn_idx, bvci);
3687
3688 /* some uplink PDU occurring on PTP-BVC */
3689 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
3690 var PDU_BSSGP inner := valueof(ts_BSSGP_UL_UD('12345678'O, cell_id, '4223'O));
3691 f_TC_status_dl(sgsn_idx, pcu_idx, inner);
3692 }
3693 }
3694 }
3695
3696 f_cleanup();
3697}
3698
3699/* TODO: test case for DL-STATUS(SUSPEND/RESUME) containing RA-ID; expect routing by RA-ID */
3700/* 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 +01003701
Daniel Willmann423d8f42020-09-08 18:58:22 +02003702control {
3703 execute( TC_BVC_bringup() );
Pau Espin Pedrol4e431832023-02-08 12:43:47 +01003704 execute( TC_BVC_bringup_conflicting() );
3705
Harald Welte92686012020-11-15 21:45:49 +01003706 execute( TC_ul_unitdata() );
Daniel Willmann8d9fcf42021-05-28 15:05:41 +02003707 execute( TC_ul_unitdata_pool_failure() );
Harald Welte78d8db92020-11-15 23:27:27 +01003708 execute( TC_dl_unitdata() );
Harald Welte6dc2ac42020-11-16 09:16:17 +01003709 execute( TC_ra_capability() );
Daniel Willmannace3ece2020-11-16 19:53:26 +01003710 execute( TC_ra_capability_upd() );
Daniel Willmann165d6612020-11-19 14:27:29 +01003711 execute( TC_radio_status() );
Harald Welte3148a962021-01-17 11:15:28 +01003712 execute( TC_radio_status_tmsi() );
3713 execute( TC_radio_status_imsi() );
Daniel Willmannfa67f492020-11-19 15:48:05 +01003714 execute( TC_suspend() );
Daniel Willmann087a33d2020-11-19 15:58:43 +01003715 execute( TC_resume() );
Harald Weltef8e5c5d2020-11-27 22:37:23 +01003716 execute( TC_trace() );
Harald Weltec0351d12020-11-27 22:49:02 +01003717 execute( TC_llc_discarded() );
Harald Weltef20af412020-11-28 16:11:11 +01003718 execute( TC_overload() );
Harald Welte239aa502020-11-24 23:14:20 +01003719 execute( TC_bvc_block_ptp() );
3720 execute( TC_bvc_unblock_ptp() );
Harald Welte60a8ec72020-11-25 17:12:53 +01003721 execute( TC_bvc_reset_ptp_from_bss() );
Harald Welte16786e92020-11-27 19:11:56 +01003722 execute( TC_bvc_reset_sig_from_bss() );
Harald Welte60a8ec72020-11-25 17:12:53 +01003723 execute( TC_bvc_reset_ptp_from_sgsn() );
Daniel Willmannc5bbcc62021-09-24 13:17:20 +02003724 execute( TC_bvc_reset_blocked_ptp_from_sgsn() );
Harald Welte16786e92020-11-27 19:11:56 +01003725 execute( TC_bvc_reset_sig_from_sgsn() );
Harald Weltef6e59b02020-12-08 08:29:09 +01003726 if (mp_enable_bss_load_sharing) {
Harald Weltef8ef0282020-11-18 12:16:59 +01003727 /* don't enable this by default, as we don't yet have any automatic test setup for FR with 4 NS-VC */
3728 execute( TC_load_sharing_dl() );
3729 }
Harald Welte0e188242020-11-22 21:46:48 +01003730
3731 /* PAGING-PS over PTP BVC */
3732 execute( TC_paging_ps_ptp_bss() );
3733 execute( TC_paging_ps_ptp_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01003734 execute( TC_paging_ps_ptp_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003735 execute( TC_paging_ps_ptp_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01003736 execute( TC_paging_ps_ptp_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003737 execute( TC_paging_ps_ptp_bvci() );
Harald Welteb5a04aa2021-01-16 13:04:40 +01003738 execute( TC_paging_ps_ptp_bvci_imsi() );
Harald Welte7462a592020-11-23 22:07:07 +01003739 execute( TC_paging_ps_ptp_bvci_unknown() );
Harald Weltecf200072021-01-16 15:20:46 +01003740 execute( TC_paging_ps_reject_ptp_bvci() );
3741 execute( TC_paging_ps_reject_ptp_bvci_imsi() );
Harald Welte7595d562021-01-16 19:09:20 +01003742 execute( TC_dummy_paging_ps_ptp() );
Harald Welte0e188242020-11-22 21:46:48 +01003743
3744 /* PAGING-PS over SIG BVC */
3745 execute( TC_paging_ps_sig_bss() );
3746 execute( TC_paging_ps_sig_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01003747 execute( TC_paging_ps_sig_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003748 execute( TC_paging_ps_sig_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01003749 execute( TC_paging_ps_sig_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003750 execute( TC_paging_ps_sig_bvci() );
Harald Welteb5a04aa2021-01-16 13:04:40 +01003751 execute( TC_paging_ps_sig_bvci_imsi() );
Harald Welte7462a592020-11-23 22:07:07 +01003752 execute( TC_paging_ps_sig_bvci_unknown() );
Harald Weltecf200072021-01-16 15:20:46 +01003753 execute( TC_paging_ps_reject_sig_bvci() );
3754 execute( TC_paging_ps_reject_sig_bvci_imsi() );
Harald Welte7595d562021-01-16 19:09:20 +01003755 execute( TC_dummy_paging_ps_sig() );
Harald Welte0e188242020-11-22 21:46:48 +01003756
3757 /* PAGING-CS over PTP BVC */
3758 execute( TC_paging_cs_ptp_bss() );
3759 execute( TC_paging_cs_ptp_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01003760 execute( TC_paging_cs_ptp_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003761 execute( TC_paging_cs_ptp_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01003762 execute( TC_paging_cs_ptp_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003763 execute( TC_paging_cs_ptp_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01003764 execute( TC_paging_cs_ptp_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003765
3766 /* PAGING-CS over SIG BVC */
3767 execute( TC_paging_cs_sig_bss() );
3768 execute( TC_paging_cs_sig_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01003769 execute( TC_paging_cs_sig_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003770 execute( TC_paging_cs_sig_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01003771 execute( TC_paging_cs_sig_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003772 execute( TC_paging_cs_sig_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01003773 execute( TC_paging_cs_sig_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003774
Harald Weltef86f1852021-01-16 21:56:17 +01003775 /* RAN Information Management */
3776 execute( TC_rim_info_req() );
3777 execute( TC_rim_info() );
3778 execute( TC_rim_info_ack() );
3779 execute( TC_rim_info_error() );
3780 execute( TC_rim_info_app_error() );
3781 execute( TC_rim_info_pcu2pcu() );
Pau Espin Pedrol40778e82021-05-07 13:20:58 +02003782 execute( TC_rim_from_eutran() );
Harald Weltef86f1852021-01-16 21:56:17 +01003783
Harald Welte0e188242020-11-22 21:46:48 +01003784
Daniel Willmannc7c8e322021-11-25 18:13:21 +01003785 execute( TC_flush_ll_bvci_new() );
3786
Pau Espin Pedrol4e431832023-02-08 12:43:47 +01003787 execute( TC_flush_ll_no_bvci_new() );
3788
Harald Welte299aa482020-12-09 15:10:55 +01003789 execute( TC_fc_bvc() );
Harald Weltecc3894b2020-12-09 16:50:12 +01003790 execute( TC_fc_ms() );
Harald Welted6f89812021-01-16 18:57:49 +01003791 execute( TC_ms_reg_enq() );
Harald Welte04358652021-01-17 13:48:13 +01003792
3793 /* Uplink STATUS */
3794 execute( TC_status_sig_ul_tlli() );
3795 execute( TC_status_sig_ul_tmsi() );
3796 execute( TC_status_ptp_ul_tlli() );
3797 execute( TC_status_ptp_ul_tmsi() );
3798
3799 /* Downlink STATUS */
3800 execute( TC_status_sig_dl_bvci() );
3801 execute( TC_status_ptp_dl_bvci() );
Daniel Willmann423d8f42020-09-08 18:58:22 +02003802}
3803
3804
3805}