blob: ddf98a924e4c542e545987c714d1104a5aaa7913 [file] [log] [blame]
Daniel Willmann423d8f42020-09-08 18:58:22 +02001module GBProxy_Tests {
2
3/* Osmocom GBProxy test suite in TTCN-3
Harald Welte207166c2021-01-16 12:52:30 +01004 * (C) 2020-2021 Harald Welte <laforge@osmocom.org>
Daniel Willmann423d8f42020-09-08 18:58:22 +02005 * (C) 2020 sysmocom - s.f.m.c. GmbH
6 * All rights reserved.
7 *
8 * Author: Daniel Willmann <dwillmann@sysmocom.de>
9
10 * Released under the terms of GNU General Public License, Version 2 or
11 * (at your option) any later version.
12 *
13 * SPDX-License-Identifier: GPL-2.0-or-later
14 */
15
16import from General_Types all;
17import from Osmocom_Types all;
Harald Welteb9f0fdc2020-12-09 14:44:50 +010018import from Misc_Helpers all;
Daniel Willmann423d8f42020-09-08 18:58:22 +020019import from GSM_Types all;
20import from Native_Functions all;
21import from NS_Types all;
22import from NS_Emulation all;
23import from BSSGP_Types all;
24import from BSSGP_Emulation all;
25import from SCCPasp_Types all;
26import from Osmocom_Gb_Types all;
27
28import from MobileL3_CommonIE_Types all;
29import from MobileL3_GMM_SM_Types all;
30import from MobileL3_Types all;
31import from L3_Templates all;
32import from L3_Common all;
33
34import from TELNETasp_PortType all;
35import from Osmocom_VTY_Functions all;
Harald Welteb5688f22021-03-30 16:28:04 +020036import from Osmocom_CTRL_Adapter all;
Daniel Willmann423d8f42020-09-08 18:58:22 +020037
38import from LLC_Types all;
39import from LLC_Templates all;
40
41import from GSM_RR_Types all;
42
Harald Welte6d63f742020-11-15 19:44:04 +010043/* mcc_mnc is 24.008 10.5.5.15 encoded. 262 42 */
44const BcdMccMnc c_mcc_mnc := '262F42'H;
45
Harald Welte0d5fceb2020-11-29 16:04:07 +010046/* 48.016 section 6.1.4.2: The default maximum information field size of 1600 octets shall be supported on the Gb interface */
47const integer max_fr_info_size := 1600;
48
Daniel Willmann423d8f42020-09-08 18:58:22 +020049modulepar {
Harald Welteb5688f22021-03-30 16:28:04 +020050 charstring mp_gbproxy_ip := "127.0.0.1";
51 integer mp_gbproxy_ctrl_port := 4263;
Harald Welte77218d02021-01-15 19:59:15 +010052 /* NRI bit-length. 0 for no pooling */
53 integer mp_nri_bitlength := 5;
54 roro_integer mp_sgsn_nri := {
55 { 3 }, /* list of NRIs of first SGSN */
56 { 4 } /* list of NRIs of second SGSN */
57 };
Harald Weltef6e59b02020-12-08 08:29:09 +010058 boolean mp_enable_bss_load_sharing := false;
Daniel Willmann2c9300f2020-12-01 10:54:08 +010059 /* SGSN NS configuration */
Harald Welte6d63f742020-11-15 19:44:04 +010060 NSConfigurations mp_nsconfig_sgsn := {
Daniel Willmann423d8f42020-09-08 18:58:22 +020061 {
Daniel Willmann423d8f42020-09-08 18:58:22 +020062 nsei := 101,
63 role_sgsn := true,
Harald Welte90f19742020-11-06 19:34:40 +010064 handle_sns := false,
65 nsvc := {
66 {
67 provider := {
68 ip := {
69 address_family := AF_INET,
70 local_udp_port := 7777,
Harald Welted05a4a92021-01-18 12:03:53 +010071 local_ip := "127.0.0.10",
Harald Welte90f19742020-11-06 19:34:40 +010072 remote_udp_port := 23000,
Harald Weltebe7afce2021-01-17 22:04:36 +010073 remote_ip := "127.0.0.1",
Harald Welte388057d2021-01-18 18:52:49 +010074 data_weight := 0,
Harald Weltebe7afce2021-01-17 22:04:36 +010075 signalling_weight := 1
Harald Welte90f19742020-11-06 19:34:40 +010076 }
77 },
78 nsvci := 101
Harald Welte388057d2021-01-18 18:52:49 +010079 }, {
80 provider := {
81 ip := {
82 address_family := AF_INET,
83 local_udp_port := 7770,
84 local_ip := "127.0.0.10",
85 remote_udp_port := 23000,
86 remote_ip := "127.0.0.1",
87 data_weight := 1,
88 signalling_weight := 0
89 }
90 },
91 nsvci := 201
Harald Welte90f19742020-11-06 19:34:40 +010092 }
Harald Weltebe7afce2021-01-17 22:04:36 +010093
Harald Welte90f19742020-11-06 19:34:40 +010094 }
Harald Welteb978ed62020-12-12 14:01:11 +010095 }, {
96 nsei := 102,
97 role_sgsn := true,
98 handle_sns := false,
99 nsvc := {
100 {
101 provider := {
102 ip := {
103 address_family := AF_INET,
104 local_udp_port := 8888,
Harald Welted05a4a92021-01-18 12:03:53 +0100105 local_ip := "127.0.0.11",
Harald Welteb978ed62020-12-12 14:01:11 +0100106 remote_udp_port := 23000,
Harald Weltebe7afce2021-01-17 22:04:36 +0100107 remote_ip := "127.0.0.1",
Harald Welte388057d2021-01-18 18:52:49 +0100108 data_weight := 0,
Harald Weltebe7afce2021-01-17 22:04:36 +0100109 signalling_weight := 1
Harald Welteb978ed62020-12-12 14:01:11 +0100110 }
111 },
112 nsvci := 102
Harald Welte388057d2021-01-18 18:52:49 +0100113 }, {
114 provider := {
115 ip := {
116 address_family := AF_INET,
117 local_udp_port := 8880,
118 local_ip := "127.0.0.11",
119 remote_udp_port := 23000,
120 remote_ip := "127.0.0.1",
121 data_weight := 1,
122 signalling_weight := 0
123 }
124 },
125 nsvci := 202
Harald Welteb978ed62020-12-12 14:01:11 +0100126 }
127 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200128 }
129 };
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100130 /* BSS NSEI start at 2000 + x
131 * NSVCI start from value of NSEI + 100
132 * UDP port is NSVCI * 10 */
Harald Welte6d63f742020-11-15 19:44:04 +0100133 NSConfigurations mp_nsconfig_pcu := {
Daniel Willmann423d8f42020-09-08 18:58:22 +0200134 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100135 nsei := 2001,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200136 role_sgsn := false,
Harald Welte7079ce82021-04-01 17:38:51 +0200137 handle_sns := true,
Harald Welte90f19742020-11-06 19:34:40 +0100138 nsvc := {
139 {
140 provider := {
141 ip := {
142 address_family := AF_INET,
143 local_udp_port := 21010,
Harald Welted05a4a92021-01-18 12:03:53 +0100144 local_ip := "127.0.1.1",
Harald Welte90f19742020-11-06 19:34:40 +0100145 remote_udp_port := 23000,
Harald Welte7079ce82021-04-01 17:38:51 +0200146 remote_ip := "127.0.0.2",
Harald Weltebe7afce2021-01-17 22:04:36 +0100147 data_weight := 1,
148 signalling_weight := 1
Harald Welte90f19742020-11-06 19:34:40 +0100149 }
150 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100151 nsvci := 2101
Harald Welte90f19742020-11-06 19:34:40 +0100152 }
153 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200154 },
155 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100156 nsei := 2002,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200157 role_sgsn := false,
Harald Welte7079ce82021-04-01 17:38:51 +0200158 handle_sns := true,
Harald Welte90f19742020-11-06 19:34:40 +0100159 nsvc := {
160 {
161 provider := {
162 ip := {
163 address_family := AF_INET,
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100164 local_udp_port := 21020,
Harald Welted05a4a92021-01-18 12:03:53 +0100165 local_ip := "127.0.2.1",
Harald Welte90f19742020-11-06 19:34:40 +0100166 remote_udp_port := 23000,
Harald Welte7079ce82021-04-01 17:38:51 +0200167 remote_ip := "127.0.0.2",
Harald Weltebe7afce2021-01-17 22:04:36 +0100168 data_weight := 1,
169 signalling_weight := 1
Harald Welte90f19742020-11-06 19:34:40 +0100170 }
171 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100172 nsvci := 2102
Harald Welte90f19742020-11-06 19:34:40 +0100173 }
174 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200175 },
176 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100177 nsei := 2003,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200178 role_sgsn := false,
Harald Welte7079ce82021-04-01 17:38:51 +0200179 handle_sns := true,
Harald Welte90f19742020-11-06 19:34:40 +0100180 nsvc := {
181 {
182 provider := {
183 ip := {
184 address_family := AF_INET,
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100185 local_udp_port := 21030,
Harald Welted05a4a92021-01-18 12:03:53 +0100186 local_ip := "127.0.3.1",
Harald Welte90f19742020-11-06 19:34:40 +0100187 remote_udp_port := 23000,
Harald Welte7079ce82021-04-01 17:38:51 +0200188 remote_ip := "127.0.0.2",
Harald Weltebe7afce2021-01-17 22:04:36 +0100189 data_weight := 1,
190 signalling_weight := 1
Harald Welte90f19742020-11-06 19:34:40 +0100191 }
192 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100193 nsvci := 2103
Harald Welte90f19742020-11-06 19:34:40 +0100194 }
195 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200196 }
197 };
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100198 /* BVCI are NSEI*10 + x
199 * The first NSE only has one BVC, the second one 2 and so on
200 * The Cell ID is BVCI + 10000
201 * LAC/RAC are configured in such a way that:
202 * LAC 13135 is present once in NSE(2001), twice in NSE(2002) and once in NSE(2003)
203 * LAC 13300 is present twice in NSE(2003)
204 * RAI 13135-1 is present in NSE(2002) and NSE(2003)
205 * RAI 13300-0 is present twice in NSE(2003)
206 */
Harald Welte6d63f742020-11-15 19:44:04 +0100207 BssgpConfigs mp_gbconfigs := {
208 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100209 nsei := 2001,
Harald Welte6d63f742020-11-15 19:44:04 +0100210 sgsn_role := false,
211 bvc := {
212 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100213 bvci := 20011,
Harald Welte6d63f742020-11-15 19:44:04 +0100214 cell_id := {
215 ra_id := {
216 lai := {
217 mcc_mnc := c_mcc_mnc,
218 lac := 13135
219 },
220 rac := 0
221 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100222 cell_id := 30011
Harald Welte6d63f742020-11-15 19:44:04 +0100223 },
224 depth := BSSGP_DECODE_DEPTH_BSSGP,
225 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
226 }
227 }
228 }, {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100229 nsei := 2002,
Harald Welte6d63f742020-11-15 19:44:04 +0100230 sgsn_role := false,
231 bvc := {
232 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100233 bvci := 20021,
Harald Welte6d63f742020-11-15 19:44:04 +0100234 cell_id := {
235 ra_id := {
236 lai := {
237 mcc_mnc := c_mcc_mnc,
Harald Welte0e188242020-11-22 21:46:48 +0100238 lac := 13135
Harald Welte6d63f742020-11-15 19:44:04 +0100239 },
Harald Welte0e188242020-11-22 21:46:48 +0100240 rac := 1
Harald Welte6d63f742020-11-15 19:44:04 +0100241 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100242 cell_id := 30021
243 },
244 depth := BSSGP_DECODE_DEPTH_BSSGP,
245 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
246 },
247 {
248 bvci := 20022,
249 cell_id := {
250 ra_id := {
251 lai := {
252 mcc_mnc := c_mcc_mnc,
253 lac := 13135
254 },
255 rac := 2
256 },
257 cell_id := 30022
Harald Welte6d63f742020-11-15 19:44:04 +0100258 },
259 depth := BSSGP_DECODE_DEPTH_BSSGP,
260 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
261 }
262 }
263 }, {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100264 nsei := 2003,
Harald Welte6d63f742020-11-15 19:44:04 +0100265 sgsn_role := false,
266 bvc := {
267 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100268 bvci := 20031,
269 cell_id := {
270 ra_id := {
271 lai := {
272 mcc_mnc := c_mcc_mnc,
273 lac := 13135
274 },
275 rac := 1
276 },
277 cell_id := 30031
278 },
279 depth := BSSGP_DECODE_DEPTH_BSSGP,
280 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
281 },
282 {
283 bvci := 20032,
Harald Welte6d63f742020-11-15 19:44:04 +0100284 cell_id := {
285 ra_id := {
286 lai := {
287 mcc_mnc := c_mcc_mnc,
288 lac := 13300
289 },
290 rac := 0
291 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100292 cell_id := 30032
293 },
294 depth := BSSGP_DECODE_DEPTH_BSSGP,
295 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
296 },
297 {
298 bvci := 20033,
299 cell_id := {
300 ra_id := {
301 lai := {
302 mcc_mnc := c_mcc_mnc,
303 lac := 13300
304 },
305 rac := 0
306 },
307 cell_id := 30033
Harald Welte6d63f742020-11-15 19:44:04 +0100308 },
309 depth := BSSGP_DECODE_DEPTH_BSSGP,
310 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
311 }
312 }
313 }
314 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200315};
316
Daniel Willmann423d8f42020-09-08 18:58:22 +0200317type record GbInstance {
318 NS_CT vc_NS,
319 BSSGP_CT vc_BSSGP,
Harald Welte67dc8c22020-11-17 18:32:29 +0100320 BSSGP_BVC_CTs vc_BSSGP_BVC,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200321 BssgpConfig cfg
322};
Harald Welte67dc8c22020-11-17 18:32:29 +0100323type record of BSSGP_BVC_CT BSSGP_BVC_CTs
Daniel Willmann423d8f42020-09-08 18:58:22 +0200324
325const integer NUM_PCU := 3;
Harald Welte6d63f742020-11-15 19:44:04 +0100326type record of GbInstance GbInstances;
327type record of BssgpConfig BssgpConfigs;
328type record of NSConfiguration NSConfigurations;
329type record of BssgpCellId BssgpCellIds;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200330
Harald Welte572b0172021-03-30 13:19:56 +0200331/* you cannot simply change this to any larger number of SGSNs and expect all test
332 * cases to work. This would have overly complicated the code. Check below for
333 * tests that use interleave on SGSN_MGMT.receive() for each SGSN NSEI for example */
Harald Welteb978ed62020-12-12 14:01:11 +0100334const integer NUM_SGSN := 2;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200335
Harald Welteb5688f22021-03-30 16:28:04 +0200336type component test_CT extends CTRL_Adapter_CT {
Harald Welte6d63f742020-11-15 19:44:04 +0100337 var GbInstances g_pcu;
338 var GbInstances g_sgsn;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200339
Daniel Willmann8d9fcf42021-05-28 15:05:41 +0200340 port NS_CTRL_PT NS_CTRL;
341
Daniel Willmann423d8f42020-09-08 18:58:22 +0200342 port BSSGP_CT_PROC_PT PROC;
343
Harald Weltefbae83f2020-11-15 23:25:55 +0100344 port BSSGP_BVC_MGMT_PT SGSN_MGMT;
345 port BSSGP_BVC_MGMT_PT PCU_MGMT;
346
Daniel Willmann423d8f42020-09-08 18:58:22 +0200347 port TELNETasp_PT GBPVTY;
348
349 var boolean g_initialized := false;
350 var boolean g_use_echo := false;
Harald Welte16786e92020-11-27 19:11:56 +0100351
352 var ro_integer g_roi := {};
Daniel Willmannc38c85d2021-01-21 18:11:12 +0100353 var roro_integer g_roroi := {};
Harald Welte425d3762020-12-09 14:33:18 +0100354 timer g_Tguard;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200355};
356
357type component BSSGP_ConnHdlr {
Harald Welte3dd21b32020-11-17 19:21:00 +0100358 /* array of per-BVC ports on the PCU side */
Harald Welte158becf2020-12-09 12:32:32 +0100359 port BSSGP_PT PCU_PTP[NUM_PCU];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200360 port BSSGP_PT PCU_SIG[NUM_PCU];
361 port BSSGP_PROC_PT PCU_PROC[NUM_PCU];
Harald Welte3dd21b32020-11-17 19:21:00 +0100362 /* component reference to the component to which we're currently connected */
363 var BSSGP_BVC_CT pcu_ct[NUM_PCU];
Harald Welte0e188242020-11-22 21:46:48 +0100364 /* BSSGP BVC configuration of the component to which we're currently connected */
365 var BssgpBvcConfig pcu_bvc_cfg[NUM_PCU];
Harald Welte3dd21b32020-11-17 19:21:00 +0100366
367 /* array of per-BVC ports on the SGSN side */
Harald Welte158becf2020-12-09 12:32:32 +0100368 port BSSGP_PT SGSN_PTP[NUM_SGSN];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200369 port BSSGP_PT SGSN_SIG[NUM_SGSN];
370 port BSSGP_PROC_PT SGSN_PROC[NUM_SGSN];
Harald Welte3dd21b32020-11-17 19:21:00 +0100371 /* component reference to the component to which we're currently connected */
372 var BSSGP_BVC_CT sgsn_ct[NUM_PCU];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200373
374 var BSSGP_ConnHdlrPars g_pars;
375 timer g_Tguard;
376 var LLC_Entities llc;
Harald Welte0e188242020-11-22 21:46:48 +0100377
378 var ro_integer g_roi := {};
Daniel Willmann423d8f42020-09-08 18:58:22 +0200379}
380
381type record SGSN_ConnHdlrNetworkPars {
382 boolean expect_ptmsi,
383 boolean expect_auth,
384 boolean expect_ciph
385};
386
387type record BSSGP_ConnHdlrPars {
388 /* IMEI of the simulated ME */
389 hexstring imei,
390 /* IMSI of the simulated MS */
391 hexstring imsi,
392 /* MSISDN of the simulated MS (probably unused) */
393 hexstring msisdn,
394 /* P-TMSI allocated to the simulated MS */
395 OCT4 p_tmsi optional,
396 OCT3 p_tmsi_sig optional,
397 /* TLLI of the simulated MS */
398 OCT4 tlli,
399 OCT4 tlli_old optional,
400 RoutingAreaIdentificationV ra optional,
Harald Welte16357a92020-11-17 18:20:00 +0100401 GbInstances pcu,
Harald Welte3dd21b32020-11-17 19:21:00 +0100402 GbInstances sgsn,
Harald Weltec5f486b2021-01-16 11:07:01 +0100403 /* The SGSN index to be used within the test */
404 integer sgsn_idx,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200405 float t_guard
406};
407
Harald Welte04358652021-01-17 13:48:13 +0100408private function get_bvc_idx_for_bvci(GbInstance gbi, BssgpBvci bvci) return integer
409{
410 var integer i;
411
412 for (i := 0; i < lengthof(gbi.cfg.bvc); i := i + 1) {
413 if (gbi.cfg.bvc[i].bvci == bvci) {
414 return i;
415 }
416 }
417 setverdict(fail, "Could not find BVC Index for BVCI ", bvci);
418 return -1;
419}
420
Daniel Willmann423d8f42020-09-08 18:58:22 +0200421private function f_cellid_to_RAI(in BssgpCellId cell_id) return RoutingAreaIdentificationV {
422 /* mcc_mnc is encoded as of 24.008 10.5.5.15 */
423 var BcdMccMnc mcc_mnc := cell_id.ra_id.lai.mcc_mnc;
424
425 var RoutingAreaIdentificationV ret := {
426 mccDigit1 := mcc_mnc[0],
427 mccDigit2 := mcc_mnc[1],
428 mccDigit3 := mcc_mnc[2],
429 mncDigit3 := mcc_mnc[3],
430 mncDigit1 := mcc_mnc[4],
431 mncDigit2 := mcc_mnc[5],
432 lac := int2oct(cell_id.ra_id.lai.lac, 16),
433 rac := int2oct(cell_id.ra_id.rac, 8)
434 }
435 return ret;
436};
437
Harald Welte95339432020-12-02 18:50:52 +0100438private function f_fix_create_cb(inout BssgpConfig cfg)
439{
440 for (var integer i := 0; i < lengthof(cfg.bvc); i := i + 1) {
441 if (not isbound(cfg.bvc[i].create_cb)) {
442 cfg.bvc[i].create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
443 }
444 }
445}
446
Daniel Willmann423d8f42020-09-08 18:58:22 +0200447private function f_init_gb_pcu(inout GbInstance gb, charstring id, integer offset) runs on test_CT {
Harald Welteb419d0e2020-11-16 16:45:05 +0100448 var charstring ns_id := id & "-NS(PCU[" & int2str(offset) & "])";
449 var charstring bssgp_id := id & "-BSSGP(PCU[" & int2str(offset) & "])";
450 gb.vc_NS := NS_CT.create(ns_id);
451 gb.vc_BSSGP := BSSGP_CT.create(bssgp_id);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200452 /* connect lower end of BSSGP emulation with NS upper port */
453 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
454
Harald Welteb419d0e2020-11-16 16:45:05 +0100455 gb.vc_NS.start(NSStart(mp_nsconfig_pcu[offset], ns_id));
456 gb.vc_BSSGP.start(BssgpStart(gb.cfg, bssgp_id));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200457
458 for (var integer i := 0; i < lengthof(gb.cfg.bvc); i := i + 1) {
Harald Welteb978ed62020-12-12 14:01:11 +0100459 /* obtain the component reference of the BSSGP_BVC_CT for each PTP BVC */
Daniel Willmann423d8f42020-09-08 18:58:22 +0200460 connect(self:PROC, gb.vc_BSSGP:PROC);
461 gb.vc_BSSGP_BVC[i] := f_bssgp_get_bvci_ct(gb.cfg.bvc[i].bvci, PROC);
462 disconnect(self:PROC, gb.vc_BSSGP:PROC);
Harald Welteb978ed62020-12-12 14:01:11 +0100463 /* connect all of the per-BVC MGMT ports to our PCU_MGMT port (1:N) */
Harald Weltefbae83f2020-11-15 23:25:55 +0100464 connect(self:PCU_MGMT, gb.vc_BSSGP_BVC[i]:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200465 }
Harald Welteb978ed62020-12-12 14:01:11 +0100466 /* connect all of the BSSGP/NSE global MGMT port to our PCU_MGMT port (1:N) */
Harald Welte16786e92020-11-27 19:11:56 +0100467 connect(self:PCU_MGMT, gb.vc_BSSGP:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200468}
469
470private function f_init_gb_sgsn(inout GbInstance gb, charstring id, integer offset) runs on test_CT {
Harald Welteb419d0e2020-11-16 16:45:05 +0100471 var charstring ns_id := id & "-NS(SGSN[" & int2str(offset) & "])";
472 var charstring bssgp_id := id & "-BSSGP(SGSN[" & int2str(offset) & "])";
473 gb.vc_NS := NS_CT.create(ns_id);
474 gb.vc_BSSGP := BSSGP_CT.create(bssgp_id);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200475 /* connect lower end of BSSGP emulation with NS upper port */
476 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
477
Harald Welteb419d0e2020-11-16 16:45:05 +0100478 gb.vc_NS.start(NSStart(mp_nsconfig_sgsn[offset], ns_id));
479 gb.vc_BSSGP.start(BssgpStart(gb.cfg, bssgp_id));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200480
481 for (var integer i := 0; i < lengthof(gb.cfg.bvc); i := i + 1) {
Harald Welteb978ed62020-12-12 14:01:11 +0100482 /* obtain the component reference of the BSSGP_BVC_CT for each PTP BVC */
Daniel Willmann423d8f42020-09-08 18:58:22 +0200483 connect(self:PROC, gb.vc_BSSGP:PROC);
484 gb.vc_BSSGP_BVC[i] := f_bssgp_get_bvci_ct(gb.cfg.bvc[i].bvci, PROC);
485 disconnect(self:PROC, gb.vc_BSSGP:PROC);
Harald Welteb978ed62020-12-12 14:01:11 +0100486 /* connect all of the per-BVC MGMT ports to our SGSN_MGMT port (1:N) */
Harald Weltefbae83f2020-11-15 23:25:55 +0100487 connect(self:SGSN_MGMT, gb.vc_BSSGP_BVC[i]:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200488 }
Harald Welteb978ed62020-12-12 14:01:11 +0100489 /* connect all of the BSSGP/NSE global MGMT port to our SGSN_MGMT port (1:N) */
Harald Welte16786e92020-11-27 19:11:56 +0100490 connect(self:SGSN_MGMT, gb.vc_BSSGP:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200491}
492
493
Harald Welteb9f0fdc2020-12-09 14:44:50 +0100494private function f_destroy_gb(inout GbInstance gb) runs on test_CT {
495 gb.vc_NS.stop;
496 gb.vc_BSSGP.stop;
497
498 for (var integer i := 0; i < lengthof(gb.cfg.bvc); i := i + 1) {
499 gb.vc_BSSGP_BVC[i].stop;
500 }
501}
502
Daniel Willmann423d8f42020-09-08 18:58:22 +0200503private function f_init_vty() runs on test_CT {
504 map(self:GBPVTY, system:GBPVTY);
505 f_vty_set_prompts(GBPVTY);
506 f_vty_transceive(GBPVTY, "enable");
507}
508
Harald Welteb978ed62020-12-12 14:01:11 +0100509/* count the number of unblocked BVCI for each SGSN NSE */
510private altstep as_count_unblocked4nse(integer sgsn_idx, inout roro_integer bvci_unblocked)
511runs on test_CT {
512 var BssgpStatusIndication bsi;
513 [] SGSN_MGMT.receive(BssgpStatusIndication:{g_sgsn[sgsn_idx].cfg.nsei, ?, BVC_S_UNBLOCKED}) -> value bsi {
514 bvci_unblocked[sgsn_idx] := bvci_unblocked[sgsn_idx] & { bsi.bvci };
515 /* 'repeat' until sufficient number of BVC-rest has been received on all SGSNs */
516 for (var integer i := 0; i < lengthof(bvci_unblocked); i := i+1) {
517 if (lengthof(bvci_unblocked[i]) < lengthof(g_sgsn[i].cfg.bvc)) {
518 repeat;
519 }
520 }
521 }
522}
523
Harald Welteb5688f22021-03-30 16:28:04 +0200524private template (value) charstring ts_pcu_bvc_fsm_id(uint16_t nsei, uint16_t bvci) :=
525 "NSE" & f_int2str(nsei, 5) & "-BVC" & f_int2str(bvci, 5);
526
527function f_bvc_fsm_ensure_state(uint16_t nsei, uint16_t bvci, template (present) charstring exp)
528runs on CTRL_Adapter_CT {
529 f_ctrl_get_exp_inst_state(IPA_CTRL, "BSSGP-BVC", ts_pcu_bvc_fsm_id(nsei, bvci), exp);
530}
531
Harald Welte425d3762020-12-09 14:33:18 +0100532function f_init(float t_guard := 30.0) runs on test_CT {
Harald Welteb978ed62020-12-12 14:01:11 +0100533 var roro_integer bvci_unblocked;
Harald Weltefbae83f2020-11-15 23:25:55 +0100534 var BssgpStatusIndication bsi;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200535 var integer i;
536
537 if (g_initialized == true) {
538 return;
539 }
540 g_initialized := true;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200541
Harald Welte425d3762020-12-09 14:33:18 +0100542 g_Tguard.start(t_guard);
543 activate(as_gTguard(g_Tguard));
544
Harald Welteb5688f22021-03-30 16:28:04 +0200545 f_ipa_ctrl_start_client(mp_gbproxy_ip, mp_gbproxy_ctrl_port);
546
Harald Welteb978ed62020-12-12 14:01:11 +0100547 var BssgpBvcConfigs bvcs := { };
Harald Welte6d63f742020-11-15 19:44:04 +0100548 for (i := 0; i < lengthof(mp_gbconfigs); i := i+1) {
549 g_pcu[i].cfg := mp_gbconfigs[i];
Harald Welte95339432020-12-02 18:50:52 +0100550 /* make sure all have a proper crate_cb, which cannot be specified in config file */
551 f_fix_create_cb(g_pcu[i].cfg);
Harald Welte6d63f742020-11-15 19:44:04 +0100552 /* concatenate all the PCU-side BVCs for the SGSN side */
Harald Welteb978ed62020-12-12 14:01:11 +0100553 bvcs := bvcs & g_pcu[i].cfg.bvc;
554 }
555
556 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
557 g_sgsn[i].cfg := {
558 nsei := mp_nsconfig_sgsn[i].nsei,
559 sgsn_role := true,
560 bvc := bvcs
561 }
Harald Welte6d63f742020-11-15 19:44:04 +0100562 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200563
564 f_init_vty();
Harald Welte6d63f742020-11-15 19:44:04 +0100565 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
Daniel Willmann443fc572020-11-18 13:26:57 +0100566 f_vty_transceive(GBPVTY, "nsvc nsei " & int2str(g_sgsn[i].cfg.nsei) & " force-unconfigured");
Daniel Willmannad93c052020-12-04 14:14:38 +0100567 }
568 for (i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
569 f_vty_transceive(GBPVTY, "nsvc nsei " & int2str(g_pcu[i].cfg.nsei) & " force-unconfigured");
570 f_vty_transceive(GBPVTY, "delete-gbproxy-peer " & int2str(g_pcu[i].cfg.nsei) & " only-bvc");
571 }
572
573 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
Harald Welteea1ba592020-11-17 18:05:13 +0100574 f_init_gb_sgsn(g_sgsn[i], "GbProxy_Test", i);
Harald Welte6d63f742020-11-15 19:44:04 +0100575 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200576 f_sleep(4.0);
Harald Welte6d63f742020-11-15 19:44:04 +0100577 for (i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
Harald Welteb419d0e2020-11-16 16:45:05 +0100578 f_init_gb_pcu(g_pcu[i], "GbProxy_Test", i);
Harald Welte6d63f742020-11-15 19:44:04 +0100579 }
Harald Weltefbae83f2020-11-15 23:25:55 +0100580
Harald Welteb978ed62020-12-12 14:01:11 +0100581 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
582 bvci_unblocked[i] := {};
583 }
584
Harald Weltefbae83f2020-11-15 23:25:55 +0100585 /* wait until all BVC are unblocked on both sides */
Harald Welted2801272020-11-17 19:22:58 +0100586 timer T := 15.0;
Harald Weltefbae83f2020-11-15 23:25:55 +0100587 T.start;
588 alt {
Harald Welteb978ed62020-12-12 14:01:11 +0100589 /* TODO: We need to add more lines if NUM_SGSN increases. Activating default altsteps
590 * unfortunately doesn't work as we want to access the local variable bvci_unblocked. */
591 [] as_count_unblocked4nse(0, bvci_unblocked);
592 [lengthof(g_sgsn) > 1] as_count_unblocked4nse(1, bvci_unblocked);
Harald Weltefbae83f2020-11-15 23:25:55 +0100593 [] SGSN_MGMT.receive(BssgpStatusIndication:{*, ?, ?}) {
594 repeat;
595 }
Harald Welte3c905152020-11-26 20:56:09 +0100596 [] SGSN_MGMT.receive(BssgpResetIndication:?) {
597 repeat;
598 }
Harald Weltefbae83f2020-11-15 23:25:55 +0100599 [] SGSN_MGMT.receive {
Harald Welted5b7e742021-01-27 10:50:24 +0100600 f_shutdown(__FILE__, __LINE__, fail, "Received unexpected message on SGSN_MGMT");
Harald Weltefbae83f2020-11-15 23:25:55 +0100601 }
602
603 [] PCU_MGMT.receive(BssgpStatusIndication:{*, ?, BVC_S_UNBLOCKED}) -> value bsi {
604 repeat;
605 }
606 [] PCU_MGMT.receive(BssgpStatusIndication:{*, ?, ?}) {
607 repeat;
608 }
609 [] PCU_MGMT.receive(BssgpResetIndication:{0}) {
610 repeat;
611 }
612 [] PCU_MGMT.receive {
Harald Welted5b7e742021-01-27 10:50:24 +0100613 f_shutdown(__FILE__, __LINE__, fail, "Received unexpected message on PCU_MGMT");
Harald Weltefbae83f2020-11-15 23:25:55 +0100614 }
615
616 [] T.timeout {
Harald Welte6929e322020-12-12 13:10:45 +0100617 setverdict(fail, "Timeout waiting for unblock of all BVCs on SGSN side; ",
Harald Welteb978ed62020-12-12 14:01:11 +0100618 "unblocked so far: ", bvci_unblocked);
Harald Welte6929e322020-12-12 13:10:45 +0100619 /* don't stop here but print below analysis */
Harald Weltefbae83f2020-11-15 23:25:55 +0100620 }
621 }
622
Harald Welteb978ed62020-12-12 14:01:11 +0100623 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
624 /* iterate over list and check all BVCI */
625 for (var integer j := 0; j < lengthof(g_sgsn[i].cfg.bvc); j := j+1) {
626 var BssgpBvci bvci := g_sgsn[i].cfg.bvc[j].bvci;
627 if (not ro_integer_contains(bvci_unblocked[i], bvci)) {
Harald Welted5b7e742021-01-27 10:50:24 +0100628 f_shutdown(__FILE__, __LINE__, fail,
629 log2str("SGSN ", i, " BVCI=", bvci, " was not unblocked during start-up"));
Harald Welteb978ed62020-12-12 14:01:11 +0100630 }
Harald Weltefbae83f2020-11-15 23:25:55 +0100631 }
632 }
Harald Welte425d3762020-12-09 14:33:18 +0100633
Daniel Willmannd70d45a2021-07-23 10:23:51 +0200634 /* Wait to ensure the gbproxy processed the RESET_ACK messages from the SGSN.
635 * Otherwise the state might still be WAIT_RESET_ACK */
636 f_sleep(0.2);
637
Harald Welteb5688f22021-03-30 16:28:04 +0200638 /* verify all SGSN-side BVC FSM in IUT are UNBLOCKED */
639 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
640 f_bvc_fsm_ensure_state(mp_nsconfig_sgsn[i].nsei, 0, "UNBLOCKED");
641 /* iterate over list and check all BVCI */
642 for (var integer j := 0; j < lengthof(g_sgsn[i].cfg.bvc); j := j+1) {
643 var BssgpBvci bvci := g_sgsn[i].cfg.bvc[j].bvci;
644 f_bvc_fsm_ensure_state(mp_nsconfig_sgsn[i].nsei, bvci, "UNBLOCKED");
645 }
646 }
647 /* verify all PCU-side BVC FSM in IUT are UNBLOCKED */
648 for (i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
649 f_bvc_fsm_ensure_state(mp_nsconfig_pcu[i].nsei, 0, "UNBLOCKED");
650 /* iterate over list and check all BVCI */
651 for (var integer j := 0; j < lengthof(g_pcu[i].cfg.bvc); j := j+1) {
652 var BssgpBvci bvci := g_pcu[i].cfg.bvc[j].bvci;
653 f_bvc_fsm_ensure_state(mp_nsconfig_pcu[i].nsei, bvci, "UNBLOCKED");
654 }
655 }
656
Harald Welte425d3762020-12-09 14:33:18 +0100657 /* re-start guard timer after all BVCs are up, so it only counts the actual test case */
658 g_Tguard.start(t_guard);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200659}
660
661function f_cleanup() runs on test_CT {
Harald Welteb9f0fdc2020-12-09 14:44:50 +0100662 var integer i;
663
Daniel Willmann491af2a2021-01-08 01:32:51 +0100664 /* To avoid a dynamic test case error we need to prevent messages arriving on unconnected
665 * ports. Waiting here ensures that any messages "in flight" will be delivered to the port
666 * before the component is shutdown and disconnected. */
667 f_sleep(0.2);
668
Harald Welteb9f0fdc2020-12-09 14:44:50 +0100669 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
670 f_destroy_gb(g_sgsn[i]);
671 }
672 for (i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
673 f_destroy_gb(g_pcu[i]);
674 }
675
676 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, pass);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200677}
678
679type function void_fn(charstring id) runs on BSSGP_ConnHdlr;
680
681/* helper function to create, connect and start a BSSGP_ConnHdlr component */
Harald Welte207166c2021-01-16 12:52:30 +0100682function f_start_handler(void_fn fn, charstring id, integer imsi_suffix, float t_guard := 30.0,
683 integer sgsn_idx := 0, integer nri_idx := 0, boolean have_ptmsi := true)
Daniel Willmann423d8f42020-09-08 18:58:22 +0200684runs on test_CT return BSSGP_ConnHdlr {
685 var BSSGP_ConnHdlr vc_conn;
Harald Weltec5f486b2021-01-16 11:07:01 +0100686 var integer nri := mp_sgsn_nri[sgsn_idx][nri_idx];
Harald Welte77218d02021-01-15 19:59:15 +0100687 var OCT4 p_tmsi := f_gen_tmsi(imsi_suffix, nri_v := nri, nri_bitlen := mp_nri_bitlength);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200688
689 var BSSGP_ConnHdlrPars pars := {
690 imei := f_gen_imei(imsi_suffix),
691 imsi := f_gen_imsi(imsi_suffix),
692 msisdn := f_gen_msisdn(imsi_suffix),
Harald Weltedbd5e672021-01-14 21:03:14 +0100693 p_tmsi := p_tmsi,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200694 p_tmsi_sig := omit,
Harald Weltedbd5e672021-01-14 21:03:14 +0100695 tlli := f_gprs_tlli_from_tmsi(p_tmsi, TLLI_LOCAL),
Daniel Willmann423d8f42020-09-08 18:58:22 +0200696 tlli_old := omit,
697 ra := omit,
Harald Welte2ecbca82021-01-16 11:23:09 +0100698 pcu := g_pcu,
699 sgsn := g_sgsn,
Harald Weltec5f486b2021-01-16 11:07:01 +0100700 sgsn_idx := sgsn_idx,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200701 t_guard := t_guard
702 };
Harald Welte207166c2021-01-16 12:52:30 +0100703 if (not have_ptmsi) {
704 pars.p_tmsi := omit;
705 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200706
707 vc_conn := BSSGP_ConnHdlr.create(id);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200708
Harald Welte25a04b12021-01-17 11:09:49 +0100709 log("Starting ", id, " for SGSN[", sgsn_idx, "], NRI=", nri, ", P-TMSI=", pars.p_tmsi,
710 ", TLLI=", pars.tlli, ", IMSI=", pars.imsi, " on component=", vc_conn);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200711 vc_conn.start(f_handler_init(fn, id, pars));
712 return vc_conn;
713}
714
Harald Welte207166c2021-01-16 12:52:30 +0100715function f_start_handlers(void_fn fn, charstring id, integer imsi_suffix, float t_guard := 30.0,
716 boolean have_ptmsi := true)
Harald Weltec5f486b2021-01-16 11:07:01 +0100717runs on test_CT
718{
719 var integer sgsn_idx, nri_idx;
720 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx:=sgsn_idx+1) {
721 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx:=nri_idx+1) {
722 var integer extd_imsi_suffix := 1000*sgsn_idx + 100*nri_idx;
723 var BSSGP_ConnHdlr vc_conn;
Harald Welte207166c2021-01-16 12:52:30 +0100724 vc_conn := f_start_handler(fn, id, extd_imsi_suffix, t_guard, sgsn_idx, nri_idx,
725 have_ptmsi);
Harald Weltec5f486b2021-01-16 11:07:01 +0100726 /* Idea: we could also run them in parallel ? */
727 vc_conn.done;
728 }
729 }
730}
731
Harald Welte3dd21b32020-11-17 19:21:00 +0100732/* 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 +0100733private function f_connect_to_pcu_bvc(integer port_idx, integer nse_idx, integer bvc_idx)
734runs on BSSGP_ConnHdlr {
735 var BSSGP_BVC_CT bvc_ct := g_pars.pcu[nse_idx].vc_BSSGP_BVC[bvc_idx]
Harald Welte158becf2020-12-09 12:32:32 +0100736 if (PCU_PTP[port_idx].checkstate("Connected")) {
Harald Welte3dd21b32020-11-17 19:21:00 +0100737 /* unregister + disconnect from old BVC */
738 f_client_unregister(g_pars.imsi, PCU_PROC[port_idx]);
Harald Welte158becf2020-12-09 12:32:32 +0100739 disconnect(self:PCU_PTP[port_idx], pcu_ct[port_idx]:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100740 disconnect(self:PCU_SIG[port_idx], pcu_ct[port_idx]:BSSGP_SP_SIG);
741 disconnect(self:PCU_PROC[port_idx], pcu_ct[port_idx]:BSSGP_PROC);
742 }
743 /* connect to new BVC and register us */
Harald Welte158becf2020-12-09 12:32:32 +0100744 connect(self:PCU_PTP[port_idx], bvc_ct:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100745 connect(self:PCU_SIG[port_idx], bvc_ct:BSSGP_SP_SIG);
746 connect(self:PCU_PROC[port_idx], bvc_ct:BSSGP_PROC);
747 f_client_register(g_pars.imsi, g_pars.tlli, PCU_PROC[port_idx]);
748 pcu_ct[port_idx] := bvc_ct;
Harald Welte0e188242020-11-22 21:46:48 +0100749 pcu_bvc_cfg[port_idx] := g_pars.pcu[nse_idx].cfg.bvc[bvc_idx];
Harald Welte3dd21b32020-11-17 19:21:00 +0100750}
751
752/* Connect the SGSN-side per-BVC ports (SGSN/SGSN_SIG/SGSN_PROC) array slot 'port_idx' to specified per-BVC component */
753private 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 +0100754 if (SGSN_PTP[port_idx].checkstate("Connected")) {
Harald Welte3dd21b32020-11-17 19:21:00 +0100755 /* unregister + disconnect from old BVC */
756 f_client_unregister(g_pars.imsi, SGSN_PROC[port_idx]);
Harald Welte158becf2020-12-09 12:32:32 +0100757 disconnect(self:SGSN_PTP[port_idx], sgsn_ct[port_idx]:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100758 disconnect(self:SGSN_SIG[port_idx], sgsn_ct[port_idx]:BSSGP_SP_SIG);
759 disconnect(self:SGSN_PROC[port_idx], sgsn_ct[port_idx]:BSSGP_PROC);
760 }
761 /* connect to new BVC and register us */
Harald Welte158becf2020-12-09 12:32:32 +0100762 connect(self:SGSN_PTP[port_idx], bvc_ct:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100763 connect(self:SGSN_SIG[port_idx], bvc_ct:BSSGP_SP_SIG);
764 connect(self:SGSN_PROC[port_idx], bvc_ct:BSSGP_PROC);
765 f_client_register(g_pars.imsi, g_pars.tlli, SGSN_PROC[port_idx]);
766 sgsn_ct[port_idx] := bvc_ct;
767}
768
Harald Welte425d3762020-12-09 14:33:18 +0100769private altstep as_gTguard(timer Tguard) {
770 [] Tguard.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +0100771 f_shutdown(__FILE__, __LINE__, fail, "Tguard timeout");
Daniel Willmann423d8f42020-09-08 18:58:22 +0200772 }
773}
774
775/* first function called in every ConnHdlr */
776private function f_handler_init(void_fn fn, charstring id, BSSGP_ConnHdlrPars pars)
777runs on BSSGP_ConnHdlr {
Harald Welte1e834f32020-11-15 20:02:59 +0100778 var integer i;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200779 /* do some common stuff like setting up g_pars */
780 g_pars := pars;
781
782 llc := f_llc_create(false);
783
Harald Welte3dd21b32020-11-17 19:21:00 +0100784 /* default connections on PCU side: First BVC of each NSE/PCU */
785 for (i := 0; i < lengthof(g_pars.pcu); i := i+1) {
Harald Welte0e188242020-11-22 21:46:48 +0100786 f_connect_to_pcu_bvc(port_idx := i, nse_idx := i, bvc_idx := 0);
Harald Welte1e834f32020-11-15 20:02:59 +0100787 }
Harald Welte3dd21b32020-11-17 19:21:00 +0100788
789 /* default connections on SGSN side: First BVC of each NSE/SGSN */
790 for (i := 0; i < lengthof(g_pars.sgsn); i := i+1) {
791 f_connect_to_sgsn_bvc(i, g_pars.sgsn[i].vc_BSSGP_BVC[0]);
Harald Welte1e834f32020-11-15 20:02:59 +0100792 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200793
794 g_Tguard.start(pars.t_guard);
Harald Welte425d3762020-12-09 14:33:18 +0100795 activate(as_gTguard(g_Tguard));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200796
797 /* call the user-supplied test case function */
798 fn.apply(id);
Harald Welteb33fb592021-01-16 12:50:56 +0100799
800 for (i := 0; i < NUM_SGSN; i := i+1) {
801 if (SGSN_PROC[i].checkstate("Connected")) {
802 f_client_unregister(g_pars.imsi, SGSN_PROC[i])
803 }
804 }
805
806 for (i := 0; i < NUM_PCU; i := i+1) {
807 if (PCU_PROC[i].checkstate("Connected")) {
808 f_client_unregister(g_pars.imsi, PCU_PROC[i])
809 }
810 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200811}
812
Harald Welte1e834f32020-11-15 20:02:59 +0100813private function f_client_register(hexstring imsi, OCT4 tlli, BSSGP_PROC_PT PT)
814runs on BSSGP_ConnHdlr {
815 PT.call(BSSGP_register_client:{imsi, tlli}) {
816 [] PT.getreply(BSSGP_register_client:{imsi, tlli}) {};
817 }
818}
819
820private function f_client_unregister(hexstring imsi, BSSGP_PROC_PT PT)
821runs on BSSGP_ConnHdlr {
822 PT.call(BSSGP_unregister_client:{imsi}) {
823 [] PT.getreply(BSSGP_unregister_client:{imsi}) {};
824 }
825}
826
Harald Welte22ef5d92020-11-16 13:35:14 +0100827/* Send 'tx' on PTP-BVCI from PCU; expect 'rx' on SGSN */
828friend function f_pcu2sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
Harald Weltec5f486b2021-01-16 11:07:01 +0100829 integer pcu_idx := 0, boolean use_sig := false) runs on BSSGP_ConnHdlr {
830 var integer sgsn_idx := g_pars.sgsn_idx;
Harald Welte22ef5d92020-11-16 13:35:14 +0100831 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +0100832 timer T := 2.0;
Harald Welte22ef5d92020-11-16 13:35:14 +0100833
Daniel Willmann4798fd72020-11-24 16:23:29 +0100834 if (use_sig) {
835 PCU_SIG[pcu_idx].send(tx);
836 } else {
Harald Welte158becf2020-12-09 12:32:32 +0100837 PCU_PTP[pcu_idx].send(tx);
Daniel Willmann4798fd72020-11-24 16:23:29 +0100838 }
839
Harald Welte22ef5d92020-11-16 13:35:14 +0100840 T.start;
841 alt {
Daniel Willmann4798fd72020-11-24 16:23:29 +0100842 [use_sig] SGSN_SIG[sgsn_idx].receive(exp_rx) {
843 setverdict(pass);
844 }
Harald Welte158becf2020-12-09 12:32:32 +0100845 [not use_sig] SGSN_PTP[sgsn_idx].receive(exp_rx) {
Harald Welte22ef5d92020-11-16 13:35:14 +0100846 setverdict(pass);
847 }
Harald Welte158becf2020-12-09 12:32:32 +0100848 [] SGSN_PTP[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +0100849 f_shutdown(__FILE__, __LINE__, fail,
850 log2str("Unexpected BSSGP on SGSN[", sgsn_idx, "] side: ", rx));
Harald Welte22ef5d92020-11-16 13:35:14 +0100851 }
Daniel Willmann4798fd72020-11-24 16:23:29 +0100852 [] SGSN_SIG[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +0100853 f_shutdown(__FILE__, __LINE__, fail,
854 log2str("Unexpected SIG BSSGP on SGSN[", sgsn_idx, "] side: ", rx));
Daniel Willmann4798fd72020-11-24 16:23:29 +0100855 }
Harald Welte22ef5d92020-11-16 13:35:14 +0100856 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +0100857 f_shutdown(__FILE__, __LINE__, fail,
858 log2str("Timeout waiting for BSSGP on SGSN[", sgsn_idx, "] side: ", exp_rx));
Harald Welte22ef5d92020-11-16 13:35:14 +0100859 }
860 }
861}
862
Harald Welte3148a962021-01-17 11:15:28 +0100863/* Send 'tx' from PCU; expect 'exp_rx' on _any_ SGSN */
864friend function f_pcu2any_sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
865 integer pcu_idx := 0, boolean use_sig := false)
866runs on BSSGP_ConnHdlr return integer {
867 var integer rx_idx := -1;
868 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +0100869 timer T := 2.0;
Harald Welte3148a962021-01-17 11:15:28 +0100870
871 if (use_sig) {
872 PCU_SIG[pcu_idx].send(tx);
873 } else {
874 PCU_PTP[pcu_idx].send(tx);
875 }
876
877 T.start;
878 alt {
879 [use_sig] any from SGSN_SIG.receive(exp_rx) -> @index value rx_idx {
880 setverdict(pass);
881 }
882 [not use_sig] any from SGSN_PTP.receive(exp_rx) -> @index value rx_idx {
883 setverdict(pass);
884 }
885 [] any from SGSN_PTP.receive(PDU_BSSGP:?) -> value rx @index value rx_idx {
Harald Welted5b7e742021-01-27 10:50:24 +0100886 f_shutdown(__FILE__, __LINE__, fail,
887 log2str("Unexpected BSSGP on SGSN[", rx_idx, "] side: ", rx));
Harald Welte3148a962021-01-17 11:15:28 +0100888 }
889 [] any from SGSN_SIG.receive(PDU_BSSGP:?) -> value rx @index value rx_idx {
Harald Welted5b7e742021-01-27 10:50:24 +0100890 f_shutdown(__FILE__, __LINE__, fail,
891 log2str("Unexpected SIG BSSGP on SGSN[", rx_idx, "] side: ", rx));
Harald Welte3148a962021-01-17 11:15:28 +0100892 }
893 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +0100894 f_shutdown(__FILE__, __LINE__, fail,
895 log2str("Timeout waiting for BSSGP on SGSN side: ", exp_rx));
Harald Welte3148a962021-01-17 11:15:28 +0100896 }
897 }
898 return rx_idx;
899}
900
Harald Welte22ef5d92020-11-16 13:35:14 +0100901/* Send 'tx' on PTP-BVCI from SGSN; expect 'rx' on PCU */
902friend function f_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
Harald Weltec5f486b2021-01-16 11:07:01 +0100903 integer pcu_idx := 0, boolean use_sig := false) runs on BSSGP_ConnHdlr {
904 var integer sgsn_idx := g_pars.sgsn_idx;
Harald Welte22ef5d92020-11-16 13:35:14 +0100905 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +0100906 timer T := 2.0;
Harald Welte22ef5d92020-11-16 13:35:14 +0100907
Daniel Willmann4798fd72020-11-24 16:23:29 +0100908 if (use_sig) {
909 SGSN_SIG[sgsn_idx].send(tx);
910 } else {
Harald Welte158becf2020-12-09 12:32:32 +0100911 SGSN_PTP[sgsn_idx].send(tx);
Daniel Willmann4798fd72020-11-24 16:23:29 +0100912 }
913
Harald Welte22ef5d92020-11-16 13:35:14 +0100914 T.start;
915 alt {
Daniel Willmann4798fd72020-11-24 16:23:29 +0100916 [use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
917 setverdict(pass);
918 }
Harald Welte158becf2020-12-09 12:32:32 +0100919 [not use_sig] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte22ef5d92020-11-16 13:35:14 +0100920 setverdict(pass);
921 }
Harald Welte158becf2020-12-09 12:32:32 +0100922 [] PCU_PTP[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +0100923 f_shutdown(__FILE__, __LINE__, fail, log2str("Unexpected BSSGP on PCU side: ", rx));
Harald Welte22ef5d92020-11-16 13:35:14 +0100924 }
Daniel Willmann4798fd72020-11-24 16:23:29 +0100925 [] PCU_SIG[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +0100926 f_shutdown(__FILE__, __LINE__, fail, log2str("Unexpected SIG BSSGP on PCU side: ", rx));
Daniel Willmann4798fd72020-11-24 16:23:29 +0100927 }
Harald Welte22ef5d92020-11-16 13:35:14 +0100928 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +0100929 f_shutdown(__FILE__, __LINE__, fail,
930 log2str("Timeout waiting for BSSGP on PCU side: ", exp_rx));
Harald Welte22ef5d92020-11-16 13:35:14 +0100931 }
932 }
933}
Harald Welte1e834f32020-11-15 20:02:59 +0100934
Harald Welte3807ed12020-11-24 19:05:22 +0100935/***********************************************************************
936 * GlobaLTest_CT: Using the per-NSE GLOBAL ports on PCU + SGSN side
937 ***********************************************************************/
938
939type component GlobalTest_CT extends test_CT {
940 port BSSGP_PT G_PCU[NUM_PCU];
Harald Welte04358652021-01-17 13:48:13 +0100941 var integer g_pcu_idx[NUM_PCU]; /* BVC index currently connected to G_PCU */
Harald Welte3807ed12020-11-24 19:05:22 +0100942 port BSSGP_PT G_SGSN[NUM_SGSN];
Harald Welte04358652021-01-17 13:48:13 +0100943 var integer g_sgsn_idx[NUM_SGSN]; /* BVC index currently connected to G_SGSN */
Harald Weltef86f1852021-01-16 21:56:17 +0100944 port BSSGP_PT RIM_PCU[NUM_PCU];
945 port BSSGP_PT RIM_SGSN[NUM_SGSN];
Harald Welte3807ed12020-11-24 19:05:22 +0100946};
947
Harald Welte299aa482020-12-09 15:10:55 +0100948/* connect the signaling BVC of each NSE to the G_PCU / G_SGSN ports */
Harald Welte3807ed12020-11-24 19:05:22 +0100949private function f_global_init() runs on GlobalTest_CT {
950 var integer i;
951 for (i := 0; i < lengthof(g_sgsn); i := i+1) {
952 connect(self:G_SGSN[i], g_sgsn[i].vc_BSSGP:GLOBAL);
Harald Weltef86f1852021-01-16 21:56:17 +0100953 connect(self:RIM_SGSN[i], g_sgsn[i].vc_BSSGP:RIM);
Harald Welte3807ed12020-11-24 19:05:22 +0100954 }
955 for (i := 0; i < lengthof(g_pcu); i := i+1) {
956 connect(self:G_PCU[i], g_pcu[i].vc_BSSGP:GLOBAL);
Harald Weltef86f1852021-01-16 21:56:17 +0100957 connect(self:RIM_PCU[i], g_pcu[i].vc_BSSGP:RIM);
Harald Welte3807ed12020-11-24 19:05:22 +0100958 }
959}
960
Harald Welte299aa482020-12-09 15:10:55 +0100961/* connect the first PTP BVC of each NSE to the G_PCU / G_SGSN ports */
962private function f_global_init_ptp() runs on GlobalTest_CT {
963 var integer i;
964 for (i := 0; i < lengthof(g_sgsn); i := i+1) {
Harald Welte04358652021-01-17 13:48:13 +0100965 log("Connecting G_SGSN[", i, "] to BVCI=", g_sgsn[i].cfg.bvc[0].bvci);
Harald Welte299aa482020-12-09 15:10:55 +0100966 connect(self:G_SGSN[i], g_sgsn[i].vc_BSSGP_BVC[0]:GLOBAL);
Harald Welte04358652021-01-17 13:48:13 +0100967 g_sgsn_idx[i] := 0;
Harald Welte299aa482020-12-09 15:10:55 +0100968 }
969 for (i := 0; i < lengthof(g_pcu); i := i+1) {
Harald Welte04358652021-01-17 13:48:13 +0100970 log("Connecting G_PCU[", i, "] to BVCI=", g_pcu[i].cfg.bvc[0].bvci);
Harald Welte299aa482020-12-09 15:10:55 +0100971 connect(self:G_PCU[i], g_pcu[i].vc_BSSGP_BVC[0]:GLOBAL);
Harald Welte04358652021-01-17 13:48:13 +0100972 g_pcu_idx[i] := 0;
Harald Welte299aa482020-12-09 15:10:55 +0100973 }
974}
975
Harald Welte04358652021-01-17 13:48:13 +0100976/* (re)connect G_SGSN[sgsn_idx] to a specific PTP BVCI */
977private function f_global_ptp_connect_sgsn_bvci(integer sgsn_idx, BssgpBvci bvci) runs on GlobalTest_CT
978{
979 var integer sgsn_bvc_idx := get_bvc_idx_for_bvci(g_sgsn[sgsn_idx], bvci);
980 var integer old_sgsn_bvc_idx := g_sgsn_idx[sgsn_idx];
981 disconnect(self:G_SGSN[sgsn_idx], g_sgsn[sgsn_idx].vc_BSSGP_BVC[old_sgsn_bvc_idx]:GLOBAL);
982 connect(self:G_SGSN[sgsn_idx], g_sgsn[sgsn_idx].vc_BSSGP_BVC[sgsn_bvc_idx]:GLOBAL);
983 g_sgsn_idx[sgsn_idx] := sgsn_bvc_idx;
984}
985
986/* (re)connect G_PCU[pcu_idx] to a specific PTP BVCI */
987private function f_global_ptp_connect_pcu_bvci(integer pcu_idx, BssgpBvci bvci) runs on GlobalTest_CT
988{
989 var integer pcu_bvc_idx := get_bvc_idx_for_bvci(g_pcu[pcu_idx], bvci);
990 var integer old_pcu_bvc_idx := g_pcu_idx[pcu_idx];
991 disconnect(self:G_PCU[pcu_idx], g_pcu[pcu_idx].vc_BSSGP_BVC[old_pcu_bvc_idx]:GLOBAL);
992 connect(self:G_PCU[pcu_idx], g_pcu[pcu_idx].vc_BSSGP_BVC[pcu_bvc_idx]:GLOBAL);
993 g_pcu_idx[pcu_idx] := pcu_bvc_idx;
994}
995
Harald Welte3807ed12020-11-24 19:05:22 +0100996/* Send 'tx' on PTP-BVCI from PCU; expect 'rx' on SGSN */
997friend function f_global_pcu2sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
998 integer pcu_idx := 0, integer sgsn_idx := 0) runs on GlobalTest_CT {
Harald Welte04358652021-01-17 13:48:13 +0100999 var integer rx_idx;
Harald Welte3807ed12020-11-24 19:05:22 +01001000 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +01001001 timer T := 2.0;
Harald Welte3807ed12020-11-24 19:05:22 +01001002
1003 G_PCU[pcu_idx].send(tx);
1004 T.start;
1005 alt {
1006 [] G_SGSN[sgsn_idx].receive(exp_rx) {
1007 setverdict(pass);
1008 }
Harald Welte04358652021-01-17 13:48:13 +01001009 [] any from G_SGSN.receive(exp_rx) -> @index value rx_idx {
1010 setverdict(fail, "BSSGP arrived on wrong SGSN[", rx_idx, "] instead of SGSN[", sgsn_idx, "]");
1011 }
Harald Welte3807ed12020-11-24 19:05:22 +01001012 [] G_SGSN[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +01001013 f_shutdown(__FILE__, __LINE__, fail, log2str("Unexpected BSSGP on SGSN side: ", rx));
Harald Welte3807ed12020-11-24 19:05:22 +01001014 }
1015 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +01001016 f_shutdown(__FILE__, __LINE__, fail, log2str("Timeout waiting for BSSGP on SGSN side: ", exp_rx));
Harald Welte3807ed12020-11-24 19:05:22 +01001017 }
1018 }
1019}
1020
1021/* Send 'tx' on PTP-BVCI from SGSN; expect 'rx' on PCU */
1022friend function f_global_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
1023 integer sgsn_idx := 0, integer pcu_idx := 0) runs on GlobalTest_CT {
Harald Welte04358652021-01-17 13:48:13 +01001024 var integer rx_idx;
Harald Welte3807ed12020-11-24 19:05:22 +01001025 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +01001026 timer T := 2.0;
Harald Welte3807ed12020-11-24 19:05:22 +01001027
1028 G_SGSN[sgsn_idx].send(tx);
1029 T.start;
1030 alt {
1031 [] G_PCU[pcu_idx].receive(exp_rx) {
1032 setverdict(pass);
1033 }
Harald Welte04358652021-01-17 13:48:13 +01001034 [] any from G_PCU.receive(exp_rx) -> @index value rx_idx {
1035 setverdict(fail, "BSSGP arrived on wrong PCU[", rx_idx, "] instead of PCU[", pcu_idx, "]");
1036 }
Harald Welte3807ed12020-11-24 19:05:22 +01001037 [] G_PCU[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +01001038 f_shutdown(__FILE__, __LINE__, fail, log2str("Unexpected BSSGP on PCU side: ", rx));
Harald Welte3807ed12020-11-24 19:05:22 +01001039 }
1040 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +01001041 f_shutdown(__FILE__, __LINE__, fail, log2str("Timeout waiting for BSSGP on PCU side: ", exp_rx));
Harald Welte3807ed12020-11-24 19:05:22 +01001042 }
1043 }
1044}
1045
1046
Daniel Willmann423d8f42020-09-08 18:58:22 +02001047/* TODO:
1048 * Detach without Attach
1049 * SM procedures without attach / RAU
1050 * ATTACH / RAU
1051 ** with / without authentication
1052 ** with / without P-TMSI allocation
1053 * re-transmissions of LLC frames
1054 * PDP Context activation
1055 ** with different GGSN config in SGSN VTY
1056 ** with different PDP context type (v4/v6/v46)
1057 ** timeout from GGSN
1058 ** multiple / secondary PDP context
1059 */
1060
1061private function f_TC_BVC_bringup(charstring id) runs on BSSGP_ConnHdlr {
1062 f_sleep(5.0);
1063 setverdict(pass);
1064}
1065
1066testcase TC_BVC_bringup() runs on test_CT {
Daniel Willmann423d8f42020-09-08 18:58:22 +02001067 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001068 f_start_handlers(refers(f_TC_BVC_bringup), testcasename(), 51);
Daniel Willmann423d8f42020-09-08 18:58:22 +02001069 f_cleanup();
1070}
1071
Daniel Willmann116d8b52021-12-06 16:27:54 +01001072testcase TC_BVC_bringup_conflicting() runs on test_CT {
1073 var float t_guard := 15.0;
1074 var BssgpStatusIndication bsi;
1075 var integer i;
1076
1077
1078 g_Tguard.start(t_guard);
1079 activate(as_gTguard(g_Tguard));
1080
1081 f_ipa_ctrl_start_client(mp_gbproxy_ip, mp_gbproxy_ctrl_port);
1082
1083 var BssgpBvcConfigs bvcs := { };
1084 for (i := 0; i < lengthof(mp_gbconfigs); i := i+1) {
1085 g_pcu[i].cfg := mp_gbconfigs[i];
1086 g_pcu[i].cfg.bvc[0].bvci := 23;
1087 /* make sure all have a proper create_cb, which cannot be specified in config file */
1088 f_fix_create_cb(g_pcu[i].cfg);
1089 /* concatenate all the PCU-side BVCs for the SGSN side */
1090 bvcs := bvcs & g_pcu[i].cfg.bvc;
1091 }
1092
1093 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
1094 g_sgsn[i].cfg := {
1095 nsei := mp_nsconfig_sgsn[i].nsei,
1096 sgsn_role := true,
1097 bvc := bvcs
1098 }
1099 }
1100
1101 f_init_vty();
1102 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
1103 f_vty_transceive(GBPVTY, "nsvc nsei " & int2str(g_sgsn[i].cfg.nsei) & " force-unconfigured");
1104 }
1105 for (i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1106 f_vty_transceive(GBPVTY, "nsvc nsei " & int2str(g_pcu[i].cfg.nsei) & " force-unconfigured");
1107 f_vty_transceive(GBPVTY, "delete-gbproxy-peer " & int2str(g_pcu[i].cfg.nsei) & " only-bvc");
1108 }
1109
1110 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
1111 f_init_gb_sgsn(g_sgsn[i], "GbProxy_Test", i);
1112 }
1113 f_sleep(4.0);
1114 for (i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1115 f_init_gb_pcu(g_pcu[i], "GbProxy_Test", i);
1116 }
1117
1118 /* wait until all BVC are unblocked on both sides */
1119 timer T := 10.0;
1120 T.start;
1121 alt {
1122 [] SGSN_MGMT.receive(BssgpStatusIndication:{*, ?, ?}) {
1123 repeat;
1124 }
1125 [] SGSN_MGMT.receive(BssgpResetIndication:?) {
1126 repeat;
1127 }
1128 [] SGSN_MGMT.receive {
1129 f_shutdown(__FILE__, __LINE__, fail, "Received unexpected message on SGSN_MGMT");
1130 }
1131 [] PCU_MGMT.receive(BssgpStatusIndication:{*, ?, BVC_S_UNBLOCKED}) -> value bsi {
1132 repeat;
1133 }
1134 [] PCU_MGMT.receive(BssgpStatusIndication:{*, ?, ?}) {
1135 repeat;
1136 }
1137 [] PCU_MGMT.receive(BssgpResetIndication:{0}) {
1138 repeat;
1139 }
1140 [] PCU_MGMT.receive {
1141 f_shutdown(__FILE__, __LINE__, fail, "Received unexpected message on PCU_MGMT");
1142 }
1143 [] T.timeout {
1144 }
1145 }
1146
1147 /* Wait to ensure the gbproxy processed the RESET_ACK messages from the SGSN.
1148 * Otherwise the state might still be WAIT_RESET_ACK */
1149 f_sleep(0.2);
1150
1151 /* Verify BVCs, but ignore conflicting BVCI 23 */
1152 /* verify SGSN-side BVC FSM in IUT are UNBLOCKED */
1153 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
1154 f_bvc_fsm_ensure_state(mp_nsconfig_sgsn[i].nsei, 0, "UNBLOCKED");
1155 /* iterate over list and check all BVCI */
1156 for (var integer j := 0; j < lengthof(g_sgsn[i].cfg.bvc); j := j+1) {
1157 var BssgpBvci bvci := g_sgsn[i].cfg.bvc[j].bvci;
1158 if (bvci == 23) {
1159 continue;
1160 }
1161 f_bvc_fsm_ensure_state(mp_nsconfig_sgsn[i].nsei, bvci, "UNBLOCKED");
1162 }
1163 }
1164 /* verify PCU-side BVC FSM in IUT are UNBLOCKED */
1165 for (i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1166 f_bvc_fsm_ensure_state(mp_nsconfig_pcu[i].nsei, 0, "UNBLOCKED");
1167 /* iterate over list and check all BVCI */
1168 for (var integer j := 0; j < lengthof(g_pcu[i].cfg.bvc); j := j+1) {
1169 var BssgpBvci bvci := g_pcu[i].cfg.bvc[j].bvci;
1170 if (bvci == 23) {
1171 continue;
1172 }
1173 f_bvc_fsm_ensure_state(mp_nsconfig_pcu[i].nsei, bvci, "UNBLOCKED");
1174 }
1175 }
1176
1177 /* re-start guard timer after all BVCs are up, so it only counts the actual test case */
1178 g_Tguard.start(t_guard);
1179 f_start_handlers(refers(f_TC_BVC_bringup), testcasename(), 51);
1180 f_cleanup();
1181}
1182
Daniel Willmann423d8f42020-09-08 18:58:22 +02001183friend function f_bssgp_suspend(integer ran_idx := 0) runs on BSSGP_ConnHdlr return OCT1 {
Harald Welte16357a92020-11-17 18:20:00 +01001184 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Daniel Willmann423d8f42020-09-08 18:58:22 +02001185 timer T := 5.0;
1186 var PDU_BSSGP rx_pdu;
Harald Welte16357a92020-11-17 18:20:00 +01001187 PCU_SIG[ran_idx].send(ts_BSSGP_SUSPEND(g_pars.tlli, bvcc.cell_id.ra_id));
Daniel Willmann423d8f42020-09-08 18:58:22 +02001188 T.start;
1189 alt {
Harald Welte16357a92020-11-17 18:20:00 +01001190 [] 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 +02001191 return rx_pdu.pDU_BSSGP_SUSPEND_ACK.suspend_Reference_Number.suspend_Reference_Number_value;
1192 }
Harald Welte16357a92020-11-17 18:20:00 +01001193 [] 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 +01001194 f_shutdown(__FILE__, __LINE__, fail,
1195 log2str("SUSPEND-NACK in response to SUSPEND for TLLI ", g_pars.tlli));
Daniel Willmann423d8f42020-09-08 18:58:22 +02001196 }
1197 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +01001198 f_shutdown(__FILE__, __LINE__, fail,
1199 log2str("No SUSPEND-ACK in response to SUSPEND for TLLI ", g_pars.tlli));
Daniel Willmann423d8f42020-09-08 18:58:22 +02001200 }
1201 }
1202 return '00'O;
1203}
1204
1205friend function f_bssgp_resume(OCT1 susp_ref, integer ran_idx := 0) runs on BSSGP_ConnHdlr {
Harald Welte16357a92020-11-17 18:20:00 +01001206 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Daniel Willmann423d8f42020-09-08 18:58:22 +02001207 timer T := 5.0;
Harald Welte16357a92020-11-17 18:20:00 +01001208 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 +02001209 T.start;
1210 alt {
Harald Welte16357a92020-11-17 18:20:00 +01001211 [] PCU_SIG[ran_idx].receive(tr_BSSGP_RESUME_ACK(g_pars.tlli, bvcc.cell_id.ra_id));
1212 [] PCU_SIG[ran_idx].receive(tr_BSSGP_RESUME_NACK(g_pars.tlli, bvcc.cell_id.ra_id, ?)) {
Harald Welted5b7e742021-01-27 10:50:24 +01001213 f_shutdown(__FILE__, __LINE__, fail,
1214 log2str("RESUME-NACK in response to RESUME for TLLI ", g_pars.tlli));
Daniel Willmann423d8f42020-09-08 18:58:22 +02001215 }
1216 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +01001217 f_shutdown(__FILE__, __LINE__, fail,
1218 log2str("No RESUME-ACK in response to SUSPEND for TLLI ", g_pars.tlli));
Daniel Willmann423d8f42020-09-08 18:58:22 +02001219 }
1220 }
1221}
1222
1223
Harald Welte92686012020-11-15 21:45:49 +01001224/* send uplink-unitdata of a variety of different sizes; expect it to show up on SGSN */
1225private function f_TC_ul_unitdata(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte16357a92020-11-17 18:20:00 +01001226 var integer ran_idx := 0;
1227 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Harald Welte92686012020-11-15 21:45:49 +01001228 var integer i;
1229
Harald Welte0d5fceb2020-11-29 16:04:07 +01001230 for (i := 0; i < max_fr_info_size-4; i := i+4) {
Harald Welte92686012020-11-15 21:45:49 +01001231 var octetstring payload := f_rnd_octstring(i);
Harald Welte16357a92020-11-17 18:20:00 +01001232 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 +01001233 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte16357a92020-11-17 18:20:00 +01001234 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 +01001235
Harald Welte0d5fceb2020-11-29 16:04:07 +01001236 log("UL-UNITDATA(payload_size=", i);
Harald Welte22ef5d92020-11-16 13:35:14 +01001237 f_pcu2sgsn(pdu_tx, pdu_rx);
Harald Welte92686012020-11-15 21:45:49 +01001238 }
1239 setverdict(pass);
1240}
1241
1242testcase TC_ul_unitdata() runs on test_CT
1243{
Daniel Willmannc879f342021-02-11 14:28:01 +01001244 f_init(60.0);
Harald Welte2ecbca82021-01-16 11:23:09 +01001245 f_start_handlers(refers(f_TC_ul_unitdata), testcasename(), 1);
Harald Welte92686012020-11-15 21:45:49 +01001246 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Welte92686012020-11-15 21:45:49 +01001247 f_cleanup();
1248}
1249
Daniel Willmann8d9fcf42021-05-28 15:05:41 +02001250
1251/* send uplink-unitdata of a variety of different sizes; expect it to show up on the only connected SGSN */
1252private function f_TC_ul_unitdata_pool_failure(charstring id) runs on BSSGP_ConnHdlr {
1253 var integer ran_idx := 0;
1254 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
1255 var integer i;
1256
1257 /* All data should arrive at the one SGSN that is still up */
1258 g_pars.sgsn_idx := 0;
1259
1260 for (i := 0; i < max_fr_info_size-4; i := i+4) {
1261 var octetstring payload := f_rnd_octstring(i);
1262 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_UL_UD(g_pars.tlli, bvcc.cell_id, payload);
1263 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1264 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_UL_UD(g_pars.tlli, bvcc.cell_id, payload);
1265
1266 log("UL-UNITDATA(payload_size=", i);
1267 f_pcu2sgsn(pdu_tx, pdu_rx);
1268 }
1269 setverdict(pass);
1270}
1271
Daniel Willmannc5bbcc62021-09-24 13:17:20 +02001272private function f_disable_ns_pcu(integer pcu_idx) runs on test_CT
1273{
1274 var integer i;
1275
1276 connect(self:NS_CTRL, g_pcu[pcu_idx].vc_NS:NS_CTRL);
1277 for (i := 0; i < lengthof(mp_nsconfig_pcu[pcu_idx].nsvc); i := i + 1) {
1278 var uint16_t nsvci := mp_nsconfig_pcu[pcu_idx].nsvc[i].nsvci;
1279 var NsDisableVcRequest tx_disar;
1280 tx_disar.nsvci := nsvci;
1281 log(tx_disar);
1282 NS_CTRL.send(tx_disar);
1283 }
1284 disconnect(self:NS_CTRL, g_pcu[pcu_idx].vc_NS:NS_CTRL);
1285}
1286
Daniel Willmann8d9fcf42021-05-28 15:05:41 +02001287testcase TC_ul_unitdata_pool_failure() runs on test_CT
1288{
1289 var integer i;
1290 var integer j;
1291
1292 f_init(60.0);
1293
1294 for (i := 1; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
1295 connect(self:NS_CTRL, g_sgsn[i].vc_NS:NS_CTRL);
1296 for (j := 0; j < lengthof(mp_nsconfig_sgsn[i].nsvc); j := j+1) {
1297 var uint16_t nsvci := mp_nsconfig_sgsn[i].nsvc[j].nsvci;
1298 var NsDisableVcRequest tx_disar;
1299 tx_disar.nsvci := nsvci;
1300 NS_CTRL.send(tx_disar);
1301 }
1302 disconnect(self:NS_CTRL, g_sgsn[i].vc_NS:NS_CTRL);
1303 }
1304 /* Wait until gbproxy notices that the NSVCs are down */
1305 f_sleep(15.0);
1306
1307 f_start_handlers(refers(f_TC_ul_unitdata_pool_failure), testcasename(), 1);
1308 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
1309 f_cleanup();
1310}
1311
Harald Welte78d8db92020-11-15 23:27:27 +01001312/* send downlink-unitdata of a variety of different sizes; expect it to show up on PCU */
1313private function f_TC_dl_unitdata(charstring id) runs on BSSGP_ConnHdlr {
1314 var integer i;
1315
Harald Welte0d5fceb2020-11-29 16:04:07 +01001316 for (i := 0; i < max_fr_info_size-4; i := i+4) {
Harald Welte78d8db92020-11-15 23:27:27 +01001317 var octetstring payload := f_rnd_octstring(i);
1318 var template (value) PDU_BSSGP pdu_tx :=
1319 ts_BSSGP_DL_UD(g_pars.tlli, payload, omit, ts_BSSGP_IMSI(g_pars.imsi));
1320 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1321 var template (present) PDU_BSSGP pdu_rx :=
Daniel Willmann325458d2021-02-11 14:22:42 +01001322 tr_BSSGP_DL_UD(g_pars.tlli, payload, tr_BSSGP_IMSI(g_pars.imsi));
Harald Welte78d8db92020-11-15 23:27:27 +01001323
Harald Welte0d5fceb2020-11-29 16:04:07 +01001324 log("DL-UNITDATA(payload_size=", i);
Harald Welte22ef5d92020-11-16 13:35:14 +01001325 f_sgsn2pcu(pdu_tx, pdu_rx);
Harald Welte78d8db92020-11-15 23:27:27 +01001326 }
1327 setverdict(pass);
1328}
1329
1330testcase TC_dl_unitdata() runs on test_CT
1331{
Daniel Willmannc879f342021-02-11 14:28:01 +01001332 f_init(60.0);
Harald Welte2ecbca82021-01-16 11:23:09 +01001333 f_start_handlers(refers(f_TC_dl_unitdata), testcasename(), 2);
Harald Welte78d8db92020-11-15 23:27:27 +01001334 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Welte78d8db92020-11-15 23:27:27 +01001335 f_cleanup();
1336}
Harald Welte92686012020-11-15 21:45:49 +01001337
Harald Welte6dc2ac42020-11-16 09:16:17 +01001338private function f_TC_ra_capability(charstring id) runs on BSSGP_ConnHdlr {
1339 var integer i;
1340
1341 for (i := 0; i < 10; i := i+1) {
1342 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RA_CAP(g_pars.tlli, { ts_RaCapRec_BSSGP });
1343 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1344 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RA_CAP(g_pars.tlli, { tr_RaCapRec_BSSGP })
1345
Harald Welte22ef5d92020-11-16 13:35:14 +01001346 f_sgsn2pcu(pdu_tx, pdu_rx);
Harald Welte6dc2ac42020-11-16 09:16:17 +01001347 }
1348 setverdict(pass);
1349}
1350testcase TC_ra_capability() runs on test_CT
1351{
Harald Welte6dc2ac42020-11-16 09:16:17 +01001352 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001353 f_start_handlers(refers(f_TC_ra_capability), testcasename(), 3);
Harald Welte6dc2ac42020-11-16 09:16:17 +01001354 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Welte6dc2ac42020-11-16 09:16:17 +01001355 f_cleanup();
1356}
1357
Daniel Willmannace3ece2020-11-16 19:53:26 +01001358private function f_TC_ra_capability_upd(charstring id) runs on BSSGP_ConnHdlr {
1359 var integer i;
1360 var OCT1 tag;
1361 for (i := 0; i < 10; i := i+1) {
1362 tag := int2oct(23 + i, 1);
1363 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RA_CAP_UPD(g_pars.tlli, tag);
1364 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1365 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RA_CAP_UPD(g_pars.tlli, tag)
1366
1367 f_pcu2sgsn(pdu_tx, pdu_rx);
1368
1369 pdu_tx := ts_BSSGP_RA_CAP_UPD_ACK(g_pars.tlli, tag, '42'O);
1370 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1371 pdu_rx := tr_BSSGP_RA_CAP_UPD_ACK(g_pars.tlli, tag, '42'O)
1372
1373 f_sgsn2pcu(pdu_tx, pdu_rx);
1374 }
1375 setverdict(pass);
1376}
1377testcase TC_ra_capability_upd() runs on test_CT
1378{
Daniel Willmannace3ece2020-11-16 19:53:26 +01001379 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001380 f_start_handlers(refers(f_TC_ra_capability_upd), testcasename(), 4);
Daniel Willmannace3ece2020-11-16 19:53:26 +01001381 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Daniel Willmannace3ece2020-11-16 19:53:26 +01001382 f_cleanup();
1383}
1384
Daniel Willmann165d6612020-11-19 14:27:29 +01001385private function f_TC_radio_status(charstring id) runs on BSSGP_ConnHdlr {
1386 var integer i;
1387 var BssgpRadioCause cause := BSSGP_RADIO_CAUSE_CONTACT_LOST;
1388 for (i := 0; i < 10; i := i+1) {
1389 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RADIO_STATUS(g_pars.tlli, cause);
1390 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1391 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RADIO_STATUS(g_pars.tlli, cause)
1392
1393 f_pcu2sgsn(pdu_tx, pdu_rx);
1394 }
1395 setverdict(pass);
1396}
1397testcase TC_radio_status() runs on test_CT
1398{
Daniel Willmann165d6612020-11-19 14:27:29 +01001399 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001400 f_start_handlers(refers(f_TC_radio_status), testcasename(), 5);
Daniel Willmann165d6612020-11-19 14:27:29 +01001401 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Daniel Willmann165d6612020-11-19 14:27:29 +01001402 f_cleanup();
1403}
1404
Harald Welte3148a962021-01-17 11:15:28 +01001405private function f_TC_radio_status_tmsi(charstring id) runs on BSSGP_ConnHdlr {
1406 var integer i;
1407 var BssgpRadioCause cause := BSSGP_RADIO_CAUSE_CONTACT_LOST;
1408 for (i := 0; i < 10; i := i+1) {
1409 var integer tmsi_int := oct2int(g_pars.p_tmsi);
1410 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RADIO_STATUS(omit, cause, tmsi_int);
1411 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1412 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RADIO_STATUS(omit, cause, tmsi_int);
1413 f_pcu2sgsn(pdu_tx, pdu_rx);
1414 }
1415 setverdict(pass);
1416}
1417testcase TC_radio_status_tmsi() runs on test_CT
1418{
1419 f_init();
1420 f_start_handlers(refers(f_TC_radio_status_tmsi), testcasename(), 5);
1421 f_cleanup();
1422}
1423
1424private function f_TC_radio_status_imsi(charstring id) runs on BSSGP_ConnHdlr {
1425 var integer i;
1426 var BssgpRadioCause cause := BSSGP_RADIO_CAUSE_CONTACT_LOST;
1427 for (i := 0; i < 10; i := i+1) {
1428 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RADIO_STATUS(omit, cause, imsi := g_pars.imsi);
1429 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1430 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RADIO_STATUS(omit, cause, imsi := g_pars.imsi);
1431 f_pcu2any_sgsn(pdu_tx, pdu_rx);
1432 }
1433 setverdict(pass);
1434}
1435testcase TC_radio_status_imsi() runs on test_CT
1436{
1437 f_init();
1438 f_start_handlers(refers(f_TC_radio_status_imsi), testcasename(), 5);
1439 f_cleanup();
1440}
1441
1442
1443
Harald Welte99ed5072021-01-15 20:38:58 +01001444private function f_suspend_one(integer sgsn_idx, integer nri_idx, integer pcu_idx, integer bvc_idx,
1445 integer suffix)
Harald Welte00963752021-01-15 20:33:11 +01001446runs on GlobalTest_CT
1447{
1448 var RoutingAreaIdentification ra_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id.ra_id;
Harald Welte99ed5072021-01-15 20:38:58 +01001449 var OCT4 p_tmsi := f_gen_tmsi(suffix, nri_v := mp_sgsn_nri[sgsn_idx][nri_idx],
1450 nri_bitlen := mp_nri_bitlength);
1451 var OCT4 tlli := f_gprs_tlli_from_tmsi(p_tmsi, TLLI_LOCAL);
Harald Welte00963752021-01-15 20:33:11 +01001452 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_SUSPEND(tlli, ra_id);
1453 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1454 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_SUSPEND(tlli, ra_id);
1455 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1456
1457 pdu_tx := ts_BSSGP_SUSPEND_ACK(tlli, ra_id, int2oct(suffix, 1));
1458 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1459 pdu_rx := tr_BSSGP_SUSPEND_ACK(tlli, ra_id, int2oct(suffix, 1));
1460 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1461
1462 pdu_tx := ts_BSSGP_SUSPEND(tlli, ra_id);
1463 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1464 pdu_rx := tr_BSSGP_SUSPEND(tlli, ra_id);
1465 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1466
1467 /* These messages are simple passed through so just also test sending NACK */
1468 pdu_tx := ts_BSSGP_SUSPEND_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1469 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1470 pdu_rx := tr_BSSGP_SUSPEND_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1471 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1472}
1473
Harald Weltec5c33732021-01-15 21:04:35 +01001474private function f_TC_suspend(integer sgsn_idx, integer nri_idx, integer pcu_idx, integer bvc_idx)
1475runs on GlobalTest_CT {
Daniel Willmannfa67f492020-11-19 15:48:05 +01001476 var integer i;
Daniel Willmann165d6612020-11-19 14:27:29 +01001477
Daniel Willmannfa67f492020-11-19 15:48:05 +01001478 for (i := 0; i < 10; i := i+1) {
Harald Weltec5c33732021-01-15 21:04:35 +01001479 f_suspend_one(sgsn_idx, nri_idx, pcu_idx, bvc_idx, suffix := i);
Daniel Willmannfa67f492020-11-19 15:48:05 +01001480 }
1481 setverdict(pass);
1482}
Harald Welte3807ed12020-11-24 19:05:22 +01001483testcase TC_suspend() runs on GlobalTest_CT
Daniel Willmannfa67f492020-11-19 15:48:05 +01001484{
Harald Weltec5c33732021-01-15 21:04:35 +01001485 var integer sgsn_idx, nri_idx;
Daniel Willmannfa67f492020-11-19 15:48:05 +01001486 f_init();
Harald Welte3807ed12020-11-24 19:05:22 +01001487 f_global_init();
Harald Weltec5c33732021-01-15 21:04:35 +01001488 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx+1) {
1489 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx+1) {
1490 f_TC_suspend(sgsn_idx, nri_idx, pcu_idx:=0, bvc_idx:=0);
1491 }
1492 }
Daniel Willmannfa67f492020-11-19 15:48:05 +01001493 f_cleanup();
1494}
Harald Welte6dc2ac42020-11-16 09:16:17 +01001495
Harald Welte99ed5072021-01-15 20:38:58 +01001496private function f_resume_one(integer sgsn_idx, integer nri_idx, integer pcu_idx, integer bvc_idx,
1497 integer suffix)
Harald Welte00963752021-01-15 20:33:11 +01001498runs on GlobalTest_CT
1499{
1500 var RoutingAreaIdentification ra_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id.ra_id;
Harald Welte99ed5072021-01-15 20:38:58 +01001501 var OCT4 p_tmsi := f_gen_tmsi(suffix, nri_v := mp_sgsn_nri[sgsn_idx][nri_idx],
1502 nri_bitlen := mp_nri_bitlength);
1503 var OCT4 tlli := f_gprs_tlli_from_tmsi(p_tmsi, TLLI_LOCAL);
Harald Welte00963752021-01-15 20:33:11 +01001504 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1505 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1506 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1507 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1508
1509 pdu_tx := ts_BSSGP_RESUME_ACK(tlli, ra_id);
1510 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1511 pdu_rx := tr_BSSGP_RESUME_ACK(tlli, ra_id);
1512 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1513
1514 pdu_tx := ts_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1515 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1516 pdu_rx := tr_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1517 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1518
1519 /* These messages are simple passed through so just also test sending NACK */
1520 pdu_tx := ts_BSSGP_RESUME_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1521 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1522 pdu_rx := tr_BSSGP_RESUME_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1523 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1524}
1525
Harald Weltec5c33732021-01-15 21:04:35 +01001526private function f_TC_resume(integer sgsn_idx, integer nri_idx, integer pcu_idx, integer bvc_idx)
1527runs on GlobalTest_CT {
Daniel Willmann087a33d2020-11-19 15:58:43 +01001528 var integer i;
1529
Daniel Willmann087a33d2020-11-19 15:58:43 +01001530 for (i := 0; i < 10; i := i+1) {
Harald Weltec5c33732021-01-15 21:04:35 +01001531 f_resume_one(sgsn_idx, nri_idx, pcu_idx, bvc_idx, suffix := i);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001532 }
1533 setverdict(pass);
1534}
Harald Welte3807ed12020-11-24 19:05:22 +01001535testcase TC_resume() runs on GlobalTest_CT
Daniel Willmann087a33d2020-11-19 15:58:43 +01001536{
Harald Weltec5c33732021-01-15 21:04:35 +01001537 var integer sgsn_idx, nri_idx;
Daniel Willmann087a33d2020-11-19 15:58:43 +01001538 f_init();
Harald Welte3807ed12020-11-24 19:05:22 +01001539 f_global_init();
Harald Weltec5c33732021-01-15 21:04:35 +01001540 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx+1) {
1541 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx+1) {
1542 f_TC_resume(sgsn_idx, nri_idx, pcu_idx:=0, bvc_idx:=0);
1543 }
1544 }
Daniel Willmann087a33d2020-11-19 15:58:43 +01001545 f_cleanup();
1546}
1547
Harald Weltef8ef0282020-11-18 12:16:59 +01001548/* test the load-sharing between multiple NS-VC on the BSS side */
1549private function f_TC_dl_ud_unidir(charstring id) runs on BSSGP_ConnHdlr {
1550 var integer i;
1551
1552 for (i := 0; i < 10; i := i+1) {
1553 var octetstring payload := f_rnd_octstring(i);
1554 var template (value) PDU_BSSGP pdu_tx :=
1555 ts_BSSGP_DL_UD(g_pars.tlli, payload, omit, ts_BSSGP_IMSI(g_pars.imsi));
Harald Welte09a1ce42021-01-16 11:18:38 +01001556 SGSN_PTP[g_pars.sgsn_idx].send(pdu_tx);
Harald Weltef8ef0282020-11-18 12:16:59 +01001557 }
1558 setverdict(pass);
1559}
Harald Welte09a1ce42021-01-16 11:18:38 +01001560
1561private function f_TC_load_sharing_dl(integer sgsn_idx) runs on test_CT_NS
Harald Weltef8ef0282020-11-18 12:16:59 +01001562{
1563 const integer num_ue := 10;
1564 var BSSGP_ConnHdlr vc_conn[num_ue];
Harald Weltef8ef0282020-11-18 12:16:59 +01001565 /* all BVC are now fully brought up. We disconnect BSSGP from NS on the BSS
1566 * side so we get the raw NsUnitdataIndication and hence observe different
1567 * NSVCI */
1568 disconnect(g_pcu[0].vc_NS:NS_SP, g_pcu[0].vc_BSSGP:BSCP);
1569 connect(g_pcu[0].vc_NS:NS_SP, self:NS);
1570
1571 /* there may still be some NS-VCs coming up? After all, the BVC-RESET succeeds after the first
1572 * of the NS-VC is ALIVE/UNBLOCKED */
1573 f_sleep(3.0);
1574
1575 /* start parallel components generating DL-UNITDATA from the SGSN side */
1576 for (var integer i:= 0; i < num_ue; i := i+1) {
Harald Welte2ecbca82021-01-16 11:23:09 +01001577 vc_conn[i] := f_start_handler(refers(f_TC_dl_ud_unidir), testcasename(),
Harald Welte09a1ce42021-01-16 11:18:38 +01001578 5+i, 30.0, sgsn_idx);
Harald Weltef8ef0282020-11-18 12:16:59 +01001579 }
1580
1581 /* now start counting all the messages that were queued before */
1582 /* TODO: We have a hard-coded assumption of 4 NS-VC in one NSE/NS-VCG here! */
1583 var ro_integer rx_count := { 0, 0, 0, 0 };
1584 timer T := 2.0;
1585 T.start;
1586 alt {
1587 [] as_NsUdiCount(0, rx_count);
1588 [] as_NsUdiCount(1, rx_count);
1589 [] as_NsUdiCount(2, rx_count);
1590 [] as_NsUdiCount(3, rx_count);
1591 [] NS.receive(NsUnitdataIndication:{0,?,?,*,*}) { repeat; } /* signaling BVC */
1592 [] NS.receive(NsStatusIndication:?) { repeat; }
1593 [] NS.receive {
Harald Welted5b7e742021-01-27 10:50:24 +01001594 f_shutdown(__FILE__, __LINE__, fail, "Rx unexpected NS");
Harald Weltef8ef0282020-11-18 12:16:59 +01001595 }
1596 [] T.timeout {
1597 }
1598 }
1599 for (var integer i := 0; i < lengthof(rx_count); i := i+1) {
1600 log("Rx on NSVCI ", mp_nsconfig_pcu[0].nsvc[i].nsvci, ": ", rx_count[i]);
1601 if (rx_count[i] == 0) {
1602 setverdict(fail, "Data not shared over all NSVC");
1603 }
1604 }
Harald Welte09a1ce42021-01-16 11:18:38 +01001605}
1606
1607testcase TC_load_sharing_dl() runs on test_CT_NS
1608{
1609 var integer sgsn_idx, nri_idx;
1610 f_init();
1611 for (sgsn_idx:=0; sgsn_idx < NUM_SGSN; sgsn_idx:=sgsn_idx+1) {
1612 f_TC_load_sharing_dl(sgsn_idx);
1613 }
Harald Weltef8ef0282020-11-18 12:16:59 +01001614 setverdict(pass);
1615}
1616private altstep as_NsUdiCount(integer nsvc_idx, inout ro_integer roi) runs on test_CT_NS {
1617 var NsUnitdataIndication udi;
1618 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[0];
1619 [] NS.receive(NsUnitdataIndication:{bvcc.bvci, g_pcu[0].cfg.nsei, mp_nsconfig_pcu[0].nsvc[nsvc_idx].nsvci, *, *}) -> value udi {
1620 roi[nsvc_idx] := roi[nsvc_idx] + 1;
1621 repeat;
1622 }
1623}
1624type component test_CT_NS extends test_CT {
1625 port NS_PT NS;
1626};
1627
1628
Harald Welte0e188242020-11-22 21:46:48 +01001629/***********************************************************************
1630 * PAGING PS procedure
1631 ***********************************************************************/
1632
1633private function f_send_paging_ps(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1634 boolean use_sig := false)
1635runs on BSSGP_ConnHdlr return template (present) PDU_BSSGP {
1636 var template (value) PDU_BSSGP pdu_tx;
1637 var template (present) PDU_BSSGP pdu_rx;
1638 /* we always specify '0' as BVCI in the templates below, as we override it with
1639 * 'p4' later anyway */
1640 pdu_rx := tr_BSSGP_PS_PAGING(0);
1641 pdu_rx.pDU_BSSGP_PAGING_PS.iMSI := tr_BSSGP_IMSI(g_pars.imsi);
1642 if (ispresent(g_pars.p_tmsi)) {
1643 pdu_tx := ts_BSSGP_PS_PAGING_PTMSI(0, g_pars.imsi, oct2int(g_pars.p_tmsi));
1644 pdu_rx.pDU_BSSGP_PAGING_PS.pTMSI := tr_BSSGP_TMSI(oct2int(g_pars.p_tmsi));
1645 } else {
1646 pdu_tx := ts_BSSGP_PS_PAGING_IMSI(0, g_pars.imsi);
1647 pdu_rx.pDU_BSSGP_PAGING_PS.pTMSI := omit;
1648 }
1649 pdu_tx.pDU_BSSGP_PAGING_PS.paging_Field4 := p4;
1650 pdu_rx.pDU_BSSGP_PAGING_PS.paging_Field4 := p4;
1651 if (use_sig == false) {
Harald Welte158becf2020-12-09 12:32:32 +01001652 SGSN_PTP[sgsn_idx].send(pdu_tx);
Harald Welte0e188242020-11-22 21:46:48 +01001653 } else {
1654 SGSN_SIG[sgsn_idx].send(pdu_tx);
1655 }
1656 return pdu_rx;
1657}
1658
1659/* send paging defined by 'p4' on given SGSN-side index (ptp or signaling) and expect one paging to arrive on
1660 * specified PCU index */
1661private function f_send_paging_ps_exp_one_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1662 boolean use_sig := false,integer pcu_idx := 0)
1663runs on BSSGP_ConnHdlr {
1664 var template (present) PDU_BSSGP exp_rx;
Daniel Willmann1a859712020-12-04 00:59:45 +01001665 var boolean test_done := false;
Harald Welte0e188242020-11-22 21:46:48 +01001666 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1667 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1668 exp_rx := f_send_paging_ps(p4, sgsn_idx, use_sig);
1669 /* Expect paging to propagate to the one BSS addressed by the BVCI only */
1670 timer T := 2.0;
1671 T.start;
1672 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001673 [not use_sig and not test_done] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001674 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001675 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001676 repeat;
1677 }
1678 [not use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
1679 setverdict(fail, "Received paging on SIGNALING BVC, expected PTP BVC");
1680 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001681 [use_sig and not test_done] PCU_SIG[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001682 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001683 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001684 repeat;
1685 }
Harald Welte158becf2020-12-09 12:32:32 +01001686 [use_sig] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001687 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1688 }
Harald Welte158becf2020-12-09 12:32:32 +01001689 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001690 setverdict(fail, "Paging received on unexpected BVC");
1691 }
1692 [] any from PCU_SIG.receive(exp_rx) {
1693 setverdict(fail, "Paging received on unexpected BVC");
1694 }
Harald Welte158becf2020-12-09 12:32:32 +01001695 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01001696 setverdict(fail, "Different Paging than expected received PTP BVC");
1697 }
1698 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1699 setverdict(fail, "Different Paging than expected on SIGNALING BVC");
1700 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001701 [not test_done] T.timeout {
1702 setverdict(fail, "Timeout waiting for paging");
1703 }
1704 [test_done] T.timeout;
Harald Welte0e188242020-11-22 21:46:48 +01001705 }
1706}
1707
Harald Welte7462a592020-11-23 22:07:07 +01001708/* send a PS-PAGING but don't expect it to show up on any PTP or SIG BVC */
1709private function f_send_paging_ps_exp_no_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1710 boolean use_sig := false)
1711runs on BSSGP_ConnHdlr {
1712 var template (present) PDU_BSSGP exp_rx;
1713 exp_rx := f_send_paging_ps(p4, sgsn_idx, use_sig);
1714 /* Expect paging to propagate to no BSS */
1715 timer T := 2.0;
1716 T.start;
1717 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001718 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte7462a592020-11-23 22:07:07 +01001719 setverdict(fail, "Paging received on unexpected BVC");
1720 }
1721 [] any from PCU_SIG.receive(exp_rx) {
1722 setverdict(fail, "Paging received on unexpected BVC");
1723 }
Harald Welte158becf2020-12-09 12:32:32 +01001724 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte7462a592020-11-23 22:07:07 +01001725 setverdict(fail, "Different Paging received on PTP BVC");
1726 }
1727 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1728 setverdict(fail, "Different Paging received on SIGNALING BVC");
1729 }
1730 [] T.timeout {
1731 setverdict(pass);
1732 }
1733 }
1734}
1735
Harald Welte0e188242020-11-22 21:46:48 +01001736private function f_TC_paging_ps_ptp_bss(charstring id) runs on BSSGP_ConnHdlr
1737{
1738 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1739 * at that BVC (cell) only, and paging all over the BSS area is not possible */
Daniel Willmann2a330672021-01-18 18:50:02 +01001740 f_send_paging_ps_exp_one_bss(ts_BssgpP4BssArea, g_pars.sgsn_idx, false, 0);
Harald Welte0e188242020-11-22 21:46:48 +01001741}
1742testcase TC_paging_ps_ptp_bss() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001743 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001744 f_start_handlers(refers(f_TC_paging_ps_ptp_bss), testcasename(), 9);
Harald Welte0e188242020-11-22 21:46:48 +01001745 f_cleanup();
1746}
1747
1748/* PS-PAGING on PTP-BVC for Location Area */
1749private function f_TC_paging_ps_ptp_lac(charstring id) runs on BSSGP_ConnHdlr
1750{
1751 var template (present) PDU_BSSGP exp_rx;
1752 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1753 * at that BVC (cell) only, and paging all over the BSS area is not possible */
Daniel Willmann2a330672021-01-18 18:50:02 +01001754 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 +01001755}
1756testcase TC_paging_ps_ptp_lac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001757 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001758 f_start_handlers(refers(f_TC_paging_ps_ptp_lac), testcasename(), 10);
Harald Welte0e188242020-11-22 21:46:48 +01001759 f_cleanup();
1760}
1761
Harald Welte7462a592020-11-23 22:07:07 +01001762/* PS-PAGING on PTP-BVC for unknown Location Area */
1763private function f_TC_paging_ps_ptp_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1764{
1765 var GSM_Types.LocationAreaIdentification unknown_la := {
1766 mcc_mnc := '567F99'H,
1767 lac := 33333
1768 };
1769 /* as it's sent on the PTP BVC, we expect it to pass even for unknown LAC */
Daniel Willmann2a330672021-01-18 18:50:02 +01001770 f_send_paging_ps_exp_one_bss(ts_BssgpP4LAC(unknown_la), g_pars.sgsn_idx, false, 0);
Harald Welte7462a592020-11-23 22:07:07 +01001771}
1772testcase TC_paging_ps_ptp_lac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001773 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001774 f_start_handlers(refers(f_TC_paging_ps_ptp_lac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001775 f_cleanup();
1776}
1777
Harald Welte0e188242020-11-22 21:46:48 +01001778/* PS-PAGING on PTP-BVC for Routeing Area */
1779private function f_TC_paging_ps_ptp_rac(charstring id) runs on BSSGP_ConnHdlr
1780{
1781 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1782 * at that BVC (cell) only, and paging all over the BSS area is not possible */
Daniel Willmann2a330672021-01-18 18:50:02 +01001783 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 +01001784}
1785testcase TC_paging_ps_ptp_rac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001786 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001787 f_start_handlers(refers(f_TC_paging_ps_ptp_rac), testcasename(), 11);
Harald Welte0e188242020-11-22 21:46:48 +01001788 f_cleanup();
1789}
1790
Harald Welte7462a592020-11-23 22:07:07 +01001791/* PS-PAGING on PTP-BVC for unknown Routeing Area */
1792private function f_TC_paging_ps_ptp_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1793{
1794 var RoutingAreaIdentification unknown_ra := {
1795 lai := {
1796 mcc_mnc := '567F99'H,
1797 lac := 33333
1798 },
1799 rac := 254
1800 };
1801 /* as it's sent on the PTP BVC, we expect it to pass even for unknown RAC */
Daniel Willmann2a330672021-01-18 18:50:02 +01001802 f_send_paging_ps_exp_one_bss(ts_BssgpP4RAC(unknown_ra), g_pars.sgsn_idx, false, 0);
Harald Welte7462a592020-11-23 22:07:07 +01001803}
1804testcase TC_paging_ps_ptp_rac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001805 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001806 f_start_handlers(refers(f_TC_paging_ps_ptp_rac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001807 f_cleanup();
1808}
1809
Harald Welte0e188242020-11-22 21:46:48 +01001810/* PS-PAGING on PTP-BVC for BVCI (one cell) */
1811private function f_TC_paging_ps_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
1812{
1813 /* this should be the normal case for MS in READY MM state after a lower layer failure */
Daniel Willmann2a330672021-01-18 18:50:02 +01001814 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 +01001815}
1816testcase TC_paging_ps_ptp_bvci() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001817 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001818 f_start_handlers(refers(f_TC_paging_ps_ptp_bvci), testcasename(), 12);
Harald Welte0e188242020-11-22 21:46:48 +01001819 f_cleanup();
1820}
1821
Harald Welteb5a04aa2021-01-16 13:04:40 +01001822
1823/* PS-PAGING on PTP-BVC for BVCI (one cell) using IMSI only (no P-TMSI allocated) */
1824testcase TC_paging_ps_ptp_bvci_imsi() runs on test_CT {
1825 f_init();
1826 f_start_handlers(refers(f_TC_paging_ps_ptp_bvci), testcasename(), 12, have_ptmsi:=false);
1827 f_cleanup();
1828}
1829
Harald Weltecf200072021-01-16 15:20:46 +01001830/* Rejected PS-PAGING on PTP-BVC for BVCI (one cell) */
1831testcase TC_paging_ps_reject_ptp_bvci() runs on test_CT {
1832 f_init();
1833 f_start_handlers(refers(f_TC_paging_ps_reject_ptp_bvci), testcasename(), 16);
1834 f_cleanup();
1835}
1836
1837/* Rejected PS-PAGING on PTP-BVC for BVCI (one cell) using IMSI only (no P-TMSI allocated) */
1838private function f_TC_paging_ps_reject_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
1839{
1840 /* first send the PS-PAGING from SGSN -> PCU */
Daniel Willmann2a330672021-01-18 18:50:02 +01001841 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 +01001842 /* then simulate the PS-PAGING-REJECT from the PCU */
1843 f_send_paging_ps_rej(use_sig:=false);
1844}
1845testcase TC_paging_ps_reject_ptp_bvci_imsi() runs on test_CT {
1846 f_init();
1847 f_start_handlers(refers(f_TC_paging_ps_reject_ptp_bvci), testcasename(), 16, have_ptmsi:=false);
1848 f_cleanup();
1849}
Harald Welteb5a04aa2021-01-16 13:04:40 +01001850
Harald Welte7462a592020-11-23 22:07:07 +01001851/* PS-PAGING on PTP-BVC for unknown BVCI */
1852private function f_TC_paging_ps_ptp_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1853{
1854 /* as it's sent on the PTP BVC, we expect it to pass even for unknown BVCI */
Daniel Willmann2a330672021-01-18 18:50:02 +01001855 f_send_paging_ps_exp_one_bss(ts_BssgpP4Bvci(33333), g_pars.sgsn_idx, false, 0);
Harald Welte7462a592020-11-23 22:07:07 +01001856}
1857testcase TC_paging_ps_ptp_bvci_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001858 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001859 f_start_handlers(refers(f_TC_paging_ps_ptp_bvci_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001860 f_cleanup();
1861}
1862
Harald Welte7595d562021-01-16 19:09:20 +01001863/* DUMMY PAGING PS on PTP BVC */
1864private function f_TC_dummy_paging_ps_ptp(charstring id) runs on BSSGP_ConnHdlr
1865{
1866 f_sgsn2pcu(ts_BSSGP_DUMMY_PAGING_PS(g_pars.imsi, omit),
1867 tr_BSSGP_DUMMY_PAGING_PS(g_pars.imsi, omit), use_sig := false);
1868 f_pcu2sgsn(ts_BSSGP_DUMMY_PAGING_PS_RESP(g_pars.imsi, 1, 5),
1869 tr_BSSGP_DUMMY_PAGING_PS_RESP(g_pars.imsi, 1, 5), use_sig := false)
1870}
1871testcase TC_dummy_paging_ps_ptp() runs on test_CT {
1872 f_init();
1873 f_start_handlers(refers(f_TC_dummy_paging_ps_ptp), testcasename(), 11);
1874 f_cleanup();
1875}
1876
Harald Welte0e188242020-11-22 21:46:48 +01001877/* altstep for expecting BSSGP PDU on signaling BVC of given pcu_idx + storing in 'roi' */
1878private altstep as_paging_sig_pcu(integer pcu_idx, template (present) PDU_BSSGP exp_rx, inout ro_integer roi)
1879runs on BSSGP_ConnHdlr {
1880[] PCU_SIG[pcu_idx].receive(exp_rx) {
1881 if (ro_integer_contains(roi, pcu_idx)) {
1882 setverdict(fail, "Received multiple paging on same SIG BVC");
1883 }
1884 roi := roi & { pcu_idx };
1885 repeat;
1886 }
Harald Welte158becf2020-12-09 12:32:32 +01001887[] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001888 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1889 }
1890[] PCU_SIG[pcu_idx].receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1891 setverdict(fail, "Different Paging than expected received SIGNALING BVC");
1892 }
Harald Welte158becf2020-12-09 12:32:32 +01001893[] PCU_PTP[pcu_idx].receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01001894 setverdict(fail, "Different Paging than expected received PTP BVC");
1895 }
1896}
1897
1898type record of default ro_default;
1899
1900/* send PS-PAGING on SIG BVC, expect it to arrive on given list of PCU indexes */
1901private function f_send_paging_ps_exp_multi(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1902 ro_integer exp_on_pcu_idx) runs on BSSGP_ConnHdlr
1903{
1904 var template (present) PDU_BSSGP exp_rx;
Daniel Willmann193e1a02021-01-17 12:55:53 +01001905 exp_rx := f_send_paging_ps(p4, sgsn_idx, true);
Harald Welte0e188242020-11-22 21:46:48 +01001906
1907 /* FIXME: make sure the relevant BVCs/BSS are connected to the ports! */
1908 var ro_default defaults := {};
1909 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1910 var default d := activate(as_paging_sig_pcu(i, exp_rx, g_roi));
1911 defaults := defaults & { d };
1912 }
1913 f_sleep(2.0);
1914 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
1915 deactivate(defaults[i]);
1916 }
1917 log("Paging received on PCU ", g_roi);
1918
1919 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1920 var boolean rx_on_i := ro_integer_contains(g_roi, i);
1921 var boolean exp_on_i := ro_integer_contains(exp_on_pcu_idx, i);
1922 if (exp_on_i and not rx_on_i) {
1923 setverdict(fail, "PS-PAGING not received on ", mp_nsconfig_pcu[i].nsei);
1924 }
1925 if (not exp_on_i and rx_on_i) {
1926 setverdict(fail, "PS-PAGING not expected but received on ", mp_nsconfig_pcu[i].nsei);
1927 }
1928 }
1929 setverdict(pass);
1930}
1931
Harald Weltecf200072021-01-16 15:20:46 +01001932/* Send PAGING-PS-REJECT on SIG BVC, expect it to arrive on the "right" SGSN */
1933private function f_send_paging_ps_rej(boolean use_sig := true, integer pcu_idx := 0) runs on BSSGP_ConnHdlr
1934{
1935 var template (value) PDU_BSSGP pdu_tx;
1936 var template (present) PDU_BSSGP exp_rx;
1937 var PDU_BSSGP pdu_rx;
1938 timer T := 5.0;
1939 var template (omit) GsmTmsi tmsi_int := omit;
1940
1941 if (ispresent(g_pars.p_tmsi)) {
1942 tmsi_int := oct2int(g_pars.p_tmsi);
1943 }
1944
1945 pdu_tx := ts_BSSGP_PAGING_PS_REJ(g_pars.imsi, 23, 42, tmsi_int);
1946 exp_rx := tr_BSSGP_PAGING_PS_REJ(g_pars.imsi, 23, 42, tmsi_int);
1947
1948 if (use_sig) {
1949 PCU_SIG[pcu_idx].send(pdu_tx);
1950 } else {
1951 PCU_PTP[pcu_idx].send(pdu_tx);
1952 }
1953 T.start;
1954 alt {
1955 [use_sig] SGSN_SIG[g_pars.sgsn_idx].receive(exp_rx) -> value pdu_rx {
1956 setverdict(pass);
1957 }
1958 [use_sig] SGSN_SIG[g_pars.sgsn_idx].receive {
1959 setverdict(fail, "Unexpected PDU on SGSN");
1960 }
1961 [use_sig] any from SGSN_SIG.receive(exp_rx) -> value pdu_rx {
1962 setverdict(fail, "PAGING-PS-REJECT arrived on wrong SGSN");
1963 }
1964 [not use_sig] SGSN_PTP[g_pars.sgsn_idx].receive(exp_rx) -> value pdu_rx {
1965 setverdict(pass);
1966 }
1967 [not use_sig] SGSN_PTP[g_pars.sgsn_idx].receive {
1968 setverdict(fail, "Unexpected PDU on SGSN");
1969 }
1970 [not use_sig] any from SGSN_PTP.receive(exp_rx) -> value pdu_rx {
1971 setverdict(fail, "PAGING-PS-REJECT arrived on wrong SGSN");
1972 }
1973 [] T.timeout {
1974 setverdict(fail, "Timeout waiting for PAGING-PS-REJECT");
1975 }
1976 }
1977}
1978
Harald Welte0e188242020-11-22 21:46:48 +01001979/* PS-PAGING on SIG-BVC for BSS Area */
1980private function f_TC_paging_ps_sig_bss(charstring id) runs on BSSGP_ConnHdlr
1981{
1982 /* we expect the paging to arrive on all three NSE */
Daniel Willmann43320442021-01-17 14:07:05 +01001983 f_send_paging_ps_exp_multi(ts_BssgpP4BssArea, g_pars.sgsn_idx, {0, 1, 2});
Harald Welte0e188242020-11-22 21:46:48 +01001984}
1985testcase TC_paging_ps_sig_bss() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001986 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001987 f_start_handlers(refers(f_TC_paging_ps_sig_bss), testcasename(), 13);
Harald Welte0e188242020-11-22 21:46:48 +01001988 f_cleanup();
1989}
1990
1991/* PS-PAGING on SIG-BVC for Location Area */
1992private function f_TC_paging_ps_sig_lac(charstring id) runs on BSSGP_ConnHdlr
1993{
Daniel Willmann2c9300f2020-12-01 10:54:08 +01001994 /* The first LAC (13135) is shared by all three NSEs */
Daniel Willmann43320442021-01-17 14:07:05 +01001995 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 +01001996 /* Reset state */
1997 g_roi := {};
1998 /* Make LAC (13300) available on pcu index 2 */
1999 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
Daniel Willmann43320442021-01-17 14:07:05 +01002000 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 +01002001}
2002testcase TC_paging_ps_sig_lac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002003 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002004 f_start_handlers(refers(f_TC_paging_ps_sig_lac), testcasename(), 14);
Harald Welte0e188242020-11-22 21:46:48 +01002005 f_cleanup();
2006}
2007
Harald Welte7462a592020-11-23 22:07:07 +01002008/* PS-PAGING on SIG-BVC for unknown Location Area */
2009private function f_TC_paging_ps_sig_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
2010{
2011 var GSM_Types.LocationAreaIdentification unknown_la := {
2012 mcc_mnc := '567F99'H,
2013 lac := 33333
2014 };
Daniel Willmann2a330672021-01-18 18:50:02 +01002015 f_send_paging_ps_exp_no_bss(ts_BssgpP4LAC(unknown_la), g_pars.sgsn_idx, true);
Harald Welte7462a592020-11-23 22:07:07 +01002016}
2017testcase TC_paging_ps_sig_lac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002018 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002019 f_start_handlers(refers(f_TC_paging_ps_sig_lac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002020 f_cleanup();
2021}
2022
Harald Welte0e188242020-11-22 21:46:48 +01002023/* PS-PAGING on SIG-BVC for Routeing Area */
2024private function f_TC_paging_ps_sig_rac(charstring id) runs on BSSGP_ConnHdlr
2025{
Daniel Willmann2c9300f2020-12-01 10:54:08 +01002026 /* Only PCU index 0 has a matching BVC with the RA ID */
Daniel Willmann43320442021-01-17 14:07:05 +01002027 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 +01002028 g_roi := {};
2029 /* PCU index 1 and 2 have a matching BVC with the RA ID */
Daniel Willmann43320442021-01-17 14:07:05 +01002030 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 +01002031 g_roi := {};
2032 /* PCU index 2 has two matching BVCs with the RA ID */
2033 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
Daniel Willmann43320442021-01-17 14:07:05 +01002034 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 +01002035}
2036testcase TC_paging_ps_sig_rac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002037 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002038 f_start_handlers(refers(f_TC_paging_ps_sig_rac), testcasename(), 15);
Harald Welte0e188242020-11-22 21:46:48 +01002039 f_cleanup();
2040}
2041
Harald Welte7462a592020-11-23 22:07:07 +01002042/* PS-PAGING on SIG-BVC for unknown Routeing Area */
2043private function f_TC_paging_ps_sig_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
2044{
2045 var RoutingAreaIdentification unknown_ra := {
2046 lai := {
2047 mcc_mnc := '567F99'H,
2048 lac := 33333
2049 },
2050 rac := 254
2051 };
Daniel Willmann2a330672021-01-18 18:50:02 +01002052 f_send_paging_ps_exp_no_bss(ts_BssgpP4RAC(unknown_ra), g_pars.sgsn_idx, true);
Harald Welte7462a592020-11-23 22:07:07 +01002053}
2054testcase TC_paging_ps_sig_rac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002055 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002056 f_start_handlers(refers(f_TC_paging_ps_sig_rac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002057 f_cleanup();
2058}
2059
Harald Welte0e188242020-11-22 21:46:48 +01002060/* PS-PAGING on SIG-BVC for BVCI (one cell) */
2061private function f_TC_paging_ps_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
2062{
Daniel Willmann43320442021-01-17 14:07:05 +01002063 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 +01002064}
2065testcase TC_paging_ps_sig_bvci() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002066 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002067 f_start_handlers(refers(f_TC_paging_ps_sig_bvci), testcasename(), 16);
Harald Welte0e188242020-11-22 21:46:48 +01002068 f_cleanup();
2069}
2070
Harald Welteb5a04aa2021-01-16 13:04:40 +01002071/* PS-PAGING on SIG-BVC for BVCI (one cell) using IMSI only (no P-TMSI allocated) */
2072testcase TC_paging_ps_sig_bvci_imsi() runs on test_CT {
2073 f_init();
2074 f_start_handlers(refers(f_TC_paging_ps_sig_bvci), testcasename(), 16, have_ptmsi:=false);
2075 f_cleanup();
2076}
2077
Harald Weltecf200072021-01-16 15:20:46 +01002078/* Rejected PS-PAGING on SIG-BVC for BVCI (one cell) */
2079private function f_TC_paging_ps_reject_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
2080{
2081 /* first send the PS-PAGING from SGSN -> PCU */
Daniel Willmann43320442021-01-17 14:07:05 +01002082 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 +01002083 /* then simulate the PS-PAGING-REJECT from the PCU */
2084 f_send_paging_ps_rej(use_sig:=true);
2085
2086}
2087testcase TC_paging_ps_reject_sig_bvci() runs on test_CT {
2088 f_init();
2089 f_start_handlers(refers(f_TC_paging_ps_reject_sig_bvci), testcasename(), 16);
2090 f_cleanup();
2091}
2092
2093/* Rejected PS-PAGING on SIG-BVC for BVCI (one cell) using IMSI only (no P-TMSI allocated) */
2094testcase TC_paging_ps_reject_sig_bvci_imsi() runs on test_CT {
2095 f_init();
2096 f_start_handlers(refers(f_TC_paging_ps_reject_sig_bvci), testcasename(), 16, have_ptmsi:=false);
2097 f_cleanup();
2098}
2099
Harald Welte7462a592020-11-23 22:07:07 +01002100/* PS-PAGING on SIG-BVC for unknown BVCI */
2101private function f_TC_paging_ps_sig_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
2102{
Daniel Willmann2a330672021-01-18 18:50:02 +01002103 f_send_paging_ps_exp_no_bss(ts_BssgpP4Bvci(33333), g_pars.sgsn_idx, true);
Harald Welte7462a592020-11-23 22:07:07 +01002104}
2105testcase TC_paging_ps_sig_bvci_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002106 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002107 f_start_handlers(refers(f_TC_paging_ps_sig_bvci_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002108 f_cleanup();
2109}
2110
Harald Welte7595d562021-01-16 19:09:20 +01002111/* DUMMY PAGING PS on SIG BVC */
2112private function f_TC_dummy_paging_ps_sig(charstring id) runs on BSSGP_ConnHdlr
2113{
2114 f_sgsn2pcu(ts_BSSGP_DUMMY_PAGING_PS(g_pars.imsi, omit),
2115 tr_BSSGP_DUMMY_PAGING_PS(g_pars.imsi, omit), use_sig := true);
2116 f_pcu2sgsn(ts_BSSGP_DUMMY_PAGING_PS_RESP(g_pars.imsi, 1, 5),
2117 tr_BSSGP_DUMMY_PAGING_PS_RESP(g_pars.imsi, 1, 5), use_sig := true)
2118}
2119testcase TC_dummy_paging_ps_sig() runs on test_CT {
2120 f_init();
2121 f_start_handlers(refers(f_TC_dummy_paging_ps_sig), testcasename(), 11);
2122 f_cleanup();
2123}
2124
Harald Welte7462a592020-11-23 22:07:07 +01002125
Harald Welte0e188242020-11-22 21:46:48 +01002126
2127/***********************************************************************
2128 * PAGING CS procedure
2129 ***********************************************************************/
2130
2131private function f_send_paging_cs(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
2132 boolean use_sig := false)
2133runs on BSSGP_ConnHdlr return template (present) PDU_BSSGP {
2134 var template (value) PDU_BSSGP pdu_tx;
2135 var template (present) PDU_BSSGP pdu_rx;
2136 /* we always specify '0' as BVCI in the templates below, as we override it with
2137 * 'p4' later anyway */
2138 pdu_rx := tr_BSSGP_CS_PAGING(0);
2139 pdu_rx.pDU_BSSGP_PAGING_CS.iMSI := tr_BSSGP_IMSI(g_pars.imsi);
2140 if (ispresent(g_pars.p_tmsi)) {
2141 pdu_tx := ts_BSSGP_CS_PAGING_PTMSI(0, g_pars.imsi, oct2int(g_pars.p_tmsi));
2142 pdu_rx.pDU_BSSGP_PAGING_CS.tMSI := tr_BSSGP_TMSI(oct2int(g_pars.p_tmsi));
2143 } else {
2144 pdu_tx := ts_BSSGP_CS_PAGING_IMSI(0, g_pars.imsi);
2145 pdu_rx.pDU_BSSGP_PAGING_CS.tMSI := omit;
2146 }
2147 pdu_tx.pDU_BSSGP_PAGING_CS.paging_Field4 := p4;
2148 pdu_rx.pDU_BSSGP_PAGING_CS.paging_Field4 := p4;
2149 if (use_sig == false) {
Harald Welte158becf2020-12-09 12:32:32 +01002150 SGSN_PTP[sgsn_idx].send(pdu_tx);
Harald Welte0e188242020-11-22 21:46:48 +01002151 } else {
2152 SGSN_SIG[sgsn_idx].send(pdu_tx);
2153 }
2154 return pdu_rx;
2155}
2156
2157/* send paging defined by 'p4' on given SGSN-side index (ptp or signaling) and expect one paging to arrive on
2158 * specified PCU index */
2159private function f_send_paging_cs_exp_one_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
2160 boolean use_sig := false,integer pcu_idx := 0)
2161runs on BSSGP_ConnHdlr {
2162 var template (present) PDU_BSSGP exp_rx;
Daniel Willmann1a859712020-12-04 00:59:45 +01002163 var boolean test_done := false;
Harald Welte0e188242020-11-22 21:46:48 +01002164 /* doesn't really make sense: Sending to a single BVCI means the message ends up
2165 * at that BVC (cell) only, and paging all over the BSS area is not possible */
2166 exp_rx := f_send_paging_cs(p4, sgsn_idx, use_sig);
2167 /* Expect paging to propagate to the one BSS addressed by the BVCI only */
2168 timer T := 2.0;
2169 T.start;
2170 alt {
Harald Welte158becf2020-12-09 12:32:32 +01002171 [not use_sig and not test_done] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01002172 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01002173 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01002174 repeat;
2175 }
2176 [not use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
2177 setverdict(fail, "Received paging on SIGNALING BVC, expected PTP BVC");
2178 }
Daniel Willmann1a859712020-12-04 00:59:45 +01002179 [use_sig and not test_done] PCU_SIG[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01002180 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01002181 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01002182 repeat;
2183 }
Harald Welte158becf2020-12-09 12:32:32 +01002184 [use_sig] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01002185 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
2186 }
Harald Welte158becf2020-12-09 12:32:32 +01002187 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01002188 setverdict(fail, "Paging received on unexpected BVC");
2189 }
2190 [] any from PCU_SIG.receive(exp_rx) {
2191 setverdict(fail, "Paging received on unexpected BVC");
2192 }
Harald Welte158becf2020-12-09 12:32:32 +01002193 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01002194 setverdict(fail, "Different Paging than expected received PTP BVC");
2195 }
2196 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
2197 setverdict(fail, "Different Paging than expected on SIGNALING BVC");
2198 }
Daniel Willmann1a859712020-12-04 00:59:45 +01002199 [not test_done] T.timeout {
2200 setverdict(fail, "Timeout while waiting for paging")
2201 }
2202 [test_done] T.timeout;
Harald Welte0e188242020-11-22 21:46:48 +01002203 }
2204}
2205
Harald Welte7462a592020-11-23 22:07:07 +01002206/* send a CS-PAGING but don't expect it to show up on any PTP or SIG BVC */
2207private function f_send_paging_cs_exp_no_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
2208 boolean use_sig := false)
2209runs on BSSGP_ConnHdlr {
2210 var template (present) PDU_BSSGP exp_rx;
2211 exp_rx := f_send_paging_cs(p4, sgsn_idx, use_sig);
2212 /* Expect paging to propagate to no BSS */
2213 timer T := 2.0;
2214 T.start;
2215 alt {
Harald Welte158becf2020-12-09 12:32:32 +01002216 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte7462a592020-11-23 22:07:07 +01002217 setverdict(fail, "Paging received on unexpected BVC");
2218 }
2219 [] any from PCU_SIG.receive(exp_rx) {
2220 setverdict(fail, "Paging received on unexpected BVC");
2221 }
Harald Welte158becf2020-12-09 12:32:32 +01002222 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
Harald Welte7462a592020-11-23 22:07:07 +01002223 setverdict(fail, "Different Paging received on PTP BVC");
2224 }
2225 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
2226 setverdict(fail, "Different Paging received on SIGNALING BVC");
2227 }
2228 [] T.timeout {
2229 setverdict(pass);
2230 }
2231 }
2232}
2233
Harald Welte0e188242020-11-22 21:46:48 +01002234private function f_TC_paging_cs_ptp_bss(charstring id) runs on BSSGP_ConnHdlr
2235{
2236 /* doesn't really make sense: Sending to a single BVCI means the message ends up
2237 * at that BVC (cell) only, and paging all over the BSS area is not possible */
2238 f_send_paging_cs_exp_one_bss(ts_BssgpP4BssArea, 0, false, 0);
2239}
2240testcase TC_paging_cs_ptp_bss() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002241 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002242 f_start_handlers(refers(f_TC_paging_cs_ptp_bss), testcasename(), 17);
Harald Welte0e188242020-11-22 21:46:48 +01002243 f_cleanup();
2244}
2245
2246/* CS-PAGING on PTP-BVC for Location Area */
2247private function f_TC_paging_cs_ptp_lac(charstring id) runs on BSSGP_ConnHdlr
2248{
2249 var template (present) PDU_BSSGP exp_rx;
2250 /* doesn't really make sense: Sending to a single BVCI means the message ends up
2251 * at that BVC (cell) only, and paging all over the BSS area is not possible */
2252 f_send_paging_cs_exp_one_bss(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, false, 0);
2253}
2254testcase TC_paging_cs_ptp_lac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002255 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002256 f_start_handlers(refers(f_TC_paging_cs_ptp_lac), testcasename(), 18);
Harald Welte0e188242020-11-22 21:46:48 +01002257 f_cleanup();
2258}
2259
Harald Welte7462a592020-11-23 22:07:07 +01002260/* CS-PAGING on PTP-BVC for unknown Location Area */
2261private function f_TC_paging_cs_ptp_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
2262{
2263 var GSM_Types.LocationAreaIdentification unknown_la := {
2264 mcc_mnc := '567F99'H,
2265 lac := 33333
2266 };
2267 /* as it's sent on the PTP BVC, we expect it to pass even for unknown LAC */
2268 f_send_paging_cs_exp_one_bss(ts_BssgpP4LAC(unknown_la), 0, false, 0);
2269}
2270testcase TC_paging_cs_ptp_lac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002271 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002272 f_start_handlers(refers(f_TC_paging_cs_ptp_lac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002273 f_cleanup();
2274}
2275
Harald Welte0e188242020-11-22 21:46:48 +01002276/* CS-PAGING on PTP-BVC for Routeing Area */
2277private function f_TC_paging_cs_ptp_rac(charstring id) runs on BSSGP_ConnHdlr
2278{
2279 /* doesn't really make sense: Sending to a single BVCI means the message ends up
2280 * at that BVC (cell) only, and paging all over the BSS area is not possible */
2281 f_send_paging_cs_exp_one_bss(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, false, 0);
2282}
2283testcase TC_paging_cs_ptp_rac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002284 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002285 f_start_handlers(refers(f_TC_paging_cs_ptp_rac), testcasename(), 19);
Harald Welte0e188242020-11-22 21:46:48 +01002286 f_cleanup();
2287}
2288
Harald Welte7462a592020-11-23 22:07:07 +01002289/* CS-PAGING on PTP-BVC for unknown Routeing Area */
2290private function f_TC_paging_cs_ptp_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
2291{
2292 var RoutingAreaIdentification unknown_ra := {
2293 lai := {
2294 mcc_mnc := '567F99'H,
2295 lac := 33333
2296 },
2297 rac := 254
2298 };
2299 /* as it's sent on the PTP BVC, we expect it to pass even for unknown RAC */
2300 f_send_paging_cs_exp_one_bss(ts_BssgpP4RAC(unknown_ra), 0, false, 0);
2301}
2302testcase TC_paging_cs_ptp_rac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002303 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002304 f_start_handlers(refers(f_TC_paging_cs_ptp_rac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002305 f_cleanup();
2306}
2307
Harald Welte0e188242020-11-22 21:46:48 +01002308/* CS-PAGING on PTP-BVC for BVCI (one cell) */
2309private function f_TC_paging_cs_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
2310{
2311 /* this should be the normal case for MS in READY MM state after a lower layer failure */
2312 f_send_paging_cs_exp_one_bss(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, false, 0);
2313}
2314testcase TC_paging_cs_ptp_bvci() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002315 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002316 f_start_handlers(refers(f_TC_paging_cs_ptp_bvci), testcasename(), 20);
Harald Welte0e188242020-11-22 21:46:48 +01002317 f_cleanup();
2318}
2319
Harald Welte7462a592020-11-23 22:07:07 +01002320/* CS-PAGING on PTP-BVC for unknown BVCI */
2321private function f_TC_paging_cs_ptp_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
2322{
2323 /* as it's sent on the PTP BVC, we expect it to pass even for unknown BVCI */
2324 f_send_paging_cs_exp_one_bss(ts_BssgpP4Bvci(33333), 0, false, 0);
2325}
2326testcase TC_paging_cs_ptp_bvci_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002327 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002328 f_start_handlers(refers(f_TC_paging_cs_ptp_bvci_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002329 f_cleanup();
2330}
2331
Harald Welte0e188242020-11-22 21:46:48 +01002332/* send CS-PAGING on SIG BVC, expect it to arrive on given list of PCU indexes */
2333private function f_send_paging_cs_exp_multi(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
2334 ro_integer exp_on_pcu_idx) runs on BSSGP_ConnHdlr
2335{
2336 var template (present) PDU_BSSGP exp_rx;
2337 exp_rx := f_send_paging_cs(p4, 0, true);
2338
2339 /* FIXME: make sure the relevant BVCs/BSS are connected to the ports! */
2340 var ro_default defaults := {};
2341 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
2342 var default d := activate(as_paging_sig_pcu(i, exp_rx, g_roi));
2343 defaults := defaults & { d };
2344 }
2345 f_sleep(2.0);
2346 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2347 deactivate(defaults[i]);
2348 }
2349 log("Paging received on PCU ", g_roi);
2350
2351 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
2352 var boolean rx_on_i := ro_integer_contains(g_roi, i);
2353 var boolean exp_on_i := ro_integer_contains(exp_on_pcu_idx, i);
2354 if (exp_on_i and not rx_on_i) {
2355 setverdict(fail, "PS-PAGING not received on ", mp_nsconfig_pcu[i].nsei);
2356 }
2357 if (not exp_on_i and rx_on_i) {
2358 setverdict(fail, "PS-PAGING not expected but received on ", mp_nsconfig_pcu[i].nsei);
2359 }
2360 }
2361 setverdict(pass);
2362}
2363
2364/* CS-PAGING on SIG-BVC for BSS Area */
2365private function f_TC_paging_cs_sig_bss(charstring id) runs on BSSGP_ConnHdlr
2366{
2367 /* we expect the paging to arrive on all three NSE */
2368 f_send_paging_cs_exp_multi(ts_BssgpP4BssArea, 0, {0, 1, 2});
2369}
2370testcase TC_paging_cs_sig_bss() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002371 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002372 f_start_handlers(refers(f_TC_paging_cs_sig_bss), testcasename(), 13);
Harald Welte0e188242020-11-22 21:46:48 +01002373 f_cleanup();
2374}
2375
2376/* CS-PAGING on SIG-BVC for Location Area */
2377private function f_TC_paging_cs_sig_lac(charstring id) runs on BSSGP_ConnHdlr
2378{
Daniel Willmannd4fb73c2020-12-07 13:57:17 +01002379 /* The first LAC (13135) is shared by all three NSEs */
2380 f_send_paging_cs_exp_multi(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, {0, 1, 2});
2381 /* Reset state */
2382 g_roi := {};
2383 /* Make LAC (13300) available on pcu index 2 */
2384 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
2385 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 +01002386}
2387testcase TC_paging_cs_sig_lac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002388 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002389 f_start_handlers(refers(f_TC_paging_cs_sig_lac), testcasename(), 14);
Harald Welte0e188242020-11-22 21:46:48 +01002390 f_cleanup();
2391}
2392
Harald Welte7462a592020-11-23 22:07:07 +01002393/* CS-PAGING on SIG-BVC for unknown Location Area */
2394private function f_TC_paging_cs_sig_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
2395{
2396 var GSM_Types.LocationAreaIdentification unknown_la := {
2397 mcc_mnc := '567F99'H,
2398 lac := 33333
2399 };
2400 f_send_paging_cs_exp_no_bss(ts_BssgpP4LAC(unknown_la), 0, true);
2401}
2402testcase TC_paging_cs_sig_lac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002403 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002404 f_start_handlers(refers(f_TC_paging_cs_sig_lac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002405 f_cleanup();
2406}
2407
Harald Welte0e188242020-11-22 21:46:48 +01002408/* CS-PAGING on SIG-BVC for Routeing Area */
2409private function f_TC_paging_cs_sig_rac(charstring id) runs on BSSGP_ConnHdlr
2410{
Daniel Willmannd4fb73c2020-12-07 13:57:17 +01002411 /* Only PCU index 0 has a matching BVC with the RA ID */
Harald Welte0e188242020-11-22 21:46:48 +01002412 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 +01002413 g_roi := {};
2414 /* PCU index 1 and 2 have a matching BVC with the RA ID */
2415 f_send_paging_cs_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[2].cell_id.ra_id), 0, {1, 2});
2416 g_roi := {};
2417 /* PCU index 2 has two matching BVCs with the RA ID */
2418 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
2419 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 +01002420}
2421testcase TC_paging_cs_sig_rac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002422 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002423 f_start_handlers(refers(f_TC_paging_cs_sig_rac), testcasename(), 15);
Harald Welte0e188242020-11-22 21:46:48 +01002424 f_cleanup();
2425}
2426
Harald Welte7462a592020-11-23 22:07:07 +01002427/* CS-PAGING on SIG-BVC for unknown Routeing Area */
2428private function f_TC_paging_cs_sig_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
2429{
2430 var RoutingAreaIdentification unknown_ra := {
2431 lai := {
2432 mcc_mnc := '567F99'H,
2433 lac := 33333
2434 },
2435 rac := 254
2436 };
2437 f_send_paging_cs_exp_no_bss(ts_BssgpP4RAC(unknown_ra), 0, true);
2438}
2439testcase TC_paging_cs_sig_rac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002440 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002441 f_start_handlers(refers(f_TC_paging_cs_sig_rac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002442 f_cleanup();
2443}
2444
Harald Welte0e188242020-11-22 21:46:48 +01002445/* CS-PAGING on SIG-BVC for BVCI (one cell) */
2446private function f_TC_paging_cs_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
2447{
2448 f_send_paging_cs_exp_multi(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, {0});
2449}
2450testcase TC_paging_cs_sig_bvci() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002451 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002452 f_start_handlers(refers(f_TC_paging_cs_sig_bvci), testcasename(), 16);
Harald Welte0e188242020-11-22 21:46:48 +01002453 f_cleanup();
2454}
2455
Harald Welte7462a592020-11-23 22:07:07 +01002456/* CS-PAGING on SIG-BVC for unknown BVCI */
2457private function f_TC_paging_cs_sig_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
2458{
2459 f_send_paging_cs_exp_no_bss(ts_BssgpP4Bvci(33333), 0, true);
2460}
2461testcase TC_paging_cs_sig_bvci_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002462 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002463 f_start_handlers(refers(f_TC_paging_cs_sig_bvci_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002464 f_cleanup();
2465}
2466
Harald Welte4f91c3b2020-12-09 12:25:51 +01002467/***********************************************************************
2468 * FLUSH-LL procedure
2469 ***********************************************************************/
2470
Daniel Willmannc7c8e322021-11-25 18:13:21 +01002471private function f_TC_flush_ll_bvci_new(charstring id) runs on BSSGP_ConnHdlr {
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002472 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
2473 var integer i;
2474 for (i := 0; i < 10; i := i+1) {
2475 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_FLUSH_LL(g_pars.tlli, bvci, bvci_new := bvci);
2476 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2477 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_FLUSH_LL(g_pars.tlli, bvci, bvci_new := bvci);
2478
2479 f_sgsn2pcu(pdu_tx, pdu_rx, use_sig := true);
2480
Daniel Willmannc7c8e322021-11-25 18:13:21 +01002481 pdu_tx := ts_BSSGP_FLUSH_LL_ACK(g_pars.tlli, int2oct(1, 1), 23, bvci_new := bvci);
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002482 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Daniel Willmannc7c8e322021-11-25 18:13:21 +01002483 pdu_rx := tr_BSSGP_FLUSH_LL_ACK(g_pars.tlli, int2oct(1, 1), 23, bvci_new := bvci);
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002484
2485 f_pcu2sgsn(pdu_tx, pdu_rx, use_sig := true);
2486 }
2487 setverdict(pass);
2488}
Daniel Willmannc7c8e322021-11-25 18:13:21 +01002489
2490testcase TC_flush_ll_bvci_new() runs on test_CT
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002491{
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002492 f_init();
Daniel Willmannc7c8e322021-11-25 18:13:21 +01002493 f_start_handlers(refers(f_TC_flush_ll_bvci_new), testcasename(), 6);
2494 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
2495 f_cleanup();
2496}
2497
2498private function f_TC_flush_ll_no_bvci_new(charstring id) runs on BSSGP_ConnHdlr {
2499 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
2500 var integer i;
2501 for (i := 0; i < 10; i := i+1) {
2502 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_FLUSH_LL(g_pars.tlli, bvci);
2503 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2504 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_FLUSH_LL(g_pars.tlli, bvci);
2505
2506 f_sgsn2pcu(pdu_tx, pdu_rx, use_sig := true);
2507
2508 pdu_tx := ts_BSSGP_FLUSH_LL_ACK(g_pars.tlli, int2oct(0, 1), 23);
2509 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2510 pdu_rx := tr_BSSGP_FLUSH_LL_ACK(g_pars.tlli, int2oct(0, 1), 23);
2511
2512 f_pcu2sgsn(pdu_tx, pdu_rx, use_sig := true);
2513 }
2514 setverdict(pass);
2515}
2516
2517testcase TC_flush_ll_no_bvci_new() runs on test_CT
2518{
2519 f_init();
2520 f_start_handlers(refers(f_TC_flush_ll_no_bvci_new), testcasename(), 6);
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002521 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002522 f_cleanup();
2523}
Harald Welte6dc2ac42020-11-16 09:16:17 +01002524
Harald Welte4f91c3b2020-12-09 12:25:51 +01002525/***********************************************************************
2526 * SGSN-INVOKE-TRACE procedure
2527 ***********************************************************************/
2528
Harald Weltef8e5c5d2020-11-27 22:37:23 +01002529private altstep as_bssgp_g_pcu_count(integer pcu_idx, template (present) PDU_BSSGP exp_rx, inout ro_integer roi)
2530runs on GlobalTest_CT {
2531[] G_PCU[pcu_idx].receive(exp_rx) from g_pcu[pcu_idx].vc_BSSGP {
2532 if (ro_integer_contains(roi, pcu_idx)) {
2533 setverdict(fail, "Received multiple on same SIG BVC");
2534 }
2535 roi := roi & { pcu_idx };
2536 repeat;
2537 }
2538}
2539/* send a INVOKE-TRACE from SGSN and expect to receive a copy on each NSE */
2540testcase TC_trace() runs on GlobalTest_CT
2541{
2542 var BSSGP_ConnHdlr vc_conn;
2543 f_init();
2544 f_global_init();
2545
2546 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_INVOKE_TRACE('23'O, '4321'O);
2547 var template (present) PDU_BSSGP exp_rx := ts_BSSGP_INVOKE_TRACE('23'O, '4321'O);
2548
2549 var ro_default defaults := {};
2550 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2551 activate(as_bssgp_g_pcu_count(i, exp_rx, g_roi));
2552 }
2553 G_SGSN[0].send(pdu_tx);
2554 f_sleep(2.0);
2555 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2556 deactivate(defaults[i]);
2557 }
2558
2559 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2560 if (not ro_integer_contains(g_roi, i)) {
2561 setverdict(fail, "Failed to receive TRACE on PCU index ", i);
2562 }
2563 }
2564 setverdict(pass);
2565
2566 f_cleanup();
2567}
2568
Harald Welte4f91c3b2020-12-09 12:25:51 +01002569/***********************************************************************
2570 * LLC-DISCARDED procedure
2571 ***********************************************************************/
2572
Harald Weltec0351d12020-11-27 22:49:02 +01002573private function f_TC_llc_discarded(charstring id) runs on BSSGP_ConnHdlr {
2574 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
2575
2576 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_LLC_DISCARDED(g_pars.tlli, 23, bvci, 2342);
2577 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2578 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_LLC_DISCARDED(g_pars.tlli, 23, bvci, 2342);
2579
2580 f_pcu2sgsn(pdu_tx, pdu_rx, use_sig := true);
2581
2582 setverdict(pass);
2583}
2584/* Send a LLC-DISCARDED from BSS side and expect it to show up on SGSN (SIG BVC) */
2585testcase TC_llc_discarded() runs on test_CT
2586{
Harald Weltec0351d12020-11-27 22:49:02 +01002587 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002588 f_start_handlers(refers(f_TC_llc_discarded), testcasename(), 6);
Harald Weltec0351d12020-11-27 22:49:02 +01002589 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Weltec0351d12020-11-27 22:49:02 +01002590 f_cleanup();
2591}
2592
Harald Welte4f91c3b2020-12-09 12:25:51 +01002593/***********************************************************************
2594 * OVERLOAD procedure
2595 ***********************************************************************/
2596
Harald Weltef20af412020-11-28 16:11:11 +01002597/* Send an OVERLOAD from SGSN side and expect it to show up on each PCU (SIG BVC) */
2598testcase TC_overload() runs on GlobalTest_CT
2599{
2600 f_init();
2601 f_global_init();
2602
2603 var template (value) PDU_BSSGP pdu_tx := ts_OVERLOAD('1'B);
2604 var template (present) PDU_BSSGP exp_rx := tr_OVERLOAD('1'B);
2605
2606 var ro_default defaults := {};
2607 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2608 activate(as_bssgp_g_pcu_count(i, exp_rx, g_roi));
2609 }
2610 G_SGSN[0].send(pdu_tx);
2611 f_sleep(2.0);
2612 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2613 deactivate(defaults[i]);
2614 }
2615
2616 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2617 if (not ro_integer_contains(g_roi, i)) {
2618 setverdict(fail, "Failed to receive OVERLOAD on PCU index ", i);
2619 }
2620 }
2621 setverdict(pass);
2622
2623 f_cleanup();
2624}
2625
Harald Welte4f91c3b2020-12-09 12:25:51 +01002626/***********************************************************************
2627 * BVC-BLOCK / BVC-UNBLOCK procedure
2628 ***********************************************************************/
2629
Harald Welte239aa502020-11-24 23:14:20 +01002630private function f_block_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2631{
2632 var BSSGP_BVC_CT bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2633 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2634 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2635
2636 SGSN_MGMT.clear;
2637 PCU_MGMT.clear;
2638
2639 /* block the PTP BVC from the PCU side */
2640 PCU_MGMT.send(BssgpBlockRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to bvc_ct;
2641 /* expect state on both PCU and SGSN side to change */
2642 interleave {
2643 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_BLOCKED)) from bvc_ct;
Harald Welte572b0172021-03-30 13:19:56 +02002644 [] SGSN_MGMT.receive(tr_BssgpStsInd(mp_nsconfig_sgsn[0].nsei, bvc_cfg.bvci, BVC_S_BLOCKED));
2645 [] SGSN_MGMT.receive(tr_BssgpStsInd(mp_nsconfig_sgsn[1].nsei, bvc_cfg.bvci, BVC_S_BLOCKED));
2646 /* Doesn't auto-scale with NUM_SGSN */
Harald Welte239aa502020-11-24 23:14:20 +01002647 }
2648 setverdict(pass);
2649}
2650testcase TC_bvc_block_ptp() runs on test_CT
2651{
2652 f_init();
2653 f_sleep(1.0);
2654 f_block_ptp_bvc_from_pcu(0, 0);
2655 f_cleanup();
2656}
2657
2658private function f_unblock_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2659{
2660 var BSSGP_BVC_CT bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2661 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2662 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2663
2664 SGSN_MGMT.clear;
2665 PCU_MGMT.clear;
2666
2667 /* block the PTP BVC from the PCU side */
2668 PCU_MGMT.send(BssgpUnblockRequest:{}) to bvc_ct;
2669 /* expect state on both PCU and SGSN side to change */
2670 interleave {
2671 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_UNBLOCKED)) from bvc_ct;
Harald Welte572b0172021-03-30 13:19:56 +02002672 [] SGSN_MGMT.receive(tr_BssgpStsInd(mp_nsconfig_sgsn[0].nsei, bvc_cfg.bvci, BVC_S_UNBLOCKED));
2673 [] SGSN_MGMT.receive(tr_BssgpStsInd(mp_nsconfig_sgsn[1].nsei, bvc_cfg.bvci, BVC_S_UNBLOCKED));
2674 /* Doesn't auto-scale with NUM_SGSN */
Harald Welte239aa502020-11-24 23:14:20 +01002675 }
2676 setverdict(pass);
2677}
2678testcase TC_bvc_unblock_ptp() runs on test_CT
2679{
2680 f_init();
2681 f_sleep(1.0);
2682 f_block_ptp_bvc_from_pcu(0, 0);
2683 f_sleep(1.0);
2684 f_unblock_ptp_bvc_from_pcu(0, 0);
2685 f_cleanup();
2686}
2687
Harald Welte4f91c3b2020-12-09 12:25:51 +01002688/***********************************************************************
2689 * BVC-RESET procedure
2690 ***********************************************************************/
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002691private altstep as_count_bvc_reset(integer sgsn_idx, BssgpBvci bvci, inout roro_integer roroi)
2692runs on test_CT {
2693 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(sgsn_idx, bvci);
2694 [] SGSN_MGMT.receive(BssgpResetIndication:{bvci}) from sgsn_bvc_ct {
2695 roroi[sgsn_idx] := roroi[sgsn_idx] & { bvci };
2696 repeat;
2697 }
2698}
Harald Welte60a8ec72020-11-25 17:12:53 +01002699private altstep as_ignore_status(BSSGP_BVC_MGMT_PT pt) {
2700[] pt.receive(BssgpStatusIndication:?) { repeat; }
2701}
2702private function f_get_sgsn_bvc_ct(integer sgsn_idx, BssgpBvci bvci) runs on test_CT return BSSGP_BVC_CT {
2703 for (var integer i := 0; i < lengthof(g_sgsn[sgsn_idx].cfg.bvc); i := i+1) {
2704 if (g_sgsn[sgsn_idx].cfg.bvc[i].bvci == bvci) {
2705 return g_sgsn[sgsn_idx].vc_BSSGP_BVC[i];
2706 }
2707 }
2708 return null;
2709}
2710private function f_reset_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2711{
2712 var BSSGP_BVC_CT pcu_bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2713 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2714 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002715 var ro_default defaults;
2716 var integer i;
Harald Welte60a8ec72020-11-25 17:12:53 +01002717
2718 SGSN_MGMT.clear;
2719 PCU_MGMT.clear;
2720
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002721 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
2722 g_roroi[i] := {};
2723 }
2724
Harald Welte60a8ec72020-11-25 17:12:53 +01002725 /* block the PTP BVC from the PCU side */
2726 PCU_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to pcu_bvc_ct;
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002727
Harald Welte60a8ec72020-11-25 17:12:53 +01002728 /* expect state on both PCU and SGSN side to change */
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002729 defaults := { activate(as_ignore_status(SGSN_MGMT)) };
2730
2731 /* Activate altsteps: One for each SGSN */
2732 for (i := 0; i < lengthof(g_sgsn); i := i+1) {
2733 var default d := activate(as_count_bvc_reset(i, bvc_cfg.bvci, g_roroi));
2734 defaults := defaults & { d };
Harald Welte60a8ec72020-11-25 17:12:53 +01002735 }
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002736
2737 timer T := 3.0;
2738 T.start;
2739 alt {
2740 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_BLOCKED)) from pcu_bvc_ct {
2741 g_roi := g_roi & { bvc_cfg.bvci };
2742 repeat;
2743 }
2744 [] T.timeout;
2745 }
2746
2747 for (i := 0; i < lengthof(defaults); i := i+1) {
2748 deactivate(defaults[i]);
2749 }
2750
2751 /* Check if BVC-RESET was received at all SGSNs */
2752 for (i := 0; i < lengthof(g_sgsn); i := i+1) {
2753 if (not ro_integer_contains(g_roroi[i], bvc_cfg.bvci)) {
2754 setverdict(fail, "Missing SGSN[", i, "] BVC-BLOCK of BVCI=", bvc_cfg.bvci);
2755 }
2756 }
2757
Harald Welte60a8ec72020-11-25 17:12:53 +01002758 setverdict(pass);
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002759 f_cleanup();
Harald Welte60a8ec72020-11-25 17:12:53 +01002760}
2761/* Send a BVC-RESET for a PTP BVC from the BSS side: expect it to propagate */
2762testcase TC_bvc_reset_ptp_from_bss() runs on test_CT
2763{
2764 f_init();
2765 f_sleep(3.0);
2766 f_reset_ptp_bvc_from_pcu(0, 0);
2767 f_cleanup();
2768}
2769
Harald Welteb1cc0b22021-03-30 12:16:36 +02002770private altstep as_count_bvc_sts(integer sgsn_idx, BssgpBvci bvci,
2771 template (present) BvcState exp_bvc_state, inout roro_integer roroi)
Harald Welte16786e92020-11-27 19:11:56 +01002772runs on test_CT {
2773 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(sgsn_idx, bvci);
Harald Welteb1cc0b22021-03-30 12:16:36 +02002774 [] SGSN_MGMT.receive(tr_BssgpStsInd(?, bvci, exp_bvc_state)) from sgsn_bvc_ct {
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002775 roroi[sgsn_idx] := roroi[sgsn_idx] & { bvci };
Harald Welteb2647f72020-12-07 14:36:35 +01002776 repeat;
Harald Welte16786e92020-11-27 19:11:56 +01002777 }
2778}
Harald Welteb1cc0b22021-03-30 12:16:36 +02002779
2780private altstep as_count_bvc_block(integer sgsn_idx, BssgpBvci bvci, inout roro_integer roroi)
2781runs on test_CT {
2782 [] as_count_bvc_sts(sgsn_idx, bvci, BVC_S_BLOCKED, roroi);
2783}
2784
2785private altstep as_count_bvc_unblock(integer sgsn_idx, BssgpBvci bvci, inout roro_integer roroi)
2786runs on test_CT {
2787 [] as_count_bvc_sts(sgsn_idx, bvci, BVC_S_UNBLOCKED, roroi);
2788}
2789
Harald Welte16786e92020-11-27 19:11:56 +01002790/* reset the signaling BVC from one BSS; expect no signaling BVC reset on SGSN; but BVC-BLOCK for PTP */
2791testcase TC_bvc_reset_sig_from_bss() runs on test_CT {
2792
2793 f_init();
2794 f_sleep(3.0);
2795
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002796 for (var integer i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
2797 g_roroi[i] := {};
2798 }
2799
Harald Welte16786e92020-11-27 19:11:56 +01002800 /* Start BVC-RESET procedure for BVCI=0 */
2801 PCU_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to g_pcu[0].vc_BSSGP;
2802
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002803 /* Activate altsteps: One for each PTP BVC and SGSN within that PCUs NSE */
Harald Welte16786e92020-11-27 19:11:56 +01002804 var ro_default defaults := {};
2805 for (var integer i := 0; i < lengthof(g_pcu[0].cfg.bvc); i := i+1) {
2806 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[i];
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002807 for (var integer j := 0; j < lengthof(g_sgsn); j := j+1) {
2808 var default d := activate(as_count_bvc_block(j, bvcc.bvci, g_roroi));
2809 defaults := defaults & { d };
2810 }
Harald Welte16786e92020-11-27 19:11:56 +01002811 }
2812
2813 timer T := 3.0;
2814 T.start;
2815 alt {
2816 [] SGSN_MGMT.receive(BssgpResetIndication:{0}) {
2817 setverdict(fail, "BSS-side Reset of BVCI=0 should not propagate");
2818 }
2819 [] T.timeout;
2820 }
2821
2822 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2823 deactivate(defaults[i]);
2824 }
2825
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002826 /* check if BVC-block was received on all expected BVC/SGSN */
Harald Welte16786e92020-11-27 19:11:56 +01002827 for (var integer i := 0; i < lengthof(g_pcu[0].cfg.bvc); i := i+1) {
2828 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[i];
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002829 for (var integer j := 0; j < lengthof(g_sgsn); j := j+1) {
2830 if (not ro_integer_contains(g_roroi[j], bvcc.bvci)) {
2831 setverdict(fail, "Missing SGSN[", j, "] BVC-BLOCK of BVCI=", bvcc.bvci);
2832 }
Harald Welte16786e92020-11-27 19:11:56 +01002833 }
2834 }
2835
2836 /* check if BVC-block was not received on any unexpected BVC is not required as
2837 * such a message would basically run into 'no matching clause' */
Daniel Willmannf2590212020-12-04 14:20:50 +01002838 setverdict(pass);
Harald Welte16786e92020-11-27 19:11:56 +01002839 f_cleanup();
2840}
2841
Harald Welte60a8ec72020-11-25 17:12:53 +01002842private function f_reset_ptp_bvc_from_sgsn(integer pcu_idx, integer bvc_idx) runs on test_CT
2843{
2844 var BSSGP_BVC_CT pcu_bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2845 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2846 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2847 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(0, bvc_cfg.bvci);
2848 var default d;
2849
2850 SGSN_MGMT.clear;
2851 PCU_MGMT.clear;
2852
2853 /* block the PTP BVC from the PCU side */
2854 SGSN_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to sgsn_bvc_ct;
2855 /* expect state on both PCU and SGSN side to change */
2856 d := activate(as_ignore_status(PCU_MGMT));
2857 interleave {
2858 [] SGSN_MGMT.receive(tr_BssgpStsInd(?, bvc_cfg.bvci, BVC_S_BLOCKED)) from sgsn_bvc_ct;
2859 [] PCU_MGMT.receive(BssgpResetIndication:{bvc_cfg.bvci}) from pcu_bvc_ct;
2860 }
2861 deactivate(d);
2862 setverdict(pass);
2863}
Daniel Willmannc5bbcc62021-09-24 13:17:20 +02002864
Harald Welte60a8ec72020-11-25 17:12:53 +01002865/* Send a BVC-RESET for a PTP BVC from the SGSN side: expect it to propagate */
2866testcase TC_bvc_reset_ptp_from_sgsn() runs on test_CT
2867{
2868 f_init();
2869 f_sleep(3.0);
2870 f_reset_ptp_bvc_from_sgsn(0, 0);
2871 f_cleanup();
2872}
2873
Daniel Willmannc5bbcc62021-09-24 13:17:20 +02002874/* Send a BVC-RESET for a blocked PTP BVC from the SGSN side: expect NS-STATUS with cause BVCI unknown */
2875testcase TC_bvc_reset_blocked_ptp_from_sgsn() runs on GlobalTest_CT
2876{
2877 f_init();
2878 f_global_init();
2879 f_sleep(3.0);
2880 /* Make sure NS for BVC is down and try again */
2881 f_disable_ns_pcu(0);
2882 f_sleep(10.0);
2883
2884 var BssgpBvcConfig bvc_cfg := g_pcu[0].cfg.bvc[0];
2885 SGSN_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to f_get_sgsn_bvc_ct(0, bvc_cfg.bvci);
2886
2887 /* Check for NS-STATUS with BVCI unknown, ignore other messages */
2888 var template (present) PDU_BSSGP exp_rx :=
2889 tr_BSSGP_STATUS(bvc_cfg.bvci, BSSGP_CAUSE_BVCI_UNKNOWN, ?);
2890
2891 alt {
2892 [] G_SGSN[0].receive(exp_rx) {
2893 setverdict(pass);
2894 }
2895 [] SGSN_MGMT.receive(BssgpStatusIndication:{*, bvc_cfg.bvci, BVC_S_UNBLOCKED}) {
2896 setverdict(fail, "BVC unblocked that should be gone on BSS side");
2897 }
2898 [] SGSN_MGMT.receive {
2899 repeat;
2900 }
2901 [] G_SGSN[0].receive {
2902 repeat;
2903 }
2904 }
2905
2906 f_cleanup();
2907}
2908
Daniel Willmannef7015f2021-01-08 00:43:56 +01002909private altstep as_ignore_mgmt(BSSGP_BVC_MGMT_PT pt) {
2910 [] pt.receive {repeat; }
2911}
2912
Harald Welte16786e92020-11-27 19:11:56 +01002913private altstep as_count_bvc0_block(integer pcu_idx, Nsei nsei, inout ro_integer roi)
2914runs on test_CT {
2915 var BSSGP_CT pcu_ct := g_pcu[pcu_idx].vc_BSSGP;
2916 [] PCU_MGMT.receive(BssgpResetIndication:{0}) from pcu_ct {
2917 roi := roi & { nsei };
Daniel Willmannef7015f2021-01-08 00:43:56 +01002918 repeat;
Harald Welte16786e92020-11-27 19:11:56 +01002919 }
2920}
Daniel Willmannef7015f2021-01-08 00:43:56 +01002921
Harald Welte16786e92020-11-27 19:11:56 +01002922/* reset the signaling BVC from the SGSN; expect all signaling BVC on all BSS to be reset */
2923testcase TC_bvc_reset_sig_from_sgsn() runs on test_CT {
2924
2925 f_init();
2926 f_sleep(3.0);
2927
Daniel Willmannef7015f2021-01-08 00:43:56 +01002928 SGSN_MGMT.clear;
2929 PCU_MGMT.clear;
2930
Harald Welte16786e92020-11-27 19:11:56 +01002931 /* Start BVC-RESET procedure for BVCI=0 */
2932 SGSN_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to g_sgsn[0].vc_BSSGP;
2933
Daniel Willmannef7015f2021-01-08 00:43:56 +01002934 /* Defaults match in reverse activation order, this one is a catch-all for Status indications
2935 * and reset indications sent from other components (like the ptp_bvcs). If we don't drain
2936 * the port and a different message sits at the front we wait forever and fail the test.
2937 */
2938 var ro_default defaults := { activate(as_ignore_mgmt(PCU_MGMT)) };
2939
Harald Welte16786e92020-11-27 19:11:56 +01002940 /* Activate altsteps: One for each PCU NSE */
Harald Welte16786e92020-11-27 19:11:56 +01002941 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2942 var NSConfiguration nscfg := mp_nsconfig_pcu[i];
2943 var default d := activate(as_count_bvc0_block(i, nscfg.nsei, g_roi));
2944 defaults := defaults & { d };
2945 }
2946
2947 f_sleep(3.0);
2948
2949 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2950 deactivate(defaults[i]);
2951 }
2952
2953 /* check if BVC-block was received on all expected BVC */
2954 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2955 var NSConfiguration nscfg := mp_nsconfig_pcu[i];
2956 if (not ro_integer_contains(g_roi, nscfg.nsei)) {
2957 setverdict(fail, "Missing PCU-side BVC-RESET of BVCI=0 on PCU index ", i);
2958 }
2959 }
2960
2961 /* check if BVC-block was not received on any unexpected BVC is not required as
2962 * such a message would basically run into 'no matching clause' */
2963
2964 f_cleanup();
2965}
2966
Harald Welte299aa482020-12-09 15:10:55 +01002967/***********************************************************************
2968 * FLOW-CONTROL-BVC procedure
2969 ***********************************************************************/
2970
2971private altstep as_g_count_sgsn(integer sgsn_idx, inout ro_integer roi,
2972 template PDU_BSSGP exp_rx, template (omit) PDU_BSSGP tx_reply)
2973runs on GlobalTest_CT {
2974 [] G_SGSN[sgsn_idx].receive(exp_rx) {
2975 roi := roi & { sgsn_idx };
2976 if (ispresent(tx_reply)) {
2977 G_SGSN[sgsn_idx].send(tx_reply);
2978 }
Harald Welte5fb01742021-01-15 21:07:52 +01002979 repeat;
Harald Welte299aa482020-12-09 15:10:55 +01002980 }
2981}
2982/* Send FC-BVC from simulated PCU; expect each SGSN to receive it; expect PCU to receive ACK */
2983testcase TC_fc_bvc() runs on GlobalTest_CT
2984{
2985 f_init();
2986 f_global_init_ptp();
2987
Pau Espin Pedrol6ee01262021-02-05 13:05:06 +01002988 var template (value) PDU_BSSGP pdu_tx := ts_BVC_FC_BVC(10240, 2000, 1024, 1000, '01'O);
Harald Welte299aa482020-12-09 15:10:55 +01002989 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2990 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 +01002991 var template (value) PDU_BSSGP ack_tx :=
2992 ts_BVC_FC_BVC_ACK(pdu_tx.pDU_BSSGP_FLOW_CONTROL_BVC.tag.unstructured_Value);
Harald Welte299aa482020-12-09 15:10:55 +01002993
2994 /* Send a FC-BVC from BSS to gbproxy, expect an ACK in response */
2995 G_PCU[0].send(pdu_tx);
2996
2997 /* Activate altsteps: One for each SGSN-side PTP BVC port */
2998 var ro_default defaults := {};
2999 for (var integer i := 0; i < lengthof(g_sgsn); i := i+1) {
3000 var default d := activate(as_g_count_sgsn(i, g_roi, pdu_rx, ack_tx));
3001 defaults := defaults & { d };
3002 }
3003
3004 f_sleep(3.0);
3005
3006 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
3007 deactivate(defaults[i]);
3008 }
3009
3010 /* check if BVC-block was received on all expected BVC */
3011 for (var integer i := 0; i < lengthof(g_sgsn); i := i+1) {
3012 if (not ro_integer_contains(g_roi, i)) {
3013 setverdict(fail, "Missing BVC-FLOW-CONTROL on SGSN index ", i);
3014 }
3015 }
3016
3017 /* Expect ACK on PCU side */
3018 G_PCU[0].receive(ack_tx);
3019
3020 setverdict(pass);
3021
3022 f_cleanup();
3023}
3024
Harald Weltecc3894b2020-12-09 16:50:12 +01003025/***********************************************************************
3026 * FLOW-CONTROL-MS procedure
3027 ***********************************************************************/
3028
3029private function f_TC_fc_ms(charstring id) runs on BSSGP_ConnHdlr {
3030 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
3031
3032 var template (value) PDU_BSSGP fc_tx := ts_BVC_FC_MS(g_pars.tlli, 100, 200, '12'O);
3033 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
3034 var template (present) PDU_BSSGP fc_rx := tr_BVC_FC_MS(g_pars.tlli, 100, 200, '12'O);
3035 var template (value) PDU_BSSGP ack_tx := ts_BVC_FC_MS_ACK(g_pars.tlli, '12'O);
3036
3037 f_pcu2sgsn(fc_tx, fc_rx, use_sig := false);
3038 f_sgsn2pcu(ack_tx, ack_tx, use_sig := false);
3039
3040 setverdict(pass);
3041}
3042/* Send a FLOW-CONTROL-MS from BSS side and expect it to show up on SGSN (PTP BVC) */
3043testcase TC_fc_ms() runs on test_CT
3044{
Harald Weltecc3894b2020-12-09 16:50:12 +01003045 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01003046 f_start_handlers(refers(f_TC_fc_ms), testcasename(), 21);
Harald Weltecc3894b2020-12-09 16:50:12 +01003047 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Weltecc3894b2020-12-09 16:50:12 +01003048 f_cleanup();
3049}
3050
Harald Welted6f89812021-01-16 18:57:49 +01003051/***********************************************************************
3052 * MS-REGISTRATION ENQUIRY procedure
3053 ***********************************************************************/
Harald Weltecc3894b2020-12-09 16:50:12 +01003054
Harald Welted6f89812021-01-16 18:57:49 +01003055private function f_TC_ms_reg_enq(charstring id) runs on BSSGP_ConnHdlr
3056{
Daniel Willmann04918c02021-07-06 13:59:04 +02003057 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 +01003058 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);
3059}
3060testcase TC_ms_reg_enq() runs on test_CT
3061{
3062 f_init();
3063 f_start_handlers(refers(f_TC_ms_reg_enq), testcasename(), 22);
3064 f_cleanup();
3065}
Harald Welte299aa482020-12-09 15:10:55 +01003066
Harald Weltef86f1852021-01-16 21:56:17 +01003067/***********************************************************************
3068 * RIM (RAN Information Management)
3069 ***********************************************************************/
3070
3071/* Our tests here are rather synthetic, as they don't reflect normal message flows
3072 as they would be observed in a live network. However, for testing gbproxy, this shouldn't
3073 matter as gbproxy is not concerned with anything but the source / destination routing
3074 information */
3075
3076/* gbproxy must route all unknown RIM Routing Info (Cell Id) to the SGSN. We just define
3077 one here of which we know it is not used among the [simulated] PCUs */
3078const BssgpCellId cell_id_sgsn := {
3079 ra_id := {
3080 lai := {
3081 mcc_mnc := c_mcc_mnc,
3082 lac := 65534
3083 },
3084 rac := 0
3085 },
3086 cell_id := 65533
3087};
3088
3089/* Send 'tx' on PTP-BVCI from PCU; expect 'rx' on any of our SGSN (RIM can be routed anywhere) */
3090friend function f_rim_pcu2sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
3091 integer pcu_idx := 0) runs on GlobalTest_CT {
3092 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +01003093 timer T := 2.0;
Harald Weltef86f1852021-01-16 21:56:17 +01003094
3095 RIM_PCU[pcu_idx].send(tx);
3096 T.start;
3097 alt {
3098 [] any from RIM_SGSN.receive(exp_rx) {
3099 setverdict(pass);
3100 }
3101 [] any from RIM_SGSN.receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +01003102 f_shutdown(__FILE__, __LINE__, fail, log2str("Unexpected BSSGP on SGSN side: ", rx));
Harald Weltef86f1852021-01-16 21:56:17 +01003103 }
3104 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +01003105 f_shutdown(__FILE__, __LINE__, fail,
3106 log2str("Timeout waiting for BSSGP on SGSN side: ", exp_rx));
Harald Weltef86f1852021-01-16 21:56:17 +01003107 }
3108 }
3109}
3110
3111/* Send 'tx' on PTP-BVCI from SGSN; expect 'rx' on PCU */
3112friend function f_rim_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
3113 integer sgsn_idx := 0, integer pcu_idx := 0) runs on GlobalTest_CT {
3114 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +01003115 timer T := 2.0;
Harald Weltef86f1852021-01-16 21:56:17 +01003116
3117 RIM_SGSN[sgsn_idx].send(tx);
3118 T.start;
3119 alt {
3120 [] RIM_PCU[pcu_idx].receive(exp_rx) {
3121 setverdict(pass);
3122 }
3123 [] RIM_PCU[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +01003124 f_shutdown(__FILE__, __LINE__, fail, log2str("Unexpected BSSGP on PCU side: ", rx));
Harald Weltef86f1852021-01-16 21:56:17 +01003125 }
3126 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +01003127 f_shutdown(__FILE__, __LINE__, fail,
3128 log2str("Timeout waiting for BSSGP on PCU side: ", exp_rx));
Harald Weltef86f1852021-01-16 21:56:17 +01003129 }
3130 }
3131}
3132
3133/* Send 'tx' on PTP-BVCI from SRC-PCU; expect 'rx' on DST-PCU */
3134friend function f_rim_pcu2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
3135 integer src_pcu_idx, integer dst_pcu_idx) runs on GlobalTest_CT {
3136 var integer rx_idx;
3137 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +01003138 timer T := 2.0;
Harald Weltef86f1852021-01-16 21:56:17 +01003139
3140 RIM_PCU[src_pcu_idx].send(tx);
3141 T.start;
3142 alt {
3143 [] RIM_PCU[dst_pcu_idx].receive(exp_rx) -> value rx{
3144 setverdict(pass);
3145 }
3146 [] any from RIM_PCU.receive(exp_rx) -> @index value rx_idx {
3147 setverdict(fail, "Received RIM on wrong PCU[", rx_idx ,"], expected on PCU[", dst_pcu_idx, "]");
3148 }
3149 [] any from RIM_SGSN.receive(exp_rx) {
3150 setverdict(fail, "Received RIM on SGSN but expected it on other PCU");
3151 }
3152 [] any from RIM_SGSN.receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +01003153 f_shutdown(__FILE__, __LINE__, fail, log2str("Unexpected BSSGP on SGSN side: ", rx));
Harald Weltef86f1852021-01-16 21:56:17 +01003154 }
3155 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +01003156 f_shutdown(__FILE__, __LINE__, fail,
3157 log2str("Timeout waiting for BSSGP on SGSN side: ", exp_rx));
Harald Weltef86f1852021-01-16 21:56:17 +01003158 }
3159 }
3160}
3161
3162
3163type function rim_fn(integer sgsn_idx, integer pcu_idx, integer bvc_idx) runs on GlobalTest_CT;
3164
3165/* helper function for the RIM test cases: Execute 'fn' for each BVC on each PCU for
3166 each SGSN */
3167private function f_rim_iterator(rim_fn fn) runs on GlobalTest_CT
3168{
3169 var integer sgsn_idx, pcu_idx, bvc_idx;
3170 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx+1) {
3171 for (pcu_idx := 0; pcu_idx < lengthof(g_pcu); pcu_idx := pcu_idx+1) {
3172 for (bvc_idx := 0; bvc_idx < lengthof(g_pcu[pcu_idx].cfg.bvc); bvc_idx := bvc_idx+1) {
3173 log("Testing RIM SGSN[", sgsn_idx, "] <-> PCU[", pcu_idx, "][", bvc_idx, "]");
3174 fn.apply(sgsn_idx, pcu_idx, bvc_idx);
3175 }
3176 }
3177 }
3178}
3179
3180/* RAN-INFORMATION-REQUEST */
3181private function f_TC_rim_info_req(integer sgsn_idx, integer pcu_idx, integer bvc_idx := 0)
3182runs on GlobalTest_CT
3183{
3184 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003185 var template (value) RAN_Information_Request_RIM_Container cont_tx;
3186 var template RAN_Information_Request_RIM_Container cont_rx;
3187 var template RIM_Routing_Address ra_pcu;
3188 var template RIM_Routing_Address ra_sgsn;
Harald Weltef86f1852021-01-16 21:56:17 +01003189
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003190 ra_pcu := t_RIM_Routing_Address_cid(cell_id);
3191 ra_sgsn := t_RIM_Routing_Address_cid(cell_id_sgsn);
3192
3193 cont_tx := ts_RAN_Information_Request_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3194 ts_RIM_Sequence_Number(0),
3195 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
3196 cont_rx := tr_RAN_Information_Request_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
3197 tr_RIM_Sequence_Number(0),
3198 tr_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
3199
3200 f_rim_pcu2sgsn(ts_RAN_INFORMATION_REQUEST(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3201 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3202 cont := cont_tx),
3203 tr_RAN_INFORMATION_REQUEST(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3204 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3205 cont := cont_rx),
3206 pcu_idx);
3207
3208 f_rim_sgsn2pcu(ts_RAN_INFORMATION_REQUEST(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3209 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3210 cont := cont_tx),
3211 tr_RAN_INFORMATION_REQUEST(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3212 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3213 cont := cont_rx),
Harald Weltef86f1852021-01-16 21:56:17 +01003214 sgsn_idx, pcu_idx);
3215}
3216testcase TC_rim_info_req() runs on GlobalTest_CT
3217{
3218 f_init();
3219 f_global_init();
3220 f_rim_iterator(refers(f_TC_rim_info_req));
3221 f_cleanup();
3222}
3223
3224/* RAN-INFORMATION */
3225private function f_TC_rim_info(integer sgsn_idx, integer pcu_idx, integer bvc_idx := 0)
3226runs on GlobalTest_CT
3227{
3228 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003229 var template (value) RAN_Information_RIM_Container cont_tx;
3230 var template RAN_Information_RIM_Container cont_rx;
3231 var template RIM_Routing_Address ra_pcu;
3232 var template RIM_Routing_Address ra_sgsn;
Harald Weltef86f1852021-01-16 21:56:17 +01003233
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003234 ra_pcu := t_RIM_Routing_Address_cid(cell_id);
3235 ra_sgsn := t_RIM_Routing_Address_cid(cell_id_sgsn);
3236
3237 cont_tx := ts_RAN_Information_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3238 ts_RIM_Sequence_Number(0),
3239 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
3240
3241 cont_rx := tr_RAN_Information_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
3242 tr_RIM_Sequence_Number(0),
3243 tr_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
3244
3245 f_rim_pcu2sgsn(ts_PDU_BSSGP_RAN_INFORMATION(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3246 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3247 cont := cont_tx),
3248 tr_PDU_BSSGP_RAN_INFORMATION(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3249 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3250 cont := cont_rx),
3251 pcu_idx);
3252
3253 f_rim_sgsn2pcu(ts_PDU_BSSGP_RAN_INFORMATION(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3254 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3255 cont := cont_tx),
3256 tr_PDU_BSSGP_RAN_INFORMATION(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3257 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3258 cont := cont_rx),
Harald Weltef86f1852021-01-16 21:56:17 +01003259 sgsn_idx, pcu_idx);
3260}
3261testcase TC_rim_info() runs on GlobalTest_CT
3262{
3263 f_init();
3264 f_global_init();
3265 f_rim_iterator(refers(f_TC_rim_info));
3266 f_cleanup();
3267}
3268
3269/* RAN-INFORMATION-ACK */
3270private function f_TC_rim_info_ack(integer sgsn_idx, integer pcu_idx, integer bvc_idx := 0)
3271runs on GlobalTest_CT
3272{
3273 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003274 var template (value) RAN_Information_Ack_RIM_Container cont_tx;
3275 var template RAN_Information_Ack_RIM_Container cont_rx;
3276 var template RIM_Routing_Address ra_pcu;
3277 var template RIM_Routing_Address ra_sgsn;
Harald Weltef86f1852021-01-16 21:56:17 +01003278
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003279 ra_pcu := t_RIM_Routing_Address_cid(cell_id);
3280 ra_sgsn := t_RIM_Routing_Address_cid(cell_id_sgsn);
3281
3282 cont_tx := ts_RAN_Information_Ack_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3283 ts_RIM_Sequence_Number(0));
3284
3285 cont_rx := tr_RAN_Information_Ack_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
3286 tr_RIM_Sequence_Number(0));
3287
3288 f_rim_pcu2sgsn(ts_PDU_BSSGP_RAN_INFORMATION_ACK(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3289 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3290 cont := cont_tx),
3291 tr_PDU_BSSGP_RAN_INFORMATION_ACK(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3292 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3293 cont := cont_rx),
3294 pcu_idx);
3295
3296 f_rim_sgsn2pcu(ts_PDU_BSSGP_RAN_INFORMATION_ACK(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3297 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3298 cont := cont_tx),
3299 tr_PDU_BSSGP_RAN_INFORMATION_ACK(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3300 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3301 cont := cont_rx),
Harald Weltef86f1852021-01-16 21:56:17 +01003302 sgsn_idx, pcu_idx);
3303}
3304testcase TC_rim_info_ack() runs on GlobalTest_CT
3305{
3306 f_init();
3307 f_global_init();
3308 f_rim_iterator(refers(f_TC_rim_info_ack));
3309 f_cleanup();
3310}
3311
3312/* RAN-INFORMATION-ERROR */
3313private function f_TC_rim_info_error(integer sgsn_idx, integer pcu_idx, integer bvc_idx := 0)
3314runs on GlobalTest_CT
3315{
3316 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003317 var template (value) RAN_Information_Error_RIM_Container cont_tx;
3318 var template RAN_Information_Error_RIM_Container cont_rx;
3319 var template RIM_Routing_Address ra_pcu;
3320 var template RIM_Routing_Address ra_sgsn;
Harald Weltef86f1852021-01-16 21:56:17 +01003321
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003322 ra_pcu := t_RIM_Routing_Address_cid(cell_id);
3323 ra_sgsn := t_RIM_Routing_Address_cid(cell_id_sgsn);
3324
3325 cont_tx := ts_RAN_Information_Error_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3326 ts_BSSGP_CAUSE(BSSGP_CAUSE_EQUIMENT_FAILURE),
Pau Espin Pedrol6ee01262021-02-05 13:05:06 +01003327 omit, valueof(ts_BVC_UNBLOCK(23)));
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003328
3329 cont_rx := tr_RAN_Information_Error_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
Pau Espin Pedrol6ee01262021-02-05 13:05:06 +01003330 ts_BSSGP_CAUSE(BSSGP_CAUSE_EQUIMENT_FAILURE),
3331 omit, enc_PDU_BSSGP(valueof(tr_BVC_UNBLOCK(23))));
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003332
3333 f_rim_pcu2sgsn(ts_PDU_BSSGP_RAN_INFORMATION_ERROR(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3334 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3335 cont := cont_tx),
3336 tr_PDU_BSSGP_RAN_INFORMATION_ERROR(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3337 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3338 cont := cont_rx),
3339 pcu_idx);
3340
3341 f_rim_sgsn2pcu(ts_PDU_BSSGP_RAN_INFORMATION_ERROR(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3342 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3343 cont := cont_tx),
3344 tr_PDU_BSSGP_RAN_INFORMATION_ERROR(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3345 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3346 cont := cont_rx),
Harald Weltef86f1852021-01-16 21:56:17 +01003347 sgsn_idx, pcu_idx);
3348}
3349testcase TC_rim_info_error() runs on GlobalTest_CT
3350{
3351 f_init();
3352 f_global_init();
3353 f_rim_iterator(refers(f_TC_rim_info_error));
3354 f_cleanup();
3355}
3356
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003357//////////////////
Harald Weltef86f1852021-01-16 21:56:17 +01003358/* RAN-INFORMATION-APPLICATION-ERROR */
3359private function f_TC_rim_info_app_error(integer sgsn_idx, integer pcu_idx, integer bvc_idx := 0)
3360runs on GlobalTest_CT
3361{
3362 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003363 var template (value) Application_Error_Container app_cont_tx;
3364 var template Application_Error_Container app_cont_rx;
3365 var template (value) RAN_Information_Application_Error_RIM_Container cont_tx;
3366 var template RAN_Information_Application_Error_RIM_Container cont_rx;
3367 var template RIM_Routing_Address ra_pcu;
3368 var template RIM_Routing_Address ra_sgsn;
Harald Weltef86f1852021-01-16 21:56:17 +01003369
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003370 ra_pcu := t_RIM_Routing_Address_cid(cell_id);
3371 ra_sgsn := t_RIM_Routing_Address_cid(cell_id_sgsn);
3372
3373 app_cont_tx := tsu_Application_Error_Container_NACC(cell_id, 23,
3374 tsu_Application_Container_IE_NACC_req(cell_id));
3375
3376 app_cont_rx := rsu_Application_Error_Container_NACC(cell_id, 23,
3377 rsu_Application_Container_IE_NACC_req(cell_id));
3378
3379 cont_tx := ts_RAN_Information_Application_Error_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3380 ts_RIM_Sequence_Number(0),
3381 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP),
3382 omit, app_cont_tx);
3383 cont_rx := tr_RAN_Information_Application_Error_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
3384 tr_RIM_Sequence_Number(0),
3385 tr_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP),
3386 omit, app_cont_rx);
3387
3388 f_rim_pcu2sgsn(ts_PDU_BSSGP_RAN_INFORMATION_APPLICATION_ERROR(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3389 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3390 cont := cont_tx),
3391 tr_PDU_BSSGP_RAN_INFORMATION_APPLICATION_ERROR(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3392 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3393 cont := cont_rx),
3394 pcu_idx);
3395
3396 f_rim_sgsn2pcu(ts_PDU_BSSGP_RAN_INFORMATION_APPLICATION_ERROR(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3397 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3398 cont := cont_tx),
3399 tr_PDU_BSSGP_RAN_INFORMATION_APPLICATION_ERROR(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3400 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3401 cont := cont_rx),
Harald Weltef86f1852021-01-16 21:56:17 +01003402 sgsn_idx, pcu_idx);
3403}
3404testcase TC_rim_info_app_error() runs on GlobalTest_CT
3405{
3406 f_init();
3407 f_global_init();
3408 f_rim_iterator(refers(f_TC_rim_info_app_error));
3409 f_cleanup();
3410}
3411
3412/* RAN-INFORMATION routing directly between PCUs, without SGSN involvement */
3413private function f_TC_rim_info_pcu2pcu(integer src_pcu_idx, integer src_bvc_idx,
3414 integer dst_pcu_idx, integer dst_bvc_idx)
3415runs on GlobalTest_CT
3416{
3417 var BssgpCellId cell_id_src := g_pcu[src_pcu_idx].cfg.bvc[src_bvc_idx].cell_id;
3418 var BssgpCellId cell_id_dst := g_pcu[dst_pcu_idx].cfg.bvc[dst_bvc_idx].cell_id;
Philipp Maier1bd60ce2021-02-10 18:25:50 +01003419 var template (value) RIM_Routing_Information ri_pcu_src_tx;
3420 var template (value) RIM_Routing_Information ri_pcu_dst_tx;
3421 var template RIM_Routing_Information ri_pcu_src_rx;
3422 var template RIM_Routing_Information ri_pcu_dst_rx;
3423 var template (value) RAN_Information_RIM_Container cont_tx;
3424 var template RAN_Information_RIM_Container cont_rx;
Harald Weltef86f1852021-01-16 21:56:17 +01003425
3426 log("Testing RIM PCU2PCU from PCU[", src_pcu_idx, "][", src_bvc_idx, "] to PCU[",
3427 dst_pcu_idx, "][", dst_bvc_idx, "]");
3428
Philipp Maier1bd60ce2021-02-10 18:25:50 +01003429 ri_pcu_src_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_src));
Philipp Maier1bd60ce2021-02-10 18:25:50 +01003431 ri_pcu_dst_tx := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID,
Harald Weltef86f1852021-01-16 21:56:17 +01003432 t_RIM_Routing_Address_cid(cell_id_dst));
Philipp Maier1bd60ce2021-02-10 18:25:50 +01003433 ri_pcu_src_rx := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID,
3434 t_RIM_Routing_Address_cid(cell_id_src));
3435 ri_pcu_dst_rx := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID,
3436 t_RIM_Routing_Address_cid(cell_id_dst));
3437
3438 cont_tx := ts_RAN_Information_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3439 ts_RIM_Sequence_Number(0),
3440 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
3441 cont_rx := tr_RAN_Information_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
3442 tr_RIM_Sequence_Number(0),
3443 tr_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
3444
3445 f_rim_pcu2pcu(ts_PDU_BSSGP_RAN_INFORMATION(dst := ri_pcu_dst_tx, src := ri_pcu_src_tx, cont := cont_tx),
3446 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 +01003447 src_pcu_idx, dst_pcu_idx);
3448}
3449testcase TC_rim_info_pcu2pcu() runs on GlobalTest_CT
3450{
3451 var integer src_pcu_idx, dst_pcu_idx;
3452 var integer src_bvc_idx, dst_bvc_idx;
3453 f_init();
3454 f_global_init();
3455
3456 for (src_pcu_idx := 0; src_pcu_idx < lengthof(g_pcu); src_pcu_idx := src_pcu_idx + 1) {
3457 for (src_bvc_idx := 0; src_bvc_idx < lengthof(g_pcu[src_pcu_idx].cfg.bvc); src_bvc_idx := src_bvc_idx + 1) {
3458 for (dst_pcu_idx := 0; dst_pcu_idx < lengthof(g_pcu); dst_pcu_idx := dst_pcu_idx + 1) {
3459 if (dst_pcu_idx == src_pcu_idx) {
3460 continue;
3461 }
3462
3463 for (dst_bvc_idx := 0; dst_bvc_idx < lengthof(g_pcu[dst_pcu_idx].cfg.bvc);
3464dst_bvc_idx := dst_bvc_idx + 1) {
3465 f_TC_rim_info_pcu2pcu(src_pcu_idx, src_bvc_idx, dst_pcu_idx, dst_bvc_idx);
3466 }
3467 }
3468 }
3469 }
3470
3471 f_cleanup();
3472}
3473
Pau Espin Pedrol40778e82021-05-07 13:20:58 +02003474
3475/* Test RIM REQ sent from an MME->SGSN->GBPROXY->PCU and back (eNACC) */
3476private function f_TC_rim_from_eutran(integer sgsn_idx, integer pcu_idx, integer bvc_idx := 0)
3477runs on GlobalTest_CT
3478{
3479 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
3480 var template (value) RAN_Information_Request_RIM_Container cont_tx;
3481 var template RAN_Information_Request_RIM_Container cont_rx;
3482 var template RIM_Routing_Address ra_pcu;
3483 var template RIM_Routing_Address ra_sgsn;
3484
3485 ra_pcu := t_RIM_Routing_Address_cid(cell_id);
3486 ra_sgsn := t_RIM_Routing_Address_enbid(cell_id_sgsn, tac := 3, gnbid := '12345678123456'O);
3487
3488 cont_tx := ts_RAN_Information_Request_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3489 ts_RIM_Sequence_Number(0),
3490 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
3491 cont_rx := tr_RAN_Information_Request_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
3492 tr_RIM_Sequence_Number(0),
3493 tr_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
3494
3495 f_rim_sgsn2pcu(ts_RAN_INFORMATION_REQUEST(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3496 src := ts_RIM_Routing_Information(RIM_ADDR_EUTRAN_NODEB_ID, ra_sgsn),
3497 cont := cont_tx),
3498 tr_RAN_INFORMATION_REQUEST(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3499 src := tr_RIM_Routing_Information(RIM_ADDR_EUTRAN_NODEB_ID, ra_sgsn),
3500 cont := cont_rx),
3501 sgsn_idx, pcu_idx);
3502
3503
3504 f_rim_pcu2sgsn(ts_RAN_INFORMATION_REQUEST(dst := ts_RIM_Routing_Information(RIM_ADDR_EUTRAN_NODEB_ID, ra_sgsn),
3505 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3506 cont := cont_tx),
3507 tr_RAN_INFORMATION_REQUEST(dst := tr_RIM_Routing_Information(RIM_ADDR_EUTRAN_NODEB_ID, ra_sgsn),
3508 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3509 cont := cont_rx),
3510 pcu_idx);
3511}
3512testcase TC_rim_from_eutran() runs on GlobalTest_CT
3513{
3514 f_init();
3515 f_global_init();
3516 f_rim_iterator(refers(f_TC_rim_from_eutran));
3517 f_cleanup();
3518}
3519
Harald Welte04358652021-01-17 13:48:13 +01003520/***********************************************************************
3521 * STATUS handling
3522 ***********************************************************************/
3523
3524/* BSSGP STATUS PDU must be routed based on inner "PDU In Error" message */
3525
3526/* generate a TMSI with NRI matching sgsn_idx + nri_idx */
3527private function f_gen_tmsi_for_sgsn_nri(integer sgsn_idx, integer nri_idx) runs on test_CT return OCT4
3528{
3529 var integer nri := mp_sgsn_nri[sgsn_idx][nri_idx];
3530 return f_gen_tmsi(0, nri_v := nri, nri_bitlen := mp_nri_bitlength);
3531}
3532
3533/* generate a TLLI with NRI matching sgsn_idx + nri_idx */
3534private function f_gen_tlli_for_sgsn_nri(integer sgsn_idx, integer nri_idx) runs on test_CT return OCT4
3535{
3536 var OCT4 p_tmsi := f_gen_tmsi_for_sgsn_nri(sgsn_idx, nri_idx);
3537 return f_gprs_tlli_from_tmsi(p_tmsi, TLLI_LOCAL);
3538}
3539
3540/* STATUS in uplink direction; expect routing by its NRI */
3541private function f_TC_status_ul(integer pcu_idx, integer sgsn_idx, PDU_BSSGP inner)
3542runs on GlobalTest_CT
3543{
3544 var template (value) PDU_BSSGP tx := ts_BSSGP_STATUS(omit, BSSGP_CAUSE_EQUIMENT_FAILURE, inner);
3545 var template (present) PDU_BSSGP exp_rx :=
3546 tr_BSSGP_STATUS(omit, BSSGP_CAUSE_EQUIMENT_FAILURE,
3547 tx.pDU_BSSGP_STATUS.pDU_in_Error.erroneous_BSSGP_PDU);
3548
3549 f_global_pcu2sgsn(tx, exp_rx, pcu_idx, sgsn_idx);
3550}
3551
3552/* STATUS in uplink direction; expect routing by its NRI */
3553private function f_TC_status_dl(integer sgsn_idx, integer pcu_idx, PDU_BSSGP inner)
3554runs on GlobalTest_CT
3555{
3556 var template (value) PDU_BSSGP tx := ts_BSSGP_STATUS(omit, BSSGP_CAUSE_EQUIMENT_FAILURE, inner);
3557 var template (present) PDU_BSSGP exp_rx :=
3558 tr_BSSGP_STATUS(omit, BSSGP_CAUSE_EQUIMENT_FAILURE,
3559 tx.pDU_BSSGP_STATUS.pDU_in_Error.erroneous_BSSGP_PDU);
3560
3561 f_global_sgsn2pcu(tx, exp_rx, sgsn_idx, pcu_idx);
3562}
3563
3564/* STATUS in uplink direction on SIG-BVC containing a TLLI; expect routing by its NRI */
3565testcase TC_status_sig_ul_tlli() runs on GlobalTest_CT
3566{
3567 var integer sgsn_idx, nri_idx;
3568
3569 f_init();
3570 f_global_init();
3571
3572 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3573 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx + 1) {
3574 /* some downlink PDU occurring on SIG-BVC with a TLLI */
3575 var OCT4 tlli := f_gen_tlli_for_sgsn_nri(sgsn_idx, nri_idx);
3576 var PDU_BSSGP inner := valueof(ts_BSSGP_FLUSH_LL(tlli, 2342));
3577
3578 f_TC_status_ul(0, sgsn_idx, inner);
3579 }
3580 }
3581
3582 f_cleanup();
3583}
3584
3585/* STATUS in uplink direction on SIG-BVC containing a TMSI; expect routing by its NRI */
3586testcase TC_status_sig_ul_tmsi() runs on GlobalTest_CT
3587{
3588 var integer sgsn_idx, nri_idx;
3589
3590 f_init();
3591 f_global_init();
3592
3593 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3594 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx + 1) {
3595 /* some downlink PDU occurring on SIG-BVC with a TMSI */
3596 const hexstring imsi := '001010123456789'H
3597 var OCT4 tmsi := f_gen_tmsi_for_sgsn_nri(sgsn_idx, nri_idx);
3598 var BssgpBvci bvci := g_pcu[0].cfg.bvc[0].bvci;
3599 var PDU_BSSGP inner := valueof(ts_BSSGP_CS_PAGING_PTMSI(bvci, imsi, oct2int(tmsi)));
3600 f_TC_status_ul(0, sgsn_idx, inner);
3601 }
3602 }
3603
3604 f_cleanup();
3605}
3606
3607
3608/* STATUS in uplink direction on PTP-BVC containing a TLLI; expect routing by its NRI */
3609testcase TC_status_ptp_ul_tlli() runs on GlobalTest_CT
3610{
3611 var integer sgsn_idx, nri_idx;
3612
3613 f_init();
3614 f_global_init_ptp();
3615
3616 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3617 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx + 1) {
3618 /* some downlink PDU occurring on PTP-BVC with a TLLI */
3619 var OCT4 tlli := f_gen_tlli_for_sgsn_nri(sgsn_idx, nri_idx);
3620 var PDU_BSSGP inner := valueof(ts_BSSGP_DL_UD(tlli, '2342'O));
3621
3622 f_TC_status_ul(0, sgsn_idx, inner);
3623 }
3624 }
3625
3626 f_cleanup();
3627}
3628
3629/* STATUS in uplink direction on PTP-BVC containing a TMSI; expect routing by its NRI */
3630testcase TC_status_ptp_ul_tmsi() runs on GlobalTest_CT
3631{
3632 var integer sgsn_idx, nri_idx;
3633
3634 f_init();
3635 f_global_init_ptp();
3636
3637 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3638 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx + 1) {
3639 /* some downlink PDU occurring on PTP-BVC with a TMSI */
3640 const hexstring imsi := '001010123456789'H
3641 var OCT4 tmsi := f_gen_tmsi_for_sgsn_nri(sgsn_idx, nri_idx);
3642 var BssgpBvci bvci := g_pcu[0].cfg.bvc[0].bvci;
3643 var PDU_BSSGP inner := valueof(ts_BSSGP_CS_PAGING_PTMSI(bvci, imsi, oct2int(tmsi)));
3644 f_TC_status_ul(0, sgsn_idx, inner);
3645 }
3646 }
3647
3648 f_cleanup();
3649}
3650
3651/* STATUS in downlink direction in SIG-BVC containing a BVCI; expect routing by it */
3652testcase TC_status_sig_dl_bvci() runs on GlobalTest_CT
3653{
3654 var integer sgsn_idx, pcu_idx, bvc_idx;
3655
3656 f_init();
3657 f_global_init();
3658
3659 /* test each BVC in each PCU from each SGSN */
3660 for (pcu_idx := 0; pcu_idx < lengthof(g_pcu); pcu_idx := pcu_idx + 1) {
3661 for (bvc_idx := 0; bvc_idx < lengthof(g_pcu[pcu_idx].cfg.bvc); bvc_idx := bvc_idx + 1) {
3662 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3663 /* some uplink PDU occurring on SIG-BVC containing a BVCI */
3664 var BssgpBvci bvci := g_pcu[pcu_idx].cfg.bvc[bvc_idx].bvci;
3665 var PDU_BSSGP inner := valueof(ts_BSSGP_LLC_DISCARDED('12345678'O, 1, bvci, 23));
3666 f_TC_status_dl(sgsn_idx, pcu_idx, inner);
3667 }
3668 }
3669 }
3670
3671 f_cleanup();
3672}
3673
3674/* STATUS in downlink direction in PTP-BVC; expect routing by BVCI */
3675testcase TC_status_ptp_dl_bvci() runs on GlobalTest_CT
3676{
3677 var integer sgsn_idx, pcu_idx, bvc_idx;
3678
3679 f_init();
3680 f_global_init_ptp();
3681
3682 /* test each BVC in each PCU from each SGSN */
3683 for (pcu_idx := 0; pcu_idx < lengthof(g_pcu); pcu_idx := pcu_idx + 1) {
3684 for (bvc_idx := 0; bvc_idx < lengthof(g_pcu[pcu_idx].cfg.bvc); bvc_idx := bvc_idx + 1) {
3685 var BssgpBvci bvci := g_pcu[pcu_idx].cfg.bvc[bvc_idx].bvci;
3686 f_global_ptp_connect_pcu_bvci(pcu_idx, bvci);
3687 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3688 f_global_ptp_connect_sgsn_bvci(sgsn_idx, bvci);
3689
3690 /* some uplink PDU occurring on PTP-BVC */
3691 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
3692 var PDU_BSSGP inner := valueof(ts_BSSGP_UL_UD('12345678'O, cell_id, '4223'O));
3693 f_TC_status_dl(sgsn_idx, pcu_idx, inner);
3694 }
3695 }
3696 }
3697
3698 f_cleanup();
3699}
3700
3701/* TODO: test case for DL-STATUS(SUSPEND/RESUME) containing RA-ID; expect routing by RA-ID */
3702/* 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 +01003703
Daniel Willmann423d8f42020-09-08 18:58:22 +02003704control {
3705 execute( TC_BVC_bringup() );
Daniel Willmann116d8b52021-12-06 16:27:54 +01003706 /* Depends on osmo-gbproxy > 0.2.0 */
3707 if (Misc_Helpers.f_osmo_repo_is("nightly")) {
3708 execute( TC_BVC_bringup_conflicting() );
3709 }
Harald Welte92686012020-11-15 21:45:49 +01003710 execute( TC_ul_unitdata() );
Daniel Willmann8d9fcf42021-05-28 15:05:41 +02003711 execute( TC_ul_unitdata_pool_failure() );
Harald Welte78d8db92020-11-15 23:27:27 +01003712 execute( TC_dl_unitdata() );
Harald Welte6dc2ac42020-11-16 09:16:17 +01003713 execute( TC_ra_capability() );
Daniel Willmannace3ece2020-11-16 19:53:26 +01003714 execute( TC_ra_capability_upd() );
Daniel Willmann165d6612020-11-19 14:27:29 +01003715 execute( TC_radio_status() );
Harald Welte3148a962021-01-17 11:15:28 +01003716 execute( TC_radio_status_tmsi() );
3717 execute( TC_radio_status_imsi() );
Daniel Willmannfa67f492020-11-19 15:48:05 +01003718 execute( TC_suspend() );
Daniel Willmann087a33d2020-11-19 15:58:43 +01003719 execute( TC_resume() );
Harald Weltef8e5c5d2020-11-27 22:37:23 +01003720 execute( TC_trace() );
Harald Weltec0351d12020-11-27 22:49:02 +01003721 execute( TC_llc_discarded() );
Harald Weltef20af412020-11-28 16:11:11 +01003722 execute( TC_overload() );
Harald Welte239aa502020-11-24 23:14:20 +01003723 execute( TC_bvc_block_ptp() );
3724 execute( TC_bvc_unblock_ptp() );
Harald Welte60a8ec72020-11-25 17:12:53 +01003725 execute( TC_bvc_reset_ptp_from_bss() );
Harald Welte16786e92020-11-27 19:11:56 +01003726 execute( TC_bvc_reset_sig_from_bss() );
Harald Welte60a8ec72020-11-25 17:12:53 +01003727 execute( TC_bvc_reset_ptp_from_sgsn() );
Daniel Willmannc5bbcc62021-09-24 13:17:20 +02003728 execute( TC_bvc_reset_blocked_ptp_from_sgsn() );
Harald Welte16786e92020-11-27 19:11:56 +01003729 execute( TC_bvc_reset_sig_from_sgsn() );
Harald Weltef6e59b02020-12-08 08:29:09 +01003730 if (mp_enable_bss_load_sharing) {
Harald Weltef8ef0282020-11-18 12:16:59 +01003731 /* don't enable this by default, as we don't yet have any automatic test setup for FR with 4 NS-VC */
3732 execute( TC_load_sharing_dl() );
3733 }
Harald Welte0e188242020-11-22 21:46:48 +01003734
3735 /* PAGING-PS over PTP BVC */
3736 execute( TC_paging_ps_ptp_bss() );
3737 execute( TC_paging_ps_ptp_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01003738 execute( TC_paging_ps_ptp_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003739 execute( TC_paging_ps_ptp_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01003740 execute( TC_paging_ps_ptp_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003741 execute( TC_paging_ps_ptp_bvci() );
Harald Welteb5a04aa2021-01-16 13:04:40 +01003742 execute( TC_paging_ps_ptp_bvci_imsi() );
Harald Welte7462a592020-11-23 22:07:07 +01003743 execute( TC_paging_ps_ptp_bvci_unknown() );
Harald Weltecf200072021-01-16 15:20:46 +01003744 execute( TC_paging_ps_reject_ptp_bvci() );
3745 execute( TC_paging_ps_reject_ptp_bvci_imsi() );
Harald Welte7595d562021-01-16 19:09:20 +01003746 execute( TC_dummy_paging_ps_ptp() );
Harald Welte0e188242020-11-22 21:46:48 +01003747
3748 /* PAGING-PS over SIG BVC */
3749 execute( TC_paging_ps_sig_bss() );
3750 execute( TC_paging_ps_sig_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01003751 execute( TC_paging_ps_sig_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003752 execute( TC_paging_ps_sig_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01003753 execute( TC_paging_ps_sig_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003754 execute( TC_paging_ps_sig_bvci() );
Harald Welteb5a04aa2021-01-16 13:04:40 +01003755 execute( TC_paging_ps_sig_bvci_imsi() );
Harald Welte7462a592020-11-23 22:07:07 +01003756 execute( TC_paging_ps_sig_bvci_unknown() );
Harald Weltecf200072021-01-16 15:20:46 +01003757 execute( TC_paging_ps_reject_sig_bvci() );
3758 execute( TC_paging_ps_reject_sig_bvci_imsi() );
Harald Welte7595d562021-01-16 19:09:20 +01003759 execute( TC_dummy_paging_ps_sig() );
Harald Welte0e188242020-11-22 21:46:48 +01003760
3761 /* PAGING-CS over PTP BVC */
3762 execute( TC_paging_cs_ptp_bss() );
3763 execute( TC_paging_cs_ptp_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01003764 execute( TC_paging_cs_ptp_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003765 execute( TC_paging_cs_ptp_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01003766 execute( TC_paging_cs_ptp_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003767 execute( TC_paging_cs_ptp_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01003768 execute( TC_paging_cs_ptp_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003769
3770 /* PAGING-CS over SIG BVC */
3771 execute( TC_paging_cs_sig_bss() );
3772 execute( TC_paging_cs_sig_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01003773 execute( TC_paging_cs_sig_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003774 execute( TC_paging_cs_sig_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01003775 execute( TC_paging_cs_sig_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003776 execute( TC_paging_cs_sig_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01003777 execute( TC_paging_cs_sig_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003778
Harald Weltef86f1852021-01-16 21:56:17 +01003779 /* RAN Information Management */
3780 execute( TC_rim_info_req() );
3781 execute( TC_rim_info() );
3782 execute( TC_rim_info_ack() );
3783 execute( TC_rim_info_error() );
3784 execute( TC_rim_info_app_error() );
3785 execute( TC_rim_info_pcu2pcu() );
Pau Espin Pedrol40778e82021-05-07 13:20:58 +02003786 execute( TC_rim_from_eutran() );
Harald Weltef86f1852021-01-16 21:56:17 +01003787
Harald Welte0e188242020-11-22 21:46:48 +01003788
Daniel Willmannc7c8e322021-11-25 18:13:21 +01003789 execute( TC_flush_ll_bvci_new() );
3790
3791 /* Depends on osmo-gbproxy > 0.2.0 */
3792 if (Misc_Helpers.f_osmo_repo_is("nightly")) {
3793 execute( TC_flush_ll_no_bvci_new() );
3794 }
Harald Welte299aa482020-12-09 15:10:55 +01003795 execute( TC_fc_bvc() );
Harald Weltecc3894b2020-12-09 16:50:12 +01003796 execute( TC_fc_ms() );
Harald Welted6f89812021-01-16 18:57:49 +01003797 execute( TC_ms_reg_enq() );
Harald Welte04358652021-01-17 13:48:13 +01003798
3799 /* Uplink STATUS */
3800 execute( TC_status_sig_ul_tlli() );
3801 execute( TC_status_sig_ul_tmsi() );
3802 execute( TC_status_ptp_ul_tlli() );
3803 execute( TC_status_ptp_ul_tmsi() );
3804
3805 /* Downlink STATUS */
3806 execute( TC_status_sig_dl_bvci() );
3807 execute( TC_status_ptp_dl_bvci() );
Daniel Willmann423d8f42020-09-08 18:58:22 +02003808}
3809
3810
3811}