blob: 035a47d603a5f932d3cac65b058f2d3a9fef0bcd [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
1072friend function f_bssgp_suspend(integer ran_idx := 0) runs on BSSGP_ConnHdlr return OCT1 {
Harald Welte16357a92020-11-17 18:20:00 +01001073 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Daniel Willmann423d8f42020-09-08 18:58:22 +02001074 timer T := 5.0;
1075 var PDU_BSSGP rx_pdu;
Harald Welte16357a92020-11-17 18:20:00 +01001076 PCU_SIG[ran_idx].send(ts_BSSGP_SUSPEND(g_pars.tlli, bvcc.cell_id.ra_id));
Daniel Willmann423d8f42020-09-08 18:58:22 +02001077 T.start;
1078 alt {
Harald Welte16357a92020-11-17 18:20:00 +01001079 [] 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 +02001080 return rx_pdu.pDU_BSSGP_SUSPEND_ACK.suspend_Reference_Number.suspend_Reference_Number_value;
1081 }
Harald Welte16357a92020-11-17 18:20:00 +01001082 [] 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 +01001083 f_shutdown(__FILE__, __LINE__, fail,
1084 log2str("SUSPEND-NACK in response to SUSPEND for TLLI ", g_pars.tlli));
Daniel Willmann423d8f42020-09-08 18:58:22 +02001085 }
1086 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +01001087 f_shutdown(__FILE__, __LINE__, fail,
1088 log2str("No SUSPEND-ACK in response to SUSPEND for TLLI ", g_pars.tlli));
Daniel Willmann423d8f42020-09-08 18:58:22 +02001089 }
1090 }
1091 return '00'O;
1092}
1093
1094friend function f_bssgp_resume(OCT1 susp_ref, integer ran_idx := 0) runs on BSSGP_ConnHdlr {
Harald Welte16357a92020-11-17 18:20:00 +01001095 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Daniel Willmann423d8f42020-09-08 18:58:22 +02001096 timer T := 5.0;
Harald Welte16357a92020-11-17 18:20:00 +01001097 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 +02001098 T.start;
1099 alt {
Harald Welte16357a92020-11-17 18:20:00 +01001100 [] PCU_SIG[ran_idx].receive(tr_BSSGP_RESUME_ACK(g_pars.tlli, bvcc.cell_id.ra_id));
1101 [] PCU_SIG[ran_idx].receive(tr_BSSGP_RESUME_NACK(g_pars.tlli, bvcc.cell_id.ra_id, ?)) {
Harald Welted5b7e742021-01-27 10:50:24 +01001102 f_shutdown(__FILE__, __LINE__, fail,
1103 log2str("RESUME-NACK in response to RESUME for TLLI ", g_pars.tlli));
Daniel Willmann423d8f42020-09-08 18:58:22 +02001104 }
1105 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +01001106 f_shutdown(__FILE__, __LINE__, fail,
1107 log2str("No RESUME-ACK in response to SUSPEND for TLLI ", g_pars.tlli));
Daniel Willmann423d8f42020-09-08 18:58:22 +02001108 }
1109 }
1110}
1111
1112
Harald Welte92686012020-11-15 21:45:49 +01001113/* send uplink-unitdata of a variety of different sizes; expect it to show up on SGSN */
1114private function f_TC_ul_unitdata(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte16357a92020-11-17 18:20:00 +01001115 var integer ran_idx := 0;
1116 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Harald Welte92686012020-11-15 21:45:49 +01001117 var integer i;
1118
Harald Welte0d5fceb2020-11-29 16:04:07 +01001119 for (i := 0; i < max_fr_info_size-4; i := i+4) {
Harald Welte92686012020-11-15 21:45:49 +01001120 var octetstring payload := f_rnd_octstring(i);
Harald Welte16357a92020-11-17 18:20:00 +01001121 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 +01001122 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte16357a92020-11-17 18:20:00 +01001123 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 +01001124
Harald Welte0d5fceb2020-11-29 16:04:07 +01001125 log("UL-UNITDATA(payload_size=", i);
Harald Welte22ef5d92020-11-16 13:35:14 +01001126 f_pcu2sgsn(pdu_tx, pdu_rx);
Harald Welte92686012020-11-15 21:45:49 +01001127 }
1128 setverdict(pass);
1129}
1130
1131testcase TC_ul_unitdata() runs on test_CT
1132{
Daniel Willmannc879f342021-02-11 14:28:01 +01001133 f_init(60.0);
Harald Welte2ecbca82021-01-16 11:23:09 +01001134 f_start_handlers(refers(f_TC_ul_unitdata), testcasename(), 1);
Harald Welte92686012020-11-15 21:45:49 +01001135 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Welte92686012020-11-15 21:45:49 +01001136 f_cleanup();
1137}
1138
Daniel Willmann8d9fcf42021-05-28 15:05:41 +02001139
1140/* send uplink-unitdata of a variety of different sizes; expect it to show up on the only connected SGSN */
1141private function f_TC_ul_unitdata_pool_failure(charstring id) runs on BSSGP_ConnHdlr {
1142 var integer ran_idx := 0;
1143 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
1144 var integer i;
1145
1146 /* All data should arrive at the one SGSN that is still up */
1147 g_pars.sgsn_idx := 0;
1148
1149 for (i := 0; i < max_fr_info_size-4; i := i+4) {
1150 var octetstring payload := f_rnd_octstring(i);
1151 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_UL_UD(g_pars.tlli, bvcc.cell_id, payload);
1152 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1153 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_UL_UD(g_pars.tlli, bvcc.cell_id, payload);
1154
1155 log("UL-UNITDATA(payload_size=", i);
1156 f_pcu2sgsn(pdu_tx, pdu_rx);
1157 }
1158 setverdict(pass);
1159}
1160
1161testcase TC_ul_unitdata_pool_failure() runs on test_CT
1162{
1163 var integer i;
1164 var integer j;
1165
1166 f_init(60.0);
1167
1168 for (i := 1; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
1169 connect(self:NS_CTRL, g_sgsn[i].vc_NS:NS_CTRL);
1170 for (j := 0; j < lengthof(mp_nsconfig_sgsn[i].nsvc); j := j+1) {
1171 var uint16_t nsvci := mp_nsconfig_sgsn[i].nsvc[j].nsvci;
1172 var NsDisableVcRequest tx_disar;
1173 tx_disar.nsvci := nsvci;
1174 NS_CTRL.send(tx_disar);
1175 }
1176 disconnect(self:NS_CTRL, g_sgsn[i].vc_NS:NS_CTRL);
1177 }
1178 /* Wait until gbproxy notices that the NSVCs are down */
1179 f_sleep(15.0);
1180
1181 f_start_handlers(refers(f_TC_ul_unitdata_pool_failure), testcasename(), 1);
1182 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
1183 f_cleanup();
1184}
1185
Harald Welte78d8db92020-11-15 23:27:27 +01001186/* send downlink-unitdata of a variety of different sizes; expect it to show up on PCU */
1187private function f_TC_dl_unitdata(charstring id) runs on BSSGP_ConnHdlr {
1188 var integer i;
1189
Harald Welte0d5fceb2020-11-29 16:04:07 +01001190 for (i := 0; i < max_fr_info_size-4; i := i+4) {
Harald Welte78d8db92020-11-15 23:27:27 +01001191 var octetstring payload := f_rnd_octstring(i);
1192 var template (value) PDU_BSSGP pdu_tx :=
1193 ts_BSSGP_DL_UD(g_pars.tlli, payload, omit, ts_BSSGP_IMSI(g_pars.imsi));
1194 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1195 var template (present) PDU_BSSGP pdu_rx :=
Daniel Willmann325458d2021-02-11 14:22:42 +01001196 tr_BSSGP_DL_UD(g_pars.tlli, payload, tr_BSSGP_IMSI(g_pars.imsi));
Harald Welte78d8db92020-11-15 23:27:27 +01001197
Harald Welte0d5fceb2020-11-29 16:04:07 +01001198 log("DL-UNITDATA(payload_size=", i);
Harald Welte22ef5d92020-11-16 13:35:14 +01001199 f_sgsn2pcu(pdu_tx, pdu_rx);
Harald Welte78d8db92020-11-15 23:27:27 +01001200 }
1201 setverdict(pass);
1202}
1203
1204testcase TC_dl_unitdata() runs on test_CT
1205{
Daniel Willmannc879f342021-02-11 14:28:01 +01001206 f_init(60.0);
Harald Welte2ecbca82021-01-16 11:23:09 +01001207 f_start_handlers(refers(f_TC_dl_unitdata), testcasename(), 2);
Harald Welte78d8db92020-11-15 23:27:27 +01001208 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Welte78d8db92020-11-15 23:27:27 +01001209 f_cleanup();
1210}
Harald Welte92686012020-11-15 21:45:49 +01001211
Harald Welte6dc2ac42020-11-16 09:16:17 +01001212private function f_TC_ra_capability(charstring id) runs on BSSGP_ConnHdlr {
1213 var integer i;
1214
1215 for (i := 0; i < 10; i := i+1) {
1216 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RA_CAP(g_pars.tlli, { ts_RaCapRec_BSSGP });
1217 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1218 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RA_CAP(g_pars.tlli, { tr_RaCapRec_BSSGP })
1219
Harald Welte22ef5d92020-11-16 13:35:14 +01001220 f_sgsn2pcu(pdu_tx, pdu_rx);
Harald Welte6dc2ac42020-11-16 09:16:17 +01001221 }
1222 setverdict(pass);
1223}
1224testcase TC_ra_capability() runs on test_CT
1225{
Harald Welte6dc2ac42020-11-16 09:16:17 +01001226 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001227 f_start_handlers(refers(f_TC_ra_capability), testcasename(), 3);
Harald Welte6dc2ac42020-11-16 09:16:17 +01001228 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Welte6dc2ac42020-11-16 09:16:17 +01001229 f_cleanup();
1230}
1231
Daniel Willmannace3ece2020-11-16 19:53:26 +01001232private function f_TC_ra_capability_upd(charstring id) runs on BSSGP_ConnHdlr {
1233 var integer i;
1234 var OCT1 tag;
1235 for (i := 0; i < 10; i := i+1) {
1236 tag := int2oct(23 + i, 1);
1237 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RA_CAP_UPD(g_pars.tlli, tag);
1238 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1239 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RA_CAP_UPD(g_pars.tlli, tag)
1240
1241 f_pcu2sgsn(pdu_tx, pdu_rx);
1242
1243 pdu_tx := ts_BSSGP_RA_CAP_UPD_ACK(g_pars.tlli, tag, '42'O);
1244 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1245 pdu_rx := tr_BSSGP_RA_CAP_UPD_ACK(g_pars.tlli, tag, '42'O)
1246
1247 f_sgsn2pcu(pdu_tx, pdu_rx);
1248 }
1249 setverdict(pass);
1250}
1251testcase TC_ra_capability_upd() runs on test_CT
1252{
Daniel Willmannace3ece2020-11-16 19:53:26 +01001253 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001254 f_start_handlers(refers(f_TC_ra_capability_upd), testcasename(), 4);
Daniel Willmannace3ece2020-11-16 19:53:26 +01001255 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Daniel Willmannace3ece2020-11-16 19:53:26 +01001256 f_cleanup();
1257}
1258
Daniel Willmann165d6612020-11-19 14:27:29 +01001259private function f_TC_radio_status(charstring id) runs on BSSGP_ConnHdlr {
1260 var integer i;
1261 var BssgpRadioCause cause := BSSGP_RADIO_CAUSE_CONTACT_LOST;
1262 for (i := 0; i < 10; i := i+1) {
1263 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RADIO_STATUS(g_pars.tlli, cause);
1264 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1265 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RADIO_STATUS(g_pars.tlli, cause)
1266
1267 f_pcu2sgsn(pdu_tx, pdu_rx);
1268 }
1269 setverdict(pass);
1270}
1271testcase TC_radio_status() runs on test_CT
1272{
Daniel Willmann165d6612020-11-19 14:27:29 +01001273 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001274 f_start_handlers(refers(f_TC_radio_status), testcasename(), 5);
Daniel Willmann165d6612020-11-19 14:27:29 +01001275 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Daniel Willmann165d6612020-11-19 14:27:29 +01001276 f_cleanup();
1277}
1278
Harald Welte3148a962021-01-17 11:15:28 +01001279private function f_TC_radio_status_tmsi(charstring id) runs on BSSGP_ConnHdlr {
1280 var integer i;
1281 var BssgpRadioCause cause := BSSGP_RADIO_CAUSE_CONTACT_LOST;
1282 for (i := 0; i < 10; i := i+1) {
1283 var integer tmsi_int := oct2int(g_pars.p_tmsi);
1284 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RADIO_STATUS(omit, cause, tmsi_int);
1285 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1286 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RADIO_STATUS(omit, cause, tmsi_int);
1287 f_pcu2sgsn(pdu_tx, pdu_rx);
1288 }
1289 setverdict(pass);
1290}
1291testcase TC_radio_status_tmsi() runs on test_CT
1292{
1293 f_init();
1294 f_start_handlers(refers(f_TC_radio_status_tmsi), testcasename(), 5);
1295 f_cleanup();
1296}
1297
1298private function f_TC_radio_status_imsi(charstring id) runs on BSSGP_ConnHdlr {
1299 var integer i;
1300 var BssgpRadioCause cause := BSSGP_RADIO_CAUSE_CONTACT_LOST;
1301 for (i := 0; i < 10; i := i+1) {
1302 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RADIO_STATUS(omit, cause, imsi := g_pars.imsi);
1303 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1304 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RADIO_STATUS(omit, cause, imsi := g_pars.imsi);
1305 f_pcu2any_sgsn(pdu_tx, pdu_rx);
1306 }
1307 setverdict(pass);
1308}
1309testcase TC_radio_status_imsi() runs on test_CT
1310{
1311 f_init();
1312 f_start_handlers(refers(f_TC_radio_status_imsi), testcasename(), 5);
1313 f_cleanup();
1314}
1315
1316
1317
Harald Welte99ed5072021-01-15 20:38:58 +01001318private function f_suspend_one(integer sgsn_idx, integer nri_idx, integer pcu_idx, integer bvc_idx,
1319 integer suffix)
Harald Welte00963752021-01-15 20:33:11 +01001320runs on GlobalTest_CT
1321{
1322 var RoutingAreaIdentification ra_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id.ra_id;
Harald Welte99ed5072021-01-15 20:38:58 +01001323 var OCT4 p_tmsi := f_gen_tmsi(suffix, nri_v := mp_sgsn_nri[sgsn_idx][nri_idx],
1324 nri_bitlen := mp_nri_bitlength);
1325 var OCT4 tlli := f_gprs_tlli_from_tmsi(p_tmsi, TLLI_LOCAL);
Harald Welte00963752021-01-15 20:33:11 +01001326 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_SUSPEND(tlli, ra_id);
1327 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1328 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_SUSPEND(tlli, ra_id);
1329 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1330
1331 pdu_tx := ts_BSSGP_SUSPEND_ACK(tlli, ra_id, int2oct(suffix, 1));
1332 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1333 pdu_rx := tr_BSSGP_SUSPEND_ACK(tlli, ra_id, int2oct(suffix, 1));
1334 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1335
1336 pdu_tx := ts_BSSGP_SUSPEND(tlli, ra_id);
1337 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1338 pdu_rx := tr_BSSGP_SUSPEND(tlli, ra_id);
1339 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1340
1341 /* These messages are simple passed through so just also test sending NACK */
1342 pdu_tx := ts_BSSGP_SUSPEND_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1343 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1344 pdu_rx := tr_BSSGP_SUSPEND_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1345 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1346}
1347
Harald Weltec5c33732021-01-15 21:04:35 +01001348private function f_TC_suspend(integer sgsn_idx, integer nri_idx, integer pcu_idx, integer bvc_idx)
1349runs on GlobalTest_CT {
Daniel Willmannfa67f492020-11-19 15:48:05 +01001350 var integer i;
Daniel Willmann165d6612020-11-19 14:27:29 +01001351
Daniel Willmannfa67f492020-11-19 15:48:05 +01001352 for (i := 0; i < 10; i := i+1) {
Harald Weltec5c33732021-01-15 21:04:35 +01001353 f_suspend_one(sgsn_idx, nri_idx, pcu_idx, bvc_idx, suffix := i);
Daniel Willmannfa67f492020-11-19 15:48:05 +01001354 }
1355 setverdict(pass);
1356}
Harald Welte3807ed12020-11-24 19:05:22 +01001357testcase TC_suspend() runs on GlobalTest_CT
Daniel Willmannfa67f492020-11-19 15:48:05 +01001358{
Harald Weltec5c33732021-01-15 21:04:35 +01001359 var integer sgsn_idx, nri_idx;
Daniel Willmannfa67f492020-11-19 15:48:05 +01001360 f_init();
Harald Welte3807ed12020-11-24 19:05:22 +01001361 f_global_init();
Harald Weltec5c33732021-01-15 21:04:35 +01001362 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx+1) {
1363 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx+1) {
1364 f_TC_suspend(sgsn_idx, nri_idx, pcu_idx:=0, bvc_idx:=0);
1365 }
1366 }
Daniel Willmannfa67f492020-11-19 15:48:05 +01001367 f_cleanup();
1368}
Harald Welte6dc2ac42020-11-16 09:16:17 +01001369
Harald Welte99ed5072021-01-15 20:38:58 +01001370private function f_resume_one(integer sgsn_idx, integer nri_idx, integer pcu_idx, integer bvc_idx,
1371 integer suffix)
Harald Welte00963752021-01-15 20:33:11 +01001372runs on GlobalTest_CT
1373{
1374 var RoutingAreaIdentification ra_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id.ra_id;
Harald Welte99ed5072021-01-15 20:38:58 +01001375 var OCT4 p_tmsi := f_gen_tmsi(suffix, nri_v := mp_sgsn_nri[sgsn_idx][nri_idx],
1376 nri_bitlen := mp_nri_bitlength);
1377 var OCT4 tlli := f_gprs_tlli_from_tmsi(p_tmsi, TLLI_LOCAL);
Harald Welte00963752021-01-15 20:33:11 +01001378 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1379 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1380 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1381 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1382
1383 pdu_tx := ts_BSSGP_RESUME_ACK(tlli, ra_id);
1384 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1385 pdu_rx := tr_BSSGP_RESUME_ACK(tlli, ra_id);
1386 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1387
1388 pdu_tx := ts_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1389 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1390 pdu_rx := tr_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1391 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1392
1393 /* These messages are simple passed through so just also test sending NACK */
1394 pdu_tx := ts_BSSGP_RESUME_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1395 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1396 pdu_rx := tr_BSSGP_RESUME_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1397 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1398}
1399
Harald Weltec5c33732021-01-15 21:04:35 +01001400private function f_TC_resume(integer sgsn_idx, integer nri_idx, integer pcu_idx, integer bvc_idx)
1401runs on GlobalTest_CT {
Daniel Willmann087a33d2020-11-19 15:58:43 +01001402 var integer i;
1403
Daniel Willmann087a33d2020-11-19 15:58:43 +01001404 for (i := 0; i < 10; i := i+1) {
Harald Weltec5c33732021-01-15 21:04:35 +01001405 f_resume_one(sgsn_idx, nri_idx, pcu_idx, bvc_idx, suffix := i);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001406 }
1407 setverdict(pass);
1408}
Harald Welte3807ed12020-11-24 19:05:22 +01001409testcase TC_resume() runs on GlobalTest_CT
Daniel Willmann087a33d2020-11-19 15:58:43 +01001410{
Harald Weltec5c33732021-01-15 21:04:35 +01001411 var integer sgsn_idx, nri_idx;
Daniel Willmann087a33d2020-11-19 15:58:43 +01001412 f_init();
Harald Welte3807ed12020-11-24 19:05:22 +01001413 f_global_init();
Harald Weltec5c33732021-01-15 21:04:35 +01001414 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx+1) {
1415 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx+1) {
1416 f_TC_resume(sgsn_idx, nri_idx, pcu_idx:=0, bvc_idx:=0);
1417 }
1418 }
Daniel Willmann087a33d2020-11-19 15:58:43 +01001419 f_cleanup();
1420}
1421
Harald Weltef8ef0282020-11-18 12:16:59 +01001422/* test the load-sharing between multiple NS-VC on the BSS side */
1423private function f_TC_dl_ud_unidir(charstring id) runs on BSSGP_ConnHdlr {
1424 var integer i;
1425
1426 for (i := 0; i < 10; i := i+1) {
1427 var octetstring payload := f_rnd_octstring(i);
1428 var template (value) PDU_BSSGP pdu_tx :=
1429 ts_BSSGP_DL_UD(g_pars.tlli, payload, omit, ts_BSSGP_IMSI(g_pars.imsi));
Harald Welte09a1ce42021-01-16 11:18:38 +01001430 SGSN_PTP[g_pars.sgsn_idx].send(pdu_tx);
Harald Weltef8ef0282020-11-18 12:16:59 +01001431 }
1432 setverdict(pass);
1433}
Harald Welte09a1ce42021-01-16 11:18:38 +01001434
1435private function f_TC_load_sharing_dl(integer sgsn_idx) runs on test_CT_NS
Harald Weltef8ef0282020-11-18 12:16:59 +01001436{
1437 const integer num_ue := 10;
1438 var BSSGP_ConnHdlr vc_conn[num_ue];
Harald Weltef8ef0282020-11-18 12:16:59 +01001439 /* all BVC are now fully brought up. We disconnect BSSGP from NS on the BSS
1440 * side so we get the raw NsUnitdataIndication and hence observe different
1441 * NSVCI */
1442 disconnect(g_pcu[0].vc_NS:NS_SP, g_pcu[0].vc_BSSGP:BSCP);
1443 connect(g_pcu[0].vc_NS:NS_SP, self:NS);
1444
1445 /* there may still be some NS-VCs coming up? After all, the BVC-RESET succeeds after the first
1446 * of the NS-VC is ALIVE/UNBLOCKED */
1447 f_sleep(3.0);
1448
1449 /* start parallel components generating DL-UNITDATA from the SGSN side */
1450 for (var integer i:= 0; i < num_ue; i := i+1) {
Harald Welte2ecbca82021-01-16 11:23:09 +01001451 vc_conn[i] := f_start_handler(refers(f_TC_dl_ud_unidir), testcasename(),
Harald Welte09a1ce42021-01-16 11:18:38 +01001452 5+i, 30.0, sgsn_idx);
Harald Weltef8ef0282020-11-18 12:16:59 +01001453 }
1454
1455 /* now start counting all the messages that were queued before */
1456 /* TODO: We have a hard-coded assumption of 4 NS-VC in one NSE/NS-VCG here! */
1457 var ro_integer rx_count := { 0, 0, 0, 0 };
1458 timer T := 2.0;
1459 T.start;
1460 alt {
1461 [] as_NsUdiCount(0, rx_count);
1462 [] as_NsUdiCount(1, rx_count);
1463 [] as_NsUdiCount(2, rx_count);
1464 [] as_NsUdiCount(3, rx_count);
1465 [] NS.receive(NsUnitdataIndication:{0,?,?,*,*}) { repeat; } /* signaling BVC */
1466 [] NS.receive(NsStatusIndication:?) { repeat; }
1467 [] NS.receive {
Harald Welted5b7e742021-01-27 10:50:24 +01001468 f_shutdown(__FILE__, __LINE__, fail, "Rx unexpected NS");
Harald Weltef8ef0282020-11-18 12:16:59 +01001469 }
1470 [] T.timeout {
1471 }
1472 }
1473 for (var integer i := 0; i < lengthof(rx_count); i := i+1) {
1474 log("Rx on NSVCI ", mp_nsconfig_pcu[0].nsvc[i].nsvci, ": ", rx_count[i]);
1475 if (rx_count[i] == 0) {
1476 setverdict(fail, "Data not shared over all NSVC");
1477 }
1478 }
Harald Welte09a1ce42021-01-16 11:18:38 +01001479}
1480
1481testcase TC_load_sharing_dl() runs on test_CT_NS
1482{
1483 var integer sgsn_idx, nri_idx;
1484 f_init();
1485 for (sgsn_idx:=0; sgsn_idx < NUM_SGSN; sgsn_idx:=sgsn_idx+1) {
1486 f_TC_load_sharing_dl(sgsn_idx);
1487 }
Harald Weltef8ef0282020-11-18 12:16:59 +01001488 setverdict(pass);
1489}
1490private altstep as_NsUdiCount(integer nsvc_idx, inout ro_integer roi) runs on test_CT_NS {
1491 var NsUnitdataIndication udi;
1492 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[0];
1493 [] NS.receive(NsUnitdataIndication:{bvcc.bvci, g_pcu[0].cfg.nsei, mp_nsconfig_pcu[0].nsvc[nsvc_idx].nsvci, *, *}) -> value udi {
1494 roi[nsvc_idx] := roi[nsvc_idx] + 1;
1495 repeat;
1496 }
1497}
1498type component test_CT_NS extends test_CT {
1499 port NS_PT NS;
1500};
1501
1502
Harald Welte0e188242020-11-22 21:46:48 +01001503/***********************************************************************
1504 * PAGING PS procedure
1505 ***********************************************************************/
1506
1507private function f_send_paging_ps(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1508 boolean use_sig := false)
1509runs on BSSGP_ConnHdlr return template (present) PDU_BSSGP {
1510 var template (value) PDU_BSSGP pdu_tx;
1511 var template (present) PDU_BSSGP pdu_rx;
1512 /* we always specify '0' as BVCI in the templates below, as we override it with
1513 * 'p4' later anyway */
1514 pdu_rx := tr_BSSGP_PS_PAGING(0);
1515 pdu_rx.pDU_BSSGP_PAGING_PS.iMSI := tr_BSSGP_IMSI(g_pars.imsi);
1516 if (ispresent(g_pars.p_tmsi)) {
1517 pdu_tx := ts_BSSGP_PS_PAGING_PTMSI(0, g_pars.imsi, oct2int(g_pars.p_tmsi));
1518 pdu_rx.pDU_BSSGP_PAGING_PS.pTMSI := tr_BSSGP_TMSI(oct2int(g_pars.p_tmsi));
1519 } else {
1520 pdu_tx := ts_BSSGP_PS_PAGING_IMSI(0, g_pars.imsi);
1521 pdu_rx.pDU_BSSGP_PAGING_PS.pTMSI := omit;
1522 }
1523 pdu_tx.pDU_BSSGP_PAGING_PS.paging_Field4 := p4;
1524 pdu_rx.pDU_BSSGP_PAGING_PS.paging_Field4 := p4;
1525 if (use_sig == false) {
Harald Welte158becf2020-12-09 12:32:32 +01001526 SGSN_PTP[sgsn_idx].send(pdu_tx);
Harald Welte0e188242020-11-22 21:46:48 +01001527 } else {
1528 SGSN_SIG[sgsn_idx].send(pdu_tx);
1529 }
1530 return pdu_rx;
1531}
1532
1533/* send paging defined by 'p4' on given SGSN-side index (ptp or signaling) and expect one paging to arrive on
1534 * specified PCU index */
1535private function f_send_paging_ps_exp_one_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1536 boolean use_sig := false,integer pcu_idx := 0)
1537runs on BSSGP_ConnHdlr {
1538 var template (present) PDU_BSSGP exp_rx;
Daniel Willmann1a859712020-12-04 00:59:45 +01001539 var boolean test_done := false;
Harald Welte0e188242020-11-22 21:46:48 +01001540 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1541 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1542 exp_rx := f_send_paging_ps(p4, sgsn_idx, use_sig);
1543 /* Expect paging to propagate to the one BSS addressed by the BVCI only */
1544 timer T := 2.0;
1545 T.start;
1546 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001547 [not use_sig and not test_done] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001548 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001549 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001550 repeat;
1551 }
1552 [not use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
1553 setverdict(fail, "Received paging on SIGNALING BVC, expected PTP BVC");
1554 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001555 [use_sig and not test_done] PCU_SIG[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001556 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001557 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001558 repeat;
1559 }
Harald Welte158becf2020-12-09 12:32:32 +01001560 [use_sig] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001561 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1562 }
Harald Welte158becf2020-12-09 12:32:32 +01001563 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001564 setverdict(fail, "Paging received on unexpected BVC");
1565 }
1566 [] any from PCU_SIG.receive(exp_rx) {
1567 setverdict(fail, "Paging received on unexpected BVC");
1568 }
Harald Welte158becf2020-12-09 12:32:32 +01001569 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01001570 setverdict(fail, "Different Paging than expected received PTP BVC");
1571 }
1572 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1573 setverdict(fail, "Different Paging than expected on SIGNALING BVC");
1574 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001575 [not test_done] T.timeout {
1576 setverdict(fail, "Timeout waiting for paging");
1577 }
1578 [test_done] T.timeout;
Harald Welte0e188242020-11-22 21:46:48 +01001579 }
1580}
1581
Harald Welte7462a592020-11-23 22:07:07 +01001582/* send a PS-PAGING but don't expect it to show up on any PTP or SIG BVC */
1583private function f_send_paging_ps_exp_no_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1584 boolean use_sig := false)
1585runs on BSSGP_ConnHdlr {
1586 var template (present) PDU_BSSGP exp_rx;
1587 exp_rx := f_send_paging_ps(p4, sgsn_idx, use_sig);
1588 /* Expect paging to propagate to no BSS */
1589 timer T := 2.0;
1590 T.start;
1591 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001592 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte7462a592020-11-23 22:07:07 +01001593 setverdict(fail, "Paging received on unexpected BVC");
1594 }
1595 [] any from PCU_SIG.receive(exp_rx) {
1596 setverdict(fail, "Paging received on unexpected BVC");
1597 }
Harald Welte158becf2020-12-09 12:32:32 +01001598 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte7462a592020-11-23 22:07:07 +01001599 setverdict(fail, "Different Paging received on PTP BVC");
1600 }
1601 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1602 setverdict(fail, "Different Paging received on SIGNALING BVC");
1603 }
1604 [] T.timeout {
1605 setverdict(pass);
1606 }
1607 }
1608}
1609
Harald Welte0e188242020-11-22 21:46:48 +01001610private function f_TC_paging_ps_ptp_bss(charstring id) runs on BSSGP_ConnHdlr
1611{
1612 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1613 * at that BVC (cell) only, and paging all over the BSS area is not possible */
Daniel Willmann2a330672021-01-18 18:50:02 +01001614 f_send_paging_ps_exp_one_bss(ts_BssgpP4BssArea, g_pars.sgsn_idx, false, 0);
Harald Welte0e188242020-11-22 21:46:48 +01001615}
1616testcase TC_paging_ps_ptp_bss() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001617 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001618 f_start_handlers(refers(f_TC_paging_ps_ptp_bss), testcasename(), 9);
Harald Welte0e188242020-11-22 21:46:48 +01001619 f_cleanup();
1620}
1621
1622/* PS-PAGING on PTP-BVC for Location Area */
1623private function f_TC_paging_ps_ptp_lac(charstring id) runs on BSSGP_ConnHdlr
1624{
1625 var template (present) PDU_BSSGP exp_rx;
1626 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1627 * at that BVC (cell) only, and paging all over the BSS area is not possible */
Daniel Willmann2a330672021-01-18 18:50:02 +01001628 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 +01001629}
1630testcase TC_paging_ps_ptp_lac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001631 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001632 f_start_handlers(refers(f_TC_paging_ps_ptp_lac), testcasename(), 10);
Harald Welte0e188242020-11-22 21:46:48 +01001633 f_cleanup();
1634}
1635
Harald Welte7462a592020-11-23 22:07:07 +01001636/* PS-PAGING on PTP-BVC for unknown Location Area */
1637private function f_TC_paging_ps_ptp_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1638{
1639 var GSM_Types.LocationAreaIdentification unknown_la := {
1640 mcc_mnc := '567F99'H,
1641 lac := 33333
1642 };
1643 /* as it's sent on the PTP BVC, we expect it to pass even for unknown LAC */
Daniel Willmann2a330672021-01-18 18:50:02 +01001644 f_send_paging_ps_exp_one_bss(ts_BssgpP4LAC(unknown_la), g_pars.sgsn_idx, false, 0);
Harald Welte7462a592020-11-23 22:07:07 +01001645}
1646testcase TC_paging_ps_ptp_lac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001647 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001648 f_start_handlers(refers(f_TC_paging_ps_ptp_lac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001649 f_cleanup();
1650}
1651
Harald Welte0e188242020-11-22 21:46:48 +01001652/* PS-PAGING on PTP-BVC for Routeing Area */
1653private function f_TC_paging_ps_ptp_rac(charstring id) runs on BSSGP_ConnHdlr
1654{
1655 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1656 * at that BVC (cell) only, and paging all over the BSS area is not possible */
Daniel Willmann2a330672021-01-18 18:50:02 +01001657 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 +01001658}
1659testcase TC_paging_ps_ptp_rac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001660 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001661 f_start_handlers(refers(f_TC_paging_ps_ptp_rac), testcasename(), 11);
Harald Welte0e188242020-11-22 21:46:48 +01001662 f_cleanup();
1663}
1664
Harald Welte7462a592020-11-23 22:07:07 +01001665/* PS-PAGING on PTP-BVC for unknown Routeing Area */
1666private function f_TC_paging_ps_ptp_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1667{
1668 var RoutingAreaIdentification unknown_ra := {
1669 lai := {
1670 mcc_mnc := '567F99'H,
1671 lac := 33333
1672 },
1673 rac := 254
1674 };
1675 /* as it's sent on the PTP BVC, we expect it to pass even for unknown RAC */
Daniel Willmann2a330672021-01-18 18:50:02 +01001676 f_send_paging_ps_exp_one_bss(ts_BssgpP4RAC(unknown_ra), g_pars.sgsn_idx, false, 0);
Harald Welte7462a592020-11-23 22:07:07 +01001677}
1678testcase TC_paging_ps_ptp_rac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001679 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001680 f_start_handlers(refers(f_TC_paging_ps_ptp_rac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001681 f_cleanup();
1682}
1683
Harald Welte0e188242020-11-22 21:46:48 +01001684/* PS-PAGING on PTP-BVC for BVCI (one cell) */
1685private function f_TC_paging_ps_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
1686{
1687 /* this should be the normal case for MS in READY MM state after a lower layer failure */
Daniel Willmann2a330672021-01-18 18:50:02 +01001688 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 +01001689}
1690testcase TC_paging_ps_ptp_bvci() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001691 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001692 f_start_handlers(refers(f_TC_paging_ps_ptp_bvci), testcasename(), 12);
Harald Welte0e188242020-11-22 21:46:48 +01001693 f_cleanup();
1694}
1695
Harald Welteb5a04aa2021-01-16 13:04:40 +01001696
1697/* PS-PAGING on PTP-BVC for BVCI (one cell) using IMSI only (no P-TMSI allocated) */
1698testcase TC_paging_ps_ptp_bvci_imsi() runs on test_CT {
1699 f_init();
1700 f_start_handlers(refers(f_TC_paging_ps_ptp_bvci), testcasename(), 12, have_ptmsi:=false);
1701 f_cleanup();
1702}
1703
Harald Weltecf200072021-01-16 15:20:46 +01001704/* Rejected PS-PAGING on PTP-BVC for BVCI (one cell) */
1705testcase TC_paging_ps_reject_ptp_bvci() runs on test_CT {
1706 f_init();
1707 f_start_handlers(refers(f_TC_paging_ps_reject_ptp_bvci), testcasename(), 16);
1708 f_cleanup();
1709}
1710
1711/* Rejected PS-PAGING on PTP-BVC for BVCI (one cell) using IMSI only (no P-TMSI allocated) */
1712private function f_TC_paging_ps_reject_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
1713{
1714 /* first send the PS-PAGING from SGSN -> PCU */
Daniel Willmann2a330672021-01-18 18:50:02 +01001715 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 +01001716 /* then simulate the PS-PAGING-REJECT from the PCU */
1717 f_send_paging_ps_rej(use_sig:=false);
1718}
1719testcase TC_paging_ps_reject_ptp_bvci_imsi() runs on test_CT {
1720 f_init();
1721 f_start_handlers(refers(f_TC_paging_ps_reject_ptp_bvci), testcasename(), 16, have_ptmsi:=false);
1722 f_cleanup();
1723}
Harald Welteb5a04aa2021-01-16 13:04:40 +01001724
Harald Welte7462a592020-11-23 22:07:07 +01001725/* PS-PAGING on PTP-BVC for unknown BVCI */
1726private function f_TC_paging_ps_ptp_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1727{
1728 /* as it's sent on the PTP BVC, we expect it to pass even for unknown BVCI */
Daniel Willmann2a330672021-01-18 18:50:02 +01001729 f_send_paging_ps_exp_one_bss(ts_BssgpP4Bvci(33333), g_pars.sgsn_idx, false, 0);
Harald Welte7462a592020-11-23 22:07:07 +01001730}
1731testcase TC_paging_ps_ptp_bvci_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001732 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001733 f_start_handlers(refers(f_TC_paging_ps_ptp_bvci_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001734 f_cleanup();
1735}
1736
Harald Welte7595d562021-01-16 19:09:20 +01001737/* DUMMY PAGING PS on PTP BVC */
1738private function f_TC_dummy_paging_ps_ptp(charstring id) runs on BSSGP_ConnHdlr
1739{
1740 f_sgsn2pcu(ts_BSSGP_DUMMY_PAGING_PS(g_pars.imsi, omit),
1741 tr_BSSGP_DUMMY_PAGING_PS(g_pars.imsi, omit), use_sig := false);
1742 f_pcu2sgsn(ts_BSSGP_DUMMY_PAGING_PS_RESP(g_pars.imsi, 1, 5),
1743 tr_BSSGP_DUMMY_PAGING_PS_RESP(g_pars.imsi, 1, 5), use_sig := false)
1744}
1745testcase TC_dummy_paging_ps_ptp() runs on test_CT {
1746 f_init();
1747 f_start_handlers(refers(f_TC_dummy_paging_ps_ptp), testcasename(), 11);
1748 f_cleanup();
1749}
1750
Harald Welte0e188242020-11-22 21:46:48 +01001751/* altstep for expecting BSSGP PDU on signaling BVC of given pcu_idx + storing in 'roi' */
1752private altstep as_paging_sig_pcu(integer pcu_idx, template (present) PDU_BSSGP exp_rx, inout ro_integer roi)
1753runs on BSSGP_ConnHdlr {
1754[] PCU_SIG[pcu_idx].receive(exp_rx) {
1755 if (ro_integer_contains(roi, pcu_idx)) {
1756 setverdict(fail, "Received multiple paging on same SIG BVC");
1757 }
1758 roi := roi & { pcu_idx };
1759 repeat;
1760 }
Harald Welte158becf2020-12-09 12:32:32 +01001761[] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001762 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1763 }
1764[] PCU_SIG[pcu_idx].receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1765 setverdict(fail, "Different Paging than expected received SIGNALING BVC");
1766 }
Harald Welte158becf2020-12-09 12:32:32 +01001767[] PCU_PTP[pcu_idx].receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01001768 setverdict(fail, "Different Paging than expected received PTP BVC");
1769 }
1770}
1771
1772type record of default ro_default;
1773
1774/* send PS-PAGING on SIG BVC, expect it to arrive on given list of PCU indexes */
1775private function f_send_paging_ps_exp_multi(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1776 ro_integer exp_on_pcu_idx) runs on BSSGP_ConnHdlr
1777{
1778 var template (present) PDU_BSSGP exp_rx;
Daniel Willmann193e1a02021-01-17 12:55:53 +01001779 exp_rx := f_send_paging_ps(p4, sgsn_idx, true);
Harald Welte0e188242020-11-22 21:46:48 +01001780
1781 /* FIXME: make sure the relevant BVCs/BSS are connected to the ports! */
1782 var ro_default defaults := {};
1783 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1784 var default d := activate(as_paging_sig_pcu(i, exp_rx, g_roi));
1785 defaults := defaults & { d };
1786 }
1787 f_sleep(2.0);
1788 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
1789 deactivate(defaults[i]);
1790 }
1791 log("Paging received on PCU ", g_roi);
1792
1793 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1794 var boolean rx_on_i := ro_integer_contains(g_roi, i);
1795 var boolean exp_on_i := ro_integer_contains(exp_on_pcu_idx, i);
1796 if (exp_on_i and not rx_on_i) {
1797 setverdict(fail, "PS-PAGING not received on ", mp_nsconfig_pcu[i].nsei);
1798 }
1799 if (not exp_on_i and rx_on_i) {
1800 setverdict(fail, "PS-PAGING not expected but received on ", mp_nsconfig_pcu[i].nsei);
1801 }
1802 }
1803 setverdict(pass);
1804}
1805
Harald Weltecf200072021-01-16 15:20:46 +01001806/* Send PAGING-PS-REJECT on SIG BVC, expect it to arrive on the "right" SGSN */
1807private function f_send_paging_ps_rej(boolean use_sig := true, integer pcu_idx := 0) runs on BSSGP_ConnHdlr
1808{
1809 var template (value) PDU_BSSGP pdu_tx;
1810 var template (present) PDU_BSSGP exp_rx;
1811 var PDU_BSSGP pdu_rx;
1812 timer T := 5.0;
1813 var template (omit) GsmTmsi tmsi_int := omit;
1814
1815 if (ispresent(g_pars.p_tmsi)) {
1816 tmsi_int := oct2int(g_pars.p_tmsi);
1817 }
1818
1819 pdu_tx := ts_BSSGP_PAGING_PS_REJ(g_pars.imsi, 23, 42, tmsi_int);
1820 exp_rx := tr_BSSGP_PAGING_PS_REJ(g_pars.imsi, 23, 42, tmsi_int);
1821
1822 if (use_sig) {
1823 PCU_SIG[pcu_idx].send(pdu_tx);
1824 } else {
1825 PCU_PTP[pcu_idx].send(pdu_tx);
1826 }
1827 T.start;
1828 alt {
1829 [use_sig] SGSN_SIG[g_pars.sgsn_idx].receive(exp_rx) -> value pdu_rx {
1830 setverdict(pass);
1831 }
1832 [use_sig] SGSN_SIG[g_pars.sgsn_idx].receive {
1833 setverdict(fail, "Unexpected PDU on SGSN");
1834 }
1835 [use_sig] any from SGSN_SIG.receive(exp_rx) -> value pdu_rx {
1836 setverdict(fail, "PAGING-PS-REJECT arrived on wrong SGSN");
1837 }
1838 [not use_sig] SGSN_PTP[g_pars.sgsn_idx].receive(exp_rx) -> value pdu_rx {
1839 setverdict(pass);
1840 }
1841 [not use_sig] SGSN_PTP[g_pars.sgsn_idx].receive {
1842 setverdict(fail, "Unexpected PDU on SGSN");
1843 }
1844 [not use_sig] any from SGSN_PTP.receive(exp_rx) -> value pdu_rx {
1845 setverdict(fail, "PAGING-PS-REJECT arrived on wrong SGSN");
1846 }
1847 [] T.timeout {
1848 setverdict(fail, "Timeout waiting for PAGING-PS-REJECT");
1849 }
1850 }
1851}
1852
Harald Welte0e188242020-11-22 21:46:48 +01001853/* PS-PAGING on SIG-BVC for BSS Area */
1854private function f_TC_paging_ps_sig_bss(charstring id) runs on BSSGP_ConnHdlr
1855{
1856 /* we expect the paging to arrive on all three NSE */
Daniel Willmann43320442021-01-17 14:07:05 +01001857 f_send_paging_ps_exp_multi(ts_BssgpP4BssArea, g_pars.sgsn_idx, {0, 1, 2});
Harald Welte0e188242020-11-22 21:46:48 +01001858}
1859testcase TC_paging_ps_sig_bss() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001860 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001861 f_start_handlers(refers(f_TC_paging_ps_sig_bss), testcasename(), 13);
Harald Welte0e188242020-11-22 21:46:48 +01001862 f_cleanup();
1863}
1864
1865/* PS-PAGING on SIG-BVC for Location Area */
1866private function f_TC_paging_ps_sig_lac(charstring id) runs on BSSGP_ConnHdlr
1867{
Daniel Willmann2c9300f2020-12-01 10:54:08 +01001868 /* The first LAC (13135) is shared by all three NSEs */
Daniel Willmann43320442021-01-17 14:07:05 +01001869 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 +01001870 /* Reset state */
1871 g_roi := {};
1872 /* Make LAC (13300) available on pcu index 2 */
1873 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
Daniel Willmann43320442021-01-17 14:07:05 +01001874 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 +01001875}
1876testcase TC_paging_ps_sig_lac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001877 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001878 f_start_handlers(refers(f_TC_paging_ps_sig_lac), testcasename(), 14);
Harald Welte0e188242020-11-22 21:46:48 +01001879 f_cleanup();
1880}
1881
Harald Welte7462a592020-11-23 22:07:07 +01001882/* PS-PAGING on SIG-BVC for unknown Location Area */
1883private function f_TC_paging_ps_sig_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1884{
1885 var GSM_Types.LocationAreaIdentification unknown_la := {
1886 mcc_mnc := '567F99'H,
1887 lac := 33333
1888 };
Daniel Willmann2a330672021-01-18 18:50:02 +01001889 f_send_paging_ps_exp_no_bss(ts_BssgpP4LAC(unknown_la), g_pars.sgsn_idx, true);
Harald Welte7462a592020-11-23 22:07:07 +01001890}
1891testcase TC_paging_ps_sig_lac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001892 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001893 f_start_handlers(refers(f_TC_paging_ps_sig_lac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001894 f_cleanup();
1895}
1896
Harald Welte0e188242020-11-22 21:46:48 +01001897/* PS-PAGING on SIG-BVC for Routeing Area */
1898private function f_TC_paging_ps_sig_rac(charstring id) runs on BSSGP_ConnHdlr
1899{
Daniel Willmann2c9300f2020-12-01 10:54:08 +01001900 /* Only PCU index 0 has a matching BVC with the RA ID */
Daniel Willmann43320442021-01-17 14:07:05 +01001901 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 +01001902 g_roi := {};
1903 /* PCU index 1 and 2 have a matching BVC with the RA ID */
Daniel Willmann43320442021-01-17 14:07:05 +01001904 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 +01001905 g_roi := {};
1906 /* PCU index 2 has two matching BVCs with the RA ID */
1907 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
Daniel Willmann43320442021-01-17 14:07:05 +01001908 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 +01001909}
1910testcase TC_paging_ps_sig_rac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001911 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001912 f_start_handlers(refers(f_TC_paging_ps_sig_rac), testcasename(), 15);
Harald Welte0e188242020-11-22 21:46:48 +01001913 f_cleanup();
1914}
1915
Harald Welte7462a592020-11-23 22:07:07 +01001916/* PS-PAGING on SIG-BVC for unknown Routeing Area */
1917private function f_TC_paging_ps_sig_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1918{
1919 var RoutingAreaIdentification unknown_ra := {
1920 lai := {
1921 mcc_mnc := '567F99'H,
1922 lac := 33333
1923 },
1924 rac := 254
1925 };
Daniel Willmann2a330672021-01-18 18:50:02 +01001926 f_send_paging_ps_exp_no_bss(ts_BssgpP4RAC(unknown_ra), g_pars.sgsn_idx, true);
Harald Welte7462a592020-11-23 22:07:07 +01001927}
1928testcase TC_paging_ps_sig_rac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001929 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001930 f_start_handlers(refers(f_TC_paging_ps_sig_rac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001931 f_cleanup();
1932}
1933
Harald Welte0e188242020-11-22 21:46:48 +01001934/* PS-PAGING on SIG-BVC for BVCI (one cell) */
1935private function f_TC_paging_ps_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
1936{
Daniel Willmann43320442021-01-17 14:07:05 +01001937 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 +01001938}
1939testcase TC_paging_ps_sig_bvci() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001940 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001941 f_start_handlers(refers(f_TC_paging_ps_sig_bvci), testcasename(), 16);
Harald Welte0e188242020-11-22 21:46:48 +01001942 f_cleanup();
1943}
1944
Harald Welteb5a04aa2021-01-16 13:04:40 +01001945/* PS-PAGING on SIG-BVC for BVCI (one cell) using IMSI only (no P-TMSI allocated) */
1946testcase TC_paging_ps_sig_bvci_imsi() runs on test_CT {
1947 f_init();
1948 f_start_handlers(refers(f_TC_paging_ps_sig_bvci), testcasename(), 16, have_ptmsi:=false);
1949 f_cleanup();
1950}
1951
Harald Weltecf200072021-01-16 15:20:46 +01001952/* Rejected PS-PAGING on SIG-BVC for BVCI (one cell) */
1953private function f_TC_paging_ps_reject_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
1954{
1955 /* first send the PS-PAGING from SGSN -> PCU */
Daniel Willmann43320442021-01-17 14:07:05 +01001956 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 +01001957 /* then simulate the PS-PAGING-REJECT from the PCU */
1958 f_send_paging_ps_rej(use_sig:=true);
1959
1960}
1961testcase TC_paging_ps_reject_sig_bvci() runs on test_CT {
1962 f_init();
1963 f_start_handlers(refers(f_TC_paging_ps_reject_sig_bvci), testcasename(), 16);
1964 f_cleanup();
1965}
1966
1967/* Rejected PS-PAGING on SIG-BVC for BVCI (one cell) using IMSI only (no P-TMSI allocated) */
1968testcase TC_paging_ps_reject_sig_bvci_imsi() runs on test_CT {
1969 f_init();
1970 f_start_handlers(refers(f_TC_paging_ps_reject_sig_bvci), testcasename(), 16, have_ptmsi:=false);
1971 f_cleanup();
1972}
1973
Harald Welte7462a592020-11-23 22:07:07 +01001974/* PS-PAGING on SIG-BVC for unknown BVCI */
1975private function f_TC_paging_ps_sig_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1976{
Daniel Willmann2a330672021-01-18 18:50:02 +01001977 f_send_paging_ps_exp_no_bss(ts_BssgpP4Bvci(33333), g_pars.sgsn_idx, true);
Harald Welte7462a592020-11-23 22:07:07 +01001978}
1979testcase TC_paging_ps_sig_bvci_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001980 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001981 f_start_handlers(refers(f_TC_paging_ps_sig_bvci_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001982 f_cleanup();
1983}
1984
Harald Welte7595d562021-01-16 19:09:20 +01001985/* DUMMY PAGING PS on SIG BVC */
1986private function f_TC_dummy_paging_ps_sig(charstring id) runs on BSSGP_ConnHdlr
1987{
1988 f_sgsn2pcu(ts_BSSGP_DUMMY_PAGING_PS(g_pars.imsi, omit),
1989 tr_BSSGP_DUMMY_PAGING_PS(g_pars.imsi, omit), use_sig := true);
1990 f_pcu2sgsn(ts_BSSGP_DUMMY_PAGING_PS_RESP(g_pars.imsi, 1, 5),
1991 tr_BSSGP_DUMMY_PAGING_PS_RESP(g_pars.imsi, 1, 5), use_sig := true)
1992}
1993testcase TC_dummy_paging_ps_sig() runs on test_CT {
1994 f_init();
1995 f_start_handlers(refers(f_TC_dummy_paging_ps_sig), testcasename(), 11);
1996 f_cleanup();
1997}
1998
Harald Welte7462a592020-11-23 22:07:07 +01001999
Harald Welte0e188242020-11-22 21:46:48 +01002000
2001/***********************************************************************
2002 * PAGING CS procedure
2003 ***********************************************************************/
2004
2005private function f_send_paging_cs(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
2006 boolean use_sig := false)
2007runs on BSSGP_ConnHdlr return template (present) PDU_BSSGP {
2008 var template (value) PDU_BSSGP pdu_tx;
2009 var template (present) PDU_BSSGP pdu_rx;
2010 /* we always specify '0' as BVCI in the templates below, as we override it with
2011 * 'p4' later anyway */
2012 pdu_rx := tr_BSSGP_CS_PAGING(0);
2013 pdu_rx.pDU_BSSGP_PAGING_CS.iMSI := tr_BSSGP_IMSI(g_pars.imsi);
2014 if (ispresent(g_pars.p_tmsi)) {
2015 pdu_tx := ts_BSSGP_CS_PAGING_PTMSI(0, g_pars.imsi, oct2int(g_pars.p_tmsi));
2016 pdu_rx.pDU_BSSGP_PAGING_CS.tMSI := tr_BSSGP_TMSI(oct2int(g_pars.p_tmsi));
2017 } else {
2018 pdu_tx := ts_BSSGP_CS_PAGING_IMSI(0, g_pars.imsi);
2019 pdu_rx.pDU_BSSGP_PAGING_CS.tMSI := omit;
2020 }
2021 pdu_tx.pDU_BSSGP_PAGING_CS.paging_Field4 := p4;
2022 pdu_rx.pDU_BSSGP_PAGING_CS.paging_Field4 := p4;
2023 if (use_sig == false) {
Harald Welte158becf2020-12-09 12:32:32 +01002024 SGSN_PTP[sgsn_idx].send(pdu_tx);
Harald Welte0e188242020-11-22 21:46:48 +01002025 } else {
2026 SGSN_SIG[sgsn_idx].send(pdu_tx);
2027 }
2028 return pdu_rx;
2029}
2030
2031/* send paging defined by 'p4' on given SGSN-side index (ptp or signaling) and expect one paging to arrive on
2032 * specified PCU index */
2033private function f_send_paging_cs_exp_one_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
2034 boolean use_sig := false,integer pcu_idx := 0)
2035runs on BSSGP_ConnHdlr {
2036 var template (present) PDU_BSSGP exp_rx;
Daniel Willmann1a859712020-12-04 00:59:45 +01002037 var boolean test_done := false;
Harald Welte0e188242020-11-22 21:46:48 +01002038 /* doesn't really make sense: Sending to a single BVCI means the message ends up
2039 * at that BVC (cell) only, and paging all over the BSS area is not possible */
2040 exp_rx := f_send_paging_cs(p4, sgsn_idx, use_sig);
2041 /* Expect paging to propagate to the one BSS addressed by the BVCI only */
2042 timer T := 2.0;
2043 T.start;
2044 alt {
Harald Welte158becf2020-12-09 12:32:32 +01002045 [not use_sig and not test_done] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01002046 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01002047 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01002048 repeat;
2049 }
2050 [not use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
2051 setverdict(fail, "Received paging on SIGNALING BVC, expected PTP BVC");
2052 }
Daniel Willmann1a859712020-12-04 00:59:45 +01002053 [use_sig and not test_done] PCU_SIG[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01002054 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01002055 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01002056 repeat;
2057 }
Harald Welte158becf2020-12-09 12:32:32 +01002058 [use_sig] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01002059 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
2060 }
Harald Welte158becf2020-12-09 12:32:32 +01002061 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01002062 setverdict(fail, "Paging received on unexpected BVC");
2063 }
2064 [] any from PCU_SIG.receive(exp_rx) {
2065 setverdict(fail, "Paging received on unexpected BVC");
2066 }
Harald Welte158becf2020-12-09 12:32:32 +01002067 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01002068 setverdict(fail, "Different Paging than expected received PTP BVC");
2069 }
2070 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
2071 setverdict(fail, "Different Paging than expected on SIGNALING BVC");
2072 }
Daniel Willmann1a859712020-12-04 00:59:45 +01002073 [not test_done] T.timeout {
2074 setverdict(fail, "Timeout while waiting for paging")
2075 }
2076 [test_done] T.timeout;
Harald Welte0e188242020-11-22 21:46:48 +01002077 }
2078}
2079
Harald Welte7462a592020-11-23 22:07:07 +01002080/* send a CS-PAGING but don't expect it to show up on any PTP or SIG BVC */
2081private function f_send_paging_cs_exp_no_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
2082 boolean use_sig := false)
2083runs on BSSGP_ConnHdlr {
2084 var template (present) PDU_BSSGP exp_rx;
2085 exp_rx := f_send_paging_cs(p4, sgsn_idx, use_sig);
2086 /* Expect paging to propagate to no BSS */
2087 timer T := 2.0;
2088 T.start;
2089 alt {
Harald Welte158becf2020-12-09 12:32:32 +01002090 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte7462a592020-11-23 22:07:07 +01002091 setverdict(fail, "Paging received on unexpected BVC");
2092 }
2093 [] any from PCU_SIG.receive(exp_rx) {
2094 setverdict(fail, "Paging received on unexpected BVC");
2095 }
Harald Welte158becf2020-12-09 12:32:32 +01002096 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
Harald Welte7462a592020-11-23 22:07:07 +01002097 setverdict(fail, "Different Paging received on PTP BVC");
2098 }
2099 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
2100 setverdict(fail, "Different Paging received on SIGNALING BVC");
2101 }
2102 [] T.timeout {
2103 setverdict(pass);
2104 }
2105 }
2106}
2107
Harald Welte0e188242020-11-22 21:46:48 +01002108private function f_TC_paging_cs_ptp_bss(charstring id) runs on BSSGP_ConnHdlr
2109{
2110 /* doesn't really make sense: Sending to a single BVCI means the message ends up
2111 * at that BVC (cell) only, and paging all over the BSS area is not possible */
2112 f_send_paging_cs_exp_one_bss(ts_BssgpP4BssArea, 0, false, 0);
2113}
2114testcase TC_paging_cs_ptp_bss() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002115 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002116 f_start_handlers(refers(f_TC_paging_cs_ptp_bss), testcasename(), 17);
Harald Welte0e188242020-11-22 21:46:48 +01002117 f_cleanup();
2118}
2119
2120/* CS-PAGING on PTP-BVC for Location Area */
2121private function f_TC_paging_cs_ptp_lac(charstring id) runs on BSSGP_ConnHdlr
2122{
2123 var template (present) PDU_BSSGP exp_rx;
2124 /* doesn't really make sense: Sending to a single BVCI means the message ends up
2125 * at that BVC (cell) only, and paging all over the BSS area is not possible */
2126 f_send_paging_cs_exp_one_bss(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, false, 0);
2127}
2128testcase TC_paging_cs_ptp_lac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002129 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002130 f_start_handlers(refers(f_TC_paging_cs_ptp_lac), testcasename(), 18);
Harald Welte0e188242020-11-22 21:46:48 +01002131 f_cleanup();
2132}
2133
Harald Welte7462a592020-11-23 22:07:07 +01002134/* CS-PAGING on PTP-BVC for unknown Location Area */
2135private function f_TC_paging_cs_ptp_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
2136{
2137 var GSM_Types.LocationAreaIdentification unknown_la := {
2138 mcc_mnc := '567F99'H,
2139 lac := 33333
2140 };
2141 /* as it's sent on the PTP BVC, we expect it to pass even for unknown LAC */
2142 f_send_paging_cs_exp_one_bss(ts_BssgpP4LAC(unknown_la), 0, false, 0);
2143}
2144testcase TC_paging_cs_ptp_lac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002145 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002146 f_start_handlers(refers(f_TC_paging_cs_ptp_lac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002147 f_cleanup();
2148}
2149
Harald Welte0e188242020-11-22 21:46:48 +01002150/* CS-PAGING on PTP-BVC for Routeing Area */
2151private function f_TC_paging_cs_ptp_rac(charstring id) runs on BSSGP_ConnHdlr
2152{
2153 /* doesn't really make sense: Sending to a single BVCI means the message ends up
2154 * at that BVC (cell) only, and paging all over the BSS area is not possible */
2155 f_send_paging_cs_exp_one_bss(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, false, 0);
2156}
2157testcase TC_paging_cs_ptp_rac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002158 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002159 f_start_handlers(refers(f_TC_paging_cs_ptp_rac), testcasename(), 19);
Harald Welte0e188242020-11-22 21:46:48 +01002160 f_cleanup();
2161}
2162
Harald Welte7462a592020-11-23 22:07:07 +01002163/* CS-PAGING on PTP-BVC for unknown Routeing Area */
2164private function f_TC_paging_cs_ptp_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
2165{
2166 var RoutingAreaIdentification unknown_ra := {
2167 lai := {
2168 mcc_mnc := '567F99'H,
2169 lac := 33333
2170 },
2171 rac := 254
2172 };
2173 /* as it's sent on the PTP BVC, we expect it to pass even for unknown RAC */
2174 f_send_paging_cs_exp_one_bss(ts_BssgpP4RAC(unknown_ra), 0, false, 0);
2175}
2176testcase TC_paging_cs_ptp_rac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002177 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002178 f_start_handlers(refers(f_TC_paging_cs_ptp_rac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002179 f_cleanup();
2180}
2181
Harald Welte0e188242020-11-22 21:46:48 +01002182/* CS-PAGING on PTP-BVC for BVCI (one cell) */
2183private function f_TC_paging_cs_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
2184{
2185 /* this should be the normal case for MS in READY MM state after a lower layer failure */
2186 f_send_paging_cs_exp_one_bss(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, false, 0);
2187}
2188testcase TC_paging_cs_ptp_bvci() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002189 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002190 f_start_handlers(refers(f_TC_paging_cs_ptp_bvci), testcasename(), 20);
Harald Welte0e188242020-11-22 21:46:48 +01002191 f_cleanup();
2192}
2193
Harald Welte7462a592020-11-23 22:07:07 +01002194/* CS-PAGING on PTP-BVC for unknown BVCI */
2195private function f_TC_paging_cs_ptp_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
2196{
2197 /* as it's sent on the PTP BVC, we expect it to pass even for unknown BVCI */
2198 f_send_paging_cs_exp_one_bss(ts_BssgpP4Bvci(33333), 0, false, 0);
2199}
2200testcase TC_paging_cs_ptp_bvci_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002201 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002202 f_start_handlers(refers(f_TC_paging_cs_ptp_bvci_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002203 f_cleanup();
2204}
2205
Harald Welte0e188242020-11-22 21:46:48 +01002206/* send CS-PAGING on SIG BVC, expect it to arrive on given list of PCU indexes */
2207private function f_send_paging_cs_exp_multi(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
2208 ro_integer exp_on_pcu_idx) runs on BSSGP_ConnHdlr
2209{
2210 var template (present) PDU_BSSGP exp_rx;
2211 exp_rx := f_send_paging_cs(p4, 0, true);
2212
2213 /* FIXME: make sure the relevant BVCs/BSS are connected to the ports! */
2214 var ro_default defaults := {};
2215 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
2216 var default d := activate(as_paging_sig_pcu(i, exp_rx, g_roi));
2217 defaults := defaults & { d };
2218 }
2219 f_sleep(2.0);
2220 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2221 deactivate(defaults[i]);
2222 }
2223 log("Paging received on PCU ", g_roi);
2224
2225 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
2226 var boolean rx_on_i := ro_integer_contains(g_roi, i);
2227 var boolean exp_on_i := ro_integer_contains(exp_on_pcu_idx, i);
2228 if (exp_on_i and not rx_on_i) {
2229 setverdict(fail, "PS-PAGING not received on ", mp_nsconfig_pcu[i].nsei);
2230 }
2231 if (not exp_on_i and rx_on_i) {
2232 setverdict(fail, "PS-PAGING not expected but received on ", mp_nsconfig_pcu[i].nsei);
2233 }
2234 }
2235 setverdict(pass);
2236}
2237
2238/* CS-PAGING on SIG-BVC for BSS Area */
2239private function f_TC_paging_cs_sig_bss(charstring id) runs on BSSGP_ConnHdlr
2240{
2241 /* we expect the paging to arrive on all three NSE */
2242 f_send_paging_cs_exp_multi(ts_BssgpP4BssArea, 0, {0, 1, 2});
2243}
2244testcase TC_paging_cs_sig_bss() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002245 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002246 f_start_handlers(refers(f_TC_paging_cs_sig_bss), testcasename(), 13);
Harald Welte0e188242020-11-22 21:46:48 +01002247 f_cleanup();
2248}
2249
2250/* CS-PAGING on SIG-BVC for Location Area */
2251private function f_TC_paging_cs_sig_lac(charstring id) runs on BSSGP_ConnHdlr
2252{
Daniel Willmannd4fb73c2020-12-07 13:57:17 +01002253 /* The first LAC (13135) is shared by all three NSEs */
2254 f_send_paging_cs_exp_multi(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, {0, 1, 2});
2255 /* Reset state */
2256 g_roi := {};
2257 /* Make LAC (13300) available on pcu index 2 */
2258 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
2259 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 +01002260}
2261testcase TC_paging_cs_sig_lac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002262 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002263 f_start_handlers(refers(f_TC_paging_cs_sig_lac), testcasename(), 14);
Harald Welte0e188242020-11-22 21:46:48 +01002264 f_cleanup();
2265}
2266
Harald Welte7462a592020-11-23 22:07:07 +01002267/* CS-PAGING on SIG-BVC for unknown Location Area */
2268private function f_TC_paging_cs_sig_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
2269{
2270 var GSM_Types.LocationAreaIdentification unknown_la := {
2271 mcc_mnc := '567F99'H,
2272 lac := 33333
2273 };
2274 f_send_paging_cs_exp_no_bss(ts_BssgpP4LAC(unknown_la), 0, true);
2275}
2276testcase TC_paging_cs_sig_lac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002277 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002278 f_start_handlers(refers(f_TC_paging_cs_sig_lac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002279 f_cleanup();
2280}
2281
Harald Welte0e188242020-11-22 21:46:48 +01002282/* CS-PAGING on SIG-BVC for Routeing Area */
2283private function f_TC_paging_cs_sig_rac(charstring id) runs on BSSGP_ConnHdlr
2284{
Daniel Willmannd4fb73c2020-12-07 13:57:17 +01002285 /* Only PCU index 0 has a matching BVC with the RA ID */
Harald Welte0e188242020-11-22 21:46:48 +01002286 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 +01002287 g_roi := {};
2288 /* PCU index 1 and 2 have a matching BVC with the RA ID */
2289 f_send_paging_cs_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[2].cell_id.ra_id), 0, {1, 2});
2290 g_roi := {};
2291 /* PCU index 2 has two matching BVCs with the RA ID */
2292 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
2293 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 +01002294}
2295testcase TC_paging_cs_sig_rac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002296 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002297 f_start_handlers(refers(f_TC_paging_cs_sig_rac), testcasename(), 15);
Harald Welte0e188242020-11-22 21:46:48 +01002298 f_cleanup();
2299}
2300
Harald Welte7462a592020-11-23 22:07:07 +01002301/* CS-PAGING on SIG-BVC for unknown Routeing Area */
2302private function f_TC_paging_cs_sig_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
2303{
2304 var RoutingAreaIdentification unknown_ra := {
2305 lai := {
2306 mcc_mnc := '567F99'H,
2307 lac := 33333
2308 },
2309 rac := 254
2310 };
2311 f_send_paging_cs_exp_no_bss(ts_BssgpP4RAC(unknown_ra), 0, true);
2312}
2313testcase TC_paging_cs_sig_rac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002314 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002315 f_start_handlers(refers(f_TC_paging_cs_sig_rac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002316 f_cleanup();
2317}
2318
Harald Welte0e188242020-11-22 21:46:48 +01002319/* CS-PAGING on SIG-BVC for BVCI (one cell) */
2320private function f_TC_paging_cs_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
2321{
2322 f_send_paging_cs_exp_multi(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, {0});
2323}
2324testcase TC_paging_cs_sig_bvci() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002325 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002326 f_start_handlers(refers(f_TC_paging_cs_sig_bvci), testcasename(), 16);
Harald Welte0e188242020-11-22 21:46:48 +01002327 f_cleanup();
2328}
2329
Harald Welte7462a592020-11-23 22:07:07 +01002330/* CS-PAGING on SIG-BVC for unknown BVCI */
2331private function f_TC_paging_cs_sig_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
2332{
2333 f_send_paging_cs_exp_no_bss(ts_BssgpP4Bvci(33333), 0, true);
2334}
2335testcase TC_paging_cs_sig_bvci_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002336 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002337 f_start_handlers(refers(f_TC_paging_cs_sig_bvci_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002338 f_cleanup();
2339}
2340
Harald Welte4f91c3b2020-12-09 12:25:51 +01002341/***********************************************************************
2342 * FLUSH-LL procedure
2343 ***********************************************************************/
2344
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002345private function f_TC_flush_ll(charstring id) runs on BSSGP_ConnHdlr {
2346 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
2347 var integer i;
2348 for (i := 0; i < 10; i := i+1) {
2349 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_FLUSH_LL(g_pars.tlli, bvci, bvci_new := bvci);
2350 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2351 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_FLUSH_LL(g_pars.tlli, bvci, bvci_new := bvci);
2352
2353 f_sgsn2pcu(pdu_tx, pdu_rx, use_sig := true);
2354
2355 pdu_tx := ts_BSSGP_FLUSH_LL_ACK(g_pars.tlli, int2oct(0, 1), 23, bvci_new := bvci);
2356 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2357 pdu_rx := tr_BSSGP_FLUSH_LL_ACK(g_pars.tlli, int2oct(0, 1), 23, bvci_new := bvci);
2358
2359 f_pcu2sgsn(pdu_tx, pdu_rx, use_sig := true);
2360 }
2361 setverdict(pass);
2362}
2363testcase TC_flush_ll() runs on test_CT
2364{
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002365 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002366 f_start_handlers(refers(f_TC_flush_ll), testcasename(), 6);
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002367 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002368 f_cleanup();
2369}
Harald Welte6dc2ac42020-11-16 09:16:17 +01002370
Harald Welte4f91c3b2020-12-09 12:25:51 +01002371/***********************************************************************
2372 * SGSN-INVOKE-TRACE procedure
2373 ***********************************************************************/
2374
Harald Weltef8e5c5d2020-11-27 22:37:23 +01002375private altstep as_bssgp_g_pcu_count(integer pcu_idx, template (present) PDU_BSSGP exp_rx, inout ro_integer roi)
2376runs on GlobalTest_CT {
2377[] G_PCU[pcu_idx].receive(exp_rx) from g_pcu[pcu_idx].vc_BSSGP {
2378 if (ro_integer_contains(roi, pcu_idx)) {
2379 setverdict(fail, "Received multiple on same SIG BVC");
2380 }
2381 roi := roi & { pcu_idx };
2382 repeat;
2383 }
2384}
2385/* send a INVOKE-TRACE from SGSN and expect to receive a copy on each NSE */
2386testcase TC_trace() runs on GlobalTest_CT
2387{
2388 var BSSGP_ConnHdlr vc_conn;
2389 f_init();
2390 f_global_init();
2391
2392 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_INVOKE_TRACE('23'O, '4321'O);
2393 var template (present) PDU_BSSGP exp_rx := ts_BSSGP_INVOKE_TRACE('23'O, '4321'O);
2394
2395 var ro_default defaults := {};
2396 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2397 activate(as_bssgp_g_pcu_count(i, exp_rx, g_roi));
2398 }
2399 G_SGSN[0].send(pdu_tx);
2400 f_sleep(2.0);
2401 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2402 deactivate(defaults[i]);
2403 }
2404
2405 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2406 if (not ro_integer_contains(g_roi, i)) {
2407 setverdict(fail, "Failed to receive TRACE on PCU index ", i);
2408 }
2409 }
2410 setverdict(pass);
2411
2412 f_cleanup();
2413}
2414
Harald Welte4f91c3b2020-12-09 12:25:51 +01002415/***********************************************************************
2416 * LLC-DISCARDED procedure
2417 ***********************************************************************/
2418
Harald Weltec0351d12020-11-27 22:49:02 +01002419private function f_TC_llc_discarded(charstring id) runs on BSSGP_ConnHdlr {
2420 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
2421
2422 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_LLC_DISCARDED(g_pars.tlli, 23, bvci, 2342);
2423 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2424 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_LLC_DISCARDED(g_pars.tlli, 23, bvci, 2342);
2425
2426 f_pcu2sgsn(pdu_tx, pdu_rx, use_sig := true);
2427
2428 setverdict(pass);
2429}
2430/* Send a LLC-DISCARDED from BSS side and expect it to show up on SGSN (SIG BVC) */
2431testcase TC_llc_discarded() runs on test_CT
2432{
Harald Weltec0351d12020-11-27 22:49:02 +01002433 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002434 f_start_handlers(refers(f_TC_llc_discarded), testcasename(), 6);
Harald Weltec0351d12020-11-27 22:49:02 +01002435 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Weltec0351d12020-11-27 22:49:02 +01002436 f_cleanup();
2437}
2438
Harald Welte4f91c3b2020-12-09 12:25:51 +01002439/***********************************************************************
2440 * OVERLOAD procedure
2441 ***********************************************************************/
2442
Harald Weltef20af412020-11-28 16:11:11 +01002443/* Send an OVERLOAD from SGSN side and expect it to show up on each PCU (SIG BVC) */
2444testcase TC_overload() runs on GlobalTest_CT
2445{
2446 f_init();
2447 f_global_init();
2448
2449 var template (value) PDU_BSSGP pdu_tx := ts_OVERLOAD('1'B);
2450 var template (present) PDU_BSSGP exp_rx := tr_OVERLOAD('1'B);
2451
2452 var ro_default defaults := {};
2453 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2454 activate(as_bssgp_g_pcu_count(i, exp_rx, g_roi));
2455 }
2456 G_SGSN[0].send(pdu_tx);
2457 f_sleep(2.0);
2458 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2459 deactivate(defaults[i]);
2460 }
2461
2462 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2463 if (not ro_integer_contains(g_roi, i)) {
2464 setverdict(fail, "Failed to receive OVERLOAD on PCU index ", i);
2465 }
2466 }
2467 setverdict(pass);
2468
2469 f_cleanup();
2470}
2471
Harald Welte4f91c3b2020-12-09 12:25:51 +01002472/***********************************************************************
2473 * BVC-BLOCK / BVC-UNBLOCK procedure
2474 ***********************************************************************/
2475
Harald Welte239aa502020-11-24 23:14:20 +01002476private function f_block_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2477{
2478 var BSSGP_BVC_CT bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2479 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2480 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2481
2482 SGSN_MGMT.clear;
2483 PCU_MGMT.clear;
2484
2485 /* block the PTP BVC from the PCU side */
2486 PCU_MGMT.send(BssgpBlockRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to bvc_ct;
2487 /* expect state on both PCU and SGSN side to change */
2488 interleave {
2489 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_BLOCKED)) from bvc_ct;
Harald Welte572b0172021-03-30 13:19:56 +02002490 [] SGSN_MGMT.receive(tr_BssgpStsInd(mp_nsconfig_sgsn[0].nsei, bvc_cfg.bvci, BVC_S_BLOCKED));
2491 [] SGSN_MGMT.receive(tr_BssgpStsInd(mp_nsconfig_sgsn[1].nsei, bvc_cfg.bvci, BVC_S_BLOCKED));
2492 /* Doesn't auto-scale with NUM_SGSN */
Harald Welte239aa502020-11-24 23:14:20 +01002493 }
2494 setverdict(pass);
2495}
2496testcase TC_bvc_block_ptp() runs on test_CT
2497{
2498 f_init();
2499 f_sleep(1.0);
2500 f_block_ptp_bvc_from_pcu(0, 0);
2501 f_cleanup();
2502}
2503
2504private function f_unblock_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2505{
2506 var BSSGP_BVC_CT bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2507 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2508 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2509
2510 SGSN_MGMT.clear;
2511 PCU_MGMT.clear;
2512
2513 /* block the PTP BVC from the PCU side */
2514 PCU_MGMT.send(BssgpUnblockRequest:{}) to bvc_ct;
2515 /* expect state on both PCU and SGSN side to change */
2516 interleave {
2517 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_UNBLOCKED)) from bvc_ct;
Harald Welte572b0172021-03-30 13:19:56 +02002518 [] SGSN_MGMT.receive(tr_BssgpStsInd(mp_nsconfig_sgsn[0].nsei, bvc_cfg.bvci, BVC_S_UNBLOCKED));
2519 [] SGSN_MGMT.receive(tr_BssgpStsInd(mp_nsconfig_sgsn[1].nsei, bvc_cfg.bvci, BVC_S_UNBLOCKED));
2520 /* Doesn't auto-scale with NUM_SGSN */
Harald Welte239aa502020-11-24 23:14:20 +01002521 }
2522 setverdict(pass);
2523}
2524testcase TC_bvc_unblock_ptp() runs on test_CT
2525{
2526 f_init();
2527 f_sleep(1.0);
2528 f_block_ptp_bvc_from_pcu(0, 0);
2529 f_sleep(1.0);
2530 f_unblock_ptp_bvc_from_pcu(0, 0);
2531 f_cleanup();
2532}
2533
Harald Welte4f91c3b2020-12-09 12:25:51 +01002534/***********************************************************************
2535 * BVC-RESET procedure
2536 ***********************************************************************/
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002537private altstep as_count_bvc_reset(integer sgsn_idx, BssgpBvci bvci, inout roro_integer roroi)
2538runs on test_CT {
2539 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(sgsn_idx, bvci);
2540 [] SGSN_MGMT.receive(BssgpResetIndication:{bvci}) from sgsn_bvc_ct {
2541 roroi[sgsn_idx] := roroi[sgsn_idx] & { bvci };
2542 repeat;
2543 }
2544}
Harald Welte60a8ec72020-11-25 17:12:53 +01002545private altstep as_ignore_status(BSSGP_BVC_MGMT_PT pt) {
2546[] pt.receive(BssgpStatusIndication:?) { repeat; }
2547}
2548private function f_get_sgsn_bvc_ct(integer sgsn_idx, BssgpBvci bvci) runs on test_CT return BSSGP_BVC_CT {
2549 for (var integer i := 0; i < lengthof(g_sgsn[sgsn_idx].cfg.bvc); i := i+1) {
2550 if (g_sgsn[sgsn_idx].cfg.bvc[i].bvci == bvci) {
2551 return g_sgsn[sgsn_idx].vc_BSSGP_BVC[i];
2552 }
2553 }
2554 return null;
2555}
2556private function f_reset_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2557{
2558 var BSSGP_BVC_CT pcu_bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2559 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2560 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002561 var ro_default defaults;
2562 var integer i;
Harald Welte60a8ec72020-11-25 17:12:53 +01002563
2564 SGSN_MGMT.clear;
2565 PCU_MGMT.clear;
2566
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002567 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
2568 g_roroi[i] := {};
2569 }
2570
Harald Welte60a8ec72020-11-25 17:12:53 +01002571 /* block the PTP BVC from the PCU side */
2572 PCU_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to pcu_bvc_ct;
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002573
Harald Welte60a8ec72020-11-25 17:12:53 +01002574 /* expect state on both PCU and SGSN side to change */
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002575 defaults := { activate(as_ignore_status(SGSN_MGMT)) };
2576
2577 /* Activate altsteps: One for each SGSN */
2578 for (i := 0; i < lengthof(g_sgsn); i := i+1) {
2579 var default d := activate(as_count_bvc_reset(i, bvc_cfg.bvci, g_roroi));
2580 defaults := defaults & { d };
Harald Welte60a8ec72020-11-25 17:12:53 +01002581 }
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002582
2583 timer T := 3.0;
2584 T.start;
2585 alt {
2586 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_BLOCKED)) from pcu_bvc_ct {
2587 g_roi := g_roi & { bvc_cfg.bvci };
2588 repeat;
2589 }
2590 [] T.timeout;
2591 }
2592
2593 for (i := 0; i < lengthof(defaults); i := i+1) {
2594 deactivate(defaults[i]);
2595 }
2596
2597 /* Check if BVC-RESET was received at all SGSNs */
2598 for (i := 0; i < lengthof(g_sgsn); i := i+1) {
2599 if (not ro_integer_contains(g_roroi[i], bvc_cfg.bvci)) {
2600 setverdict(fail, "Missing SGSN[", i, "] BVC-BLOCK of BVCI=", bvc_cfg.bvci);
2601 }
2602 }
2603
Harald Welte60a8ec72020-11-25 17:12:53 +01002604 setverdict(pass);
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002605 f_cleanup();
Harald Welte60a8ec72020-11-25 17:12:53 +01002606}
2607/* Send a BVC-RESET for a PTP BVC from the BSS side: expect it to propagate */
2608testcase TC_bvc_reset_ptp_from_bss() runs on test_CT
2609{
2610 f_init();
2611 f_sleep(3.0);
2612 f_reset_ptp_bvc_from_pcu(0, 0);
2613 f_cleanup();
2614}
2615
Harald Welteb1cc0b22021-03-30 12:16:36 +02002616private altstep as_count_bvc_sts(integer sgsn_idx, BssgpBvci bvci,
2617 template (present) BvcState exp_bvc_state, inout roro_integer roroi)
Harald Welte16786e92020-11-27 19:11:56 +01002618runs on test_CT {
2619 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(sgsn_idx, bvci);
Harald Welteb1cc0b22021-03-30 12:16:36 +02002620 [] SGSN_MGMT.receive(tr_BssgpStsInd(?, bvci, exp_bvc_state)) from sgsn_bvc_ct {
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002621 roroi[sgsn_idx] := roroi[sgsn_idx] & { bvci };
Harald Welteb2647f72020-12-07 14:36:35 +01002622 repeat;
Harald Welte16786e92020-11-27 19:11:56 +01002623 }
2624}
Harald Welteb1cc0b22021-03-30 12:16:36 +02002625
2626private altstep as_count_bvc_block(integer sgsn_idx, BssgpBvci bvci, inout roro_integer roroi)
2627runs on test_CT {
2628 [] as_count_bvc_sts(sgsn_idx, bvci, BVC_S_BLOCKED, roroi);
2629}
2630
2631private altstep as_count_bvc_unblock(integer sgsn_idx, BssgpBvci bvci, inout roro_integer roroi)
2632runs on test_CT {
2633 [] as_count_bvc_sts(sgsn_idx, bvci, BVC_S_UNBLOCKED, roroi);
2634}
2635
Harald Welte16786e92020-11-27 19:11:56 +01002636/* reset the signaling BVC from one BSS; expect no signaling BVC reset on SGSN; but BVC-BLOCK for PTP */
2637testcase TC_bvc_reset_sig_from_bss() runs on test_CT {
2638
2639 f_init();
2640 f_sleep(3.0);
2641
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002642 for (var integer i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
2643 g_roroi[i] := {};
2644 }
2645
Harald Welte16786e92020-11-27 19:11:56 +01002646 /* Start BVC-RESET procedure for BVCI=0 */
2647 PCU_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to g_pcu[0].vc_BSSGP;
2648
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002649 /* Activate altsteps: One for each PTP BVC and SGSN within that PCUs NSE */
Harald Welte16786e92020-11-27 19:11:56 +01002650 var ro_default defaults := {};
2651 for (var integer i := 0; i < lengthof(g_pcu[0].cfg.bvc); i := i+1) {
2652 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[i];
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002653 for (var integer j := 0; j < lengthof(g_sgsn); j := j+1) {
2654 var default d := activate(as_count_bvc_block(j, bvcc.bvci, g_roroi));
2655 defaults := defaults & { d };
2656 }
Harald Welte16786e92020-11-27 19:11:56 +01002657 }
2658
2659 timer T := 3.0;
2660 T.start;
2661 alt {
2662 [] SGSN_MGMT.receive(BssgpResetIndication:{0}) {
2663 setverdict(fail, "BSS-side Reset of BVCI=0 should not propagate");
2664 }
2665 [] T.timeout;
2666 }
2667
2668 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2669 deactivate(defaults[i]);
2670 }
2671
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002672 /* check if BVC-block was received on all expected BVC/SGSN */
Harald Welte16786e92020-11-27 19:11:56 +01002673 for (var integer i := 0; i < lengthof(g_pcu[0].cfg.bvc); i := i+1) {
2674 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[i];
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002675 for (var integer j := 0; j < lengthof(g_sgsn); j := j+1) {
2676 if (not ro_integer_contains(g_roroi[j], bvcc.bvci)) {
2677 setverdict(fail, "Missing SGSN[", j, "] BVC-BLOCK of BVCI=", bvcc.bvci);
2678 }
Harald Welte16786e92020-11-27 19:11:56 +01002679 }
2680 }
2681
2682 /* check if BVC-block was not received on any unexpected BVC is not required as
2683 * such a message would basically run into 'no matching clause' */
Daniel Willmannf2590212020-12-04 14:20:50 +01002684 setverdict(pass);
Harald Welte16786e92020-11-27 19:11:56 +01002685 f_cleanup();
2686}
2687
Harald Welte60a8ec72020-11-25 17:12:53 +01002688private function f_reset_ptp_bvc_from_sgsn(integer pcu_idx, integer bvc_idx) runs on test_CT
2689{
2690 var BSSGP_BVC_CT pcu_bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2691 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2692 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2693 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(0, bvc_cfg.bvci);
2694 var default d;
2695
2696 SGSN_MGMT.clear;
2697 PCU_MGMT.clear;
2698
2699 /* block the PTP BVC from the PCU side */
2700 SGSN_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to sgsn_bvc_ct;
2701 /* expect state on both PCU and SGSN side to change */
2702 d := activate(as_ignore_status(PCU_MGMT));
2703 interleave {
2704 [] SGSN_MGMT.receive(tr_BssgpStsInd(?, bvc_cfg.bvci, BVC_S_BLOCKED)) from sgsn_bvc_ct;
2705 [] PCU_MGMT.receive(BssgpResetIndication:{bvc_cfg.bvci}) from pcu_bvc_ct;
2706 }
2707 deactivate(d);
2708 setverdict(pass);
2709}
2710/* Send a BVC-RESET for a PTP BVC from the SGSN side: expect it to propagate */
2711testcase TC_bvc_reset_ptp_from_sgsn() runs on test_CT
2712{
2713 f_init();
2714 f_sleep(3.0);
2715 f_reset_ptp_bvc_from_sgsn(0, 0);
2716 f_cleanup();
2717}
2718
Daniel Willmannef7015f2021-01-08 00:43:56 +01002719private altstep as_ignore_mgmt(BSSGP_BVC_MGMT_PT pt) {
2720 [] pt.receive {repeat; }
2721}
2722
Harald Welte16786e92020-11-27 19:11:56 +01002723private altstep as_count_bvc0_block(integer pcu_idx, Nsei nsei, inout ro_integer roi)
2724runs on test_CT {
2725 var BSSGP_CT pcu_ct := g_pcu[pcu_idx].vc_BSSGP;
2726 [] PCU_MGMT.receive(BssgpResetIndication:{0}) from pcu_ct {
2727 roi := roi & { nsei };
Daniel Willmannef7015f2021-01-08 00:43:56 +01002728 repeat;
Harald Welte16786e92020-11-27 19:11:56 +01002729 }
2730}
Daniel Willmannef7015f2021-01-08 00:43:56 +01002731
Harald Welte16786e92020-11-27 19:11:56 +01002732/* reset the signaling BVC from the SGSN; expect all signaling BVC on all BSS to be reset */
2733testcase TC_bvc_reset_sig_from_sgsn() runs on test_CT {
2734
2735 f_init();
2736 f_sleep(3.0);
2737
Daniel Willmannef7015f2021-01-08 00:43:56 +01002738 SGSN_MGMT.clear;
2739 PCU_MGMT.clear;
2740
Harald Welte16786e92020-11-27 19:11:56 +01002741 /* Start BVC-RESET procedure for BVCI=0 */
2742 SGSN_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to g_sgsn[0].vc_BSSGP;
2743
Daniel Willmannef7015f2021-01-08 00:43:56 +01002744 /* Defaults match in reverse activation order, this one is a catch-all for Status indications
2745 * and reset indications sent from other components (like the ptp_bvcs). If we don't drain
2746 * the port and a different message sits at the front we wait forever and fail the test.
2747 */
2748 var ro_default defaults := { activate(as_ignore_mgmt(PCU_MGMT)) };
2749
Harald Welte16786e92020-11-27 19:11:56 +01002750 /* Activate altsteps: One for each PCU NSE */
Harald Welte16786e92020-11-27 19:11:56 +01002751 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2752 var NSConfiguration nscfg := mp_nsconfig_pcu[i];
2753 var default d := activate(as_count_bvc0_block(i, nscfg.nsei, g_roi));
2754 defaults := defaults & { d };
2755 }
2756
2757 f_sleep(3.0);
2758
2759 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2760 deactivate(defaults[i]);
2761 }
2762
2763 /* check if BVC-block was received on all expected BVC */
2764 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2765 var NSConfiguration nscfg := mp_nsconfig_pcu[i];
2766 if (not ro_integer_contains(g_roi, nscfg.nsei)) {
2767 setverdict(fail, "Missing PCU-side BVC-RESET of BVCI=0 on PCU index ", i);
2768 }
2769 }
2770
2771 /* check if BVC-block was not received on any unexpected BVC is not required as
2772 * such a message would basically run into 'no matching clause' */
2773
2774 f_cleanup();
2775}
2776
Harald Welte299aa482020-12-09 15:10:55 +01002777/***********************************************************************
2778 * FLOW-CONTROL-BVC procedure
2779 ***********************************************************************/
2780
2781private altstep as_g_count_sgsn(integer sgsn_idx, inout ro_integer roi,
2782 template PDU_BSSGP exp_rx, template (omit) PDU_BSSGP tx_reply)
2783runs on GlobalTest_CT {
2784 [] G_SGSN[sgsn_idx].receive(exp_rx) {
2785 roi := roi & { sgsn_idx };
2786 if (ispresent(tx_reply)) {
2787 G_SGSN[sgsn_idx].send(tx_reply);
2788 }
Harald Welte5fb01742021-01-15 21:07:52 +01002789 repeat;
Harald Welte299aa482020-12-09 15:10:55 +01002790 }
2791}
2792/* Send FC-BVC from simulated PCU; expect each SGSN to receive it; expect PCU to receive ACK */
2793testcase TC_fc_bvc() runs on GlobalTest_CT
2794{
2795 f_init();
2796 f_global_init_ptp();
2797
Pau Espin Pedrol6ee01262021-02-05 13:05:06 +01002798 var template (value) PDU_BSSGP pdu_tx := ts_BVC_FC_BVC(10240, 2000, 1024, 1000, '01'O);
Harald Welte299aa482020-12-09 15:10:55 +01002799 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2800 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 +01002801 var template (value) PDU_BSSGP ack_tx :=
2802 ts_BVC_FC_BVC_ACK(pdu_tx.pDU_BSSGP_FLOW_CONTROL_BVC.tag.unstructured_Value);
Harald Welte299aa482020-12-09 15:10:55 +01002803
2804 /* Send a FC-BVC from BSS to gbproxy, expect an ACK in response */
2805 G_PCU[0].send(pdu_tx);
2806
2807 /* Activate altsteps: One for each SGSN-side PTP BVC port */
2808 var ro_default defaults := {};
2809 for (var integer i := 0; i < lengthof(g_sgsn); i := i+1) {
2810 var default d := activate(as_g_count_sgsn(i, g_roi, pdu_rx, ack_tx));
2811 defaults := defaults & { d };
2812 }
2813
2814 f_sleep(3.0);
2815
2816 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2817 deactivate(defaults[i]);
2818 }
2819
2820 /* check if BVC-block was received on all expected BVC */
2821 for (var integer i := 0; i < lengthof(g_sgsn); i := i+1) {
2822 if (not ro_integer_contains(g_roi, i)) {
2823 setverdict(fail, "Missing BVC-FLOW-CONTROL on SGSN index ", i);
2824 }
2825 }
2826
2827 /* Expect ACK on PCU side */
2828 G_PCU[0].receive(ack_tx);
2829
2830 setverdict(pass);
2831
2832 f_cleanup();
2833}
2834
Harald Weltecc3894b2020-12-09 16:50:12 +01002835/***********************************************************************
2836 * FLOW-CONTROL-MS procedure
2837 ***********************************************************************/
2838
2839private function f_TC_fc_ms(charstring id) runs on BSSGP_ConnHdlr {
2840 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
2841
2842 var template (value) PDU_BSSGP fc_tx := ts_BVC_FC_MS(g_pars.tlli, 100, 200, '12'O);
2843 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2844 var template (present) PDU_BSSGP fc_rx := tr_BVC_FC_MS(g_pars.tlli, 100, 200, '12'O);
2845 var template (value) PDU_BSSGP ack_tx := ts_BVC_FC_MS_ACK(g_pars.tlli, '12'O);
2846
2847 f_pcu2sgsn(fc_tx, fc_rx, use_sig := false);
2848 f_sgsn2pcu(ack_tx, ack_tx, use_sig := false);
2849
2850 setverdict(pass);
2851}
2852/* Send a FLOW-CONTROL-MS from BSS side and expect it to show up on SGSN (PTP BVC) */
2853testcase TC_fc_ms() runs on test_CT
2854{
Harald Weltecc3894b2020-12-09 16:50:12 +01002855 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002856 f_start_handlers(refers(f_TC_fc_ms), testcasename(), 21);
Harald Weltecc3894b2020-12-09 16:50:12 +01002857 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Weltecc3894b2020-12-09 16:50:12 +01002858 f_cleanup();
2859}
2860
Harald Welted6f89812021-01-16 18:57:49 +01002861/***********************************************************************
2862 * MS-REGISTRATION ENQUIRY procedure
2863 ***********************************************************************/
Harald Weltecc3894b2020-12-09 16:50:12 +01002864
Harald Welted6f89812021-01-16 18:57:49 +01002865private function f_TC_ms_reg_enq(charstring id) runs on BSSGP_ConnHdlr
2866{
Daniel Willmann04918c02021-07-06 13:59:04 +02002867 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 +01002868 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);
2869}
2870testcase TC_ms_reg_enq() runs on test_CT
2871{
2872 f_init();
2873 f_start_handlers(refers(f_TC_ms_reg_enq), testcasename(), 22);
2874 f_cleanup();
2875}
Harald Welte299aa482020-12-09 15:10:55 +01002876
Harald Weltef86f1852021-01-16 21:56:17 +01002877/***********************************************************************
2878 * RIM (RAN Information Management)
2879 ***********************************************************************/
2880
2881/* Our tests here are rather synthetic, as they don't reflect normal message flows
2882 as they would be observed in a live network. However, for testing gbproxy, this shouldn't
2883 matter as gbproxy is not concerned with anything but the source / destination routing
2884 information */
2885
2886/* gbproxy must route all unknown RIM Routing Info (Cell Id) to the SGSN. We just define
2887 one here of which we know it is not used among the [simulated] PCUs */
2888const BssgpCellId cell_id_sgsn := {
2889 ra_id := {
2890 lai := {
2891 mcc_mnc := c_mcc_mnc,
2892 lac := 65534
2893 },
2894 rac := 0
2895 },
2896 cell_id := 65533
2897};
2898
2899/* Send 'tx' on PTP-BVCI from PCU; expect 'rx' on any of our SGSN (RIM can be routed anywhere) */
2900friend function f_rim_pcu2sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
2901 integer pcu_idx := 0) runs on GlobalTest_CT {
2902 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +01002903 timer T := 2.0;
Harald Weltef86f1852021-01-16 21:56:17 +01002904
2905 RIM_PCU[pcu_idx].send(tx);
2906 T.start;
2907 alt {
2908 [] any from RIM_SGSN.receive(exp_rx) {
2909 setverdict(pass);
2910 }
2911 [] any from RIM_SGSN.receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +01002912 f_shutdown(__FILE__, __LINE__, fail, log2str("Unexpected BSSGP on SGSN side: ", rx));
Harald Weltef86f1852021-01-16 21:56:17 +01002913 }
2914 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +01002915 f_shutdown(__FILE__, __LINE__, fail,
2916 log2str("Timeout waiting for BSSGP on SGSN side: ", exp_rx));
Harald Weltef86f1852021-01-16 21:56:17 +01002917 }
2918 }
2919}
2920
2921/* Send 'tx' on PTP-BVCI from SGSN; expect 'rx' on PCU */
2922friend function f_rim_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
2923 integer sgsn_idx := 0, integer pcu_idx := 0) runs on GlobalTest_CT {
2924 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +01002925 timer T := 2.0;
Harald Weltef86f1852021-01-16 21:56:17 +01002926
2927 RIM_SGSN[sgsn_idx].send(tx);
2928 T.start;
2929 alt {
2930 [] RIM_PCU[pcu_idx].receive(exp_rx) {
2931 setverdict(pass);
2932 }
2933 [] RIM_PCU[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +01002934 f_shutdown(__FILE__, __LINE__, fail, log2str("Unexpected BSSGP on PCU side: ", rx));
Harald Weltef86f1852021-01-16 21:56:17 +01002935 }
2936 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +01002937 f_shutdown(__FILE__, __LINE__, fail,
2938 log2str("Timeout waiting for BSSGP on PCU side: ", exp_rx));
Harald Weltef86f1852021-01-16 21:56:17 +01002939 }
2940 }
2941}
2942
2943/* Send 'tx' on PTP-BVCI from SRC-PCU; expect 'rx' on DST-PCU */
2944friend function f_rim_pcu2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
2945 integer src_pcu_idx, integer dst_pcu_idx) runs on GlobalTest_CT {
2946 var integer rx_idx;
2947 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +01002948 timer T := 2.0;
Harald Weltef86f1852021-01-16 21:56:17 +01002949
2950 RIM_PCU[src_pcu_idx].send(tx);
2951 T.start;
2952 alt {
2953 [] RIM_PCU[dst_pcu_idx].receive(exp_rx) -> value rx{
2954 setverdict(pass);
2955 }
2956 [] any from RIM_PCU.receive(exp_rx) -> @index value rx_idx {
2957 setverdict(fail, "Received RIM on wrong PCU[", rx_idx ,"], expected on PCU[", dst_pcu_idx, "]");
2958 }
2959 [] any from RIM_SGSN.receive(exp_rx) {
2960 setverdict(fail, "Received RIM on SGSN but expected it on other PCU");
2961 }
2962 [] any from RIM_SGSN.receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +01002963 f_shutdown(__FILE__, __LINE__, fail, log2str("Unexpected BSSGP on SGSN side: ", rx));
Harald Weltef86f1852021-01-16 21:56:17 +01002964 }
2965 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +01002966 f_shutdown(__FILE__, __LINE__, fail,
2967 log2str("Timeout waiting for BSSGP on SGSN side: ", exp_rx));
Harald Weltef86f1852021-01-16 21:56:17 +01002968 }
2969 }
2970}
2971
2972
2973type function rim_fn(integer sgsn_idx, integer pcu_idx, integer bvc_idx) runs on GlobalTest_CT;
2974
2975/* helper function for the RIM test cases: Execute 'fn' for each BVC on each PCU for
2976 each SGSN */
2977private function f_rim_iterator(rim_fn fn) runs on GlobalTest_CT
2978{
2979 var integer sgsn_idx, pcu_idx, bvc_idx;
2980 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx+1) {
2981 for (pcu_idx := 0; pcu_idx < lengthof(g_pcu); pcu_idx := pcu_idx+1) {
2982 for (bvc_idx := 0; bvc_idx < lengthof(g_pcu[pcu_idx].cfg.bvc); bvc_idx := bvc_idx+1) {
2983 log("Testing RIM SGSN[", sgsn_idx, "] <-> PCU[", pcu_idx, "][", bvc_idx, "]");
2984 fn.apply(sgsn_idx, pcu_idx, bvc_idx);
2985 }
2986 }
2987 }
2988}
2989
2990/* RAN-INFORMATION-REQUEST */
2991private function f_TC_rim_info_req(integer sgsn_idx, integer pcu_idx, integer bvc_idx := 0)
2992runs on GlobalTest_CT
2993{
2994 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
Philipp Maier14d3a8e2021-01-28 21:43:16 +01002995 var template (value) RAN_Information_Request_RIM_Container cont_tx;
2996 var template RAN_Information_Request_RIM_Container cont_rx;
2997 var template RIM_Routing_Address ra_pcu;
2998 var template RIM_Routing_Address ra_sgsn;
Harald Weltef86f1852021-01-16 21:56:17 +01002999
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003000 ra_pcu := t_RIM_Routing_Address_cid(cell_id);
3001 ra_sgsn := t_RIM_Routing_Address_cid(cell_id_sgsn);
3002
3003 cont_tx := ts_RAN_Information_Request_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3004 ts_RIM_Sequence_Number(0),
3005 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
3006 cont_rx := tr_RAN_Information_Request_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
3007 tr_RIM_Sequence_Number(0),
3008 tr_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
3009
3010 f_rim_pcu2sgsn(ts_RAN_INFORMATION_REQUEST(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3011 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3012 cont := cont_tx),
3013 tr_RAN_INFORMATION_REQUEST(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3014 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3015 cont := cont_rx),
3016 pcu_idx);
3017
3018 f_rim_sgsn2pcu(ts_RAN_INFORMATION_REQUEST(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3019 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3020 cont := cont_tx),
3021 tr_RAN_INFORMATION_REQUEST(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3022 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3023 cont := cont_rx),
Harald Weltef86f1852021-01-16 21:56:17 +01003024 sgsn_idx, pcu_idx);
3025}
3026testcase TC_rim_info_req() runs on GlobalTest_CT
3027{
3028 f_init();
3029 f_global_init();
3030 f_rim_iterator(refers(f_TC_rim_info_req));
3031 f_cleanup();
3032}
3033
3034/* RAN-INFORMATION */
3035private function f_TC_rim_info(integer sgsn_idx, integer pcu_idx, integer bvc_idx := 0)
3036runs on GlobalTest_CT
3037{
3038 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003039 var template (value) RAN_Information_RIM_Container cont_tx;
3040 var template RAN_Information_RIM_Container cont_rx;
3041 var template RIM_Routing_Address ra_pcu;
3042 var template RIM_Routing_Address ra_sgsn;
Harald Weltef86f1852021-01-16 21:56:17 +01003043
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003044 ra_pcu := t_RIM_Routing_Address_cid(cell_id);
3045 ra_sgsn := t_RIM_Routing_Address_cid(cell_id_sgsn);
3046
3047 cont_tx := ts_RAN_Information_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3048 ts_RIM_Sequence_Number(0),
3049 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
3050
3051 cont_rx := tr_RAN_Information_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
3052 tr_RIM_Sequence_Number(0),
3053 tr_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
3054
3055 f_rim_pcu2sgsn(ts_PDU_BSSGP_RAN_INFORMATION(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3056 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3057 cont := cont_tx),
3058 tr_PDU_BSSGP_RAN_INFORMATION(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3059 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3060 cont := cont_rx),
3061 pcu_idx);
3062
3063 f_rim_sgsn2pcu(ts_PDU_BSSGP_RAN_INFORMATION(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3064 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3065 cont := cont_tx),
3066 tr_PDU_BSSGP_RAN_INFORMATION(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3067 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3068 cont := cont_rx),
Harald Weltef86f1852021-01-16 21:56:17 +01003069 sgsn_idx, pcu_idx);
3070}
3071testcase TC_rim_info() runs on GlobalTest_CT
3072{
3073 f_init();
3074 f_global_init();
3075 f_rim_iterator(refers(f_TC_rim_info));
3076 f_cleanup();
3077}
3078
3079/* RAN-INFORMATION-ACK */
3080private function f_TC_rim_info_ack(integer sgsn_idx, integer pcu_idx, integer bvc_idx := 0)
3081runs on GlobalTest_CT
3082{
3083 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003084 var template (value) RAN_Information_Ack_RIM_Container cont_tx;
3085 var template RAN_Information_Ack_RIM_Container cont_rx;
3086 var template RIM_Routing_Address ra_pcu;
3087 var template RIM_Routing_Address ra_sgsn;
Harald Weltef86f1852021-01-16 21:56:17 +01003088
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003089 ra_pcu := t_RIM_Routing_Address_cid(cell_id);
3090 ra_sgsn := t_RIM_Routing_Address_cid(cell_id_sgsn);
3091
3092 cont_tx := ts_RAN_Information_Ack_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3093 ts_RIM_Sequence_Number(0));
3094
3095 cont_rx := tr_RAN_Information_Ack_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
3096 tr_RIM_Sequence_Number(0));
3097
3098 f_rim_pcu2sgsn(ts_PDU_BSSGP_RAN_INFORMATION_ACK(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3099 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3100 cont := cont_tx),
3101 tr_PDU_BSSGP_RAN_INFORMATION_ACK(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3102 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3103 cont := cont_rx),
3104 pcu_idx);
3105
3106 f_rim_sgsn2pcu(ts_PDU_BSSGP_RAN_INFORMATION_ACK(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3107 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3108 cont := cont_tx),
3109 tr_PDU_BSSGP_RAN_INFORMATION_ACK(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3110 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3111 cont := cont_rx),
Harald Weltef86f1852021-01-16 21:56:17 +01003112 sgsn_idx, pcu_idx);
3113}
3114testcase TC_rim_info_ack() runs on GlobalTest_CT
3115{
3116 f_init();
3117 f_global_init();
3118 f_rim_iterator(refers(f_TC_rim_info_ack));
3119 f_cleanup();
3120}
3121
3122/* RAN-INFORMATION-ERROR */
3123private function f_TC_rim_info_error(integer sgsn_idx, integer pcu_idx, integer bvc_idx := 0)
3124runs on GlobalTest_CT
3125{
3126 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003127 var template (value) RAN_Information_Error_RIM_Container cont_tx;
3128 var template RAN_Information_Error_RIM_Container cont_rx;
3129 var template RIM_Routing_Address ra_pcu;
3130 var template RIM_Routing_Address ra_sgsn;
Harald Weltef86f1852021-01-16 21:56:17 +01003131
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003132 ra_pcu := t_RIM_Routing_Address_cid(cell_id);
3133 ra_sgsn := t_RIM_Routing_Address_cid(cell_id_sgsn);
3134
3135 cont_tx := ts_RAN_Information_Error_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3136 ts_BSSGP_CAUSE(BSSGP_CAUSE_EQUIMENT_FAILURE),
Pau Espin Pedrol6ee01262021-02-05 13:05:06 +01003137 omit, valueof(ts_BVC_UNBLOCK(23)));
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003138
3139 cont_rx := tr_RAN_Information_Error_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
Pau Espin Pedrol6ee01262021-02-05 13:05:06 +01003140 ts_BSSGP_CAUSE(BSSGP_CAUSE_EQUIMENT_FAILURE),
3141 omit, enc_PDU_BSSGP(valueof(tr_BVC_UNBLOCK(23))));
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003142
3143 f_rim_pcu2sgsn(ts_PDU_BSSGP_RAN_INFORMATION_ERROR(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3144 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3145 cont := cont_tx),
3146 tr_PDU_BSSGP_RAN_INFORMATION_ERROR(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3147 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3148 cont := cont_rx),
3149 pcu_idx);
3150
3151 f_rim_sgsn2pcu(ts_PDU_BSSGP_RAN_INFORMATION_ERROR(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3152 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3153 cont := cont_tx),
3154 tr_PDU_BSSGP_RAN_INFORMATION_ERROR(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3155 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3156 cont := cont_rx),
Harald Weltef86f1852021-01-16 21:56:17 +01003157 sgsn_idx, pcu_idx);
3158}
3159testcase TC_rim_info_error() runs on GlobalTest_CT
3160{
3161 f_init();
3162 f_global_init();
3163 f_rim_iterator(refers(f_TC_rim_info_error));
3164 f_cleanup();
3165}
3166
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003167//////////////////
Harald Weltef86f1852021-01-16 21:56:17 +01003168/* RAN-INFORMATION-APPLICATION-ERROR */
3169private function f_TC_rim_info_app_error(integer sgsn_idx, integer pcu_idx, integer bvc_idx := 0)
3170runs on GlobalTest_CT
3171{
3172 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003173 var template (value) Application_Error_Container app_cont_tx;
3174 var template Application_Error_Container app_cont_rx;
3175 var template (value) RAN_Information_Application_Error_RIM_Container cont_tx;
3176 var template RAN_Information_Application_Error_RIM_Container cont_rx;
3177 var template RIM_Routing_Address ra_pcu;
3178 var template RIM_Routing_Address ra_sgsn;
Harald Weltef86f1852021-01-16 21:56:17 +01003179
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003180 ra_pcu := t_RIM_Routing_Address_cid(cell_id);
3181 ra_sgsn := t_RIM_Routing_Address_cid(cell_id_sgsn);
3182
3183 app_cont_tx := tsu_Application_Error_Container_NACC(cell_id, 23,
3184 tsu_Application_Container_IE_NACC_req(cell_id));
3185
3186 app_cont_rx := rsu_Application_Error_Container_NACC(cell_id, 23,
3187 rsu_Application_Container_IE_NACC_req(cell_id));
3188
3189 cont_tx := ts_RAN_Information_Application_Error_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3190 ts_RIM_Sequence_Number(0),
3191 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP),
3192 omit, app_cont_tx);
3193 cont_rx := tr_RAN_Information_Application_Error_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
3194 tr_RIM_Sequence_Number(0),
3195 tr_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP),
3196 omit, app_cont_rx);
3197
3198 f_rim_pcu2sgsn(ts_PDU_BSSGP_RAN_INFORMATION_APPLICATION_ERROR(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3199 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3200 cont := cont_tx),
3201 tr_PDU_BSSGP_RAN_INFORMATION_APPLICATION_ERROR(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3202 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3203 cont := cont_rx),
3204 pcu_idx);
3205
3206 f_rim_sgsn2pcu(ts_PDU_BSSGP_RAN_INFORMATION_APPLICATION_ERROR(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3207 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3208 cont := cont_tx),
3209 tr_PDU_BSSGP_RAN_INFORMATION_APPLICATION_ERROR(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3210 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3211 cont := cont_rx),
Harald Weltef86f1852021-01-16 21:56:17 +01003212 sgsn_idx, pcu_idx);
3213}
3214testcase TC_rim_info_app_error() runs on GlobalTest_CT
3215{
3216 f_init();
3217 f_global_init();
3218 f_rim_iterator(refers(f_TC_rim_info_app_error));
3219 f_cleanup();
3220}
3221
3222/* RAN-INFORMATION routing directly between PCUs, without SGSN involvement */
3223private function f_TC_rim_info_pcu2pcu(integer src_pcu_idx, integer src_bvc_idx,
3224 integer dst_pcu_idx, integer dst_bvc_idx)
3225runs on GlobalTest_CT
3226{
3227 var BssgpCellId cell_id_src := g_pcu[src_pcu_idx].cfg.bvc[src_bvc_idx].cell_id;
3228 var BssgpCellId cell_id_dst := g_pcu[dst_pcu_idx].cfg.bvc[dst_bvc_idx].cell_id;
Philipp Maier1bd60ce2021-02-10 18:25:50 +01003229 var template (value) RIM_Routing_Information ri_pcu_src_tx;
3230 var template (value) RIM_Routing_Information ri_pcu_dst_tx;
3231 var template RIM_Routing_Information ri_pcu_src_rx;
3232 var template RIM_Routing_Information ri_pcu_dst_rx;
3233 var template (value) RAN_Information_RIM_Container cont_tx;
3234 var template RAN_Information_RIM_Container cont_rx;
Harald Weltef86f1852021-01-16 21:56:17 +01003235
3236 log("Testing RIM PCU2PCU from PCU[", src_pcu_idx, "][", src_bvc_idx, "] to PCU[",
3237 dst_pcu_idx, "][", dst_bvc_idx, "]");
3238
Philipp Maier1bd60ce2021-02-10 18:25:50 +01003239 ri_pcu_src_tx := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID,
Harald Weltef86f1852021-01-16 21:56:17 +01003240 t_RIM_Routing_Address_cid(cell_id_src));
Philipp Maier1bd60ce2021-02-10 18:25:50 +01003241 ri_pcu_dst_tx := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID,
Harald Weltef86f1852021-01-16 21:56:17 +01003242 t_RIM_Routing_Address_cid(cell_id_dst));
Philipp Maier1bd60ce2021-02-10 18:25:50 +01003243 ri_pcu_src_rx := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID,
3244 t_RIM_Routing_Address_cid(cell_id_src));
3245 ri_pcu_dst_rx := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID,
3246 t_RIM_Routing_Address_cid(cell_id_dst));
3247
3248 cont_tx := ts_RAN_Information_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3249 ts_RIM_Sequence_Number(0),
3250 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
3251 cont_rx := tr_RAN_Information_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
3252 tr_RIM_Sequence_Number(0),
3253 tr_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
3254
3255 f_rim_pcu2pcu(ts_PDU_BSSGP_RAN_INFORMATION(dst := ri_pcu_dst_tx, src := ri_pcu_src_tx, cont := cont_tx),
3256 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 +01003257 src_pcu_idx, dst_pcu_idx);
3258}
3259testcase TC_rim_info_pcu2pcu() runs on GlobalTest_CT
3260{
3261 var integer src_pcu_idx, dst_pcu_idx;
3262 var integer src_bvc_idx, dst_bvc_idx;
3263 f_init();
3264 f_global_init();
3265
3266 for (src_pcu_idx := 0; src_pcu_idx < lengthof(g_pcu); src_pcu_idx := src_pcu_idx + 1) {
3267 for (src_bvc_idx := 0; src_bvc_idx < lengthof(g_pcu[src_pcu_idx].cfg.bvc); src_bvc_idx := src_bvc_idx + 1) {
3268 for (dst_pcu_idx := 0; dst_pcu_idx < lengthof(g_pcu); dst_pcu_idx := dst_pcu_idx + 1) {
3269 if (dst_pcu_idx == src_pcu_idx) {
3270 continue;
3271 }
3272
3273 for (dst_bvc_idx := 0; dst_bvc_idx < lengthof(g_pcu[dst_pcu_idx].cfg.bvc);
3274dst_bvc_idx := dst_bvc_idx + 1) {
3275 f_TC_rim_info_pcu2pcu(src_pcu_idx, src_bvc_idx, dst_pcu_idx, dst_bvc_idx);
3276 }
3277 }
3278 }
3279 }
3280
3281 f_cleanup();
3282}
3283
Pau Espin Pedrol40778e82021-05-07 13:20:58 +02003284
3285/* Test RIM REQ sent from an MME->SGSN->GBPROXY->PCU and back (eNACC) */
3286private function f_TC_rim_from_eutran(integer sgsn_idx, integer pcu_idx, integer bvc_idx := 0)
3287runs on GlobalTest_CT
3288{
3289 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
3290 var template (value) RAN_Information_Request_RIM_Container cont_tx;
3291 var template RAN_Information_Request_RIM_Container cont_rx;
3292 var template RIM_Routing_Address ra_pcu;
3293 var template RIM_Routing_Address ra_sgsn;
3294
3295 ra_pcu := t_RIM_Routing_Address_cid(cell_id);
3296 ra_sgsn := t_RIM_Routing_Address_enbid(cell_id_sgsn, tac := 3, gnbid := '12345678123456'O);
3297
3298 cont_tx := ts_RAN_Information_Request_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3299 ts_RIM_Sequence_Number(0),
3300 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
3301 cont_rx := tr_RAN_Information_Request_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
3302 tr_RIM_Sequence_Number(0),
3303 tr_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
3304
3305 f_rim_sgsn2pcu(ts_RAN_INFORMATION_REQUEST(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3306 src := ts_RIM_Routing_Information(RIM_ADDR_EUTRAN_NODEB_ID, ra_sgsn),
3307 cont := cont_tx),
3308 tr_RAN_INFORMATION_REQUEST(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3309 src := tr_RIM_Routing_Information(RIM_ADDR_EUTRAN_NODEB_ID, ra_sgsn),
3310 cont := cont_rx),
3311 sgsn_idx, pcu_idx);
3312
3313
3314 f_rim_pcu2sgsn(ts_RAN_INFORMATION_REQUEST(dst := ts_RIM_Routing_Information(RIM_ADDR_EUTRAN_NODEB_ID, ra_sgsn),
3315 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3316 cont := cont_tx),
3317 tr_RAN_INFORMATION_REQUEST(dst := tr_RIM_Routing_Information(RIM_ADDR_EUTRAN_NODEB_ID, ra_sgsn),
3318 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3319 cont := cont_rx),
3320 pcu_idx);
3321}
3322testcase TC_rim_from_eutran() runs on GlobalTest_CT
3323{
3324 f_init();
3325 f_global_init();
3326 f_rim_iterator(refers(f_TC_rim_from_eutran));
3327 f_cleanup();
3328}
3329
Harald Welte04358652021-01-17 13:48:13 +01003330/***********************************************************************
3331 * STATUS handling
3332 ***********************************************************************/
3333
3334/* BSSGP STATUS PDU must be routed based on inner "PDU In Error" message */
3335
3336/* generate a TMSI with NRI matching sgsn_idx + nri_idx */
3337private function f_gen_tmsi_for_sgsn_nri(integer sgsn_idx, integer nri_idx) runs on test_CT return OCT4
3338{
3339 var integer nri := mp_sgsn_nri[sgsn_idx][nri_idx];
3340 return f_gen_tmsi(0, nri_v := nri, nri_bitlen := mp_nri_bitlength);
3341}
3342
3343/* generate a TLLI with NRI matching sgsn_idx + nri_idx */
3344private function f_gen_tlli_for_sgsn_nri(integer sgsn_idx, integer nri_idx) runs on test_CT return OCT4
3345{
3346 var OCT4 p_tmsi := f_gen_tmsi_for_sgsn_nri(sgsn_idx, nri_idx);
3347 return f_gprs_tlli_from_tmsi(p_tmsi, TLLI_LOCAL);
3348}
3349
3350/* STATUS in uplink direction; expect routing by its NRI */
3351private function f_TC_status_ul(integer pcu_idx, integer sgsn_idx, PDU_BSSGP inner)
3352runs on GlobalTest_CT
3353{
3354 var template (value) PDU_BSSGP tx := ts_BSSGP_STATUS(omit, BSSGP_CAUSE_EQUIMENT_FAILURE, inner);
3355 var template (present) PDU_BSSGP exp_rx :=
3356 tr_BSSGP_STATUS(omit, BSSGP_CAUSE_EQUIMENT_FAILURE,
3357 tx.pDU_BSSGP_STATUS.pDU_in_Error.erroneous_BSSGP_PDU);
3358
3359 f_global_pcu2sgsn(tx, exp_rx, pcu_idx, sgsn_idx);
3360}
3361
3362/* STATUS in uplink direction; expect routing by its NRI */
3363private function f_TC_status_dl(integer sgsn_idx, integer pcu_idx, PDU_BSSGP inner)
3364runs on GlobalTest_CT
3365{
3366 var template (value) PDU_BSSGP tx := ts_BSSGP_STATUS(omit, BSSGP_CAUSE_EQUIMENT_FAILURE, inner);
3367 var template (present) PDU_BSSGP exp_rx :=
3368 tr_BSSGP_STATUS(omit, BSSGP_CAUSE_EQUIMENT_FAILURE,
3369 tx.pDU_BSSGP_STATUS.pDU_in_Error.erroneous_BSSGP_PDU);
3370
3371 f_global_sgsn2pcu(tx, exp_rx, sgsn_idx, pcu_idx);
3372}
3373
3374/* STATUS in uplink direction on SIG-BVC containing a TLLI; expect routing by its NRI */
3375testcase TC_status_sig_ul_tlli() runs on GlobalTest_CT
3376{
3377 var integer sgsn_idx, nri_idx;
3378
3379 f_init();
3380 f_global_init();
3381
3382 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3383 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx + 1) {
3384 /* some downlink PDU occurring on SIG-BVC with a TLLI */
3385 var OCT4 tlli := f_gen_tlli_for_sgsn_nri(sgsn_idx, nri_idx);
3386 var PDU_BSSGP inner := valueof(ts_BSSGP_FLUSH_LL(tlli, 2342));
3387
3388 f_TC_status_ul(0, sgsn_idx, inner);
3389 }
3390 }
3391
3392 f_cleanup();
3393}
3394
3395/* STATUS in uplink direction on SIG-BVC containing a TMSI; expect routing by its NRI */
3396testcase TC_status_sig_ul_tmsi() runs on GlobalTest_CT
3397{
3398 var integer sgsn_idx, nri_idx;
3399
3400 f_init();
3401 f_global_init();
3402
3403 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3404 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx + 1) {
3405 /* some downlink PDU occurring on SIG-BVC with a TMSI */
3406 const hexstring imsi := '001010123456789'H
3407 var OCT4 tmsi := f_gen_tmsi_for_sgsn_nri(sgsn_idx, nri_idx);
3408 var BssgpBvci bvci := g_pcu[0].cfg.bvc[0].bvci;
3409 var PDU_BSSGP inner := valueof(ts_BSSGP_CS_PAGING_PTMSI(bvci, imsi, oct2int(tmsi)));
3410 f_TC_status_ul(0, sgsn_idx, inner);
3411 }
3412 }
3413
3414 f_cleanup();
3415}
3416
3417
3418/* STATUS in uplink direction on PTP-BVC containing a TLLI; expect routing by its NRI */
3419testcase TC_status_ptp_ul_tlli() runs on GlobalTest_CT
3420{
3421 var integer sgsn_idx, nri_idx;
3422
3423 f_init();
3424 f_global_init_ptp();
3425
3426 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3427 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx + 1) {
3428 /* some downlink PDU occurring on PTP-BVC with a TLLI */
3429 var OCT4 tlli := f_gen_tlli_for_sgsn_nri(sgsn_idx, nri_idx);
3430 var PDU_BSSGP inner := valueof(ts_BSSGP_DL_UD(tlli, '2342'O));
3431
3432 f_TC_status_ul(0, sgsn_idx, inner);
3433 }
3434 }
3435
3436 f_cleanup();
3437}
3438
3439/* STATUS in uplink direction on PTP-BVC containing a TMSI; expect routing by its NRI */
3440testcase TC_status_ptp_ul_tmsi() runs on GlobalTest_CT
3441{
3442 var integer sgsn_idx, nri_idx;
3443
3444 f_init();
3445 f_global_init_ptp();
3446
3447 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3448 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx + 1) {
3449 /* some downlink PDU occurring on PTP-BVC with a TMSI */
3450 const hexstring imsi := '001010123456789'H
3451 var OCT4 tmsi := f_gen_tmsi_for_sgsn_nri(sgsn_idx, nri_idx);
3452 var BssgpBvci bvci := g_pcu[0].cfg.bvc[0].bvci;
3453 var PDU_BSSGP inner := valueof(ts_BSSGP_CS_PAGING_PTMSI(bvci, imsi, oct2int(tmsi)));
3454 f_TC_status_ul(0, sgsn_idx, inner);
3455 }
3456 }
3457
3458 f_cleanup();
3459}
3460
3461/* STATUS in downlink direction in SIG-BVC containing a BVCI; expect routing by it */
3462testcase TC_status_sig_dl_bvci() runs on GlobalTest_CT
3463{
3464 var integer sgsn_idx, pcu_idx, bvc_idx;
3465
3466 f_init();
3467 f_global_init();
3468
3469 /* test each BVC in each PCU from each SGSN */
3470 for (pcu_idx := 0; pcu_idx < lengthof(g_pcu); pcu_idx := pcu_idx + 1) {
3471 for (bvc_idx := 0; bvc_idx < lengthof(g_pcu[pcu_idx].cfg.bvc); bvc_idx := bvc_idx + 1) {
3472 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3473 /* some uplink PDU occurring on SIG-BVC containing a BVCI */
3474 var BssgpBvci bvci := g_pcu[pcu_idx].cfg.bvc[bvc_idx].bvci;
3475 var PDU_BSSGP inner := valueof(ts_BSSGP_LLC_DISCARDED('12345678'O, 1, bvci, 23));
3476 f_TC_status_dl(sgsn_idx, pcu_idx, inner);
3477 }
3478 }
3479 }
3480
3481 f_cleanup();
3482}
3483
3484/* STATUS in downlink direction in PTP-BVC; expect routing by BVCI */
3485testcase TC_status_ptp_dl_bvci() runs on GlobalTest_CT
3486{
3487 var integer sgsn_idx, pcu_idx, bvc_idx;
3488
3489 f_init();
3490 f_global_init_ptp();
3491
3492 /* test each BVC in each PCU from each SGSN */
3493 for (pcu_idx := 0; pcu_idx < lengthof(g_pcu); pcu_idx := pcu_idx + 1) {
3494 for (bvc_idx := 0; bvc_idx < lengthof(g_pcu[pcu_idx].cfg.bvc); bvc_idx := bvc_idx + 1) {
3495 var BssgpBvci bvci := g_pcu[pcu_idx].cfg.bvc[bvc_idx].bvci;
3496 f_global_ptp_connect_pcu_bvci(pcu_idx, bvci);
3497 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3498 f_global_ptp_connect_sgsn_bvci(sgsn_idx, bvci);
3499
3500 /* some uplink PDU occurring on PTP-BVC */
3501 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
3502 var PDU_BSSGP inner := valueof(ts_BSSGP_UL_UD('12345678'O, cell_id, '4223'O));
3503 f_TC_status_dl(sgsn_idx, pcu_idx, inner);
3504 }
3505 }
3506 }
3507
3508 f_cleanup();
3509}
3510
3511/* TODO: test case for DL-STATUS(SUSPEND/RESUME) containing RA-ID; expect routing by RA-ID */
3512/* 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 +01003513
Daniel Willmann423d8f42020-09-08 18:58:22 +02003514control {
3515 execute( TC_BVC_bringup() );
Harald Welte92686012020-11-15 21:45:49 +01003516 execute( TC_ul_unitdata() );
Daniel Willmann8d9fcf42021-05-28 15:05:41 +02003517 execute( TC_ul_unitdata_pool_failure() );
Harald Welte78d8db92020-11-15 23:27:27 +01003518 execute( TC_dl_unitdata() );
Harald Welte6dc2ac42020-11-16 09:16:17 +01003519 execute( TC_ra_capability() );
Daniel Willmannace3ece2020-11-16 19:53:26 +01003520 execute( TC_ra_capability_upd() );
Daniel Willmann165d6612020-11-19 14:27:29 +01003521 execute( TC_radio_status() );
Harald Welte3148a962021-01-17 11:15:28 +01003522 execute( TC_radio_status_tmsi() );
3523 execute( TC_radio_status_imsi() );
Daniel Willmannfa67f492020-11-19 15:48:05 +01003524 execute( TC_suspend() );
Daniel Willmann087a33d2020-11-19 15:58:43 +01003525 execute( TC_resume() );
Harald Weltef8e5c5d2020-11-27 22:37:23 +01003526 execute( TC_trace() );
Harald Weltec0351d12020-11-27 22:49:02 +01003527 execute( TC_llc_discarded() );
Harald Weltef20af412020-11-28 16:11:11 +01003528 execute( TC_overload() );
Harald Welte239aa502020-11-24 23:14:20 +01003529 execute( TC_bvc_block_ptp() );
3530 execute( TC_bvc_unblock_ptp() );
Harald Welte60a8ec72020-11-25 17:12:53 +01003531 execute( TC_bvc_reset_ptp_from_bss() );
Harald Welte16786e92020-11-27 19:11:56 +01003532 execute( TC_bvc_reset_sig_from_bss() );
Harald Welte60a8ec72020-11-25 17:12:53 +01003533 execute( TC_bvc_reset_ptp_from_sgsn() );
Harald Welte16786e92020-11-27 19:11:56 +01003534 execute( TC_bvc_reset_sig_from_sgsn() );
Harald Weltef6e59b02020-12-08 08:29:09 +01003535 if (mp_enable_bss_load_sharing) {
Harald Weltef8ef0282020-11-18 12:16:59 +01003536 /* don't enable this by default, as we don't yet have any automatic test setup for FR with 4 NS-VC */
3537 execute( TC_load_sharing_dl() );
3538 }
Harald Welte0e188242020-11-22 21:46:48 +01003539
3540 /* PAGING-PS over PTP BVC */
3541 execute( TC_paging_ps_ptp_bss() );
3542 execute( TC_paging_ps_ptp_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01003543 execute( TC_paging_ps_ptp_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003544 execute( TC_paging_ps_ptp_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01003545 execute( TC_paging_ps_ptp_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003546 execute( TC_paging_ps_ptp_bvci() );
Harald Welteb5a04aa2021-01-16 13:04:40 +01003547 execute( TC_paging_ps_ptp_bvci_imsi() );
Harald Welte7462a592020-11-23 22:07:07 +01003548 execute( TC_paging_ps_ptp_bvci_unknown() );
Harald Weltecf200072021-01-16 15:20:46 +01003549 execute( TC_paging_ps_reject_ptp_bvci() );
3550 execute( TC_paging_ps_reject_ptp_bvci_imsi() );
Harald Welte7595d562021-01-16 19:09:20 +01003551 execute( TC_dummy_paging_ps_ptp() );
Harald Welte0e188242020-11-22 21:46:48 +01003552
3553 /* PAGING-PS over SIG BVC */
3554 execute( TC_paging_ps_sig_bss() );
3555 execute( TC_paging_ps_sig_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01003556 execute( TC_paging_ps_sig_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003557 execute( TC_paging_ps_sig_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01003558 execute( TC_paging_ps_sig_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003559 execute( TC_paging_ps_sig_bvci() );
Harald Welteb5a04aa2021-01-16 13:04:40 +01003560 execute( TC_paging_ps_sig_bvci_imsi() );
Harald Welte7462a592020-11-23 22:07:07 +01003561 execute( TC_paging_ps_sig_bvci_unknown() );
Harald Weltecf200072021-01-16 15:20:46 +01003562 execute( TC_paging_ps_reject_sig_bvci() );
3563 execute( TC_paging_ps_reject_sig_bvci_imsi() );
Harald Welte7595d562021-01-16 19:09:20 +01003564 execute( TC_dummy_paging_ps_sig() );
Harald Welte0e188242020-11-22 21:46:48 +01003565
3566 /* PAGING-CS over PTP BVC */
3567 execute( TC_paging_cs_ptp_bss() );
3568 execute( TC_paging_cs_ptp_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01003569 execute( TC_paging_cs_ptp_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003570 execute( TC_paging_cs_ptp_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01003571 execute( TC_paging_cs_ptp_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003572 execute( TC_paging_cs_ptp_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01003573 execute( TC_paging_cs_ptp_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003574
3575 /* PAGING-CS over SIG BVC */
3576 execute( TC_paging_cs_sig_bss() );
3577 execute( TC_paging_cs_sig_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01003578 execute( TC_paging_cs_sig_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003579 execute( TC_paging_cs_sig_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01003580 execute( TC_paging_cs_sig_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003581 execute( TC_paging_cs_sig_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01003582 execute( TC_paging_cs_sig_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003583
Harald Weltef86f1852021-01-16 21:56:17 +01003584 /* RAN Information Management */
3585 execute( TC_rim_info_req() );
3586 execute( TC_rim_info() );
3587 execute( TC_rim_info_ack() );
3588 execute( TC_rim_info_error() );
3589 execute( TC_rim_info_app_error() );
3590 execute( TC_rim_info_pcu2pcu() );
Pau Espin Pedrol40778e82021-05-07 13:20:58 +02003591 execute( TC_rim_from_eutran() );
Harald Weltef86f1852021-01-16 21:56:17 +01003592
Harald Welte0e188242020-11-22 21:46:48 +01003593
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01003594 execute( TC_flush_ll() );
Harald Welte299aa482020-12-09 15:10:55 +01003595 execute( TC_fc_bvc() );
Harald Weltecc3894b2020-12-09 16:50:12 +01003596 execute( TC_fc_ms() );
Harald Welted6f89812021-01-16 18:57:49 +01003597 execute( TC_ms_reg_enq() );
Harald Welte04358652021-01-17 13:48:13 +01003598
3599 /* Uplink STATUS */
3600 execute( TC_status_sig_ul_tlli() );
3601 execute( TC_status_sig_ul_tmsi() );
3602 execute( TC_status_ptp_ul_tlli() );
3603 execute( TC_status_ptp_ul_tmsi() );
3604
3605 /* Downlink STATUS */
3606 execute( TC_status_sig_dl_bvci() );
3607 execute( TC_status_ptp_dl_bvci() );
Daniel Willmann423d8f42020-09-08 18:58:22 +02003608}
3609
3610
3611}