blob: f569eafd3110950b60e97469fd8a4dd7fc7b3109 [file] [log] [blame]
Daniel Willmann423d8f42020-09-08 18:58:22 +02001module GBProxy_Tests {
2
3/* Osmocom GBProxy test suite in TTCN-3
Harald Welte207166c2021-01-16 12:52:30 +01004 * (C) 2020-2021 Harald Welte <laforge@osmocom.org>
Daniel Willmann423d8f42020-09-08 18:58:22 +02005 * (C) 2020 sysmocom - s.f.m.c. GmbH
6 * All rights reserved.
7 *
8 * Author: Daniel Willmann <dwillmann@sysmocom.de>
9
10 * Released under the terms of GNU General Public License, Version 2 or
11 * (at your option) any later version.
12 *
13 * SPDX-License-Identifier: GPL-2.0-or-later
14 */
15
16import from General_Types all;
17import from Osmocom_Types all;
Harald Welteb9f0fdc2020-12-09 14:44:50 +010018import from Misc_Helpers all;
Daniel Willmann423d8f42020-09-08 18:58:22 +020019import from GSM_Types all;
20import from Native_Functions all;
21import from NS_Types all;
22import from NS_Emulation all;
23import from BSSGP_Types all;
24import from BSSGP_Emulation all;
25import from SCCPasp_Types all;
26import from Osmocom_Gb_Types all;
27
28import from MobileL3_CommonIE_Types all;
29import from MobileL3_GMM_SM_Types all;
30import from MobileL3_Types all;
31import from L3_Templates all;
32import from L3_Common all;
33
34import from TELNETasp_PortType all;
35import from Osmocom_VTY_Functions all;
Harald Welteb5688f22021-03-30 16:28:04 +020036import from Osmocom_CTRL_Adapter all;
Daniel Willmann423d8f42020-09-08 18:58:22 +020037
38import from LLC_Types all;
39import from LLC_Templates all;
40
41import from GSM_RR_Types all;
42
Harald Welte6d63f742020-11-15 19:44:04 +010043/* mcc_mnc is 24.008 10.5.5.15 encoded. 262 42 */
44const BcdMccMnc c_mcc_mnc := '262F42'H;
45
Harald Welte0d5fceb2020-11-29 16:04:07 +010046/* 48.016 section 6.1.4.2: The default maximum information field size of 1600 octets shall be supported on the Gb interface */
47const integer max_fr_info_size := 1600;
48
Daniel Willmann423d8f42020-09-08 18:58:22 +020049modulepar {
Harald Welteb5688f22021-03-30 16:28:04 +020050 charstring mp_gbproxy_ip := "127.0.0.1";
51 integer mp_gbproxy_ctrl_port := 4263;
Harald Welte77218d02021-01-15 19:59:15 +010052 /* NRI bit-length. 0 for no pooling */
53 integer mp_nri_bitlength := 5;
54 roro_integer mp_sgsn_nri := {
55 { 3 }, /* list of NRIs of first SGSN */
56 { 4 } /* list of NRIs of second SGSN */
57 };
Harald Weltef6e59b02020-12-08 08:29:09 +010058 boolean mp_enable_bss_load_sharing := false;
Daniel Willmann2c9300f2020-12-01 10:54:08 +010059 /* SGSN NS configuration */
Harald Welte6d63f742020-11-15 19:44:04 +010060 NSConfigurations mp_nsconfig_sgsn := {
Daniel Willmann423d8f42020-09-08 18:58:22 +020061 {
Daniel Willmann423d8f42020-09-08 18:58:22 +020062 nsei := 101,
63 role_sgsn := true,
Harald Welte90f19742020-11-06 19:34:40 +010064 handle_sns := false,
65 nsvc := {
66 {
67 provider := {
68 ip := {
69 address_family := AF_INET,
70 local_udp_port := 7777,
Harald Welted05a4a92021-01-18 12:03:53 +010071 local_ip := "127.0.0.10",
Harald Welte90f19742020-11-06 19:34:40 +010072 remote_udp_port := 23000,
Harald Weltebe7afce2021-01-17 22:04:36 +010073 remote_ip := "127.0.0.1",
Harald Welte388057d2021-01-18 18:52:49 +010074 data_weight := 0,
Harald Weltebe7afce2021-01-17 22:04:36 +010075 signalling_weight := 1
Harald Welte90f19742020-11-06 19:34:40 +010076 }
77 },
78 nsvci := 101
Harald Welte388057d2021-01-18 18:52:49 +010079 }, {
80 provider := {
81 ip := {
82 address_family := AF_INET,
83 local_udp_port := 7770,
84 local_ip := "127.0.0.10",
85 remote_udp_port := 23000,
86 remote_ip := "127.0.0.1",
87 data_weight := 1,
88 signalling_weight := 0
89 }
90 },
91 nsvci := 201
Harald Welte90f19742020-11-06 19:34:40 +010092 }
Harald Weltebe7afce2021-01-17 22:04:36 +010093
Harald Welte90f19742020-11-06 19:34:40 +010094 }
Harald Welteb978ed62020-12-12 14:01:11 +010095 }, {
96 nsei := 102,
97 role_sgsn := true,
98 handle_sns := false,
99 nsvc := {
100 {
101 provider := {
102 ip := {
103 address_family := AF_INET,
104 local_udp_port := 8888,
Harald Welted05a4a92021-01-18 12:03:53 +0100105 local_ip := "127.0.0.11",
Harald Welteb978ed62020-12-12 14:01:11 +0100106 remote_udp_port := 23000,
Harald Weltebe7afce2021-01-17 22:04:36 +0100107 remote_ip := "127.0.0.1",
Harald Welte388057d2021-01-18 18:52:49 +0100108 data_weight := 0,
Harald Weltebe7afce2021-01-17 22:04:36 +0100109 signalling_weight := 1
Harald Welteb978ed62020-12-12 14:01:11 +0100110 }
111 },
112 nsvci := 102
Harald Welte388057d2021-01-18 18:52:49 +0100113 }, {
114 provider := {
115 ip := {
116 address_family := AF_INET,
117 local_udp_port := 8880,
118 local_ip := "127.0.0.11",
119 remote_udp_port := 23000,
120 remote_ip := "127.0.0.1",
121 data_weight := 1,
122 signalling_weight := 0
123 }
124 },
125 nsvci := 202
Harald Welteb978ed62020-12-12 14:01:11 +0100126 }
127 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200128 }
129 };
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100130 /* BSS NSEI start at 2000 + x
131 * NSVCI start from value of NSEI + 100
132 * UDP port is NSVCI * 10 */
Harald Welte6d63f742020-11-15 19:44:04 +0100133 NSConfigurations mp_nsconfig_pcu := {
Daniel Willmann423d8f42020-09-08 18:58:22 +0200134 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100135 nsei := 2001,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200136 role_sgsn := false,
Harald Welte7079ce82021-04-01 17:38:51 +0200137 handle_sns := true,
Harald Welte90f19742020-11-06 19:34:40 +0100138 nsvc := {
139 {
140 provider := {
141 ip := {
142 address_family := AF_INET,
143 local_udp_port := 21010,
Harald Welted05a4a92021-01-18 12:03:53 +0100144 local_ip := "127.0.1.1",
Harald Welte90f19742020-11-06 19:34:40 +0100145 remote_udp_port := 23000,
Harald Welte7079ce82021-04-01 17:38:51 +0200146 remote_ip := "127.0.0.2",
Harald Weltebe7afce2021-01-17 22:04:36 +0100147 data_weight := 1,
148 signalling_weight := 1
Harald Welte90f19742020-11-06 19:34:40 +0100149 }
150 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100151 nsvci := 2101
Harald Welte90f19742020-11-06 19:34:40 +0100152 }
153 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200154 },
155 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100156 nsei := 2002,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200157 role_sgsn := false,
Harald Welte7079ce82021-04-01 17:38:51 +0200158 handle_sns := true,
Harald Welte90f19742020-11-06 19:34:40 +0100159 nsvc := {
160 {
161 provider := {
162 ip := {
163 address_family := AF_INET,
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100164 local_udp_port := 21020,
Harald Welted05a4a92021-01-18 12:03:53 +0100165 local_ip := "127.0.2.1",
Harald Welte90f19742020-11-06 19:34:40 +0100166 remote_udp_port := 23000,
Harald Welte7079ce82021-04-01 17:38:51 +0200167 remote_ip := "127.0.0.2",
Harald Weltebe7afce2021-01-17 22:04:36 +0100168 data_weight := 1,
169 signalling_weight := 1
Harald Welte90f19742020-11-06 19:34:40 +0100170 }
171 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100172 nsvci := 2102
Harald Welte90f19742020-11-06 19:34:40 +0100173 }
174 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200175 },
176 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100177 nsei := 2003,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200178 role_sgsn := false,
Harald Welte7079ce82021-04-01 17:38:51 +0200179 handle_sns := true,
Harald Welte90f19742020-11-06 19:34:40 +0100180 nsvc := {
181 {
182 provider := {
183 ip := {
184 address_family := AF_INET,
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100185 local_udp_port := 21030,
Harald Welted05a4a92021-01-18 12:03:53 +0100186 local_ip := "127.0.3.1",
Harald Welte90f19742020-11-06 19:34:40 +0100187 remote_udp_port := 23000,
Harald Welte7079ce82021-04-01 17:38:51 +0200188 remote_ip := "127.0.0.2",
Harald Weltebe7afce2021-01-17 22:04:36 +0100189 data_weight := 1,
190 signalling_weight := 1
Harald Welte90f19742020-11-06 19:34:40 +0100191 }
192 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100193 nsvci := 2103
Harald Welte90f19742020-11-06 19:34:40 +0100194 }
195 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200196 }
197 };
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100198 /* BVCI are NSEI*10 + x
199 * The first NSE only has one BVC, the second one 2 and so on
200 * The Cell ID is BVCI + 10000
201 * LAC/RAC are configured in such a way that:
202 * LAC 13135 is present once in NSE(2001), twice in NSE(2002) and once in NSE(2003)
203 * LAC 13300 is present twice in NSE(2003)
204 * RAI 13135-1 is present in NSE(2002) and NSE(2003)
205 * RAI 13300-0 is present twice in NSE(2003)
206 */
Harald Welte6d63f742020-11-15 19:44:04 +0100207 BssgpConfigs mp_gbconfigs := {
208 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100209 nsei := 2001,
Harald Welte6d63f742020-11-15 19:44:04 +0100210 sgsn_role := false,
211 bvc := {
212 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100213 bvci := 20011,
Harald Welte6d63f742020-11-15 19:44:04 +0100214 cell_id := {
215 ra_id := {
216 lai := {
217 mcc_mnc := c_mcc_mnc,
218 lac := 13135
219 },
220 rac := 0
221 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100222 cell_id := 30011
Harald Welte6d63f742020-11-15 19:44:04 +0100223 },
224 depth := BSSGP_DECODE_DEPTH_BSSGP,
225 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
226 }
227 }
228 }, {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100229 nsei := 2002,
Harald Welte6d63f742020-11-15 19:44:04 +0100230 sgsn_role := false,
231 bvc := {
232 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100233 bvci := 20021,
Harald Welte6d63f742020-11-15 19:44:04 +0100234 cell_id := {
235 ra_id := {
236 lai := {
237 mcc_mnc := c_mcc_mnc,
Harald Welte0e188242020-11-22 21:46:48 +0100238 lac := 13135
Harald Welte6d63f742020-11-15 19:44:04 +0100239 },
Harald Welte0e188242020-11-22 21:46:48 +0100240 rac := 1
Harald Welte6d63f742020-11-15 19:44:04 +0100241 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100242 cell_id := 30021
243 },
244 depth := BSSGP_DECODE_DEPTH_BSSGP,
245 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
246 },
247 {
248 bvci := 20022,
249 cell_id := {
250 ra_id := {
251 lai := {
252 mcc_mnc := c_mcc_mnc,
253 lac := 13135
254 },
255 rac := 2
256 },
257 cell_id := 30022
Harald Welte6d63f742020-11-15 19:44:04 +0100258 },
259 depth := BSSGP_DECODE_DEPTH_BSSGP,
260 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
261 }
262 }
263 }, {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100264 nsei := 2003,
Harald Welte6d63f742020-11-15 19:44:04 +0100265 sgsn_role := false,
266 bvc := {
267 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100268 bvci := 20031,
269 cell_id := {
270 ra_id := {
271 lai := {
272 mcc_mnc := c_mcc_mnc,
273 lac := 13135
274 },
275 rac := 1
276 },
277 cell_id := 30031
278 },
279 depth := BSSGP_DECODE_DEPTH_BSSGP,
280 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
281 },
282 {
283 bvci := 20032,
Harald Welte6d63f742020-11-15 19:44:04 +0100284 cell_id := {
285 ra_id := {
286 lai := {
287 mcc_mnc := c_mcc_mnc,
288 lac := 13300
289 },
290 rac := 0
291 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100292 cell_id := 30032
293 },
294 depth := BSSGP_DECODE_DEPTH_BSSGP,
295 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
296 },
297 {
298 bvci := 20033,
299 cell_id := {
300 ra_id := {
301 lai := {
302 mcc_mnc := c_mcc_mnc,
303 lac := 13300
304 },
305 rac := 0
306 },
307 cell_id := 30033
Harald Welte6d63f742020-11-15 19:44:04 +0100308 },
309 depth := BSSGP_DECODE_DEPTH_BSSGP,
310 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
311 }
312 }
313 }
314 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200315};
316
Daniel Willmann423d8f42020-09-08 18:58:22 +0200317type record GbInstance {
318 NS_CT vc_NS,
319 BSSGP_CT vc_BSSGP,
Harald Welte67dc8c22020-11-17 18:32:29 +0100320 BSSGP_BVC_CTs vc_BSSGP_BVC,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200321 BssgpConfig cfg
322};
Harald Welte67dc8c22020-11-17 18:32:29 +0100323type record of BSSGP_BVC_CT BSSGP_BVC_CTs
Daniel Willmann423d8f42020-09-08 18:58:22 +0200324
325const integer NUM_PCU := 3;
Harald Welte6d63f742020-11-15 19:44:04 +0100326type record of GbInstance GbInstances;
327type record of BssgpConfig BssgpConfigs;
328type record of NSConfiguration NSConfigurations;
329type record of BssgpCellId BssgpCellIds;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200330
Harald Welte572b0172021-03-30 13:19:56 +0200331/* you cannot simply change this to any larger number of SGSNs and expect all test
332 * cases to work. This would have overly complicated the code. Check below for
333 * tests that use interleave on SGSN_MGMT.receive() for each SGSN NSEI for example */
Harald Welteb978ed62020-12-12 14:01:11 +0100334const integer NUM_SGSN := 2;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200335
Harald Welteb5688f22021-03-30 16:28:04 +0200336type component test_CT extends CTRL_Adapter_CT {
Harald Welte6d63f742020-11-15 19:44:04 +0100337 var GbInstances g_pcu;
338 var GbInstances g_sgsn;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200339
Daniel Willmann8d9fcf42021-05-28 15:05:41 +0200340 port NS_CTRL_PT NS_CTRL;
341
Daniel Willmann423d8f42020-09-08 18:58:22 +0200342 port BSSGP_CT_PROC_PT PROC;
343
Harald Weltefbae83f2020-11-15 23:25:55 +0100344 port BSSGP_BVC_MGMT_PT SGSN_MGMT;
345 port BSSGP_BVC_MGMT_PT PCU_MGMT;
346
Daniel Willmann423d8f42020-09-08 18:58:22 +0200347 port TELNETasp_PT GBPVTY;
348
349 var boolean g_initialized := false;
350 var boolean g_use_echo := false;
Harald Welte16786e92020-11-27 19:11:56 +0100351
352 var ro_integer g_roi := {};
Daniel Willmannc38c85d2021-01-21 18:11:12 +0100353 var roro_integer g_roroi := {};
Harald Welte425d3762020-12-09 14:33:18 +0100354 timer g_Tguard;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200355};
356
357type component BSSGP_ConnHdlr {
Harald Welte3dd21b32020-11-17 19:21:00 +0100358 /* array of per-BVC ports on the PCU side */
Harald Welte158becf2020-12-09 12:32:32 +0100359 port BSSGP_PT PCU_PTP[NUM_PCU];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200360 port BSSGP_PT PCU_SIG[NUM_PCU];
361 port BSSGP_PROC_PT PCU_PROC[NUM_PCU];
Harald Welte3dd21b32020-11-17 19:21:00 +0100362 /* component reference to the component to which we're currently connected */
363 var BSSGP_BVC_CT pcu_ct[NUM_PCU];
Harald Welte0e188242020-11-22 21:46:48 +0100364 /* BSSGP BVC configuration of the component to which we're currently connected */
365 var BssgpBvcConfig pcu_bvc_cfg[NUM_PCU];
Harald Welte3dd21b32020-11-17 19:21:00 +0100366
367 /* array of per-BVC ports on the SGSN side */
Harald Welte158becf2020-12-09 12:32:32 +0100368 port BSSGP_PT SGSN_PTP[NUM_SGSN];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200369 port BSSGP_PT SGSN_SIG[NUM_SGSN];
370 port BSSGP_PROC_PT SGSN_PROC[NUM_SGSN];
Harald Welte3dd21b32020-11-17 19:21:00 +0100371 /* component reference to the component to which we're currently connected */
372 var BSSGP_BVC_CT sgsn_ct[NUM_PCU];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200373
374 var BSSGP_ConnHdlrPars g_pars;
375 timer g_Tguard;
376 var LLC_Entities llc;
Harald Welte0e188242020-11-22 21:46:48 +0100377
378 var ro_integer g_roi := {};
Daniel Willmann423d8f42020-09-08 18:58:22 +0200379}
380
381type record SGSN_ConnHdlrNetworkPars {
382 boolean expect_ptmsi,
383 boolean expect_auth,
384 boolean expect_ciph
385};
386
387type record BSSGP_ConnHdlrPars {
388 /* IMEI of the simulated ME */
389 hexstring imei,
390 /* IMSI of the simulated MS */
391 hexstring imsi,
392 /* MSISDN of the simulated MS (probably unused) */
393 hexstring msisdn,
394 /* P-TMSI allocated to the simulated MS */
395 OCT4 p_tmsi optional,
396 OCT3 p_tmsi_sig optional,
397 /* TLLI of the simulated MS */
398 OCT4 tlli,
399 OCT4 tlli_old optional,
400 RoutingAreaIdentificationV ra optional,
Harald Welte16357a92020-11-17 18:20:00 +0100401 GbInstances pcu,
Harald Welte3dd21b32020-11-17 19:21:00 +0100402 GbInstances sgsn,
Harald Weltec5f486b2021-01-16 11:07:01 +0100403 /* The SGSN index to be used within the test */
404 integer sgsn_idx,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200405 float t_guard
406};
407
Harald Welte04358652021-01-17 13:48:13 +0100408private function get_bvc_idx_for_bvci(GbInstance gbi, BssgpBvci bvci) return integer
409{
410 var integer i;
411
412 for (i := 0; i < lengthof(gbi.cfg.bvc); i := i + 1) {
413 if (gbi.cfg.bvc[i].bvci == bvci) {
414 return i;
415 }
416 }
417 setverdict(fail, "Could not find BVC Index for BVCI ", bvci);
418 return -1;
419}
420
Daniel Willmann423d8f42020-09-08 18:58:22 +0200421private function f_cellid_to_RAI(in BssgpCellId cell_id) return RoutingAreaIdentificationV {
422 /* mcc_mnc is encoded as of 24.008 10.5.5.15 */
423 var BcdMccMnc mcc_mnc := cell_id.ra_id.lai.mcc_mnc;
424
425 var RoutingAreaIdentificationV ret := {
426 mccDigit1 := mcc_mnc[0],
427 mccDigit2 := mcc_mnc[1],
428 mccDigit3 := mcc_mnc[2],
429 mncDigit3 := mcc_mnc[3],
430 mncDigit1 := mcc_mnc[4],
431 mncDigit2 := mcc_mnc[5],
432 lac := int2oct(cell_id.ra_id.lai.lac, 16),
433 rac := int2oct(cell_id.ra_id.rac, 8)
434 }
435 return ret;
436};
437
Harald Welte95339432020-12-02 18:50:52 +0100438private function f_fix_create_cb(inout BssgpConfig cfg)
439{
440 for (var integer i := 0; i < lengthof(cfg.bvc); i := i + 1) {
441 if (not isbound(cfg.bvc[i].create_cb)) {
442 cfg.bvc[i].create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
443 }
444 }
445}
446
Daniel Willmann423d8f42020-09-08 18:58:22 +0200447private function f_init_gb_pcu(inout GbInstance gb, charstring id, integer offset) runs on test_CT {
Harald Welteb419d0e2020-11-16 16:45:05 +0100448 var charstring ns_id := id & "-NS(PCU[" & int2str(offset) & "])";
449 var charstring bssgp_id := id & "-BSSGP(PCU[" & int2str(offset) & "])";
450 gb.vc_NS := NS_CT.create(ns_id);
451 gb.vc_BSSGP := BSSGP_CT.create(bssgp_id);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200452 /* connect lower end of BSSGP emulation with NS upper port */
453 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
454
Harald Welteb419d0e2020-11-16 16:45:05 +0100455 gb.vc_NS.start(NSStart(mp_nsconfig_pcu[offset], ns_id));
456 gb.vc_BSSGP.start(BssgpStart(gb.cfg, bssgp_id));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200457
458 for (var integer i := 0; i < lengthof(gb.cfg.bvc); i := i + 1) {
Harald Welteb978ed62020-12-12 14:01:11 +0100459 /* obtain the component reference of the BSSGP_BVC_CT for each PTP BVC */
Daniel Willmann423d8f42020-09-08 18:58:22 +0200460 connect(self:PROC, gb.vc_BSSGP:PROC);
461 gb.vc_BSSGP_BVC[i] := f_bssgp_get_bvci_ct(gb.cfg.bvc[i].bvci, PROC);
462 disconnect(self:PROC, gb.vc_BSSGP:PROC);
Harald Welteb978ed62020-12-12 14:01:11 +0100463 /* connect all of the per-BVC MGMT ports to our PCU_MGMT port (1:N) */
Harald Weltefbae83f2020-11-15 23:25:55 +0100464 connect(self:PCU_MGMT, gb.vc_BSSGP_BVC[i]:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200465 }
Harald Welteb978ed62020-12-12 14:01:11 +0100466 /* connect all of the BSSGP/NSE global MGMT port to our PCU_MGMT port (1:N) */
Harald Welte16786e92020-11-27 19:11:56 +0100467 connect(self:PCU_MGMT, gb.vc_BSSGP:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200468}
469
470private function f_init_gb_sgsn(inout GbInstance gb, charstring id, integer offset) runs on test_CT {
Harald Welteb419d0e2020-11-16 16:45:05 +0100471 var charstring ns_id := id & "-NS(SGSN[" & int2str(offset) & "])";
472 var charstring bssgp_id := id & "-BSSGP(SGSN[" & int2str(offset) & "])";
473 gb.vc_NS := NS_CT.create(ns_id);
474 gb.vc_BSSGP := BSSGP_CT.create(bssgp_id);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200475 /* connect lower end of BSSGP emulation with NS upper port */
476 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
477
Harald Welteb419d0e2020-11-16 16:45:05 +0100478 gb.vc_NS.start(NSStart(mp_nsconfig_sgsn[offset], ns_id));
479 gb.vc_BSSGP.start(BssgpStart(gb.cfg, bssgp_id));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200480
481 for (var integer i := 0; i < lengthof(gb.cfg.bvc); i := i + 1) {
Harald Welteb978ed62020-12-12 14:01:11 +0100482 /* obtain the component reference of the BSSGP_BVC_CT for each PTP BVC */
Daniel Willmann423d8f42020-09-08 18:58:22 +0200483 connect(self:PROC, gb.vc_BSSGP:PROC);
484 gb.vc_BSSGP_BVC[i] := f_bssgp_get_bvci_ct(gb.cfg.bvc[i].bvci, PROC);
485 disconnect(self:PROC, gb.vc_BSSGP:PROC);
Harald Welteb978ed62020-12-12 14:01:11 +0100486 /* connect all of the per-BVC MGMT ports to our SGSN_MGMT port (1:N) */
Harald Weltefbae83f2020-11-15 23:25:55 +0100487 connect(self:SGSN_MGMT, gb.vc_BSSGP_BVC[i]:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200488 }
Harald Welteb978ed62020-12-12 14:01:11 +0100489 /* connect all of the BSSGP/NSE global MGMT port to our SGSN_MGMT port (1:N) */
Harald Welte16786e92020-11-27 19:11:56 +0100490 connect(self:SGSN_MGMT, gb.vc_BSSGP:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200491}
492
493
Harald Welteb9f0fdc2020-12-09 14:44:50 +0100494private function f_destroy_gb(inout GbInstance gb) runs on test_CT {
495 gb.vc_NS.stop;
496 gb.vc_BSSGP.stop;
497
498 for (var integer i := 0; i < lengthof(gb.cfg.bvc); i := i + 1) {
499 gb.vc_BSSGP_BVC[i].stop;
500 }
501}
502
Daniel Willmann423d8f42020-09-08 18:58:22 +0200503private function f_init_vty() runs on test_CT {
504 map(self:GBPVTY, system:GBPVTY);
505 f_vty_set_prompts(GBPVTY);
506 f_vty_transceive(GBPVTY, "enable");
507}
508
Harald Welteb978ed62020-12-12 14:01:11 +0100509/* count the number of unblocked BVCI for each SGSN NSE */
510private altstep as_count_unblocked4nse(integer sgsn_idx, inout roro_integer bvci_unblocked)
511runs on test_CT {
512 var BssgpStatusIndication bsi;
513 [] SGSN_MGMT.receive(BssgpStatusIndication:{g_sgsn[sgsn_idx].cfg.nsei, ?, BVC_S_UNBLOCKED}) -> value bsi {
514 bvci_unblocked[sgsn_idx] := bvci_unblocked[sgsn_idx] & { bsi.bvci };
515 /* 'repeat' until sufficient number of BVC-rest has been received on all SGSNs */
516 for (var integer i := 0; i < lengthof(bvci_unblocked); i := i+1) {
517 if (lengthof(bvci_unblocked[i]) < lengthof(g_sgsn[i].cfg.bvc)) {
518 repeat;
519 }
520 }
521 }
522}
523
Harald Welteb5688f22021-03-30 16:28:04 +0200524private template (value) charstring ts_pcu_bvc_fsm_id(uint16_t nsei, uint16_t bvci) :=
525 "NSE" & f_int2str(nsei, 5) & "-BVC" & f_int2str(bvci, 5);
526
527function f_bvc_fsm_ensure_state(uint16_t nsei, uint16_t bvci, template (present) charstring exp)
528runs on CTRL_Adapter_CT {
529 f_ctrl_get_exp_inst_state(IPA_CTRL, "BSSGP-BVC", ts_pcu_bvc_fsm_id(nsei, bvci), exp);
530}
531
Harald Welte425d3762020-12-09 14:33:18 +0100532function f_init(float t_guard := 30.0) runs on test_CT {
Harald Welteb978ed62020-12-12 14:01:11 +0100533 var roro_integer bvci_unblocked;
Harald Weltefbae83f2020-11-15 23:25:55 +0100534 var BssgpStatusIndication bsi;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200535 var integer i;
536
537 if (g_initialized == true) {
538 return;
539 }
540 g_initialized := true;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200541
Harald Welte425d3762020-12-09 14:33:18 +0100542 g_Tguard.start(t_guard);
543 activate(as_gTguard(g_Tguard));
544
Harald Welteb5688f22021-03-30 16:28:04 +0200545 f_ipa_ctrl_start_client(mp_gbproxy_ip, mp_gbproxy_ctrl_port);
546
Harald Welteb978ed62020-12-12 14:01:11 +0100547 var BssgpBvcConfigs bvcs := { };
Harald Welte6d63f742020-11-15 19:44:04 +0100548 for (i := 0; i < lengthof(mp_gbconfigs); i := i+1) {
549 g_pcu[i].cfg := mp_gbconfigs[i];
Harald Welte95339432020-12-02 18:50:52 +0100550 /* make sure all have a proper crate_cb, which cannot be specified in config file */
551 f_fix_create_cb(g_pcu[i].cfg);
Harald Welte6d63f742020-11-15 19:44:04 +0100552 /* concatenate all the PCU-side BVCs for the SGSN side */
Harald Welteb978ed62020-12-12 14:01:11 +0100553 bvcs := bvcs & g_pcu[i].cfg.bvc;
554 }
555
556 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
557 g_sgsn[i].cfg := {
558 nsei := mp_nsconfig_sgsn[i].nsei,
559 sgsn_role := true,
560 bvc := bvcs
561 }
Harald Welte6d63f742020-11-15 19:44:04 +0100562 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200563
564 f_init_vty();
Harald Welte6d63f742020-11-15 19:44:04 +0100565 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
Daniel Willmann443fc572020-11-18 13:26:57 +0100566 f_vty_transceive(GBPVTY, "nsvc nsei " & int2str(g_sgsn[i].cfg.nsei) & " force-unconfigured");
Daniel Willmannad93c052020-12-04 14:14:38 +0100567 }
568 for (i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
569 f_vty_transceive(GBPVTY, "nsvc nsei " & int2str(g_pcu[i].cfg.nsei) & " force-unconfigured");
570 f_vty_transceive(GBPVTY, "delete-gbproxy-peer " & int2str(g_pcu[i].cfg.nsei) & " only-bvc");
571 }
572
573 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
Harald Welteea1ba592020-11-17 18:05:13 +0100574 f_init_gb_sgsn(g_sgsn[i], "GbProxy_Test", i);
Harald Welte6d63f742020-11-15 19:44:04 +0100575 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200576 f_sleep(4.0);
Harald Welte6d63f742020-11-15 19:44:04 +0100577 for (i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
Harald Welteb419d0e2020-11-16 16:45:05 +0100578 f_init_gb_pcu(g_pcu[i], "GbProxy_Test", i);
Harald Welte6d63f742020-11-15 19:44:04 +0100579 }
Harald Weltefbae83f2020-11-15 23:25:55 +0100580
Harald Welteb978ed62020-12-12 14:01:11 +0100581 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
582 bvci_unblocked[i] := {};
583 }
584
Harald Weltefbae83f2020-11-15 23:25:55 +0100585 /* wait until all BVC are unblocked on both sides */
Harald Welted2801272020-11-17 19:22:58 +0100586 timer T := 15.0;
Harald Weltefbae83f2020-11-15 23:25:55 +0100587 T.start;
588 alt {
Harald Welteb978ed62020-12-12 14:01:11 +0100589 /* TODO: We need to add more lines if NUM_SGSN increases. Activating default altsteps
590 * unfortunately doesn't work as we want to access the local variable bvci_unblocked. */
591 [] as_count_unblocked4nse(0, bvci_unblocked);
592 [lengthof(g_sgsn) > 1] as_count_unblocked4nse(1, bvci_unblocked);
Harald Weltefbae83f2020-11-15 23:25:55 +0100593 [] SGSN_MGMT.receive(BssgpStatusIndication:{*, ?, ?}) {
594 repeat;
595 }
Harald Welte3c905152020-11-26 20:56:09 +0100596 [] SGSN_MGMT.receive(BssgpResetIndication:?) {
597 repeat;
598 }
Harald Weltefbae83f2020-11-15 23:25:55 +0100599 [] SGSN_MGMT.receive {
Harald Welted5b7e742021-01-27 10:50:24 +0100600 f_shutdown(__FILE__, __LINE__, fail, "Received unexpected message on SGSN_MGMT");
Harald Weltefbae83f2020-11-15 23:25:55 +0100601 }
602
603 [] PCU_MGMT.receive(BssgpStatusIndication:{*, ?, BVC_S_UNBLOCKED}) -> value bsi {
604 repeat;
605 }
606 [] PCU_MGMT.receive(BssgpStatusIndication:{*, ?, ?}) {
607 repeat;
608 }
609 [] PCU_MGMT.receive(BssgpResetIndication:{0}) {
610 repeat;
611 }
612 [] PCU_MGMT.receive {
Harald Welted5b7e742021-01-27 10:50:24 +0100613 f_shutdown(__FILE__, __LINE__, fail, "Received unexpected message on PCU_MGMT");
Harald Weltefbae83f2020-11-15 23:25:55 +0100614 }
615
616 [] T.timeout {
Harald Welte6929e322020-12-12 13:10:45 +0100617 setverdict(fail, "Timeout waiting for unblock of all BVCs on SGSN side; ",
Harald Welteb978ed62020-12-12 14:01:11 +0100618 "unblocked so far: ", bvci_unblocked);
Harald Welte6929e322020-12-12 13:10:45 +0100619 /* don't stop here but print below analysis */
Harald Weltefbae83f2020-11-15 23:25:55 +0100620 }
621 }
622
Harald Welteb978ed62020-12-12 14:01:11 +0100623 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
624 /* iterate over list and check all BVCI */
625 for (var integer j := 0; j < lengthof(g_sgsn[i].cfg.bvc); j := j+1) {
626 var BssgpBvci bvci := g_sgsn[i].cfg.bvc[j].bvci;
627 if (not ro_integer_contains(bvci_unblocked[i], bvci)) {
Harald Welted5b7e742021-01-27 10:50:24 +0100628 f_shutdown(__FILE__, __LINE__, fail,
629 log2str("SGSN ", i, " BVCI=", bvci, " was not unblocked during start-up"));
Harald Welteb978ed62020-12-12 14:01:11 +0100630 }
Harald Weltefbae83f2020-11-15 23:25:55 +0100631 }
632 }
Harald Welte425d3762020-12-09 14:33:18 +0100633
Daniel Willmannd70d45a2021-07-23 10:23:51 +0200634 /* Wait to ensure the gbproxy processed the RESET_ACK messages from the SGSN.
635 * Otherwise the state might still be WAIT_RESET_ACK */
636 f_sleep(0.2);
637
Harald Welteb5688f22021-03-30 16:28:04 +0200638 /* verify all SGSN-side BVC FSM in IUT are UNBLOCKED */
639 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
640 f_bvc_fsm_ensure_state(mp_nsconfig_sgsn[i].nsei, 0, "UNBLOCKED");
641 /* iterate over list and check all BVCI */
642 for (var integer j := 0; j < lengthof(g_sgsn[i].cfg.bvc); j := j+1) {
643 var BssgpBvci bvci := g_sgsn[i].cfg.bvc[j].bvci;
644 f_bvc_fsm_ensure_state(mp_nsconfig_sgsn[i].nsei, bvci, "UNBLOCKED");
645 }
646 }
647 /* verify all PCU-side BVC FSM in IUT are UNBLOCKED */
648 for (i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
649 f_bvc_fsm_ensure_state(mp_nsconfig_pcu[i].nsei, 0, "UNBLOCKED");
650 /* iterate over list and check all BVCI */
651 for (var integer j := 0; j < lengthof(g_pcu[i].cfg.bvc); j := j+1) {
652 var BssgpBvci bvci := g_pcu[i].cfg.bvc[j].bvci;
653 f_bvc_fsm_ensure_state(mp_nsconfig_pcu[i].nsei, bvci, "UNBLOCKED");
654 }
655 }
656
Harald Welte425d3762020-12-09 14:33:18 +0100657 /* re-start guard timer after all BVCs are up, so it only counts the actual test case */
658 g_Tguard.start(t_guard);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200659}
660
661function f_cleanup() runs on test_CT {
Harald Welteb9f0fdc2020-12-09 14:44:50 +0100662 var integer i;
663
Daniel Willmann491af2a2021-01-08 01:32:51 +0100664 /* To avoid a dynamic test case error we need to prevent messages arriving on unconnected
665 * ports. Waiting here ensures that any messages "in flight" will be delivered to the port
666 * before the component is shutdown and disconnected. */
667 f_sleep(0.2);
668
Harald Welteb9f0fdc2020-12-09 14:44:50 +0100669 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
670 f_destroy_gb(g_sgsn[i]);
671 }
672 for (i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
673 f_destroy_gb(g_pcu[i]);
674 }
675
676 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, pass);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200677}
678
679type function void_fn(charstring id) runs on BSSGP_ConnHdlr;
680
681/* helper function to create, connect and start a BSSGP_ConnHdlr component */
Harald Welte207166c2021-01-16 12:52:30 +0100682function f_start_handler(void_fn fn, charstring id, integer imsi_suffix, float t_guard := 30.0,
683 integer sgsn_idx := 0, integer nri_idx := 0, boolean have_ptmsi := true)
Daniel Willmann423d8f42020-09-08 18:58:22 +0200684runs on test_CT return BSSGP_ConnHdlr {
685 var BSSGP_ConnHdlr vc_conn;
Harald Weltec5f486b2021-01-16 11:07:01 +0100686 var integer nri := mp_sgsn_nri[sgsn_idx][nri_idx];
Harald Welte77218d02021-01-15 19:59:15 +0100687 var OCT4 p_tmsi := f_gen_tmsi(imsi_suffix, nri_v := nri, nri_bitlen := mp_nri_bitlength);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200688
689 var BSSGP_ConnHdlrPars pars := {
690 imei := f_gen_imei(imsi_suffix),
691 imsi := f_gen_imsi(imsi_suffix),
692 msisdn := f_gen_msisdn(imsi_suffix),
Harald Weltedbd5e672021-01-14 21:03:14 +0100693 p_tmsi := p_tmsi,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200694 p_tmsi_sig := omit,
Harald Weltedbd5e672021-01-14 21:03:14 +0100695 tlli := f_gprs_tlli_from_tmsi(p_tmsi, TLLI_LOCAL),
Daniel Willmann423d8f42020-09-08 18:58:22 +0200696 tlli_old := omit,
697 ra := omit,
Harald Welte2ecbca82021-01-16 11:23:09 +0100698 pcu := g_pcu,
699 sgsn := g_sgsn,
Harald Weltec5f486b2021-01-16 11:07:01 +0100700 sgsn_idx := sgsn_idx,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200701 t_guard := t_guard
702 };
Harald Welte207166c2021-01-16 12:52:30 +0100703 if (not have_ptmsi) {
704 pars.p_tmsi := omit;
705 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200706
707 vc_conn := BSSGP_ConnHdlr.create(id);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200708
Harald Welte25a04b12021-01-17 11:09:49 +0100709 log("Starting ", id, " for SGSN[", sgsn_idx, "], NRI=", nri, ", P-TMSI=", pars.p_tmsi,
710 ", TLLI=", pars.tlli, ", IMSI=", pars.imsi, " on component=", vc_conn);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200711 vc_conn.start(f_handler_init(fn, id, pars));
712 return vc_conn;
713}
714
Harald Welte207166c2021-01-16 12:52:30 +0100715function f_start_handlers(void_fn fn, charstring id, integer imsi_suffix, float t_guard := 30.0,
716 boolean have_ptmsi := true)
Harald Weltec5f486b2021-01-16 11:07:01 +0100717runs on test_CT
718{
719 var integer sgsn_idx, nri_idx;
720 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx:=sgsn_idx+1) {
721 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx:=nri_idx+1) {
722 var integer extd_imsi_suffix := 1000*sgsn_idx + 100*nri_idx;
723 var BSSGP_ConnHdlr vc_conn;
Harald Welte207166c2021-01-16 12:52:30 +0100724 vc_conn := f_start_handler(fn, id, extd_imsi_suffix, t_guard, sgsn_idx, nri_idx,
725 have_ptmsi);
Harald Weltec5f486b2021-01-16 11:07:01 +0100726 /* Idea: we could also run them in parallel ? */
727 vc_conn.done;
728 }
729 }
730}
731
Harald Welte3dd21b32020-11-17 19:21:00 +0100732/* Connect the PCU-side per-BVC ports (PCU/PCU_SIG/PCU_PROC) array slot 'port_idx' to specified per-BVC component */
Harald Welte0e188242020-11-22 21:46:48 +0100733private function f_connect_to_pcu_bvc(integer port_idx, integer nse_idx, integer bvc_idx)
734runs on BSSGP_ConnHdlr {
735 var BSSGP_BVC_CT bvc_ct := g_pars.pcu[nse_idx].vc_BSSGP_BVC[bvc_idx]
Harald Welte158becf2020-12-09 12:32:32 +0100736 if (PCU_PTP[port_idx].checkstate("Connected")) {
Harald Welte3dd21b32020-11-17 19:21:00 +0100737 /* unregister + disconnect from old BVC */
738 f_client_unregister(g_pars.imsi, PCU_PROC[port_idx]);
Harald Welte158becf2020-12-09 12:32:32 +0100739 disconnect(self:PCU_PTP[port_idx], pcu_ct[port_idx]:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100740 disconnect(self:PCU_SIG[port_idx], pcu_ct[port_idx]:BSSGP_SP_SIG);
741 disconnect(self:PCU_PROC[port_idx], pcu_ct[port_idx]:BSSGP_PROC);
742 }
743 /* connect to new BVC and register us */
Harald Welte158becf2020-12-09 12:32:32 +0100744 connect(self:PCU_PTP[port_idx], bvc_ct:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100745 connect(self:PCU_SIG[port_idx], bvc_ct:BSSGP_SP_SIG);
746 connect(self:PCU_PROC[port_idx], bvc_ct:BSSGP_PROC);
747 f_client_register(g_pars.imsi, g_pars.tlli, PCU_PROC[port_idx]);
748 pcu_ct[port_idx] := bvc_ct;
Harald Welte0e188242020-11-22 21:46:48 +0100749 pcu_bvc_cfg[port_idx] := g_pars.pcu[nse_idx].cfg.bvc[bvc_idx];
Harald Welte3dd21b32020-11-17 19:21:00 +0100750}
751
752/* Connect the SGSN-side per-BVC ports (SGSN/SGSN_SIG/SGSN_PROC) array slot 'port_idx' to specified per-BVC component */
753private function f_connect_to_sgsn_bvc(integer port_idx, BSSGP_BVC_CT bvc_ct) runs on BSSGP_ConnHdlr {
Harald Welte158becf2020-12-09 12:32:32 +0100754 if (SGSN_PTP[port_idx].checkstate("Connected")) {
Harald Welte3dd21b32020-11-17 19:21:00 +0100755 /* unregister + disconnect from old BVC */
756 f_client_unregister(g_pars.imsi, SGSN_PROC[port_idx]);
Harald Welte158becf2020-12-09 12:32:32 +0100757 disconnect(self:SGSN_PTP[port_idx], sgsn_ct[port_idx]:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100758 disconnect(self:SGSN_SIG[port_idx], sgsn_ct[port_idx]:BSSGP_SP_SIG);
759 disconnect(self:SGSN_PROC[port_idx], sgsn_ct[port_idx]:BSSGP_PROC);
760 }
761 /* connect to new BVC and register us */
Harald Welte158becf2020-12-09 12:32:32 +0100762 connect(self:SGSN_PTP[port_idx], bvc_ct:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100763 connect(self:SGSN_SIG[port_idx], bvc_ct:BSSGP_SP_SIG);
764 connect(self:SGSN_PROC[port_idx], bvc_ct:BSSGP_PROC);
765 f_client_register(g_pars.imsi, g_pars.tlli, SGSN_PROC[port_idx]);
766 sgsn_ct[port_idx] := bvc_ct;
767}
768
Harald Welte425d3762020-12-09 14:33:18 +0100769private altstep as_gTguard(timer Tguard) {
770 [] Tguard.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +0100771 f_shutdown(__FILE__, __LINE__, fail, "Tguard timeout");
Daniel Willmann423d8f42020-09-08 18:58:22 +0200772 }
773}
774
775/* first function called in every ConnHdlr */
776private function f_handler_init(void_fn fn, charstring id, BSSGP_ConnHdlrPars pars)
777runs on BSSGP_ConnHdlr {
Harald Welte1e834f32020-11-15 20:02:59 +0100778 var integer i;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200779 /* do some common stuff like setting up g_pars */
780 g_pars := pars;
781
782 llc := f_llc_create(false);
783
Harald Welte3dd21b32020-11-17 19:21:00 +0100784 /* default connections on PCU side: First BVC of each NSE/PCU */
785 for (i := 0; i < lengthof(g_pars.pcu); i := i+1) {
Harald Welte0e188242020-11-22 21:46:48 +0100786 f_connect_to_pcu_bvc(port_idx := i, nse_idx := i, bvc_idx := 0);
Harald Welte1e834f32020-11-15 20:02:59 +0100787 }
Harald Welte3dd21b32020-11-17 19:21:00 +0100788
789 /* default connections on SGSN side: First BVC of each NSE/SGSN */
790 for (i := 0; i < lengthof(g_pars.sgsn); i := i+1) {
791 f_connect_to_sgsn_bvc(i, g_pars.sgsn[i].vc_BSSGP_BVC[0]);
Harald Welte1e834f32020-11-15 20:02:59 +0100792 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200793
794 g_Tguard.start(pars.t_guard);
Harald Welte425d3762020-12-09 14:33:18 +0100795 activate(as_gTguard(g_Tguard));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200796
797 /* call the user-supplied test case function */
798 fn.apply(id);
Harald Welteb33fb592021-01-16 12:50:56 +0100799
800 for (i := 0; i < NUM_SGSN; i := i+1) {
801 if (SGSN_PROC[i].checkstate("Connected")) {
802 f_client_unregister(g_pars.imsi, SGSN_PROC[i])
803 }
804 }
805
806 for (i := 0; i < NUM_PCU; i := i+1) {
807 if (PCU_PROC[i].checkstate("Connected")) {
808 f_client_unregister(g_pars.imsi, PCU_PROC[i])
809 }
810 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200811}
812
Harald Welte1e834f32020-11-15 20:02:59 +0100813private function f_client_register(hexstring imsi, OCT4 tlli, BSSGP_PROC_PT PT)
814runs on BSSGP_ConnHdlr {
815 PT.call(BSSGP_register_client:{imsi, tlli}) {
816 [] PT.getreply(BSSGP_register_client:{imsi, tlli}) {};
817 }
818}
819
820private function f_client_unregister(hexstring imsi, BSSGP_PROC_PT PT)
821runs on BSSGP_ConnHdlr {
822 PT.call(BSSGP_unregister_client:{imsi}) {
823 [] PT.getreply(BSSGP_unregister_client:{imsi}) {};
824 }
825}
826
Harald Welte22ef5d92020-11-16 13:35:14 +0100827/* Send 'tx' on PTP-BVCI from PCU; expect 'rx' on SGSN */
828friend function f_pcu2sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
Harald Weltec5f486b2021-01-16 11:07:01 +0100829 integer pcu_idx := 0, boolean use_sig := false) runs on BSSGP_ConnHdlr {
830 var integer sgsn_idx := g_pars.sgsn_idx;
Harald Welte22ef5d92020-11-16 13:35:14 +0100831 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +0100832 timer T := 2.0;
Harald Welte22ef5d92020-11-16 13:35:14 +0100833
Daniel Willmann4798fd72020-11-24 16:23:29 +0100834 if (use_sig) {
835 PCU_SIG[pcu_idx].send(tx);
836 } else {
Harald Welte158becf2020-12-09 12:32:32 +0100837 PCU_PTP[pcu_idx].send(tx);
Daniel Willmann4798fd72020-11-24 16:23:29 +0100838 }
839
Harald Welte22ef5d92020-11-16 13:35:14 +0100840 T.start;
841 alt {
Daniel Willmann4798fd72020-11-24 16:23:29 +0100842 [use_sig] SGSN_SIG[sgsn_idx].receive(exp_rx) {
843 setverdict(pass);
844 }
Harald Welte158becf2020-12-09 12:32:32 +0100845 [not use_sig] SGSN_PTP[sgsn_idx].receive(exp_rx) {
Harald Welte22ef5d92020-11-16 13:35:14 +0100846 setverdict(pass);
847 }
Harald Welte158becf2020-12-09 12:32:32 +0100848 [] SGSN_PTP[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +0100849 f_shutdown(__FILE__, __LINE__, fail,
850 log2str("Unexpected BSSGP on SGSN[", sgsn_idx, "] side: ", rx));
Harald Welte22ef5d92020-11-16 13:35:14 +0100851 }
Daniel Willmann4798fd72020-11-24 16:23:29 +0100852 [] SGSN_SIG[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +0100853 f_shutdown(__FILE__, __LINE__, fail,
854 log2str("Unexpected SIG BSSGP on SGSN[", sgsn_idx, "] side: ", rx));
Daniel Willmann4798fd72020-11-24 16:23:29 +0100855 }
Harald Welte22ef5d92020-11-16 13:35:14 +0100856 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +0100857 f_shutdown(__FILE__, __LINE__, fail,
858 log2str("Timeout waiting for BSSGP on SGSN[", sgsn_idx, "] side: ", exp_rx));
Harald Welte22ef5d92020-11-16 13:35:14 +0100859 }
860 }
861}
862
Harald Welte3148a962021-01-17 11:15:28 +0100863/* Send 'tx' from PCU; expect 'exp_rx' on _any_ SGSN */
864friend function f_pcu2any_sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
865 integer pcu_idx := 0, boolean use_sig := false)
866runs on BSSGP_ConnHdlr return integer {
867 var integer rx_idx := -1;
868 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +0100869 timer T := 2.0;
Harald Welte3148a962021-01-17 11:15:28 +0100870
871 if (use_sig) {
872 PCU_SIG[pcu_idx].send(tx);
873 } else {
874 PCU_PTP[pcu_idx].send(tx);
875 }
876
877 T.start;
878 alt {
879 [use_sig] any from SGSN_SIG.receive(exp_rx) -> @index value rx_idx {
880 setverdict(pass);
881 }
882 [not use_sig] any from SGSN_PTP.receive(exp_rx) -> @index value rx_idx {
883 setverdict(pass);
884 }
885 [] any from SGSN_PTP.receive(PDU_BSSGP:?) -> value rx @index value rx_idx {
Harald Welted5b7e742021-01-27 10:50:24 +0100886 f_shutdown(__FILE__, __LINE__, fail,
887 log2str("Unexpected BSSGP on SGSN[", rx_idx, "] side: ", rx));
Harald Welte3148a962021-01-17 11:15:28 +0100888 }
889 [] any from SGSN_SIG.receive(PDU_BSSGP:?) -> value rx @index value rx_idx {
Harald Welted5b7e742021-01-27 10:50:24 +0100890 f_shutdown(__FILE__, __LINE__, fail,
891 log2str("Unexpected SIG BSSGP on SGSN[", rx_idx, "] side: ", rx));
Harald Welte3148a962021-01-17 11:15:28 +0100892 }
893 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +0100894 f_shutdown(__FILE__, __LINE__, fail,
895 log2str("Timeout waiting for BSSGP on SGSN side: ", exp_rx));
Harald Welte3148a962021-01-17 11:15:28 +0100896 }
897 }
898 return rx_idx;
899}
900
Harald Welte22ef5d92020-11-16 13:35:14 +0100901/* Send 'tx' on PTP-BVCI from SGSN; expect 'rx' on PCU */
902friend function f_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
Harald Weltec5f486b2021-01-16 11:07:01 +0100903 integer pcu_idx := 0, boolean use_sig := false) runs on BSSGP_ConnHdlr {
904 var integer sgsn_idx := g_pars.sgsn_idx;
Harald Welte22ef5d92020-11-16 13:35:14 +0100905 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +0100906 timer T := 2.0;
Harald Welte22ef5d92020-11-16 13:35:14 +0100907
Daniel Willmann4798fd72020-11-24 16:23:29 +0100908 if (use_sig) {
909 SGSN_SIG[sgsn_idx].send(tx);
910 } else {
Harald Welte158becf2020-12-09 12:32:32 +0100911 SGSN_PTP[sgsn_idx].send(tx);
Daniel Willmann4798fd72020-11-24 16:23:29 +0100912 }
913
Harald Welte22ef5d92020-11-16 13:35:14 +0100914 T.start;
915 alt {
Daniel Willmann4798fd72020-11-24 16:23:29 +0100916 [use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
917 setverdict(pass);
918 }
Harald Welte158becf2020-12-09 12:32:32 +0100919 [not use_sig] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte22ef5d92020-11-16 13:35:14 +0100920 setverdict(pass);
921 }
Harald Welte158becf2020-12-09 12:32:32 +0100922 [] PCU_PTP[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +0100923 f_shutdown(__FILE__, __LINE__, fail, log2str("Unexpected BSSGP on PCU side: ", rx));
Harald Welte22ef5d92020-11-16 13:35:14 +0100924 }
Daniel Willmann4798fd72020-11-24 16:23:29 +0100925 [] PCU_SIG[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +0100926 f_shutdown(__FILE__, __LINE__, fail, log2str("Unexpected SIG BSSGP on PCU side: ", rx));
Daniel Willmann4798fd72020-11-24 16:23:29 +0100927 }
Harald Welte22ef5d92020-11-16 13:35:14 +0100928 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +0100929 f_shutdown(__FILE__, __LINE__, fail,
930 log2str("Timeout waiting for BSSGP on PCU side: ", exp_rx));
Harald Welte22ef5d92020-11-16 13:35:14 +0100931 }
932 }
933}
Harald Welte1e834f32020-11-15 20:02:59 +0100934
Harald Welte3807ed12020-11-24 19:05:22 +0100935/***********************************************************************
936 * GlobaLTest_CT: Using the per-NSE GLOBAL ports on PCU + SGSN side
937 ***********************************************************************/
938
939type component GlobalTest_CT extends test_CT {
940 port BSSGP_PT G_PCU[NUM_PCU];
Harald Welte04358652021-01-17 13:48:13 +0100941 var integer g_pcu_idx[NUM_PCU]; /* BVC index currently connected to G_PCU */
Harald Welte3807ed12020-11-24 19:05:22 +0100942 port BSSGP_PT G_SGSN[NUM_SGSN];
Harald Welte04358652021-01-17 13:48:13 +0100943 var integer g_sgsn_idx[NUM_SGSN]; /* BVC index currently connected to G_SGSN */
Harald Weltef86f1852021-01-16 21:56:17 +0100944 port BSSGP_PT RIM_PCU[NUM_PCU];
945 port BSSGP_PT RIM_SGSN[NUM_SGSN];
Harald Welte3807ed12020-11-24 19:05:22 +0100946};
947
Harald Welte299aa482020-12-09 15:10:55 +0100948/* connect the signaling BVC of each NSE to the G_PCU / G_SGSN ports */
Harald Welte3807ed12020-11-24 19:05:22 +0100949private function f_global_init() runs on GlobalTest_CT {
950 var integer i;
951 for (i := 0; i < lengthof(g_sgsn); i := i+1) {
952 connect(self:G_SGSN[i], g_sgsn[i].vc_BSSGP:GLOBAL);
Harald Weltef86f1852021-01-16 21:56:17 +0100953 connect(self:RIM_SGSN[i], g_sgsn[i].vc_BSSGP:RIM);
Harald Welte3807ed12020-11-24 19:05:22 +0100954 }
955 for (i := 0; i < lengthof(g_pcu); i := i+1) {
956 connect(self:G_PCU[i], g_pcu[i].vc_BSSGP:GLOBAL);
Harald Weltef86f1852021-01-16 21:56:17 +0100957 connect(self:RIM_PCU[i], g_pcu[i].vc_BSSGP:RIM);
Harald Welte3807ed12020-11-24 19:05:22 +0100958 }
959}
960
Harald Welte299aa482020-12-09 15:10:55 +0100961/* connect the first PTP BVC of each NSE to the G_PCU / G_SGSN ports */
962private function f_global_init_ptp() runs on GlobalTest_CT {
963 var integer i;
964 for (i := 0; i < lengthof(g_sgsn); i := i+1) {
Harald Welte04358652021-01-17 13:48:13 +0100965 log("Connecting G_SGSN[", i, "] to BVCI=", g_sgsn[i].cfg.bvc[0].bvci);
Harald Welte299aa482020-12-09 15:10:55 +0100966 connect(self:G_SGSN[i], g_sgsn[i].vc_BSSGP_BVC[0]:GLOBAL);
Harald Welte04358652021-01-17 13:48:13 +0100967 g_sgsn_idx[i] := 0;
Harald Welte299aa482020-12-09 15:10:55 +0100968 }
969 for (i := 0; i < lengthof(g_pcu); i := i+1) {
Harald Welte04358652021-01-17 13:48:13 +0100970 log("Connecting G_PCU[", i, "] to BVCI=", g_pcu[i].cfg.bvc[0].bvci);
Harald Welte299aa482020-12-09 15:10:55 +0100971 connect(self:G_PCU[i], g_pcu[i].vc_BSSGP_BVC[0]:GLOBAL);
Harald Welte04358652021-01-17 13:48:13 +0100972 g_pcu_idx[i] := 0;
Harald Welte299aa482020-12-09 15:10:55 +0100973 }
974}
975
Harald Welte04358652021-01-17 13:48:13 +0100976/* (re)connect G_SGSN[sgsn_idx] to a specific PTP BVCI */
977private function f_global_ptp_connect_sgsn_bvci(integer sgsn_idx, BssgpBvci bvci) runs on GlobalTest_CT
978{
979 var integer sgsn_bvc_idx := get_bvc_idx_for_bvci(g_sgsn[sgsn_idx], bvci);
980 var integer old_sgsn_bvc_idx := g_sgsn_idx[sgsn_idx];
981 disconnect(self:G_SGSN[sgsn_idx], g_sgsn[sgsn_idx].vc_BSSGP_BVC[old_sgsn_bvc_idx]:GLOBAL);
982 connect(self:G_SGSN[sgsn_idx], g_sgsn[sgsn_idx].vc_BSSGP_BVC[sgsn_bvc_idx]:GLOBAL);
983 g_sgsn_idx[sgsn_idx] := sgsn_bvc_idx;
984}
985
986/* (re)connect G_PCU[pcu_idx] to a specific PTP BVCI */
987private function f_global_ptp_connect_pcu_bvci(integer pcu_idx, BssgpBvci bvci) runs on GlobalTest_CT
988{
989 var integer pcu_bvc_idx := get_bvc_idx_for_bvci(g_pcu[pcu_idx], bvci);
990 var integer old_pcu_bvc_idx := g_pcu_idx[pcu_idx];
991 disconnect(self:G_PCU[pcu_idx], g_pcu[pcu_idx].vc_BSSGP_BVC[old_pcu_bvc_idx]:GLOBAL);
992 connect(self:G_PCU[pcu_idx], g_pcu[pcu_idx].vc_BSSGP_BVC[pcu_bvc_idx]:GLOBAL);
993 g_pcu_idx[pcu_idx] := pcu_bvc_idx;
994}
995
Harald Welte3807ed12020-11-24 19:05:22 +0100996/* Send 'tx' on PTP-BVCI from PCU; expect 'rx' on SGSN */
997friend function f_global_pcu2sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
998 integer pcu_idx := 0, integer sgsn_idx := 0) runs on GlobalTest_CT {
Harald Welte04358652021-01-17 13:48:13 +0100999 var integer rx_idx;
Harald Welte3807ed12020-11-24 19:05:22 +01001000 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +01001001 timer T := 2.0;
Harald Welte3807ed12020-11-24 19:05:22 +01001002
1003 G_PCU[pcu_idx].send(tx);
1004 T.start;
1005 alt {
1006 [] G_SGSN[sgsn_idx].receive(exp_rx) {
1007 setverdict(pass);
1008 }
Harald Welte04358652021-01-17 13:48:13 +01001009 [] any from G_SGSN.receive(exp_rx) -> @index value rx_idx {
1010 setverdict(fail, "BSSGP arrived on wrong SGSN[", rx_idx, "] instead of SGSN[", sgsn_idx, "]");
1011 }
Harald Welte3807ed12020-11-24 19:05:22 +01001012 [] G_SGSN[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +01001013 f_shutdown(__FILE__, __LINE__, fail, log2str("Unexpected BSSGP on SGSN side: ", rx));
Harald Welte3807ed12020-11-24 19:05:22 +01001014 }
1015 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +01001016 f_shutdown(__FILE__, __LINE__, fail, log2str("Timeout waiting for BSSGP on SGSN side: ", exp_rx));
Harald Welte3807ed12020-11-24 19:05:22 +01001017 }
1018 }
1019}
1020
1021/* Send 'tx' on PTP-BVCI from SGSN; expect 'rx' on PCU */
1022friend function f_global_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
1023 integer sgsn_idx := 0, integer pcu_idx := 0) runs on GlobalTest_CT {
Harald Welte04358652021-01-17 13:48:13 +01001024 var integer rx_idx;
Harald Welte3807ed12020-11-24 19:05:22 +01001025 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +01001026 timer T := 2.0;
Harald Welte3807ed12020-11-24 19:05:22 +01001027
1028 G_SGSN[sgsn_idx].send(tx);
1029 T.start;
1030 alt {
1031 [] G_PCU[pcu_idx].receive(exp_rx) {
1032 setverdict(pass);
1033 }
Harald Welte04358652021-01-17 13:48:13 +01001034 [] any from G_PCU.receive(exp_rx) -> @index value rx_idx {
1035 setverdict(fail, "BSSGP arrived on wrong PCU[", rx_idx, "] instead of PCU[", pcu_idx, "]");
1036 }
Harald Welte3807ed12020-11-24 19:05:22 +01001037 [] G_PCU[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +01001038 f_shutdown(__FILE__, __LINE__, fail, log2str("Unexpected BSSGP on PCU side: ", rx));
Harald Welte3807ed12020-11-24 19:05:22 +01001039 }
1040 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +01001041 f_shutdown(__FILE__, __LINE__, fail, log2str("Timeout waiting for BSSGP on PCU side: ", exp_rx));
Harald Welte3807ed12020-11-24 19:05:22 +01001042 }
1043 }
1044}
1045
1046
Daniel Willmann423d8f42020-09-08 18:58:22 +02001047/* TODO:
1048 * Detach without Attach
1049 * SM procedures without attach / RAU
1050 * ATTACH / RAU
1051 ** with / without authentication
1052 ** with / without P-TMSI allocation
1053 * re-transmissions of LLC frames
1054 * PDP Context activation
1055 ** with different GGSN config in SGSN VTY
1056 ** with different PDP context type (v4/v6/v46)
1057 ** timeout from GGSN
1058 ** multiple / secondary PDP context
1059 */
1060
1061private function f_TC_BVC_bringup(charstring id) runs on BSSGP_ConnHdlr {
1062 f_sleep(5.0);
1063 setverdict(pass);
1064}
1065
1066testcase TC_BVC_bringup() runs on test_CT {
Daniel Willmann423d8f42020-09-08 18:58:22 +02001067 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001068 f_start_handlers(refers(f_TC_BVC_bringup), testcasename(), 51);
Daniel Willmann423d8f42020-09-08 18:58:22 +02001069 f_cleanup();
1070}
1071
1072friend function f_bssgp_suspend(integer ran_idx := 0) runs on BSSGP_ConnHdlr return OCT1 {
Harald Welte16357a92020-11-17 18:20:00 +01001073 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Daniel Willmann423d8f42020-09-08 18:58:22 +02001074 timer T := 5.0;
1075 var PDU_BSSGP rx_pdu;
Harald Welte16357a92020-11-17 18:20:00 +01001076 PCU_SIG[ran_idx].send(ts_BSSGP_SUSPEND(g_pars.tlli, bvcc.cell_id.ra_id));
Daniel Willmann423d8f42020-09-08 18:58:22 +02001077 T.start;
1078 alt {
Harald Welte16357a92020-11-17 18:20:00 +01001079 [] PCU_SIG[ran_idx].receive(tr_BSSGP_SUSPEND_ACK(g_pars.tlli, bvcc.cell_id.ra_id, ?)) -> value rx_pdu {
Daniel Willmann423d8f42020-09-08 18:58:22 +02001080 return rx_pdu.pDU_BSSGP_SUSPEND_ACK.suspend_Reference_Number.suspend_Reference_Number_value;
1081 }
Harald Welte16357a92020-11-17 18:20:00 +01001082 [] PCU_SIG[ran_idx].receive(tr_BSSGP_SUSPEND_NACK(g_pars.tlli, bvcc.cell_id.ra_id, ?)) -> value rx_pdu {
Harald Welted5b7e742021-01-27 10:50:24 +01001083 f_shutdown(__FILE__, __LINE__, fail,
1084 log2str("SUSPEND-NACK in response to SUSPEND for TLLI ", g_pars.tlli));
Daniel Willmann423d8f42020-09-08 18:58:22 +02001085 }
1086 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +01001087 f_shutdown(__FILE__, __LINE__, fail,
1088 log2str("No SUSPEND-ACK in response to SUSPEND for TLLI ", g_pars.tlli));
Daniel Willmann423d8f42020-09-08 18:58:22 +02001089 }
1090 }
1091 return '00'O;
1092}
1093
1094friend function f_bssgp_resume(OCT1 susp_ref, integer ran_idx := 0) runs on BSSGP_ConnHdlr {
Harald Welte16357a92020-11-17 18:20:00 +01001095 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Daniel Willmann423d8f42020-09-08 18:58:22 +02001096 timer T := 5.0;
Harald Welte16357a92020-11-17 18:20:00 +01001097 PCU_SIG[ran_idx].send(ts_BSSGP_RESUME(g_pars.tlli, bvcc.cell_id.ra_id, susp_ref));
Daniel Willmann423d8f42020-09-08 18:58:22 +02001098 T.start;
1099 alt {
Harald Welte16357a92020-11-17 18:20:00 +01001100 [] PCU_SIG[ran_idx].receive(tr_BSSGP_RESUME_ACK(g_pars.tlli, bvcc.cell_id.ra_id));
1101 [] PCU_SIG[ran_idx].receive(tr_BSSGP_RESUME_NACK(g_pars.tlli, bvcc.cell_id.ra_id, ?)) {
Harald Welted5b7e742021-01-27 10:50:24 +01001102 f_shutdown(__FILE__, __LINE__, fail,
1103 log2str("RESUME-NACK in response to RESUME for TLLI ", g_pars.tlli));
Daniel Willmann423d8f42020-09-08 18:58:22 +02001104 }
1105 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +01001106 f_shutdown(__FILE__, __LINE__, fail,
1107 log2str("No RESUME-ACK in response to SUSPEND for TLLI ", g_pars.tlli));
Daniel Willmann423d8f42020-09-08 18:58:22 +02001108 }
1109 }
1110}
1111
1112
Harald Welte92686012020-11-15 21:45:49 +01001113/* send uplink-unitdata of a variety of different sizes; expect it to show up on SGSN */
1114private function f_TC_ul_unitdata(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte16357a92020-11-17 18:20:00 +01001115 var integer ran_idx := 0;
1116 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Harald Welte92686012020-11-15 21:45:49 +01001117 var integer i;
1118
Harald Welte0d5fceb2020-11-29 16:04:07 +01001119 for (i := 0; i < max_fr_info_size-4; i := i+4) {
Harald Welte92686012020-11-15 21:45:49 +01001120 var octetstring payload := f_rnd_octstring(i);
Harald Welte16357a92020-11-17 18:20:00 +01001121 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_UL_UD(g_pars.tlli, bvcc.cell_id, payload);
Harald Welte92686012020-11-15 21:45:49 +01001122 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte16357a92020-11-17 18:20:00 +01001123 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_UL_UD(g_pars.tlli, bvcc.cell_id, payload);
Harald Welte92686012020-11-15 21:45:49 +01001124
Harald Welte0d5fceb2020-11-29 16:04:07 +01001125 log("UL-UNITDATA(payload_size=", i);
Harald Welte22ef5d92020-11-16 13:35:14 +01001126 f_pcu2sgsn(pdu_tx, pdu_rx);
Harald Welte92686012020-11-15 21:45:49 +01001127 }
1128 setverdict(pass);
1129}
1130
1131testcase TC_ul_unitdata() runs on test_CT
1132{
Daniel Willmannc879f342021-02-11 14:28:01 +01001133 f_init(60.0);
Harald Welte2ecbca82021-01-16 11:23:09 +01001134 f_start_handlers(refers(f_TC_ul_unitdata), testcasename(), 1);
Harald Welte92686012020-11-15 21:45:49 +01001135 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Welte92686012020-11-15 21:45:49 +01001136 f_cleanup();
1137}
1138
Daniel Willmann8d9fcf42021-05-28 15:05:41 +02001139
1140/* send uplink-unitdata of a variety of different sizes; expect it to show up on the only connected SGSN */
1141private function f_TC_ul_unitdata_pool_failure(charstring id) runs on BSSGP_ConnHdlr {
1142 var integer ran_idx := 0;
1143 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
1144 var integer i;
1145
1146 /* All data should arrive at the one SGSN that is still up */
1147 g_pars.sgsn_idx := 0;
1148
1149 for (i := 0; i < max_fr_info_size-4; i := i+4) {
1150 var octetstring payload := f_rnd_octstring(i);
1151 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_UL_UD(g_pars.tlli, bvcc.cell_id, payload);
1152 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1153 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_UL_UD(g_pars.tlli, bvcc.cell_id, payload);
1154
1155 log("UL-UNITDATA(payload_size=", i);
1156 f_pcu2sgsn(pdu_tx, pdu_rx);
1157 }
1158 setverdict(pass);
1159}
1160
Daniel Willmannc5bbcc62021-09-24 13:17:20 +02001161private function f_disable_ns_pcu(integer pcu_idx) runs on test_CT
1162{
1163 var integer i;
1164
1165 connect(self:NS_CTRL, g_pcu[pcu_idx].vc_NS:NS_CTRL);
1166 for (i := 0; i < lengthof(mp_nsconfig_pcu[pcu_idx].nsvc); i := i + 1) {
1167 var uint16_t nsvci := mp_nsconfig_pcu[pcu_idx].nsvc[i].nsvci;
1168 var NsDisableVcRequest tx_disar;
1169 tx_disar.nsvci := nsvci;
1170 log(tx_disar);
1171 NS_CTRL.send(tx_disar);
1172 }
1173 disconnect(self:NS_CTRL, g_pcu[pcu_idx].vc_NS:NS_CTRL);
1174}
1175
Daniel Willmann8d9fcf42021-05-28 15:05:41 +02001176testcase TC_ul_unitdata_pool_failure() runs on test_CT
1177{
1178 var integer i;
1179 var integer j;
1180
1181 f_init(60.0);
1182
1183 for (i := 1; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
1184 connect(self:NS_CTRL, g_sgsn[i].vc_NS:NS_CTRL);
1185 for (j := 0; j < lengthof(mp_nsconfig_sgsn[i].nsvc); j := j+1) {
1186 var uint16_t nsvci := mp_nsconfig_sgsn[i].nsvc[j].nsvci;
1187 var NsDisableVcRequest tx_disar;
1188 tx_disar.nsvci := nsvci;
1189 NS_CTRL.send(tx_disar);
1190 }
1191 disconnect(self:NS_CTRL, g_sgsn[i].vc_NS:NS_CTRL);
1192 }
1193 /* Wait until gbproxy notices that the NSVCs are down */
1194 f_sleep(15.0);
1195
1196 f_start_handlers(refers(f_TC_ul_unitdata_pool_failure), testcasename(), 1);
1197 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
1198 f_cleanup();
1199}
1200
Harald Welte78d8db92020-11-15 23:27:27 +01001201/* send downlink-unitdata of a variety of different sizes; expect it to show up on PCU */
1202private function f_TC_dl_unitdata(charstring id) runs on BSSGP_ConnHdlr {
1203 var integer i;
1204
Harald Welte0d5fceb2020-11-29 16:04:07 +01001205 for (i := 0; i < max_fr_info_size-4; i := i+4) {
Harald Welte78d8db92020-11-15 23:27:27 +01001206 var octetstring payload := f_rnd_octstring(i);
1207 var template (value) PDU_BSSGP pdu_tx :=
1208 ts_BSSGP_DL_UD(g_pars.tlli, payload, omit, ts_BSSGP_IMSI(g_pars.imsi));
1209 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1210 var template (present) PDU_BSSGP pdu_rx :=
Daniel Willmann325458d2021-02-11 14:22:42 +01001211 tr_BSSGP_DL_UD(g_pars.tlli, payload, tr_BSSGP_IMSI(g_pars.imsi));
Harald Welte78d8db92020-11-15 23:27:27 +01001212
Harald Welte0d5fceb2020-11-29 16:04:07 +01001213 log("DL-UNITDATA(payload_size=", i);
Harald Welte22ef5d92020-11-16 13:35:14 +01001214 f_sgsn2pcu(pdu_tx, pdu_rx);
Harald Welte78d8db92020-11-15 23:27:27 +01001215 }
1216 setverdict(pass);
1217}
1218
1219testcase TC_dl_unitdata() runs on test_CT
1220{
Daniel Willmannc879f342021-02-11 14:28:01 +01001221 f_init(60.0);
Harald Welte2ecbca82021-01-16 11:23:09 +01001222 f_start_handlers(refers(f_TC_dl_unitdata), testcasename(), 2);
Harald Welte78d8db92020-11-15 23:27:27 +01001223 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Welte78d8db92020-11-15 23:27:27 +01001224 f_cleanup();
1225}
Harald Welte92686012020-11-15 21:45:49 +01001226
Harald Welte6dc2ac42020-11-16 09:16:17 +01001227private function f_TC_ra_capability(charstring id) runs on BSSGP_ConnHdlr {
1228 var integer i;
1229
1230 for (i := 0; i < 10; i := i+1) {
1231 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RA_CAP(g_pars.tlli, { ts_RaCapRec_BSSGP });
1232 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1233 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RA_CAP(g_pars.tlli, { tr_RaCapRec_BSSGP })
1234
Harald Welte22ef5d92020-11-16 13:35:14 +01001235 f_sgsn2pcu(pdu_tx, pdu_rx);
Harald Welte6dc2ac42020-11-16 09:16:17 +01001236 }
1237 setverdict(pass);
1238}
1239testcase TC_ra_capability() runs on test_CT
1240{
Harald Welte6dc2ac42020-11-16 09:16:17 +01001241 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001242 f_start_handlers(refers(f_TC_ra_capability), testcasename(), 3);
Harald Welte6dc2ac42020-11-16 09:16:17 +01001243 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Welte6dc2ac42020-11-16 09:16:17 +01001244 f_cleanup();
1245}
1246
Daniel Willmannace3ece2020-11-16 19:53:26 +01001247private function f_TC_ra_capability_upd(charstring id) runs on BSSGP_ConnHdlr {
1248 var integer i;
1249 var OCT1 tag;
1250 for (i := 0; i < 10; i := i+1) {
1251 tag := int2oct(23 + i, 1);
1252 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RA_CAP_UPD(g_pars.tlli, tag);
1253 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1254 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RA_CAP_UPD(g_pars.tlli, tag)
1255
1256 f_pcu2sgsn(pdu_tx, pdu_rx);
1257
1258 pdu_tx := ts_BSSGP_RA_CAP_UPD_ACK(g_pars.tlli, tag, '42'O);
1259 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1260 pdu_rx := tr_BSSGP_RA_CAP_UPD_ACK(g_pars.tlli, tag, '42'O)
1261
1262 f_sgsn2pcu(pdu_tx, pdu_rx);
1263 }
1264 setverdict(pass);
1265}
1266testcase TC_ra_capability_upd() runs on test_CT
1267{
Daniel Willmannace3ece2020-11-16 19:53:26 +01001268 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001269 f_start_handlers(refers(f_TC_ra_capability_upd), testcasename(), 4);
Daniel Willmannace3ece2020-11-16 19:53:26 +01001270 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Daniel Willmannace3ece2020-11-16 19:53:26 +01001271 f_cleanup();
1272}
1273
Daniel Willmann165d6612020-11-19 14:27:29 +01001274private function f_TC_radio_status(charstring id) runs on BSSGP_ConnHdlr {
1275 var integer i;
1276 var BssgpRadioCause cause := BSSGP_RADIO_CAUSE_CONTACT_LOST;
1277 for (i := 0; i < 10; i := i+1) {
1278 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RADIO_STATUS(g_pars.tlli, cause);
1279 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1280 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RADIO_STATUS(g_pars.tlli, cause)
1281
1282 f_pcu2sgsn(pdu_tx, pdu_rx);
1283 }
1284 setverdict(pass);
1285}
1286testcase TC_radio_status() runs on test_CT
1287{
Daniel Willmann165d6612020-11-19 14:27:29 +01001288 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001289 f_start_handlers(refers(f_TC_radio_status), testcasename(), 5);
Daniel Willmann165d6612020-11-19 14:27:29 +01001290 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Daniel Willmann165d6612020-11-19 14:27:29 +01001291 f_cleanup();
1292}
1293
Harald Welte3148a962021-01-17 11:15:28 +01001294private function f_TC_radio_status_tmsi(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 integer tmsi_int := oct2int(g_pars.p_tmsi);
1299 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RADIO_STATUS(omit, cause, tmsi_int);
1300 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1301 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RADIO_STATUS(omit, cause, tmsi_int);
1302 f_pcu2sgsn(pdu_tx, pdu_rx);
1303 }
1304 setverdict(pass);
1305}
1306testcase TC_radio_status_tmsi() runs on test_CT
1307{
1308 f_init();
1309 f_start_handlers(refers(f_TC_radio_status_tmsi), testcasename(), 5);
1310 f_cleanup();
1311}
1312
1313private function f_TC_radio_status_imsi(charstring id) runs on BSSGP_ConnHdlr {
1314 var integer i;
1315 var BssgpRadioCause cause := BSSGP_RADIO_CAUSE_CONTACT_LOST;
1316 for (i := 0; i < 10; i := i+1) {
1317 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RADIO_STATUS(omit, cause, imsi := g_pars.imsi);
1318 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1319 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RADIO_STATUS(omit, cause, imsi := g_pars.imsi);
1320 f_pcu2any_sgsn(pdu_tx, pdu_rx);
1321 }
1322 setverdict(pass);
1323}
1324testcase TC_radio_status_imsi() runs on test_CT
1325{
1326 f_init();
1327 f_start_handlers(refers(f_TC_radio_status_imsi), testcasename(), 5);
1328 f_cleanup();
1329}
1330
1331
1332
Harald Welte99ed5072021-01-15 20:38:58 +01001333private function f_suspend_one(integer sgsn_idx, integer nri_idx, integer pcu_idx, integer bvc_idx,
1334 integer suffix)
Harald Welte00963752021-01-15 20:33:11 +01001335runs on GlobalTest_CT
1336{
1337 var RoutingAreaIdentification ra_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id.ra_id;
Harald Welte99ed5072021-01-15 20:38:58 +01001338 var OCT4 p_tmsi := f_gen_tmsi(suffix, nri_v := mp_sgsn_nri[sgsn_idx][nri_idx],
1339 nri_bitlen := mp_nri_bitlength);
1340 var OCT4 tlli := f_gprs_tlli_from_tmsi(p_tmsi, TLLI_LOCAL);
Harald Welte00963752021-01-15 20:33:11 +01001341 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_SUSPEND(tlli, ra_id);
1342 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1343 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_SUSPEND(tlli, ra_id);
1344 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1345
1346 pdu_tx := ts_BSSGP_SUSPEND_ACK(tlli, ra_id, int2oct(suffix, 1));
1347 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1348 pdu_rx := tr_BSSGP_SUSPEND_ACK(tlli, ra_id, int2oct(suffix, 1));
1349 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1350
1351 pdu_tx := ts_BSSGP_SUSPEND(tlli, ra_id);
1352 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1353 pdu_rx := tr_BSSGP_SUSPEND(tlli, ra_id);
1354 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1355
1356 /* These messages are simple passed through so just also test sending NACK */
1357 pdu_tx := ts_BSSGP_SUSPEND_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1358 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1359 pdu_rx := tr_BSSGP_SUSPEND_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1360 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1361}
1362
Harald Weltec5c33732021-01-15 21:04:35 +01001363private function f_TC_suspend(integer sgsn_idx, integer nri_idx, integer pcu_idx, integer bvc_idx)
1364runs on GlobalTest_CT {
Daniel Willmannfa67f492020-11-19 15:48:05 +01001365 var integer i;
Daniel Willmann165d6612020-11-19 14:27:29 +01001366
Daniel Willmannfa67f492020-11-19 15:48:05 +01001367 for (i := 0; i < 10; i := i+1) {
Harald Weltec5c33732021-01-15 21:04:35 +01001368 f_suspend_one(sgsn_idx, nri_idx, pcu_idx, bvc_idx, suffix := i);
Daniel Willmannfa67f492020-11-19 15:48:05 +01001369 }
1370 setverdict(pass);
1371}
Harald Welte3807ed12020-11-24 19:05:22 +01001372testcase TC_suspend() runs on GlobalTest_CT
Daniel Willmannfa67f492020-11-19 15:48:05 +01001373{
Harald Weltec5c33732021-01-15 21:04:35 +01001374 var integer sgsn_idx, nri_idx;
Daniel Willmannfa67f492020-11-19 15:48:05 +01001375 f_init();
Harald Welte3807ed12020-11-24 19:05:22 +01001376 f_global_init();
Harald Weltec5c33732021-01-15 21:04:35 +01001377 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx+1) {
1378 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx+1) {
1379 f_TC_suspend(sgsn_idx, nri_idx, pcu_idx:=0, bvc_idx:=0);
1380 }
1381 }
Daniel Willmannfa67f492020-11-19 15:48:05 +01001382 f_cleanup();
1383}
Harald Welte6dc2ac42020-11-16 09:16:17 +01001384
Harald Welte99ed5072021-01-15 20:38:58 +01001385private function f_resume_one(integer sgsn_idx, integer nri_idx, integer pcu_idx, integer bvc_idx,
1386 integer suffix)
Harald Welte00963752021-01-15 20:33:11 +01001387runs on GlobalTest_CT
1388{
1389 var RoutingAreaIdentification ra_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id.ra_id;
Harald Welte99ed5072021-01-15 20:38:58 +01001390 var OCT4 p_tmsi := f_gen_tmsi(suffix, nri_v := mp_sgsn_nri[sgsn_idx][nri_idx],
1391 nri_bitlen := mp_nri_bitlength);
1392 var OCT4 tlli := f_gprs_tlli_from_tmsi(p_tmsi, TLLI_LOCAL);
Harald Welte00963752021-01-15 20:33:11 +01001393 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1394 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1395 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1396 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1397
1398 pdu_tx := ts_BSSGP_RESUME_ACK(tlli, ra_id);
1399 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1400 pdu_rx := tr_BSSGP_RESUME_ACK(tlli, ra_id);
1401 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1402
1403 pdu_tx := ts_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1404 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1405 pdu_rx := tr_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1406 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1407
1408 /* These messages are simple passed through so just also test sending NACK */
1409 pdu_tx := ts_BSSGP_RESUME_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1410 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1411 pdu_rx := tr_BSSGP_RESUME_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1412 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1413}
1414
Harald Weltec5c33732021-01-15 21:04:35 +01001415private function f_TC_resume(integer sgsn_idx, integer nri_idx, integer pcu_idx, integer bvc_idx)
1416runs on GlobalTest_CT {
Daniel Willmann087a33d2020-11-19 15:58:43 +01001417 var integer i;
1418
Daniel Willmann087a33d2020-11-19 15:58:43 +01001419 for (i := 0; i < 10; i := i+1) {
Harald Weltec5c33732021-01-15 21:04:35 +01001420 f_resume_one(sgsn_idx, nri_idx, pcu_idx, bvc_idx, suffix := i);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001421 }
1422 setverdict(pass);
1423}
Harald Welte3807ed12020-11-24 19:05:22 +01001424testcase TC_resume() runs on GlobalTest_CT
Daniel Willmann087a33d2020-11-19 15:58:43 +01001425{
Harald Weltec5c33732021-01-15 21:04:35 +01001426 var integer sgsn_idx, nri_idx;
Daniel Willmann087a33d2020-11-19 15:58:43 +01001427 f_init();
Harald Welte3807ed12020-11-24 19:05:22 +01001428 f_global_init();
Harald Weltec5c33732021-01-15 21:04:35 +01001429 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx+1) {
1430 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx+1) {
1431 f_TC_resume(sgsn_idx, nri_idx, pcu_idx:=0, bvc_idx:=0);
1432 }
1433 }
Daniel Willmann087a33d2020-11-19 15:58:43 +01001434 f_cleanup();
1435}
1436
Harald Weltef8ef0282020-11-18 12:16:59 +01001437/* test the load-sharing between multiple NS-VC on the BSS side */
1438private function f_TC_dl_ud_unidir(charstring id) runs on BSSGP_ConnHdlr {
1439 var integer i;
1440
1441 for (i := 0; i < 10; i := i+1) {
1442 var octetstring payload := f_rnd_octstring(i);
1443 var template (value) PDU_BSSGP pdu_tx :=
1444 ts_BSSGP_DL_UD(g_pars.tlli, payload, omit, ts_BSSGP_IMSI(g_pars.imsi));
Harald Welte09a1ce42021-01-16 11:18:38 +01001445 SGSN_PTP[g_pars.sgsn_idx].send(pdu_tx);
Harald Weltef8ef0282020-11-18 12:16:59 +01001446 }
1447 setverdict(pass);
1448}
Harald Welte09a1ce42021-01-16 11:18:38 +01001449
1450private function f_TC_load_sharing_dl(integer sgsn_idx) runs on test_CT_NS
Harald Weltef8ef0282020-11-18 12:16:59 +01001451{
1452 const integer num_ue := 10;
1453 var BSSGP_ConnHdlr vc_conn[num_ue];
Harald Weltef8ef0282020-11-18 12:16:59 +01001454 /* all BVC are now fully brought up. We disconnect BSSGP from NS on the BSS
1455 * side so we get the raw NsUnitdataIndication and hence observe different
1456 * NSVCI */
1457 disconnect(g_pcu[0].vc_NS:NS_SP, g_pcu[0].vc_BSSGP:BSCP);
1458 connect(g_pcu[0].vc_NS:NS_SP, self:NS);
1459
1460 /* there may still be some NS-VCs coming up? After all, the BVC-RESET succeeds after the first
1461 * of the NS-VC is ALIVE/UNBLOCKED */
1462 f_sleep(3.0);
1463
1464 /* start parallel components generating DL-UNITDATA from the SGSN side */
1465 for (var integer i:= 0; i < num_ue; i := i+1) {
Harald Welte2ecbca82021-01-16 11:23:09 +01001466 vc_conn[i] := f_start_handler(refers(f_TC_dl_ud_unidir), testcasename(),
Harald Welte09a1ce42021-01-16 11:18:38 +01001467 5+i, 30.0, sgsn_idx);
Harald Weltef8ef0282020-11-18 12:16:59 +01001468 }
1469
1470 /* now start counting all the messages that were queued before */
1471 /* TODO: We have a hard-coded assumption of 4 NS-VC in one NSE/NS-VCG here! */
1472 var ro_integer rx_count := { 0, 0, 0, 0 };
1473 timer T := 2.0;
1474 T.start;
1475 alt {
1476 [] as_NsUdiCount(0, rx_count);
1477 [] as_NsUdiCount(1, rx_count);
1478 [] as_NsUdiCount(2, rx_count);
1479 [] as_NsUdiCount(3, rx_count);
1480 [] NS.receive(NsUnitdataIndication:{0,?,?,*,*}) { repeat; } /* signaling BVC */
1481 [] NS.receive(NsStatusIndication:?) { repeat; }
1482 [] NS.receive {
Harald Welted5b7e742021-01-27 10:50:24 +01001483 f_shutdown(__FILE__, __LINE__, fail, "Rx unexpected NS");
Harald Weltef8ef0282020-11-18 12:16:59 +01001484 }
1485 [] T.timeout {
1486 }
1487 }
1488 for (var integer i := 0; i < lengthof(rx_count); i := i+1) {
1489 log("Rx on NSVCI ", mp_nsconfig_pcu[0].nsvc[i].nsvci, ": ", rx_count[i]);
1490 if (rx_count[i] == 0) {
1491 setverdict(fail, "Data not shared over all NSVC");
1492 }
1493 }
Harald Welte09a1ce42021-01-16 11:18:38 +01001494}
1495
1496testcase TC_load_sharing_dl() runs on test_CT_NS
1497{
1498 var integer sgsn_idx, nri_idx;
1499 f_init();
1500 for (sgsn_idx:=0; sgsn_idx < NUM_SGSN; sgsn_idx:=sgsn_idx+1) {
1501 f_TC_load_sharing_dl(sgsn_idx);
1502 }
Harald Weltef8ef0282020-11-18 12:16:59 +01001503 setverdict(pass);
1504}
1505private altstep as_NsUdiCount(integer nsvc_idx, inout ro_integer roi) runs on test_CT_NS {
1506 var NsUnitdataIndication udi;
1507 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[0];
1508 [] NS.receive(NsUnitdataIndication:{bvcc.bvci, g_pcu[0].cfg.nsei, mp_nsconfig_pcu[0].nsvc[nsvc_idx].nsvci, *, *}) -> value udi {
1509 roi[nsvc_idx] := roi[nsvc_idx] + 1;
1510 repeat;
1511 }
1512}
1513type component test_CT_NS extends test_CT {
1514 port NS_PT NS;
1515};
1516
1517
Harald Welte0e188242020-11-22 21:46:48 +01001518/***********************************************************************
1519 * PAGING PS procedure
1520 ***********************************************************************/
1521
1522private function f_send_paging_ps(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1523 boolean use_sig := false)
1524runs on BSSGP_ConnHdlr return template (present) PDU_BSSGP {
1525 var template (value) PDU_BSSGP pdu_tx;
1526 var template (present) PDU_BSSGP pdu_rx;
1527 /* we always specify '0' as BVCI in the templates below, as we override it with
1528 * 'p4' later anyway */
1529 pdu_rx := tr_BSSGP_PS_PAGING(0);
1530 pdu_rx.pDU_BSSGP_PAGING_PS.iMSI := tr_BSSGP_IMSI(g_pars.imsi);
1531 if (ispresent(g_pars.p_tmsi)) {
1532 pdu_tx := ts_BSSGP_PS_PAGING_PTMSI(0, g_pars.imsi, oct2int(g_pars.p_tmsi));
1533 pdu_rx.pDU_BSSGP_PAGING_PS.pTMSI := tr_BSSGP_TMSI(oct2int(g_pars.p_tmsi));
1534 } else {
1535 pdu_tx := ts_BSSGP_PS_PAGING_IMSI(0, g_pars.imsi);
1536 pdu_rx.pDU_BSSGP_PAGING_PS.pTMSI := omit;
1537 }
1538 pdu_tx.pDU_BSSGP_PAGING_PS.paging_Field4 := p4;
1539 pdu_rx.pDU_BSSGP_PAGING_PS.paging_Field4 := p4;
1540 if (use_sig == false) {
Harald Welte158becf2020-12-09 12:32:32 +01001541 SGSN_PTP[sgsn_idx].send(pdu_tx);
Harald Welte0e188242020-11-22 21:46:48 +01001542 } else {
1543 SGSN_SIG[sgsn_idx].send(pdu_tx);
1544 }
1545 return pdu_rx;
1546}
1547
1548/* send paging defined by 'p4' on given SGSN-side index (ptp or signaling) and expect one paging to arrive on
1549 * specified PCU index */
1550private function f_send_paging_ps_exp_one_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1551 boolean use_sig := false,integer pcu_idx := 0)
1552runs on BSSGP_ConnHdlr {
1553 var template (present) PDU_BSSGP exp_rx;
Daniel Willmann1a859712020-12-04 00:59:45 +01001554 var boolean test_done := false;
Harald Welte0e188242020-11-22 21:46:48 +01001555 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1556 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1557 exp_rx := f_send_paging_ps(p4, sgsn_idx, use_sig);
1558 /* Expect paging to propagate to the one BSS addressed by the BVCI only */
1559 timer T := 2.0;
1560 T.start;
1561 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001562 [not use_sig and not test_done] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001563 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001564 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001565 repeat;
1566 }
1567 [not use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
1568 setverdict(fail, "Received paging on SIGNALING BVC, expected PTP BVC");
1569 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001570 [use_sig and not test_done] PCU_SIG[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001571 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001572 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001573 repeat;
1574 }
Harald Welte158becf2020-12-09 12:32:32 +01001575 [use_sig] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001576 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1577 }
Harald Welte158becf2020-12-09 12:32:32 +01001578 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001579 setverdict(fail, "Paging received on unexpected BVC");
1580 }
1581 [] any from PCU_SIG.receive(exp_rx) {
1582 setverdict(fail, "Paging received on unexpected BVC");
1583 }
Harald Welte158becf2020-12-09 12:32:32 +01001584 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01001585 setverdict(fail, "Different Paging than expected received PTP BVC");
1586 }
1587 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1588 setverdict(fail, "Different Paging than expected on SIGNALING BVC");
1589 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001590 [not test_done] T.timeout {
1591 setverdict(fail, "Timeout waiting for paging");
1592 }
1593 [test_done] T.timeout;
Harald Welte0e188242020-11-22 21:46:48 +01001594 }
1595}
1596
Harald Welte7462a592020-11-23 22:07:07 +01001597/* send a PS-PAGING but don't expect it to show up on any PTP or SIG BVC */
1598private function f_send_paging_ps_exp_no_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1599 boolean use_sig := false)
1600runs on BSSGP_ConnHdlr {
1601 var template (present) PDU_BSSGP exp_rx;
1602 exp_rx := f_send_paging_ps(p4, sgsn_idx, use_sig);
1603 /* Expect paging to propagate to no BSS */
1604 timer T := 2.0;
1605 T.start;
1606 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001607 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte7462a592020-11-23 22:07:07 +01001608 setverdict(fail, "Paging received on unexpected BVC");
1609 }
1610 [] any from PCU_SIG.receive(exp_rx) {
1611 setverdict(fail, "Paging received on unexpected BVC");
1612 }
Harald Welte158becf2020-12-09 12:32:32 +01001613 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte7462a592020-11-23 22:07:07 +01001614 setverdict(fail, "Different Paging received on PTP BVC");
1615 }
1616 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1617 setverdict(fail, "Different Paging received on SIGNALING BVC");
1618 }
1619 [] T.timeout {
1620 setverdict(pass);
1621 }
1622 }
1623}
1624
Harald Welte0e188242020-11-22 21:46:48 +01001625private function f_TC_paging_ps_ptp_bss(charstring id) runs on BSSGP_ConnHdlr
1626{
1627 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1628 * at that BVC (cell) only, and paging all over the BSS area is not possible */
Daniel Willmann2a330672021-01-18 18:50:02 +01001629 f_send_paging_ps_exp_one_bss(ts_BssgpP4BssArea, g_pars.sgsn_idx, false, 0);
Harald Welte0e188242020-11-22 21:46:48 +01001630}
1631testcase TC_paging_ps_ptp_bss() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001632 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001633 f_start_handlers(refers(f_TC_paging_ps_ptp_bss), testcasename(), 9);
Harald Welte0e188242020-11-22 21:46:48 +01001634 f_cleanup();
1635}
1636
1637/* PS-PAGING on PTP-BVC for Location Area */
1638private function f_TC_paging_ps_ptp_lac(charstring id) runs on BSSGP_ConnHdlr
1639{
1640 var template (present) PDU_BSSGP exp_rx;
1641 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1642 * at that BVC (cell) only, and paging all over the BSS area is not possible */
Daniel Willmann2a330672021-01-18 18:50:02 +01001643 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 +01001644}
1645testcase TC_paging_ps_ptp_lac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001646 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001647 f_start_handlers(refers(f_TC_paging_ps_ptp_lac), testcasename(), 10);
Harald Welte0e188242020-11-22 21:46:48 +01001648 f_cleanup();
1649}
1650
Harald Welte7462a592020-11-23 22:07:07 +01001651/* PS-PAGING on PTP-BVC for unknown Location Area */
1652private function f_TC_paging_ps_ptp_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1653{
1654 var GSM_Types.LocationAreaIdentification unknown_la := {
1655 mcc_mnc := '567F99'H,
1656 lac := 33333
1657 };
1658 /* as it's sent on the PTP BVC, we expect it to pass even for unknown LAC */
Daniel Willmann2a330672021-01-18 18:50:02 +01001659 f_send_paging_ps_exp_one_bss(ts_BssgpP4LAC(unknown_la), g_pars.sgsn_idx, false, 0);
Harald Welte7462a592020-11-23 22:07:07 +01001660}
1661testcase TC_paging_ps_ptp_lac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001662 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001663 f_start_handlers(refers(f_TC_paging_ps_ptp_lac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001664 f_cleanup();
1665}
1666
Harald Welte0e188242020-11-22 21:46:48 +01001667/* PS-PAGING on PTP-BVC for Routeing Area */
1668private function f_TC_paging_ps_ptp_rac(charstring id) runs on BSSGP_ConnHdlr
1669{
1670 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1671 * at that BVC (cell) only, and paging all over the BSS area is not possible */
Daniel Willmann2a330672021-01-18 18:50:02 +01001672 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 +01001673}
1674testcase TC_paging_ps_ptp_rac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001675 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001676 f_start_handlers(refers(f_TC_paging_ps_ptp_rac), testcasename(), 11);
Harald Welte0e188242020-11-22 21:46:48 +01001677 f_cleanup();
1678}
1679
Harald Welte7462a592020-11-23 22:07:07 +01001680/* PS-PAGING on PTP-BVC for unknown Routeing Area */
1681private function f_TC_paging_ps_ptp_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1682{
1683 var RoutingAreaIdentification unknown_ra := {
1684 lai := {
1685 mcc_mnc := '567F99'H,
1686 lac := 33333
1687 },
1688 rac := 254
1689 };
1690 /* as it's sent on the PTP BVC, we expect it to pass even for unknown RAC */
Daniel Willmann2a330672021-01-18 18:50:02 +01001691 f_send_paging_ps_exp_one_bss(ts_BssgpP4RAC(unknown_ra), g_pars.sgsn_idx, false, 0);
Harald Welte7462a592020-11-23 22:07:07 +01001692}
1693testcase TC_paging_ps_ptp_rac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001694 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001695 f_start_handlers(refers(f_TC_paging_ps_ptp_rac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001696 f_cleanup();
1697}
1698
Harald Welte0e188242020-11-22 21:46:48 +01001699/* PS-PAGING on PTP-BVC for BVCI (one cell) */
1700private function f_TC_paging_ps_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
1701{
1702 /* this should be the normal case for MS in READY MM state after a lower layer failure */
Daniel Willmann2a330672021-01-18 18:50:02 +01001703 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 +01001704}
1705testcase TC_paging_ps_ptp_bvci() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001706 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001707 f_start_handlers(refers(f_TC_paging_ps_ptp_bvci), testcasename(), 12);
Harald Welte0e188242020-11-22 21:46:48 +01001708 f_cleanup();
1709}
1710
Harald Welteb5a04aa2021-01-16 13:04:40 +01001711
1712/* PS-PAGING on PTP-BVC for BVCI (one cell) using IMSI only (no P-TMSI allocated) */
1713testcase TC_paging_ps_ptp_bvci_imsi() runs on test_CT {
1714 f_init();
1715 f_start_handlers(refers(f_TC_paging_ps_ptp_bvci), testcasename(), 12, have_ptmsi:=false);
1716 f_cleanup();
1717}
1718
Harald Weltecf200072021-01-16 15:20:46 +01001719/* Rejected PS-PAGING on PTP-BVC for BVCI (one cell) */
1720testcase TC_paging_ps_reject_ptp_bvci() runs on test_CT {
1721 f_init();
1722 f_start_handlers(refers(f_TC_paging_ps_reject_ptp_bvci), testcasename(), 16);
1723 f_cleanup();
1724}
1725
1726/* Rejected PS-PAGING on PTP-BVC for BVCI (one cell) using IMSI only (no P-TMSI allocated) */
1727private function f_TC_paging_ps_reject_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
1728{
1729 /* first send the PS-PAGING from SGSN -> PCU */
Daniel Willmann2a330672021-01-18 18:50:02 +01001730 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 +01001731 /* then simulate the PS-PAGING-REJECT from the PCU */
1732 f_send_paging_ps_rej(use_sig:=false);
1733}
1734testcase TC_paging_ps_reject_ptp_bvci_imsi() runs on test_CT {
1735 f_init();
1736 f_start_handlers(refers(f_TC_paging_ps_reject_ptp_bvci), testcasename(), 16, have_ptmsi:=false);
1737 f_cleanup();
1738}
Harald Welteb5a04aa2021-01-16 13:04:40 +01001739
Harald Welte7462a592020-11-23 22:07:07 +01001740/* PS-PAGING on PTP-BVC for unknown BVCI */
1741private function f_TC_paging_ps_ptp_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1742{
1743 /* as it's sent on the PTP BVC, we expect it to pass even for unknown BVCI */
Daniel Willmann2a330672021-01-18 18:50:02 +01001744 f_send_paging_ps_exp_one_bss(ts_BssgpP4Bvci(33333), g_pars.sgsn_idx, false, 0);
Harald Welte7462a592020-11-23 22:07:07 +01001745}
1746testcase TC_paging_ps_ptp_bvci_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001747 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001748 f_start_handlers(refers(f_TC_paging_ps_ptp_bvci_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001749 f_cleanup();
1750}
1751
Harald Welte7595d562021-01-16 19:09:20 +01001752/* DUMMY PAGING PS on PTP BVC */
1753private function f_TC_dummy_paging_ps_ptp(charstring id) runs on BSSGP_ConnHdlr
1754{
1755 f_sgsn2pcu(ts_BSSGP_DUMMY_PAGING_PS(g_pars.imsi, omit),
1756 tr_BSSGP_DUMMY_PAGING_PS(g_pars.imsi, omit), use_sig := false);
1757 f_pcu2sgsn(ts_BSSGP_DUMMY_PAGING_PS_RESP(g_pars.imsi, 1, 5),
1758 tr_BSSGP_DUMMY_PAGING_PS_RESP(g_pars.imsi, 1, 5), use_sig := false)
1759}
1760testcase TC_dummy_paging_ps_ptp() runs on test_CT {
1761 f_init();
1762 f_start_handlers(refers(f_TC_dummy_paging_ps_ptp), testcasename(), 11);
1763 f_cleanup();
1764}
1765
Harald Welte0e188242020-11-22 21:46:48 +01001766/* altstep for expecting BSSGP PDU on signaling BVC of given pcu_idx + storing in 'roi' */
1767private altstep as_paging_sig_pcu(integer pcu_idx, template (present) PDU_BSSGP exp_rx, inout ro_integer roi)
1768runs on BSSGP_ConnHdlr {
1769[] PCU_SIG[pcu_idx].receive(exp_rx) {
1770 if (ro_integer_contains(roi, pcu_idx)) {
1771 setverdict(fail, "Received multiple paging on same SIG BVC");
1772 }
1773 roi := roi & { pcu_idx };
1774 repeat;
1775 }
Harald Welte158becf2020-12-09 12:32:32 +01001776[] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001777 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1778 }
1779[] PCU_SIG[pcu_idx].receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1780 setverdict(fail, "Different Paging than expected received SIGNALING BVC");
1781 }
Harald Welte158becf2020-12-09 12:32:32 +01001782[] PCU_PTP[pcu_idx].receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01001783 setverdict(fail, "Different Paging than expected received PTP BVC");
1784 }
1785}
1786
1787type record of default ro_default;
1788
1789/* send PS-PAGING on SIG BVC, expect it to arrive on given list of PCU indexes */
1790private function f_send_paging_ps_exp_multi(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1791 ro_integer exp_on_pcu_idx) runs on BSSGP_ConnHdlr
1792{
1793 var template (present) PDU_BSSGP exp_rx;
Daniel Willmann193e1a02021-01-17 12:55:53 +01001794 exp_rx := f_send_paging_ps(p4, sgsn_idx, true);
Harald Welte0e188242020-11-22 21:46:48 +01001795
1796 /* FIXME: make sure the relevant BVCs/BSS are connected to the ports! */
1797 var ro_default defaults := {};
1798 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1799 var default d := activate(as_paging_sig_pcu(i, exp_rx, g_roi));
1800 defaults := defaults & { d };
1801 }
1802 f_sleep(2.0);
1803 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
1804 deactivate(defaults[i]);
1805 }
1806 log("Paging received on PCU ", g_roi);
1807
1808 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1809 var boolean rx_on_i := ro_integer_contains(g_roi, i);
1810 var boolean exp_on_i := ro_integer_contains(exp_on_pcu_idx, i);
1811 if (exp_on_i and not rx_on_i) {
1812 setverdict(fail, "PS-PAGING not received on ", mp_nsconfig_pcu[i].nsei);
1813 }
1814 if (not exp_on_i and rx_on_i) {
1815 setverdict(fail, "PS-PAGING not expected but received on ", mp_nsconfig_pcu[i].nsei);
1816 }
1817 }
1818 setverdict(pass);
1819}
1820
Harald Weltecf200072021-01-16 15:20:46 +01001821/* Send PAGING-PS-REJECT on SIG BVC, expect it to arrive on the "right" SGSN */
1822private function f_send_paging_ps_rej(boolean use_sig := true, integer pcu_idx := 0) runs on BSSGP_ConnHdlr
1823{
1824 var template (value) PDU_BSSGP pdu_tx;
1825 var template (present) PDU_BSSGP exp_rx;
1826 var PDU_BSSGP pdu_rx;
1827 timer T := 5.0;
1828 var template (omit) GsmTmsi tmsi_int := omit;
1829
1830 if (ispresent(g_pars.p_tmsi)) {
1831 tmsi_int := oct2int(g_pars.p_tmsi);
1832 }
1833
1834 pdu_tx := ts_BSSGP_PAGING_PS_REJ(g_pars.imsi, 23, 42, tmsi_int);
1835 exp_rx := tr_BSSGP_PAGING_PS_REJ(g_pars.imsi, 23, 42, tmsi_int);
1836
1837 if (use_sig) {
1838 PCU_SIG[pcu_idx].send(pdu_tx);
1839 } else {
1840 PCU_PTP[pcu_idx].send(pdu_tx);
1841 }
1842 T.start;
1843 alt {
1844 [use_sig] SGSN_SIG[g_pars.sgsn_idx].receive(exp_rx) -> value pdu_rx {
1845 setverdict(pass);
1846 }
1847 [use_sig] SGSN_SIG[g_pars.sgsn_idx].receive {
1848 setverdict(fail, "Unexpected PDU on SGSN");
1849 }
1850 [use_sig] any from SGSN_SIG.receive(exp_rx) -> value pdu_rx {
1851 setverdict(fail, "PAGING-PS-REJECT arrived on wrong SGSN");
1852 }
1853 [not use_sig] SGSN_PTP[g_pars.sgsn_idx].receive(exp_rx) -> value pdu_rx {
1854 setverdict(pass);
1855 }
1856 [not use_sig] SGSN_PTP[g_pars.sgsn_idx].receive {
1857 setverdict(fail, "Unexpected PDU on SGSN");
1858 }
1859 [not use_sig] any from SGSN_PTP.receive(exp_rx) -> value pdu_rx {
1860 setverdict(fail, "PAGING-PS-REJECT arrived on wrong SGSN");
1861 }
1862 [] T.timeout {
1863 setverdict(fail, "Timeout waiting for PAGING-PS-REJECT");
1864 }
1865 }
1866}
1867
Harald Welte0e188242020-11-22 21:46:48 +01001868/* PS-PAGING on SIG-BVC for BSS Area */
1869private function f_TC_paging_ps_sig_bss(charstring id) runs on BSSGP_ConnHdlr
1870{
1871 /* we expect the paging to arrive on all three NSE */
Daniel Willmann43320442021-01-17 14:07:05 +01001872 f_send_paging_ps_exp_multi(ts_BssgpP4BssArea, g_pars.sgsn_idx, {0, 1, 2});
Harald Welte0e188242020-11-22 21:46:48 +01001873}
1874testcase TC_paging_ps_sig_bss() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001875 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001876 f_start_handlers(refers(f_TC_paging_ps_sig_bss), testcasename(), 13);
Harald Welte0e188242020-11-22 21:46:48 +01001877 f_cleanup();
1878}
1879
1880/* PS-PAGING on SIG-BVC for Location Area */
1881private function f_TC_paging_ps_sig_lac(charstring id) runs on BSSGP_ConnHdlr
1882{
Daniel Willmann2c9300f2020-12-01 10:54:08 +01001883 /* The first LAC (13135) is shared by all three NSEs */
Daniel Willmann43320442021-01-17 14:07:05 +01001884 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 +01001885 /* Reset state */
1886 g_roi := {};
1887 /* Make LAC (13300) available on pcu index 2 */
1888 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
Daniel Willmann43320442021-01-17 14:07:05 +01001889 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 +01001890}
1891testcase TC_paging_ps_sig_lac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001892 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001893 f_start_handlers(refers(f_TC_paging_ps_sig_lac), testcasename(), 14);
Harald Welte0e188242020-11-22 21:46:48 +01001894 f_cleanup();
1895}
1896
Harald Welte7462a592020-11-23 22:07:07 +01001897/* PS-PAGING on SIG-BVC for unknown Location Area */
1898private function f_TC_paging_ps_sig_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1899{
1900 var GSM_Types.LocationAreaIdentification unknown_la := {
1901 mcc_mnc := '567F99'H,
1902 lac := 33333
1903 };
Daniel Willmann2a330672021-01-18 18:50:02 +01001904 f_send_paging_ps_exp_no_bss(ts_BssgpP4LAC(unknown_la), g_pars.sgsn_idx, true);
Harald Welte7462a592020-11-23 22:07:07 +01001905}
1906testcase TC_paging_ps_sig_lac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001907 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001908 f_start_handlers(refers(f_TC_paging_ps_sig_lac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001909 f_cleanup();
1910}
1911
Harald Welte0e188242020-11-22 21:46:48 +01001912/* PS-PAGING on SIG-BVC for Routeing Area */
1913private function f_TC_paging_ps_sig_rac(charstring id) runs on BSSGP_ConnHdlr
1914{
Daniel Willmann2c9300f2020-12-01 10:54:08 +01001915 /* Only PCU index 0 has a matching BVC with the RA ID */
Daniel Willmann43320442021-01-17 14:07:05 +01001916 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 +01001917 g_roi := {};
1918 /* PCU index 1 and 2 have a matching BVC with the RA ID */
Daniel Willmann43320442021-01-17 14:07:05 +01001919 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 +01001920 g_roi := {};
1921 /* PCU index 2 has two matching BVCs with the RA ID */
1922 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
Daniel Willmann43320442021-01-17 14:07:05 +01001923 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 +01001924}
1925testcase TC_paging_ps_sig_rac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001926 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001927 f_start_handlers(refers(f_TC_paging_ps_sig_rac), testcasename(), 15);
Harald Welte0e188242020-11-22 21:46:48 +01001928 f_cleanup();
1929}
1930
Harald Welte7462a592020-11-23 22:07:07 +01001931/* PS-PAGING on SIG-BVC for unknown Routeing Area */
1932private function f_TC_paging_ps_sig_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1933{
1934 var RoutingAreaIdentification unknown_ra := {
1935 lai := {
1936 mcc_mnc := '567F99'H,
1937 lac := 33333
1938 },
1939 rac := 254
1940 };
Daniel Willmann2a330672021-01-18 18:50:02 +01001941 f_send_paging_ps_exp_no_bss(ts_BssgpP4RAC(unknown_ra), g_pars.sgsn_idx, true);
Harald Welte7462a592020-11-23 22:07:07 +01001942}
1943testcase TC_paging_ps_sig_rac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001944 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001945 f_start_handlers(refers(f_TC_paging_ps_sig_rac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001946 f_cleanup();
1947}
1948
Harald Welte0e188242020-11-22 21:46:48 +01001949/* PS-PAGING on SIG-BVC for BVCI (one cell) */
1950private function f_TC_paging_ps_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
1951{
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 Welte0e188242020-11-22 21:46:48 +01001953}
1954testcase TC_paging_ps_sig_bvci() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001955 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001956 f_start_handlers(refers(f_TC_paging_ps_sig_bvci), testcasename(), 16);
Harald Welte0e188242020-11-22 21:46:48 +01001957 f_cleanup();
1958}
1959
Harald Welteb5a04aa2021-01-16 13:04:40 +01001960/* PS-PAGING on SIG-BVC for BVCI (one cell) using IMSI only (no P-TMSI allocated) */
1961testcase TC_paging_ps_sig_bvci_imsi() runs on test_CT {
1962 f_init();
1963 f_start_handlers(refers(f_TC_paging_ps_sig_bvci), testcasename(), 16, have_ptmsi:=false);
1964 f_cleanup();
1965}
1966
Harald Weltecf200072021-01-16 15:20:46 +01001967/* Rejected PS-PAGING on SIG-BVC for BVCI (one cell) */
1968private function f_TC_paging_ps_reject_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
1969{
1970 /* first send the PS-PAGING from SGSN -> PCU */
Daniel Willmann43320442021-01-17 14:07:05 +01001971 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 +01001972 /* then simulate the PS-PAGING-REJECT from the PCU */
1973 f_send_paging_ps_rej(use_sig:=true);
1974
1975}
1976testcase TC_paging_ps_reject_sig_bvci() runs on test_CT {
1977 f_init();
1978 f_start_handlers(refers(f_TC_paging_ps_reject_sig_bvci), testcasename(), 16);
1979 f_cleanup();
1980}
1981
1982/* Rejected PS-PAGING on SIG-BVC for BVCI (one cell) using IMSI only (no P-TMSI allocated) */
1983testcase TC_paging_ps_reject_sig_bvci_imsi() runs on test_CT {
1984 f_init();
1985 f_start_handlers(refers(f_TC_paging_ps_reject_sig_bvci), testcasename(), 16, have_ptmsi:=false);
1986 f_cleanup();
1987}
1988
Harald Welte7462a592020-11-23 22:07:07 +01001989/* PS-PAGING on SIG-BVC for unknown BVCI */
1990private function f_TC_paging_ps_sig_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1991{
Daniel Willmann2a330672021-01-18 18:50:02 +01001992 f_send_paging_ps_exp_no_bss(ts_BssgpP4Bvci(33333), g_pars.sgsn_idx, true);
Harald Welte7462a592020-11-23 22:07:07 +01001993}
1994testcase TC_paging_ps_sig_bvci_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001995 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001996 f_start_handlers(refers(f_TC_paging_ps_sig_bvci_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001997 f_cleanup();
1998}
1999
Harald Welte7595d562021-01-16 19:09:20 +01002000/* DUMMY PAGING PS on SIG BVC */
2001private function f_TC_dummy_paging_ps_sig(charstring id) runs on BSSGP_ConnHdlr
2002{
2003 f_sgsn2pcu(ts_BSSGP_DUMMY_PAGING_PS(g_pars.imsi, omit),
2004 tr_BSSGP_DUMMY_PAGING_PS(g_pars.imsi, omit), use_sig := true);
2005 f_pcu2sgsn(ts_BSSGP_DUMMY_PAGING_PS_RESP(g_pars.imsi, 1, 5),
2006 tr_BSSGP_DUMMY_PAGING_PS_RESP(g_pars.imsi, 1, 5), use_sig := true)
2007}
2008testcase TC_dummy_paging_ps_sig() runs on test_CT {
2009 f_init();
2010 f_start_handlers(refers(f_TC_dummy_paging_ps_sig), testcasename(), 11);
2011 f_cleanup();
2012}
2013
Harald Welte7462a592020-11-23 22:07:07 +01002014
Harald Welte0e188242020-11-22 21:46:48 +01002015
2016/***********************************************************************
2017 * PAGING CS procedure
2018 ***********************************************************************/
2019
2020private function f_send_paging_cs(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
2021 boolean use_sig := false)
2022runs on BSSGP_ConnHdlr return template (present) PDU_BSSGP {
2023 var template (value) PDU_BSSGP pdu_tx;
2024 var template (present) PDU_BSSGP pdu_rx;
2025 /* we always specify '0' as BVCI in the templates below, as we override it with
2026 * 'p4' later anyway */
2027 pdu_rx := tr_BSSGP_CS_PAGING(0);
2028 pdu_rx.pDU_BSSGP_PAGING_CS.iMSI := tr_BSSGP_IMSI(g_pars.imsi);
2029 if (ispresent(g_pars.p_tmsi)) {
2030 pdu_tx := ts_BSSGP_CS_PAGING_PTMSI(0, g_pars.imsi, oct2int(g_pars.p_tmsi));
2031 pdu_rx.pDU_BSSGP_PAGING_CS.tMSI := tr_BSSGP_TMSI(oct2int(g_pars.p_tmsi));
2032 } else {
2033 pdu_tx := ts_BSSGP_CS_PAGING_IMSI(0, g_pars.imsi);
2034 pdu_rx.pDU_BSSGP_PAGING_CS.tMSI := omit;
2035 }
2036 pdu_tx.pDU_BSSGP_PAGING_CS.paging_Field4 := p4;
2037 pdu_rx.pDU_BSSGP_PAGING_CS.paging_Field4 := p4;
2038 if (use_sig == false) {
Harald Welte158becf2020-12-09 12:32:32 +01002039 SGSN_PTP[sgsn_idx].send(pdu_tx);
Harald Welte0e188242020-11-22 21:46:48 +01002040 } else {
2041 SGSN_SIG[sgsn_idx].send(pdu_tx);
2042 }
2043 return pdu_rx;
2044}
2045
2046/* send paging defined by 'p4' on given SGSN-side index (ptp or signaling) and expect one paging to arrive on
2047 * specified PCU index */
2048private function f_send_paging_cs_exp_one_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
2049 boolean use_sig := false,integer pcu_idx := 0)
2050runs on BSSGP_ConnHdlr {
2051 var template (present) PDU_BSSGP exp_rx;
Daniel Willmann1a859712020-12-04 00:59:45 +01002052 var boolean test_done := false;
Harald Welte0e188242020-11-22 21:46:48 +01002053 /* doesn't really make sense: Sending to a single BVCI means the message ends up
2054 * at that BVC (cell) only, and paging all over the BSS area is not possible */
2055 exp_rx := f_send_paging_cs(p4, sgsn_idx, use_sig);
2056 /* Expect paging to propagate to the one BSS addressed by the BVCI only */
2057 timer T := 2.0;
2058 T.start;
2059 alt {
Harald Welte158becf2020-12-09 12:32:32 +01002060 [not use_sig and not test_done] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01002061 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01002062 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01002063 repeat;
2064 }
2065 [not use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
2066 setverdict(fail, "Received paging on SIGNALING BVC, expected PTP BVC");
2067 }
Daniel Willmann1a859712020-12-04 00:59:45 +01002068 [use_sig and not test_done] PCU_SIG[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01002069 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01002070 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01002071 repeat;
2072 }
Harald Welte158becf2020-12-09 12:32:32 +01002073 [use_sig] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01002074 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
2075 }
Harald Welte158becf2020-12-09 12:32:32 +01002076 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01002077 setverdict(fail, "Paging received on unexpected BVC");
2078 }
2079 [] any from PCU_SIG.receive(exp_rx) {
2080 setverdict(fail, "Paging received on unexpected BVC");
2081 }
Harald Welte158becf2020-12-09 12:32:32 +01002082 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01002083 setverdict(fail, "Different Paging than expected received PTP BVC");
2084 }
2085 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
2086 setverdict(fail, "Different Paging than expected on SIGNALING BVC");
2087 }
Daniel Willmann1a859712020-12-04 00:59:45 +01002088 [not test_done] T.timeout {
2089 setverdict(fail, "Timeout while waiting for paging")
2090 }
2091 [test_done] T.timeout;
Harald Welte0e188242020-11-22 21:46:48 +01002092 }
2093}
2094
Harald Welte7462a592020-11-23 22:07:07 +01002095/* send a CS-PAGING but don't expect it to show up on any PTP or SIG BVC */
2096private function f_send_paging_cs_exp_no_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
2097 boolean use_sig := false)
2098runs on BSSGP_ConnHdlr {
2099 var template (present) PDU_BSSGP exp_rx;
2100 exp_rx := f_send_paging_cs(p4, sgsn_idx, use_sig);
2101 /* Expect paging to propagate to no BSS */
2102 timer T := 2.0;
2103 T.start;
2104 alt {
Harald Welte158becf2020-12-09 12:32:32 +01002105 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte7462a592020-11-23 22:07:07 +01002106 setverdict(fail, "Paging received on unexpected BVC");
2107 }
2108 [] any from PCU_SIG.receive(exp_rx) {
2109 setverdict(fail, "Paging received on unexpected BVC");
2110 }
Harald Welte158becf2020-12-09 12:32:32 +01002111 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
Harald Welte7462a592020-11-23 22:07:07 +01002112 setverdict(fail, "Different Paging received on PTP BVC");
2113 }
2114 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
2115 setverdict(fail, "Different Paging received on SIGNALING BVC");
2116 }
2117 [] T.timeout {
2118 setverdict(pass);
2119 }
2120 }
2121}
2122
Harald Welte0e188242020-11-22 21:46:48 +01002123private function f_TC_paging_cs_ptp_bss(charstring id) runs on BSSGP_ConnHdlr
2124{
2125 /* doesn't really make sense: Sending to a single BVCI means the message ends up
2126 * at that BVC (cell) only, and paging all over the BSS area is not possible */
2127 f_send_paging_cs_exp_one_bss(ts_BssgpP4BssArea, 0, false, 0);
2128}
2129testcase TC_paging_cs_ptp_bss() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002130 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002131 f_start_handlers(refers(f_TC_paging_cs_ptp_bss), testcasename(), 17);
Harald Welte0e188242020-11-22 21:46:48 +01002132 f_cleanup();
2133}
2134
2135/* CS-PAGING on PTP-BVC for Location Area */
2136private function f_TC_paging_cs_ptp_lac(charstring id) runs on BSSGP_ConnHdlr
2137{
2138 var template (present) PDU_BSSGP exp_rx;
2139 /* doesn't really make sense: Sending to a single BVCI means the message ends up
2140 * at that BVC (cell) only, and paging all over the BSS area is not possible */
2141 f_send_paging_cs_exp_one_bss(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, false, 0);
2142}
2143testcase TC_paging_cs_ptp_lac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002144 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002145 f_start_handlers(refers(f_TC_paging_cs_ptp_lac), testcasename(), 18);
Harald Welte0e188242020-11-22 21:46:48 +01002146 f_cleanup();
2147}
2148
Harald Welte7462a592020-11-23 22:07:07 +01002149/* CS-PAGING on PTP-BVC for unknown Location Area */
2150private function f_TC_paging_cs_ptp_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
2151{
2152 var GSM_Types.LocationAreaIdentification unknown_la := {
2153 mcc_mnc := '567F99'H,
2154 lac := 33333
2155 };
2156 /* as it's sent on the PTP BVC, we expect it to pass even for unknown LAC */
2157 f_send_paging_cs_exp_one_bss(ts_BssgpP4LAC(unknown_la), 0, false, 0);
2158}
2159testcase TC_paging_cs_ptp_lac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002160 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002161 f_start_handlers(refers(f_TC_paging_cs_ptp_lac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002162 f_cleanup();
2163}
2164
Harald Welte0e188242020-11-22 21:46:48 +01002165/* CS-PAGING on PTP-BVC for Routeing Area */
2166private function f_TC_paging_cs_ptp_rac(charstring id) runs on BSSGP_ConnHdlr
2167{
2168 /* doesn't really make sense: Sending to a single BVCI means the message ends up
2169 * at that BVC (cell) only, and paging all over the BSS area is not possible */
2170 f_send_paging_cs_exp_one_bss(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, false, 0);
2171}
2172testcase TC_paging_cs_ptp_rac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002173 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002174 f_start_handlers(refers(f_TC_paging_cs_ptp_rac), testcasename(), 19);
Harald Welte0e188242020-11-22 21:46:48 +01002175 f_cleanup();
2176}
2177
Harald Welte7462a592020-11-23 22:07:07 +01002178/* CS-PAGING on PTP-BVC for unknown Routeing Area */
2179private function f_TC_paging_cs_ptp_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
2180{
2181 var RoutingAreaIdentification unknown_ra := {
2182 lai := {
2183 mcc_mnc := '567F99'H,
2184 lac := 33333
2185 },
2186 rac := 254
2187 };
2188 /* as it's sent on the PTP BVC, we expect it to pass even for unknown RAC */
2189 f_send_paging_cs_exp_one_bss(ts_BssgpP4RAC(unknown_ra), 0, false, 0);
2190}
2191testcase TC_paging_cs_ptp_rac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002192 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002193 f_start_handlers(refers(f_TC_paging_cs_ptp_rac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002194 f_cleanup();
2195}
2196
Harald Welte0e188242020-11-22 21:46:48 +01002197/* CS-PAGING on PTP-BVC for BVCI (one cell) */
2198private function f_TC_paging_cs_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
2199{
2200 /* this should be the normal case for MS in READY MM state after a lower layer failure */
2201 f_send_paging_cs_exp_one_bss(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, false, 0);
2202}
2203testcase TC_paging_cs_ptp_bvci() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002204 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002205 f_start_handlers(refers(f_TC_paging_cs_ptp_bvci), testcasename(), 20);
Harald Welte0e188242020-11-22 21:46:48 +01002206 f_cleanup();
2207}
2208
Harald Welte7462a592020-11-23 22:07:07 +01002209/* CS-PAGING on PTP-BVC for unknown BVCI */
2210private function f_TC_paging_cs_ptp_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
2211{
2212 /* as it's sent on the PTP BVC, we expect it to pass even for unknown BVCI */
2213 f_send_paging_cs_exp_one_bss(ts_BssgpP4Bvci(33333), 0, false, 0);
2214}
2215testcase TC_paging_cs_ptp_bvci_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002216 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002217 f_start_handlers(refers(f_TC_paging_cs_ptp_bvci_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002218 f_cleanup();
2219}
2220
Harald Welte0e188242020-11-22 21:46:48 +01002221/* send CS-PAGING on SIG BVC, expect it to arrive on given list of PCU indexes */
2222private function f_send_paging_cs_exp_multi(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
2223 ro_integer exp_on_pcu_idx) runs on BSSGP_ConnHdlr
2224{
2225 var template (present) PDU_BSSGP exp_rx;
2226 exp_rx := f_send_paging_cs(p4, 0, true);
2227
2228 /* FIXME: make sure the relevant BVCs/BSS are connected to the ports! */
2229 var ro_default defaults := {};
2230 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
2231 var default d := activate(as_paging_sig_pcu(i, exp_rx, g_roi));
2232 defaults := defaults & { d };
2233 }
2234 f_sleep(2.0);
2235 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2236 deactivate(defaults[i]);
2237 }
2238 log("Paging received on PCU ", g_roi);
2239
2240 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
2241 var boolean rx_on_i := ro_integer_contains(g_roi, i);
2242 var boolean exp_on_i := ro_integer_contains(exp_on_pcu_idx, i);
2243 if (exp_on_i and not rx_on_i) {
2244 setverdict(fail, "PS-PAGING not received on ", mp_nsconfig_pcu[i].nsei);
2245 }
2246 if (not exp_on_i and rx_on_i) {
2247 setverdict(fail, "PS-PAGING not expected but received on ", mp_nsconfig_pcu[i].nsei);
2248 }
2249 }
2250 setverdict(pass);
2251}
2252
2253/* CS-PAGING on SIG-BVC for BSS Area */
2254private function f_TC_paging_cs_sig_bss(charstring id) runs on BSSGP_ConnHdlr
2255{
2256 /* we expect the paging to arrive on all three NSE */
2257 f_send_paging_cs_exp_multi(ts_BssgpP4BssArea, 0, {0, 1, 2});
2258}
2259testcase TC_paging_cs_sig_bss() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002260 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002261 f_start_handlers(refers(f_TC_paging_cs_sig_bss), testcasename(), 13);
Harald Welte0e188242020-11-22 21:46:48 +01002262 f_cleanup();
2263}
2264
2265/* CS-PAGING on SIG-BVC for Location Area */
2266private function f_TC_paging_cs_sig_lac(charstring id) runs on BSSGP_ConnHdlr
2267{
Daniel Willmannd4fb73c2020-12-07 13:57:17 +01002268 /* The first LAC (13135) is shared by all three NSEs */
2269 f_send_paging_cs_exp_multi(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, {0, 1, 2});
2270 /* Reset state */
2271 g_roi := {};
2272 /* Make LAC (13300) available on pcu index 2 */
2273 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
2274 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 +01002275}
2276testcase TC_paging_cs_sig_lac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002277 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002278 f_start_handlers(refers(f_TC_paging_cs_sig_lac), testcasename(), 14);
Harald Welte0e188242020-11-22 21:46:48 +01002279 f_cleanup();
2280}
2281
Harald Welte7462a592020-11-23 22:07:07 +01002282/* CS-PAGING on SIG-BVC for unknown Location Area */
2283private function f_TC_paging_cs_sig_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
2284{
2285 var GSM_Types.LocationAreaIdentification unknown_la := {
2286 mcc_mnc := '567F99'H,
2287 lac := 33333
2288 };
2289 f_send_paging_cs_exp_no_bss(ts_BssgpP4LAC(unknown_la), 0, true);
2290}
2291testcase TC_paging_cs_sig_lac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002292 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002293 f_start_handlers(refers(f_TC_paging_cs_sig_lac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002294 f_cleanup();
2295}
2296
Harald Welte0e188242020-11-22 21:46:48 +01002297/* CS-PAGING on SIG-BVC for Routeing Area */
2298private function f_TC_paging_cs_sig_rac(charstring id) runs on BSSGP_ConnHdlr
2299{
Daniel Willmannd4fb73c2020-12-07 13:57:17 +01002300 /* Only PCU index 0 has a matching BVC with the RA ID */
Harald Welte0e188242020-11-22 21:46:48 +01002301 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 +01002302 g_roi := {};
2303 /* PCU index 1 and 2 have a matching BVC with the RA ID */
2304 f_send_paging_cs_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[2].cell_id.ra_id), 0, {1, 2});
2305 g_roi := {};
2306 /* PCU index 2 has two matching BVCs with the RA ID */
2307 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
2308 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 +01002309}
2310testcase TC_paging_cs_sig_rac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002311 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002312 f_start_handlers(refers(f_TC_paging_cs_sig_rac), testcasename(), 15);
Harald Welte0e188242020-11-22 21:46:48 +01002313 f_cleanup();
2314}
2315
Harald Welte7462a592020-11-23 22:07:07 +01002316/* CS-PAGING on SIG-BVC for unknown Routeing Area */
2317private function f_TC_paging_cs_sig_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
2318{
2319 var RoutingAreaIdentification unknown_ra := {
2320 lai := {
2321 mcc_mnc := '567F99'H,
2322 lac := 33333
2323 },
2324 rac := 254
2325 };
2326 f_send_paging_cs_exp_no_bss(ts_BssgpP4RAC(unknown_ra), 0, true);
2327}
2328testcase TC_paging_cs_sig_rac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002329 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002330 f_start_handlers(refers(f_TC_paging_cs_sig_rac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002331 f_cleanup();
2332}
2333
Harald Welte0e188242020-11-22 21:46:48 +01002334/* CS-PAGING on SIG-BVC for BVCI (one cell) */
2335private function f_TC_paging_cs_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
2336{
2337 f_send_paging_cs_exp_multi(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, {0});
2338}
2339testcase TC_paging_cs_sig_bvci() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002340 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002341 f_start_handlers(refers(f_TC_paging_cs_sig_bvci), testcasename(), 16);
Harald Welte0e188242020-11-22 21:46:48 +01002342 f_cleanup();
2343}
2344
Harald Welte7462a592020-11-23 22:07:07 +01002345/* CS-PAGING on SIG-BVC for unknown BVCI */
2346private function f_TC_paging_cs_sig_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
2347{
2348 f_send_paging_cs_exp_no_bss(ts_BssgpP4Bvci(33333), 0, true);
2349}
2350testcase TC_paging_cs_sig_bvci_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002351 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002352 f_start_handlers(refers(f_TC_paging_cs_sig_bvci_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002353 f_cleanup();
2354}
2355
Harald Welte4f91c3b2020-12-09 12:25:51 +01002356/***********************************************************************
2357 * FLUSH-LL procedure
2358 ***********************************************************************/
2359
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002360private function f_TC_flush_ll(charstring id) runs on BSSGP_ConnHdlr {
2361 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
2362 var integer i;
2363 for (i := 0; i < 10; i := i+1) {
2364 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_FLUSH_LL(g_pars.tlli, bvci, bvci_new := bvci);
2365 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2366 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_FLUSH_LL(g_pars.tlli, bvci, bvci_new := bvci);
2367
2368 f_sgsn2pcu(pdu_tx, pdu_rx, use_sig := true);
2369
2370 pdu_tx := ts_BSSGP_FLUSH_LL_ACK(g_pars.tlli, int2oct(0, 1), 23, bvci_new := bvci);
2371 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2372 pdu_rx := tr_BSSGP_FLUSH_LL_ACK(g_pars.tlli, int2oct(0, 1), 23, bvci_new := bvci);
2373
2374 f_pcu2sgsn(pdu_tx, pdu_rx, use_sig := true);
2375 }
2376 setverdict(pass);
2377}
2378testcase TC_flush_ll() runs on test_CT
2379{
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002380 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002381 f_start_handlers(refers(f_TC_flush_ll), testcasename(), 6);
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002382 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002383 f_cleanup();
2384}
Harald Welte6dc2ac42020-11-16 09:16:17 +01002385
Harald Welte4f91c3b2020-12-09 12:25:51 +01002386/***********************************************************************
2387 * SGSN-INVOKE-TRACE procedure
2388 ***********************************************************************/
2389
Harald Weltef8e5c5d2020-11-27 22:37:23 +01002390private altstep as_bssgp_g_pcu_count(integer pcu_idx, template (present) PDU_BSSGP exp_rx, inout ro_integer roi)
2391runs on GlobalTest_CT {
2392[] G_PCU[pcu_idx].receive(exp_rx) from g_pcu[pcu_idx].vc_BSSGP {
2393 if (ro_integer_contains(roi, pcu_idx)) {
2394 setverdict(fail, "Received multiple on same SIG BVC");
2395 }
2396 roi := roi & { pcu_idx };
2397 repeat;
2398 }
2399}
2400/* send a INVOKE-TRACE from SGSN and expect to receive a copy on each NSE */
2401testcase TC_trace() runs on GlobalTest_CT
2402{
2403 var BSSGP_ConnHdlr vc_conn;
2404 f_init();
2405 f_global_init();
2406
2407 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_INVOKE_TRACE('23'O, '4321'O);
2408 var template (present) PDU_BSSGP exp_rx := ts_BSSGP_INVOKE_TRACE('23'O, '4321'O);
2409
2410 var ro_default defaults := {};
2411 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2412 activate(as_bssgp_g_pcu_count(i, exp_rx, g_roi));
2413 }
2414 G_SGSN[0].send(pdu_tx);
2415 f_sleep(2.0);
2416 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2417 deactivate(defaults[i]);
2418 }
2419
2420 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2421 if (not ro_integer_contains(g_roi, i)) {
2422 setverdict(fail, "Failed to receive TRACE on PCU index ", i);
2423 }
2424 }
2425 setverdict(pass);
2426
2427 f_cleanup();
2428}
2429
Harald Welte4f91c3b2020-12-09 12:25:51 +01002430/***********************************************************************
2431 * LLC-DISCARDED procedure
2432 ***********************************************************************/
2433
Harald Weltec0351d12020-11-27 22:49:02 +01002434private function f_TC_llc_discarded(charstring id) runs on BSSGP_ConnHdlr {
2435 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
2436
2437 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_LLC_DISCARDED(g_pars.tlli, 23, bvci, 2342);
2438 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2439 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_LLC_DISCARDED(g_pars.tlli, 23, bvci, 2342);
2440
2441 f_pcu2sgsn(pdu_tx, pdu_rx, use_sig := true);
2442
2443 setverdict(pass);
2444}
2445/* Send a LLC-DISCARDED from BSS side and expect it to show up on SGSN (SIG BVC) */
2446testcase TC_llc_discarded() runs on test_CT
2447{
Harald Weltec0351d12020-11-27 22:49:02 +01002448 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002449 f_start_handlers(refers(f_TC_llc_discarded), testcasename(), 6);
Harald Weltec0351d12020-11-27 22:49:02 +01002450 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Weltec0351d12020-11-27 22:49:02 +01002451 f_cleanup();
2452}
2453
Harald Welte4f91c3b2020-12-09 12:25:51 +01002454/***********************************************************************
2455 * OVERLOAD procedure
2456 ***********************************************************************/
2457
Harald Weltef20af412020-11-28 16:11:11 +01002458/* Send an OVERLOAD from SGSN side and expect it to show up on each PCU (SIG BVC) */
2459testcase TC_overload() runs on GlobalTest_CT
2460{
2461 f_init();
2462 f_global_init();
2463
2464 var template (value) PDU_BSSGP pdu_tx := ts_OVERLOAD('1'B);
2465 var template (present) PDU_BSSGP exp_rx := tr_OVERLOAD('1'B);
2466
2467 var ro_default defaults := {};
2468 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2469 activate(as_bssgp_g_pcu_count(i, exp_rx, g_roi));
2470 }
2471 G_SGSN[0].send(pdu_tx);
2472 f_sleep(2.0);
2473 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2474 deactivate(defaults[i]);
2475 }
2476
2477 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2478 if (not ro_integer_contains(g_roi, i)) {
2479 setverdict(fail, "Failed to receive OVERLOAD on PCU index ", i);
2480 }
2481 }
2482 setverdict(pass);
2483
2484 f_cleanup();
2485}
2486
Harald Welte4f91c3b2020-12-09 12:25:51 +01002487/***********************************************************************
2488 * BVC-BLOCK / BVC-UNBLOCK procedure
2489 ***********************************************************************/
2490
Harald Welte239aa502020-11-24 23:14:20 +01002491private function f_block_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2492{
2493 var BSSGP_BVC_CT bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2494 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2495 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2496
2497 SGSN_MGMT.clear;
2498 PCU_MGMT.clear;
2499
2500 /* block the PTP BVC from the PCU side */
2501 PCU_MGMT.send(BssgpBlockRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to bvc_ct;
2502 /* expect state on both PCU and SGSN side to change */
2503 interleave {
2504 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_BLOCKED)) from bvc_ct;
Harald Welte572b0172021-03-30 13:19:56 +02002505 [] SGSN_MGMT.receive(tr_BssgpStsInd(mp_nsconfig_sgsn[0].nsei, bvc_cfg.bvci, BVC_S_BLOCKED));
2506 [] SGSN_MGMT.receive(tr_BssgpStsInd(mp_nsconfig_sgsn[1].nsei, bvc_cfg.bvci, BVC_S_BLOCKED));
2507 /* Doesn't auto-scale with NUM_SGSN */
Harald Welte239aa502020-11-24 23:14:20 +01002508 }
2509 setverdict(pass);
2510}
2511testcase TC_bvc_block_ptp() runs on test_CT
2512{
2513 f_init();
2514 f_sleep(1.0);
2515 f_block_ptp_bvc_from_pcu(0, 0);
2516 f_cleanup();
2517}
2518
2519private function f_unblock_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2520{
2521 var BSSGP_BVC_CT bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2522 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2523 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2524
2525 SGSN_MGMT.clear;
2526 PCU_MGMT.clear;
2527
2528 /* block the PTP BVC from the PCU side */
2529 PCU_MGMT.send(BssgpUnblockRequest:{}) to bvc_ct;
2530 /* expect state on both PCU and SGSN side to change */
2531 interleave {
2532 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_UNBLOCKED)) from bvc_ct;
Harald Welte572b0172021-03-30 13:19:56 +02002533 [] SGSN_MGMT.receive(tr_BssgpStsInd(mp_nsconfig_sgsn[0].nsei, bvc_cfg.bvci, BVC_S_UNBLOCKED));
2534 [] SGSN_MGMT.receive(tr_BssgpStsInd(mp_nsconfig_sgsn[1].nsei, bvc_cfg.bvci, BVC_S_UNBLOCKED));
2535 /* Doesn't auto-scale with NUM_SGSN */
Harald Welte239aa502020-11-24 23:14:20 +01002536 }
2537 setverdict(pass);
2538}
2539testcase TC_bvc_unblock_ptp() runs on test_CT
2540{
2541 f_init();
2542 f_sleep(1.0);
2543 f_block_ptp_bvc_from_pcu(0, 0);
2544 f_sleep(1.0);
2545 f_unblock_ptp_bvc_from_pcu(0, 0);
2546 f_cleanup();
2547}
2548
Harald Welte4f91c3b2020-12-09 12:25:51 +01002549/***********************************************************************
2550 * BVC-RESET procedure
2551 ***********************************************************************/
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002552private altstep as_count_bvc_reset(integer sgsn_idx, BssgpBvci bvci, inout roro_integer roroi)
2553runs on test_CT {
2554 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(sgsn_idx, bvci);
2555 [] SGSN_MGMT.receive(BssgpResetIndication:{bvci}) from sgsn_bvc_ct {
2556 roroi[sgsn_idx] := roroi[sgsn_idx] & { bvci };
2557 repeat;
2558 }
2559}
Harald Welte60a8ec72020-11-25 17:12:53 +01002560private altstep as_ignore_status(BSSGP_BVC_MGMT_PT pt) {
2561[] pt.receive(BssgpStatusIndication:?) { repeat; }
2562}
2563private function f_get_sgsn_bvc_ct(integer sgsn_idx, BssgpBvci bvci) runs on test_CT return BSSGP_BVC_CT {
2564 for (var integer i := 0; i < lengthof(g_sgsn[sgsn_idx].cfg.bvc); i := i+1) {
2565 if (g_sgsn[sgsn_idx].cfg.bvc[i].bvci == bvci) {
2566 return g_sgsn[sgsn_idx].vc_BSSGP_BVC[i];
2567 }
2568 }
2569 return null;
2570}
2571private function f_reset_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2572{
2573 var BSSGP_BVC_CT pcu_bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2574 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2575 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002576 var ro_default defaults;
2577 var integer i;
Harald Welte60a8ec72020-11-25 17:12:53 +01002578
2579 SGSN_MGMT.clear;
2580 PCU_MGMT.clear;
2581
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002582 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
2583 g_roroi[i] := {};
2584 }
2585
Harald Welte60a8ec72020-11-25 17:12:53 +01002586 /* block the PTP BVC from the PCU side */
2587 PCU_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to pcu_bvc_ct;
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002588
Harald Welte60a8ec72020-11-25 17:12:53 +01002589 /* expect state on both PCU and SGSN side to change */
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002590 defaults := { activate(as_ignore_status(SGSN_MGMT)) };
2591
2592 /* Activate altsteps: One for each SGSN */
2593 for (i := 0; i < lengthof(g_sgsn); i := i+1) {
2594 var default d := activate(as_count_bvc_reset(i, bvc_cfg.bvci, g_roroi));
2595 defaults := defaults & { d };
Harald Welte60a8ec72020-11-25 17:12:53 +01002596 }
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002597
2598 timer T := 3.0;
2599 T.start;
2600 alt {
2601 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_BLOCKED)) from pcu_bvc_ct {
2602 g_roi := g_roi & { bvc_cfg.bvci };
2603 repeat;
2604 }
2605 [] T.timeout;
2606 }
2607
2608 for (i := 0; i < lengthof(defaults); i := i+1) {
2609 deactivate(defaults[i]);
2610 }
2611
2612 /* Check if BVC-RESET was received at all SGSNs */
2613 for (i := 0; i < lengthof(g_sgsn); i := i+1) {
2614 if (not ro_integer_contains(g_roroi[i], bvc_cfg.bvci)) {
2615 setverdict(fail, "Missing SGSN[", i, "] BVC-BLOCK of BVCI=", bvc_cfg.bvci);
2616 }
2617 }
2618
Harald Welte60a8ec72020-11-25 17:12:53 +01002619 setverdict(pass);
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002620 f_cleanup();
Harald Welte60a8ec72020-11-25 17:12:53 +01002621}
2622/* Send a BVC-RESET for a PTP BVC from the BSS side: expect it to propagate */
2623testcase TC_bvc_reset_ptp_from_bss() runs on test_CT
2624{
2625 f_init();
2626 f_sleep(3.0);
2627 f_reset_ptp_bvc_from_pcu(0, 0);
2628 f_cleanup();
2629}
2630
Harald Welteb1cc0b22021-03-30 12:16:36 +02002631private altstep as_count_bvc_sts(integer sgsn_idx, BssgpBvci bvci,
2632 template (present) BvcState exp_bvc_state, inout roro_integer roroi)
Harald Welte16786e92020-11-27 19:11:56 +01002633runs on test_CT {
2634 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(sgsn_idx, bvci);
Harald Welteb1cc0b22021-03-30 12:16:36 +02002635 [] SGSN_MGMT.receive(tr_BssgpStsInd(?, bvci, exp_bvc_state)) from sgsn_bvc_ct {
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002636 roroi[sgsn_idx] := roroi[sgsn_idx] & { bvci };
Harald Welteb2647f72020-12-07 14:36:35 +01002637 repeat;
Harald Welte16786e92020-11-27 19:11:56 +01002638 }
2639}
Harald Welteb1cc0b22021-03-30 12:16:36 +02002640
2641private altstep as_count_bvc_block(integer sgsn_idx, BssgpBvci bvci, inout roro_integer roroi)
2642runs on test_CT {
2643 [] as_count_bvc_sts(sgsn_idx, bvci, BVC_S_BLOCKED, roroi);
2644}
2645
2646private altstep as_count_bvc_unblock(integer sgsn_idx, BssgpBvci bvci, inout roro_integer roroi)
2647runs on test_CT {
2648 [] as_count_bvc_sts(sgsn_idx, bvci, BVC_S_UNBLOCKED, roroi);
2649}
2650
Harald Welte16786e92020-11-27 19:11:56 +01002651/* reset the signaling BVC from one BSS; expect no signaling BVC reset on SGSN; but BVC-BLOCK for PTP */
2652testcase TC_bvc_reset_sig_from_bss() runs on test_CT {
2653
2654 f_init();
2655 f_sleep(3.0);
2656
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002657 for (var integer i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
2658 g_roroi[i] := {};
2659 }
2660
Harald Welte16786e92020-11-27 19:11:56 +01002661 /* Start BVC-RESET procedure for BVCI=0 */
2662 PCU_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to g_pcu[0].vc_BSSGP;
2663
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002664 /* Activate altsteps: One for each PTP BVC and SGSN within that PCUs NSE */
Harald Welte16786e92020-11-27 19:11:56 +01002665 var ro_default defaults := {};
2666 for (var integer i := 0; i < lengthof(g_pcu[0].cfg.bvc); i := i+1) {
2667 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[i];
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002668 for (var integer j := 0; j < lengthof(g_sgsn); j := j+1) {
2669 var default d := activate(as_count_bvc_block(j, bvcc.bvci, g_roroi));
2670 defaults := defaults & { d };
2671 }
Harald Welte16786e92020-11-27 19:11:56 +01002672 }
2673
2674 timer T := 3.0;
2675 T.start;
2676 alt {
2677 [] SGSN_MGMT.receive(BssgpResetIndication:{0}) {
2678 setverdict(fail, "BSS-side Reset of BVCI=0 should not propagate");
2679 }
2680 [] T.timeout;
2681 }
2682
2683 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2684 deactivate(defaults[i]);
2685 }
2686
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002687 /* check if BVC-block was received on all expected BVC/SGSN */
Harald Welte16786e92020-11-27 19:11:56 +01002688 for (var integer i := 0; i < lengthof(g_pcu[0].cfg.bvc); i := i+1) {
2689 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[i];
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002690 for (var integer j := 0; j < lengthof(g_sgsn); j := j+1) {
2691 if (not ro_integer_contains(g_roroi[j], bvcc.bvci)) {
2692 setverdict(fail, "Missing SGSN[", j, "] BVC-BLOCK of BVCI=", bvcc.bvci);
2693 }
Harald Welte16786e92020-11-27 19:11:56 +01002694 }
2695 }
2696
2697 /* check if BVC-block was not received on any unexpected BVC is not required as
2698 * such a message would basically run into 'no matching clause' */
Daniel Willmannf2590212020-12-04 14:20:50 +01002699 setverdict(pass);
Harald Welte16786e92020-11-27 19:11:56 +01002700 f_cleanup();
2701}
2702
Harald Welte60a8ec72020-11-25 17:12:53 +01002703private function f_reset_ptp_bvc_from_sgsn(integer pcu_idx, integer bvc_idx) runs on test_CT
2704{
2705 var BSSGP_BVC_CT pcu_bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2706 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2707 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2708 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(0, bvc_cfg.bvci);
2709 var default d;
2710
2711 SGSN_MGMT.clear;
2712 PCU_MGMT.clear;
2713
2714 /* block the PTP BVC from the PCU side */
2715 SGSN_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to sgsn_bvc_ct;
2716 /* expect state on both PCU and SGSN side to change */
2717 d := activate(as_ignore_status(PCU_MGMT));
2718 interleave {
2719 [] SGSN_MGMT.receive(tr_BssgpStsInd(?, bvc_cfg.bvci, BVC_S_BLOCKED)) from sgsn_bvc_ct;
2720 [] PCU_MGMT.receive(BssgpResetIndication:{bvc_cfg.bvci}) from pcu_bvc_ct;
2721 }
2722 deactivate(d);
2723 setverdict(pass);
2724}
Daniel Willmannc5bbcc62021-09-24 13:17:20 +02002725
Harald Welte60a8ec72020-11-25 17:12:53 +01002726/* Send a BVC-RESET for a PTP BVC from the SGSN side: expect it to propagate */
2727testcase TC_bvc_reset_ptp_from_sgsn() runs on test_CT
2728{
2729 f_init();
2730 f_sleep(3.0);
2731 f_reset_ptp_bvc_from_sgsn(0, 0);
2732 f_cleanup();
2733}
2734
Daniel Willmannc5bbcc62021-09-24 13:17:20 +02002735/* Send a BVC-RESET for a blocked PTP BVC from the SGSN side: expect NS-STATUS with cause BVCI unknown */
2736testcase TC_bvc_reset_blocked_ptp_from_sgsn() runs on GlobalTest_CT
2737{
2738 f_init();
2739 f_global_init();
2740 f_sleep(3.0);
2741 /* Make sure NS for BVC is down and try again */
2742 f_disable_ns_pcu(0);
2743 f_sleep(10.0);
2744
2745 var BssgpBvcConfig bvc_cfg := g_pcu[0].cfg.bvc[0];
2746 SGSN_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to f_get_sgsn_bvc_ct(0, bvc_cfg.bvci);
2747
2748 /* Check for NS-STATUS with BVCI unknown, ignore other messages */
2749 var template (present) PDU_BSSGP exp_rx :=
2750 tr_BSSGP_STATUS(bvc_cfg.bvci, BSSGP_CAUSE_BVCI_UNKNOWN, ?);
2751
2752 alt {
2753 [] G_SGSN[0].receive(exp_rx) {
2754 setverdict(pass);
2755 }
2756 [] SGSN_MGMT.receive(BssgpStatusIndication:{*, bvc_cfg.bvci, BVC_S_UNBLOCKED}) {
2757 setverdict(fail, "BVC unblocked that should be gone on BSS side");
2758 }
2759 [] SGSN_MGMT.receive {
2760 repeat;
2761 }
2762 [] G_SGSN[0].receive {
2763 repeat;
2764 }
2765 }
2766
2767 f_cleanup();
2768}
2769
Daniel Willmannef7015f2021-01-08 00:43:56 +01002770private altstep as_ignore_mgmt(BSSGP_BVC_MGMT_PT pt) {
2771 [] pt.receive {repeat; }
2772}
2773
Harald Welte16786e92020-11-27 19:11:56 +01002774private altstep as_count_bvc0_block(integer pcu_idx, Nsei nsei, inout ro_integer roi)
2775runs on test_CT {
2776 var BSSGP_CT pcu_ct := g_pcu[pcu_idx].vc_BSSGP;
2777 [] PCU_MGMT.receive(BssgpResetIndication:{0}) from pcu_ct {
2778 roi := roi & { nsei };
Daniel Willmannef7015f2021-01-08 00:43:56 +01002779 repeat;
Harald Welte16786e92020-11-27 19:11:56 +01002780 }
2781}
Daniel Willmannef7015f2021-01-08 00:43:56 +01002782
Harald Welte16786e92020-11-27 19:11:56 +01002783/* reset the signaling BVC from the SGSN; expect all signaling BVC on all BSS to be reset */
2784testcase TC_bvc_reset_sig_from_sgsn() runs on test_CT {
2785
2786 f_init();
2787 f_sleep(3.0);
2788
Daniel Willmannef7015f2021-01-08 00:43:56 +01002789 SGSN_MGMT.clear;
2790 PCU_MGMT.clear;
2791
Harald Welte16786e92020-11-27 19:11:56 +01002792 /* Start BVC-RESET procedure for BVCI=0 */
2793 SGSN_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to g_sgsn[0].vc_BSSGP;
2794
Daniel Willmannef7015f2021-01-08 00:43:56 +01002795 /* Defaults match in reverse activation order, this one is a catch-all for Status indications
2796 * and reset indications sent from other components (like the ptp_bvcs). If we don't drain
2797 * the port and a different message sits at the front we wait forever and fail the test.
2798 */
2799 var ro_default defaults := { activate(as_ignore_mgmt(PCU_MGMT)) };
2800
Harald Welte16786e92020-11-27 19:11:56 +01002801 /* Activate altsteps: One for each PCU NSE */
Harald Welte16786e92020-11-27 19:11:56 +01002802 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2803 var NSConfiguration nscfg := mp_nsconfig_pcu[i];
2804 var default d := activate(as_count_bvc0_block(i, nscfg.nsei, g_roi));
2805 defaults := defaults & { d };
2806 }
2807
2808 f_sleep(3.0);
2809
2810 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2811 deactivate(defaults[i]);
2812 }
2813
2814 /* check if BVC-block was received on all expected BVC */
2815 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2816 var NSConfiguration nscfg := mp_nsconfig_pcu[i];
2817 if (not ro_integer_contains(g_roi, nscfg.nsei)) {
2818 setverdict(fail, "Missing PCU-side BVC-RESET of BVCI=0 on PCU index ", i);
2819 }
2820 }
2821
2822 /* check if BVC-block was not received on any unexpected BVC is not required as
2823 * such a message would basically run into 'no matching clause' */
2824
2825 f_cleanup();
2826}
2827
Harald Welte299aa482020-12-09 15:10:55 +01002828/***********************************************************************
2829 * FLOW-CONTROL-BVC procedure
2830 ***********************************************************************/
2831
2832private altstep as_g_count_sgsn(integer sgsn_idx, inout ro_integer roi,
2833 template PDU_BSSGP exp_rx, template (omit) PDU_BSSGP tx_reply)
2834runs on GlobalTest_CT {
2835 [] G_SGSN[sgsn_idx].receive(exp_rx) {
2836 roi := roi & { sgsn_idx };
2837 if (ispresent(tx_reply)) {
2838 G_SGSN[sgsn_idx].send(tx_reply);
2839 }
Harald Welte5fb01742021-01-15 21:07:52 +01002840 repeat;
Harald Welte299aa482020-12-09 15:10:55 +01002841 }
2842}
2843/* Send FC-BVC from simulated PCU; expect each SGSN to receive it; expect PCU to receive ACK */
2844testcase TC_fc_bvc() runs on GlobalTest_CT
2845{
2846 f_init();
2847 f_global_init_ptp();
2848
Pau Espin Pedrol6ee01262021-02-05 13:05:06 +01002849 var template (value) PDU_BSSGP pdu_tx := ts_BVC_FC_BVC(10240, 2000, 1024, 1000, '01'O);
Harald Welte299aa482020-12-09 15:10:55 +01002850 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2851 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 +01002852 var template (value) PDU_BSSGP ack_tx :=
2853 ts_BVC_FC_BVC_ACK(pdu_tx.pDU_BSSGP_FLOW_CONTROL_BVC.tag.unstructured_Value);
Harald Welte299aa482020-12-09 15:10:55 +01002854
2855 /* Send a FC-BVC from BSS to gbproxy, expect an ACK in response */
2856 G_PCU[0].send(pdu_tx);
2857
2858 /* Activate altsteps: One for each SGSN-side PTP BVC port */
2859 var ro_default defaults := {};
2860 for (var integer i := 0; i < lengthof(g_sgsn); i := i+1) {
2861 var default d := activate(as_g_count_sgsn(i, g_roi, pdu_rx, ack_tx));
2862 defaults := defaults & { d };
2863 }
2864
2865 f_sleep(3.0);
2866
2867 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2868 deactivate(defaults[i]);
2869 }
2870
2871 /* check if BVC-block was received on all expected BVC */
2872 for (var integer i := 0; i < lengthof(g_sgsn); i := i+1) {
2873 if (not ro_integer_contains(g_roi, i)) {
2874 setverdict(fail, "Missing BVC-FLOW-CONTROL on SGSN index ", i);
2875 }
2876 }
2877
2878 /* Expect ACK on PCU side */
2879 G_PCU[0].receive(ack_tx);
2880
2881 setverdict(pass);
2882
2883 f_cleanup();
2884}
2885
Harald Weltecc3894b2020-12-09 16:50:12 +01002886/***********************************************************************
2887 * FLOW-CONTROL-MS procedure
2888 ***********************************************************************/
2889
2890private function f_TC_fc_ms(charstring id) runs on BSSGP_ConnHdlr {
2891 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
2892
2893 var template (value) PDU_BSSGP fc_tx := ts_BVC_FC_MS(g_pars.tlli, 100, 200, '12'O);
2894 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2895 var template (present) PDU_BSSGP fc_rx := tr_BVC_FC_MS(g_pars.tlli, 100, 200, '12'O);
2896 var template (value) PDU_BSSGP ack_tx := ts_BVC_FC_MS_ACK(g_pars.tlli, '12'O);
2897
2898 f_pcu2sgsn(fc_tx, fc_rx, use_sig := false);
2899 f_sgsn2pcu(ack_tx, ack_tx, use_sig := false);
2900
2901 setverdict(pass);
2902}
2903/* Send a FLOW-CONTROL-MS from BSS side and expect it to show up on SGSN (PTP BVC) */
2904testcase TC_fc_ms() runs on test_CT
2905{
Harald Weltecc3894b2020-12-09 16:50:12 +01002906 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002907 f_start_handlers(refers(f_TC_fc_ms), testcasename(), 21);
Harald Weltecc3894b2020-12-09 16:50:12 +01002908 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Weltecc3894b2020-12-09 16:50:12 +01002909 f_cleanup();
2910}
2911
Harald Welted6f89812021-01-16 18:57:49 +01002912/***********************************************************************
2913 * MS-REGISTRATION ENQUIRY procedure
2914 ***********************************************************************/
Harald Weltecc3894b2020-12-09 16:50:12 +01002915
Harald Welted6f89812021-01-16 18:57:49 +01002916private function f_TC_ms_reg_enq(charstring id) runs on BSSGP_ConnHdlr
2917{
Daniel Willmann04918c02021-07-06 13:59:04 +02002918 f_pcu2any_sgsn(ts_BSSGP_MS_REG_ENQ(g_pars.imsi), tr_BSSGP_MS_REG_ENQ(g_pars.imsi), use_sig := true);
Harald Welted6f89812021-01-16 18:57:49 +01002919 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);
2920}
2921testcase TC_ms_reg_enq() runs on test_CT
2922{
2923 f_init();
2924 f_start_handlers(refers(f_TC_ms_reg_enq), testcasename(), 22);
2925 f_cleanup();
2926}
Harald Welte299aa482020-12-09 15:10:55 +01002927
Harald Weltef86f1852021-01-16 21:56:17 +01002928/***********************************************************************
2929 * RIM (RAN Information Management)
2930 ***********************************************************************/
2931
2932/* Our tests here are rather synthetic, as they don't reflect normal message flows
2933 as they would be observed in a live network. However, for testing gbproxy, this shouldn't
2934 matter as gbproxy is not concerned with anything but the source / destination routing
2935 information */
2936
2937/* gbproxy must route all unknown RIM Routing Info (Cell Id) to the SGSN. We just define
2938 one here of which we know it is not used among the [simulated] PCUs */
2939const BssgpCellId cell_id_sgsn := {
2940 ra_id := {
2941 lai := {
2942 mcc_mnc := c_mcc_mnc,
2943 lac := 65534
2944 },
2945 rac := 0
2946 },
2947 cell_id := 65533
2948};
2949
2950/* Send 'tx' on PTP-BVCI from PCU; expect 'rx' on any of our SGSN (RIM can be routed anywhere) */
2951friend function f_rim_pcu2sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
2952 integer pcu_idx := 0) runs on GlobalTest_CT {
2953 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +01002954 timer T := 2.0;
Harald Weltef86f1852021-01-16 21:56:17 +01002955
2956 RIM_PCU[pcu_idx].send(tx);
2957 T.start;
2958 alt {
2959 [] any from RIM_SGSN.receive(exp_rx) {
2960 setverdict(pass);
2961 }
2962 [] any from RIM_SGSN.receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +01002963 f_shutdown(__FILE__, __LINE__, fail, log2str("Unexpected BSSGP on SGSN side: ", rx));
Harald Weltef86f1852021-01-16 21:56:17 +01002964 }
2965 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +01002966 f_shutdown(__FILE__, __LINE__, fail,
2967 log2str("Timeout waiting for BSSGP on SGSN side: ", exp_rx));
Harald Weltef86f1852021-01-16 21:56:17 +01002968 }
2969 }
2970}
2971
2972/* Send 'tx' on PTP-BVCI from SGSN; expect 'rx' on PCU */
2973friend function f_rim_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
2974 integer sgsn_idx := 0, integer pcu_idx := 0) runs on GlobalTest_CT {
2975 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +01002976 timer T := 2.0;
Harald Weltef86f1852021-01-16 21:56:17 +01002977
2978 RIM_SGSN[sgsn_idx].send(tx);
2979 T.start;
2980 alt {
2981 [] RIM_PCU[pcu_idx].receive(exp_rx) {
2982 setverdict(pass);
2983 }
2984 [] RIM_PCU[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +01002985 f_shutdown(__FILE__, __LINE__, fail, log2str("Unexpected BSSGP on PCU side: ", rx));
Harald Weltef86f1852021-01-16 21:56:17 +01002986 }
2987 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +01002988 f_shutdown(__FILE__, __LINE__, fail,
2989 log2str("Timeout waiting for BSSGP on PCU side: ", exp_rx));
Harald Weltef86f1852021-01-16 21:56:17 +01002990 }
2991 }
2992}
2993
2994/* Send 'tx' on PTP-BVCI from SRC-PCU; expect 'rx' on DST-PCU */
2995friend function f_rim_pcu2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
2996 integer src_pcu_idx, integer dst_pcu_idx) runs on GlobalTest_CT {
2997 var integer rx_idx;
2998 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +01002999 timer T := 2.0;
Harald Weltef86f1852021-01-16 21:56:17 +01003000
3001 RIM_PCU[src_pcu_idx].send(tx);
3002 T.start;
3003 alt {
3004 [] RIM_PCU[dst_pcu_idx].receive(exp_rx) -> value rx{
3005 setverdict(pass);
3006 }
3007 [] any from RIM_PCU.receive(exp_rx) -> @index value rx_idx {
3008 setverdict(fail, "Received RIM on wrong PCU[", rx_idx ,"], expected on PCU[", dst_pcu_idx, "]");
3009 }
3010 [] any from RIM_SGSN.receive(exp_rx) {
3011 setverdict(fail, "Received RIM on SGSN but expected it on other PCU");
3012 }
3013 [] any from RIM_SGSN.receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +01003014 f_shutdown(__FILE__, __LINE__, fail, log2str("Unexpected BSSGP on SGSN side: ", rx));
Harald Weltef86f1852021-01-16 21:56:17 +01003015 }
3016 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +01003017 f_shutdown(__FILE__, __LINE__, fail,
3018 log2str("Timeout waiting for BSSGP on SGSN side: ", exp_rx));
Harald Weltef86f1852021-01-16 21:56:17 +01003019 }
3020 }
3021}
3022
3023
3024type function rim_fn(integer sgsn_idx, integer pcu_idx, integer bvc_idx) runs on GlobalTest_CT;
3025
3026/* helper function for the RIM test cases: Execute 'fn' for each BVC on each PCU for
3027 each SGSN */
3028private function f_rim_iterator(rim_fn fn) runs on GlobalTest_CT
3029{
3030 var integer sgsn_idx, pcu_idx, bvc_idx;
3031 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx+1) {
3032 for (pcu_idx := 0; pcu_idx < lengthof(g_pcu); pcu_idx := pcu_idx+1) {
3033 for (bvc_idx := 0; bvc_idx < lengthof(g_pcu[pcu_idx].cfg.bvc); bvc_idx := bvc_idx+1) {
3034 log("Testing RIM SGSN[", sgsn_idx, "] <-> PCU[", pcu_idx, "][", bvc_idx, "]");
3035 fn.apply(sgsn_idx, pcu_idx, bvc_idx);
3036 }
3037 }
3038 }
3039}
3040
3041/* RAN-INFORMATION-REQUEST */
3042private function f_TC_rim_info_req(integer sgsn_idx, integer pcu_idx, integer bvc_idx := 0)
3043runs on GlobalTest_CT
3044{
3045 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003046 var template (value) RAN_Information_Request_RIM_Container cont_tx;
3047 var template RAN_Information_Request_RIM_Container cont_rx;
3048 var template RIM_Routing_Address ra_pcu;
3049 var template RIM_Routing_Address ra_sgsn;
Harald Weltef86f1852021-01-16 21:56:17 +01003050
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003051 ra_pcu := t_RIM_Routing_Address_cid(cell_id);
3052 ra_sgsn := t_RIM_Routing_Address_cid(cell_id_sgsn);
3053
3054 cont_tx := ts_RAN_Information_Request_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3055 ts_RIM_Sequence_Number(0),
3056 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
3057 cont_rx := tr_RAN_Information_Request_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
3058 tr_RIM_Sequence_Number(0),
3059 tr_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
3060
3061 f_rim_pcu2sgsn(ts_RAN_INFORMATION_REQUEST(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3062 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3063 cont := cont_tx),
3064 tr_RAN_INFORMATION_REQUEST(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3065 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3066 cont := cont_rx),
3067 pcu_idx);
3068
3069 f_rim_sgsn2pcu(ts_RAN_INFORMATION_REQUEST(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3070 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3071 cont := cont_tx),
3072 tr_RAN_INFORMATION_REQUEST(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3073 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3074 cont := cont_rx),
Harald Weltef86f1852021-01-16 21:56:17 +01003075 sgsn_idx, pcu_idx);
3076}
3077testcase TC_rim_info_req() runs on GlobalTest_CT
3078{
3079 f_init();
3080 f_global_init();
3081 f_rim_iterator(refers(f_TC_rim_info_req));
3082 f_cleanup();
3083}
3084
3085/* RAN-INFORMATION */
3086private function f_TC_rim_info(integer sgsn_idx, integer pcu_idx, integer bvc_idx := 0)
3087runs on GlobalTest_CT
3088{
3089 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003090 var template (value) RAN_Information_RIM_Container cont_tx;
3091 var template RAN_Information_RIM_Container cont_rx;
3092 var template RIM_Routing_Address ra_pcu;
3093 var template RIM_Routing_Address ra_sgsn;
Harald Weltef86f1852021-01-16 21:56:17 +01003094
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003095 ra_pcu := t_RIM_Routing_Address_cid(cell_id);
3096 ra_sgsn := t_RIM_Routing_Address_cid(cell_id_sgsn);
3097
3098 cont_tx := ts_RAN_Information_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3099 ts_RIM_Sequence_Number(0),
3100 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
3101
3102 cont_rx := tr_RAN_Information_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
3103 tr_RIM_Sequence_Number(0),
3104 tr_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
3105
3106 f_rim_pcu2sgsn(ts_PDU_BSSGP_RAN_INFORMATION(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3107 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3108 cont := cont_tx),
3109 tr_PDU_BSSGP_RAN_INFORMATION(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3110 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3111 cont := cont_rx),
3112 pcu_idx);
3113
3114 f_rim_sgsn2pcu(ts_PDU_BSSGP_RAN_INFORMATION(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3115 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3116 cont := cont_tx),
3117 tr_PDU_BSSGP_RAN_INFORMATION(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3118 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3119 cont := cont_rx),
Harald Weltef86f1852021-01-16 21:56:17 +01003120 sgsn_idx, pcu_idx);
3121}
3122testcase TC_rim_info() runs on GlobalTest_CT
3123{
3124 f_init();
3125 f_global_init();
3126 f_rim_iterator(refers(f_TC_rim_info));
3127 f_cleanup();
3128}
3129
3130/* RAN-INFORMATION-ACK */
3131private function f_TC_rim_info_ack(integer sgsn_idx, integer pcu_idx, integer bvc_idx := 0)
3132runs on GlobalTest_CT
3133{
3134 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003135 var template (value) RAN_Information_Ack_RIM_Container cont_tx;
3136 var template RAN_Information_Ack_RIM_Container cont_rx;
3137 var template RIM_Routing_Address ra_pcu;
3138 var template RIM_Routing_Address ra_sgsn;
Harald Weltef86f1852021-01-16 21:56:17 +01003139
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003140 ra_pcu := t_RIM_Routing_Address_cid(cell_id);
3141 ra_sgsn := t_RIM_Routing_Address_cid(cell_id_sgsn);
3142
3143 cont_tx := ts_RAN_Information_Ack_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3144 ts_RIM_Sequence_Number(0));
3145
3146 cont_rx := tr_RAN_Information_Ack_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
3147 tr_RIM_Sequence_Number(0));
3148
3149 f_rim_pcu2sgsn(ts_PDU_BSSGP_RAN_INFORMATION_ACK(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3150 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3151 cont := cont_tx),
3152 tr_PDU_BSSGP_RAN_INFORMATION_ACK(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3153 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3154 cont := cont_rx),
3155 pcu_idx);
3156
3157 f_rim_sgsn2pcu(ts_PDU_BSSGP_RAN_INFORMATION_ACK(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3158 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3159 cont := cont_tx),
3160 tr_PDU_BSSGP_RAN_INFORMATION_ACK(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3161 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3162 cont := cont_rx),
Harald Weltef86f1852021-01-16 21:56:17 +01003163 sgsn_idx, pcu_idx);
3164}
3165testcase TC_rim_info_ack() runs on GlobalTest_CT
3166{
3167 f_init();
3168 f_global_init();
3169 f_rim_iterator(refers(f_TC_rim_info_ack));
3170 f_cleanup();
3171}
3172
3173/* RAN-INFORMATION-ERROR */
3174private function f_TC_rim_info_error(integer sgsn_idx, integer pcu_idx, integer bvc_idx := 0)
3175runs on GlobalTest_CT
3176{
3177 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003178 var template (value) RAN_Information_Error_RIM_Container cont_tx;
3179 var template RAN_Information_Error_RIM_Container cont_rx;
3180 var template RIM_Routing_Address ra_pcu;
3181 var template RIM_Routing_Address ra_sgsn;
Harald Weltef86f1852021-01-16 21:56:17 +01003182
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003183 ra_pcu := t_RIM_Routing_Address_cid(cell_id);
3184 ra_sgsn := t_RIM_Routing_Address_cid(cell_id_sgsn);
3185
3186 cont_tx := ts_RAN_Information_Error_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3187 ts_BSSGP_CAUSE(BSSGP_CAUSE_EQUIMENT_FAILURE),
Pau Espin Pedrol6ee01262021-02-05 13:05:06 +01003188 omit, valueof(ts_BVC_UNBLOCK(23)));
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003189
3190 cont_rx := tr_RAN_Information_Error_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
Pau Espin Pedrol6ee01262021-02-05 13:05:06 +01003191 ts_BSSGP_CAUSE(BSSGP_CAUSE_EQUIMENT_FAILURE),
3192 omit, enc_PDU_BSSGP(valueof(tr_BVC_UNBLOCK(23))));
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003193
3194 f_rim_pcu2sgsn(ts_PDU_BSSGP_RAN_INFORMATION_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_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_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_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_error() runs on GlobalTest_CT
3211{
3212 f_init();
3213 f_global_init();
3214 f_rim_iterator(refers(f_TC_rim_info_error));
3215 f_cleanup();
3216}
3217
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003218//////////////////
Harald Weltef86f1852021-01-16 21:56:17 +01003219/* RAN-INFORMATION-APPLICATION-ERROR */
3220private function f_TC_rim_info_app_error(integer sgsn_idx, integer pcu_idx, integer bvc_idx := 0)
3221runs on GlobalTest_CT
3222{
3223 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003224 var template (value) Application_Error_Container app_cont_tx;
3225 var template Application_Error_Container app_cont_rx;
3226 var template (value) RAN_Information_Application_Error_RIM_Container cont_tx;
3227 var template RAN_Information_Application_Error_RIM_Container cont_rx;
3228 var template RIM_Routing_Address ra_pcu;
3229 var template RIM_Routing_Address ra_sgsn;
Harald Weltef86f1852021-01-16 21:56:17 +01003230
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003231 ra_pcu := t_RIM_Routing_Address_cid(cell_id);
3232 ra_sgsn := t_RIM_Routing_Address_cid(cell_id_sgsn);
3233
3234 app_cont_tx := tsu_Application_Error_Container_NACC(cell_id, 23,
3235 tsu_Application_Container_IE_NACC_req(cell_id));
3236
3237 app_cont_rx := rsu_Application_Error_Container_NACC(cell_id, 23,
3238 rsu_Application_Container_IE_NACC_req(cell_id));
3239
3240 cont_tx := ts_RAN_Information_Application_Error_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3241 ts_RIM_Sequence_Number(0),
3242 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP),
3243 omit, app_cont_tx);
3244 cont_rx := tr_RAN_Information_Application_Error_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
3245 tr_RIM_Sequence_Number(0),
3246 tr_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP),
3247 omit, app_cont_rx);
3248
3249 f_rim_pcu2sgsn(ts_PDU_BSSGP_RAN_INFORMATION_APPLICATION_ERROR(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3250 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3251 cont := cont_tx),
3252 tr_PDU_BSSGP_RAN_INFORMATION_APPLICATION_ERROR(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3253 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3254 cont := cont_rx),
3255 pcu_idx);
3256
3257 f_rim_sgsn2pcu(ts_PDU_BSSGP_RAN_INFORMATION_APPLICATION_ERROR(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3258 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3259 cont := cont_tx),
3260 tr_PDU_BSSGP_RAN_INFORMATION_APPLICATION_ERROR(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3261 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3262 cont := cont_rx),
Harald Weltef86f1852021-01-16 21:56:17 +01003263 sgsn_idx, pcu_idx);
3264}
3265testcase TC_rim_info_app_error() runs on GlobalTest_CT
3266{
3267 f_init();
3268 f_global_init();
3269 f_rim_iterator(refers(f_TC_rim_info_app_error));
3270 f_cleanup();
3271}
3272
3273/* RAN-INFORMATION routing directly between PCUs, without SGSN involvement */
3274private function f_TC_rim_info_pcu2pcu(integer src_pcu_idx, integer src_bvc_idx,
3275 integer dst_pcu_idx, integer dst_bvc_idx)
3276runs on GlobalTest_CT
3277{
3278 var BssgpCellId cell_id_src := g_pcu[src_pcu_idx].cfg.bvc[src_bvc_idx].cell_id;
3279 var BssgpCellId cell_id_dst := g_pcu[dst_pcu_idx].cfg.bvc[dst_bvc_idx].cell_id;
Philipp Maier1bd60ce2021-02-10 18:25:50 +01003280 var template (value) RIM_Routing_Information ri_pcu_src_tx;
3281 var template (value) RIM_Routing_Information ri_pcu_dst_tx;
3282 var template RIM_Routing_Information ri_pcu_src_rx;
3283 var template RIM_Routing_Information ri_pcu_dst_rx;
3284 var template (value) RAN_Information_RIM_Container cont_tx;
3285 var template RAN_Information_RIM_Container cont_rx;
Harald Weltef86f1852021-01-16 21:56:17 +01003286
3287 log("Testing RIM PCU2PCU from PCU[", src_pcu_idx, "][", src_bvc_idx, "] to PCU[",
3288 dst_pcu_idx, "][", dst_bvc_idx, "]");
3289
Philipp Maier1bd60ce2021-02-10 18:25:50 +01003290 ri_pcu_src_tx := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID,
Harald Weltef86f1852021-01-16 21:56:17 +01003291 t_RIM_Routing_Address_cid(cell_id_src));
Philipp Maier1bd60ce2021-02-10 18:25:50 +01003292 ri_pcu_dst_tx := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID,
Harald Weltef86f1852021-01-16 21:56:17 +01003293 t_RIM_Routing_Address_cid(cell_id_dst));
Philipp Maier1bd60ce2021-02-10 18:25:50 +01003294 ri_pcu_src_rx := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID,
3295 t_RIM_Routing_Address_cid(cell_id_src));
3296 ri_pcu_dst_rx := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID,
3297 t_RIM_Routing_Address_cid(cell_id_dst));
3298
3299 cont_tx := ts_RAN_Information_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3300 ts_RIM_Sequence_Number(0),
3301 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
3302 cont_rx := tr_RAN_Information_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
3303 tr_RIM_Sequence_Number(0),
3304 tr_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
3305
3306 f_rim_pcu2pcu(ts_PDU_BSSGP_RAN_INFORMATION(dst := ri_pcu_dst_tx, src := ri_pcu_src_tx, cont := cont_tx),
3307 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 +01003308 src_pcu_idx, dst_pcu_idx);
3309}
3310testcase TC_rim_info_pcu2pcu() runs on GlobalTest_CT
3311{
3312 var integer src_pcu_idx, dst_pcu_idx;
3313 var integer src_bvc_idx, dst_bvc_idx;
3314 f_init();
3315 f_global_init();
3316
3317 for (src_pcu_idx := 0; src_pcu_idx < lengthof(g_pcu); src_pcu_idx := src_pcu_idx + 1) {
3318 for (src_bvc_idx := 0; src_bvc_idx < lengthof(g_pcu[src_pcu_idx].cfg.bvc); src_bvc_idx := src_bvc_idx + 1) {
3319 for (dst_pcu_idx := 0; dst_pcu_idx < lengthof(g_pcu); dst_pcu_idx := dst_pcu_idx + 1) {
3320 if (dst_pcu_idx == src_pcu_idx) {
3321 continue;
3322 }
3323
3324 for (dst_bvc_idx := 0; dst_bvc_idx < lengthof(g_pcu[dst_pcu_idx].cfg.bvc);
3325dst_bvc_idx := dst_bvc_idx + 1) {
3326 f_TC_rim_info_pcu2pcu(src_pcu_idx, src_bvc_idx, dst_pcu_idx, dst_bvc_idx);
3327 }
3328 }
3329 }
3330 }
3331
3332 f_cleanup();
3333}
3334
Pau Espin Pedrol40778e82021-05-07 13:20:58 +02003335
3336/* Test RIM REQ sent from an MME->SGSN->GBPROXY->PCU and back (eNACC) */
3337private function f_TC_rim_from_eutran(integer sgsn_idx, integer pcu_idx, integer bvc_idx := 0)
3338runs on GlobalTest_CT
3339{
3340 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
3341 var template (value) RAN_Information_Request_RIM_Container cont_tx;
3342 var template RAN_Information_Request_RIM_Container cont_rx;
3343 var template RIM_Routing_Address ra_pcu;
3344 var template RIM_Routing_Address ra_sgsn;
3345
3346 ra_pcu := t_RIM_Routing_Address_cid(cell_id);
3347 ra_sgsn := t_RIM_Routing_Address_enbid(cell_id_sgsn, tac := 3, gnbid := '12345678123456'O);
3348
3349 cont_tx := ts_RAN_Information_Request_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3350 ts_RIM_Sequence_Number(0),
3351 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
3352 cont_rx := tr_RAN_Information_Request_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
3353 tr_RIM_Sequence_Number(0),
3354 tr_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
3355
3356 f_rim_sgsn2pcu(ts_RAN_INFORMATION_REQUEST(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3357 src := ts_RIM_Routing_Information(RIM_ADDR_EUTRAN_NODEB_ID, ra_sgsn),
3358 cont := cont_tx),
3359 tr_RAN_INFORMATION_REQUEST(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3360 src := tr_RIM_Routing_Information(RIM_ADDR_EUTRAN_NODEB_ID, ra_sgsn),
3361 cont := cont_rx),
3362 sgsn_idx, pcu_idx);
3363
3364
3365 f_rim_pcu2sgsn(ts_RAN_INFORMATION_REQUEST(dst := ts_RIM_Routing_Information(RIM_ADDR_EUTRAN_NODEB_ID, ra_sgsn),
3366 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3367 cont := cont_tx),
3368 tr_RAN_INFORMATION_REQUEST(dst := tr_RIM_Routing_Information(RIM_ADDR_EUTRAN_NODEB_ID, ra_sgsn),
3369 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3370 cont := cont_rx),
3371 pcu_idx);
3372}
3373testcase TC_rim_from_eutran() runs on GlobalTest_CT
3374{
3375 f_init();
3376 f_global_init();
3377 f_rim_iterator(refers(f_TC_rim_from_eutran));
3378 f_cleanup();
3379}
3380
Harald Welte04358652021-01-17 13:48:13 +01003381/***********************************************************************
3382 * STATUS handling
3383 ***********************************************************************/
3384
3385/* BSSGP STATUS PDU must be routed based on inner "PDU In Error" message */
3386
3387/* generate a TMSI with NRI matching sgsn_idx + nri_idx */
3388private function f_gen_tmsi_for_sgsn_nri(integer sgsn_idx, integer nri_idx) runs on test_CT return OCT4
3389{
3390 var integer nri := mp_sgsn_nri[sgsn_idx][nri_idx];
3391 return f_gen_tmsi(0, nri_v := nri, nri_bitlen := mp_nri_bitlength);
3392}
3393
3394/* generate a TLLI with NRI matching sgsn_idx + nri_idx */
3395private function f_gen_tlli_for_sgsn_nri(integer sgsn_idx, integer nri_idx) runs on test_CT return OCT4
3396{
3397 var OCT4 p_tmsi := f_gen_tmsi_for_sgsn_nri(sgsn_idx, nri_idx);
3398 return f_gprs_tlli_from_tmsi(p_tmsi, TLLI_LOCAL);
3399}
3400
3401/* STATUS in uplink direction; expect routing by its NRI */
3402private function f_TC_status_ul(integer pcu_idx, integer sgsn_idx, PDU_BSSGP inner)
3403runs on GlobalTest_CT
3404{
3405 var template (value) PDU_BSSGP tx := ts_BSSGP_STATUS(omit, BSSGP_CAUSE_EQUIMENT_FAILURE, inner);
3406 var template (present) PDU_BSSGP exp_rx :=
3407 tr_BSSGP_STATUS(omit, BSSGP_CAUSE_EQUIMENT_FAILURE,
3408 tx.pDU_BSSGP_STATUS.pDU_in_Error.erroneous_BSSGP_PDU);
3409
3410 f_global_pcu2sgsn(tx, exp_rx, pcu_idx, sgsn_idx);
3411}
3412
3413/* STATUS in uplink direction; expect routing by its NRI */
3414private function f_TC_status_dl(integer sgsn_idx, integer pcu_idx, PDU_BSSGP inner)
3415runs on GlobalTest_CT
3416{
3417 var template (value) PDU_BSSGP tx := ts_BSSGP_STATUS(omit, BSSGP_CAUSE_EQUIMENT_FAILURE, inner);
3418 var template (present) PDU_BSSGP exp_rx :=
3419 tr_BSSGP_STATUS(omit, BSSGP_CAUSE_EQUIMENT_FAILURE,
3420 tx.pDU_BSSGP_STATUS.pDU_in_Error.erroneous_BSSGP_PDU);
3421
3422 f_global_sgsn2pcu(tx, exp_rx, sgsn_idx, pcu_idx);
3423}
3424
3425/* STATUS in uplink direction on SIG-BVC containing a TLLI; expect routing by its NRI */
3426testcase TC_status_sig_ul_tlli() runs on GlobalTest_CT
3427{
3428 var integer sgsn_idx, nri_idx;
3429
3430 f_init();
3431 f_global_init();
3432
3433 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3434 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx + 1) {
3435 /* some downlink PDU occurring on SIG-BVC with a TLLI */
3436 var OCT4 tlli := f_gen_tlli_for_sgsn_nri(sgsn_idx, nri_idx);
3437 var PDU_BSSGP inner := valueof(ts_BSSGP_FLUSH_LL(tlli, 2342));
3438
3439 f_TC_status_ul(0, sgsn_idx, inner);
3440 }
3441 }
3442
3443 f_cleanup();
3444}
3445
3446/* STATUS in uplink direction on SIG-BVC containing a TMSI; expect routing by its NRI */
3447testcase TC_status_sig_ul_tmsi() runs on GlobalTest_CT
3448{
3449 var integer sgsn_idx, nri_idx;
3450
3451 f_init();
3452 f_global_init();
3453
3454 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3455 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx + 1) {
3456 /* some downlink PDU occurring on SIG-BVC with a TMSI */
3457 const hexstring imsi := '001010123456789'H
3458 var OCT4 tmsi := f_gen_tmsi_for_sgsn_nri(sgsn_idx, nri_idx);
3459 var BssgpBvci bvci := g_pcu[0].cfg.bvc[0].bvci;
3460 var PDU_BSSGP inner := valueof(ts_BSSGP_CS_PAGING_PTMSI(bvci, imsi, oct2int(tmsi)));
3461 f_TC_status_ul(0, sgsn_idx, inner);
3462 }
3463 }
3464
3465 f_cleanup();
3466}
3467
3468
3469/* STATUS in uplink direction on PTP-BVC containing a TLLI; expect routing by its NRI */
3470testcase TC_status_ptp_ul_tlli() runs on GlobalTest_CT
3471{
3472 var integer sgsn_idx, nri_idx;
3473
3474 f_init();
3475 f_global_init_ptp();
3476
3477 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3478 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx + 1) {
3479 /* some downlink PDU occurring on PTP-BVC with a TLLI */
3480 var OCT4 tlli := f_gen_tlli_for_sgsn_nri(sgsn_idx, nri_idx);
3481 var PDU_BSSGP inner := valueof(ts_BSSGP_DL_UD(tlli, '2342'O));
3482
3483 f_TC_status_ul(0, sgsn_idx, inner);
3484 }
3485 }
3486
3487 f_cleanup();
3488}
3489
3490/* STATUS in uplink direction on PTP-BVC containing a TMSI; expect routing by its NRI */
3491testcase TC_status_ptp_ul_tmsi() runs on GlobalTest_CT
3492{
3493 var integer sgsn_idx, nri_idx;
3494
3495 f_init();
3496 f_global_init_ptp();
3497
3498 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3499 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx + 1) {
3500 /* some downlink PDU occurring on PTP-BVC with a TMSI */
3501 const hexstring imsi := '001010123456789'H
3502 var OCT4 tmsi := f_gen_tmsi_for_sgsn_nri(sgsn_idx, nri_idx);
3503 var BssgpBvci bvci := g_pcu[0].cfg.bvc[0].bvci;
3504 var PDU_BSSGP inner := valueof(ts_BSSGP_CS_PAGING_PTMSI(bvci, imsi, oct2int(tmsi)));
3505 f_TC_status_ul(0, sgsn_idx, inner);
3506 }
3507 }
3508
3509 f_cleanup();
3510}
3511
3512/* STATUS in downlink direction in SIG-BVC containing a BVCI; expect routing by it */
3513testcase TC_status_sig_dl_bvci() runs on GlobalTest_CT
3514{
3515 var integer sgsn_idx, pcu_idx, bvc_idx;
3516
3517 f_init();
3518 f_global_init();
3519
3520 /* test each BVC in each PCU from each SGSN */
3521 for (pcu_idx := 0; pcu_idx < lengthof(g_pcu); pcu_idx := pcu_idx + 1) {
3522 for (bvc_idx := 0; bvc_idx < lengthof(g_pcu[pcu_idx].cfg.bvc); bvc_idx := bvc_idx + 1) {
3523 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3524 /* some uplink PDU occurring on SIG-BVC containing a BVCI */
3525 var BssgpBvci bvci := g_pcu[pcu_idx].cfg.bvc[bvc_idx].bvci;
3526 var PDU_BSSGP inner := valueof(ts_BSSGP_LLC_DISCARDED('12345678'O, 1, bvci, 23));
3527 f_TC_status_dl(sgsn_idx, pcu_idx, inner);
3528 }
3529 }
3530 }
3531
3532 f_cleanup();
3533}
3534
3535/* STATUS in downlink direction in PTP-BVC; expect routing by BVCI */
3536testcase TC_status_ptp_dl_bvci() runs on GlobalTest_CT
3537{
3538 var integer sgsn_idx, pcu_idx, bvc_idx;
3539
3540 f_init();
3541 f_global_init_ptp();
3542
3543 /* test each BVC in each PCU from each SGSN */
3544 for (pcu_idx := 0; pcu_idx < lengthof(g_pcu); pcu_idx := pcu_idx + 1) {
3545 for (bvc_idx := 0; bvc_idx < lengthof(g_pcu[pcu_idx].cfg.bvc); bvc_idx := bvc_idx + 1) {
3546 var BssgpBvci bvci := g_pcu[pcu_idx].cfg.bvc[bvc_idx].bvci;
3547 f_global_ptp_connect_pcu_bvci(pcu_idx, bvci);
3548 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3549 f_global_ptp_connect_sgsn_bvci(sgsn_idx, bvci);
3550
3551 /* some uplink PDU occurring on PTP-BVC */
3552 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
3553 var PDU_BSSGP inner := valueof(ts_BSSGP_UL_UD('12345678'O, cell_id, '4223'O));
3554 f_TC_status_dl(sgsn_idx, pcu_idx, inner);
3555 }
3556 }
3557 }
3558
3559 f_cleanup();
3560}
3561
3562/* TODO: test case for DL-STATUS(SUSPEND/RESUME) containing RA-ID; expect routing by RA-ID */
3563/* 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 +01003564
Daniel Willmann423d8f42020-09-08 18:58:22 +02003565control {
3566 execute( TC_BVC_bringup() );
Harald Welte92686012020-11-15 21:45:49 +01003567 execute( TC_ul_unitdata() );
Daniel Willmann8d9fcf42021-05-28 15:05:41 +02003568 execute( TC_ul_unitdata_pool_failure() );
Harald Welte78d8db92020-11-15 23:27:27 +01003569 execute( TC_dl_unitdata() );
Harald Welte6dc2ac42020-11-16 09:16:17 +01003570 execute( TC_ra_capability() );
Daniel Willmannace3ece2020-11-16 19:53:26 +01003571 execute( TC_ra_capability_upd() );
Daniel Willmann165d6612020-11-19 14:27:29 +01003572 execute( TC_radio_status() );
Harald Welte3148a962021-01-17 11:15:28 +01003573 execute( TC_radio_status_tmsi() );
3574 execute( TC_radio_status_imsi() );
Daniel Willmannfa67f492020-11-19 15:48:05 +01003575 execute( TC_suspend() );
Daniel Willmann087a33d2020-11-19 15:58:43 +01003576 execute( TC_resume() );
Harald Weltef8e5c5d2020-11-27 22:37:23 +01003577 execute( TC_trace() );
Harald Weltec0351d12020-11-27 22:49:02 +01003578 execute( TC_llc_discarded() );
Harald Weltef20af412020-11-28 16:11:11 +01003579 execute( TC_overload() );
Harald Welte239aa502020-11-24 23:14:20 +01003580 execute( TC_bvc_block_ptp() );
3581 execute( TC_bvc_unblock_ptp() );
Harald Welte60a8ec72020-11-25 17:12:53 +01003582 execute( TC_bvc_reset_ptp_from_bss() );
Harald Welte16786e92020-11-27 19:11:56 +01003583 execute( TC_bvc_reset_sig_from_bss() );
Harald Welte60a8ec72020-11-25 17:12:53 +01003584 execute( TC_bvc_reset_ptp_from_sgsn() );
Daniel Willmannc5bbcc62021-09-24 13:17:20 +02003585 execute( TC_bvc_reset_blocked_ptp_from_sgsn() );
Harald Welte16786e92020-11-27 19:11:56 +01003586 execute( TC_bvc_reset_sig_from_sgsn() );
Harald Weltef6e59b02020-12-08 08:29:09 +01003587 if (mp_enable_bss_load_sharing) {
Harald Weltef8ef0282020-11-18 12:16:59 +01003588 /* don't enable this by default, as we don't yet have any automatic test setup for FR with 4 NS-VC */
3589 execute( TC_load_sharing_dl() );
3590 }
Harald Welte0e188242020-11-22 21:46:48 +01003591
3592 /* PAGING-PS over PTP BVC */
3593 execute( TC_paging_ps_ptp_bss() );
3594 execute( TC_paging_ps_ptp_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01003595 execute( TC_paging_ps_ptp_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003596 execute( TC_paging_ps_ptp_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01003597 execute( TC_paging_ps_ptp_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003598 execute( TC_paging_ps_ptp_bvci() );
Harald Welteb5a04aa2021-01-16 13:04:40 +01003599 execute( TC_paging_ps_ptp_bvci_imsi() );
Harald Welte7462a592020-11-23 22:07:07 +01003600 execute( TC_paging_ps_ptp_bvci_unknown() );
Harald Weltecf200072021-01-16 15:20:46 +01003601 execute( TC_paging_ps_reject_ptp_bvci() );
3602 execute( TC_paging_ps_reject_ptp_bvci_imsi() );
Harald Welte7595d562021-01-16 19:09:20 +01003603 execute( TC_dummy_paging_ps_ptp() );
Harald Welte0e188242020-11-22 21:46:48 +01003604
3605 /* PAGING-PS over SIG BVC */
3606 execute( TC_paging_ps_sig_bss() );
3607 execute( TC_paging_ps_sig_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01003608 execute( TC_paging_ps_sig_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003609 execute( TC_paging_ps_sig_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01003610 execute( TC_paging_ps_sig_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003611 execute( TC_paging_ps_sig_bvci() );
Harald Welteb5a04aa2021-01-16 13:04:40 +01003612 execute( TC_paging_ps_sig_bvci_imsi() );
Harald Welte7462a592020-11-23 22:07:07 +01003613 execute( TC_paging_ps_sig_bvci_unknown() );
Harald Weltecf200072021-01-16 15:20:46 +01003614 execute( TC_paging_ps_reject_sig_bvci() );
3615 execute( TC_paging_ps_reject_sig_bvci_imsi() );
Harald Welte7595d562021-01-16 19:09:20 +01003616 execute( TC_dummy_paging_ps_sig() );
Harald Welte0e188242020-11-22 21:46:48 +01003617
3618 /* PAGING-CS over PTP BVC */
3619 execute( TC_paging_cs_ptp_bss() );
3620 execute( TC_paging_cs_ptp_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01003621 execute( TC_paging_cs_ptp_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003622 execute( TC_paging_cs_ptp_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01003623 execute( TC_paging_cs_ptp_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003624 execute( TC_paging_cs_ptp_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01003625 execute( TC_paging_cs_ptp_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003626
3627 /* PAGING-CS over SIG BVC */
3628 execute( TC_paging_cs_sig_bss() );
3629 execute( TC_paging_cs_sig_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01003630 execute( TC_paging_cs_sig_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003631 execute( TC_paging_cs_sig_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01003632 execute( TC_paging_cs_sig_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003633 execute( TC_paging_cs_sig_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01003634 execute( TC_paging_cs_sig_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003635
Harald Weltef86f1852021-01-16 21:56:17 +01003636 /* RAN Information Management */
3637 execute( TC_rim_info_req() );
3638 execute( TC_rim_info() );
3639 execute( TC_rim_info_ack() );
3640 execute( TC_rim_info_error() );
3641 execute( TC_rim_info_app_error() );
3642 execute( TC_rim_info_pcu2pcu() );
Pau Espin Pedrol40778e82021-05-07 13:20:58 +02003643 execute( TC_rim_from_eutran() );
Harald Weltef86f1852021-01-16 21:56:17 +01003644
Harald Welte0e188242020-11-22 21:46:48 +01003645
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01003646 execute( TC_flush_ll() );
Harald Welte299aa482020-12-09 15:10:55 +01003647 execute( TC_fc_bvc() );
Harald Weltecc3894b2020-12-09 16:50:12 +01003648 execute( TC_fc_ms() );
Harald Welted6f89812021-01-16 18:57:49 +01003649 execute( TC_ms_reg_enq() );
Harald Welte04358652021-01-17 13:48:13 +01003650
3651 /* Uplink STATUS */
3652 execute( TC_status_sig_ul_tlli() );
3653 execute( TC_status_sig_ul_tmsi() );
3654 execute( TC_status_ptp_ul_tlli() );
3655 execute( TC_status_ptp_ul_tmsi() );
3656
3657 /* Downlink STATUS */
3658 execute( TC_status_sig_dl_bvci() );
3659 execute( TC_status_ptp_dl_bvci() );
Daniel Willmann423d8f42020-09-08 18:58:22 +02003660}
3661
3662
3663}