blob: dd33106cd05ef95fabd241abb98feb47b754485b [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
Harald Welteb5688f22021-03-30 16:28:04 +0200634 /* verify all SGSN-side BVC FSM in IUT are UNBLOCKED */
635 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
636 f_bvc_fsm_ensure_state(mp_nsconfig_sgsn[i].nsei, 0, "UNBLOCKED");
637 /* iterate over list and check all BVCI */
638 for (var integer j := 0; j < lengthof(g_sgsn[i].cfg.bvc); j := j+1) {
639 var BssgpBvci bvci := g_sgsn[i].cfg.bvc[j].bvci;
640 f_bvc_fsm_ensure_state(mp_nsconfig_sgsn[i].nsei, bvci, "UNBLOCKED");
641 }
642 }
643 /* verify all PCU-side BVC FSM in IUT are UNBLOCKED */
644 for (i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
645 f_bvc_fsm_ensure_state(mp_nsconfig_pcu[i].nsei, 0, "UNBLOCKED");
646 /* iterate over list and check all BVCI */
647 for (var integer j := 0; j < lengthof(g_pcu[i].cfg.bvc); j := j+1) {
648 var BssgpBvci bvci := g_pcu[i].cfg.bvc[j].bvci;
649 f_bvc_fsm_ensure_state(mp_nsconfig_pcu[i].nsei, bvci, "UNBLOCKED");
650 }
651 }
652
Harald Welte425d3762020-12-09 14:33:18 +0100653 /* re-start guard timer after all BVCs are up, so it only counts the actual test case */
654 g_Tguard.start(t_guard);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200655}
656
657function f_cleanup() runs on test_CT {
Harald Welteb9f0fdc2020-12-09 14:44:50 +0100658 var integer i;
659
Daniel Willmann491af2a2021-01-08 01:32:51 +0100660 /* To avoid a dynamic test case error we need to prevent messages arriving on unconnected
661 * ports. Waiting here ensures that any messages "in flight" will be delivered to the port
662 * before the component is shutdown and disconnected. */
663 f_sleep(0.2);
664
Harald Welteb9f0fdc2020-12-09 14:44:50 +0100665 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
666 f_destroy_gb(g_sgsn[i]);
667 }
668 for (i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
669 f_destroy_gb(g_pcu[i]);
670 }
671
672 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, pass);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200673}
674
675type function void_fn(charstring id) runs on BSSGP_ConnHdlr;
676
677/* helper function to create, connect and start a BSSGP_ConnHdlr component */
Harald Welte207166c2021-01-16 12:52:30 +0100678function f_start_handler(void_fn fn, charstring id, integer imsi_suffix, float t_guard := 30.0,
679 integer sgsn_idx := 0, integer nri_idx := 0, boolean have_ptmsi := true)
Daniel Willmann423d8f42020-09-08 18:58:22 +0200680runs on test_CT return BSSGP_ConnHdlr {
681 var BSSGP_ConnHdlr vc_conn;
Harald Weltec5f486b2021-01-16 11:07:01 +0100682 var integer nri := mp_sgsn_nri[sgsn_idx][nri_idx];
Harald Welte77218d02021-01-15 19:59:15 +0100683 var OCT4 p_tmsi := f_gen_tmsi(imsi_suffix, nri_v := nri, nri_bitlen := mp_nri_bitlength);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200684
685 var BSSGP_ConnHdlrPars pars := {
686 imei := f_gen_imei(imsi_suffix),
687 imsi := f_gen_imsi(imsi_suffix),
688 msisdn := f_gen_msisdn(imsi_suffix),
Harald Weltedbd5e672021-01-14 21:03:14 +0100689 p_tmsi := p_tmsi,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200690 p_tmsi_sig := omit,
Harald Weltedbd5e672021-01-14 21:03:14 +0100691 tlli := f_gprs_tlli_from_tmsi(p_tmsi, TLLI_LOCAL),
Daniel Willmann423d8f42020-09-08 18:58:22 +0200692 tlli_old := omit,
693 ra := omit,
Harald Welte2ecbca82021-01-16 11:23:09 +0100694 pcu := g_pcu,
695 sgsn := g_sgsn,
Harald Weltec5f486b2021-01-16 11:07:01 +0100696 sgsn_idx := sgsn_idx,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200697 t_guard := t_guard
698 };
Harald Welte207166c2021-01-16 12:52:30 +0100699 if (not have_ptmsi) {
700 pars.p_tmsi := omit;
701 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200702
703 vc_conn := BSSGP_ConnHdlr.create(id);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200704
Harald Welte25a04b12021-01-17 11:09:49 +0100705 log("Starting ", id, " for SGSN[", sgsn_idx, "], NRI=", nri, ", P-TMSI=", pars.p_tmsi,
706 ", TLLI=", pars.tlli, ", IMSI=", pars.imsi, " on component=", vc_conn);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200707 vc_conn.start(f_handler_init(fn, id, pars));
708 return vc_conn;
709}
710
Harald Welte207166c2021-01-16 12:52:30 +0100711function f_start_handlers(void_fn fn, charstring id, integer imsi_suffix, float t_guard := 30.0,
712 boolean have_ptmsi := true)
Harald Weltec5f486b2021-01-16 11:07:01 +0100713runs on test_CT
714{
715 var integer sgsn_idx, nri_idx;
716 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx:=sgsn_idx+1) {
717 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx:=nri_idx+1) {
718 var integer extd_imsi_suffix := 1000*sgsn_idx + 100*nri_idx;
719 var BSSGP_ConnHdlr vc_conn;
Harald Welte207166c2021-01-16 12:52:30 +0100720 vc_conn := f_start_handler(fn, id, extd_imsi_suffix, t_guard, sgsn_idx, nri_idx,
721 have_ptmsi);
Harald Weltec5f486b2021-01-16 11:07:01 +0100722 /* Idea: we could also run them in parallel ? */
723 vc_conn.done;
724 }
725 }
726}
727
Harald Welte3dd21b32020-11-17 19:21:00 +0100728/* 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 +0100729private function f_connect_to_pcu_bvc(integer port_idx, integer nse_idx, integer bvc_idx)
730runs on BSSGP_ConnHdlr {
731 var BSSGP_BVC_CT bvc_ct := g_pars.pcu[nse_idx].vc_BSSGP_BVC[bvc_idx]
Harald Welte158becf2020-12-09 12:32:32 +0100732 if (PCU_PTP[port_idx].checkstate("Connected")) {
Harald Welte3dd21b32020-11-17 19:21:00 +0100733 /* unregister + disconnect from old BVC */
734 f_client_unregister(g_pars.imsi, PCU_PROC[port_idx]);
Harald Welte158becf2020-12-09 12:32:32 +0100735 disconnect(self:PCU_PTP[port_idx], pcu_ct[port_idx]:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100736 disconnect(self:PCU_SIG[port_idx], pcu_ct[port_idx]:BSSGP_SP_SIG);
737 disconnect(self:PCU_PROC[port_idx], pcu_ct[port_idx]:BSSGP_PROC);
738 }
739 /* connect to new BVC and register us */
Harald Welte158becf2020-12-09 12:32:32 +0100740 connect(self:PCU_PTP[port_idx], bvc_ct:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100741 connect(self:PCU_SIG[port_idx], bvc_ct:BSSGP_SP_SIG);
742 connect(self:PCU_PROC[port_idx], bvc_ct:BSSGP_PROC);
743 f_client_register(g_pars.imsi, g_pars.tlli, PCU_PROC[port_idx]);
744 pcu_ct[port_idx] := bvc_ct;
Harald Welte0e188242020-11-22 21:46:48 +0100745 pcu_bvc_cfg[port_idx] := g_pars.pcu[nse_idx].cfg.bvc[bvc_idx];
Harald Welte3dd21b32020-11-17 19:21:00 +0100746}
747
748/* Connect the SGSN-side per-BVC ports (SGSN/SGSN_SIG/SGSN_PROC) array slot 'port_idx' to specified per-BVC component */
749private 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 +0100750 if (SGSN_PTP[port_idx].checkstate("Connected")) {
Harald Welte3dd21b32020-11-17 19:21:00 +0100751 /* unregister + disconnect from old BVC */
752 f_client_unregister(g_pars.imsi, SGSN_PROC[port_idx]);
Harald Welte158becf2020-12-09 12:32:32 +0100753 disconnect(self:SGSN_PTP[port_idx], sgsn_ct[port_idx]:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100754 disconnect(self:SGSN_SIG[port_idx], sgsn_ct[port_idx]:BSSGP_SP_SIG);
755 disconnect(self:SGSN_PROC[port_idx], sgsn_ct[port_idx]:BSSGP_PROC);
756 }
757 /* connect to new BVC and register us */
Harald Welte158becf2020-12-09 12:32:32 +0100758 connect(self:SGSN_PTP[port_idx], bvc_ct:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100759 connect(self:SGSN_SIG[port_idx], bvc_ct:BSSGP_SP_SIG);
760 connect(self:SGSN_PROC[port_idx], bvc_ct:BSSGP_PROC);
761 f_client_register(g_pars.imsi, g_pars.tlli, SGSN_PROC[port_idx]);
762 sgsn_ct[port_idx] := bvc_ct;
763}
764
Harald Welte425d3762020-12-09 14:33:18 +0100765private altstep as_gTguard(timer Tguard) {
766 [] Tguard.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +0100767 f_shutdown(__FILE__, __LINE__, fail, "Tguard timeout");
Daniel Willmann423d8f42020-09-08 18:58:22 +0200768 }
769}
770
771/* first function called in every ConnHdlr */
772private function f_handler_init(void_fn fn, charstring id, BSSGP_ConnHdlrPars pars)
773runs on BSSGP_ConnHdlr {
Harald Welte1e834f32020-11-15 20:02:59 +0100774 var integer i;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200775 /* do some common stuff like setting up g_pars */
776 g_pars := pars;
777
778 llc := f_llc_create(false);
779
Harald Welte3dd21b32020-11-17 19:21:00 +0100780 /* default connections on PCU side: First BVC of each NSE/PCU */
781 for (i := 0; i < lengthof(g_pars.pcu); i := i+1) {
Harald Welte0e188242020-11-22 21:46:48 +0100782 f_connect_to_pcu_bvc(port_idx := i, nse_idx := i, bvc_idx := 0);
Harald Welte1e834f32020-11-15 20:02:59 +0100783 }
Harald Welte3dd21b32020-11-17 19:21:00 +0100784
785 /* default connections on SGSN side: First BVC of each NSE/SGSN */
786 for (i := 0; i < lengthof(g_pars.sgsn); i := i+1) {
787 f_connect_to_sgsn_bvc(i, g_pars.sgsn[i].vc_BSSGP_BVC[0]);
Harald Welte1e834f32020-11-15 20:02:59 +0100788 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200789
790 g_Tguard.start(pars.t_guard);
Harald Welte425d3762020-12-09 14:33:18 +0100791 activate(as_gTguard(g_Tguard));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200792
793 /* call the user-supplied test case function */
794 fn.apply(id);
Harald Welteb33fb592021-01-16 12:50:56 +0100795
796 for (i := 0; i < NUM_SGSN; i := i+1) {
797 if (SGSN_PROC[i].checkstate("Connected")) {
798 f_client_unregister(g_pars.imsi, SGSN_PROC[i])
799 }
800 }
801
802 for (i := 0; i < NUM_PCU; i := i+1) {
803 if (PCU_PROC[i].checkstate("Connected")) {
804 f_client_unregister(g_pars.imsi, PCU_PROC[i])
805 }
806 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200807}
808
Harald Welte1e834f32020-11-15 20:02:59 +0100809private function f_client_register(hexstring imsi, OCT4 tlli, BSSGP_PROC_PT PT)
810runs on BSSGP_ConnHdlr {
811 PT.call(BSSGP_register_client:{imsi, tlli}) {
812 [] PT.getreply(BSSGP_register_client:{imsi, tlli}) {};
813 }
814}
815
816private function f_client_unregister(hexstring imsi, BSSGP_PROC_PT PT)
817runs on BSSGP_ConnHdlr {
818 PT.call(BSSGP_unregister_client:{imsi}) {
819 [] PT.getreply(BSSGP_unregister_client:{imsi}) {};
820 }
821}
822
Harald Welte22ef5d92020-11-16 13:35:14 +0100823/* Send 'tx' on PTP-BVCI from PCU; expect 'rx' on SGSN */
824friend function f_pcu2sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
Harald Weltec5f486b2021-01-16 11:07:01 +0100825 integer pcu_idx := 0, boolean use_sig := false) runs on BSSGP_ConnHdlr {
826 var integer sgsn_idx := g_pars.sgsn_idx;
Harald Welte22ef5d92020-11-16 13:35:14 +0100827 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +0100828 timer T := 2.0;
Harald Welte22ef5d92020-11-16 13:35:14 +0100829
Daniel Willmann4798fd72020-11-24 16:23:29 +0100830 if (use_sig) {
831 PCU_SIG[pcu_idx].send(tx);
832 } else {
Harald Welte158becf2020-12-09 12:32:32 +0100833 PCU_PTP[pcu_idx].send(tx);
Daniel Willmann4798fd72020-11-24 16:23:29 +0100834 }
835
Harald Welte22ef5d92020-11-16 13:35:14 +0100836 T.start;
837 alt {
Daniel Willmann4798fd72020-11-24 16:23:29 +0100838 [use_sig] SGSN_SIG[sgsn_idx].receive(exp_rx) {
839 setverdict(pass);
840 }
Harald Welte158becf2020-12-09 12:32:32 +0100841 [not use_sig] SGSN_PTP[sgsn_idx].receive(exp_rx) {
Harald Welte22ef5d92020-11-16 13:35:14 +0100842 setverdict(pass);
843 }
Harald Welte158becf2020-12-09 12:32:32 +0100844 [] SGSN_PTP[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +0100845 f_shutdown(__FILE__, __LINE__, fail,
846 log2str("Unexpected BSSGP on SGSN[", sgsn_idx, "] side: ", rx));
Harald Welte22ef5d92020-11-16 13:35:14 +0100847 }
Daniel Willmann4798fd72020-11-24 16:23:29 +0100848 [] SGSN_SIG[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +0100849 f_shutdown(__FILE__, __LINE__, fail,
850 log2str("Unexpected SIG BSSGP on SGSN[", sgsn_idx, "] side: ", rx));
Daniel Willmann4798fd72020-11-24 16:23:29 +0100851 }
Harald Welte22ef5d92020-11-16 13:35:14 +0100852 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +0100853 f_shutdown(__FILE__, __LINE__, fail,
854 log2str("Timeout waiting for BSSGP on SGSN[", sgsn_idx, "] side: ", exp_rx));
Harald Welte22ef5d92020-11-16 13:35:14 +0100855 }
856 }
857}
858
Harald Welte3148a962021-01-17 11:15:28 +0100859/* Send 'tx' from PCU; expect 'exp_rx' on _any_ SGSN */
860friend function f_pcu2any_sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
861 integer pcu_idx := 0, boolean use_sig := false)
862runs on BSSGP_ConnHdlr return integer {
863 var integer rx_idx := -1;
864 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +0100865 timer T := 2.0;
Harald Welte3148a962021-01-17 11:15:28 +0100866
867 if (use_sig) {
868 PCU_SIG[pcu_idx].send(tx);
869 } else {
870 PCU_PTP[pcu_idx].send(tx);
871 }
872
873 T.start;
874 alt {
875 [use_sig] any from SGSN_SIG.receive(exp_rx) -> @index value rx_idx {
876 setverdict(pass);
877 }
878 [not use_sig] any from SGSN_PTP.receive(exp_rx) -> @index value rx_idx {
879 setverdict(pass);
880 }
881 [] any from SGSN_PTP.receive(PDU_BSSGP:?) -> value rx @index value rx_idx {
Harald Welted5b7e742021-01-27 10:50:24 +0100882 f_shutdown(__FILE__, __LINE__, fail,
883 log2str("Unexpected BSSGP on SGSN[", rx_idx, "] side: ", rx));
Harald Welte3148a962021-01-17 11:15:28 +0100884 }
885 [] any from SGSN_SIG.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 SIG BSSGP on SGSN[", rx_idx, "] side: ", rx));
Harald Welte3148a962021-01-17 11:15:28 +0100888 }
889 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +0100890 f_shutdown(__FILE__, __LINE__, fail,
891 log2str("Timeout waiting for BSSGP on SGSN side: ", exp_rx));
Harald Welte3148a962021-01-17 11:15:28 +0100892 }
893 }
894 return rx_idx;
895}
896
Harald Welte22ef5d92020-11-16 13:35:14 +0100897/* Send 'tx' on PTP-BVCI from SGSN; expect 'rx' on PCU */
898friend function f_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
Harald Weltec5f486b2021-01-16 11:07:01 +0100899 integer pcu_idx := 0, boolean use_sig := false) runs on BSSGP_ConnHdlr {
900 var integer sgsn_idx := g_pars.sgsn_idx;
Harald Welte22ef5d92020-11-16 13:35:14 +0100901 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +0100902 timer T := 2.0;
Harald Welte22ef5d92020-11-16 13:35:14 +0100903
Daniel Willmann4798fd72020-11-24 16:23:29 +0100904 if (use_sig) {
905 SGSN_SIG[sgsn_idx].send(tx);
906 } else {
Harald Welte158becf2020-12-09 12:32:32 +0100907 SGSN_PTP[sgsn_idx].send(tx);
Daniel Willmann4798fd72020-11-24 16:23:29 +0100908 }
909
Harald Welte22ef5d92020-11-16 13:35:14 +0100910 T.start;
911 alt {
Daniel Willmann4798fd72020-11-24 16:23:29 +0100912 [use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
913 setverdict(pass);
914 }
Harald Welte158becf2020-12-09 12:32:32 +0100915 [not use_sig] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte22ef5d92020-11-16 13:35:14 +0100916 setverdict(pass);
917 }
Harald Welte158becf2020-12-09 12:32:32 +0100918 [] PCU_PTP[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +0100919 f_shutdown(__FILE__, __LINE__, fail, log2str("Unexpected BSSGP on PCU side: ", rx));
Harald Welte22ef5d92020-11-16 13:35:14 +0100920 }
Daniel Willmann4798fd72020-11-24 16:23:29 +0100921 [] PCU_SIG[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +0100922 f_shutdown(__FILE__, __LINE__, fail, log2str("Unexpected SIG BSSGP on PCU side: ", rx));
Daniel Willmann4798fd72020-11-24 16:23:29 +0100923 }
Harald Welte22ef5d92020-11-16 13:35:14 +0100924 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +0100925 f_shutdown(__FILE__, __LINE__, fail,
926 log2str("Timeout waiting for BSSGP on PCU side: ", exp_rx));
Harald Welte22ef5d92020-11-16 13:35:14 +0100927 }
928 }
929}
Harald Welte1e834f32020-11-15 20:02:59 +0100930
Harald Welte3807ed12020-11-24 19:05:22 +0100931/***********************************************************************
932 * GlobaLTest_CT: Using the per-NSE GLOBAL ports on PCU + SGSN side
933 ***********************************************************************/
934
935type component GlobalTest_CT extends test_CT {
936 port BSSGP_PT G_PCU[NUM_PCU];
Harald Welte04358652021-01-17 13:48:13 +0100937 var integer g_pcu_idx[NUM_PCU]; /* BVC index currently connected to G_PCU */
Harald Welte3807ed12020-11-24 19:05:22 +0100938 port BSSGP_PT G_SGSN[NUM_SGSN];
Harald Welte04358652021-01-17 13:48:13 +0100939 var integer g_sgsn_idx[NUM_SGSN]; /* BVC index currently connected to G_SGSN */
Harald Weltef86f1852021-01-16 21:56:17 +0100940 port BSSGP_PT RIM_PCU[NUM_PCU];
941 port BSSGP_PT RIM_SGSN[NUM_SGSN];
Harald Welte3807ed12020-11-24 19:05:22 +0100942};
943
Harald Welte299aa482020-12-09 15:10:55 +0100944/* connect the signaling BVC of each NSE to the G_PCU / G_SGSN ports */
Harald Welte3807ed12020-11-24 19:05:22 +0100945private function f_global_init() runs on GlobalTest_CT {
946 var integer i;
947 for (i := 0; i < lengthof(g_sgsn); i := i+1) {
948 connect(self:G_SGSN[i], g_sgsn[i].vc_BSSGP:GLOBAL);
Harald Weltef86f1852021-01-16 21:56:17 +0100949 connect(self:RIM_SGSN[i], g_sgsn[i].vc_BSSGP:RIM);
Harald Welte3807ed12020-11-24 19:05:22 +0100950 }
951 for (i := 0; i < lengthof(g_pcu); i := i+1) {
952 connect(self:G_PCU[i], g_pcu[i].vc_BSSGP:GLOBAL);
Harald Weltef86f1852021-01-16 21:56:17 +0100953 connect(self:RIM_PCU[i], g_pcu[i].vc_BSSGP:RIM);
Harald Welte3807ed12020-11-24 19:05:22 +0100954 }
955}
956
Harald Welte299aa482020-12-09 15:10:55 +0100957/* connect the first PTP BVC of each NSE to the G_PCU / G_SGSN ports */
958private function f_global_init_ptp() runs on GlobalTest_CT {
959 var integer i;
960 for (i := 0; i < lengthof(g_sgsn); i := i+1) {
Harald Welte04358652021-01-17 13:48:13 +0100961 log("Connecting G_SGSN[", i, "] to BVCI=", g_sgsn[i].cfg.bvc[0].bvci);
Harald Welte299aa482020-12-09 15:10:55 +0100962 connect(self:G_SGSN[i], g_sgsn[i].vc_BSSGP_BVC[0]:GLOBAL);
Harald Welte04358652021-01-17 13:48:13 +0100963 g_sgsn_idx[i] := 0;
Harald Welte299aa482020-12-09 15:10:55 +0100964 }
965 for (i := 0; i < lengthof(g_pcu); i := i+1) {
Harald Welte04358652021-01-17 13:48:13 +0100966 log("Connecting G_PCU[", i, "] to BVCI=", g_pcu[i].cfg.bvc[0].bvci);
Harald Welte299aa482020-12-09 15:10:55 +0100967 connect(self:G_PCU[i], g_pcu[i].vc_BSSGP_BVC[0]:GLOBAL);
Harald Welte04358652021-01-17 13:48:13 +0100968 g_pcu_idx[i] := 0;
Harald Welte299aa482020-12-09 15:10:55 +0100969 }
970}
971
Harald Welte04358652021-01-17 13:48:13 +0100972/* (re)connect G_SGSN[sgsn_idx] to a specific PTP BVCI */
973private function f_global_ptp_connect_sgsn_bvci(integer sgsn_idx, BssgpBvci bvci) runs on GlobalTest_CT
974{
975 var integer sgsn_bvc_idx := get_bvc_idx_for_bvci(g_sgsn[sgsn_idx], bvci);
976 var integer old_sgsn_bvc_idx := g_sgsn_idx[sgsn_idx];
977 disconnect(self:G_SGSN[sgsn_idx], g_sgsn[sgsn_idx].vc_BSSGP_BVC[old_sgsn_bvc_idx]:GLOBAL);
978 connect(self:G_SGSN[sgsn_idx], g_sgsn[sgsn_idx].vc_BSSGP_BVC[sgsn_bvc_idx]:GLOBAL);
979 g_sgsn_idx[sgsn_idx] := sgsn_bvc_idx;
980}
981
982/* (re)connect G_PCU[pcu_idx] to a specific PTP BVCI */
983private function f_global_ptp_connect_pcu_bvci(integer pcu_idx, BssgpBvci bvci) runs on GlobalTest_CT
984{
985 var integer pcu_bvc_idx := get_bvc_idx_for_bvci(g_pcu[pcu_idx], bvci);
986 var integer old_pcu_bvc_idx := g_pcu_idx[pcu_idx];
987 disconnect(self:G_PCU[pcu_idx], g_pcu[pcu_idx].vc_BSSGP_BVC[old_pcu_bvc_idx]:GLOBAL);
988 connect(self:G_PCU[pcu_idx], g_pcu[pcu_idx].vc_BSSGP_BVC[pcu_bvc_idx]:GLOBAL);
989 g_pcu_idx[pcu_idx] := pcu_bvc_idx;
990}
991
Harald Welte3807ed12020-11-24 19:05:22 +0100992/* Send 'tx' on PTP-BVCI from PCU; expect 'rx' on SGSN */
993friend function f_global_pcu2sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
994 integer pcu_idx := 0, integer sgsn_idx := 0) runs on GlobalTest_CT {
Harald Welte04358652021-01-17 13:48:13 +0100995 var integer rx_idx;
Harald Welte3807ed12020-11-24 19:05:22 +0100996 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +0100997 timer T := 2.0;
Harald Welte3807ed12020-11-24 19:05:22 +0100998
999 G_PCU[pcu_idx].send(tx);
1000 T.start;
1001 alt {
1002 [] G_SGSN[sgsn_idx].receive(exp_rx) {
1003 setverdict(pass);
1004 }
Harald Welte04358652021-01-17 13:48:13 +01001005 [] any from G_SGSN.receive(exp_rx) -> @index value rx_idx {
1006 setverdict(fail, "BSSGP arrived on wrong SGSN[", rx_idx, "] instead of SGSN[", sgsn_idx, "]");
1007 }
Harald Welte3807ed12020-11-24 19:05:22 +01001008 [] G_SGSN[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +01001009 f_shutdown(__FILE__, __LINE__, fail, log2str("Unexpected BSSGP on SGSN side: ", rx));
Harald Welte3807ed12020-11-24 19:05:22 +01001010 }
1011 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +01001012 f_shutdown(__FILE__, __LINE__, fail, log2str("Timeout waiting for BSSGP on SGSN side: ", exp_rx));
Harald Welte3807ed12020-11-24 19:05:22 +01001013 }
1014 }
1015}
1016
1017/* Send 'tx' on PTP-BVCI from SGSN; expect 'rx' on PCU */
1018friend function f_global_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
1019 integer sgsn_idx := 0, integer pcu_idx := 0) runs on GlobalTest_CT {
Harald Welte04358652021-01-17 13:48:13 +01001020 var integer rx_idx;
Harald Welte3807ed12020-11-24 19:05:22 +01001021 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +01001022 timer T := 2.0;
Harald Welte3807ed12020-11-24 19:05:22 +01001023
1024 G_SGSN[sgsn_idx].send(tx);
1025 T.start;
1026 alt {
1027 [] G_PCU[pcu_idx].receive(exp_rx) {
1028 setverdict(pass);
1029 }
Harald Welte04358652021-01-17 13:48:13 +01001030 [] any from G_PCU.receive(exp_rx) -> @index value rx_idx {
1031 setverdict(fail, "BSSGP arrived on wrong PCU[", rx_idx, "] instead of PCU[", pcu_idx, "]");
1032 }
Harald Welte3807ed12020-11-24 19:05:22 +01001033 [] G_PCU[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +01001034 f_shutdown(__FILE__, __LINE__, fail, log2str("Unexpected BSSGP on PCU side: ", rx));
Harald Welte3807ed12020-11-24 19:05:22 +01001035 }
1036 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +01001037 f_shutdown(__FILE__, __LINE__, fail, log2str("Timeout waiting for BSSGP on PCU side: ", exp_rx));
Harald Welte3807ed12020-11-24 19:05:22 +01001038 }
1039 }
1040}
1041
1042
Daniel Willmann423d8f42020-09-08 18:58:22 +02001043/* TODO:
1044 * Detach without Attach
1045 * SM procedures without attach / RAU
1046 * ATTACH / RAU
1047 ** with / without authentication
1048 ** with / without P-TMSI allocation
1049 * re-transmissions of LLC frames
1050 * PDP Context activation
1051 ** with different GGSN config in SGSN VTY
1052 ** with different PDP context type (v4/v6/v46)
1053 ** timeout from GGSN
1054 ** multiple / secondary PDP context
1055 */
1056
1057private function f_TC_BVC_bringup(charstring id) runs on BSSGP_ConnHdlr {
1058 f_sleep(5.0);
1059 setverdict(pass);
1060}
1061
1062testcase TC_BVC_bringup() runs on test_CT {
Daniel Willmann423d8f42020-09-08 18:58:22 +02001063 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001064 f_start_handlers(refers(f_TC_BVC_bringup), testcasename(), 51);
Daniel Willmann423d8f42020-09-08 18:58:22 +02001065 f_cleanup();
1066}
1067
1068friend function f_bssgp_suspend(integer ran_idx := 0) runs on BSSGP_ConnHdlr return OCT1 {
Harald Welte16357a92020-11-17 18:20:00 +01001069 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Daniel Willmann423d8f42020-09-08 18:58:22 +02001070 timer T := 5.0;
1071 var PDU_BSSGP rx_pdu;
Harald Welte16357a92020-11-17 18:20:00 +01001072 PCU_SIG[ran_idx].send(ts_BSSGP_SUSPEND(g_pars.tlli, bvcc.cell_id.ra_id));
Daniel Willmann423d8f42020-09-08 18:58:22 +02001073 T.start;
1074 alt {
Harald Welte16357a92020-11-17 18:20:00 +01001075 [] 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 +02001076 return rx_pdu.pDU_BSSGP_SUSPEND_ACK.suspend_Reference_Number.suspend_Reference_Number_value;
1077 }
Harald Welte16357a92020-11-17 18:20:00 +01001078 [] 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 +01001079 f_shutdown(__FILE__, __LINE__, fail,
1080 log2str("SUSPEND-NACK in response to SUSPEND for TLLI ", g_pars.tlli));
Daniel Willmann423d8f42020-09-08 18:58:22 +02001081 }
1082 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +01001083 f_shutdown(__FILE__, __LINE__, fail,
1084 log2str("No SUSPEND-ACK in response to SUSPEND for TLLI ", g_pars.tlli));
Daniel Willmann423d8f42020-09-08 18:58:22 +02001085 }
1086 }
1087 return '00'O;
1088}
1089
1090friend function f_bssgp_resume(OCT1 susp_ref, integer ran_idx := 0) runs on BSSGP_ConnHdlr {
Harald Welte16357a92020-11-17 18:20:00 +01001091 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Daniel Willmann423d8f42020-09-08 18:58:22 +02001092 timer T := 5.0;
Harald Welte16357a92020-11-17 18:20:00 +01001093 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 +02001094 T.start;
1095 alt {
Harald Welte16357a92020-11-17 18:20:00 +01001096 [] PCU_SIG[ran_idx].receive(tr_BSSGP_RESUME_ACK(g_pars.tlli, bvcc.cell_id.ra_id));
1097 [] PCU_SIG[ran_idx].receive(tr_BSSGP_RESUME_NACK(g_pars.tlli, bvcc.cell_id.ra_id, ?)) {
Harald Welted5b7e742021-01-27 10:50:24 +01001098 f_shutdown(__FILE__, __LINE__, fail,
1099 log2str("RESUME-NACK in response to RESUME for TLLI ", g_pars.tlli));
Daniel Willmann423d8f42020-09-08 18:58:22 +02001100 }
1101 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +01001102 f_shutdown(__FILE__, __LINE__, fail,
1103 log2str("No RESUME-ACK in response to SUSPEND for TLLI ", g_pars.tlli));
Daniel Willmann423d8f42020-09-08 18:58:22 +02001104 }
1105 }
1106}
1107
1108
Harald Welte92686012020-11-15 21:45:49 +01001109/* send uplink-unitdata of a variety of different sizes; expect it to show up on SGSN */
1110private function f_TC_ul_unitdata(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte16357a92020-11-17 18:20:00 +01001111 var integer ran_idx := 0;
1112 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Harald Welte92686012020-11-15 21:45:49 +01001113 var integer i;
1114
Harald Welte0d5fceb2020-11-29 16:04:07 +01001115 for (i := 0; i < max_fr_info_size-4; i := i+4) {
Harald Welte92686012020-11-15 21:45:49 +01001116 var octetstring payload := f_rnd_octstring(i);
Harald Welte16357a92020-11-17 18:20:00 +01001117 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 +01001118 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte16357a92020-11-17 18:20:00 +01001119 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 +01001120
Harald Welte0d5fceb2020-11-29 16:04:07 +01001121 log("UL-UNITDATA(payload_size=", i);
Harald Welte22ef5d92020-11-16 13:35:14 +01001122 f_pcu2sgsn(pdu_tx, pdu_rx);
Harald Welte92686012020-11-15 21:45:49 +01001123 }
1124 setverdict(pass);
1125}
1126
1127testcase TC_ul_unitdata() runs on test_CT
1128{
Daniel Willmannc879f342021-02-11 14:28:01 +01001129 f_init(60.0);
Harald Welte2ecbca82021-01-16 11:23:09 +01001130 f_start_handlers(refers(f_TC_ul_unitdata), testcasename(), 1);
Harald Welte92686012020-11-15 21:45:49 +01001131 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Welte92686012020-11-15 21:45:49 +01001132 f_cleanup();
1133}
1134
Daniel Willmann8d9fcf42021-05-28 15:05:41 +02001135
1136/* send uplink-unitdata of a variety of different sizes; expect it to show up on the only connected SGSN */
1137private function f_TC_ul_unitdata_pool_failure(charstring id) runs on BSSGP_ConnHdlr {
1138 var integer ran_idx := 0;
1139 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
1140 var integer i;
1141
1142 /* All data should arrive at the one SGSN that is still up */
1143 g_pars.sgsn_idx := 0;
1144
1145 for (i := 0; i < max_fr_info_size-4; i := i+4) {
1146 var octetstring payload := f_rnd_octstring(i);
1147 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_UL_UD(g_pars.tlli, bvcc.cell_id, payload);
1148 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1149 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_UL_UD(g_pars.tlli, bvcc.cell_id, payload);
1150
1151 log("UL-UNITDATA(payload_size=", i);
1152 f_pcu2sgsn(pdu_tx, pdu_rx);
1153 }
1154 setverdict(pass);
1155}
1156
1157testcase TC_ul_unitdata_pool_failure() runs on test_CT
1158{
1159 var integer i;
1160 var integer j;
1161
1162 f_init(60.0);
1163
1164 for (i := 1; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
1165 connect(self:NS_CTRL, g_sgsn[i].vc_NS:NS_CTRL);
1166 for (j := 0; j < lengthof(mp_nsconfig_sgsn[i].nsvc); j := j+1) {
1167 var uint16_t nsvci := mp_nsconfig_sgsn[i].nsvc[j].nsvci;
1168 var NsDisableVcRequest tx_disar;
1169 tx_disar.nsvci := nsvci;
1170 NS_CTRL.send(tx_disar);
1171 }
1172 disconnect(self:NS_CTRL, g_sgsn[i].vc_NS:NS_CTRL);
1173 }
1174 /* Wait until gbproxy notices that the NSVCs are down */
1175 f_sleep(15.0);
1176
1177 f_start_handlers(refers(f_TC_ul_unitdata_pool_failure), testcasename(), 1);
1178 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
1179 f_cleanup();
1180}
1181
Harald Welte78d8db92020-11-15 23:27:27 +01001182/* send downlink-unitdata of a variety of different sizes; expect it to show up on PCU */
1183private function f_TC_dl_unitdata(charstring id) runs on BSSGP_ConnHdlr {
1184 var integer i;
1185
Harald Welte0d5fceb2020-11-29 16:04:07 +01001186 for (i := 0; i < max_fr_info_size-4; i := i+4) {
Harald Welte78d8db92020-11-15 23:27:27 +01001187 var octetstring payload := f_rnd_octstring(i);
1188 var template (value) PDU_BSSGP pdu_tx :=
1189 ts_BSSGP_DL_UD(g_pars.tlli, payload, omit, ts_BSSGP_IMSI(g_pars.imsi));
1190 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1191 var template (present) PDU_BSSGP pdu_rx :=
Daniel Willmann325458d2021-02-11 14:22:42 +01001192 tr_BSSGP_DL_UD(g_pars.tlli, payload, tr_BSSGP_IMSI(g_pars.imsi));
Harald Welte78d8db92020-11-15 23:27:27 +01001193
Harald Welte0d5fceb2020-11-29 16:04:07 +01001194 log("DL-UNITDATA(payload_size=", i);
Harald Welte22ef5d92020-11-16 13:35:14 +01001195 f_sgsn2pcu(pdu_tx, pdu_rx);
Harald Welte78d8db92020-11-15 23:27:27 +01001196 }
1197 setverdict(pass);
1198}
1199
1200testcase TC_dl_unitdata() runs on test_CT
1201{
Daniel Willmannc879f342021-02-11 14:28:01 +01001202 f_init(60.0);
Harald Welte2ecbca82021-01-16 11:23:09 +01001203 f_start_handlers(refers(f_TC_dl_unitdata), testcasename(), 2);
Harald Welte78d8db92020-11-15 23:27:27 +01001204 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Welte78d8db92020-11-15 23:27:27 +01001205 f_cleanup();
1206}
Harald Welte92686012020-11-15 21:45:49 +01001207
Harald Welte6dc2ac42020-11-16 09:16:17 +01001208private function f_TC_ra_capability(charstring id) runs on BSSGP_ConnHdlr {
1209 var integer i;
1210
1211 for (i := 0; i < 10; i := i+1) {
1212 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RA_CAP(g_pars.tlli, { ts_RaCapRec_BSSGP });
1213 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1214 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RA_CAP(g_pars.tlli, { tr_RaCapRec_BSSGP })
1215
Harald Welte22ef5d92020-11-16 13:35:14 +01001216 f_sgsn2pcu(pdu_tx, pdu_rx);
Harald Welte6dc2ac42020-11-16 09:16:17 +01001217 }
1218 setverdict(pass);
1219}
1220testcase TC_ra_capability() runs on test_CT
1221{
Harald Welte6dc2ac42020-11-16 09:16:17 +01001222 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001223 f_start_handlers(refers(f_TC_ra_capability), testcasename(), 3);
Harald Welte6dc2ac42020-11-16 09:16:17 +01001224 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Welte6dc2ac42020-11-16 09:16:17 +01001225 f_cleanup();
1226}
1227
Daniel Willmannace3ece2020-11-16 19:53:26 +01001228private function f_TC_ra_capability_upd(charstring id) runs on BSSGP_ConnHdlr {
1229 var integer i;
1230 var OCT1 tag;
1231 for (i := 0; i < 10; i := i+1) {
1232 tag := int2oct(23 + i, 1);
1233 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RA_CAP_UPD(g_pars.tlli, tag);
1234 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1235 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RA_CAP_UPD(g_pars.tlli, tag)
1236
1237 f_pcu2sgsn(pdu_tx, pdu_rx);
1238
1239 pdu_tx := ts_BSSGP_RA_CAP_UPD_ACK(g_pars.tlli, tag, '42'O);
1240 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1241 pdu_rx := tr_BSSGP_RA_CAP_UPD_ACK(g_pars.tlli, tag, '42'O)
1242
1243 f_sgsn2pcu(pdu_tx, pdu_rx);
1244 }
1245 setverdict(pass);
1246}
1247testcase TC_ra_capability_upd() runs on test_CT
1248{
Daniel Willmannace3ece2020-11-16 19:53:26 +01001249 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001250 f_start_handlers(refers(f_TC_ra_capability_upd), testcasename(), 4);
Daniel Willmannace3ece2020-11-16 19:53:26 +01001251 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Daniel Willmannace3ece2020-11-16 19:53:26 +01001252 f_cleanup();
1253}
1254
Daniel Willmann165d6612020-11-19 14:27:29 +01001255private function f_TC_radio_status(charstring id) runs on BSSGP_ConnHdlr {
1256 var integer i;
1257 var BssgpRadioCause cause := BSSGP_RADIO_CAUSE_CONTACT_LOST;
1258 for (i := 0; i < 10; i := i+1) {
1259 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RADIO_STATUS(g_pars.tlli, cause);
1260 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1261 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RADIO_STATUS(g_pars.tlli, cause)
1262
1263 f_pcu2sgsn(pdu_tx, pdu_rx);
1264 }
1265 setverdict(pass);
1266}
1267testcase TC_radio_status() runs on test_CT
1268{
Daniel Willmann165d6612020-11-19 14:27:29 +01001269 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001270 f_start_handlers(refers(f_TC_radio_status), testcasename(), 5);
Daniel Willmann165d6612020-11-19 14:27:29 +01001271 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Daniel Willmann165d6612020-11-19 14:27:29 +01001272 f_cleanup();
1273}
1274
Harald Welte3148a962021-01-17 11:15:28 +01001275private function f_TC_radio_status_tmsi(charstring id) runs on BSSGP_ConnHdlr {
1276 var integer i;
1277 var BssgpRadioCause cause := BSSGP_RADIO_CAUSE_CONTACT_LOST;
1278 for (i := 0; i < 10; i := i+1) {
1279 var integer tmsi_int := oct2int(g_pars.p_tmsi);
1280 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RADIO_STATUS(omit, cause, tmsi_int);
1281 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1282 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RADIO_STATUS(omit, cause, tmsi_int);
1283 f_pcu2sgsn(pdu_tx, pdu_rx);
1284 }
1285 setverdict(pass);
1286}
1287testcase TC_radio_status_tmsi() runs on test_CT
1288{
1289 f_init();
1290 f_start_handlers(refers(f_TC_radio_status_tmsi), testcasename(), 5);
1291 f_cleanup();
1292}
1293
1294private function f_TC_radio_status_imsi(charstring id) runs on BSSGP_ConnHdlr {
1295 var integer i;
1296 var BssgpRadioCause cause := BSSGP_RADIO_CAUSE_CONTACT_LOST;
1297 for (i := 0; i < 10; i := i+1) {
1298 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RADIO_STATUS(omit, cause, imsi := g_pars.imsi);
1299 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1300 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RADIO_STATUS(omit, cause, imsi := g_pars.imsi);
1301 f_pcu2any_sgsn(pdu_tx, pdu_rx);
1302 }
1303 setverdict(pass);
1304}
1305testcase TC_radio_status_imsi() runs on test_CT
1306{
1307 f_init();
1308 f_start_handlers(refers(f_TC_radio_status_imsi), testcasename(), 5);
1309 f_cleanup();
1310}
1311
1312
1313
Harald Welte99ed5072021-01-15 20:38:58 +01001314private function f_suspend_one(integer sgsn_idx, integer nri_idx, integer pcu_idx, integer bvc_idx,
1315 integer suffix)
Harald Welte00963752021-01-15 20:33:11 +01001316runs on GlobalTest_CT
1317{
1318 var RoutingAreaIdentification ra_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id.ra_id;
Harald Welte99ed5072021-01-15 20:38:58 +01001319 var OCT4 p_tmsi := f_gen_tmsi(suffix, nri_v := mp_sgsn_nri[sgsn_idx][nri_idx],
1320 nri_bitlen := mp_nri_bitlength);
1321 var OCT4 tlli := f_gprs_tlli_from_tmsi(p_tmsi, TLLI_LOCAL);
Harald Welte00963752021-01-15 20:33:11 +01001322 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_SUSPEND(tlli, ra_id);
1323 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1324 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_SUSPEND(tlli, ra_id);
1325 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1326
1327 pdu_tx := ts_BSSGP_SUSPEND_ACK(tlli, ra_id, int2oct(suffix, 1));
1328 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1329 pdu_rx := tr_BSSGP_SUSPEND_ACK(tlli, ra_id, int2oct(suffix, 1));
1330 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1331
1332 pdu_tx := ts_BSSGP_SUSPEND(tlli, ra_id);
1333 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1334 pdu_rx := tr_BSSGP_SUSPEND(tlli, ra_id);
1335 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1336
1337 /* These messages are simple passed through so just also test sending NACK */
1338 pdu_tx := ts_BSSGP_SUSPEND_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1339 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1340 pdu_rx := tr_BSSGP_SUSPEND_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1341 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1342}
1343
Harald Weltec5c33732021-01-15 21:04:35 +01001344private function f_TC_suspend(integer sgsn_idx, integer nri_idx, integer pcu_idx, integer bvc_idx)
1345runs on GlobalTest_CT {
Daniel Willmannfa67f492020-11-19 15:48:05 +01001346 var integer i;
Daniel Willmann165d6612020-11-19 14:27:29 +01001347
Daniel Willmannfa67f492020-11-19 15:48:05 +01001348 for (i := 0; i < 10; i := i+1) {
Harald Weltec5c33732021-01-15 21:04:35 +01001349 f_suspend_one(sgsn_idx, nri_idx, pcu_idx, bvc_idx, suffix := i);
Daniel Willmannfa67f492020-11-19 15:48:05 +01001350 }
1351 setverdict(pass);
1352}
Harald Welte3807ed12020-11-24 19:05:22 +01001353testcase TC_suspend() runs on GlobalTest_CT
Daniel Willmannfa67f492020-11-19 15:48:05 +01001354{
Harald Weltec5c33732021-01-15 21:04:35 +01001355 var integer sgsn_idx, nri_idx;
Daniel Willmannfa67f492020-11-19 15:48:05 +01001356 f_init();
Harald Welte3807ed12020-11-24 19:05:22 +01001357 f_global_init();
Harald Weltec5c33732021-01-15 21:04:35 +01001358 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx+1) {
1359 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx+1) {
1360 f_TC_suspend(sgsn_idx, nri_idx, pcu_idx:=0, bvc_idx:=0);
1361 }
1362 }
Daniel Willmannfa67f492020-11-19 15:48:05 +01001363 f_cleanup();
1364}
Harald Welte6dc2ac42020-11-16 09:16:17 +01001365
Harald Welte99ed5072021-01-15 20:38:58 +01001366private function f_resume_one(integer sgsn_idx, integer nri_idx, integer pcu_idx, integer bvc_idx,
1367 integer suffix)
Harald Welte00963752021-01-15 20:33:11 +01001368runs on GlobalTest_CT
1369{
1370 var RoutingAreaIdentification ra_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id.ra_id;
Harald Welte99ed5072021-01-15 20:38:58 +01001371 var OCT4 p_tmsi := f_gen_tmsi(suffix, nri_v := mp_sgsn_nri[sgsn_idx][nri_idx],
1372 nri_bitlen := mp_nri_bitlength);
1373 var OCT4 tlli := f_gprs_tlli_from_tmsi(p_tmsi, TLLI_LOCAL);
Harald Welte00963752021-01-15 20:33:11 +01001374 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1375 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1376 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1377 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1378
1379 pdu_tx := ts_BSSGP_RESUME_ACK(tlli, ra_id);
1380 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1381 pdu_rx := tr_BSSGP_RESUME_ACK(tlli, ra_id);
1382 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1383
1384 pdu_tx := ts_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1385 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1386 pdu_rx := tr_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1387 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1388
1389 /* These messages are simple passed through so just also test sending NACK */
1390 pdu_tx := ts_BSSGP_RESUME_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1391 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1392 pdu_rx := tr_BSSGP_RESUME_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1393 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1394}
1395
Harald Weltec5c33732021-01-15 21:04:35 +01001396private function f_TC_resume(integer sgsn_idx, integer nri_idx, integer pcu_idx, integer bvc_idx)
1397runs on GlobalTest_CT {
Daniel Willmann087a33d2020-11-19 15:58:43 +01001398 var integer i;
1399
Daniel Willmann087a33d2020-11-19 15:58:43 +01001400 for (i := 0; i < 10; i := i+1) {
Harald Weltec5c33732021-01-15 21:04:35 +01001401 f_resume_one(sgsn_idx, nri_idx, pcu_idx, bvc_idx, suffix := i);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001402 }
1403 setverdict(pass);
1404}
Harald Welte3807ed12020-11-24 19:05:22 +01001405testcase TC_resume() runs on GlobalTest_CT
Daniel Willmann087a33d2020-11-19 15:58:43 +01001406{
Harald Weltec5c33732021-01-15 21:04:35 +01001407 var integer sgsn_idx, nri_idx;
Daniel Willmann087a33d2020-11-19 15:58:43 +01001408 f_init();
Harald Welte3807ed12020-11-24 19:05:22 +01001409 f_global_init();
Harald Weltec5c33732021-01-15 21:04:35 +01001410 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx+1) {
1411 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx+1) {
1412 f_TC_resume(sgsn_idx, nri_idx, pcu_idx:=0, bvc_idx:=0);
1413 }
1414 }
Daniel Willmann087a33d2020-11-19 15:58:43 +01001415 f_cleanup();
1416}
1417
Harald Weltef8ef0282020-11-18 12:16:59 +01001418/* test the load-sharing between multiple NS-VC on the BSS side */
1419private function f_TC_dl_ud_unidir(charstring id) runs on BSSGP_ConnHdlr {
1420 var integer i;
1421
1422 for (i := 0; i < 10; i := i+1) {
1423 var octetstring payload := f_rnd_octstring(i);
1424 var template (value) PDU_BSSGP pdu_tx :=
1425 ts_BSSGP_DL_UD(g_pars.tlli, payload, omit, ts_BSSGP_IMSI(g_pars.imsi));
Harald Welte09a1ce42021-01-16 11:18:38 +01001426 SGSN_PTP[g_pars.sgsn_idx].send(pdu_tx);
Harald Weltef8ef0282020-11-18 12:16:59 +01001427 }
1428 setverdict(pass);
1429}
Harald Welte09a1ce42021-01-16 11:18:38 +01001430
1431private function f_TC_load_sharing_dl(integer sgsn_idx) runs on test_CT_NS
Harald Weltef8ef0282020-11-18 12:16:59 +01001432{
1433 const integer num_ue := 10;
1434 var BSSGP_ConnHdlr vc_conn[num_ue];
Harald Weltef8ef0282020-11-18 12:16:59 +01001435 /* all BVC are now fully brought up. We disconnect BSSGP from NS on the BSS
1436 * side so we get the raw NsUnitdataIndication and hence observe different
1437 * NSVCI */
1438 disconnect(g_pcu[0].vc_NS:NS_SP, g_pcu[0].vc_BSSGP:BSCP);
1439 connect(g_pcu[0].vc_NS:NS_SP, self:NS);
1440
1441 /* there may still be some NS-VCs coming up? After all, the BVC-RESET succeeds after the first
1442 * of the NS-VC is ALIVE/UNBLOCKED */
1443 f_sleep(3.0);
1444
1445 /* start parallel components generating DL-UNITDATA from the SGSN side */
1446 for (var integer i:= 0; i < num_ue; i := i+1) {
Harald Welte2ecbca82021-01-16 11:23:09 +01001447 vc_conn[i] := f_start_handler(refers(f_TC_dl_ud_unidir), testcasename(),
Harald Welte09a1ce42021-01-16 11:18:38 +01001448 5+i, 30.0, sgsn_idx);
Harald Weltef8ef0282020-11-18 12:16:59 +01001449 }
1450
1451 /* now start counting all the messages that were queued before */
1452 /* TODO: We have a hard-coded assumption of 4 NS-VC in one NSE/NS-VCG here! */
1453 var ro_integer rx_count := { 0, 0, 0, 0 };
1454 timer T := 2.0;
1455 T.start;
1456 alt {
1457 [] as_NsUdiCount(0, rx_count);
1458 [] as_NsUdiCount(1, rx_count);
1459 [] as_NsUdiCount(2, rx_count);
1460 [] as_NsUdiCount(3, rx_count);
1461 [] NS.receive(NsUnitdataIndication:{0,?,?,*,*}) { repeat; } /* signaling BVC */
1462 [] NS.receive(NsStatusIndication:?) { repeat; }
1463 [] NS.receive {
Harald Welted5b7e742021-01-27 10:50:24 +01001464 f_shutdown(__FILE__, __LINE__, fail, "Rx unexpected NS");
Harald Weltef8ef0282020-11-18 12:16:59 +01001465 }
1466 [] T.timeout {
1467 }
1468 }
1469 for (var integer i := 0; i < lengthof(rx_count); i := i+1) {
1470 log("Rx on NSVCI ", mp_nsconfig_pcu[0].nsvc[i].nsvci, ": ", rx_count[i]);
1471 if (rx_count[i] == 0) {
1472 setverdict(fail, "Data not shared over all NSVC");
1473 }
1474 }
Harald Welte09a1ce42021-01-16 11:18:38 +01001475}
1476
1477testcase TC_load_sharing_dl() runs on test_CT_NS
1478{
1479 var integer sgsn_idx, nri_idx;
1480 f_init();
1481 for (sgsn_idx:=0; sgsn_idx < NUM_SGSN; sgsn_idx:=sgsn_idx+1) {
1482 f_TC_load_sharing_dl(sgsn_idx);
1483 }
Harald Weltef8ef0282020-11-18 12:16:59 +01001484 setverdict(pass);
1485}
1486private altstep as_NsUdiCount(integer nsvc_idx, inout ro_integer roi) runs on test_CT_NS {
1487 var NsUnitdataIndication udi;
1488 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[0];
1489 [] NS.receive(NsUnitdataIndication:{bvcc.bvci, g_pcu[0].cfg.nsei, mp_nsconfig_pcu[0].nsvc[nsvc_idx].nsvci, *, *}) -> value udi {
1490 roi[nsvc_idx] := roi[nsvc_idx] + 1;
1491 repeat;
1492 }
1493}
1494type component test_CT_NS extends test_CT {
1495 port NS_PT NS;
1496};
1497
1498
Harald Welte0e188242020-11-22 21:46:48 +01001499/***********************************************************************
1500 * PAGING PS procedure
1501 ***********************************************************************/
1502
1503private function f_send_paging_ps(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1504 boolean use_sig := false)
1505runs on BSSGP_ConnHdlr return template (present) PDU_BSSGP {
1506 var template (value) PDU_BSSGP pdu_tx;
1507 var template (present) PDU_BSSGP pdu_rx;
1508 /* we always specify '0' as BVCI in the templates below, as we override it with
1509 * 'p4' later anyway */
1510 pdu_rx := tr_BSSGP_PS_PAGING(0);
1511 pdu_rx.pDU_BSSGP_PAGING_PS.iMSI := tr_BSSGP_IMSI(g_pars.imsi);
1512 if (ispresent(g_pars.p_tmsi)) {
1513 pdu_tx := ts_BSSGP_PS_PAGING_PTMSI(0, g_pars.imsi, oct2int(g_pars.p_tmsi));
1514 pdu_rx.pDU_BSSGP_PAGING_PS.pTMSI := tr_BSSGP_TMSI(oct2int(g_pars.p_tmsi));
1515 } else {
1516 pdu_tx := ts_BSSGP_PS_PAGING_IMSI(0, g_pars.imsi);
1517 pdu_rx.pDU_BSSGP_PAGING_PS.pTMSI := omit;
1518 }
1519 pdu_tx.pDU_BSSGP_PAGING_PS.paging_Field4 := p4;
1520 pdu_rx.pDU_BSSGP_PAGING_PS.paging_Field4 := p4;
1521 if (use_sig == false) {
Harald Welte158becf2020-12-09 12:32:32 +01001522 SGSN_PTP[sgsn_idx].send(pdu_tx);
Harald Welte0e188242020-11-22 21:46:48 +01001523 } else {
1524 SGSN_SIG[sgsn_idx].send(pdu_tx);
1525 }
1526 return pdu_rx;
1527}
1528
1529/* send paging defined by 'p4' on given SGSN-side index (ptp or signaling) and expect one paging to arrive on
1530 * specified PCU index */
1531private function f_send_paging_ps_exp_one_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1532 boolean use_sig := false,integer pcu_idx := 0)
1533runs on BSSGP_ConnHdlr {
1534 var template (present) PDU_BSSGP exp_rx;
Daniel Willmann1a859712020-12-04 00:59:45 +01001535 var boolean test_done := false;
Harald Welte0e188242020-11-22 21:46:48 +01001536 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1537 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1538 exp_rx := f_send_paging_ps(p4, sgsn_idx, use_sig);
1539 /* Expect paging to propagate to the one BSS addressed by the BVCI only */
1540 timer T := 2.0;
1541 T.start;
1542 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001543 [not use_sig and not test_done] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001544 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001545 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001546 repeat;
1547 }
1548 [not use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
1549 setverdict(fail, "Received paging on SIGNALING BVC, expected PTP BVC");
1550 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001551 [use_sig and not test_done] PCU_SIG[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001552 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001553 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001554 repeat;
1555 }
Harald Welte158becf2020-12-09 12:32:32 +01001556 [use_sig] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001557 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1558 }
Harald Welte158becf2020-12-09 12:32:32 +01001559 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001560 setverdict(fail, "Paging received on unexpected BVC");
1561 }
1562 [] any from PCU_SIG.receive(exp_rx) {
1563 setverdict(fail, "Paging received on unexpected BVC");
1564 }
Harald Welte158becf2020-12-09 12:32:32 +01001565 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01001566 setverdict(fail, "Different Paging than expected received PTP BVC");
1567 }
1568 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1569 setverdict(fail, "Different Paging than expected on SIGNALING BVC");
1570 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001571 [not test_done] T.timeout {
1572 setverdict(fail, "Timeout waiting for paging");
1573 }
1574 [test_done] T.timeout;
Harald Welte0e188242020-11-22 21:46:48 +01001575 }
1576}
1577
Harald Welte7462a592020-11-23 22:07:07 +01001578/* send a PS-PAGING but don't expect it to show up on any PTP or SIG BVC */
1579private function f_send_paging_ps_exp_no_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1580 boolean use_sig := false)
1581runs on BSSGP_ConnHdlr {
1582 var template (present) PDU_BSSGP exp_rx;
1583 exp_rx := f_send_paging_ps(p4, sgsn_idx, use_sig);
1584 /* Expect paging to propagate to no BSS */
1585 timer T := 2.0;
1586 T.start;
1587 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001588 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte7462a592020-11-23 22:07:07 +01001589 setverdict(fail, "Paging received on unexpected BVC");
1590 }
1591 [] any from PCU_SIG.receive(exp_rx) {
1592 setverdict(fail, "Paging received on unexpected BVC");
1593 }
Harald Welte158becf2020-12-09 12:32:32 +01001594 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte7462a592020-11-23 22:07:07 +01001595 setverdict(fail, "Different Paging received on PTP BVC");
1596 }
1597 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1598 setverdict(fail, "Different Paging received on SIGNALING BVC");
1599 }
1600 [] T.timeout {
1601 setverdict(pass);
1602 }
1603 }
1604}
1605
Harald Welte0e188242020-11-22 21:46:48 +01001606private function f_TC_paging_ps_ptp_bss(charstring id) runs on BSSGP_ConnHdlr
1607{
1608 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1609 * at that BVC (cell) only, and paging all over the BSS area is not possible */
Daniel Willmann2a330672021-01-18 18:50:02 +01001610 f_send_paging_ps_exp_one_bss(ts_BssgpP4BssArea, g_pars.sgsn_idx, false, 0);
Harald Welte0e188242020-11-22 21:46:48 +01001611}
1612testcase TC_paging_ps_ptp_bss() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001613 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001614 f_start_handlers(refers(f_TC_paging_ps_ptp_bss), testcasename(), 9);
Harald Welte0e188242020-11-22 21:46:48 +01001615 f_cleanup();
1616}
1617
1618/* PS-PAGING on PTP-BVC for Location Area */
1619private function f_TC_paging_ps_ptp_lac(charstring id) runs on BSSGP_ConnHdlr
1620{
1621 var template (present) PDU_BSSGP exp_rx;
1622 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1623 * at that BVC (cell) only, and paging all over the BSS area is not possible */
Daniel Willmann2a330672021-01-18 18:50:02 +01001624 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 +01001625}
1626testcase TC_paging_ps_ptp_lac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001627 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001628 f_start_handlers(refers(f_TC_paging_ps_ptp_lac), testcasename(), 10);
Harald Welte0e188242020-11-22 21:46:48 +01001629 f_cleanup();
1630}
1631
Harald Welte7462a592020-11-23 22:07:07 +01001632/* PS-PAGING on PTP-BVC for unknown Location Area */
1633private function f_TC_paging_ps_ptp_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1634{
1635 var GSM_Types.LocationAreaIdentification unknown_la := {
1636 mcc_mnc := '567F99'H,
1637 lac := 33333
1638 };
1639 /* as it's sent on the PTP BVC, we expect it to pass even for unknown LAC */
Daniel Willmann2a330672021-01-18 18:50:02 +01001640 f_send_paging_ps_exp_one_bss(ts_BssgpP4LAC(unknown_la), g_pars.sgsn_idx, false, 0);
Harald Welte7462a592020-11-23 22:07:07 +01001641}
1642testcase TC_paging_ps_ptp_lac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001643 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001644 f_start_handlers(refers(f_TC_paging_ps_ptp_lac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001645 f_cleanup();
1646}
1647
Harald Welte0e188242020-11-22 21:46:48 +01001648/* PS-PAGING on PTP-BVC for Routeing Area */
1649private function f_TC_paging_ps_ptp_rac(charstring id) runs on BSSGP_ConnHdlr
1650{
1651 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1652 * at that BVC (cell) only, and paging all over the BSS area is not possible */
Daniel Willmann2a330672021-01-18 18:50:02 +01001653 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 +01001654}
1655testcase TC_paging_ps_ptp_rac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001656 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001657 f_start_handlers(refers(f_TC_paging_ps_ptp_rac), testcasename(), 11);
Harald Welte0e188242020-11-22 21:46:48 +01001658 f_cleanup();
1659}
1660
Harald Welte7462a592020-11-23 22:07:07 +01001661/* PS-PAGING on PTP-BVC for unknown Routeing Area */
1662private function f_TC_paging_ps_ptp_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1663{
1664 var RoutingAreaIdentification unknown_ra := {
1665 lai := {
1666 mcc_mnc := '567F99'H,
1667 lac := 33333
1668 },
1669 rac := 254
1670 };
1671 /* as it's sent on the PTP BVC, we expect it to pass even for unknown RAC */
Daniel Willmann2a330672021-01-18 18:50:02 +01001672 f_send_paging_ps_exp_one_bss(ts_BssgpP4RAC(unknown_ra), g_pars.sgsn_idx, false, 0);
Harald Welte7462a592020-11-23 22:07:07 +01001673}
1674testcase TC_paging_ps_ptp_rac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001675 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001676 f_start_handlers(refers(f_TC_paging_ps_ptp_rac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001677 f_cleanup();
1678}
1679
Harald Welte0e188242020-11-22 21:46:48 +01001680/* PS-PAGING on PTP-BVC for BVCI (one cell) */
1681private function f_TC_paging_ps_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
1682{
1683 /* this should be the normal case for MS in READY MM state after a lower layer failure */
Daniel Willmann2a330672021-01-18 18:50:02 +01001684 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 +01001685}
1686testcase TC_paging_ps_ptp_bvci() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001687 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001688 f_start_handlers(refers(f_TC_paging_ps_ptp_bvci), testcasename(), 12);
Harald Welte0e188242020-11-22 21:46:48 +01001689 f_cleanup();
1690}
1691
Harald Welteb5a04aa2021-01-16 13:04:40 +01001692
1693/* PS-PAGING on PTP-BVC for BVCI (one cell) using IMSI only (no P-TMSI allocated) */
1694testcase TC_paging_ps_ptp_bvci_imsi() runs on test_CT {
1695 f_init();
1696 f_start_handlers(refers(f_TC_paging_ps_ptp_bvci), testcasename(), 12, have_ptmsi:=false);
1697 f_cleanup();
1698}
1699
Harald Weltecf200072021-01-16 15:20:46 +01001700/* Rejected PS-PAGING on PTP-BVC for BVCI (one cell) */
1701testcase TC_paging_ps_reject_ptp_bvci() runs on test_CT {
1702 f_init();
1703 f_start_handlers(refers(f_TC_paging_ps_reject_ptp_bvci), testcasename(), 16);
1704 f_cleanup();
1705}
1706
1707/* Rejected PS-PAGING on PTP-BVC for BVCI (one cell) using IMSI only (no P-TMSI allocated) */
1708private function f_TC_paging_ps_reject_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
1709{
1710 /* first send the PS-PAGING from SGSN -> PCU */
Daniel Willmann2a330672021-01-18 18:50:02 +01001711 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 +01001712 /* then simulate the PS-PAGING-REJECT from the PCU */
1713 f_send_paging_ps_rej(use_sig:=false);
1714}
1715testcase TC_paging_ps_reject_ptp_bvci_imsi() runs on test_CT {
1716 f_init();
1717 f_start_handlers(refers(f_TC_paging_ps_reject_ptp_bvci), testcasename(), 16, have_ptmsi:=false);
1718 f_cleanup();
1719}
Harald Welteb5a04aa2021-01-16 13:04:40 +01001720
Harald Welte7462a592020-11-23 22:07:07 +01001721/* PS-PAGING on PTP-BVC for unknown BVCI */
1722private function f_TC_paging_ps_ptp_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1723{
1724 /* as it's sent on the PTP BVC, we expect it to pass even for unknown BVCI */
Daniel Willmann2a330672021-01-18 18:50:02 +01001725 f_send_paging_ps_exp_one_bss(ts_BssgpP4Bvci(33333), g_pars.sgsn_idx, false, 0);
Harald Welte7462a592020-11-23 22:07:07 +01001726}
1727testcase TC_paging_ps_ptp_bvci_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001728 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001729 f_start_handlers(refers(f_TC_paging_ps_ptp_bvci_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001730 f_cleanup();
1731}
1732
Harald Welte7595d562021-01-16 19:09:20 +01001733/* DUMMY PAGING PS on PTP BVC */
1734private function f_TC_dummy_paging_ps_ptp(charstring id) runs on BSSGP_ConnHdlr
1735{
1736 f_sgsn2pcu(ts_BSSGP_DUMMY_PAGING_PS(g_pars.imsi, omit),
1737 tr_BSSGP_DUMMY_PAGING_PS(g_pars.imsi, omit), use_sig := false);
1738 f_pcu2sgsn(ts_BSSGP_DUMMY_PAGING_PS_RESP(g_pars.imsi, 1, 5),
1739 tr_BSSGP_DUMMY_PAGING_PS_RESP(g_pars.imsi, 1, 5), use_sig := false)
1740}
1741testcase TC_dummy_paging_ps_ptp() runs on test_CT {
1742 f_init();
1743 f_start_handlers(refers(f_TC_dummy_paging_ps_ptp), testcasename(), 11);
1744 f_cleanup();
1745}
1746
Harald Welte0e188242020-11-22 21:46:48 +01001747/* altstep for expecting BSSGP PDU on signaling BVC of given pcu_idx + storing in 'roi' */
1748private altstep as_paging_sig_pcu(integer pcu_idx, template (present) PDU_BSSGP exp_rx, inout ro_integer roi)
1749runs on BSSGP_ConnHdlr {
1750[] PCU_SIG[pcu_idx].receive(exp_rx) {
1751 if (ro_integer_contains(roi, pcu_idx)) {
1752 setverdict(fail, "Received multiple paging on same SIG BVC");
1753 }
1754 roi := roi & { pcu_idx };
1755 repeat;
1756 }
Harald Welte158becf2020-12-09 12:32:32 +01001757[] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001758 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1759 }
1760[] PCU_SIG[pcu_idx].receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1761 setverdict(fail, "Different Paging than expected received SIGNALING BVC");
1762 }
Harald Welte158becf2020-12-09 12:32:32 +01001763[] PCU_PTP[pcu_idx].receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01001764 setverdict(fail, "Different Paging than expected received PTP BVC");
1765 }
1766}
1767
1768type record of default ro_default;
1769
1770/* send PS-PAGING on SIG BVC, expect it to arrive on given list of PCU indexes */
1771private function f_send_paging_ps_exp_multi(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1772 ro_integer exp_on_pcu_idx) runs on BSSGP_ConnHdlr
1773{
1774 var template (present) PDU_BSSGP exp_rx;
Daniel Willmann193e1a02021-01-17 12:55:53 +01001775 exp_rx := f_send_paging_ps(p4, sgsn_idx, true);
Harald Welte0e188242020-11-22 21:46:48 +01001776
1777 /* FIXME: make sure the relevant BVCs/BSS are connected to the ports! */
1778 var ro_default defaults := {};
1779 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1780 var default d := activate(as_paging_sig_pcu(i, exp_rx, g_roi));
1781 defaults := defaults & { d };
1782 }
1783 f_sleep(2.0);
1784 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
1785 deactivate(defaults[i]);
1786 }
1787 log("Paging received on PCU ", g_roi);
1788
1789 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1790 var boolean rx_on_i := ro_integer_contains(g_roi, i);
1791 var boolean exp_on_i := ro_integer_contains(exp_on_pcu_idx, i);
1792 if (exp_on_i and not rx_on_i) {
1793 setverdict(fail, "PS-PAGING not received on ", mp_nsconfig_pcu[i].nsei);
1794 }
1795 if (not exp_on_i and rx_on_i) {
1796 setverdict(fail, "PS-PAGING not expected but received on ", mp_nsconfig_pcu[i].nsei);
1797 }
1798 }
1799 setverdict(pass);
1800}
1801
Harald Weltecf200072021-01-16 15:20:46 +01001802/* Send PAGING-PS-REJECT on SIG BVC, expect it to arrive on the "right" SGSN */
1803private function f_send_paging_ps_rej(boolean use_sig := true, integer pcu_idx := 0) runs on BSSGP_ConnHdlr
1804{
1805 var template (value) PDU_BSSGP pdu_tx;
1806 var template (present) PDU_BSSGP exp_rx;
1807 var PDU_BSSGP pdu_rx;
1808 timer T := 5.0;
1809 var template (omit) GsmTmsi tmsi_int := omit;
1810
1811 if (ispresent(g_pars.p_tmsi)) {
1812 tmsi_int := oct2int(g_pars.p_tmsi);
1813 }
1814
1815 pdu_tx := ts_BSSGP_PAGING_PS_REJ(g_pars.imsi, 23, 42, tmsi_int);
1816 exp_rx := tr_BSSGP_PAGING_PS_REJ(g_pars.imsi, 23, 42, tmsi_int);
1817
1818 if (use_sig) {
1819 PCU_SIG[pcu_idx].send(pdu_tx);
1820 } else {
1821 PCU_PTP[pcu_idx].send(pdu_tx);
1822 }
1823 T.start;
1824 alt {
1825 [use_sig] SGSN_SIG[g_pars.sgsn_idx].receive(exp_rx) -> value pdu_rx {
1826 setverdict(pass);
1827 }
1828 [use_sig] SGSN_SIG[g_pars.sgsn_idx].receive {
1829 setverdict(fail, "Unexpected PDU on SGSN");
1830 }
1831 [use_sig] any from SGSN_SIG.receive(exp_rx) -> value pdu_rx {
1832 setverdict(fail, "PAGING-PS-REJECT arrived on wrong SGSN");
1833 }
1834 [not use_sig] SGSN_PTP[g_pars.sgsn_idx].receive(exp_rx) -> value pdu_rx {
1835 setverdict(pass);
1836 }
1837 [not use_sig] SGSN_PTP[g_pars.sgsn_idx].receive {
1838 setverdict(fail, "Unexpected PDU on SGSN");
1839 }
1840 [not use_sig] any from SGSN_PTP.receive(exp_rx) -> value pdu_rx {
1841 setverdict(fail, "PAGING-PS-REJECT arrived on wrong SGSN");
1842 }
1843 [] T.timeout {
1844 setverdict(fail, "Timeout waiting for PAGING-PS-REJECT");
1845 }
1846 }
1847}
1848
Harald Welte0e188242020-11-22 21:46:48 +01001849/* PS-PAGING on SIG-BVC for BSS Area */
1850private function f_TC_paging_ps_sig_bss(charstring id) runs on BSSGP_ConnHdlr
1851{
1852 /* we expect the paging to arrive on all three NSE */
Daniel Willmann43320442021-01-17 14:07:05 +01001853 f_send_paging_ps_exp_multi(ts_BssgpP4BssArea, g_pars.sgsn_idx, {0, 1, 2});
Harald Welte0e188242020-11-22 21:46:48 +01001854}
1855testcase TC_paging_ps_sig_bss() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001856 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001857 f_start_handlers(refers(f_TC_paging_ps_sig_bss), testcasename(), 13);
Harald Welte0e188242020-11-22 21:46:48 +01001858 f_cleanup();
1859}
1860
1861/* PS-PAGING on SIG-BVC for Location Area */
1862private function f_TC_paging_ps_sig_lac(charstring id) runs on BSSGP_ConnHdlr
1863{
Daniel Willmann2c9300f2020-12-01 10:54:08 +01001864 /* The first LAC (13135) is shared by all three NSEs */
Daniel Willmann43320442021-01-17 14:07:05 +01001865 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 +01001866 /* Reset state */
1867 g_roi := {};
1868 /* Make LAC (13300) available on pcu index 2 */
1869 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
Daniel Willmann43320442021-01-17 14:07:05 +01001870 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 +01001871}
1872testcase TC_paging_ps_sig_lac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001873 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001874 f_start_handlers(refers(f_TC_paging_ps_sig_lac), testcasename(), 14);
Harald Welte0e188242020-11-22 21:46:48 +01001875 f_cleanup();
1876}
1877
Harald Welte7462a592020-11-23 22:07:07 +01001878/* PS-PAGING on SIG-BVC for unknown Location Area */
1879private function f_TC_paging_ps_sig_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1880{
1881 var GSM_Types.LocationAreaIdentification unknown_la := {
1882 mcc_mnc := '567F99'H,
1883 lac := 33333
1884 };
Daniel Willmann2a330672021-01-18 18:50:02 +01001885 f_send_paging_ps_exp_no_bss(ts_BssgpP4LAC(unknown_la), g_pars.sgsn_idx, true);
Harald Welte7462a592020-11-23 22:07:07 +01001886}
1887testcase TC_paging_ps_sig_lac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001888 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001889 f_start_handlers(refers(f_TC_paging_ps_sig_lac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001890 f_cleanup();
1891}
1892
Harald Welte0e188242020-11-22 21:46:48 +01001893/* PS-PAGING on SIG-BVC for Routeing Area */
1894private function f_TC_paging_ps_sig_rac(charstring id) runs on BSSGP_ConnHdlr
1895{
Daniel Willmann2c9300f2020-12-01 10:54:08 +01001896 /* Only PCU index 0 has a matching BVC with the RA ID */
Daniel Willmann43320442021-01-17 14:07:05 +01001897 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 +01001898 g_roi := {};
1899 /* PCU index 1 and 2 have a matching BVC with the RA ID */
Daniel Willmann43320442021-01-17 14:07:05 +01001900 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 +01001901 g_roi := {};
1902 /* PCU index 2 has two matching BVCs with the RA ID */
1903 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
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, {2});
Harald Welte0e188242020-11-22 21:46:48 +01001905}
1906testcase TC_paging_ps_sig_rac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001907 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001908 f_start_handlers(refers(f_TC_paging_ps_sig_rac), testcasename(), 15);
Harald Welte0e188242020-11-22 21:46:48 +01001909 f_cleanup();
1910}
1911
Harald Welte7462a592020-11-23 22:07:07 +01001912/* PS-PAGING on SIG-BVC for unknown Routeing Area */
1913private function f_TC_paging_ps_sig_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1914{
1915 var RoutingAreaIdentification unknown_ra := {
1916 lai := {
1917 mcc_mnc := '567F99'H,
1918 lac := 33333
1919 },
1920 rac := 254
1921 };
Daniel Willmann2a330672021-01-18 18:50:02 +01001922 f_send_paging_ps_exp_no_bss(ts_BssgpP4RAC(unknown_ra), g_pars.sgsn_idx, true);
Harald Welte7462a592020-11-23 22:07:07 +01001923}
1924testcase TC_paging_ps_sig_rac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001925 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001926 f_start_handlers(refers(f_TC_paging_ps_sig_rac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001927 f_cleanup();
1928}
1929
Harald Welte0e188242020-11-22 21:46:48 +01001930/* PS-PAGING on SIG-BVC for BVCI (one cell) */
1931private function f_TC_paging_ps_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
1932{
Daniel Willmann43320442021-01-17 14:07:05 +01001933 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 +01001934}
1935testcase TC_paging_ps_sig_bvci() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001936 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001937 f_start_handlers(refers(f_TC_paging_ps_sig_bvci), testcasename(), 16);
Harald Welte0e188242020-11-22 21:46:48 +01001938 f_cleanup();
1939}
1940
Harald Welteb5a04aa2021-01-16 13:04:40 +01001941/* PS-PAGING on SIG-BVC for BVCI (one cell) using IMSI only (no P-TMSI allocated) */
1942testcase TC_paging_ps_sig_bvci_imsi() runs on test_CT {
1943 f_init();
1944 f_start_handlers(refers(f_TC_paging_ps_sig_bvci), testcasename(), 16, have_ptmsi:=false);
1945 f_cleanup();
1946}
1947
Harald Weltecf200072021-01-16 15:20:46 +01001948/* Rejected PS-PAGING on SIG-BVC for BVCI (one cell) */
1949private function f_TC_paging_ps_reject_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
1950{
1951 /* first send the PS-PAGING from SGSN -> PCU */
Daniel Willmann43320442021-01-17 14:07:05 +01001952 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 +01001953 /* then simulate the PS-PAGING-REJECT from the PCU */
1954 f_send_paging_ps_rej(use_sig:=true);
1955
1956}
1957testcase TC_paging_ps_reject_sig_bvci() runs on test_CT {
1958 f_init();
1959 f_start_handlers(refers(f_TC_paging_ps_reject_sig_bvci), testcasename(), 16);
1960 f_cleanup();
1961}
1962
1963/* Rejected PS-PAGING on SIG-BVC for BVCI (one cell) using IMSI only (no P-TMSI allocated) */
1964testcase TC_paging_ps_reject_sig_bvci_imsi() runs on test_CT {
1965 f_init();
1966 f_start_handlers(refers(f_TC_paging_ps_reject_sig_bvci), testcasename(), 16, have_ptmsi:=false);
1967 f_cleanup();
1968}
1969
Harald Welte7462a592020-11-23 22:07:07 +01001970/* PS-PAGING on SIG-BVC for unknown BVCI */
1971private function f_TC_paging_ps_sig_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1972{
Daniel Willmann2a330672021-01-18 18:50:02 +01001973 f_send_paging_ps_exp_no_bss(ts_BssgpP4Bvci(33333), g_pars.sgsn_idx, true);
Harald Welte7462a592020-11-23 22:07:07 +01001974}
1975testcase TC_paging_ps_sig_bvci_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001976 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001977 f_start_handlers(refers(f_TC_paging_ps_sig_bvci_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001978 f_cleanup();
1979}
1980
Harald Welte7595d562021-01-16 19:09:20 +01001981/* DUMMY PAGING PS on SIG BVC */
1982private function f_TC_dummy_paging_ps_sig(charstring id) runs on BSSGP_ConnHdlr
1983{
1984 f_sgsn2pcu(ts_BSSGP_DUMMY_PAGING_PS(g_pars.imsi, omit),
1985 tr_BSSGP_DUMMY_PAGING_PS(g_pars.imsi, omit), use_sig := true);
1986 f_pcu2sgsn(ts_BSSGP_DUMMY_PAGING_PS_RESP(g_pars.imsi, 1, 5),
1987 tr_BSSGP_DUMMY_PAGING_PS_RESP(g_pars.imsi, 1, 5), use_sig := true)
1988}
1989testcase TC_dummy_paging_ps_sig() runs on test_CT {
1990 f_init();
1991 f_start_handlers(refers(f_TC_dummy_paging_ps_sig), testcasename(), 11);
1992 f_cleanup();
1993}
1994
Harald Welte7462a592020-11-23 22:07:07 +01001995
Harald Welte0e188242020-11-22 21:46:48 +01001996
1997/***********************************************************************
1998 * PAGING CS procedure
1999 ***********************************************************************/
2000
2001private function f_send_paging_cs(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
2002 boolean use_sig := false)
2003runs on BSSGP_ConnHdlr return template (present) PDU_BSSGP {
2004 var template (value) PDU_BSSGP pdu_tx;
2005 var template (present) PDU_BSSGP pdu_rx;
2006 /* we always specify '0' as BVCI in the templates below, as we override it with
2007 * 'p4' later anyway */
2008 pdu_rx := tr_BSSGP_CS_PAGING(0);
2009 pdu_rx.pDU_BSSGP_PAGING_CS.iMSI := tr_BSSGP_IMSI(g_pars.imsi);
2010 if (ispresent(g_pars.p_tmsi)) {
2011 pdu_tx := ts_BSSGP_CS_PAGING_PTMSI(0, g_pars.imsi, oct2int(g_pars.p_tmsi));
2012 pdu_rx.pDU_BSSGP_PAGING_CS.tMSI := tr_BSSGP_TMSI(oct2int(g_pars.p_tmsi));
2013 } else {
2014 pdu_tx := ts_BSSGP_CS_PAGING_IMSI(0, g_pars.imsi);
2015 pdu_rx.pDU_BSSGP_PAGING_CS.tMSI := omit;
2016 }
2017 pdu_tx.pDU_BSSGP_PAGING_CS.paging_Field4 := p4;
2018 pdu_rx.pDU_BSSGP_PAGING_CS.paging_Field4 := p4;
2019 if (use_sig == false) {
Harald Welte158becf2020-12-09 12:32:32 +01002020 SGSN_PTP[sgsn_idx].send(pdu_tx);
Harald Welte0e188242020-11-22 21:46:48 +01002021 } else {
2022 SGSN_SIG[sgsn_idx].send(pdu_tx);
2023 }
2024 return pdu_rx;
2025}
2026
2027/* send paging defined by 'p4' on given SGSN-side index (ptp or signaling) and expect one paging to arrive on
2028 * specified PCU index */
2029private function f_send_paging_cs_exp_one_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
2030 boolean use_sig := false,integer pcu_idx := 0)
2031runs on BSSGP_ConnHdlr {
2032 var template (present) PDU_BSSGP exp_rx;
Daniel Willmann1a859712020-12-04 00:59:45 +01002033 var boolean test_done := false;
Harald Welte0e188242020-11-22 21:46:48 +01002034 /* doesn't really make sense: Sending to a single BVCI means the message ends up
2035 * at that BVC (cell) only, and paging all over the BSS area is not possible */
2036 exp_rx := f_send_paging_cs(p4, sgsn_idx, use_sig);
2037 /* Expect paging to propagate to the one BSS addressed by the BVCI only */
2038 timer T := 2.0;
2039 T.start;
2040 alt {
Harald Welte158becf2020-12-09 12:32:32 +01002041 [not use_sig and not test_done] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01002042 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01002043 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01002044 repeat;
2045 }
2046 [not use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
2047 setverdict(fail, "Received paging on SIGNALING BVC, expected PTP BVC");
2048 }
Daniel Willmann1a859712020-12-04 00:59:45 +01002049 [use_sig and not test_done] PCU_SIG[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01002050 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01002051 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01002052 repeat;
2053 }
Harald Welte158becf2020-12-09 12:32:32 +01002054 [use_sig] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01002055 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
2056 }
Harald Welte158becf2020-12-09 12:32:32 +01002057 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01002058 setverdict(fail, "Paging received on unexpected BVC");
2059 }
2060 [] any from PCU_SIG.receive(exp_rx) {
2061 setverdict(fail, "Paging received on unexpected BVC");
2062 }
Harald Welte158becf2020-12-09 12:32:32 +01002063 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01002064 setverdict(fail, "Different Paging than expected received PTP BVC");
2065 }
2066 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
2067 setverdict(fail, "Different Paging than expected on SIGNALING BVC");
2068 }
Daniel Willmann1a859712020-12-04 00:59:45 +01002069 [not test_done] T.timeout {
2070 setverdict(fail, "Timeout while waiting for paging")
2071 }
2072 [test_done] T.timeout;
Harald Welte0e188242020-11-22 21:46:48 +01002073 }
2074}
2075
Harald Welte7462a592020-11-23 22:07:07 +01002076/* send a CS-PAGING but don't expect it to show up on any PTP or SIG BVC */
2077private function f_send_paging_cs_exp_no_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
2078 boolean use_sig := false)
2079runs on BSSGP_ConnHdlr {
2080 var template (present) PDU_BSSGP exp_rx;
2081 exp_rx := f_send_paging_cs(p4, sgsn_idx, use_sig);
2082 /* Expect paging to propagate to no BSS */
2083 timer T := 2.0;
2084 T.start;
2085 alt {
Harald Welte158becf2020-12-09 12:32:32 +01002086 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte7462a592020-11-23 22:07:07 +01002087 setverdict(fail, "Paging received on unexpected BVC");
2088 }
2089 [] any from PCU_SIG.receive(exp_rx) {
2090 setverdict(fail, "Paging received on unexpected BVC");
2091 }
Harald Welte158becf2020-12-09 12:32:32 +01002092 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
Harald Welte7462a592020-11-23 22:07:07 +01002093 setverdict(fail, "Different Paging received on PTP BVC");
2094 }
2095 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
2096 setverdict(fail, "Different Paging received on SIGNALING BVC");
2097 }
2098 [] T.timeout {
2099 setverdict(pass);
2100 }
2101 }
2102}
2103
Harald Welte0e188242020-11-22 21:46:48 +01002104private function f_TC_paging_cs_ptp_bss(charstring id) runs on BSSGP_ConnHdlr
2105{
2106 /* doesn't really make sense: Sending to a single BVCI means the message ends up
2107 * at that BVC (cell) only, and paging all over the BSS area is not possible */
2108 f_send_paging_cs_exp_one_bss(ts_BssgpP4BssArea, 0, false, 0);
2109}
2110testcase TC_paging_cs_ptp_bss() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002111 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002112 f_start_handlers(refers(f_TC_paging_cs_ptp_bss), testcasename(), 17);
Harald Welte0e188242020-11-22 21:46:48 +01002113 f_cleanup();
2114}
2115
2116/* CS-PAGING on PTP-BVC for Location Area */
2117private function f_TC_paging_cs_ptp_lac(charstring id) runs on BSSGP_ConnHdlr
2118{
2119 var template (present) PDU_BSSGP exp_rx;
2120 /* doesn't really make sense: Sending to a single BVCI means the message ends up
2121 * at that BVC (cell) only, and paging all over the BSS area is not possible */
2122 f_send_paging_cs_exp_one_bss(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, false, 0);
2123}
2124testcase TC_paging_cs_ptp_lac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002125 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002126 f_start_handlers(refers(f_TC_paging_cs_ptp_lac), testcasename(), 18);
Harald Welte0e188242020-11-22 21:46:48 +01002127 f_cleanup();
2128}
2129
Harald Welte7462a592020-11-23 22:07:07 +01002130/* CS-PAGING on PTP-BVC for unknown Location Area */
2131private function f_TC_paging_cs_ptp_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
2132{
2133 var GSM_Types.LocationAreaIdentification unknown_la := {
2134 mcc_mnc := '567F99'H,
2135 lac := 33333
2136 };
2137 /* as it's sent on the PTP BVC, we expect it to pass even for unknown LAC */
2138 f_send_paging_cs_exp_one_bss(ts_BssgpP4LAC(unknown_la), 0, false, 0);
2139}
2140testcase TC_paging_cs_ptp_lac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002141 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002142 f_start_handlers(refers(f_TC_paging_cs_ptp_lac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002143 f_cleanup();
2144}
2145
Harald Welte0e188242020-11-22 21:46:48 +01002146/* CS-PAGING on PTP-BVC for Routeing Area */
2147private function f_TC_paging_cs_ptp_rac(charstring id) runs on BSSGP_ConnHdlr
2148{
2149 /* doesn't really make sense: Sending to a single BVCI means the message ends up
2150 * at that BVC (cell) only, and paging all over the BSS area is not possible */
2151 f_send_paging_cs_exp_one_bss(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, false, 0);
2152}
2153testcase TC_paging_cs_ptp_rac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002154 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002155 f_start_handlers(refers(f_TC_paging_cs_ptp_rac), testcasename(), 19);
Harald Welte0e188242020-11-22 21:46:48 +01002156 f_cleanup();
2157}
2158
Harald Welte7462a592020-11-23 22:07:07 +01002159/* CS-PAGING on PTP-BVC for unknown Routeing Area */
2160private function f_TC_paging_cs_ptp_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
2161{
2162 var RoutingAreaIdentification unknown_ra := {
2163 lai := {
2164 mcc_mnc := '567F99'H,
2165 lac := 33333
2166 },
2167 rac := 254
2168 };
2169 /* as it's sent on the PTP BVC, we expect it to pass even for unknown RAC */
2170 f_send_paging_cs_exp_one_bss(ts_BssgpP4RAC(unknown_ra), 0, false, 0);
2171}
2172testcase TC_paging_cs_ptp_rac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002173 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002174 f_start_handlers(refers(f_TC_paging_cs_ptp_rac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002175 f_cleanup();
2176}
2177
Harald Welte0e188242020-11-22 21:46:48 +01002178/* CS-PAGING on PTP-BVC for BVCI (one cell) */
2179private function f_TC_paging_cs_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
2180{
2181 /* this should be the normal case for MS in READY MM state after a lower layer failure */
2182 f_send_paging_cs_exp_one_bss(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, false, 0);
2183}
2184testcase TC_paging_cs_ptp_bvci() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002185 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002186 f_start_handlers(refers(f_TC_paging_cs_ptp_bvci), testcasename(), 20);
Harald Welte0e188242020-11-22 21:46:48 +01002187 f_cleanup();
2188}
2189
Harald Welte7462a592020-11-23 22:07:07 +01002190/* CS-PAGING on PTP-BVC for unknown BVCI */
2191private function f_TC_paging_cs_ptp_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
2192{
2193 /* as it's sent on the PTP BVC, we expect it to pass even for unknown BVCI */
2194 f_send_paging_cs_exp_one_bss(ts_BssgpP4Bvci(33333), 0, false, 0);
2195}
2196testcase TC_paging_cs_ptp_bvci_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002197 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002198 f_start_handlers(refers(f_TC_paging_cs_ptp_bvci_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002199 f_cleanup();
2200}
2201
Harald Welte0e188242020-11-22 21:46:48 +01002202/* send CS-PAGING on SIG BVC, expect it to arrive on given list of PCU indexes */
2203private function f_send_paging_cs_exp_multi(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
2204 ro_integer exp_on_pcu_idx) runs on BSSGP_ConnHdlr
2205{
2206 var template (present) PDU_BSSGP exp_rx;
2207 exp_rx := f_send_paging_cs(p4, 0, true);
2208
2209 /* FIXME: make sure the relevant BVCs/BSS are connected to the ports! */
2210 var ro_default defaults := {};
2211 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
2212 var default d := activate(as_paging_sig_pcu(i, exp_rx, g_roi));
2213 defaults := defaults & { d };
2214 }
2215 f_sleep(2.0);
2216 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2217 deactivate(defaults[i]);
2218 }
2219 log("Paging received on PCU ", g_roi);
2220
2221 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
2222 var boolean rx_on_i := ro_integer_contains(g_roi, i);
2223 var boolean exp_on_i := ro_integer_contains(exp_on_pcu_idx, i);
2224 if (exp_on_i and not rx_on_i) {
2225 setverdict(fail, "PS-PAGING not received on ", mp_nsconfig_pcu[i].nsei);
2226 }
2227 if (not exp_on_i and rx_on_i) {
2228 setverdict(fail, "PS-PAGING not expected but received on ", mp_nsconfig_pcu[i].nsei);
2229 }
2230 }
2231 setverdict(pass);
2232}
2233
2234/* CS-PAGING on SIG-BVC for BSS Area */
2235private function f_TC_paging_cs_sig_bss(charstring id) runs on BSSGP_ConnHdlr
2236{
2237 /* we expect the paging to arrive on all three NSE */
2238 f_send_paging_cs_exp_multi(ts_BssgpP4BssArea, 0, {0, 1, 2});
2239}
2240testcase TC_paging_cs_sig_bss() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002241 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002242 f_start_handlers(refers(f_TC_paging_cs_sig_bss), testcasename(), 13);
Harald Welte0e188242020-11-22 21:46:48 +01002243 f_cleanup();
2244}
2245
2246/* CS-PAGING on SIG-BVC for Location Area */
2247private function f_TC_paging_cs_sig_lac(charstring id) runs on BSSGP_ConnHdlr
2248{
Daniel Willmannd4fb73c2020-12-07 13:57:17 +01002249 /* The first LAC (13135) is shared by all three NSEs */
2250 f_send_paging_cs_exp_multi(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, {0, 1, 2});
2251 /* Reset state */
2252 g_roi := {};
2253 /* Make LAC (13300) available on pcu index 2 */
2254 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
2255 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 +01002256}
2257testcase TC_paging_cs_sig_lac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002258 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002259 f_start_handlers(refers(f_TC_paging_cs_sig_lac), testcasename(), 14);
Harald Welte0e188242020-11-22 21:46:48 +01002260 f_cleanup();
2261}
2262
Harald Welte7462a592020-11-23 22:07:07 +01002263/* CS-PAGING on SIG-BVC for unknown Location Area */
2264private function f_TC_paging_cs_sig_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
2265{
2266 var GSM_Types.LocationAreaIdentification unknown_la := {
2267 mcc_mnc := '567F99'H,
2268 lac := 33333
2269 };
2270 f_send_paging_cs_exp_no_bss(ts_BssgpP4LAC(unknown_la), 0, true);
2271}
2272testcase TC_paging_cs_sig_lac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002273 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002274 f_start_handlers(refers(f_TC_paging_cs_sig_lac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002275 f_cleanup();
2276}
2277
Harald Welte0e188242020-11-22 21:46:48 +01002278/* CS-PAGING on SIG-BVC for Routeing Area */
2279private function f_TC_paging_cs_sig_rac(charstring id) runs on BSSGP_ConnHdlr
2280{
Daniel Willmannd4fb73c2020-12-07 13:57:17 +01002281 /* Only PCU index 0 has a matching BVC with the RA ID */
Harald Welte0e188242020-11-22 21:46:48 +01002282 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 +01002283 g_roi := {};
2284 /* PCU index 1 and 2 have a matching BVC with the RA ID */
2285 f_send_paging_cs_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[2].cell_id.ra_id), 0, {1, 2});
2286 g_roi := {};
2287 /* PCU index 2 has two matching BVCs with the RA ID */
2288 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
2289 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 +01002290}
2291testcase TC_paging_cs_sig_rac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002292 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002293 f_start_handlers(refers(f_TC_paging_cs_sig_rac), testcasename(), 15);
Harald Welte0e188242020-11-22 21:46:48 +01002294 f_cleanup();
2295}
2296
Harald Welte7462a592020-11-23 22:07:07 +01002297/* CS-PAGING on SIG-BVC for unknown Routeing Area */
2298private function f_TC_paging_cs_sig_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
2299{
2300 var RoutingAreaIdentification unknown_ra := {
2301 lai := {
2302 mcc_mnc := '567F99'H,
2303 lac := 33333
2304 },
2305 rac := 254
2306 };
2307 f_send_paging_cs_exp_no_bss(ts_BssgpP4RAC(unknown_ra), 0, true);
2308}
2309testcase TC_paging_cs_sig_rac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002310 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002311 f_start_handlers(refers(f_TC_paging_cs_sig_rac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002312 f_cleanup();
2313}
2314
Harald Welte0e188242020-11-22 21:46:48 +01002315/* CS-PAGING on SIG-BVC for BVCI (one cell) */
2316private function f_TC_paging_cs_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
2317{
2318 f_send_paging_cs_exp_multi(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, {0});
2319}
2320testcase TC_paging_cs_sig_bvci() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002321 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002322 f_start_handlers(refers(f_TC_paging_cs_sig_bvci), testcasename(), 16);
Harald Welte0e188242020-11-22 21:46:48 +01002323 f_cleanup();
2324}
2325
Harald Welte7462a592020-11-23 22:07:07 +01002326/* CS-PAGING on SIG-BVC for unknown BVCI */
2327private function f_TC_paging_cs_sig_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
2328{
2329 f_send_paging_cs_exp_no_bss(ts_BssgpP4Bvci(33333), 0, true);
2330}
2331testcase TC_paging_cs_sig_bvci_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002332 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002333 f_start_handlers(refers(f_TC_paging_cs_sig_bvci_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002334 f_cleanup();
2335}
2336
Harald Welte4f91c3b2020-12-09 12:25:51 +01002337/***********************************************************************
2338 * FLUSH-LL procedure
2339 ***********************************************************************/
2340
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002341private function f_TC_flush_ll(charstring id) runs on BSSGP_ConnHdlr {
2342 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
2343 var integer i;
2344 for (i := 0; i < 10; i := i+1) {
2345 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_FLUSH_LL(g_pars.tlli, bvci, bvci_new := bvci);
2346 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2347 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_FLUSH_LL(g_pars.tlli, bvci, bvci_new := bvci);
2348
2349 f_sgsn2pcu(pdu_tx, pdu_rx, use_sig := true);
2350
2351 pdu_tx := ts_BSSGP_FLUSH_LL_ACK(g_pars.tlli, int2oct(0, 1), 23, bvci_new := bvci);
2352 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2353 pdu_rx := tr_BSSGP_FLUSH_LL_ACK(g_pars.tlli, int2oct(0, 1), 23, bvci_new := bvci);
2354
2355 f_pcu2sgsn(pdu_tx, pdu_rx, use_sig := true);
2356 }
2357 setverdict(pass);
2358}
2359testcase TC_flush_ll() runs on test_CT
2360{
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002361 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002362 f_start_handlers(refers(f_TC_flush_ll), testcasename(), 6);
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002363 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002364 f_cleanup();
2365}
Harald Welte6dc2ac42020-11-16 09:16:17 +01002366
Harald Welte4f91c3b2020-12-09 12:25:51 +01002367/***********************************************************************
2368 * SGSN-INVOKE-TRACE procedure
2369 ***********************************************************************/
2370
Harald Weltef8e5c5d2020-11-27 22:37:23 +01002371private altstep as_bssgp_g_pcu_count(integer pcu_idx, template (present) PDU_BSSGP exp_rx, inout ro_integer roi)
2372runs on GlobalTest_CT {
2373[] G_PCU[pcu_idx].receive(exp_rx) from g_pcu[pcu_idx].vc_BSSGP {
2374 if (ro_integer_contains(roi, pcu_idx)) {
2375 setverdict(fail, "Received multiple on same SIG BVC");
2376 }
2377 roi := roi & { pcu_idx };
2378 repeat;
2379 }
2380}
2381/* send a INVOKE-TRACE from SGSN and expect to receive a copy on each NSE */
2382testcase TC_trace() runs on GlobalTest_CT
2383{
2384 var BSSGP_ConnHdlr vc_conn;
2385 f_init();
2386 f_global_init();
2387
2388 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_INVOKE_TRACE('23'O, '4321'O);
2389 var template (present) PDU_BSSGP exp_rx := ts_BSSGP_INVOKE_TRACE('23'O, '4321'O);
2390
2391 var ro_default defaults := {};
2392 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2393 activate(as_bssgp_g_pcu_count(i, exp_rx, g_roi));
2394 }
2395 G_SGSN[0].send(pdu_tx);
2396 f_sleep(2.0);
2397 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2398 deactivate(defaults[i]);
2399 }
2400
2401 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2402 if (not ro_integer_contains(g_roi, i)) {
2403 setverdict(fail, "Failed to receive TRACE on PCU index ", i);
2404 }
2405 }
2406 setverdict(pass);
2407
2408 f_cleanup();
2409}
2410
Harald Welte4f91c3b2020-12-09 12:25:51 +01002411/***********************************************************************
2412 * LLC-DISCARDED procedure
2413 ***********************************************************************/
2414
Harald Weltec0351d12020-11-27 22:49:02 +01002415private function f_TC_llc_discarded(charstring id) runs on BSSGP_ConnHdlr {
2416 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
2417
2418 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_LLC_DISCARDED(g_pars.tlli, 23, bvci, 2342);
2419 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2420 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_LLC_DISCARDED(g_pars.tlli, 23, bvci, 2342);
2421
2422 f_pcu2sgsn(pdu_tx, pdu_rx, use_sig := true);
2423
2424 setverdict(pass);
2425}
2426/* Send a LLC-DISCARDED from BSS side and expect it to show up on SGSN (SIG BVC) */
2427testcase TC_llc_discarded() runs on test_CT
2428{
Harald Weltec0351d12020-11-27 22:49:02 +01002429 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002430 f_start_handlers(refers(f_TC_llc_discarded), testcasename(), 6);
Harald Weltec0351d12020-11-27 22:49:02 +01002431 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Weltec0351d12020-11-27 22:49:02 +01002432 f_cleanup();
2433}
2434
Harald Welte4f91c3b2020-12-09 12:25:51 +01002435/***********************************************************************
2436 * OVERLOAD procedure
2437 ***********************************************************************/
2438
Harald Weltef20af412020-11-28 16:11:11 +01002439/* Send an OVERLOAD from SGSN side and expect it to show up on each PCU (SIG BVC) */
2440testcase TC_overload() runs on GlobalTest_CT
2441{
2442 f_init();
2443 f_global_init();
2444
2445 var template (value) PDU_BSSGP pdu_tx := ts_OVERLOAD('1'B);
2446 var template (present) PDU_BSSGP exp_rx := tr_OVERLOAD('1'B);
2447
2448 var ro_default defaults := {};
2449 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2450 activate(as_bssgp_g_pcu_count(i, exp_rx, g_roi));
2451 }
2452 G_SGSN[0].send(pdu_tx);
2453 f_sleep(2.0);
2454 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2455 deactivate(defaults[i]);
2456 }
2457
2458 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2459 if (not ro_integer_contains(g_roi, i)) {
2460 setverdict(fail, "Failed to receive OVERLOAD on PCU index ", i);
2461 }
2462 }
2463 setverdict(pass);
2464
2465 f_cleanup();
2466}
2467
Harald Welte4f91c3b2020-12-09 12:25:51 +01002468/***********************************************************************
2469 * BVC-BLOCK / BVC-UNBLOCK procedure
2470 ***********************************************************************/
2471
Harald Welte239aa502020-11-24 23:14:20 +01002472private function f_block_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2473{
2474 var BSSGP_BVC_CT bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2475 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2476 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2477
2478 SGSN_MGMT.clear;
2479 PCU_MGMT.clear;
2480
2481 /* block the PTP BVC from the PCU side */
2482 PCU_MGMT.send(BssgpBlockRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to bvc_ct;
2483 /* expect state on both PCU and SGSN side to change */
2484 interleave {
2485 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_BLOCKED)) from bvc_ct;
Harald Welte572b0172021-03-30 13:19:56 +02002486 [] SGSN_MGMT.receive(tr_BssgpStsInd(mp_nsconfig_sgsn[0].nsei, bvc_cfg.bvci, BVC_S_BLOCKED));
2487 [] SGSN_MGMT.receive(tr_BssgpStsInd(mp_nsconfig_sgsn[1].nsei, bvc_cfg.bvci, BVC_S_BLOCKED));
2488 /* Doesn't auto-scale with NUM_SGSN */
Harald Welte239aa502020-11-24 23:14:20 +01002489 }
2490 setverdict(pass);
2491}
2492testcase TC_bvc_block_ptp() runs on test_CT
2493{
2494 f_init();
2495 f_sleep(1.0);
2496 f_block_ptp_bvc_from_pcu(0, 0);
2497 f_cleanup();
2498}
2499
2500private function f_unblock_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2501{
2502 var BSSGP_BVC_CT bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2503 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2504 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2505
2506 SGSN_MGMT.clear;
2507 PCU_MGMT.clear;
2508
2509 /* block the PTP BVC from the PCU side */
2510 PCU_MGMT.send(BssgpUnblockRequest:{}) to bvc_ct;
2511 /* expect state on both PCU and SGSN side to change */
2512 interleave {
2513 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_UNBLOCKED)) from bvc_ct;
Harald Welte572b0172021-03-30 13:19:56 +02002514 [] SGSN_MGMT.receive(tr_BssgpStsInd(mp_nsconfig_sgsn[0].nsei, bvc_cfg.bvci, BVC_S_UNBLOCKED));
2515 [] SGSN_MGMT.receive(tr_BssgpStsInd(mp_nsconfig_sgsn[1].nsei, bvc_cfg.bvci, BVC_S_UNBLOCKED));
2516 /* Doesn't auto-scale with NUM_SGSN */
Harald Welte239aa502020-11-24 23:14:20 +01002517 }
2518 setverdict(pass);
2519}
2520testcase TC_bvc_unblock_ptp() runs on test_CT
2521{
2522 f_init();
2523 f_sleep(1.0);
2524 f_block_ptp_bvc_from_pcu(0, 0);
2525 f_sleep(1.0);
2526 f_unblock_ptp_bvc_from_pcu(0, 0);
2527 f_cleanup();
2528}
2529
Harald Welte4f91c3b2020-12-09 12:25:51 +01002530/***********************************************************************
2531 * BVC-RESET procedure
2532 ***********************************************************************/
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002533private altstep as_count_bvc_reset(integer sgsn_idx, BssgpBvci bvci, inout roro_integer roroi)
2534runs on test_CT {
2535 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(sgsn_idx, bvci);
2536 [] SGSN_MGMT.receive(BssgpResetIndication:{bvci}) from sgsn_bvc_ct {
2537 roroi[sgsn_idx] := roroi[sgsn_idx] & { bvci };
2538 repeat;
2539 }
2540}
Harald Welte60a8ec72020-11-25 17:12:53 +01002541private altstep as_ignore_status(BSSGP_BVC_MGMT_PT pt) {
2542[] pt.receive(BssgpStatusIndication:?) { repeat; }
2543}
2544private function f_get_sgsn_bvc_ct(integer sgsn_idx, BssgpBvci bvci) runs on test_CT return BSSGP_BVC_CT {
2545 for (var integer i := 0; i < lengthof(g_sgsn[sgsn_idx].cfg.bvc); i := i+1) {
2546 if (g_sgsn[sgsn_idx].cfg.bvc[i].bvci == bvci) {
2547 return g_sgsn[sgsn_idx].vc_BSSGP_BVC[i];
2548 }
2549 }
2550 return null;
2551}
2552private function f_reset_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2553{
2554 var BSSGP_BVC_CT pcu_bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2555 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2556 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002557 var ro_default defaults;
2558 var integer i;
Harald Welte60a8ec72020-11-25 17:12:53 +01002559
2560 SGSN_MGMT.clear;
2561 PCU_MGMT.clear;
2562
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002563 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
2564 g_roroi[i] := {};
2565 }
2566
Harald Welte60a8ec72020-11-25 17:12:53 +01002567 /* block the PTP BVC from the PCU side */
2568 PCU_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to pcu_bvc_ct;
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002569
Harald Welte60a8ec72020-11-25 17:12:53 +01002570 /* expect state on both PCU and SGSN side to change */
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002571 defaults := { activate(as_ignore_status(SGSN_MGMT)) };
2572
2573 /* Activate altsteps: One for each SGSN */
2574 for (i := 0; i < lengthof(g_sgsn); i := i+1) {
2575 var default d := activate(as_count_bvc_reset(i, bvc_cfg.bvci, g_roroi));
2576 defaults := defaults & { d };
Harald Welte60a8ec72020-11-25 17:12:53 +01002577 }
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002578
2579 timer T := 3.0;
2580 T.start;
2581 alt {
2582 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_BLOCKED)) from pcu_bvc_ct {
2583 g_roi := g_roi & { bvc_cfg.bvci };
2584 repeat;
2585 }
2586 [] T.timeout;
2587 }
2588
2589 for (i := 0; i < lengthof(defaults); i := i+1) {
2590 deactivate(defaults[i]);
2591 }
2592
2593 /* Check if BVC-RESET was received at all SGSNs */
2594 for (i := 0; i < lengthof(g_sgsn); i := i+1) {
2595 if (not ro_integer_contains(g_roroi[i], bvc_cfg.bvci)) {
2596 setverdict(fail, "Missing SGSN[", i, "] BVC-BLOCK of BVCI=", bvc_cfg.bvci);
2597 }
2598 }
2599
Harald Welte60a8ec72020-11-25 17:12:53 +01002600 setverdict(pass);
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002601 f_cleanup();
Harald Welte60a8ec72020-11-25 17:12:53 +01002602}
2603/* Send a BVC-RESET for a PTP BVC from the BSS side: expect it to propagate */
2604testcase TC_bvc_reset_ptp_from_bss() runs on test_CT
2605{
2606 f_init();
2607 f_sleep(3.0);
2608 f_reset_ptp_bvc_from_pcu(0, 0);
2609 f_cleanup();
2610}
2611
Harald Welteb1cc0b22021-03-30 12:16:36 +02002612private altstep as_count_bvc_sts(integer sgsn_idx, BssgpBvci bvci,
2613 template (present) BvcState exp_bvc_state, inout roro_integer roroi)
Harald Welte16786e92020-11-27 19:11:56 +01002614runs on test_CT {
2615 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(sgsn_idx, bvci);
Harald Welteb1cc0b22021-03-30 12:16:36 +02002616 [] SGSN_MGMT.receive(tr_BssgpStsInd(?, bvci, exp_bvc_state)) from sgsn_bvc_ct {
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002617 roroi[sgsn_idx] := roroi[sgsn_idx] & { bvci };
Harald Welteb2647f72020-12-07 14:36:35 +01002618 repeat;
Harald Welte16786e92020-11-27 19:11:56 +01002619 }
2620}
Harald Welteb1cc0b22021-03-30 12:16:36 +02002621
2622private altstep as_count_bvc_block(integer sgsn_idx, BssgpBvci bvci, inout roro_integer roroi)
2623runs on test_CT {
2624 [] as_count_bvc_sts(sgsn_idx, bvci, BVC_S_BLOCKED, roroi);
2625}
2626
2627private altstep as_count_bvc_unblock(integer sgsn_idx, BssgpBvci bvci, inout roro_integer roroi)
2628runs on test_CT {
2629 [] as_count_bvc_sts(sgsn_idx, bvci, BVC_S_UNBLOCKED, roroi);
2630}
2631
Harald Welte16786e92020-11-27 19:11:56 +01002632/* reset the signaling BVC from one BSS; expect no signaling BVC reset on SGSN; but BVC-BLOCK for PTP */
2633testcase TC_bvc_reset_sig_from_bss() runs on test_CT {
2634
2635 f_init();
2636 f_sleep(3.0);
2637
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002638 for (var integer i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
2639 g_roroi[i] := {};
2640 }
2641
Harald Welte16786e92020-11-27 19:11:56 +01002642 /* Start BVC-RESET procedure for BVCI=0 */
2643 PCU_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to g_pcu[0].vc_BSSGP;
2644
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002645 /* Activate altsteps: One for each PTP BVC and SGSN within that PCUs NSE */
Harald Welte16786e92020-11-27 19:11:56 +01002646 var ro_default defaults := {};
2647 for (var integer i := 0; i < lengthof(g_pcu[0].cfg.bvc); i := i+1) {
2648 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[i];
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002649 for (var integer j := 0; j < lengthof(g_sgsn); j := j+1) {
2650 var default d := activate(as_count_bvc_block(j, bvcc.bvci, g_roroi));
2651 defaults := defaults & { d };
2652 }
Harald Welte16786e92020-11-27 19:11:56 +01002653 }
2654
2655 timer T := 3.0;
2656 T.start;
2657 alt {
2658 [] SGSN_MGMT.receive(BssgpResetIndication:{0}) {
2659 setverdict(fail, "BSS-side Reset of BVCI=0 should not propagate");
2660 }
2661 [] T.timeout;
2662 }
2663
2664 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2665 deactivate(defaults[i]);
2666 }
2667
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002668 /* check if BVC-block was received on all expected BVC/SGSN */
Harald Welte16786e92020-11-27 19:11:56 +01002669 for (var integer i := 0; i < lengthof(g_pcu[0].cfg.bvc); i := i+1) {
2670 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[i];
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002671 for (var integer j := 0; j < lengthof(g_sgsn); j := j+1) {
2672 if (not ro_integer_contains(g_roroi[j], bvcc.bvci)) {
2673 setverdict(fail, "Missing SGSN[", j, "] BVC-BLOCK of BVCI=", bvcc.bvci);
2674 }
Harald Welte16786e92020-11-27 19:11:56 +01002675 }
2676 }
2677
2678 /* check if BVC-block was not received on any unexpected BVC is not required as
2679 * such a message would basically run into 'no matching clause' */
Daniel Willmannf2590212020-12-04 14:20:50 +01002680 setverdict(pass);
Harald Welte16786e92020-11-27 19:11:56 +01002681 f_cleanup();
2682}
2683
Harald Welte60a8ec72020-11-25 17:12:53 +01002684private function f_reset_ptp_bvc_from_sgsn(integer pcu_idx, integer bvc_idx) runs on test_CT
2685{
2686 var BSSGP_BVC_CT pcu_bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2687 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2688 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2689 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(0, bvc_cfg.bvci);
2690 var default d;
2691
2692 SGSN_MGMT.clear;
2693 PCU_MGMT.clear;
2694
2695 /* block the PTP BVC from the PCU side */
2696 SGSN_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to sgsn_bvc_ct;
2697 /* expect state on both PCU and SGSN side to change */
2698 d := activate(as_ignore_status(PCU_MGMT));
2699 interleave {
2700 [] SGSN_MGMT.receive(tr_BssgpStsInd(?, bvc_cfg.bvci, BVC_S_BLOCKED)) from sgsn_bvc_ct;
2701 [] PCU_MGMT.receive(BssgpResetIndication:{bvc_cfg.bvci}) from pcu_bvc_ct;
2702 }
2703 deactivate(d);
2704 setverdict(pass);
2705}
2706/* Send a BVC-RESET for a PTP BVC from the SGSN side: expect it to propagate */
2707testcase TC_bvc_reset_ptp_from_sgsn() runs on test_CT
2708{
2709 f_init();
2710 f_sleep(3.0);
2711 f_reset_ptp_bvc_from_sgsn(0, 0);
2712 f_cleanup();
2713}
2714
Daniel Willmannef7015f2021-01-08 00:43:56 +01002715private altstep as_ignore_mgmt(BSSGP_BVC_MGMT_PT pt) {
2716 [] pt.receive {repeat; }
2717}
2718
Harald Welte16786e92020-11-27 19:11:56 +01002719private altstep as_count_bvc0_block(integer pcu_idx, Nsei nsei, inout ro_integer roi)
2720runs on test_CT {
2721 var BSSGP_CT pcu_ct := g_pcu[pcu_idx].vc_BSSGP;
2722 [] PCU_MGMT.receive(BssgpResetIndication:{0}) from pcu_ct {
2723 roi := roi & { nsei };
Daniel Willmannef7015f2021-01-08 00:43:56 +01002724 repeat;
Harald Welte16786e92020-11-27 19:11:56 +01002725 }
2726}
Daniel Willmannef7015f2021-01-08 00:43:56 +01002727
Harald Welte16786e92020-11-27 19:11:56 +01002728/* reset the signaling BVC from the SGSN; expect all signaling BVC on all BSS to be reset */
2729testcase TC_bvc_reset_sig_from_sgsn() runs on test_CT {
2730
2731 f_init();
2732 f_sleep(3.0);
2733
Daniel Willmannef7015f2021-01-08 00:43:56 +01002734 SGSN_MGMT.clear;
2735 PCU_MGMT.clear;
2736
Harald Welte16786e92020-11-27 19:11:56 +01002737 /* Start BVC-RESET procedure for BVCI=0 */
2738 SGSN_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to g_sgsn[0].vc_BSSGP;
2739
Daniel Willmannef7015f2021-01-08 00:43:56 +01002740 /* Defaults match in reverse activation order, this one is a catch-all for Status indications
2741 * and reset indications sent from other components (like the ptp_bvcs). If we don't drain
2742 * the port and a different message sits at the front we wait forever and fail the test.
2743 */
2744 var ro_default defaults := { activate(as_ignore_mgmt(PCU_MGMT)) };
2745
Harald Welte16786e92020-11-27 19:11:56 +01002746 /* Activate altsteps: One for each PCU NSE */
Harald Welte16786e92020-11-27 19:11:56 +01002747 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2748 var NSConfiguration nscfg := mp_nsconfig_pcu[i];
2749 var default d := activate(as_count_bvc0_block(i, nscfg.nsei, g_roi));
2750 defaults := defaults & { d };
2751 }
2752
2753 f_sleep(3.0);
2754
2755 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2756 deactivate(defaults[i]);
2757 }
2758
2759 /* check if BVC-block was received on all expected BVC */
2760 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2761 var NSConfiguration nscfg := mp_nsconfig_pcu[i];
2762 if (not ro_integer_contains(g_roi, nscfg.nsei)) {
2763 setverdict(fail, "Missing PCU-side BVC-RESET of BVCI=0 on PCU index ", i);
2764 }
2765 }
2766
2767 /* check if BVC-block was not received on any unexpected BVC is not required as
2768 * such a message would basically run into 'no matching clause' */
2769
2770 f_cleanup();
2771}
2772
Harald Welte299aa482020-12-09 15:10:55 +01002773/***********************************************************************
2774 * FLOW-CONTROL-BVC procedure
2775 ***********************************************************************/
2776
2777private altstep as_g_count_sgsn(integer sgsn_idx, inout ro_integer roi,
2778 template PDU_BSSGP exp_rx, template (omit) PDU_BSSGP tx_reply)
2779runs on GlobalTest_CT {
2780 [] G_SGSN[sgsn_idx].receive(exp_rx) {
2781 roi := roi & { sgsn_idx };
2782 if (ispresent(tx_reply)) {
2783 G_SGSN[sgsn_idx].send(tx_reply);
2784 }
Harald Welte5fb01742021-01-15 21:07:52 +01002785 repeat;
Harald Welte299aa482020-12-09 15:10:55 +01002786 }
2787}
2788/* Send FC-BVC from simulated PCU; expect each SGSN to receive it; expect PCU to receive ACK */
2789testcase TC_fc_bvc() runs on GlobalTest_CT
2790{
2791 f_init();
2792 f_global_init_ptp();
2793
Pau Espin Pedrol6ee01262021-02-05 13:05:06 +01002794 var template (value) PDU_BSSGP pdu_tx := ts_BVC_FC_BVC(10240, 2000, 1024, 1000, '01'O);
Harald Welte299aa482020-12-09 15:10:55 +01002795 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2796 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 +01002797 var template (value) PDU_BSSGP ack_tx :=
2798 ts_BVC_FC_BVC_ACK(pdu_tx.pDU_BSSGP_FLOW_CONTROL_BVC.tag.unstructured_Value);
Harald Welte299aa482020-12-09 15:10:55 +01002799
2800 /* Send a FC-BVC from BSS to gbproxy, expect an ACK in response */
2801 G_PCU[0].send(pdu_tx);
2802
2803 /* Activate altsteps: One for each SGSN-side PTP BVC port */
2804 var ro_default defaults := {};
2805 for (var integer i := 0; i < lengthof(g_sgsn); i := i+1) {
2806 var default d := activate(as_g_count_sgsn(i, g_roi, pdu_rx, ack_tx));
2807 defaults := defaults & { d };
2808 }
2809
2810 f_sleep(3.0);
2811
2812 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2813 deactivate(defaults[i]);
2814 }
2815
2816 /* check if BVC-block was received on all expected BVC */
2817 for (var integer i := 0; i < lengthof(g_sgsn); i := i+1) {
2818 if (not ro_integer_contains(g_roi, i)) {
2819 setverdict(fail, "Missing BVC-FLOW-CONTROL on SGSN index ", i);
2820 }
2821 }
2822
2823 /* Expect ACK on PCU side */
2824 G_PCU[0].receive(ack_tx);
2825
2826 setverdict(pass);
2827
2828 f_cleanup();
2829}
2830
Harald Weltecc3894b2020-12-09 16:50:12 +01002831/***********************************************************************
2832 * FLOW-CONTROL-MS procedure
2833 ***********************************************************************/
2834
2835private function f_TC_fc_ms(charstring id) runs on BSSGP_ConnHdlr {
2836 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
2837
2838 var template (value) PDU_BSSGP fc_tx := ts_BVC_FC_MS(g_pars.tlli, 100, 200, '12'O);
2839 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2840 var template (present) PDU_BSSGP fc_rx := tr_BVC_FC_MS(g_pars.tlli, 100, 200, '12'O);
2841 var template (value) PDU_BSSGP ack_tx := ts_BVC_FC_MS_ACK(g_pars.tlli, '12'O);
2842
2843 f_pcu2sgsn(fc_tx, fc_rx, use_sig := false);
2844 f_sgsn2pcu(ack_tx, ack_tx, use_sig := false);
2845
2846 setverdict(pass);
2847}
2848/* Send a FLOW-CONTROL-MS from BSS side and expect it to show up on SGSN (PTP BVC) */
2849testcase TC_fc_ms() runs on test_CT
2850{
Harald Weltecc3894b2020-12-09 16:50:12 +01002851 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002852 f_start_handlers(refers(f_TC_fc_ms), testcasename(), 21);
Harald Weltecc3894b2020-12-09 16:50:12 +01002853 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Weltecc3894b2020-12-09 16:50:12 +01002854 f_cleanup();
2855}
2856
Harald Welted6f89812021-01-16 18:57:49 +01002857/***********************************************************************
2858 * MS-REGISTRATION ENQUIRY procedure
2859 ***********************************************************************/
Harald Weltecc3894b2020-12-09 16:50:12 +01002860
Harald Welted6f89812021-01-16 18:57:49 +01002861private function f_TC_ms_reg_enq(charstring id) runs on BSSGP_ConnHdlr
2862{
2863 f_pcu2sgsn(ts_BSSGP_MS_REG_ENQ(g_pars.imsi), tr_BSSGP_MS_REG_ENQ(g_pars.imsi), use_sig := true);
2864 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);
2865}
2866testcase TC_ms_reg_enq() runs on test_CT
2867{
2868 f_init();
2869 f_start_handlers(refers(f_TC_ms_reg_enq), testcasename(), 22);
2870 f_cleanup();
2871}
Harald Welte299aa482020-12-09 15:10:55 +01002872
Harald Weltef86f1852021-01-16 21:56:17 +01002873/***********************************************************************
2874 * RIM (RAN Information Management)
2875 ***********************************************************************/
2876
2877/* Our tests here are rather synthetic, as they don't reflect normal message flows
2878 as they would be observed in a live network. However, for testing gbproxy, this shouldn't
2879 matter as gbproxy is not concerned with anything but the source / destination routing
2880 information */
2881
2882/* gbproxy must route all unknown RIM Routing Info (Cell Id) to the SGSN. We just define
2883 one here of which we know it is not used among the [simulated] PCUs */
2884const BssgpCellId cell_id_sgsn := {
2885 ra_id := {
2886 lai := {
2887 mcc_mnc := c_mcc_mnc,
2888 lac := 65534
2889 },
2890 rac := 0
2891 },
2892 cell_id := 65533
2893};
2894
2895/* Send 'tx' on PTP-BVCI from PCU; expect 'rx' on any of our SGSN (RIM can be routed anywhere) */
2896friend function f_rim_pcu2sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
2897 integer pcu_idx := 0) runs on GlobalTest_CT {
2898 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +01002899 timer T := 2.0;
Harald Weltef86f1852021-01-16 21:56:17 +01002900
2901 RIM_PCU[pcu_idx].send(tx);
2902 T.start;
2903 alt {
2904 [] any from RIM_SGSN.receive(exp_rx) {
2905 setverdict(pass);
2906 }
2907 [] any from RIM_SGSN.receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +01002908 f_shutdown(__FILE__, __LINE__, fail, log2str("Unexpected BSSGP on SGSN side: ", rx));
Harald Weltef86f1852021-01-16 21:56:17 +01002909 }
2910 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +01002911 f_shutdown(__FILE__, __LINE__, fail,
2912 log2str("Timeout waiting for BSSGP on SGSN side: ", exp_rx));
Harald Weltef86f1852021-01-16 21:56:17 +01002913 }
2914 }
2915}
2916
2917/* Send 'tx' on PTP-BVCI from SGSN; expect 'rx' on PCU */
2918friend function f_rim_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
2919 integer sgsn_idx := 0, integer pcu_idx := 0) runs on GlobalTest_CT {
2920 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +01002921 timer T := 2.0;
Harald Weltef86f1852021-01-16 21:56:17 +01002922
2923 RIM_SGSN[sgsn_idx].send(tx);
2924 T.start;
2925 alt {
2926 [] RIM_PCU[pcu_idx].receive(exp_rx) {
2927 setverdict(pass);
2928 }
2929 [] RIM_PCU[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +01002930 f_shutdown(__FILE__, __LINE__, fail, log2str("Unexpected BSSGP on PCU side: ", rx));
Harald Weltef86f1852021-01-16 21:56:17 +01002931 }
2932 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +01002933 f_shutdown(__FILE__, __LINE__, fail,
2934 log2str("Timeout waiting for BSSGP on PCU side: ", exp_rx));
Harald Weltef86f1852021-01-16 21:56:17 +01002935 }
2936 }
2937}
2938
2939/* Send 'tx' on PTP-BVCI from SRC-PCU; expect 'rx' on DST-PCU */
2940friend function f_rim_pcu2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
2941 integer src_pcu_idx, integer dst_pcu_idx) runs on GlobalTest_CT {
2942 var integer rx_idx;
2943 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +01002944 timer T := 2.0;
Harald Weltef86f1852021-01-16 21:56:17 +01002945
2946 RIM_PCU[src_pcu_idx].send(tx);
2947 T.start;
2948 alt {
2949 [] RIM_PCU[dst_pcu_idx].receive(exp_rx) -> value rx{
2950 setverdict(pass);
2951 }
2952 [] any from RIM_PCU.receive(exp_rx) -> @index value rx_idx {
2953 setverdict(fail, "Received RIM on wrong PCU[", rx_idx ,"], expected on PCU[", dst_pcu_idx, "]");
2954 }
2955 [] any from RIM_SGSN.receive(exp_rx) {
2956 setverdict(fail, "Received RIM on SGSN but expected it on other PCU");
2957 }
2958 [] any from RIM_SGSN.receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +01002959 f_shutdown(__FILE__, __LINE__, fail, log2str("Unexpected BSSGP on SGSN side: ", rx));
Harald Weltef86f1852021-01-16 21:56:17 +01002960 }
2961 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +01002962 f_shutdown(__FILE__, __LINE__, fail,
2963 log2str("Timeout waiting for BSSGP on SGSN side: ", exp_rx));
Harald Weltef86f1852021-01-16 21:56:17 +01002964 }
2965 }
2966}
2967
2968
2969type function rim_fn(integer sgsn_idx, integer pcu_idx, integer bvc_idx) runs on GlobalTest_CT;
2970
2971/* helper function for the RIM test cases: Execute 'fn' for each BVC on each PCU for
2972 each SGSN */
2973private function f_rim_iterator(rim_fn fn) runs on GlobalTest_CT
2974{
2975 var integer sgsn_idx, pcu_idx, bvc_idx;
2976 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx+1) {
2977 for (pcu_idx := 0; pcu_idx < lengthof(g_pcu); pcu_idx := pcu_idx+1) {
2978 for (bvc_idx := 0; bvc_idx < lengthof(g_pcu[pcu_idx].cfg.bvc); bvc_idx := bvc_idx+1) {
2979 log("Testing RIM SGSN[", sgsn_idx, "] <-> PCU[", pcu_idx, "][", bvc_idx, "]");
2980 fn.apply(sgsn_idx, pcu_idx, bvc_idx);
2981 }
2982 }
2983 }
2984}
2985
2986/* RAN-INFORMATION-REQUEST */
2987private function f_TC_rim_info_req(integer sgsn_idx, integer pcu_idx, integer bvc_idx := 0)
2988runs on GlobalTest_CT
2989{
2990 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
Philipp Maier14d3a8e2021-01-28 21:43:16 +01002991 var template (value) RAN_Information_Request_RIM_Container cont_tx;
2992 var template RAN_Information_Request_RIM_Container cont_rx;
2993 var template RIM_Routing_Address ra_pcu;
2994 var template RIM_Routing_Address ra_sgsn;
Harald Weltef86f1852021-01-16 21:56:17 +01002995
Philipp Maier14d3a8e2021-01-28 21:43:16 +01002996 ra_pcu := t_RIM_Routing_Address_cid(cell_id);
2997 ra_sgsn := t_RIM_Routing_Address_cid(cell_id_sgsn);
2998
2999 cont_tx := ts_RAN_Information_Request_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3000 ts_RIM_Sequence_Number(0),
3001 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
3002 cont_rx := tr_RAN_Information_Request_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
3003 tr_RIM_Sequence_Number(0),
3004 tr_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
3005
3006 f_rim_pcu2sgsn(ts_RAN_INFORMATION_REQUEST(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3007 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3008 cont := cont_tx),
3009 tr_RAN_INFORMATION_REQUEST(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3010 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3011 cont := cont_rx),
3012 pcu_idx);
3013
3014 f_rim_sgsn2pcu(ts_RAN_INFORMATION_REQUEST(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3015 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3016 cont := cont_tx),
3017 tr_RAN_INFORMATION_REQUEST(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3018 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3019 cont := cont_rx),
Harald Weltef86f1852021-01-16 21:56:17 +01003020 sgsn_idx, pcu_idx);
3021}
3022testcase TC_rim_info_req() runs on GlobalTest_CT
3023{
3024 f_init();
3025 f_global_init();
3026 f_rim_iterator(refers(f_TC_rim_info_req));
3027 f_cleanup();
3028}
3029
3030/* RAN-INFORMATION */
3031private function f_TC_rim_info(integer sgsn_idx, integer pcu_idx, integer bvc_idx := 0)
3032runs on GlobalTest_CT
3033{
3034 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003035 var template (value) RAN_Information_RIM_Container cont_tx;
3036 var template RAN_Information_RIM_Container cont_rx;
3037 var template RIM_Routing_Address ra_pcu;
3038 var template RIM_Routing_Address ra_sgsn;
Harald Weltef86f1852021-01-16 21:56:17 +01003039
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003040 ra_pcu := t_RIM_Routing_Address_cid(cell_id);
3041 ra_sgsn := t_RIM_Routing_Address_cid(cell_id_sgsn);
3042
3043 cont_tx := ts_RAN_Information_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3044 ts_RIM_Sequence_Number(0),
3045 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
3046
3047 cont_rx := tr_RAN_Information_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
3048 tr_RIM_Sequence_Number(0),
3049 tr_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
3050
3051 f_rim_pcu2sgsn(ts_PDU_BSSGP_RAN_INFORMATION(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3052 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3053 cont := cont_tx),
3054 tr_PDU_BSSGP_RAN_INFORMATION(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3055 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3056 cont := cont_rx),
3057 pcu_idx);
3058
3059 f_rim_sgsn2pcu(ts_PDU_BSSGP_RAN_INFORMATION(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3060 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3061 cont := cont_tx),
3062 tr_PDU_BSSGP_RAN_INFORMATION(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3063 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3064 cont := cont_rx),
Harald Weltef86f1852021-01-16 21:56:17 +01003065 sgsn_idx, pcu_idx);
3066}
3067testcase TC_rim_info() runs on GlobalTest_CT
3068{
3069 f_init();
3070 f_global_init();
3071 f_rim_iterator(refers(f_TC_rim_info));
3072 f_cleanup();
3073}
3074
3075/* RAN-INFORMATION-ACK */
3076private function f_TC_rim_info_ack(integer sgsn_idx, integer pcu_idx, integer bvc_idx := 0)
3077runs on GlobalTest_CT
3078{
3079 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003080 var template (value) RAN_Information_Ack_RIM_Container cont_tx;
3081 var template RAN_Information_Ack_RIM_Container cont_rx;
3082 var template RIM_Routing_Address ra_pcu;
3083 var template RIM_Routing_Address ra_sgsn;
Harald Weltef86f1852021-01-16 21:56:17 +01003084
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003085 ra_pcu := t_RIM_Routing_Address_cid(cell_id);
3086 ra_sgsn := t_RIM_Routing_Address_cid(cell_id_sgsn);
3087
3088 cont_tx := ts_RAN_Information_Ack_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3089 ts_RIM_Sequence_Number(0));
3090
3091 cont_rx := tr_RAN_Information_Ack_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
3092 tr_RIM_Sequence_Number(0));
3093
3094 f_rim_pcu2sgsn(ts_PDU_BSSGP_RAN_INFORMATION_ACK(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3095 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3096 cont := cont_tx),
3097 tr_PDU_BSSGP_RAN_INFORMATION_ACK(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3098 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3099 cont := cont_rx),
3100 pcu_idx);
3101
3102 f_rim_sgsn2pcu(ts_PDU_BSSGP_RAN_INFORMATION_ACK(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3103 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3104 cont := cont_tx),
3105 tr_PDU_BSSGP_RAN_INFORMATION_ACK(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3106 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3107 cont := cont_rx),
Harald Weltef86f1852021-01-16 21:56:17 +01003108 sgsn_idx, pcu_idx);
3109}
3110testcase TC_rim_info_ack() runs on GlobalTest_CT
3111{
3112 f_init();
3113 f_global_init();
3114 f_rim_iterator(refers(f_TC_rim_info_ack));
3115 f_cleanup();
3116}
3117
3118/* RAN-INFORMATION-ERROR */
3119private function f_TC_rim_info_error(integer sgsn_idx, integer pcu_idx, integer bvc_idx := 0)
3120runs on GlobalTest_CT
3121{
3122 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003123 var template (value) RAN_Information_Error_RIM_Container cont_tx;
3124 var template RAN_Information_Error_RIM_Container cont_rx;
3125 var template RIM_Routing_Address ra_pcu;
3126 var template RIM_Routing_Address ra_sgsn;
Harald Weltef86f1852021-01-16 21:56:17 +01003127
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003128 ra_pcu := t_RIM_Routing_Address_cid(cell_id);
3129 ra_sgsn := t_RIM_Routing_Address_cid(cell_id_sgsn);
3130
3131 cont_tx := ts_RAN_Information_Error_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3132 ts_BSSGP_CAUSE(BSSGP_CAUSE_EQUIMENT_FAILURE),
Pau Espin Pedrol6ee01262021-02-05 13:05:06 +01003133 omit, valueof(ts_BVC_UNBLOCK(23)));
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003134
3135 cont_rx := tr_RAN_Information_Error_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
Pau Espin Pedrol6ee01262021-02-05 13:05:06 +01003136 ts_BSSGP_CAUSE(BSSGP_CAUSE_EQUIMENT_FAILURE),
3137 omit, enc_PDU_BSSGP(valueof(tr_BVC_UNBLOCK(23))));
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003138
3139 f_rim_pcu2sgsn(ts_PDU_BSSGP_RAN_INFORMATION_ERROR(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3140 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3141 cont := cont_tx),
3142 tr_PDU_BSSGP_RAN_INFORMATION_ERROR(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3143 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3144 cont := cont_rx),
3145 pcu_idx);
3146
3147 f_rim_sgsn2pcu(ts_PDU_BSSGP_RAN_INFORMATION_ERROR(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3148 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3149 cont := cont_tx),
3150 tr_PDU_BSSGP_RAN_INFORMATION_ERROR(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3151 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3152 cont := cont_rx),
Harald Weltef86f1852021-01-16 21:56:17 +01003153 sgsn_idx, pcu_idx);
3154}
3155testcase TC_rim_info_error() runs on GlobalTest_CT
3156{
3157 f_init();
3158 f_global_init();
3159 f_rim_iterator(refers(f_TC_rim_info_error));
3160 f_cleanup();
3161}
3162
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003163//////////////////
Harald Weltef86f1852021-01-16 21:56:17 +01003164/* RAN-INFORMATION-APPLICATION-ERROR */
3165private function f_TC_rim_info_app_error(integer sgsn_idx, integer pcu_idx, integer bvc_idx := 0)
3166runs on GlobalTest_CT
3167{
3168 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003169 var template (value) Application_Error_Container app_cont_tx;
3170 var template Application_Error_Container app_cont_rx;
3171 var template (value) RAN_Information_Application_Error_RIM_Container cont_tx;
3172 var template RAN_Information_Application_Error_RIM_Container cont_rx;
3173 var template RIM_Routing_Address ra_pcu;
3174 var template RIM_Routing_Address ra_sgsn;
Harald Weltef86f1852021-01-16 21:56:17 +01003175
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003176 ra_pcu := t_RIM_Routing_Address_cid(cell_id);
3177 ra_sgsn := t_RIM_Routing_Address_cid(cell_id_sgsn);
3178
3179 app_cont_tx := tsu_Application_Error_Container_NACC(cell_id, 23,
3180 tsu_Application_Container_IE_NACC_req(cell_id));
3181
3182 app_cont_rx := rsu_Application_Error_Container_NACC(cell_id, 23,
3183 rsu_Application_Container_IE_NACC_req(cell_id));
3184
3185 cont_tx := ts_RAN_Information_Application_Error_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3186 ts_RIM_Sequence_Number(0),
3187 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP),
3188 omit, app_cont_tx);
3189 cont_rx := tr_RAN_Information_Application_Error_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
3190 tr_RIM_Sequence_Number(0),
3191 tr_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP),
3192 omit, app_cont_rx);
3193
3194 f_rim_pcu2sgsn(ts_PDU_BSSGP_RAN_INFORMATION_APPLICATION_ERROR(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3195 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3196 cont := cont_tx),
3197 tr_PDU_BSSGP_RAN_INFORMATION_APPLICATION_ERROR(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3198 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3199 cont := cont_rx),
3200 pcu_idx);
3201
3202 f_rim_sgsn2pcu(ts_PDU_BSSGP_RAN_INFORMATION_APPLICATION_ERROR(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3203 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3204 cont := cont_tx),
3205 tr_PDU_BSSGP_RAN_INFORMATION_APPLICATION_ERROR(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3206 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3207 cont := cont_rx),
Harald Weltef86f1852021-01-16 21:56:17 +01003208 sgsn_idx, pcu_idx);
3209}
3210testcase TC_rim_info_app_error() runs on GlobalTest_CT
3211{
3212 f_init();
3213 f_global_init();
3214 f_rim_iterator(refers(f_TC_rim_info_app_error));
3215 f_cleanup();
3216}
3217
3218/* RAN-INFORMATION routing directly between PCUs, without SGSN involvement */
3219private function f_TC_rim_info_pcu2pcu(integer src_pcu_idx, integer src_bvc_idx,
3220 integer dst_pcu_idx, integer dst_bvc_idx)
3221runs on GlobalTest_CT
3222{
3223 var BssgpCellId cell_id_src := g_pcu[src_pcu_idx].cfg.bvc[src_bvc_idx].cell_id;
3224 var BssgpCellId cell_id_dst := g_pcu[dst_pcu_idx].cfg.bvc[dst_bvc_idx].cell_id;
Philipp Maier1bd60ce2021-02-10 18:25:50 +01003225 var template (value) RIM_Routing_Information ri_pcu_src_tx;
3226 var template (value) RIM_Routing_Information ri_pcu_dst_tx;
3227 var template RIM_Routing_Information ri_pcu_src_rx;
3228 var template RIM_Routing_Information ri_pcu_dst_rx;
3229 var template (value) RAN_Information_RIM_Container cont_tx;
3230 var template RAN_Information_RIM_Container cont_rx;
Harald Weltef86f1852021-01-16 21:56:17 +01003231
3232 log("Testing RIM PCU2PCU from PCU[", src_pcu_idx, "][", src_bvc_idx, "] to PCU[",
3233 dst_pcu_idx, "][", dst_bvc_idx, "]");
3234
Philipp Maier1bd60ce2021-02-10 18:25:50 +01003235 ri_pcu_src_tx := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID,
Harald Weltef86f1852021-01-16 21:56:17 +01003236 t_RIM_Routing_Address_cid(cell_id_src));
Philipp Maier1bd60ce2021-02-10 18:25:50 +01003237 ri_pcu_dst_tx := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID,
Harald Weltef86f1852021-01-16 21:56:17 +01003238 t_RIM_Routing_Address_cid(cell_id_dst));
Philipp Maier1bd60ce2021-02-10 18:25:50 +01003239 ri_pcu_src_rx := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID,
3240 t_RIM_Routing_Address_cid(cell_id_src));
3241 ri_pcu_dst_rx := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID,
3242 t_RIM_Routing_Address_cid(cell_id_dst));
3243
3244 cont_tx := ts_RAN_Information_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3245 ts_RIM_Sequence_Number(0),
3246 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
3247 cont_rx := tr_RAN_Information_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
3248 tr_RIM_Sequence_Number(0),
3249 tr_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
3250
3251 f_rim_pcu2pcu(ts_PDU_BSSGP_RAN_INFORMATION(dst := ri_pcu_dst_tx, src := ri_pcu_src_tx, cont := cont_tx),
3252 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 +01003253 src_pcu_idx, dst_pcu_idx);
3254}
3255testcase TC_rim_info_pcu2pcu() runs on GlobalTest_CT
3256{
3257 var integer src_pcu_idx, dst_pcu_idx;
3258 var integer src_bvc_idx, dst_bvc_idx;
3259 f_init();
3260 f_global_init();
3261
3262 for (src_pcu_idx := 0; src_pcu_idx < lengthof(g_pcu); src_pcu_idx := src_pcu_idx + 1) {
3263 for (src_bvc_idx := 0; src_bvc_idx < lengthof(g_pcu[src_pcu_idx].cfg.bvc); src_bvc_idx := src_bvc_idx + 1) {
3264 for (dst_pcu_idx := 0; dst_pcu_idx < lengthof(g_pcu); dst_pcu_idx := dst_pcu_idx + 1) {
3265 if (dst_pcu_idx == src_pcu_idx) {
3266 continue;
3267 }
3268
3269 for (dst_bvc_idx := 0; dst_bvc_idx < lengthof(g_pcu[dst_pcu_idx].cfg.bvc);
3270dst_bvc_idx := dst_bvc_idx + 1) {
3271 f_TC_rim_info_pcu2pcu(src_pcu_idx, src_bvc_idx, dst_pcu_idx, dst_bvc_idx);
3272 }
3273 }
3274 }
3275 }
3276
3277 f_cleanup();
3278}
3279
Pau Espin Pedrol40778e82021-05-07 13:20:58 +02003280
3281/* Test RIM REQ sent from an MME->SGSN->GBPROXY->PCU and back (eNACC) */
3282private function f_TC_rim_from_eutran(integer sgsn_idx, integer pcu_idx, integer bvc_idx := 0)
3283runs on GlobalTest_CT
3284{
3285 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
3286 var template (value) RAN_Information_Request_RIM_Container cont_tx;
3287 var template RAN_Information_Request_RIM_Container cont_rx;
3288 var template RIM_Routing_Address ra_pcu;
3289 var template RIM_Routing_Address ra_sgsn;
3290
3291 ra_pcu := t_RIM_Routing_Address_cid(cell_id);
3292 ra_sgsn := t_RIM_Routing_Address_enbid(cell_id_sgsn, tac := 3, gnbid := '12345678123456'O);
3293
3294 cont_tx := ts_RAN_Information_Request_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3295 ts_RIM_Sequence_Number(0),
3296 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
3297 cont_rx := tr_RAN_Information_Request_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
3298 tr_RIM_Sequence_Number(0),
3299 tr_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
3300
3301 f_rim_sgsn2pcu(ts_RAN_INFORMATION_REQUEST(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3302 src := ts_RIM_Routing_Information(RIM_ADDR_EUTRAN_NODEB_ID, ra_sgsn),
3303 cont := cont_tx),
3304 tr_RAN_INFORMATION_REQUEST(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3305 src := tr_RIM_Routing_Information(RIM_ADDR_EUTRAN_NODEB_ID, ra_sgsn),
3306 cont := cont_rx),
3307 sgsn_idx, pcu_idx);
3308
3309
3310 f_rim_pcu2sgsn(ts_RAN_INFORMATION_REQUEST(dst := ts_RIM_Routing_Information(RIM_ADDR_EUTRAN_NODEB_ID, ra_sgsn),
3311 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3312 cont := cont_tx),
3313 tr_RAN_INFORMATION_REQUEST(dst := tr_RIM_Routing_Information(RIM_ADDR_EUTRAN_NODEB_ID, ra_sgsn),
3314 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3315 cont := cont_rx),
3316 pcu_idx);
3317}
3318testcase TC_rim_from_eutran() runs on GlobalTest_CT
3319{
3320 f_init();
3321 f_global_init();
3322 f_rim_iterator(refers(f_TC_rim_from_eutran));
3323 f_cleanup();
3324}
3325
Harald Welte04358652021-01-17 13:48:13 +01003326/***********************************************************************
3327 * STATUS handling
3328 ***********************************************************************/
3329
3330/* BSSGP STATUS PDU must be routed based on inner "PDU In Error" message */
3331
3332/* generate a TMSI with NRI matching sgsn_idx + nri_idx */
3333private function f_gen_tmsi_for_sgsn_nri(integer sgsn_idx, integer nri_idx) runs on test_CT return OCT4
3334{
3335 var integer nri := mp_sgsn_nri[sgsn_idx][nri_idx];
3336 return f_gen_tmsi(0, nri_v := nri, nri_bitlen := mp_nri_bitlength);
3337}
3338
3339/* generate a TLLI with NRI matching sgsn_idx + nri_idx */
3340private function f_gen_tlli_for_sgsn_nri(integer sgsn_idx, integer nri_idx) runs on test_CT return OCT4
3341{
3342 var OCT4 p_tmsi := f_gen_tmsi_for_sgsn_nri(sgsn_idx, nri_idx);
3343 return f_gprs_tlli_from_tmsi(p_tmsi, TLLI_LOCAL);
3344}
3345
3346/* STATUS in uplink direction; expect routing by its NRI */
3347private function f_TC_status_ul(integer pcu_idx, integer sgsn_idx, PDU_BSSGP inner)
3348runs on GlobalTest_CT
3349{
3350 var template (value) PDU_BSSGP tx := ts_BSSGP_STATUS(omit, BSSGP_CAUSE_EQUIMENT_FAILURE, inner);
3351 var template (present) PDU_BSSGP exp_rx :=
3352 tr_BSSGP_STATUS(omit, BSSGP_CAUSE_EQUIMENT_FAILURE,
3353 tx.pDU_BSSGP_STATUS.pDU_in_Error.erroneous_BSSGP_PDU);
3354
3355 f_global_pcu2sgsn(tx, exp_rx, pcu_idx, sgsn_idx);
3356}
3357
3358/* STATUS in uplink direction; expect routing by its NRI */
3359private function f_TC_status_dl(integer sgsn_idx, integer pcu_idx, PDU_BSSGP inner)
3360runs on GlobalTest_CT
3361{
3362 var template (value) PDU_BSSGP tx := ts_BSSGP_STATUS(omit, BSSGP_CAUSE_EQUIMENT_FAILURE, inner);
3363 var template (present) PDU_BSSGP exp_rx :=
3364 tr_BSSGP_STATUS(omit, BSSGP_CAUSE_EQUIMENT_FAILURE,
3365 tx.pDU_BSSGP_STATUS.pDU_in_Error.erroneous_BSSGP_PDU);
3366
3367 f_global_sgsn2pcu(tx, exp_rx, sgsn_idx, pcu_idx);
3368}
3369
3370/* STATUS in uplink direction on SIG-BVC containing a TLLI; expect routing by its NRI */
3371testcase TC_status_sig_ul_tlli() runs on GlobalTest_CT
3372{
3373 var integer sgsn_idx, nri_idx;
3374
3375 f_init();
3376 f_global_init();
3377
3378 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3379 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx + 1) {
3380 /* some downlink PDU occurring on SIG-BVC with a TLLI */
3381 var OCT4 tlli := f_gen_tlli_for_sgsn_nri(sgsn_idx, nri_idx);
3382 var PDU_BSSGP inner := valueof(ts_BSSGP_FLUSH_LL(tlli, 2342));
3383
3384 f_TC_status_ul(0, sgsn_idx, inner);
3385 }
3386 }
3387
3388 f_cleanup();
3389}
3390
3391/* STATUS in uplink direction on SIG-BVC containing a TMSI; expect routing by its NRI */
3392testcase TC_status_sig_ul_tmsi() runs on GlobalTest_CT
3393{
3394 var integer sgsn_idx, nri_idx;
3395
3396 f_init();
3397 f_global_init();
3398
3399 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3400 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx + 1) {
3401 /* some downlink PDU occurring on SIG-BVC with a TMSI */
3402 const hexstring imsi := '001010123456789'H
3403 var OCT4 tmsi := f_gen_tmsi_for_sgsn_nri(sgsn_idx, nri_idx);
3404 var BssgpBvci bvci := g_pcu[0].cfg.bvc[0].bvci;
3405 var PDU_BSSGP inner := valueof(ts_BSSGP_CS_PAGING_PTMSI(bvci, imsi, oct2int(tmsi)));
3406 f_TC_status_ul(0, sgsn_idx, inner);
3407 }
3408 }
3409
3410 f_cleanup();
3411}
3412
3413
3414/* STATUS in uplink direction on PTP-BVC containing a TLLI; expect routing by its NRI */
3415testcase TC_status_ptp_ul_tlli() runs on GlobalTest_CT
3416{
3417 var integer sgsn_idx, nri_idx;
3418
3419 f_init();
3420 f_global_init_ptp();
3421
3422 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3423 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx + 1) {
3424 /* some downlink PDU occurring on PTP-BVC with a TLLI */
3425 var OCT4 tlli := f_gen_tlli_for_sgsn_nri(sgsn_idx, nri_idx);
3426 var PDU_BSSGP inner := valueof(ts_BSSGP_DL_UD(tlli, '2342'O));
3427
3428 f_TC_status_ul(0, sgsn_idx, inner);
3429 }
3430 }
3431
3432 f_cleanup();
3433}
3434
3435/* STATUS in uplink direction on PTP-BVC containing a TMSI; expect routing by its NRI */
3436testcase TC_status_ptp_ul_tmsi() runs on GlobalTest_CT
3437{
3438 var integer sgsn_idx, nri_idx;
3439
3440 f_init();
3441 f_global_init_ptp();
3442
3443 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3444 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx + 1) {
3445 /* some downlink PDU occurring on PTP-BVC with a TMSI */
3446 const hexstring imsi := '001010123456789'H
3447 var OCT4 tmsi := f_gen_tmsi_for_sgsn_nri(sgsn_idx, nri_idx);
3448 var BssgpBvci bvci := g_pcu[0].cfg.bvc[0].bvci;
3449 var PDU_BSSGP inner := valueof(ts_BSSGP_CS_PAGING_PTMSI(bvci, imsi, oct2int(tmsi)));
3450 f_TC_status_ul(0, sgsn_idx, inner);
3451 }
3452 }
3453
3454 f_cleanup();
3455}
3456
3457/* STATUS in downlink direction in SIG-BVC containing a BVCI; expect routing by it */
3458testcase TC_status_sig_dl_bvci() runs on GlobalTest_CT
3459{
3460 var integer sgsn_idx, pcu_idx, bvc_idx;
3461
3462 f_init();
3463 f_global_init();
3464
3465 /* test each BVC in each PCU from each SGSN */
3466 for (pcu_idx := 0; pcu_idx < lengthof(g_pcu); pcu_idx := pcu_idx + 1) {
3467 for (bvc_idx := 0; bvc_idx < lengthof(g_pcu[pcu_idx].cfg.bvc); bvc_idx := bvc_idx + 1) {
3468 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3469 /* some uplink PDU occurring on SIG-BVC containing a BVCI */
3470 var BssgpBvci bvci := g_pcu[pcu_idx].cfg.bvc[bvc_idx].bvci;
3471 var PDU_BSSGP inner := valueof(ts_BSSGP_LLC_DISCARDED('12345678'O, 1, bvci, 23));
3472 f_TC_status_dl(sgsn_idx, pcu_idx, inner);
3473 }
3474 }
3475 }
3476
3477 f_cleanup();
3478}
3479
3480/* STATUS in downlink direction in PTP-BVC; expect routing by BVCI */
3481testcase TC_status_ptp_dl_bvci() runs on GlobalTest_CT
3482{
3483 var integer sgsn_idx, pcu_idx, bvc_idx;
3484
3485 f_init();
3486 f_global_init_ptp();
3487
3488 /* test each BVC in each PCU from each SGSN */
3489 for (pcu_idx := 0; pcu_idx < lengthof(g_pcu); pcu_idx := pcu_idx + 1) {
3490 for (bvc_idx := 0; bvc_idx < lengthof(g_pcu[pcu_idx].cfg.bvc); bvc_idx := bvc_idx + 1) {
3491 var BssgpBvci bvci := g_pcu[pcu_idx].cfg.bvc[bvc_idx].bvci;
3492 f_global_ptp_connect_pcu_bvci(pcu_idx, bvci);
3493 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3494 f_global_ptp_connect_sgsn_bvci(sgsn_idx, bvci);
3495
3496 /* some uplink PDU occurring on PTP-BVC */
3497 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
3498 var PDU_BSSGP inner := valueof(ts_BSSGP_UL_UD('12345678'O, cell_id, '4223'O));
3499 f_TC_status_dl(sgsn_idx, pcu_idx, inner);
3500 }
3501 }
3502 }
3503
3504 f_cleanup();
3505}
3506
3507/* TODO: test case for DL-STATUS(SUSPEND/RESUME) containing RA-ID; expect routing by RA-ID */
3508/* 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 +01003509
Daniel Willmann423d8f42020-09-08 18:58:22 +02003510control {
3511 execute( TC_BVC_bringup() );
Harald Welte92686012020-11-15 21:45:49 +01003512 execute( TC_ul_unitdata() );
Daniel Willmann8d9fcf42021-05-28 15:05:41 +02003513 execute( TC_ul_unitdata_pool_failure() );
Harald Welte78d8db92020-11-15 23:27:27 +01003514 execute( TC_dl_unitdata() );
Harald Welte6dc2ac42020-11-16 09:16:17 +01003515 execute( TC_ra_capability() );
Daniel Willmannace3ece2020-11-16 19:53:26 +01003516 execute( TC_ra_capability_upd() );
Daniel Willmann165d6612020-11-19 14:27:29 +01003517 execute( TC_radio_status() );
Harald Welte3148a962021-01-17 11:15:28 +01003518 execute( TC_radio_status_tmsi() );
3519 execute( TC_radio_status_imsi() );
Daniel Willmannfa67f492020-11-19 15:48:05 +01003520 execute( TC_suspend() );
Daniel Willmann087a33d2020-11-19 15:58:43 +01003521 execute( TC_resume() );
Harald Weltef8e5c5d2020-11-27 22:37:23 +01003522 execute( TC_trace() );
Harald Weltec0351d12020-11-27 22:49:02 +01003523 execute( TC_llc_discarded() );
Harald Weltef20af412020-11-28 16:11:11 +01003524 execute( TC_overload() );
Harald Welte239aa502020-11-24 23:14:20 +01003525 execute( TC_bvc_block_ptp() );
3526 execute( TC_bvc_unblock_ptp() );
Harald Welte60a8ec72020-11-25 17:12:53 +01003527 execute( TC_bvc_reset_ptp_from_bss() );
Harald Welte16786e92020-11-27 19:11:56 +01003528 execute( TC_bvc_reset_sig_from_bss() );
Harald Welte60a8ec72020-11-25 17:12:53 +01003529 execute( TC_bvc_reset_ptp_from_sgsn() );
Harald Welte16786e92020-11-27 19:11:56 +01003530 execute( TC_bvc_reset_sig_from_sgsn() );
Harald Weltef6e59b02020-12-08 08:29:09 +01003531 if (mp_enable_bss_load_sharing) {
Harald Weltef8ef0282020-11-18 12:16:59 +01003532 /* don't enable this by default, as we don't yet have any automatic test setup for FR with 4 NS-VC */
3533 execute( TC_load_sharing_dl() );
3534 }
Harald Welte0e188242020-11-22 21:46:48 +01003535
3536 /* PAGING-PS over PTP BVC */
3537 execute( TC_paging_ps_ptp_bss() );
3538 execute( TC_paging_ps_ptp_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01003539 execute( TC_paging_ps_ptp_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003540 execute( TC_paging_ps_ptp_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01003541 execute( TC_paging_ps_ptp_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003542 execute( TC_paging_ps_ptp_bvci() );
Harald Welteb5a04aa2021-01-16 13:04:40 +01003543 execute( TC_paging_ps_ptp_bvci_imsi() );
Harald Welte7462a592020-11-23 22:07:07 +01003544 execute( TC_paging_ps_ptp_bvci_unknown() );
Harald Weltecf200072021-01-16 15:20:46 +01003545 execute( TC_paging_ps_reject_ptp_bvci() );
3546 execute( TC_paging_ps_reject_ptp_bvci_imsi() );
Harald Welte7595d562021-01-16 19:09:20 +01003547 execute( TC_dummy_paging_ps_ptp() );
Harald Welte0e188242020-11-22 21:46:48 +01003548
3549 /* PAGING-PS over SIG BVC */
3550 execute( TC_paging_ps_sig_bss() );
3551 execute( TC_paging_ps_sig_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01003552 execute( TC_paging_ps_sig_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003553 execute( TC_paging_ps_sig_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01003554 execute( TC_paging_ps_sig_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003555 execute( TC_paging_ps_sig_bvci() );
Harald Welteb5a04aa2021-01-16 13:04:40 +01003556 execute( TC_paging_ps_sig_bvci_imsi() );
Harald Welte7462a592020-11-23 22:07:07 +01003557 execute( TC_paging_ps_sig_bvci_unknown() );
Harald Weltecf200072021-01-16 15:20:46 +01003558 execute( TC_paging_ps_reject_sig_bvci() );
3559 execute( TC_paging_ps_reject_sig_bvci_imsi() );
Harald Welte7595d562021-01-16 19:09:20 +01003560 execute( TC_dummy_paging_ps_sig() );
Harald Welte0e188242020-11-22 21:46:48 +01003561
3562 /* PAGING-CS over PTP BVC */
3563 execute( TC_paging_cs_ptp_bss() );
3564 execute( TC_paging_cs_ptp_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01003565 execute( TC_paging_cs_ptp_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003566 execute( TC_paging_cs_ptp_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01003567 execute( TC_paging_cs_ptp_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003568 execute( TC_paging_cs_ptp_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01003569 execute( TC_paging_cs_ptp_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003570
3571 /* PAGING-CS over SIG BVC */
3572 execute( TC_paging_cs_sig_bss() );
3573 execute( TC_paging_cs_sig_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01003574 execute( TC_paging_cs_sig_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003575 execute( TC_paging_cs_sig_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01003576 execute( TC_paging_cs_sig_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003577 execute( TC_paging_cs_sig_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01003578 execute( TC_paging_cs_sig_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003579
Harald Weltef86f1852021-01-16 21:56:17 +01003580 /* RAN Information Management */
3581 execute( TC_rim_info_req() );
3582 execute( TC_rim_info() );
3583 execute( TC_rim_info_ack() );
3584 execute( TC_rim_info_error() );
3585 execute( TC_rim_info_app_error() );
3586 execute( TC_rim_info_pcu2pcu() );
Pau Espin Pedrol40778e82021-05-07 13:20:58 +02003587 execute( TC_rim_from_eutran() );
Harald Weltef86f1852021-01-16 21:56:17 +01003588
Harald Welte0e188242020-11-22 21:46:48 +01003589
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01003590 execute( TC_flush_ll() );
Harald Welte299aa482020-12-09 15:10:55 +01003591 execute( TC_fc_bvc() );
Harald Weltecc3894b2020-12-09 16:50:12 +01003592 execute( TC_fc_ms() );
Harald Welted6f89812021-01-16 18:57:49 +01003593 execute( TC_ms_reg_enq() );
Harald Welte04358652021-01-17 13:48:13 +01003594
3595 /* Uplink STATUS */
3596 execute( TC_status_sig_ul_tlli() );
3597 execute( TC_status_sig_ul_tmsi() );
3598 execute( TC_status_ptp_ul_tlli() );
3599 execute( TC_status_ptp_ul_tmsi() );
3600
3601 /* Downlink STATUS */
3602 execute( TC_status_sig_dl_bvci() );
3603 execute( TC_status_ptp_dl_bvci() );
Daniel Willmann423d8f42020-09-08 18:58:22 +02003604}
3605
3606
3607}