blob: 91ccbb02d3cc0b3ecfc9a9e7f360a9de772be225 [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;
36
37import from LLC_Types all;
38import from LLC_Templates all;
39
40import from GSM_RR_Types all;
41
Harald Welte6d63f742020-11-15 19:44:04 +010042/* mcc_mnc is 24.008 10.5.5.15 encoded. 262 42 */
43const BcdMccMnc c_mcc_mnc := '262F42'H;
44
Harald Welte0d5fceb2020-11-29 16:04:07 +010045/* 48.016 section 6.1.4.2: The default maximum information field size of 1600 octets shall be supported on the Gb interface */
46const integer max_fr_info_size := 1600;
47
Daniel Willmann423d8f42020-09-08 18:58:22 +020048modulepar {
Harald Welte77218d02021-01-15 19:59:15 +010049 /* NRI bit-length. 0 for no pooling */
50 integer mp_nri_bitlength := 5;
51 roro_integer mp_sgsn_nri := {
52 { 3 }, /* list of NRIs of first SGSN */
53 { 4 } /* list of NRIs of second SGSN */
54 };
Harald Weltef6e59b02020-12-08 08:29:09 +010055 boolean mp_enable_bss_load_sharing := false;
Daniel Willmann2c9300f2020-12-01 10:54:08 +010056 /* SGSN NS configuration */
Harald Welte6d63f742020-11-15 19:44:04 +010057 NSConfigurations mp_nsconfig_sgsn := {
Daniel Willmann423d8f42020-09-08 18:58:22 +020058 {
Daniel Willmann423d8f42020-09-08 18:58:22 +020059 nsei := 101,
60 role_sgsn := true,
Harald Welte90f19742020-11-06 19:34:40 +010061 handle_sns := false,
62 nsvc := {
63 {
64 provider := {
65 ip := {
66 address_family := AF_INET,
67 local_udp_port := 7777,
Harald Welted05a4a92021-01-18 12:03:53 +010068 local_ip := "127.0.0.10",
Harald Welte90f19742020-11-06 19:34:40 +010069 remote_udp_port := 23000,
Harald Weltebe7afce2021-01-17 22:04:36 +010070 remote_ip := "127.0.0.1",
Harald Welte388057d2021-01-18 18:52:49 +010071 data_weight := 0,
Harald Weltebe7afce2021-01-17 22:04:36 +010072 signalling_weight := 1
Harald Welte90f19742020-11-06 19:34:40 +010073 }
74 },
75 nsvci := 101
Harald Welte388057d2021-01-18 18:52:49 +010076 }, {
77 provider := {
78 ip := {
79 address_family := AF_INET,
80 local_udp_port := 7770,
81 local_ip := "127.0.0.10",
82 remote_udp_port := 23000,
83 remote_ip := "127.0.0.1",
84 data_weight := 1,
85 signalling_weight := 0
86 }
87 },
88 nsvci := 201
Harald Welte90f19742020-11-06 19:34:40 +010089 }
Harald Weltebe7afce2021-01-17 22:04:36 +010090
Harald Welte90f19742020-11-06 19:34:40 +010091 }
Harald Welteb978ed62020-12-12 14:01:11 +010092 }, {
93 nsei := 102,
94 role_sgsn := true,
95 handle_sns := false,
96 nsvc := {
97 {
98 provider := {
99 ip := {
100 address_family := AF_INET,
101 local_udp_port := 8888,
Harald Welted05a4a92021-01-18 12:03:53 +0100102 local_ip := "127.0.0.11",
Harald Welteb978ed62020-12-12 14:01:11 +0100103 remote_udp_port := 23000,
Harald Weltebe7afce2021-01-17 22:04:36 +0100104 remote_ip := "127.0.0.1",
Harald Welte388057d2021-01-18 18:52:49 +0100105 data_weight := 0,
Harald Weltebe7afce2021-01-17 22:04:36 +0100106 signalling_weight := 1
Harald Welteb978ed62020-12-12 14:01:11 +0100107 }
108 },
109 nsvci := 102
Harald Welte388057d2021-01-18 18:52:49 +0100110 }, {
111 provider := {
112 ip := {
113 address_family := AF_INET,
114 local_udp_port := 8880,
115 local_ip := "127.0.0.11",
116 remote_udp_port := 23000,
117 remote_ip := "127.0.0.1",
118 data_weight := 1,
119 signalling_weight := 0
120 }
121 },
122 nsvci := 202
Harald Welteb978ed62020-12-12 14:01:11 +0100123 }
124 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200125 }
126 };
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100127 /* BSS NSEI start at 2000 + x
128 * NSVCI start from value of NSEI + 100
129 * UDP port is NSVCI * 10 */
Harald Welte6d63f742020-11-15 19:44:04 +0100130 NSConfigurations mp_nsconfig_pcu := {
Daniel Willmann423d8f42020-09-08 18:58:22 +0200131 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100132 nsei := 2001,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200133 role_sgsn := false,
Harald Welte90f19742020-11-06 19:34:40 +0100134 handle_sns := false,
135 nsvc := {
136 {
137 provider := {
138 ip := {
139 address_family := AF_INET,
140 local_udp_port := 21010,
Harald Welted05a4a92021-01-18 12:03:53 +0100141 local_ip := "127.0.1.1",
Harald Welte90f19742020-11-06 19:34:40 +0100142 remote_udp_port := 23000,
Harald Weltebe7afce2021-01-17 22:04:36 +0100143 remote_ip := "127.0.0.1",
144 data_weight := 1,
145 signalling_weight := 1
Harald Welte90f19742020-11-06 19:34:40 +0100146 }
147 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100148 nsvci := 2101
Harald Welte90f19742020-11-06 19:34:40 +0100149 }
150 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200151 },
152 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100153 nsei := 2002,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200154 role_sgsn := false,
Harald Welte90f19742020-11-06 19:34:40 +0100155 handle_sns := false,
156 nsvc := {
157 {
158 provider := {
159 ip := {
160 address_family := AF_INET,
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100161 local_udp_port := 21020,
Harald Welted05a4a92021-01-18 12:03:53 +0100162 local_ip := "127.0.2.1",
Harald Welte90f19742020-11-06 19:34:40 +0100163 remote_udp_port := 23000,
Harald Weltebe7afce2021-01-17 22:04:36 +0100164 remote_ip := "127.0.0.1",
165 data_weight := 1,
166 signalling_weight := 1
Harald Welte90f19742020-11-06 19:34:40 +0100167 }
168 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100169 nsvci := 2102
Harald Welte90f19742020-11-06 19:34:40 +0100170 }
171 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200172 },
173 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100174 nsei := 2003,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200175 role_sgsn := false,
Harald Welte90f19742020-11-06 19:34:40 +0100176 handle_sns := false,
177 nsvc := {
178 {
179 provider := {
180 ip := {
181 address_family := AF_INET,
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100182 local_udp_port := 21030,
Harald Welted05a4a92021-01-18 12:03:53 +0100183 local_ip := "127.0.3.1",
Harald Welte90f19742020-11-06 19:34:40 +0100184 remote_udp_port := 23000,
Harald Weltebe7afce2021-01-17 22:04:36 +0100185 remote_ip := "127.0.0.1",
186 data_weight := 1,
187 signalling_weight := 1
Harald Welte90f19742020-11-06 19:34:40 +0100188 }
189 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100190 nsvci := 2103
Harald Welte90f19742020-11-06 19:34:40 +0100191 }
192 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200193 }
194 };
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100195 /* BVCI are NSEI*10 + x
196 * The first NSE only has one BVC, the second one 2 and so on
197 * The Cell ID is BVCI + 10000
198 * LAC/RAC are configured in such a way that:
199 * LAC 13135 is present once in NSE(2001), twice in NSE(2002) and once in NSE(2003)
200 * LAC 13300 is present twice in NSE(2003)
201 * RAI 13135-1 is present in NSE(2002) and NSE(2003)
202 * RAI 13300-0 is present twice in NSE(2003)
203 */
Harald Welte6d63f742020-11-15 19:44:04 +0100204 BssgpConfigs mp_gbconfigs := {
205 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100206 nsei := 2001,
Harald Welte6d63f742020-11-15 19:44:04 +0100207 sgsn_role := false,
208 bvc := {
209 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100210 bvci := 20011,
Harald Welte6d63f742020-11-15 19:44:04 +0100211 cell_id := {
212 ra_id := {
213 lai := {
214 mcc_mnc := c_mcc_mnc,
215 lac := 13135
216 },
217 rac := 0
218 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100219 cell_id := 30011
Harald Welte6d63f742020-11-15 19:44:04 +0100220 },
221 depth := BSSGP_DECODE_DEPTH_BSSGP,
222 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
223 }
224 }
225 }, {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100226 nsei := 2002,
Harald Welte6d63f742020-11-15 19:44:04 +0100227 sgsn_role := false,
228 bvc := {
229 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100230 bvci := 20021,
Harald Welte6d63f742020-11-15 19:44:04 +0100231 cell_id := {
232 ra_id := {
233 lai := {
234 mcc_mnc := c_mcc_mnc,
Harald Welte0e188242020-11-22 21:46:48 +0100235 lac := 13135
Harald Welte6d63f742020-11-15 19:44:04 +0100236 },
Harald Welte0e188242020-11-22 21:46:48 +0100237 rac := 1
Harald Welte6d63f742020-11-15 19:44:04 +0100238 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100239 cell_id := 30021
240 },
241 depth := BSSGP_DECODE_DEPTH_BSSGP,
242 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
243 },
244 {
245 bvci := 20022,
246 cell_id := {
247 ra_id := {
248 lai := {
249 mcc_mnc := c_mcc_mnc,
250 lac := 13135
251 },
252 rac := 2
253 },
254 cell_id := 30022
Harald Welte6d63f742020-11-15 19:44:04 +0100255 },
256 depth := BSSGP_DECODE_DEPTH_BSSGP,
257 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
258 }
259 }
260 }, {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100261 nsei := 2003,
Harald Welte6d63f742020-11-15 19:44:04 +0100262 sgsn_role := false,
263 bvc := {
264 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100265 bvci := 20031,
266 cell_id := {
267 ra_id := {
268 lai := {
269 mcc_mnc := c_mcc_mnc,
270 lac := 13135
271 },
272 rac := 1
273 },
274 cell_id := 30031
275 },
276 depth := BSSGP_DECODE_DEPTH_BSSGP,
277 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
278 },
279 {
280 bvci := 20032,
Harald Welte6d63f742020-11-15 19:44:04 +0100281 cell_id := {
282 ra_id := {
283 lai := {
284 mcc_mnc := c_mcc_mnc,
285 lac := 13300
286 },
287 rac := 0
288 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100289 cell_id := 30032
290 },
291 depth := BSSGP_DECODE_DEPTH_BSSGP,
292 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
293 },
294 {
295 bvci := 20033,
296 cell_id := {
297 ra_id := {
298 lai := {
299 mcc_mnc := c_mcc_mnc,
300 lac := 13300
301 },
302 rac := 0
303 },
304 cell_id := 30033
Harald Welte6d63f742020-11-15 19:44:04 +0100305 },
306 depth := BSSGP_DECODE_DEPTH_BSSGP,
307 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
308 }
309 }
310 }
311 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200312};
313
Daniel Willmann423d8f42020-09-08 18:58:22 +0200314type record GbInstance {
315 NS_CT vc_NS,
316 BSSGP_CT vc_BSSGP,
Harald Welte67dc8c22020-11-17 18:32:29 +0100317 BSSGP_BVC_CTs vc_BSSGP_BVC,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200318 BssgpConfig cfg
319};
Harald Welte67dc8c22020-11-17 18:32:29 +0100320type record of BSSGP_BVC_CT BSSGP_BVC_CTs
Daniel Willmann423d8f42020-09-08 18:58:22 +0200321
322const integer NUM_PCU := 3;
Harald Welte6d63f742020-11-15 19:44:04 +0100323type record of GbInstance GbInstances;
324type record of BssgpConfig BssgpConfigs;
325type record of NSConfiguration NSConfigurations;
326type record of BssgpCellId BssgpCellIds;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200327
Harald Welte572b0172021-03-30 13:19:56 +0200328/* you cannot simply change this to any larger number of SGSNs and expect all test
329 * cases to work. This would have overly complicated the code. Check below for
330 * tests that use interleave on SGSN_MGMT.receive() for each SGSN NSEI for example */
Harald Welteb978ed62020-12-12 14:01:11 +0100331const integer NUM_SGSN := 2;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200332
333type component test_CT {
Harald Welte6d63f742020-11-15 19:44:04 +0100334 var GbInstances g_pcu;
335 var GbInstances g_sgsn;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200336
337 port BSSGP_CT_PROC_PT PROC;
338
Harald Weltefbae83f2020-11-15 23:25:55 +0100339 port BSSGP_BVC_MGMT_PT SGSN_MGMT;
340 port BSSGP_BVC_MGMT_PT PCU_MGMT;
341
Daniel Willmann423d8f42020-09-08 18:58:22 +0200342 port TELNETasp_PT GBPVTY;
343
344 var boolean g_initialized := false;
345 var boolean g_use_echo := false;
Harald Welte16786e92020-11-27 19:11:56 +0100346
347 var ro_integer g_roi := {};
Daniel Willmannc38c85d2021-01-21 18:11:12 +0100348 var roro_integer g_roroi := {};
Harald Welte425d3762020-12-09 14:33:18 +0100349 timer g_Tguard;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200350};
351
352type component BSSGP_ConnHdlr {
Harald Welte3dd21b32020-11-17 19:21:00 +0100353 /* array of per-BVC ports on the PCU side */
Harald Welte158becf2020-12-09 12:32:32 +0100354 port BSSGP_PT PCU_PTP[NUM_PCU];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200355 port BSSGP_PT PCU_SIG[NUM_PCU];
356 port BSSGP_PROC_PT PCU_PROC[NUM_PCU];
Harald Welte3dd21b32020-11-17 19:21:00 +0100357 /* component reference to the component to which we're currently connected */
358 var BSSGP_BVC_CT pcu_ct[NUM_PCU];
Harald Welte0e188242020-11-22 21:46:48 +0100359 /* BSSGP BVC configuration of the component to which we're currently connected */
360 var BssgpBvcConfig pcu_bvc_cfg[NUM_PCU];
Harald Welte3dd21b32020-11-17 19:21:00 +0100361
362 /* array of per-BVC ports on the SGSN side */
Harald Welte158becf2020-12-09 12:32:32 +0100363 port BSSGP_PT SGSN_PTP[NUM_SGSN];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200364 port BSSGP_PT SGSN_SIG[NUM_SGSN];
365 port BSSGP_PROC_PT SGSN_PROC[NUM_SGSN];
Harald Welte3dd21b32020-11-17 19:21:00 +0100366 /* component reference to the component to which we're currently connected */
367 var BSSGP_BVC_CT sgsn_ct[NUM_PCU];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200368
369 var BSSGP_ConnHdlrPars g_pars;
370 timer g_Tguard;
371 var LLC_Entities llc;
Harald Welte0e188242020-11-22 21:46:48 +0100372
373 var ro_integer g_roi := {};
Daniel Willmann423d8f42020-09-08 18:58:22 +0200374}
375
376type record SGSN_ConnHdlrNetworkPars {
377 boolean expect_ptmsi,
378 boolean expect_auth,
379 boolean expect_ciph
380};
381
382type record BSSGP_ConnHdlrPars {
383 /* IMEI of the simulated ME */
384 hexstring imei,
385 /* IMSI of the simulated MS */
386 hexstring imsi,
387 /* MSISDN of the simulated MS (probably unused) */
388 hexstring msisdn,
389 /* P-TMSI allocated to the simulated MS */
390 OCT4 p_tmsi optional,
391 OCT3 p_tmsi_sig optional,
392 /* TLLI of the simulated MS */
393 OCT4 tlli,
394 OCT4 tlli_old optional,
395 RoutingAreaIdentificationV ra optional,
Harald Welte16357a92020-11-17 18:20:00 +0100396 GbInstances pcu,
Harald Welte3dd21b32020-11-17 19:21:00 +0100397 GbInstances sgsn,
Harald Weltec5f486b2021-01-16 11:07:01 +0100398 /* The SGSN index to be used within the test */
399 integer sgsn_idx,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200400 float t_guard
401};
402
Harald Welte04358652021-01-17 13:48:13 +0100403private function get_bvc_idx_for_bvci(GbInstance gbi, BssgpBvci bvci) return integer
404{
405 var integer i;
406
407 for (i := 0; i < lengthof(gbi.cfg.bvc); i := i + 1) {
408 if (gbi.cfg.bvc[i].bvci == bvci) {
409 return i;
410 }
411 }
412 setverdict(fail, "Could not find BVC Index for BVCI ", bvci);
413 return -1;
414}
415
Daniel Willmann423d8f42020-09-08 18:58:22 +0200416private function f_cellid_to_RAI(in BssgpCellId cell_id) return RoutingAreaIdentificationV {
417 /* mcc_mnc is encoded as of 24.008 10.5.5.15 */
418 var BcdMccMnc mcc_mnc := cell_id.ra_id.lai.mcc_mnc;
419
420 var RoutingAreaIdentificationV ret := {
421 mccDigit1 := mcc_mnc[0],
422 mccDigit2 := mcc_mnc[1],
423 mccDigit3 := mcc_mnc[2],
424 mncDigit3 := mcc_mnc[3],
425 mncDigit1 := mcc_mnc[4],
426 mncDigit2 := mcc_mnc[5],
427 lac := int2oct(cell_id.ra_id.lai.lac, 16),
428 rac := int2oct(cell_id.ra_id.rac, 8)
429 }
430 return ret;
431};
432
Harald Welte95339432020-12-02 18:50:52 +0100433private function f_fix_create_cb(inout BssgpConfig cfg)
434{
435 for (var integer i := 0; i < lengthof(cfg.bvc); i := i + 1) {
436 if (not isbound(cfg.bvc[i].create_cb)) {
437 cfg.bvc[i].create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
438 }
439 }
440}
441
Daniel Willmann423d8f42020-09-08 18:58:22 +0200442private function f_init_gb_pcu(inout GbInstance gb, charstring id, integer offset) runs on test_CT {
Harald Welteb419d0e2020-11-16 16:45:05 +0100443 var charstring ns_id := id & "-NS(PCU[" & int2str(offset) & "])";
444 var charstring bssgp_id := id & "-BSSGP(PCU[" & int2str(offset) & "])";
445 gb.vc_NS := NS_CT.create(ns_id);
446 gb.vc_BSSGP := BSSGP_CT.create(bssgp_id);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200447 /* connect lower end of BSSGP emulation with NS upper port */
448 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
449
Harald Welteb419d0e2020-11-16 16:45:05 +0100450 gb.vc_NS.start(NSStart(mp_nsconfig_pcu[offset], ns_id));
451 gb.vc_BSSGP.start(BssgpStart(gb.cfg, bssgp_id));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200452
453 for (var integer i := 0; i < lengthof(gb.cfg.bvc); i := i + 1) {
Harald Welteb978ed62020-12-12 14:01:11 +0100454 /* obtain the component reference of the BSSGP_BVC_CT for each PTP BVC */
Daniel Willmann423d8f42020-09-08 18:58:22 +0200455 connect(self:PROC, gb.vc_BSSGP:PROC);
456 gb.vc_BSSGP_BVC[i] := f_bssgp_get_bvci_ct(gb.cfg.bvc[i].bvci, PROC);
457 disconnect(self:PROC, gb.vc_BSSGP:PROC);
Harald Welteb978ed62020-12-12 14:01:11 +0100458 /* connect all of the per-BVC MGMT ports to our PCU_MGMT port (1:N) */
Harald Weltefbae83f2020-11-15 23:25:55 +0100459 connect(self:PCU_MGMT, gb.vc_BSSGP_BVC[i]:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200460 }
Harald Welteb978ed62020-12-12 14:01:11 +0100461 /* connect all of the BSSGP/NSE global MGMT port to our PCU_MGMT port (1:N) */
Harald Welte16786e92020-11-27 19:11:56 +0100462 connect(self:PCU_MGMT, gb.vc_BSSGP:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200463}
464
465private function f_init_gb_sgsn(inout GbInstance gb, charstring id, integer offset) runs on test_CT {
Harald Welteb419d0e2020-11-16 16:45:05 +0100466 var charstring ns_id := id & "-NS(SGSN[" & int2str(offset) & "])";
467 var charstring bssgp_id := id & "-BSSGP(SGSN[" & int2str(offset) & "])";
468 gb.vc_NS := NS_CT.create(ns_id);
469 gb.vc_BSSGP := BSSGP_CT.create(bssgp_id);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200470 /* connect lower end of BSSGP emulation with NS upper port */
471 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
472
Harald Welteb419d0e2020-11-16 16:45:05 +0100473 gb.vc_NS.start(NSStart(mp_nsconfig_sgsn[offset], ns_id));
474 gb.vc_BSSGP.start(BssgpStart(gb.cfg, bssgp_id));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200475
476 for (var integer i := 0; i < lengthof(gb.cfg.bvc); i := i + 1) {
Harald Welteb978ed62020-12-12 14:01:11 +0100477 /* obtain the component reference of the BSSGP_BVC_CT for each PTP BVC */
Daniel Willmann423d8f42020-09-08 18:58:22 +0200478 connect(self:PROC, gb.vc_BSSGP:PROC);
479 gb.vc_BSSGP_BVC[i] := f_bssgp_get_bvci_ct(gb.cfg.bvc[i].bvci, PROC);
480 disconnect(self:PROC, gb.vc_BSSGP:PROC);
Harald Welteb978ed62020-12-12 14:01:11 +0100481 /* connect all of the per-BVC MGMT ports to our SGSN_MGMT port (1:N) */
Harald Weltefbae83f2020-11-15 23:25:55 +0100482 connect(self:SGSN_MGMT, gb.vc_BSSGP_BVC[i]:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200483 }
Harald Welteb978ed62020-12-12 14:01:11 +0100484 /* connect all of the BSSGP/NSE global MGMT port to our SGSN_MGMT port (1:N) */
Harald Welte16786e92020-11-27 19:11:56 +0100485 connect(self:SGSN_MGMT, gb.vc_BSSGP:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200486}
487
488
Harald Welteb9f0fdc2020-12-09 14:44:50 +0100489private function f_destroy_gb(inout GbInstance gb) runs on test_CT {
490 gb.vc_NS.stop;
491 gb.vc_BSSGP.stop;
492
493 for (var integer i := 0; i < lengthof(gb.cfg.bvc); i := i + 1) {
494 gb.vc_BSSGP_BVC[i].stop;
495 }
496}
497
Daniel Willmann423d8f42020-09-08 18:58:22 +0200498private function f_init_vty() runs on test_CT {
499 map(self:GBPVTY, system:GBPVTY);
500 f_vty_set_prompts(GBPVTY);
501 f_vty_transceive(GBPVTY, "enable");
502}
503
Harald Welteb978ed62020-12-12 14:01:11 +0100504/* count the number of unblocked BVCI for each SGSN NSE */
505private altstep as_count_unblocked4nse(integer sgsn_idx, inout roro_integer bvci_unblocked)
506runs on test_CT {
507 var BssgpStatusIndication bsi;
508 [] SGSN_MGMT.receive(BssgpStatusIndication:{g_sgsn[sgsn_idx].cfg.nsei, ?, BVC_S_UNBLOCKED}) -> value bsi {
509 bvci_unblocked[sgsn_idx] := bvci_unblocked[sgsn_idx] & { bsi.bvci };
510 /* 'repeat' until sufficient number of BVC-rest has been received on all SGSNs */
511 for (var integer i := 0; i < lengthof(bvci_unblocked); i := i+1) {
512 if (lengthof(bvci_unblocked[i]) < lengthof(g_sgsn[i].cfg.bvc)) {
513 repeat;
514 }
515 }
516 }
517}
518
Harald Welte425d3762020-12-09 14:33:18 +0100519function f_init(float t_guard := 30.0) runs on test_CT {
Harald Welteb978ed62020-12-12 14:01:11 +0100520 var roro_integer bvci_unblocked;
Harald Weltefbae83f2020-11-15 23:25:55 +0100521 var BssgpStatusIndication bsi;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200522 var integer i;
523
524 if (g_initialized == true) {
525 return;
526 }
527 g_initialized := true;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200528
Harald Welte425d3762020-12-09 14:33:18 +0100529 g_Tguard.start(t_guard);
530 activate(as_gTguard(g_Tguard));
531
Harald Welteb978ed62020-12-12 14:01:11 +0100532 var BssgpBvcConfigs bvcs := { };
Harald Welte6d63f742020-11-15 19:44:04 +0100533 for (i := 0; i < lengthof(mp_gbconfigs); i := i+1) {
534 g_pcu[i].cfg := mp_gbconfigs[i];
Harald Welte95339432020-12-02 18:50:52 +0100535 /* make sure all have a proper crate_cb, which cannot be specified in config file */
536 f_fix_create_cb(g_pcu[i].cfg);
Harald Welte6d63f742020-11-15 19:44:04 +0100537 /* concatenate all the PCU-side BVCs for the SGSN side */
Harald Welteb978ed62020-12-12 14:01:11 +0100538 bvcs := bvcs & g_pcu[i].cfg.bvc;
539 }
540
541 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
542 g_sgsn[i].cfg := {
543 nsei := mp_nsconfig_sgsn[i].nsei,
544 sgsn_role := true,
545 bvc := bvcs
546 }
Harald Welte6d63f742020-11-15 19:44:04 +0100547 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200548
549 f_init_vty();
Harald Welte6d63f742020-11-15 19:44:04 +0100550 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
Daniel Willmann443fc572020-11-18 13:26:57 +0100551 f_vty_transceive(GBPVTY, "nsvc nsei " & int2str(g_sgsn[i].cfg.nsei) & " force-unconfigured");
Daniel Willmannad93c052020-12-04 14:14:38 +0100552 }
553 for (i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
554 f_vty_transceive(GBPVTY, "nsvc nsei " & int2str(g_pcu[i].cfg.nsei) & " force-unconfigured");
555 f_vty_transceive(GBPVTY, "delete-gbproxy-peer " & int2str(g_pcu[i].cfg.nsei) & " only-bvc");
556 }
557
558 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
Harald Welteea1ba592020-11-17 18:05:13 +0100559 f_init_gb_sgsn(g_sgsn[i], "GbProxy_Test", i);
Harald Welte6d63f742020-11-15 19:44:04 +0100560 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200561 f_sleep(4.0);
Harald Welte6d63f742020-11-15 19:44:04 +0100562 for (i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
Harald Welteb419d0e2020-11-16 16:45:05 +0100563 f_init_gb_pcu(g_pcu[i], "GbProxy_Test", i);
Harald Welte6d63f742020-11-15 19:44:04 +0100564 }
Harald Weltefbae83f2020-11-15 23:25:55 +0100565
Harald Welteb978ed62020-12-12 14:01:11 +0100566 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
567 bvci_unblocked[i] := {};
568 }
569
Harald Weltefbae83f2020-11-15 23:25:55 +0100570 /* wait until all BVC are unblocked on both sides */
Harald Welted2801272020-11-17 19:22:58 +0100571 timer T := 15.0;
Harald Weltefbae83f2020-11-15 23:25:55 +0100572 T.start;
573 alt {
Harald Welteb978ed62020-12-12 14:01:11 +0100574 /* TODO: We need to add more lines if NUM_SGSN increases. Activating default altsteps
575 * unfortunately doesn't work as we want to access the local variable bvci_unblocked. */
576 [] as_count_unblocked4nse(0, bvci_unblocked);
577 [lengthof(g_sgsn) > 1] as_count_unblocked4nse(1, bvci_unblocked);
Harald Weltefbae83f2020-11-15 23:25:55 +0100578 [] SGSN_MGMT.receive(BssgpStatusIndication:{*, ?, ?}) {
579 repeat;
580 }
Harald Welte3c905152020-11-26 20:56:09 +0100581 [] SGSN_MGMT.receive(BssgpResetIndication:?) {
582 repeat;
583 }
Harald Weltefbae83f2020-11-15 23:25:55 +0100584 [] SGSN_MGMT.receive {
Harald Welted5b7e742021-01-27 10:50:24 +0100585 f_shutdown(__FILE__, __LINE__, fail, "Received unexpected message on SGSN_MGMT");
Harald Weltefbae83f2020-11-15 23:25:55 +0100586 }
587
588 [] PCU_MGMT.receive(BssgpStatusIndication:{*, ?, BVC_S_UNBLOCKED}) -> value bsi {
589 repeat;
590 }
591 [] PCU_MGMT.receive(BssgpStatusIndication:{*, ?, ?}) {
592 repeat;
593 }
594 [] PCU_MGMT.receive(BssgpResetIndication:{0}) {
595 repeat;
596 }
597 [] PCU_MGMT.receive {
Harald Welted5b7e742021-01-27 10:50:24 +0100598 f_shutdown(__FILE__, __LINE__, fail, "Received unexpected message on PCU_MGMT");
Harald Weltefbae83f2020-11-15 23:25:55 +0100599 }
600
601 [] T.timeout {
Harald Welte6929e322020-12-12 13:10:45 +0100602 setverdict(fail, "Timeout waiting for unblock of all BVCs on SGSN side; ",
Harald Welteb978ed62020-12-12 14:01:11 +0100603 "unblocked so far: ", bvci_unblocked);
Harald Welte6929e322020-12-12 13:10:45 +0100604 /* don't stop here but print below analysis */
Harald Weltefbae83f2020-11-15 23:25:55 +0100605 }
606 }
607
Harald Welteb978ed62020-12-12 14:01:11 +0100608 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
609 /* iterate over list and check all BVCI */
610 for (var integer j := 0; j < lengthof(g_sgsn[i].cfg.bvc); j := j+1) {
611 var BssgpBvci bvci := g_sgsn[i].cfg.bvc[j].bvci;
612 if (not ro_integer_contains(bvci_unblocked[i], bvci)) {
Harald Welted5b7e742021-01-27 10:50:24 +0100613 f_shutdown(__FILE__, __LINE__, fail,
614 log2str("SGSN ", i, " BVCI=", bvci, " was not unblocked during start-up"));
Harald Welteb978ed62020-12-12 14:01:11 +0100615 }
Harald Weltefbae83f2020-11-15 23:25:55 +0100616 }
617 }
Harald Welte425d3762020-12-09 14:33:18 +0100618
619 /* re-start guard timer after all BVCs are up, so it only counts the actual test case */
620 g_Tguard.start(t_guard);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200621}
622
623function f_cleanup() runs on test_CT {
Harald Welteb9f0fdc2020-12-09 14:44:50 +0100624 var integer i;
625
Daniel Willmann491af2a2021-01-08 01:32:51 +0100626 /* To avoid a dynamic test case error we need to prevent messages arriving on unconnected
627 * ports. Waiting here ensures that any messages "in flight" will be delivered to the port
628 * before the component is shutdown and disconnected. */
629 f_sleep(0.2);
630
Harald Welteb9f0fdc2020-12-09 14:44:50 +0100631 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
632 f_destroy_gb(g_sgsn[i]);
633 }
634 for (i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
635 f_destroy_gb(g_pcu[i]);
636 }
637
638 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, pass);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200639}
640
641type function void_fn(charstring id) runs on BSSGP_ConnHdlr;
642
643/* helper function to create, connect and start a BSSGP_ConnHdlr component */
Harald Welte207166c2021-01-16 12:52:30 +0100644function f_start_handler(void_fn fn, charstring id, integer imsi_suffix, float t_guard := 30.0,
645 integer sgsn_idx := 0, integer nri_idx := 0, boolean have_ptmsi := true)
Daniel Willmann423d8f42020-09-08 18:58:22 +0200646runs on test_CT return BSSGP_ConnHdlr {
647 var BSSGP_ConnHdlr vc_conn;
Harald Weltec5f486b2021-01-16 11:07:01 +0100648 var integer nri := mp_sgsn_nri[sgsn_idx][nri_idx];
Harald Welte77218d02021-01-15 19:59:15 +0100649 var OCT4 p_tmsi := f_gen_tmsi(imsi_suffix, nri_v := nri, nri_bitlen := mp_nri_bitlength);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200650
651 var BSSGP_ConnHdlrPars pars := {
652 imei := f_gen_imei(imsi_suffix),
653 imsi := f_gen_imsi(imsi_suffix),
654 msisdn := f_gen_msisdn(imsi_suffix),
Harald Weltedbd5e672021-01-14 21:03:14 +0100655 p_tmsi := p_tmsi,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200656 p_tmsi_sig := omit,
Harald Weltedbd5e672021-01-14 21:03:14 +0100657 tlli := f_gprs_tlli_from_tmsi(p_tmsi, TLLI_LOCAL),
Daniel Willmann423d8f42020-09-08 18:58:22 +0200658 tlli_old := omit,
659 ra := omit,
Harald Welte2ecbca82021-01-16 11:23:09 +0100660 pcu := g_pcu,
661 sgsn := g_sgsn,
Harald Weltec5f486b2021-01-16 11:07:01 +0100662 sgsn_idx := sgsn_idx,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200663 t_guard := t_guard
664 };
Harald Welte207166c2021-01-16 12:52:30 +0100665 if (not have_ptmsi) {
666 pars.p_tmsi := omit;
667 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200668
669 vc_conn := BSSGP_ConnHdlr.create(id);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200670
Harald Welte25a04b12021-01-17 11:09:49 +0100671 log("Starting ", id, " for SGSN[", sgsn_idx, "], NRI=", nri, ", P-TMSI=", pars.p_tmsi,
672 ", TLLI=", pars.tlli, ", IMSI=", pars.imsi, " on component=", vc_conn);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200673 vc_conn.start(f_handler_init(fn, id, pars));
674 return vc_conn;
675}
676
Harald Welte207166c2021-01-16 12:52:30 +0100677function f_start_handlers(void_fn fn, charstring id, integer imsi_suffix, float t_guard := 30.0,
678 boolean have_ptmsi := true)
Harald Weltec5f486b2021-01-16 11:07:01 +0100679runs on test_CT
680{
681 var integer sgsn_idx, nri_idx;
682 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx:=sgsn_idx+1) {
683 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx:=nri_idx+1) {
684 var integer extd_imsi_suffix := 1000*sgsn_idx + 100*nri_idx;
685 var BSSGP_ConnHdlr vc_conn;
Harald Welte207166c2021-01-16 12:52:30 +0100686 vc_conn := f_start_handler(fn, id, extd_imsi_suffix, t_guard, sgsn_idx, nri_idx,
687 have_ptmsi);
Harald Weltec5f486b2021-01-16 11:07:01 +0100688 /* Idea: we could also run them in parallel ? */
689 vc_conn.done;
690 }
691 }
692}
693
Harald Welte3dd21b32020-11-17 19:21:00 +0100694/* 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 +0100695private function f_connect_to_pcu_bvc(integer port_idx, integer nse_idx, integer bvc_idx)
696runs on BSSGP_ConnHdlr {
697 var BSSGP_BVC_CT bvc_ct := g_pars.pcu[nse_idx].vc_BSSGP_BVC[bvc_idx]
Harald Welte158becf2020-12-09 12:32:32 +0100698 if (PCU_PTP[port_idx].checkstate("Connected")) {
Harald Welte3dd21b32020-11-17 19:21:00 +0100699 /* unregister + disconnect from old BVC */
700 f_client_unregister(g_pars.imsi, PCU_PROC[port_idx]);
Harald Welte158becf2020-12-09 12:32:32 +0100701 disconnect(self:PCU_PTP[port_idx], pcu_ct[port_idx]:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100702 disconnect(self:PCU_SIG[port_idx], pcu_ct[port_idx]:BSSGP_SP_SIG);
703 disconnect(self:PCU_PROC[port_idx], pcu_ct[port_idx]:BSSGP_PROC);
704 }
705 /* connect to new BVC and register us */
Harald Welte158becf2020-12-09 12:32:32 +0100706 connect(self:PCU_PTP[port_idx], bvc_ct:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100707 connect(self:PCU_SIG[port_idx], bvc_ct:BSSGP_SP_SIG);
708 connect(self:PCU_PROC[port_idx], bvc_ct:BSSGP_PROC);
709 f_client_register(g_pars.imsi, g_pars.tlli, PCU_PROC[port_idx]);
710 pcu_ct[port_idx] := bvc_ct;
Harald Welte0e188242020-11-22 21:46:48 +0100711 pcu_bvc_cfg[port_idx] := g_pars.pcu[nse_idx].cfg.bvc[bvc_idx];
Harald Welte3dd21b32020-11-17 19:21:00 +0100712}
713
714/* Connect the SGSN-side per-BVC ports (SGSN/SGSN_SIG/SGSN_PROC) array slot 'port_idx' to specified per-BVC component */
715private 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 +0100716 if (SGSN_PTP[port_idx].checkstate("Connected")) {
Harald Welte3dd21b32020-11-17 19:21:00 +0100717 /* unregister + disconnect from old BVC */
718 f_client_unregister(g_pars.imsi, SGSN_PROC[port_idx]);
Harald Welte158becf2020-12-09 12:32:32 +0100719 disconnect(self:SGSN_PTP[port_idx], sgsn_ct[port_idx]:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100720 disconnect(self:SGSN_SIG[port_idx], sgsn_ct[port_idx]:BSSGP_SP_SIG);
721 disconnect(self:SGSN_PROC[port_idx], sgsn_ct[port_idx]:BSSGP_PROC);
722 }
723 /* connect to new BVC and register us */
Harald Welte158becf2020-12-09 12:32:32 +0100724 connect(self:SGSN_PTP[port_idx], bvc_ct:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100725 connect(self:SGSN_SIG[port_idx], bvc_ct:BSSGP_SP_SIG);
726 connect(self:SGSN_PROC[port_idx], bvc_ct:BSSGP_PROC);
727 f_client_register(g_pars.imsi, g_pars.tlli, SGSN_PROC[port_idx]);
728 sgsn_ct[port_idx] := bvc_ct;
729}
730
Harald Welte425d3762020-12-09 14:33:18 +0100731private altstep as_gTguard(timer Tguard) {
732 [] Tguard.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +0100733 f_shutdown(__FILE__, __LINE__, fail, "Tguard timeout");
Daniel Willmann423d8f42020-09-08 18:58:22 +0200734 }
735}
736
737/* first function called in every ConnHdlr */
738private function f_handler_init(void_fn fn, charstring id, BSSGP_ConnHdlrPars pars)
739runs on BSSGP_ConnHdlr {
Harald Welte1e834f32020-11-15 20:02:59 +0100740 var integer i;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200741 /* do some common stuff like setting up g_pars */
742 g_pars := pars;
743
744 llc := f_llc_create(false);
745
Harald Welte3dd21b32020-11-17 19:21:00 +0100746 /* default connections on PCU side: First BVC of each NSE/PCU */
747 for (i := 0; i < lengthof(g_pars.pcu); i := i+1) {
Harald Welte0e188242020-11-22 21:46:48 +0100748 f_connect_to_pcu_bvc(port_idx := i, nse_idx := i, bvc_idx := 0);
Harald Welte1e834f32020-11-15 20:02:59 +0100749 }
Harald Welte3dd21b32020-11-17 19:21:00 +0100750
751 /* default connections on SGSN side: First BVC of each NSE/SGSN */
752 for (i := 0; i < lengthof(g_pars.sgsn); i := i+1) {
753 f_connect_to_sgsn_bvc(i, g_pars.sgsn[i].vc_BSSGP_BVC[0]);
Harald Welte1e834f32020-11-15 20:02:59 +0100754 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200755
756 g_Tguard.start(pars.t_guard);
Harald Welte425d3762020-12-09 14:33:18 +0100757 activate(as_gTguard(g_Tguard));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200758
759 /* call the user-supplied test case function */
760 fn.apply(id);
Harald Welteb33fb592021-01-16 12:50:56 +0100761
762 for (i := 0; i < NUM_SGSN; i := i+1) {
763 if (SGSN_PROC[i].checkstate("Connected")) {
764 f_client_unregister(g_pars.imsi, SGSN_PROC[i])
765 }
766 }
767
768 for (i := 0; i < NUM_PCU; i := i+1) {
769 if (PCU_PROC[i].checkstate("Connected")) {
770 f_client_unregister(g_pars.imsi, PCU_PROC[i])
771 }
772 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200773}
774
Harald Welte1e834f32020-11-15 20:02:59 +0100775private function f_client_register(hexstring imsi, OCT4 tlli, BSSGP_PROC_PT PT)
776runs on BSSGP_ConnHdlr {
777 PT.call(BSSGP_register_client:{imsi, tlli}) {
778 [] PT.getreply(BSSGP_register_client:{imsi, tlli}) {};
779 }
780}
781
782private function f_client_unregister(hexstring imsi, BSSGP_PROC_PT PT)
783runs on BSSGP_ConnHdlr {
784 PT.call(BSSGP_unregister_client:{imsi}) {
785 [] PT.getreply(BSSGP_unregister_client:{imsi}) {};
786 }
787}
788
Harald Welte22ef5d92020-11-16 13:35:14 +0100789/* Send 'tx' on PTP-BVCI from PCU; expect 'rx' on SGSN */
790friend function f_pcu2sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
Harald Weltec5f486b2021-01-16 11:07:01 +0100791 integer pcu_idx := 0, boolean use_sig := false) runs on BSSGP_ConnHdlr {
792 var integer sgsn_idx := g_pars.sgsn_idx;
Harald Welte22ef5d92020-11-16 13:35:14 +0100793 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +0100794 timer T := 2.0;
Harald Welte22ef5d92020-11-16 13:35:14 +0100795
Daniel Willmann4798fd72020-11-24 16:23:29 +0100796 if (use_sig) {
797 PCU_SIG[pcu_idx].send(tx);
798 } else {
Harald Welte158becf2020-12-09 12:32:32 +0100799 PCU_PTP[pcu_idx].send(tx);
Daniel Willmann4798fd72020-11-24 16:23:29 +0100800 }
801
Harald Welte22ef5d92020-11-16 13:35:14 +0100802 T.start;
803 alt {
Daniel Willmann4798fd72020-11-24 16:23:29 +0100804 [use_sig] SGSN_SIG[sgsn_idx].receive(exp_rx) {
805 setverdict(pass);
806 }
Harald Welte158becf2020-12-09 12:32:32 +0100807 [not use_sig] SGSN_PTP[sgsn_idx].receive(exp_rx) {
Harald Welte22ef5d92020-11-16 13:35:14 +0100808 setverdict(pass);
809 }
Harald Welte158becf2020-12-09 12:32:32 +0100810 [] SGSN_PTP[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +0100811 f_shutdown(__FILE__, __LINE__, fail,
812 log2str("Unexpected BSSGP on SGSN[", sgsn_idx, "] side: ", rx));
Harald Welte22ef5d92020-11-16 13:35:14 +0100813 }
Daniel Willmann4798fd72020-11-24 16:23:29 +0100814 [] SGSN_SIG[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +0100815 f_shutdown(__FILE__, __LINE__, fail,
816 log2str("Unexpected SIG BSSGP on SGSN[", sgsn_idx, "] side: ", rx));
Daniel Willmann4798fd72020-11-24 16:23:29 +0100817 }
Harald Welte22ef5d92020-11-16 13:35:14 +0100818 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +0100819 f_shutdown(__FILE__, __LINE__, fail,
820 log2str("Timeout waiting for BSSGP on SGSN[", sgsn_idx, "] side: ", exp_rx));
Harald Welte22ef5d92020-11-16 13:35:14 +0100821 }
822 }
823}
824
Harald Welte3148a962021-01-17 11:15:28 +0100825/* Send 'tx' from PCU; expect 'exp_rx' on _any_ SGSN */
826friend function f_pcu2any_sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
827 integer pcu_idx := 0, boolean use_sig := false)
828runs on BSSGP_ConnHdlr return integer {
829 var integer rx_idx := -1;
830 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +0100831 timer T := 2.0;
Harald Welte3148a962021-01-17 11:15:28 +0100832
833 if (use_sig) {
834 PCU_SIG[pcu_idx].send(tx);
835 } else {
836 PCU_PTP[pcu_idx].send(tx);
837 }
838
839 T.start;
840 alt {
841 [use_sig] any from SGSN_SIG.receive(exp_rx) -> @index value rx_idx {
842 setverdict(pass);
843 }
844 [not use_sig] any from SGSN_PTP.receive(exp_rx) -> @index value rx_idx {
845 setverdict(pass);
846 }
847 [] any from SGSN_PTP.receive(PDU_BSSGP:?) -> value rx @index value rx_idx {
Harald Welted5b7e742021-01-27 10:50:24 +0100848 f_shutdown(__FILE__, __LINE__, fail,
849 log2str("Unexpected BSSGP on SGSN[", rx_idx, "] side: ", rx));
Harald Welte3148a962021-01-17 11:15:28 +0100850 }
851 [] any from SGSN_SIG.receive(PDU_BSSGP:?) -> value rx @index value rx_idx {
Harald Welted5b7e742021-01-27 10:50:24 +0100852 f_shutdown(__FILE__, __LINE__, fail,
853 log2str("Unexpected SIG BSSGP on SGSN[", rx_idx, "] side: ", rx));
Harald Welte3148a962021-01-17 11:15:28 +0100854 }
855 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +0100856 f_shutdown(__FILE__, __LINE__, fail,
857 log2str("Timeout waiting for BSSGP on SGSN side: ", exp_rx));
Harald Welte3148a962021-01-17 11:15:28 +0100858 }
859 }
860 return rx_idx;
861}
862
Harald Welte22ef5d92020-11-16 13:35:14 +0100863/* Send 'tx' on PTP-BVCI from SGSN; expect 'rx' on PCU */
864friend function f_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
Harald Weltec5f486b2021-01-16 11:07:01 +0100865 integer pcu_idx := 0, boolean use_sig := false) runs on BSSGP_ConnHdlr {
866 var integer sgsn_idx := g_pars.sgsn_idx;
Harald Welte22ef5d92020-11-16 13:35:14 +0100867 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +0100868 timer T := 2.0;
Harald Welte22ef5d92020-11-16 13:35:14 +0100869
Daniel Willmann4798fd72020-11-24 16:23:29 +0100870 if (use_sig) {
871 SGSN_SIG[sgsn_idx].send(tx);
872 } else {
Harald Welte158becf2020-12-09 12:32:32 +0100873 SGSN_PTP[sgsn_idx].send(tx);
Daniel Willmann4798fd72020-11-24 16:23:29 +0100874 }
875
Harald Welte22ef5d92020-11-16 13:35:14 +0100876 T.start;
877 alt {
Daniel Willmann4798fd72020-11-24 16:23:29 +0100878 [use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
879 setverdict(pass);
880 }
Harald Welte158becf2020-12-09 12:32:32 +0100881 [not use_sig] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte22ef5d92020-11-16 13:35:14 +0100882 setverdict(pass);
883 }
Harald Welte158becf2020-12-09 12:32:32 +0100884 [] PCU_PTP[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +0100885 f_shutdown(__FILE__, __LINE__, fail, log2str("Unexpected BSSGP on PCU side: ", rx));
Harald Welte22ef5d92020-11-16 13:35:14 +0100886 }
Daniel Willmann4798fd72020-11-24 16:23:29 +0100887 [] PCU_SIG[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +0100888 f_shutdown(__FILE__, __LINE__, fail, log2str("Unexpected SIG BSSGP on PCU side: ", rx));
Daniel Willmann4798fd72020-11-24 16:23:29 +0100889 }
Harald Welte22ef5d92020-11-16 13:35:14 +0100890 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +0100891 f_shutdown(__FILE__, __LINE__, fail,
892 log2str("Timeout waiting for BSSGP on PCU side: ", exp_rx));
Harald Welte22ef5d92020-11-16 13:35:14 +0100893 }
894 }
895}
Harald Welte1e834f32020-11-15 20:02:59 +0100896
Harald Welte3807ed12020-11-24 19:05:22 +0100897/***********************************************************************
898 * GlobaLTest_CT: Using the per-NSE GLOBAL ports on PCU + SGSN side
899 ***********************************************************************/
900
901type component GlobalTest_CT extends test_CT {
902 port BSSGP_PT G_PCU[NUM_PCU];
Harald Welte04358652021-01-17 13:48:13 +0100903 var integer g_pcu_idx[NUM_PCU]; /* BVC index currently connected to G_PCU */
Harald Welte3807ed12020-11-24 19:05:22 +0100904 port BSSGP_PT G_SGSN[NUM_SGSN];
Harald Welte04358652021-01-17 13:48:13 +0100905 var integer g_sgsn_idx[NUM_SGSN]; /* BVC index currently connected to G_SGSN */
Harald Weltef86f1852021-01-16 21:56:17 +0100906 port BSSGP_PT RIM_PCU[NUM_PCU];
907 port BSSGP_PT RIM_SGSN[NUM_SGSN];
Harald Welte3807ed12020-11-24 19:05:22 +0100908};
909
Harald Welte299aa482020-12-09 15:10:55 +0100910/* connect the signaling BVC of each NSE to the G_PCU / G_SGSN ports */
Harald Welte3807ed12020-11-24 19:05:22 +0100911private function f_global_init() runs on GlobalTest_CT {
912 var integer i;
913 for (i := 0; i < lengthof(g_sgsn); i := i+1) {
914 connect(self:G_SGSN[i], g_sgsn[i].vc_BSSGP:GLOBAL);
Harald Weltef86f1852021-01-16 21:56:17 +0100915 connect(self:RIM_SGSN[i], g_sgsn[i].vc_BSSGP:RIM);
Harald Welte3807ed12020-11-24 19:05:22 +0100916 }
917 for (i := 0; i < lengthof(g_pcu); i := i+1) {
918 connect(self:G_PCU[i], g_pcu[i].vc_BSSGP:GLOBAL);
Harald Weltef86f1852021-01-16 21:56:17 +0100919 connect(self:RIM_PCU[i], g_pcu[i].vc_BSSGP:RIM);
Harald Welte3807ed12020-11-24 19:05:22 +0100920 }
921}
922
Harald Welte299aa482020-12-09 15:10:55 +0100923/* connect the first PTP BVC of each NSE to the G_PCU / G_SGSN ports */
924private function f_global_init_ptp() runs on GlobalTest_CT {
925 var integer i;
926 for (i := 0; i < lengthof(g_sgsn); i := i+1) {
Harald Welte04358652021-01-17 13:48:13 +0100927 log("Connecting G_SGSN[", i, "] to BVCI=", g_sgsn[i].cfg.bvc[0].bvci);
Harald Welte299aa482020-12-09 15:10:55 +0100928 connect(self:G_SGSN[i], g_sgsn[i].vc_BSSGP_BVC[0]:GLOBAL);
Harald Welte04358652021-01-17 13:48:13 +0100929 g_sgsn_idx[i] := 0;
Harald Welte299aa482020-12-09 15:10:55 +0100930 }
931 for (i := 0; i < lengthof(g_pcu); i := i+1) {
Harald Welte04358652021-01-17 13:48:13 +0100932 log("Connecting G_PCU[", i, "] to BVCI=", g_pcu[i].cfg.bvc[0].bvci);
Harald Welte299aa482020-12-09 15:10:55 +0100933 connect(self:G_PCU[i], g_pcu[i].vc_BSSGP_BVC[0]:GLOBAL);
Harald Welte04358652021-01-17 13:48:13 +0100934 g_pcu_idx[i] := 0;
Harald Welte299aa482020-12-09 15:10:55 +0100935 }
936}
937
Harald Welte04358652021-01-17 13:48:13 +0100938/* (re)connect G_SGSN[sgsn_idx] to a specific PTP BVCI */
939private function f_global_ptp_connect_sgsn_bvci(integer sgsn_idx, BssgpBvci bvci) runs on GlobalTest_CT
940{
941 var integer sgsn_bvc_idx := get_bvc_idx_for_bvci(g_sgsn[sgsn_idx], bvci);
942 var integer old_sgsn_bvc_idx := g_sgsn_idx[sgsn_idx];
943 disconnect(self:G_SGSN[sgsn_idx], g_sgsn[sgsn_idx].vc_BSSGP_BVC[old_sgsn_bvc_idx]:GLOBAL);
944 connect(self:G_SGSN[sgsn_idx], g_sgsn[sgsn_idx].vc_BSSGP_BVC[sgsn_bvc_idx]:GLOBAL);
945 g_sgsn_idx[sgsn_idx] := sgsn_bvc_idx;
946}
947
948/* (re)connect G_PCU[pcu_idx] to a specific PTP BVCI */
949private function f_global_ptp_connect_pcu_bvci(integer pcu_idx, BssgpBvci bvci) runs on GlobalTest_CT
950{
951 var integer pcu_bvc_idx := get_bvc_idx_for_bvci(g_pcu[pcu_idx], bvci);
952 var integer old_pcu_bvc_idx := g_pcu_idx[pcu_idx];
953 disconnect(self:G_PCU[pcu_idx], g_pcu[pcu_idx].vc_BSSGP_BVC[old_pcu_bvc_idx]:GLOBAL);
954 connect(self:G_PCU[pcu_idx], g_pcu[pcu_idx].vc_BSSGP_BVC[pcu_bvc_idx]:GLOBAL);
955 g_pcu_idx[pcu_idx] := pcu_bvc_idx;
956}
957
Harald Welte3807ed12020-11-24 19:05:22 +0100958/* Send 'tx' on PTP-BVCI from PCU; expect 'rx' on SGSN */
959friend function f_global_pcu2sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
960 integer pcu_idx := 0, integer sgsn_idx := 0) runs on GlobalTest_CT {
Harald Welte04358652021-01-17 13:48:13 +0100961 var integer rx_idx;
Harald Welte3807ed12020-11-24 19:05:22 +0100962 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +0100963 timer T := 2.0;
Harald Welte3807ed12020-11-24 19:05:22 +0100964
965 G_PCU[pcu_idx].send(tx);
966 T.start;
967 alt {
968 [] G_SGSN[sgsn_idx].receive(exp_rx) {
969 setverdict(pass);
970 }
Harald Welte04358652021-01-17 13:48:13 +0100971 [] any from G_SGSN.receive(exp_rx) -> @index value rx_idx {
972 setverdict(fail, "BSSGP arrived on wrong SGSN[", rx_idx, "] instead of SGSN[", sgsn_idx, "]");
973 }
Harald Welte3807ed12020-11-24 19:05:22 +0100974 [] G_SGSN[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +0100975 f_shutdown(__FILE__, __LINE__, fail, log2str("Unexpected BSSGP on SGSN side: ", rx));
Harald Welte3807ed12020-11-24 19:05:22 +0100976 }
977 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +0100978 f_shutdown(__FILE__, __LINE__, fail, log2str("Timeout waiting for BSSGP on SGSN side: ", exp_rx));
Harald Welte3807ed12020-11-24 19:05:22 +0100979 }
980 }
981}
982
983/* Send 'tx' on PTP-BVCI from SGSN; expect 'rx' on PCU */
984friend function f_global_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
985 integer sgsn_idx := 0, integer pcu_idx := 0) runs on GlobalTest_CT {
Harald Welte04358652021-01-17 13:48:13 +0100986 var integer rx_idx;
Harald Welte3807ed12020-11-24 19:05:22 +0100987 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +0100988 timer T := 2.0;
Harald Welte3807ed12020-11-24 19:05:22 +0100989
990 G_SGSN[sgsn_idx].send(tx);
991 T.start;
992 alt {
993 [] G_PCU[pcu_idx].receive(exp_rx) {
994 setverdict(pass);
995 }
Harald Welte04358652021-01-17 13:48:13 +0100996 [] any from G_PCU.receive(exp_rx) -> @index value rx_idx {
997 setverdict(fail, "BSSGP arrived on wrong PCU[", rx_idx, "] instead of PCU[", pcu_idx, "]");
998 }
Harald Welte3807ed12020-11-24 19:05:22 +0100999 [] G_PCU[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +01001000 f_shutdown(__FILE__, __LINE__, fail, log2str("Unexpected BSSGP on PCU side: ", rx));
Harald Welte3807ed12020-11-24 19:05:22 +01001001 }
1002 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +01001003 f_shutdown(__FILE__, __LINE__, fail, log2str("Timeout waiting for BSSGP on PCU side: ", exp_rx));
Harald Welte3807ed12020-11-24 19:05:22 +01001004 }
1005 }
1006}
1007
1008
Daniel Willmann423d8f42020-09-08 18:58:22 +02001009/* TODO:
1010 * Detach without Attach
1011 * SM procedures without attach / RAU
1012 * ATTACH / RAU
1013 ** with / without authentication
1014 ** with / without P-TMSI allocation
1015 * re-transmissions of LLC frames
1016 * PDP Context activation
1017 ** with different GGSN config in SGSN VTY
1018 ** with different PDP context type (v4/v6/v46)
1019 ** timeout from GGSN
1020 ** multiple / secondary PDP context
1021 */
1022
1023private function f_TC_BVC_bringup(charstring id) runs on BSSGP_ConnHdlr {
1024 f_sleep(5.0);
1025 setverdict(pass);
1026}
1027
1028testcase TC_BVC_bringup() runs on test_CT {
Daniel Willmann423d8f42020-09-08 18:58:22 +02001029 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001030 f_start_handlers(refers(f_TC_BVC_bringup), testcasename(), 51);
Daniel Willmann423d8f42020-09-08 18:58:22 +02001031 f_cleanup();
1032}
1033
1034friend function f_bssgp_suspend(integer ran_idx := 0) runs on BSSGP_ConnHdlr return OCT1 {
Harald Welte16357a92020-11-17 18:20:00 +01001035 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Daniel Willmann423d8f42020-09-08 18:58:22 +02001036 timer T := 5.0;
1037 var PDU_BSSGP rx_pdu;
Harald Welte16357a92020-11-17 18:20:00 +01001038 PCU_SIG[ran_idx].send(ts_BSSGP_SUSPEND(g_pars.tlli, bvcc.cell_id.ra_id));
Daniel Willmann423d8f42020-09-08 18:58:22 +02001039 T.start;
1040 alt {
Harald Welte16357a92020-11-17 18:20:00 +01001041 [] 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 +02001042 return rx_pdu.pDU_BSSGP_SUSPEND_ACK.suspend_Reference_Number.suspend_Reference_Number_value;
1043 }
Harald Welte16357a92020-11-17 18:20:00 +01001044 [] 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 +01001045 f_shutdown(__FILE__, __LINE__, fail,
1046 log2str("SUSPEND-NACK in response to SUSPEND for TLLI ", g_pars.tlli));
Daniel Willmann423d8f42020-09-08 18:58:22 +02001047 }
1048 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +01001049 f_shutdown(__FILE__, __LINE__, fail,
1050 log2str("No SUSPEND-ACK in response to SUSPEND for TLLI ", g_pars.tlli));
Daniel Willmann423d8f42020-09-08 18:58:22 +02001051 }
1052 }
1053 return '00'O;
1054}
1055
1056friend function f_bssgp_resume(OCT1 susp_ref, integer ran_idx := 0) runs on BSSGP_ConnHdlr {
Harald Welte16357a92020-11-17 18:20:00 +01001057 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Daniel Willmann423d8f42020-09-08 18:58:22 +02001058 timer T := 5.0;
Harald Welte16357a92020-11-17 18:20:00 +01001059 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 +02001060 T.start;
1061 alt {
Harald Welte16357a92020-11-17 18:20:00 +01001062 [] PCU_SIG[ran_idx].receive(tr_BSSGP_RESUME_ACK(g_pars.tlli, bvcc.cell_id.ra_id));
1063 [] PCU_SIG[ran_idx].receive(tr_BSSGP_RESUME_NACK(g_pars.tlli, bvcc.cell_id.ra_id, ?)) {
Harald Welted5b7e742021-01-27 10:50:24 +01001064 f_shutdown(__FILE__, __LINE__, fail,
1065 log2str("RESUME-NACK in response to RESUME for TLLI ", g_pars.tlli));
Daniel Willmann423d8f42020-09-08 18:58:22 +02001066 }
1067 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +01001068 f_shutdown(__FILE__, __LINE__, fail,
1069 log2str("No RESUME-ACK in response to SUSPEND for TLLI ", g_pars.tlli));
Daniel Willmann423d8f42020-09-08 18:58:22 +02001070 }
1071 }
1072}
1073
1074
Harald Welte92686012020-11-15 21:45:49 +01001075/* send uplink-unitdata of a variety of different sizes; expect it to show up on SGSN */
1076private function f_TC_ul_unitdata(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte16357a92020-11-17 18:20:00 +01001077 var integer ran_idx := 0;
1078 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Harald Welte92686012020-11-15 21:45:49 +01001079 var integer i;
1080
Harald Welte0d5fceb2020-11-29 16:04:07 +01001081 for (i := 0; i < max_fr_info_size-4; i := i+4) {
Harald Welte92686012020-11-15 21:45:49 +01001082 var octetstring payload := f_rnd_octstring(i);
Harald Welte16357a92020-11-17 18:20:00 +01001083 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 +01001084 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte16357a92020-11-17 18:20:00 +01001085 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 +01001086
Harald Welte0d5fceb2020-11-29 16:04:07 +01001087 log("UL-UNITDATA(payload_size=", i);
Harald Welte22ef5d92020-11-16 13:35:14 +01001088 f_pcu2sgsn(pdu_tx, pdu_rx);
Harald Welte92686012020-11-15 21:45:49 +01001089 }
1090 setverdict(pass);
1091}
1092
1093testcase TC_ul_unitdata() runs on test_CT
1094{
Daniel Willmannc879f342021-02-11 14:28:01 +01001095 f_init(60.0);
Harald Welte2ecbca82021-01-16 11:23:09 +01001096 f_start_handlers(refers(f_TC_ul_unitdata), testcasename(), 1);
Harald Welte92686012020-11-15 21:45:49 +01001097 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Welte92686012020-11-15 21:45:49 +01001098 f_cleanup();
1099}
1100
Harald Welte78d8db92020-11-15 23:27:27 +01001101/* send downlink-unitdata of a variety of different sizes; expect it to show up on PCU */
1102private function f_TC_dl_unitdata(charstring id) runs on BSSGP_ConnHdlr {
1103 var integer i;
1104
Harald Welte0d5fceb2020-11-29 16:04:07 +01001105 for (i := 0; i < max_fr_info_size-4; i := i+4) {
Harald Welte78d8db92020-11-15 23:27:27 +01001106 var octetstring payload := f_rnd_octstring(i);
1107 var template (value) PDU_BSSGP pdu_tx :=
1108 ts_BSSGP_DL_UD(g_pars.tlli, payload, omit, ts_BSSGP_IMSI(g_pars.imsi));
1109 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1110 var template (present) PDU_BSSGP pdu_rx :=
Daniel Willmann325458d2021-02-11 14:22:42 +01001111 tr_BSSGP_DL_UD(g_pars.tlli, payload, tr_BSSGP_IMSI(g_pars.imsi));
Harald Welte78d8db92020-11-15 23:27:27 +01001112
Harald Welte0d5fceb2020-11-29 16:04:07 +01001113 log("DL-UNITDATA(payload_size=", i);
Harald Welte22ef5d92020-11-16 13:35:14 +01001114 f_sgsn2pcu(pdu_tx, pdu_rx);
Harald Welte78d8db92020-11-15 23:27:27 +01001115 }
1116 setverdict(pass);
1117}
1118
1119testcase TC_dl_unitdata() runs on test_CT
1120{
Daniel Willmannc879f342021-02-11 14:28:01 +01001121 f_init(60.0);
Harald Welte2ecbca82021-01-16 11:23:09 +01001122 f_start_handlers(refers(f_TC_dl_unitdata), testcasename(), 2);
Harald Welte78d8db92020-11-15 23:27:27 +01001123 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Welte78d8db92020-11-15 23:27:27 +01001124 f_cleanup();
1125}
Harald Welte92686012020-11-15 21:45:49 +01001126
Harald Welte6dc2ac42020-11-16 09:16:17 +01001127private function f_TC_ra_capability(charstring id) runs on BSSGP_ConnHdlr {
1128 var integer i;
1129
1130 for (i := 0; i < 10; i := i+1) {
1131 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RA_CAP(g_pars.tlli, { ts_RaCapRec_BSSGP });
1132 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1133 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RA_CAP(g_pars.tlli, { tr_RaCapRec_BSSGP })
1134
Harald Welte22ef5d92020-11-16 13:35:14 +01001135 f_sgsn2pcu(pdu_tx, pdu_rx);
Harald Welte6dc2ac42020-11-16 09:16:17 +01001136 }
1137 setverdict(pass);
1138}
1139testcase TC_ra_capability() runs on test_CT
1140{
Harald Welte6dc2ac42020-11-16 09:16:17 +01001141 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001142 f_start_handlers(refers(f_TC_ra_capability), testcasename(), 3);
Harald Welte6dc2ac42020-11-16 09:16:17 +01001143 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Welte6dc2ac42020-11-16 09:16:17 +01001144 f_cleanup();
1145}
1146
Daniel Willmannace3ece2020-11-16 19:53:26 +01001147private function f_TC_ra_capability_upd(charstring id) runs on BSSGP_ConnHdlr {
1148 var integer i;
1149 var OCT1 tag;
1150 for (i := 0; i < 10; i := i+1) {
1151 tag := int2oct(23 + i, 1);
1152 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RA_CAP_UPD(g_pars.tlli, tag);
1153 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1154 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RA_CAP_UPD(g_pars.tlli, tag)
1155
1156 f_pcu2sgsn(pdu_tx, pdu_rx);
1157
1158 pdu_tx := ts_BSSGP_RA_CAP_UPD_ACK(g_pars.tlli, tag, '42'O);
1159 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1160 pdu_rx := tr_BSSGP_RA_CAP_UPD_ACK(g_pars.tlli, tag, '42'O)
1161
1162 f_sgsn2pcu(pdu_tx, pdu_rx);
1163 }
1164 setverdict(pass);
1165}
1166testcase TC_ra_capability_upd() runs on test_CT
1167{
Daniel Willmannace3ece2020-11-16 19:53:26 +01001168 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001169 f_start_handlers(refers(f_TC_ra_capability_upd), testcasename(), 4);
Daniel Willmannace3ece2020-11-16 19:53:26 +01001170 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Daniel Willmannace3ece2020-11-16 19:53:26 +01001171 f_cleanup();
1172}
1173
Daniel Willmann165d6612020-11-19 14:27:29 +01001174private function f_TC_radio_status(charstring id) runs on BSSGP_ConnHdlr {
1175 var integer i;
1176 var BssgpRadioCause cause := BSSGP_RADIO_CAUSE_CONTACT_LOST;
1177 for (i := 0; i < 10; i := i+1) {
1178 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RADIO_STATUS(g_pars.tlli, cause);
1179 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1180 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RADIO_STATUS(g_pars.tlli, cause)
1181
1182 f_pcu2sgsn(pdu_tx, pdu_rx);
1183 }
1184 setverdict(pass);
1185}
1186testcase TC_radio_status() runs on test_CT
1187{
Daniel Willmann165d6612020-11-19 14:27:29 +01001188 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001189 f_start_handlers(refers(f_TC_radio_status), testcasename(), 5);
Daniel Willmann165d6612020-11-19 14:27:29 +01001190 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Daniel Willmann165d6612020-11-19 14:27:29 +01001191 f_cleanup();
1192}
1193
Harald Welte3148a962021-01-17 11:15:28 +01001194private function f_TC_radio_status_tmsi(charstring id) runs on BSSGP_ConnHdlr {
1195 var integer i;
1196 var BssgpRadioCause cause := BSSGP_RADIO_CAUSE_CONTACT_LOST;
1197 for (i := 0; i < 10; i := i+1) {
1198 var integer tmsi_int := oct2int(g_pars.p_tmsi);
1199 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RADIO_STATUS(omit, cause, tmsi_int);
1200 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1201 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RADIO_STATUS(omit, cause, tmsi_int);
1202 f_pcu2sgsn(pdu_tx, pdu_rx);
1203 }
1204 setverdict(pass);
1205}
1206testcase TC_radio_status_tmsi() runs on test_CT
1207{
1208 f_init();
1209 f_start_handlers(refers(f_TC_radio_status_tmsi), testcasename(), 5);
1210 f_cleanup();
1211}
1212
1213private function f_TC_radio_status_imsi(charstring id) runs on BSSGP_ConnHdlr {
1214 var integer i;
1215 var BssgpRadioCause cause := BSSGP_RADIO_CAUSE_CONTACT_LOST;
1216 for (i := 0; i < 10; i := i+1) {
1217 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RADIO_STATUS(omit, cause, imsi := g_pars.imsi);
1218 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1219 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RADIO_STATUS(omit, cause, imsi := g_pars.imsi);
1220 f_pcu2any_sgsn(pdu_tx, pdu_rx);
1221 }
1222 setverdict(pass);
1223}
1224testcase TC_radio_status_imsi() runs on test_CT
1225{
1226 f_init();
1227 f_start_handlers(refers(f_TC_radio_status_imsi), testcasename(), 5);
1228 f_cleanup();
1229}
1230
1231
1232
Harald Welte99ed5072021-01-15 20:38:58 +01001233private function f_suspend_one(integer sgsn_idx, integer nri_idx, integer pcu_idx, integer bvc_idx,
1234 integer suffix)
Harald Welte00963752021-01-15 20:33:11 +01001235runs on GlobalTest_CT
1236{
1237 var RoutingAreaIdentification ra_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id.ra_id;
Harald Welte99ed5072021-01-15 20:38:58 +01001238 var OCT4 p_tmsi := f_gen_tmsi(suffix, nri_v := mp_sgsn_nri[sgsn_idx][nri_idx],
1239 nri_bitlen := mp_nri_bitlength);
1240 var OCT4 tlli := f_gprs_tlli_from_tmsi(p_tmsi, TLLI_LOCAL);
Harald Welte00963752021-01-15 20:33:11 +01001241 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_SUSPEND(tlli, ra_id);
1242 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1243 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_SUSPEND(tlli, ra_id);
1244 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1245
1246 pdu_tx := ts_BSSGP_SUSPEND_ACK(tlli, ra_id, int2oct(suffix, 1));
1247 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1248 pdu_rx := tr_BSSGP_SUSPEND_ACK(tlli, ra_id, int2oct(suffix, 1));
1249 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1250
1251 pdu_tx := ts_BSSGP_SUSPEND(tlli, ra_id);
1252 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1253 pdu_rx := tr_BSSGP_SUSPEND(tlli, ra_id);
1254 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1255
1256 /* These messages are simple passed through so just also test sending NACK */
1257 pdu_tx := ts_BSSGP_SUSPEND_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1258 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1259 pdu_rx := tr_BSSGP_SUSPEND_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1260 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1261}
1262
Harald Weltec5c33732021-01-15 21:04:35 +01001263private function f_TC_suspend(integer sgsn_idx, integer nri_idx, integer pcu_idx, integer bvc_idx)
1264runs on GlobalTest_CT {
Daniel Willmannfa67f492020-11-19 15:48:05 +01001265 var integer i;
Daniel Willmann165d6612020-11-19 14:27:29 +01001266
Daniel Willmannfa67f492020-11-19 15:48:05 +01001267 for (i := 0; i < 10; i := i+1) {
Harald Weltec5c33732021-01-15 21:04:35 +01001268 f_suspend_one(sgsn_idx, nri_idx, pcu_idx, bvc_idx, suffix := i);
Daniel Willmannfa67f492020-11-19 15:48:05 +01001269 }
1270 setverdict(pass);
1271}
Harald Welte3807ed12020-11-24 19:05:22 +01001272testcase TC_suspend() runs on GlobalTest_CT
Daniel Willmannfa67f492020-11-19 15:48:05 +01001273{
Harald Weltec5c33732021-01-15 21:04:35 +01001274 var integer sgsn_idx, nri_idx;
Daniel Willmannfa67f492020-11-19 15:48:05 +01001275 f_init();
Harald Welte3807ed12020-11-24 19:05:22 +01001276 f_global_init();
Harald Weltec5c33732021-01-15 21:04:35 +01001277 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx+1) {
1278 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx+1) {
1279 f_TC_suspend(sgsn_idx, nri_idx, pcu_idx:=0, bvc_idx:=0);
1280 }
1281 }
Daniel Willmannfa67f492020-11-19 15:48:05 +01001282 f_cleanup();
1283}
Harald Welte6dc2ac42020-11-16 09:16:17 +01001284
Harald Welte99ed5072021-01-15 20:38:58 +01001285private function f_resume_one(integer sgsn_idx, integer nri_idx, integer pcu_idx, integer bvc_idx,
1286 integer suffix)
Harald Welte00963752021-01-15 20:33:11 +01001287runs on GlobalTest_CT
1288{
1289 var RoutingAreaIdentification ra_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id.ra_id;
Harald Welte99ed5072021-01-15 20:38:58 +01001290 var OCT4 p_tmsi := f_gen_tmsi(suffix, nri_v := mp_sgsn_nri[sgsn_idx][nri_idx],
1291 nri_bitlen := mp_nri_bitlength);
1292 var OCT4 tlli := f_gprs_tlli_from_tmsi(p_tmsi, TLLI_LOCAL);
Harald Welte00963752021-01-15 20:33:11 +01001293 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1294 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1295 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1296 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1297
1298 pdu_tx := ts_BSSGP_RESUME_ACK(tlli, ra_id);
1299 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1300 pdu_rx := tr_BSSGP_RESUME_ACK(tlli, ra_id);
1301 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1302
1303 pdu_tx := ts_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1304 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1305 pdu_rx := tr_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1306 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1307
1308 /* These messages are simple passed through so just also test sending NACK */
1309 pdu_tx := ts_BSSGP_RESUME_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1310 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1311 pdu_rx := tr_BSSGP_RESUME_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1312 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1313}
1314
Harald Weltec5c33732021-01-15 21:04:35 +01001315private function f_TC_resume(integer sgsn_idx, integer nri_idx, integer pcu_idx, integer bvc_idx)
1316runs on GlobalTest_CT {
Daniel Willmann087a33d2020-11-19 15:58:43 +01001317 var integer i;
1318
Daniel Willmann087a33d2020-11-19 15:58:43 +01001319 for (i := 0; i < 10; i := i+1) {
Harald Weltec5c33732021-01-15 21:04:35 +01001320 f_resume_one(sgsn_idx, nri_idx, pcu_idx, bvc_idx, suffix := i);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001321 }
1322 setverdict(pass);
1323}
Harald Welte3807ed12020-11-24 19:05:22 +01001324testcase TC_resume() runs on GlobalTest_CT
Daniel Willmann087a33d2020-11-19 15:58:43 +01001325{
Harald Weltec5c33732021-01-15 21:04:35 +01001326 var integer sgsn_idx, nri_idx;
Daniel Willmann087a33d2020-11-19 15:58:43 +01001327 f_init();
Harald Welte3807ed12020-11-24 19:05:22 +01001328 f_global_init();
Harald Weltec5c33732021-01-15 21:04:35 +01001329 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx+1) {
1330 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx+1) {
1331 f_TC_resume(sgsn_idx, nri_idx, pcu_idx:=0, bvc_idx:=0);
1332 }
1333 }
Daniel Willmann087a33d2020-11-19 15:58:43 +01001334 f_cleanup();
1335}
1336
Harald Weltef8ef0282020-11-18 12:16:59 +01001337/* test the load-sharing between multiple NS-VC on the BSS side */
1338private function f_TC_dl_ud_unidir(charstring id) runs on BSSGP_ConnHdlr {
1339 var integer i;
1340
1341 for (i := 0; i < 10; i := i+1) {
1342 var octetstring payload := f_rnd_octstring(i);
1343 var template (value) PDU_BSSGP pdu_tx :=
1344 ts_BSSGP_DL_UD(g_pars.tlli, payload, omit, ts_BSSGP_IMSI(g_pars.imsi));
Harald Welte09a1ce42021-01-16 11:18:38 +01001345 SGSN_PTP[g_pars.sgsn_idx].send(pdu_tx);
Harald Weltef8ef0282020-11-18 12:16:59 +01001346 }
1347 setverdict(pass);
1348}
Harald Welte09a1ce42021-01-16 11:18:38 +01001349
1350private function f_TC_load_sharing_dl(integer sgsn_idx) runs on test_CT_NS
Harald Weltef8ef0282020-11-18 12:16:59 +01001351{
1352 const integer num_ue := 10;
1353 var BSSGP_ConnHdlr vc_conn[num_ue];
Harald Weltef8ef0282020-11-18 12:16:59 +01001354 /* all BVC are now fully brought up. We disconnect BSSGP from NS on the BSS
1355 * side so we get the raw NsUnitdataIndication and hence observe different
1356 * NSVCI */
1357 disconnect(g_pcu[0].vc_NS:NS_SP, g_pcu[0].vc_BSSGP:BSCP);
1358 connect(g_pcu[0].vc_NS:NS_SP, self:NS);
1359
1360 /* there may still be some NS-VCs coming up? After all, the BVC-RESET succeeds after the first
1361 * of the NS-VC is ALIVE/UNBLOCKED */
1362 f_sleep(3.0);
1363
1364 /* start parallel components generating DL-UNITDATA from the SGSN side */
1365 for (var integer i:= 0; i < num_ue; i := i+1) {
Harald Welte2ecbca82021-01-16 11:23:09 +01001366 vc_conn[i] := f_start_handler(refers(f_TC_dl_ud_unidir), testcasename(),
Harald Welte09a1ce42021-01-16 11:18:38 +01001367 5+i, 30.0, sgsn_idx);
Harald Weltef8ef0282020-11-18 12:16:59 +01001368 }
1369
1370 /* now start counting all the messages that were queued before */
1371 /* TODO: We have a hard-coded assumption of 4 NS-VC in one NSE/NS-VCG here! */
1372 var ro_integer rx_count := { 0, 0, 0, 0 };
1373 timer T := 2.0;
1374 T.start;
1375 alt {
1376 [] as_NsUdiCount(0, rx_count);
1377 [] as_NsUdiCount(1, rx_count);
1378 [] as_NsUdiCount(2, rx_count);
1379 [] as_NsUdiCount(3, rx_count);
1380 [] NS.receive(NsUnitdataIndication:{0,?,?,*,*}) { repeat; } /* signaling BVC */
1381 [] NS.receive(NsStatusIndication:?) { repeat; }
1382 [] NS.receive {
Harald Welted5b7e742021-01-27 10:50:24 +01001383 f_shutdown(__FILE__, __LINE__, fail, "Rx unexpected NS");
Harald Weltef8ef0282020-11-18 12:16:59 +01001384 }
1385 [] T.timeout {
1386 }
1387 }
1388 for (var integer i := 0; i < lengthof(rx_count); i := i+1) {
1389 log("Rx on NSVCI ", mp_nsconfig_pcu[0].nsvc[i].nsvci, ": ", rx_count[i]);
1390 if (rx_count[i] == 0) {
1391 setverdict(fail, "Data not shared over all NSVC");
1392 }
1393 }
Harald Welte09a1ce42021-01-16 11:18:38 +01001394}
1395
1396testcase TC_load_sharing_dl() runs on test_CT_NS
1397{
1398 var integer sgsn_idx, nri_idx;
1399 f_init();
1400 for (sgsn_idx:=0; sgsn_idx < NUM_SGSN; sgsn_idx:=sgsn_idx+1) {
1401 f_TC_load_sharing_dl(sgsn_idx);
1402 }
Harald Weltef8ef0282020-11-18 12:16:59 +01001403 setverdict(pass);
1404}
1405private altstep as_NsUdiCount(integer nsvc_idx, inout ro_integer roi) runs on test_CT_NS {
1406 var NsUnitdataIndication udi;
1407 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[0];
1408 [] NS.receive(NsUnitdataIndication:{bvcc.bvci, g_pcu[0].cfg.nsei, mp_nsconfig_pcu[0].nsvc[nsvc_idx].nsvci, *, *}) -> value udi {
1409 roi[nsvc_idx] := roi[nsvc_idx] + 1;
1410 repeat;
1411 }
1412}
1413type component test_CT_NS extends test_CT {
1414 port NS_PT NS;
1415};
1416
1417
Harald Welte0e188242020-11-22 21:46:48 +01001418/***********************************************************************
1419 * PAGING PS procedure
1420 ***********************************************************************/
1421
1422private function f_send_paging_ps(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1423 boolean use_sig := false)
1424runs on BSSGP_ConnHdlr return template (present) PDU_BSSGP {
1425 var template (value) PDU_BSSGP pdu_tx;
1426 var template (present) PDU_BSSGP pdu_rx;
1427 /* we always specify '0' as BVCI in the templates below, as we override it with
1428 * 'p4' later anyway */
1429 pdu_rx := tr_BSSGP_PS_PAGING(0);
1430 pdu_rx.pDU_BSSGP_PAGING_PS.iMSI := tr_BSSGP_IMSI(g_pars.imsi);
1431 if (ispresent(g_pars.p_tmsi)) {
1432 pdu_tx := ts_BSSGP_PS_PAGING_PTMSI(0, g_pars.imsi, oct2int(g_pars.p_tmsi));
1433 pdu_rx.pDU_BSSGP_PAGING_PS.pTMSI := tr_BSSGP_TMSI(oct2int(g_pars.p_tmsi));
1434 } else {
1435 pdu_tx := ts_BSSGP_PS_PAGING_IMSI(0, g_pars.imsi);
1436 pdu_rx.pDU_BSSGP_PAGING_PS.pTMSI := omit;
1437 }
1438 pdu_tx.pDU_BSSGP_PAGING_PS.paging_Field4 := p4;
1439 pdu_rx.pDU_BSSGP_PAGING_PS.paging_Field4 := p4;
1440 if (use_sig == false) {
Harald Welte158becf2020-12-09 12:32:32 +01001441 SGSN_PTP[sgsn_idx].send(pdu_tx);
Harald Welte0e188242020-11-22 21:46:48 +01001442 } else {
1443 SGSN_SIG[sgsn_idx].send(pdu_tx);
1444 }
1445 return pdu_rx;
1446}
1447
1448/* send paging defined by 'p4' on given SGSN-side index (ptp or signaling) and expect one paging to arrive on
1449 * specified PCU index */
1450private function f_send_paging_ps_exp_one_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1451 boolean use_sig := false,integer pcu_idx := 0)
1452runs on BSSGP_ConnHdlr {
1453 var template (present) PDU_BSSGP exp_rx;
Daniel Willmann1a859712020-12-04 00:59:45 +01001454 var boolean test_done := false;
Harald Welte0e188242020-11-22 21:46:48 +01001455 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1456 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1457 exp_rx := f_send_paging_ps(p4, sgsn_idx, use_sig);
1458 /* Expect paging to propagate to the one BSS addressed by the BVCI only */
1459 timer T := 2.0;
1460 T.start;
1461 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001462 [not use_sig and not test_done] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001463 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001464 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001465 repeat;
1466 }
1467 [not use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
1468 setverdict(fail, "Received paging on SIGNALING BVC, expected PTP BVC");
1469 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001470 [use_sig and not test_done] PCU_SIG[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001471 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001472 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001473 repeat;
1474 }
Harald Welte158becf2020-12-09 12:32:32 +01001475 [use_sig] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001476 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1477 }
Harald Welte158becf2020-12-09 12:32:32 +01001478 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001479 setverdict(fail, "Paging received on unexpected BVC");
1480 }
1481 [] any from PCU_SIG.receive(exp_rx) {
1482 setverdict(fail, "Paging received on unexpected BVC");
1483 }
Harald Welte158becf2020-12-09 12:32:32 +01001484 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01001485 setverdict(fail, "Different Paging than expected received PTP BVC");
1486 }
1487 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1488 setverdict(fail, "Different Paging than expected on SIGNALING BVC");
1489 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001490 [not test_done] T.timeout {
1491 setverdict(fail, "Timeout waiting for paging");
1492 }
1493 [test_done] T.timeout;
Harald Welte0e188242020-11-22 21:46:48 +01001494 }
1495}
1496
Harald Welte7462a592020-11-23 22:07:07 +01001497/* send a PS-PAGING but don't expect it to show up on any PTP or SIG BVC */
1498private function f_send_paging_ps_exp_no_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1499 boolean use_sig := false)
1500runs on BSSGP_ConnHdlr {
1501 var template (present) PDU_BSSGP exp_rx;
1502 exp_rx := f_send_paging_ps(p4, sgsn_idx, use_sig);
1503 /* Expect paging to propagate to no BSS */
1504 timer T := 2.0;
1505 T.start;
1506 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001507 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte7462a592020-11-23 22:07:07 +01001508 setverdict(fail, "Paging received on unexpected BVC");
1509 }
1510 [] any from PCU_SIG.receive(exp_rx) {
1511 setverdict(fail, "Paging received on unexpected BVC");
1512 }
Harald Welte158becf2020-12-09 12:32:32 +01001513 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte7462a592020-11-23 22:07:07 +01001514 setverdict(fail, "Different Paging received on PTP BVC");
1515 }
1516 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1517 setverdict(fail, "Different Paging received on SIGNALING BVC");
1518 }
1519 [] T.timeout {
1520 setverdict(pass);
1521 }
1522 }
1523}
1524
Harald Welte0e188242020-11-22 21:46:48 +01001525private function f_TC_paging_ps_ptp_bss(charstring id) runs on BSSGP_ConnHdlr
1526{
1527 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1528 * at that BVC (cell) only, and paging all over the BSS area is not possible */
Daniel Willmann2a330672021-01-18 18:50:02 +01001529 f_send_paging_ps_exp_one_bss(ts_BssgpP4BssArea, g_pars.sgsn_idx, false, 0);
Harald Welte0e188242020-11-22 21:46:48 +01001530}
1531testcase TC_paging_ps_ptp_bss() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001532 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001533 f_start_handlers(refers(f_TC_paging_ps_ptp_bss), testcasename(), 9);
Harald Welte0e188242020-11-22 21:46:48 +01001534 f_cleanup();
1535}
1536
1537/* PS-PAGING on PTP-BVC for Location Area */
1538private function f_TC_paging_ps_ptp_lac(charstring id) runs on BSSGP_ConnHdlr
1539{
1540 var template (present) PDU_BSSGP exp_rx;
1541 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1542 * at that BVC (cell) only, and paging all over the BSS area is not possible */
Daniel Willmann2a330672021-01-18 18:50:02 +01001543 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 +01001544}
1545testcase TC_paging_ps_ptp_lac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001546 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001547 f_start_handlers(refers(f_TC_paging_ps_ptp_lac), testcasename(), 10);
Harald Welte0e188242020-11-22 21:46:48 +01001548 f_cleanup();
1549}
1550
Harald Welte7462a592020-11-23 22:07:07 +01001551/* PS-PAGING on PTP-BVC for unknown Location Area */
1552private function f_TC_paging_ps_ptp_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1553{
1554 var GSM_Types.LocationAreaIdentification unknown_la := {
1555 mcc_mnc := '567F99'H,
1556 lac := 33333
1557 };
1558 /* as it's sent on the PTP BVC, we expect it to pass even for unknown LAC */
Daniel Willmann2a330672021-01-18 18:50:02 +01001559 f_send_paging_ps_exp_one_bss(ts_BssgpP4LAC(unknown_la), g_pars.sgsn_idx, false, 0);
Harald Welte7462a592020-11-23 22:07:07 +01001560}
1561testcase TC_paging_ps_ptp_lac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001562 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001563 f_start_handlers(refers(f_TC_paging_ps_ptp_lac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001564 f_cleanup();
1565}
1566
Harald Welte0e188242020-11-22 21:46:48 +01001567/* PS-PAGING on PTP-BVC for Routeing Area */
1568private function f_TC_paging_ps_ptp_rac(charstring id) runs on BSSGP_ConnHdlr
1569{
1570 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1571 * at that BVC (cell) only, and paging all over the BSS area is not possible */
Daniel Willmann2a330672021-01-18 18:50:02 +01001572 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 +01001573}
1574testcase TC_paging_ps_ptp_rac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001575 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001576 f_start_handlers(refers(f_TC_paging_ps_ptp_rac), testcasename(), 11);
Harald Welte0e188242020-11-22 21:46:48 +01001577 f_cleanup();
1578}
1579
Harald Welte7462a592020-11-23 22:07:07 +01001580/* PS-PAGING on PTP-BVC for unknown Routeing Area */
1581private function f_TC_paging_ps_ptp_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1582{
1583 var RoutingAreaIdentification unknown_ra := {
1584 lai := {
1585 mcc_mnc := '567F99'H,
1586 lac := 33333
1587 },
1588 rac := 254
1589 };
1590 /* as it's sent on the PTP BVC, we expect it to pass even for unknown RAC */
Daniel Willmann2a330672021-01-18 18:50:02 +01001591 f_send_paging_ps_exp_one_bss(ts_BssgpP4RAC(unknown_ra), g_pars.sgsn_idx, false, 0);
Harald Welte7462a592020-11-23 22:07:07 +01001592}
1593testcase TC_paging_ps_ptp_rac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001594 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001595 f_start_handlers(refers(f_TC_paging_ps_ptp_rac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001596 f_cleanup();
1597}
1598
Harald Welte0e188242020-11-22 21:46:48 +01001599/* PS-PAGING on PTP-BVC for BVCI (one cell) */
1600private function f_TC_paging_ps_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
1601{
1602 /* this should be the normal case for MS in READY MM state after a lower layer failure */
Daniel Willmann2a330672021-01-18 18:50:02 +01001603 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 +01001604}
1605testcase TC_paging_ps_ptp_bvci() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001606 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001607 f_start_handlers(refers(f_TC_paging_ps_ptp_bvci), testcasename(), 12);
Harald Welte0e188242020-11-22 21:46:48 +01001608 f_cleanup();
1609}
1610
Harald Welteb5a04aa2021-01-16 13:04:40 +01001611
1612/* PS-PAGING on PTP-BVC for BVCI (one cell) using IMSI only (no P-TMSI allocated) */
1613testcase TC_paging_ps_ptp_bvci_imsi() runs on test_CT {
1614 f_init();
1615 f_start_handlers(refers(f_TC_paging_ps_ptp_bvci), testcasename(), 12, have_ptmsi:=false);
1616 f_cleanup();
1617}
1618
Harald Weltecf200072021-01-16 15:20:46 +01001619/* Rejected PS-PAGING on PTP-BVC for BVCI (one cell) */
1620testcase TC_paging_ps_reject_ptp_bvci() runs on test_CT {
1621 f_init();
1622 f_start_handlers(refers(f_TC_paging_ps_reject_ptp_bvci), testcasename(), 16);
1623 f_cleanup();
1624}
1625
1626/* Rejected PS-PAGING on PTP-BVC for BVCI (one cell) using IMSI only (no P-TMSI allocated) */
1627private function f_TC_paging_ps_reject_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
1628{
1629 /* first send the PS-PAGING from SGSN -> PCU */
Daniel Willmann2a330672021-01-18 18:50:02 +01001630 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 +01001631 /* then simulate the PS-PAGING-REJECT from the PCU */
1632 f_send_paging_ps_rej(use_sig:=false);
1633}
1634testcase TC_paging_ps_reject_ptp_bvci_imsi() runs on test_CT {
1635 f_init();
1636 f_start_handlers(refers(f_TC_paging_ps_reject_ptp_bvci), testcasename(), 16, have_ptmsi:=false);
1637 f_cleanup();
1638}
Harald Welteb5a04aa2021-01-16 13:04:40 +01001639
Harald Welte7462a592020-11-23 22:07:07 +01001640/* PS-PAGING on PTP-BVC for unknown BVCI */
1641private function f_TC_paging_ps_ptp_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1642{
1643 /* as it's sent on the PTP BVC, we expect it to pass even for unknown BVCI */
Daniel Willmann2a330672021-01-18 18:50:02 +01001644 f_send_paging_ps_exp_one_bss(ts_BssgpP4Bvci(33333), g_pars.sgsn_idx, false, 0);
Harald Welte7462a592020-11-23 22:07:07 +01001645}
1646testcase TC_paging_ps_ptp_bvci_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001647 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001648 f_start_handlers(refers(f_TC_paging_ps_ptp_bvci_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001649 f_cleanup();
1650}
1651
Harald Welte7595d562021-01-16 19:09:20 +01001652/* DUMMY PAGING PS on PTP BVC */
1653private function f_TC_dummy_paging_ps_ptp(charstring id) runs on BSSGP_ConnHdlr
1654{
1655 f_sgsn2pcu(ts_BSSGP_DUMMY_PAGING_PS(g_pars.imsi, omit),
1656 tr_BSSGP_DUMMY_PAGING_PS(g_pars.imsi, omit), use_sig := false);
1657 f_pcu2sgsn(ts_BSSGP_DUMMY_PAGING_PS_RESP(g_pars.imsi, 1, 5),
1658 tr_BSSGP_DUMMY_PAGING_PS_RESP(g_pars.imsi, 1, 5), use_sig := false)
1659}
1660testcase TC_dummy_paging_ps_ptp() runs on test_CT {
1661 f_init();
1662 f_start_handlers(refers(f_TC_dummy_paging_ps_ptp), testcasename(), 11);
1663 f_cleanup();
1664}
1665
Harald Welte0e188242020-11-22 21:46:48 +01001666/* altstep for expecting BSSGP PDU on signaling BVC of given pcu_idx + storing in 'roi' */
1667private altstep as_paging_sig_pcu(integer pcu_idx, template (present) PDU_BSSGP exp_rx, inout ro_integer roi)
1668runs on BSSGP_ConnHdlr {
1669[] PCU_SIG[pcu_idx].receive(exp_rx) {
1670 if (ro_integer_contains(roi, pcu_idx)) {
1671 setverdict(fail, "Received multiple paging on same SIG BVC");
1672 }
1673 roi := roi & { pcu_idx };
1674 repeat;
1675 }
Harald Welte158becf2020-12-09 12:32:32 +01001676[] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001677 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1678 }
1679[] PCU_SIG[pcu_idx].receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1680 setverdict(fail, "Different Paging than expected received SIGNALING BVC");
1681 }
Harald Welte158becf2020-12-09 12:32:32 +01001682[] PCU_PTP[pcu_idx].receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01001683 setverdict(fail, "Different Paging than expected received PTP BVC");
1684 }
1685}
1686
1687type record of default ro_default;
1688
1689/* send PS-PAGING on SIG BVC, expect it to arrive on given list of PCU indexes */
1690private function f_send_paging_ps_exp_multi(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1691 ro_integer exp_on_pcu_idx) runs on BSSGP_ConnHdlr
1692{
1693 var template (present) PDU_BSSGP exp_rx;
Daniel Willmann193e1a02021-01-17 12:55:53 +01001694 exp_rx := f_send_paging_ps(p4, sgsn_idx, true);
Harald Welte0e188242020-11-22 21:46:48 +01001695
1696 /* FIXME: make sure the relevant BVCs/BSS are connected to the ports! */
1697 var ro_default defaults := {};
1698 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1699 var default d := activate(as_paging_sig_pcu(i, exp_rx, g_roi));
1700 defaults := defaults & { d };
1701 }
1702 f_sleep(2.0);
1703 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
1704 deactivate(defaults[i]);
1705 }
1706 log("Paging received on PCU ", g_roi);
1707
1708 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1709 var boolean rx_on_i := ro_integer_contains(g_roi, i);
1710 var boolean exp_on_i := ro_integer_contains(exp_on_pcu_idx, i);
1711 if (exp_on_i and not rx_on_i) {
1712 setverdict(fail, "PS-PAGING not received on ", mp_nsconfig_pcu[i].nsei);
1713 }
1714 if (not exp_on_i and rx_on_i) {
1715 setverdict(fail, "PS-PAGING not expected but received on ", mp_nsconfig_pcu[i].nsei);
1716 }
1717 }
1718 setverdict(pass);
1719}
1720
Harald Weltecf200072021-01-16 15:20:46 +01001721/* Send PAGING-PS-REJECT on SIG BVC, expect it to arrive on the "right" SGSN */
1722private function f_send_paging_ps_rej(boolean use_sig := true, integer pcu_idx := 0) runs on BSSGP_ConnHdlr
1723{
1724 var template (value) PDU_BSSGP pdu_tx;
1725 var template (present) PDU_BSSGP exp_rx;
1726 var PDU_BSSGP pdu_rx;
1727 timer T := 5.0;
1728 var template (omit) GsmTmsi tmsi_int := omit;
1729
1730 if (ispresent(g_pars.p_tmsi)) {
1731 tmsi_int := oct2int(g_pars.p_tmsi);
1732 }
1733
1734 pdu_tx := ts_BSSGP_PAGING_PS_REJ(g_pars.imsi, 23, 42, tmsi_int);
1735 exp_rx := tr_BSSGP_PAGING_PS_REJ(g_pars.imsi, 23, 42, tmsi_int);
1736
1737 if (use_sig) {
1738 PCU_SIG[pcu_idx].send(pdu_tx);
1739 } else {
1740 PCU_PTP[pcu_idx].send(pdu_tx);
1741 }
1742 T.start;
1743 alt {
1744 [use_sig] SGSN_SIG[g_pars.sgsn_idx].receive(exp_rx) -> value pdu_rx {
1745 setverdict(pass);
1746 }
1747 [use_sig] SGSN_SIG[g_pars.sgsn_idx].receive {
1748 setverdict(fail, "Unexpected PDU on SGSN");
1749 }
1750 [use_sig] any from SGSN_SIG.receive(exp_rx) -> value pdu_rx {
1751 setverdict(fail, "PAGING-PS-REJECT arrived on wrong SGSN");
1752 }
1753 [not use_sig] SGSN_PTP[g_pars.sgsn_idx].receive(exp_rx) -> value pdu_rx {
1754 setverdict(pass);
1755 }
1756 [not use_sig] SGSN_PTP[g_pars.sgsn_idx].receive {
1757 setverdict(fail, "Unexpected PDU on SGSN");
1758 }
1759 [not use_sig] any from SGSN_PTP.receive(exp_rx) -> value pdu_rx {
1760 setverdict(fail, "PAGING-PS-REJECT arrived on wrong SGSN");
1761 }
1762 [] T.timeout {
1763 setverdict(fail, "Timeout waiting for PAGING-PS-REJECT");
1764 }
1765 }
1766}
1767
Harald Welte0e188242020-11-22 21:46:48 +01001768/* PS-PAGING on SIG-BVC for BSS Area */
1769private function f_TC_paging_ps_sig_bss(charstring id) runs on BSSGP_ConnHdlr
1770{
1771 /* we expect the paging to arrive on all three NSE */
Daniel Willmann43320442021-01-17 14:07:05 +01001772 f_send_paging_ps_exp_multi(ts_BssgpP4BssArea, g_pars.sgsn_idx, {0, 1, 2});
Harald Welte0e188242020-11-22 21:46:48 +01001773}
1774testcase TC_paging_ps_sig_bss() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001775 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001776 f_start_handlers(refers(f_TC_paging_ps_sig_bss), testcasename(), 13);
Harald Welte0e188242020-11-22 21:46:48 +01001777 f_cleanup();
1778}
1779
1780/* PS-PAGING on SIG-BVC for Location Area */
1781private function f_TC_paging_ps_sig_lac(charstring id) runs on BSSGP_ConnHdlr
1782{
Daniel Willmann2c9300f2020-12-01 10:54:08 +01001783 /* The first LAC (13135) is shared by all three NSEs */
Daniel Willmann43320442021-01-17 14:07:05 +01001784 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 +01001785 /* Reset state */
1786 g_roi := {};
1787 /* Make LAC (13300) available on pcu index 2 */
1788 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
Daniel Willmann43320442021-01-17 14:07:05 +01001789 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 +01001790}
1791testcase TC_paging_ps_sig_lac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001792 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001793 f_start_handlers(refers(f_TC_paging_ps_sig_lac), testcasename(), 14);
Harald Welte0e188242020-11-22 21:46:48 +01001794 f_cleanup();
1795}
1796
Harald Welte7462a592020-11-23 22:07:07 +01001797/* PS-PAGING on SIG-BVC for unknown Location Area */
1798private function f_TC_paging_ps_sig_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1799{
1800 var GSM_Types.LocationAreaIdentification unknown_la := {
1801 mcc_mnc := '567F99'H,
1802 lac := 33333
1803 };
Daniel Willmann2a330672021-01-18 18:50:02 +01001804 f_send_paging_ps_exp_no_bss(ts_BssgpP4LAC(unknown_la), g_pars.sgsn_idx, true);
Harald Welte7462a592020-11-23 22:07:07 +01001805}
1806testcase TC_paging_ps_sig_lac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001807 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001808 f_start_handlers(refers(f_TC_paging_ps_sig_lac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001809 f_cleanup();
1810}
1811
Harald Welte0e188242020-11-22 21:46:48 +01001812/* PS-PAGING on SIG-BVC for Routeing Area */
1813private function f_TC_paging_ps_sig_rac(charstring id) runs on BSSGP_ConnHdlr
1814{
Daniel Willmann2c9300f2020-12-01 10:54:08 +01001815 /* Only PCU index 0 has a matching BVC with the RA ID */
Daniel Willmann43320442021-01-17 14:07:05 +01001816 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 +01001817 g_roi := {};
1818 /* PCU index 1 and 2 have a matching BVC with the RA ID */
Daniel Willmann43320442021-01-17 14:07:05 +01001819 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 +01001820 g_roi := {};
1821 /* PCU index 2 has two matching BVCs with the RA ID */
1822 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
Daniel Willmann43320442021-01-17 14:07:05 +01001823 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 +01001824}
1825testcase TC_paging_ps_sig_rac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001826 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001827 f_start_handlers(refers(f_TC_paging_ps_sig_rac), testcasename(), 15);
Harald Welte0e188242020-11-22 21:46:48 +01001828 f_cleanup();
1829}
1830
Harald Welte7462a592020-11-23 22:07:07 +01001831/* PS-PAGING on SIG-BVC for unknown Routeing Area */
1832private function f_TC_paging_ps_sig_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1833{
1834 var RoutingAreaIdentification unknown_ra := {
1835 lai := {
1836 mcc_mnc := '567F99'H,
1837 lac := 33333
1838 },
1839 rac := 254
1840 };
Daniel Willmann2a330672021-01-18 18:50:02 +01001841 f_send_paging_ps_exp_no_bss(ts_BssgpP4RAC(unknown_ra), g_pars.sgsn_idx, true);
Harald Welte7462a592020-11-23 22:07:07 +01001842}
1843testcase TC_paging_ps_sig_rac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001844 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001845 f_start_handlers(refers(f_TC_paging_ps_sig_rac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001846 f_cleanup();
1847}
1848
Harald Welte0e188242020-11-22 21:46:48 +01001849/* PS-PAGING on SIG-BVC for BVCI (one cell) */
1850private function f_TC_paging_ps_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
1851{
Daniel Willmann43320442021-01-17 14:07:05 +01001852 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 +01001853}
1854testcase TC_paging_ps_sig_bvci() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001855 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001856 f_start_handlers(refers(f_TC_paging_ps_sig_bvci), testcasename(), 16);
Harald Welte0e188242020-11-22 21:46:48 +01001857 f_cleanup();
1858}
1859
Harald Welteb5a04aa2021-01-16 13:04:40 +01001860/* PS-PAGING on SIG-BVC for BVCI (one cell) using IMSI only (no P-TMSI allocated) */
1861testcase TC_paging_ps_sig_bvci_imsi() runs on test_CT {
1862 f_init();
1863 f_start_handlers(refers(f_TC_paging_ps_sig_bvci), testcasename(), 16, have_ptmsi:=false);
1864 f_cleanup();
1865}
1866
Harald Weltecf200072021-01-16 15:20:46 +01001867/* Rejected PS-PAGING on SIG-BVC for BVCI (one cell) */
1868private function f_TC_paging_ps_reject_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
1869{
1870 /* first send the PS-PAGING from SGSN -> PCU */
Daniel Willmann43320442021-01-17 14:07:05 +01001871 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 +01001872 /* then simulate the PS-PAGING-REJECT from the PCU */
1873 f_send_paging_ps_rej(use_sig:=true);
1874
1875}
1876testcase TC_paging_ps_reject_sig_bvci() runs on test_CT {
1877 f_init();
1878 f_start_handlers(refers(f_TC_paging_ps_reject_sig_bvci), testcasename(), 16);
1879 f_cleanup();
1880}
1881
1882/* Rejected PS-PAGING on SIG-BVC for BVCI (one cell) using IMSI only (no P-TMSI allocated) */
1883testcase TC_paging_ps_reject_sig_bvci_imsi() runs on test_CT {
1884 f_init();
1885 f_start_handlers(refers(f_TC_paging_ps_reject_sig_bvci), testcasename(), 16, have_ptmsi:=false);
1886 f_cleanup();
1887}
1888
Harald Welte7462a592020-11-23 22:07:07 +01001889/* PS-PAGING on SIG-BVC for unknown BVCI */
1890private function f_TC_paging_ps_sig_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1891{
Daniel Willmann2a330672021-01-18 18:50:02 +01001892 f_send_paging_ps_exp_no_bss(ts_BssgpP4Bvci(33333), g_pars.sgsn_idx, true);
Harald Welte7462a592020-11-23 22:07:07 +01001893}
1894testcase TC_paging_ps_sig_bvci_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001895 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001896 f_start_handlers(refers(f_TC_paging_ps_sig_bvci_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001897 f_cleanup();
1898}
1899
Harald Welte7595d562021-01-16 19:09:20 +01001900/* DUMMY PAGING PS on SIG BVC */
1901private function f_TC_dummy_paging_ps_sig(charstring id) runs on BSSGP_ConnHdlr
1902{
1903 f_sgsn2pcu(ts_BSSGP_DUMMY_PAGING_PS(g_pars.imsi, omit),
1904 tr_BSSGP_DUMMY_PAGING_PS(g_pars.imsi, omit), use_sig := true);
1905 f_pcu2sgsn(ts_BSSGP_DUMMY_PAGING_PS_RESP(g_pars.imsi, 1, 5),
1906 tr_BSSGP_DUMMY_PAGING_PS_RESP(g_pars.imsi, 1, 5), use_sig := true)
1907}
1908testcase TC_dummy_paging_ps_sig() runs on test_CT {
1909 f_init();
1910 f_start_handlers(refers(f_TC_dummy_paging_ps_sig), testcasename(), 11);
1911 f_cleanup();
1912}
1913
Harald Welte7462a592020-11-23 22:07:07 +01001914
Harald Welte0e188242020-11-22 21:46:48 +01001915
1916/***********************************************************************
1917 * PAGING CS procedure
1918 ***********************************************************************/
1919
1920private function f_send_paging_cs(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1921 boolean use_sig := false)
1922runs on BSSGP_ConnHdlr return template (present) PDU_BSSGP {
1923 var template (value) PDU_BSSGP pdu_tx;
1924 var template (present) PDU_BSSGP pdu_rx;
1925 /* we always specify '0' as BVCI in the templates below, as we override it with
1926 * 'p4' later anyway */
1927 pdu_rx := tr_BSSGP_CS_PAGING(0);
1928 pdu_rx.pDU_BSSGP_PAGING_CS.iMSI := tr_BSSGP_IMSI(g_pars.imsi);
1929 if (ispresent(g_pars.p_tmsi)) {
1930 pdu_tx := ts_BSSGP_CS_PAGING_PTMSI(0, g_pars.imsi, oct2int(g_pars.p_tmsi));
1931 pdu_rx.pDU_BSSGP_PAGING_CS.tMSI := tr_BSSGP_TMSI(oct2int(g_pars.p_tmsi));
1932 } else {
1933 pdu_tx := ts_BSSGP_CS_PAGING_IMSI(0, g_pars.imsi);
1934 pdu_rx.pDU_BSSGP_PAGING_CS.tMSI := omit;
1935 }
1936 pdu_tx.pDU_BSSGP_PAGING_CS.paging_Field4 := p4;
1937 pdu_rx.pDU_BSSGP_PAGING_CS.paging_Field4 := p4;
1938 if (use_sig == false) {
Harald Welte158becf2020-12-09 12:32:32 +01001939 SGSN_PTP[sgsn_idx].send(pdu_tx);
Harald Welte0e188242020-11-22 21:46:48 +01001940 } else {
1941 SGSN_SIG[sgsn_idx].send(pdu_tx);
1942 }
1943 return pdu_rx;
1944}
1945
1946/* send paging defined by 'p4' on given SGSN-side index (ptp or signaling) and expect one paging to arrive on
1947 * specified PCU index */
1948private function f_send_paging_cs_exp_one_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1949 boolean use_sig := false,integer pcu_idx := 0)
1950runs on BSSGP_ConnHdlr {
1951 var template (present) PDU_BSSGP exp_rx;
Daniel Willmann1a859712020-12-04 00:59:45 +01001952 var boolean test_done := false;
Harald Welte0e188242020-11-22 21:46:48 +01001953 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1954 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1955 exp_rx := f_send_paging_cs(p4, sgsn_idx, use_sig);
1956 /* Expect paging to propagate to the one BSS addressed by the BVCI only */
1957 timer T := 2.0;
1958 T.start;
1959 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001960 [not use_sig and not test_done] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001961 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001962 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001963 repeat;
1964 }
1965 [not use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
1966 setverdict(fail, "Received paging on SIGNALING BVC, expected PTP BVC");
1967 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001968 [use_sig and not test_done] PCU_SIG[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001969 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001970 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001971 repeat;
1972 }
Harald Welte158becf2020-12-09 12:32:32 +01001973 [use_sig] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001974 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1975 }
Harald Welte158becf2020-12-09 12:32:32 +01001976 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001977 setverdict(fail, "Paging received on unexpected BVC");
1978 }
1979 [] any from PCU_SIG.receive(exp_rx) {
1980 setverdict(fail, "Paging received on unexpected BVC");
1981 }
Harald Welte158becf2020-12-09 12:32:32 +01001982 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01001983 setverdict(fail, "Different Paging than expected received PTP BVC");
1984 }
1985 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
1986 setverdict(fail, "Different Paging than expected on SIGNALING BVC");
1987 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001988 [not test_done] T.timeout {
1989 setverdict(fail, "Timeout while waiting for paging")
1990 }
1991 [test_done] T.timeout;
Harald Welte0e188242020-11-22 21:46:48 +01001992 }
1993}
1994
Harald Welte7462a592020-11-23 22:07:07 +01001995/* send a CS-PAGING but don't expect it to show up on any PTP or SIG BVC */
1996private function f_send_paging_cs_exp_no_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1997 boolean use_sig := false)
1998runs on BSSGP_ConnHdlr {
1999 var template (present) PDU_BSSGP exp_rx;
2000 exp_rx := f_send_paging_cs(p4, sgsn_idx, use_sig);
2001 /* Expect paging to propagate to no BSS */
2002 timer T := 2.0;
2003 T.start;
2004 alt {
Harald Welte158becf2020-12-09 12:32:32 +01002005 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte7462a592020-11-23 22:07:07 +01002006 setverdict(fail, "Paging received on unexpected BVC");
2007 }
2008 [] any from PCU_SIG.receive(exp_rx) {
2009 setverdict(fail, "Paging received on unexpected BVC");
2010 }
Harald Welte158becf2020-12-09 12:32:32 +01002011 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
Harald Welte7462a592020-11-23 22:07:07 +01002012 setverdict(fail, "Different Paging received on PTP BVC");
2013 }
2014 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
2015 setverdict(fail, "Different Paging received on SIGNALING BVC");
2016 }
2017 [] T.timeout {
2018 setverdict(pass);
2019 }
2020 }
2021}
2022
Harald Welte0e188242020-11-22 21:46:48 +01002023private function f_TC_paging_cs_ptp_bss(charstring id) runs on BSSGP_ConnHdlr
2024{
2025 /* doesn't really make sense: Sending to a single BVCI means the message ends up
2026 * at that BVC (cell) only, and paging all over the BSS area is not possible */
2027 f_send_paging_cs_exp_one_bss(ts_BssgpP4BssArea, 0, false, 0);
2028}
2029testcase TC_paging_cs_ptp_bss() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002030 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002031 f_start_handlers(refers(f_TC_paging_cs_ptp_bss), testcasename(), 17);
Harald Welte0e188242020-11-22 21:46:48 +01002032 f_cleanup();
2033}
2034
2035/* CS-PAGING on PTP-BVC for Location Area */
2036private function f_TC_paging_cs_ptp_lac(charstring id) runs on BSSGP_ConnHdlr
2037{
2038 var template (present) PDU_BSSGP exp_rx;
2039 /* doesn't really make sense: Sending to a single BVCI means the message ends up
2040 * at that BVC (cell) only, and paging all over the BSS area is not possible */
2041 f_send_paging_cs_exp_one_bss(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, false, 0);
2042}
2043testcase TC_paging_cs_ptp_lac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002044 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002045 f_start_handlers(refers(f_TC_paging_cs_ptp_lac), testcasename(), 18);
Harald Welte0e188242020-11-22 21:46:48 +01002046 f_cleanup();
2047}
2048
Harald Welte7462a592020-11-23 22:07:07 +01002049/* CS-PAGING on PTP-BVC for unknown Location Area */
2050private function f_TC_paging_cs_ptp_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
2051{
2052 var GSM_Types.LocationAreaIdentification unknown_la := {
2053 mcc_mnc := '567F99'H,
2054 lac := 33333
2055 };
2056 /* as it's sent on the PTP BVC, we expect it to pass even for unknown LAC */
2057 f_send_paging_cs_exp_one_bss(ts_BssgpP4LAC(unknown_la), 0, false, 0);
2058}
2059testcase TC_paging_cs_ptp_lac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002060 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002061 f_start_handlers(refers(f_TC_paging_cs_ptp_lac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002062 f_cleanup();
2063}
2064
Harald Welte0e188242020-11-22 21:46:48 +01002065/* CS-PAGING on PTP-BVC for Routeing Area */
2066private function f_TC_paging_cs_ptp_rac(charstring id) runs on BSSGP_ConnHdlr
2067{
2068 /* doesn't really make sense: Sending to a single BVCI means the message ends up
2069 * at that BVC (cell) only, and paging all over the BSS area is not possible */
2070 f_send_paging_cs_exp_one_bss(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, false, 0);
2071}
2072testcase TC_paging_cs_ptp_rac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002073 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002074 f_start_handlers(refers(f_TC_paging_cs_ptp_rac), testcasename(), 19);
Harald Welte0e188242020-11-22 21:46:48 +01002075 f_cleanup();
2076}
2077
Harald Welte7462a592020-11-23 22:07:07 +01002078/* CS-PAGING on PTP-BVC for unknown Routeing Area */
2079private function f_TC_paging_cs_ptp_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
2080{
2081 var RoutingAreaIdentification unknown_ra := {
2082 lai := {
2083 mcc_mnc := '567F99'H,
2084 lac := 33333
2085 },
2086 rac := 254
2087 };
2088 /* as it's sent on the PTP BVC, we expect it to pass even for unknown RAC */
2089 f_send_paging_cs_exp_one_bss(ts_BssgpP4RAC(unknown_ra), 0, false, 0);
2090}
2091testcase TC_paging_cs_ptp_rac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002092 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002093 f_start_handlers(refers(f_TC_paging_cs_ptp_rac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002094 f_cleanup();
2095}
2096
Harald Welte0e188242020-11-22 21:46:48 +01002097/* CS-PAGING on PTP-BVC for BVCI (one cell) */
2098private function f_TC_paging_cs_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
2099{
2100 /* this should be the normal case for MS in READY MM state after a lower layer failure */
2101 f_send_paging_cs_exp_one_bss(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, false, 0);
2102}
2103testcase TC_paging_cs_ptp_bvci() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002104 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002105 f_start_handlers(refers(f_TC_paging_cs_ptp_bvci), testcasename(), 20);
Harald Welte0e188242020-11-22 21:46:48 +01002106 f_cleanup();
2107}
2108
Harald Welte7462a592020-11-23 22:07:07 +01002109/* CS-PAGING on PTP-BVC for unknown BVCI */
2110private function f_TC_paging_cs_ptp_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
2111{
2112 /* as it's sent on the PTP BVC, we expect it to pass even for unknown BVCI */
2113 f_send_paging_cs_exp_one_bss(ts_BssgpP4Bvci(33333), 0, false, 0);
2114}
2115testcase TC_paging_cs_ptp_bvci_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002116 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002117 f_start_handlers(refers(f_TC_paging_cs_ptp_bvci_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002118 f_cleanup();
2119}
2120
Harald Welte0e188242020-11-22 21:46:48 +01002121/* send CS-PAGING on SIG BVC, expect it to arrive on given list of PCU indexes */
2122private function f_send_paging_cs_exp_multi(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
2123 ro_integer exp_on_pcu_idx) runs on BSSGP_ConnHdlr
2124{
2125 var template (present) PDU_BSSGP exp_rx;
2126 exp_rx := f_send_paging_cs(p4, 0, true);
2127
2128 /* FIXME: make sure the relevant BVCs/BSS are connected to the ports! */
2129 var ro_default defaults := {};
2130 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
2131 var default d := activate(as_paging_sig_pcu(i, exp_rx, g_roi));
2132 defaults := defaults & { d };
2133 }
2134 f_sleep(2.0);
2135 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2136 deactivate(defaults[i]);
2137 }
2138 log("Paging received on PCU ", g_roi);
2139
2140 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
2141 var boolean rx_on_i := ro_integer_contains(g_roi, i);
2142 var boolean exp_on_i := ro_integer_contains(exp_on_pcu_idx, i);
2143 if (exp_on_i and not rx_on_i) {
2144 setverdict(fail, "PS-PAGING not received on ", mp_nsconfig_pcu[i].nsei);
2145 }
2146 if (not exp_on_i and rx_on_i) {
2147 setverdict(fail, "PS-PAGING not expected but received on ", mp_nsconfig_pcu[i].nsei);
2148 }
2149 }
2150 setverdict(pass);
2151}
2152
2153/* CS-PAGING on SIG-BVC for BSS Area */
2154private function f_TC_paging_cs_sig_bss(charstring id) runs on BSSGP_ConnHdlr
2155{
2156 /* we expect the paging to arrive on all three NSE */
2157 f_send_paging_cs_exp_multi(ts_BssgpP4BssArea, 0, {0, 1, 2});
2158}
2159testcase TC_paging_cs_sig_bss() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002160 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002161 f_start_handlers(refers(f_TC_paging_cs_sig_bss), testcasename(), 13);
Harald Welte0e188242020-11-22 21:46:48 +01002162 f_cleanup();
2163}
2164
2165/* CS-PAGING on SIG-BVC for Location Area */
2166private function f_TC_paging_cs_sig_lac(charstring id) runs on BSSGP_ConnHdlr
2167{
Daniel Willmannd4fb73c2020-12-07 13:57:17 +01002168 /* The first LAC (13135) is shared by all three NSEs */
2169 f_send_paging_cs_exp_multi(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, {0, 1, 2});
2170 /* Reset state */
2171 g_roi := {};
2172 /* Make LAC (13300) available on pcu index 2 */
2173 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
2174 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 +01002175}
2176testcase TC_paging_cs_sig_lac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002177 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002178 f_start_handlers(refers(f_TC_paging_cs_sig_lac), testcasename(), 14);
Harald Welte0e188242020-11-22 21:46:48 +01002179 f_cleanup();
2180}
2181
Harald Welte7462a592020-11-23 22:07:07 +01002182/* CS-PAGING on SIG-BVC for unknown Location Area */
2183private function f_TC_paging_cs_sig_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
2184{
2185 var GSM_Types.LocationAreaIdentification unknown_la := {
2186 mcc_mnc := '567F99'H,
2187 lac := 33333
2188 };
2189 f_send_paging_cs_exp_no_bss(ts_BssgpP4LAC(unknown_la), 0, true);
2190}
2191testcase TC_paging_cs_sig_lac_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_sig_lac_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 SIG-BVC for Routeing Area */
2198private function f_TC_paging_cs_sig_rac(charstring id) runs on BSSGP_ConnHdlr
2199{
Daniel Willmannd4fb73c2020-12-07 13:57:17 +01002200 /* Only PCU index 0 has a matching BVC with the RA ID */
Harald Welte0e188242020-11-22 21:46:48 +01002201 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 +01002202 g_roi := {};
2203 /* PCU index 1 and 2 have a matching BVC with the RA ID */
2204 f_send_paging_cs_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[2].cell_id.ra_id), 0, {1, 2});
2205 g_roi := {};
2206 /* PCU index 2 has two matching BVCs with the RA ID */
2207 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
2208 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 +01002209}
2210testcase TC_paging_cs_sig_rac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002211 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002212 f_start_handlers(refers(f_TC_paging_cs_sig_rac), testcasename(), 15);
Harald Welte0e188242020-11-22 21:46:48 +01002213 f_cleanup();
2214}
2215
Harald Welte7462a592020-11-23 22:07:07 +01002216/* CS-PAGING on SIG-BVC for unknown Routeing Area */
2217private function f_TC_paging_cs_sig_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
2218{
2219 var RoutingAreaIdentification unknown_ra := {
2220 lai := {
2221 mcc_mnc := '567F99'H,
2222 lac := 33333
2223 },
2224 rac := 254
2225 };
2226 f_send_paging_cs_exp_no_bss(ts_BssgpP4RAC(unknown_ra), 0, true);
2227}
2228testcase TC_paging_cs_sig_rac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002229 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002230 f_start_handlers(refers(f_TC_paging_cs_sig_rac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002231 f_cleanup();
2232}
2233
Harald Welte0e188242020-11-22 21:46:48 +01002234/* CS-PAGING on SIG-BVC for BVCI (one cell) */
2235private function f_TC_paging_cs_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
2236{
2237 f_send_paging_cs_exp_multi(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, {0});
2238}
2239testcase TC_paging_cs_sig_bvci() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002240 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002241 f_start_handlers(refers(f_TC_paging_cs_sig_bvci), testcasename(), 16);
Harald Welte0e188242020-11-22 21:46:48 +01002242 f_cleanup();
2243}
2244
Harald Welte7462a592020-11-23 22:07:07 +01002245/* CS-PAGING on SIG-BVC for unknown BVCI */
2246private function f_TC_paging_cs_sig_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
2247{
2248 f_send_paging_cs_exp_no_bss(ts_BssgpP4Bvci(33333), 0, true);
2249}
2250testcase TC_paging_cs_sig_bvci_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002251 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002252 f_start_handlers(refers(f_TC_paging_cs_sig_bvci_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002253 f_cleanup();
2254}
2255
Harald Welte4f91c3b2020-12-09 12:25:51 +01002256/***********************************************************************
2257 * FLUSH-LL procedure
2258 ***********************************************************************/
2259
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002260private function f_TC_flush_ll(charstring id) runs on BSSGP_ConnHdlr {
2261 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
2262 var integer i;
2263 for (i := 0; i < 10; i := i+1) {
2264 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_FLUSH_LL(g_pars.tlli, bvci, bvci_new := bvci);
2265 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2266 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_FLUSH_LL(g_pars.tlli, bvci, bvci_new := bvci);
2267
2268 f_sgsn2pcu(pdu_tx, pdu_rx, use_sig := true);
2269
2270 pdu_tx := ts_BSSGP_FLUSH_LL_ACK(g_pars.tlli, int2oct(0, 1), 23, bvci_new := bvci);
2271 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2272 pdu_rx := tr_BSSGP_FLUSH_LL_ACK(g_pars.tlli, int2oct(0, 1), 23, bvci_new := bvci);
2273
2274 f_pcu2sgsn(pdu_tx, pdu_rx, use_sig := true);
2275 }
2276 setverdict(pass);
2277}
2278testcase TC_flush_ll() runs on test_CT
2279{
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002280 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002281 f_start_handlers(refers(f_TC_flush_ll), testcasename(), 6);
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002282 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002283 f_cleanup();
2284}
Harald Welte6dc2ac42020-11-16 09:16:17 +01002285
Harald Welte4f91c3b2020-12-09 12:25:51 +01002286/***********************************************************************
2287 * SGSN-INVOKE-TRACE procedure
2288 ***********************************************************************/
2289
Harald Weltef8e5c5d2020-11-27 22:37:23 +01002290private altstep as_bssgp_g_pcu_count(integer pcu_idx, template (present) PDU_BSSGP exp_rx, inout ro_integer roi)
2291runs on GlobalTest_CT {
2292[] G_PCU[pcu_idx].receive(exp_rx) from g_pcu[pcu_idx].vc_BSSGP {
2293 if (ro_integer_contains(roi, pcu_idx)) {
2294 setverdict(fail, "Received multiple on same SIG BVC");
2295 }
2296 roi := roi & { pcu_idx };
2297 repeat;
2298 }
2299}
2300/* send a INVOKE-TRACE from SGSN and expect to receive a copy on each NSE */
2301testcase TC_trace() runs on GlobalTest_CT
2302{
2303 var BSSGP_ConnHdlr vc_conn;
2304 f_init();
2305 f_global_init();
2306
2307 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_INVOKE_TRACE('23'O, '4321'O);
2308 var template (present) PDU_BSSGP exp_rx := ts_BSSGP_INVOKE_TRACE('23'O, '4321'O);
2309
2310 var ro_default defaults := {};
2311 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2312 activate(as_bssgp_g_pcu_count(i, exp_rx, g_roi));
2313 }
2314 G_SGSN[0].send(pdu_tx);
2315 f_sleep(2.0);
2316 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2317 deactivate(defaults[i]);
2318 }
2319
2320 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2321 if (not ro_integer_contains(g_roi, i)) {
2322 setverdict(fail, "Failed to receive TRACE on PCU index ", i);
2323 }
2324 }
2325 setverdict(pass);
2326
2327 f_cleanup();
2328}
2329
Harald Welte4f91c3b2020-12-09 12:25:51 +01002330/***********************************************************************
2331 * LLC-DISCARDED procedure
2332 ***********************************************************************/
2333
Harald Weltec0351d12020-11-27 22:49:02 +01002334private function f_TC_llc_discarded(charstring id) runs on BSSGP_ConnHdlr {
2335 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
2336
2337 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_LLC_DISCARDED(g_pars.tlli, 23, bvci, 2342);
2338 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2339 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_LLC_DISCARDED(g_pars.tlli, 23, bvci, 2342);
2340
2341 f_pcu2sgsn(pdu_tx, pdu_rx, use_sig := true);
2342
2343 setverdict(pass);
2344}
2345/* Send a LLC-DISCARDED from BSS side and expect it to show up on SGSN (SIG BVC) */
2346testcase TC_llc_discarded() runs on test_CT
2347{
Harald Weltec0351d12020-11-27 22:49:02 +01002348 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002349 f_start_handlers(refers(f_TC_llc_discarded), testcasename(), 6);
Harald Weltec0351d12020-11-27 22:49:02 +01002350 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Weltec0351d12020-11-27 22:49:02 +01002351 f_cleanup();
2352}
2353
Harald Welte4f91c3b2020-12-09 12:25:51 +01002354/***********************************************************************
2355 * OVERLOAD procedure
2356 ***********************************************************************/
2357
Harald Weltef20af412020-11-28 16:11:11 +01002358/* Send an OVERLOAD from SGSN side and expect it to show up on each PCU (SIG BVC) */
2359testcase TC_overload() runs on GlobalTest_CT
2360{
2361 f_init();
2362 f_global_init();
2363
2364 var template (value) PDU_BSSGP pdu_tx := ts_OVERLOAD('1'B);
2365 var template (present) PDU_BSSGP exp_rx := tr_OVERLOAD('1'B);
2366
2367 var ro_default defaults := {};
2368 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2369 activate(as_bssgp_g_pcu_count(i, exp_rx, g_roi));
2370 }
2371 G_SGSN[0].send(pdu_tx);
2372 f_sleep(2.0);
2373 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2374 deactivate(defaults[i]);
2375 }
2376
2377 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2378 if (not ro_integer_contains(g_roi, i)) {
2379 setverdict(fail, "Failed to receive OVERLOAD on PCU index ", i);
2380 }
2381 }
2382 setverdict(pass);
2383
2384 f_cleanup();
2385}
2386
Harald Welte4f91c3b2020-12-09 12:25:51 +01002387/***********************************************************************
2388 * BVC-BLOCK / BVC-UNBLOCK procedure
2389 ***********************************************************************/
2390
Harald Welte239aa502020-11-24 23:14:20 +01002391private function f_block_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2392{
2393 var BSSGP_BVC_CT bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2394 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2395 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2396
2397 SGSN_MGMT.clear;
2398 PCU_MGMT.clear;
2399
2400 /* block the PTP BVC from the PCU side */
2401 PCU_MGMT.send(BssgpBlockRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to bvc_ct;
2402 /* expect state on both PCU and SGSN side to change */
2403 interleave {
2404 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_BLOCKED)) from bvc_ct;
Harald Welte572b0172021-03-30 13:19:56 +02002405 [] SGSN_MGMT.receive(tr_BssgpStsInd(mp_nsconfig_sgsn[0].nsei, bvc_cfg.bvci, BVC_S_BLOCKED));
2406 [] SGSN_MGMT.receive(tr_BssgpStsInd(mp_nsconfig_sgsn[1].nsei, bvc_cfg.bvci, BVC_S_BLOCKED));
2407 /* Doesn't auto-scale with NUM_SGSN */
Harald Welte239aa502020-11-24 23:14:20 +01002408 }
2409 setverdict(pass);
2410}
2411testcase TC_bvc_block_ptp() runs on test_CT
2412{
2413 f_init();
2414 f_sleep(1.0);
2415 f_block_ptp_bvc_from_pcu(0, 0);
2416 f_cleanup();
2417}
2418
2419private function f_unblock_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2420{
2421 var BSSGP_BVC_CT bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2422 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2423 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2424
2425 SGSN_MGMT.clear;
2426 PCU_MGMT.clear;
2427
2428 /* block the PTP BVC from the PCU side */
2429 PCU_MGMT.send(BssgpUnblockRequest:{}) to bvc_ct;
2430 /* expect state on both PCU and SGSN side to change */
2431 interleave {
2432 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_UNBLOCKED)) from bvc_ct;
Harald Welte572b0172021-03-30 13:19:56 +02002433 [] SGSN_MGMT.receive(tr_BssgpStsInd(mp_nsconfig_sgsn[0].nsei, bvc_cfg.bvci, BVC_S_UNBLOCKED));
2434 [] SGSN_MGMT.receive(tr_BssgpStsInd(mp_nsconfig_sgsn[1].nsei, bvc_cfg.bvci, BVC_S_UNBLOCKED));
2435 /* Doesn't auto-scale with NUM_SGSN */
Harald Welte239aa502020-11-24 23:14:20 +01002436 }
2437 setverdict(pass);
2438}
2439testcase TC_bvc_unblock_ptp() runs on test_CT
2440{
2441 f_init();
2442 f_sleep(1.0);
2443 f_block_ptp_bvc_from_pcu(0, 0);
2444 f_sleep(1.0);
2445 f_unblock_ptp_bvc_from_pcu(0, 0);
2446 f_cleanup();
2447}
2448
Harald Welte4f91c3b2020-12-09 12:25:51 +01002449/***********************************************************************
2450 * BVC-RESET procedure
2451 ***********************************************************************/
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002452private altstep as_count_bvc_reset(integer sgsn_idx, BssgpBvci bvci, inout roro_integer roroi)
2453runs on test_CT {
2454 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(sgsn_idx, bvci);
2455 [] SGSN_MGMT.receive(BssgpResetIndication:{bvci}) from sgsn_bvc_ct {
2456 roroi[sgsn_idx] := roroi[sgsn_idx] & { bvci };
2457 repeat;
2458 }
2459}
Harald Welte60a8ec72020-11-25 17:12:53 +01002460private altstep as_ignore_status(BSSGP_BVC_MGMT_PT pt) {
2461[] pt.receive(BssgpStatusIndication:?) { repeat; }
2462}
2463private function f_get_sgsn_bvc_ct(integer sgsn_idx, BssgpBvci bvci) runs on test_CT return BSSGP_BVC_CT {
2464 for (var integer i := 0; i < lengthof(g_sgsn[sgsn_idx].cfg.bvc); i := i+1) {
2465 if (g_sgsn[sgsn_idx].cfg.bvc[i].bvci == bvci) {
2466 return g_sgsn[sgsn_idx].vc_BSSGP_BVC[i];
2467 }
2468 }
2469 return null;
2470}
2471private function f_reset_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2472{
2473 var BSSGP_BVC_CT pcu_bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2474 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2475 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002476 var ro_default defaults;
2477 var integer i;
Harald Welte60a8ec72020-11-25 17:12:53 +01002478
2479 SGSN_MGMT.clear;
2480 PCU_MGMT.clear;
2481
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002482 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
2483 g_roroi[i] := {};
2484 }
2485
Harald Welte60a8ec72020-11-25 17:12:53 +01002486 /* block the PTP BVC from the PCU side */
2487 PCU_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to pcu_bvc_ct;
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002488
Harald Welte60a8ec72020-11-25 17:12:53 +01002489 /* expect state on both PCU and SGSN side to change */
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002490 defaults := { activate(as_ignore_status(SGSN_MGMT)) };
2491
2492 /* Activate altsteps: One for each SGSN */
2493 for (i := 0; i < lengthof(g_sgsn); i := i+1) {
2494 var default d := activate(as_count_bvc_reset(i, bvc_cfg.bvci, g_roroi));
2495 defaults := defaults & { d };
Harald Welte60a8ec72020-11-25 17:12:53 +01002496 }
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002497
2498 timer T := 3.0;
2499 T.start;
2500 alt {
2501 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_BLOCKED)) from pcu_bvc_ct {
2502 g_roi := g_roi & { bvc_cfg.bvci };
2503 repeat;
2504 }
2505 [] T.timeout;
2506 }
2507
2508 for (i := 0; i < lengthof(defaults); i := i+1) {
2509 deactivate(defaults[i]);
2510 }
2511
2512 /* Check if BVC-RESET was received at all SGSNs */
2513 for (i := 0; i < lengthof(g_sgsn); i := i+1) {
2514 if (not ro_integer_contains(g_roroi[i], bvc_cfg.bvci)) {
2515 setverdict(fail, "Missing SGSN[", i, "] BVC-BLOCK of BVCI=", bvc_cfg.bvci);
2516 }
2517 }
2518
Harald Welte60a8ec72020-11-25 17:12:53 +01002519 setverdict(pass);
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002520 f_cleanup();
Harald Welte60a8ec72020-11-25 17:12:53 +01002521}
2522/* Send a BVC-RESET for a PTP BVC from the BSS side: expect it to propagate */
2523testcase TC_bvc_reset_ptp_from_bss() runs on test_CT
2524{
2525 f_init();
2526 f_sleep(3.0);
2527 f_reset_ptp_bvc_from_pcu(0, 0);
2528 f_cleanup();
2529}
2530
Harald Welteb1cc0b22021-03-30 12:16:36 +02002531private altstep as_count_bvc_sts(integer sgsn_idx, BssgpBvci bvci,
2532 template (present) BvcState exp_bvc_state, inout roro_integer roroi)
Harald Welte16786e92020-11-27 19:11:56 +01002533runs on test_CT {
2534 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(sgsn_idx, bvci);
Harald Welteb1cc0b22021-03-30 12:16:36 +02002535 [] SGSN_MGMT.receive(tr_BssgpStsInd(?, bvci, exp_bvc_state)) from sgsn_bvc_ct {
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002536 roroi[sgsn_idx] := roroi[sgsn_idx] & { bvci };
Harald Welteb2647f72020-12-07 14:36:35 +01002537 repeat;
Harald Welte16786e92020-11-27 19:11:56 +01002538 }
2539}
Harald Welteb1cc0b22021-03-30 12:16:36 +02002540
2541private altstep as_count_bvc_block(integer sgsn_idx, BssgpBvci bvci, inout roro_integer roroi)
2542runs on test_CT {
2543 [] as_count_bvc_sts(sgsn_idx, bvci, BVC_S_BLOCKED, roroi);
2544}
2545
2546private altstep as_count_bvc_unblock(integer sgsn_idx, BssgpBvci bvci, inout roro_integer roroi)
2547runs on test_CT {
2548 [] as_count_bvc_sts(sgsn_idx, bvci, BVC_S_UNBLOCKED, roroi);
2549}
2550
Harald Welte16786e92020-11-27 19:11:56 +01002551/* reset the signaling BVC from one BSS; expect no signaling BVC reset on SGSN; but BVC-BLOCK for PTP */
2552testcase TC_bvc_reset_sig_from_bss() runs on test_CT {
2553
2554 f_init();
2555 f_sleep(3.0);
2556
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002557 for (var integer i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
2558 g_roroi[i] := {};
2559 }
2560
Harald Welte16786e92020-11-27 19:11:56 +01002561 /* Start BVC-RESET procedure for BVCI=0 */
2562 PCU_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to g_pcu[0].vc_BSSGP;
2563
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002564 /* Activate altsteps: One for each PTP BVC and SGSN within that PCUs NSE */
Harald Welte16786e92020-11-27 19:11:56 +01002565 var ro_default defaults := {};
2566 for (var integer i := 0; i < lengthof(g_pcu[0].cfg.bvc); i := i+1) {
2567 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[i];
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002568 for (var integer j := 0; j < lengthof(g_sgsn); j := j+1) {
2569 var default d := activate(as_count_bvc_block(j, bvcc.bvci, g_roroi));
2570 defaults := defaults & { d };
2571 }
Harald Welte16786e92020-11-27 19:11:56 +01002572 }
2573
2574 timer T := 3.0;
2575 T.start;
2576 alt {
2577 [] SGSN_MGMT.receive(BssgpResetIndication:{0}) {
2578 setverdict(fail, "BSS-side Reset of BVCI=0 should not propagate");
2579 }
2580 [] T.timeout;
2581 }
2582
2583 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2584 deactivate(defaults[i]);
2585 }
2586
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002587 /* check if BVC-block was received on all expected BVC/SGSN */
Harald Welte16786e92020-11-27 19:11:56 +01002588 for (var integer i := 0; i < lengthof(g_pcu[0].cfg.bvc); i := i+1) {
2589 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[i];
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002590 for (var integer j := 0; j < lengthof(g_sgsn); j := j+1) {
2591 if (not ro_integer_contains(g_roroi[j], bvcc.bvci)) {
2592 setverdict(fail, "Missing SGSN[", j, "] BVC-BLOCK of BVCI=", bvcc.bvci);
2593 }
Harald Welte16786e92020-11-27 19:11:56 +01002594 }
2595 }
2596
2597 /* check if BVC-block was not received on any unexpected BVC is not required as
2598 * such a message would basically run into 'no matching clause' */
Daniel Willmannf2590212020-12-04 14:20:50 +01002599 setverdict(pass);
Harald Welte16786e92020-11-27 19:11:56 +01002600 f_cleanup();
2601}
2602
Harald Welte60a8ec72020-11-25 17:12:53 +01002603private function f_reset_ptp_bvc_from_sgsn(integer pcu_idx, integer bvc_idx) runs on test_CT
2604{
2605 var BSSGP_BVC_CT pcu_bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2606 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2607 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2608 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(0, bvc_cfg.bvci);
2609 var default d;
2610
2611 SGSN_MGMT.clear;
2612 PCU_MGMT.clear;
2613
2614 /* block the PTP BVC from the PCU side */
2615 SGSN_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to sgsn_bvc_ct;
2616 /* expect state on both PCU and SGSN side to change */
2617 d := activate(as_ignore_status(PCU_MGMT));
2618 interleave {
2619 [] SGSN_MGMT.receive(tr_BssgpStsInd(?, bvc_cfg.bvci, BVC_S_BLOCKED)) from sgsn_bvc_ct;
2620 [] PCU_MGMT.receive(BssgpResetIndication:{bvc_cfg.bvci}) from pcu_bvc_ct;
2621 }
2622 deactivate(d);
2623 setverdict(pass);
2624}
2625/* Send a BVC-RESET for a PTP BVC from the SGSN side: expect it to propagate */
2626testcase TC_bvc_reset_ptp_from_sgsn() runs on test_CT
2627{
2628 f_init();
2629 f_sleep(3.0);
2630 f_reset_ptp_bvc_from_sgsn(0, 0);
2631 f_cleanup();
2632}
2633
Daniel Willmannef7015f2021-01-08 00:43:56 +01002634private altstep as_ignore_mgmt(BSSGP_BVC_MGMT_PT pt) {
2635 [] pt.receive {repeat; }
2636}
2637
Harald Welte16786e92020-11-27 19:11:56 +01002638private altstep as_count_bvc0_block(integer pcu_idx, Nsei nsei, inout ro_integer roi)
2639runs on test_CT {
2640 var BSSGP_CT pcu_ct := g_pcu[pcu_idx].vc_BSSGP;
2641 [] PCU_MGMT.receive(BssgpResetIndication:{0}) from pcu_ct {
2642 roi := roi & { nsei };
Daniel Willmannef7015f2021-01-08 00:43:56 +01002643 repeat;
Harald Welte16786e92020-11-27 19:11:56 +01002644 }
2645}
Daniel Willmannef7015f2021-01-08 00:43:56 +01002646
Harald Welte16786e92020-11-27 19:11:56 +01002647/* reset the signaling BVC from the SGSN; expect all signaling BVC on all BSS to be reset */
2648testcase TC_bvc_reset_sig_from_sgsn() runs on test_CT {
2649
2650 f_init();
2651 f_sleep(3.0);
2652
Daniel Willmannef7015f2021-01-08 00:43:56 +01002653 SGSN_MGMT.clear;
2654 PCU_MGMT.clear;
2655
Harald Welte16786e92020-11-27 19:11:56 +01002656 /* Start BVC-RESET procedure for BVCI=0 */
2657 SGSN_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to g_sgsn[0].vc_BSSGP;
2658
Daniel Willmannef7015f2021-01-08 00:43:56 +01002659 /* Defaults match in reverse activation order, this one is a catch-all for Status indications
2660 * and reset indications sent from other components (like the ptp_bvcs). If we don't drain
2661 * the port and a different message sits at the front we wait forever and fail the test.
2662 */
2663 var ro_default defaults := { activate(as_ignore_mgmt(PCU_MGMT)) };
2664
Harald Welte16786e92020-11-27 19:11:56 +01002665 /* Activate altsteps: One for each PCU NSE */
Harald Welte16786e92020-11-27 19:11:56 +01002666 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2667 var NSConfiguration nscfg := mp_nsconfig_pcu[i];
2668 var default d := activate(as_count_bvc0_block(i, nscfg.nsei, g_roi));
2669 defaults := defaults & { d };
2670 }
2671
2672 f_sleep(3.0);
2673
2674 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2675 deactivate(defaults[i]);
2676 }
2677
2678 /* check if BVC-block was received on all expected BVC */
2679 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2680 var NSConfiguration nscfg := mp_nsconfig_pcu[i];
2681 if (not ro_integer_contains(g_roi, nscfg.nsei)) {
2682 setverdict(fail, "Missing PCU-side BVC-RESET of BVCI=0 on PCU index ", i);
2683 }
2684 }
2685
2686 /* check if BVC-block was not received on any unexpected BVC is not required as
2687 * such a message would basically run into 'no matching clause' */
2688
2689 f_cleanup();
2690}
2691
Harald Welte299aa482020-12-09 15:10:55 +01002692/***********************************************************************
2693 * FLOW-CONTROL-BVC procedure
2694 ***********************************************************************/
2695
2696private altstep as_g_count_sgsn(integer sgsn_idx, inout ro_integer roi,
2697 template PDU_BSSGP exp_rx, template (omit) PDU_BSSGP tx_reply)
2698runs on GlobalTest_CT {
2699 [] G_SGSN[sgsn_idx].receive(exp_rx) {
2700 roi := roi & { sgsn_idx };
2701 if (ispresent(tx_reply)) {
2702 G_SGSN[sgsn_idx].send(tx_reply);
2703 }
Harald Welte5fb01742021-01-15 21:07:52 +01002704 repeat;
Harald Welte299aa482020-12-09 15:10:55 +01002705 }
2706}
2707/* Send FC-BVC from simulated PCU; expect each SGSN to receive it; expect PCU to receive ACK */
2708testcase TC_fc_bvc() runs on GlobalTest_CT
2709{
2710 f_init();
2711 f_global_init_ptp();
2712
Pau Espin Pedrol6ee01262021-02-05 13:05:06 +01002713 var template (value) PDU_BSSGP pdu_tx := ts_BVC_FC_BVC(10240, 2000, 1024, 1000, '01'O);
Harald Welte299aa482020-12-09 15:10:55 +01002714 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2715 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 +01002716 var template (value) PDU_BSSGP ack_tx :=
2717 ts_BVC_FC_BVC_ACK(pdu_tx.pDU_BSSGP_FLOW_CONTROL_BVC.tag.unstructured_Value);
Harald Welte299aa482020-12-09 15:10:55 +01002718
2719 /* Send a FC-BVC from BSS to gbproxy, expect an ACK in response */
2720 G_PCU[0].send(pdu_tx);
2721
2722 /* Activate altsteps: One for each SGSN-side PTP BVC port */
2723 var ro_default defaults := {};
2724 for (var integer i := 0; i < lengthof(g_sgsn); i := i+1) {
2725 var default d := activate(as_g_count_sgsn(i, g_roi, pdu_rx, ack_tx));
2726 defaults := defaults & { d };
2727 }
2728
2729 f_sleep(3.0);
2730
2731 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2732 deactivate(defaults[i]);
2733 }
2734
2735 /* check if BVC-block was received on all expected BVC */
2736 for (var integer i := 0; i < lengthof(g_sgsn); i := i+1) {
2737 if (not ro_integer_contains(g_roi, i)) {
2738 setverdict(fail, "Missing BVC-FLOW-CONTROL on SGSN index ", i);
2739 }
2740 }
2741
2742 /* Expect ACK on PCU side */
2743 G_PCU[0].receive(ack_tx);
2744
2745 setverdict(pass);
2746
2747 f_cleanup();
2748}
2749
Harald Weltecc3894b2020-12-09 16:50:12 +01002750/***********************************************************************
2751 * FLOW-CONTROL-MS procedure
2752 ***********************************************************************/
2753
2754private function f_TC_fc_ms(charstring id) runs on BSSGP_ConnHdlr {
2755 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
2756
2757 var template (value) PDU_BSSGP fc_tx := ts_BVC_FC_MS(g_pars.tlli, 100, 200, '12'O);
2758 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2759 var template (present) PDU_BSSGP fc_rx := tr_BVC_FC_MS(g_pars.tlli, 100, 200, '12'O);
2760 var template (value) PDU_BSSGP ack_tx := ts_BVC_FC_MS_ACK(g_pars.tlli, '12'O);
2761
2762 f_pcu2sgsn(fc_tx, fc_rx, use_sig := false);
2763 f_sgsn2pcu(ack_tx, ack_tx, use_sig := false);
2764
2765 setverdict(pass);
2766}
2767/* Send a FLOW-CONTROL-MS from BSS side and expect it to show up on SGSN (PTP BVC) */
2768testcase TC_fc_ms() runs on test_CT
2769{
Harald Weltecc3894b2020-12-09 16:50:12 +01002770 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002771 f_start_handlers(refers(f_TC_fc_ms), testcasename(), 21);
Harald Weltecc3894b2020-12-09 16:50:12 +01002772 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Weltecc3894b2020-12-09 16:50:12 +01002773 f_cleanup();
2774}
2775
Harald Welted6f89812021-01-16 18:57:49 +01002776/***********************************************************************
2777 * MS-REGISTRATION ENQUIRY procedure
2778 ***********************************************************************/
Harald Weltecc3894b2020-12-09 16:50:12 +01002779
Harald Welted6f89812021-01-16 18:57:49 +01002780private function f_TC_ms_reg_enq(charstring id) runs on BSSGP_ConnHdlr
2781{
2782 f_pcu2sgsn(ts_BSSGP_MS_REG_ENQ(g_pars.imsi), tr_BSSGP_MS_REG_ENQ(g_pars.imsi), use_sig := true);
2783 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);
2784}
2785testcase TC_ms_reg_enq() runs on test_CT
2786{
2787 f_init();
2788 f_start_handlers(refers(f_TC_ms_reg_enq), testcasename(), 22);
2789 f_cleanup();
2790}
Harald Welte299aa482020-12-09 15:10:55 +01002791
Harald Weltef86f1852021-01-16 21:56:17 +01002792/***********************************************************************
2793 * RIM (RAN Information Management)
2794 ***********************************************************************/
2795
2796/* Our tests here are rather synthetic, as they don't reflect normal message flows
2797 as they would be observed in a live network. However, for testing gbproxy, this shouldn't
2798 matter as gbproxy is not concerned with anything but the source / destination routing
2799 information */
2800
2801/* gbproxy must route all unknown RIM Routing Info (Cell Id) to the SGSN. We just define
2802 one here of which we know it is not used among the [simulated] PCUs */
2803const BssgpCellId cell_id_sgsn := {
2804 ra_id := {
2805 lai := {
2806 mcc_mnc := c_mcc_mnc,
2807 lac := 65534
2808 },
2809 rac := 0
2810 },
2811 cell_id := 65533
2812};
2813
2814/* Send 'tx' on PTP-BVCI from PCU; expect 'rx' on any of our SGSN (RIM can be routed anywhere) */
2815friend function f_rim_pcu2sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
2816 integer pcu_idx := 0) runs on GlobalTest_CT {
2817 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +01002818 timer T := 2.0;
Harald Weltef86f1852021-01-16 21:56:17 +01002819
2820 RIM_PCU[pcu_idx].send(tx);
2821 T.start;
2822 alt {
2823 [] any from RIM_SGSN.receive(exp_rx) {
2824 setverdict(pass);
2825 }
2826 [] any from RIM_SGSN.receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +01002827 f_shutdown(__FILE__, __LINE__, fail, log2str("Unexpected BSSGP on SGSN side: ", rx));
Harald Weltef86f1852021-01-16 21:56:17 +01002828 }
2829 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +01002830 f_shutdown(__FILE__, __LINE__, fail,
2831 log2str("Timeout waiting for BSSGP on SGSN side: ", exp_rx));
Harald Weltef86f1852021-01-16 21:56:17 +01002832 }
2833 }
2834}
2835
2836/* Send 'tx' on PTP-BVCI from SGSN; expect 'rx' on PCU */
2837friend function f_rim_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
2838 integer sgsn_idx := 0, integer pcu_idx := 0) runs on GlobalTest_CT {
2839 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +01002840 timer T := 2.0;
Harald Weltef86f1852021-01-16 21:56:17 +01002841
2842 RIM_SGSN[sgsn_idx].send(tx);
2843 T.start;
2844 alt {
2845 [] RIM_PCU[pcu_idx].receive(exp_rx) {
2846 setverdict(pass);
2847 }
2848 [] RIM_PCU[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +01002849 f_shutdown(__FILE__, __LINE__, fail, log2str("Unexpected BSSGP on PCU side: ", rx));
Harald Weltef86f1852021-01-16 21:56:17 +01002850 }
2851 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +01002852 f_shutdown(__FILE__, __LINE__, fail,
2853 log2str("Timeout waiting for BSSGP on PCU side: ", exp_rx));
Harald Weltef86f1852021-01-16 21:56:17 +01002854 }
2855 }
2856}
2857
2858/* Send 'tx' on PTP-BVCI from SRC-PCU; expect 'rx' on DST-PCU */
2859friend function f_rim_pcu2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
2860 integer src_pcu_idx, integer dst_pcu_idx) runs on GlobalTest_CT {
2861 var integer rx_idx;
2862 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +01002863 timer T := 2.0;
Harald Weltef86f1852021-01-16 21:56:17 +01002864
2865 RIM_PCU[src_pcu_idx].send(tx);
2866 T.start;
2867 alt {
2868 [] RIM_PCU[dst_pcu_idx].receive(exp_rx) -> value rx{
2869 setverdict(pass);
2870 }
2871 [] any from RIM_PCU.receive(exp_rx) -> @index value rx_idx {
2872 setverdict(fail, "Received RIM on wrong PCU[", rx_idx ,"], expected on PCU[", dst_pcu_idx, "]");
2873 }
2874 [] any from RIM_SGSN.receive(exp_rx) {
2875 setverdict(fail, "Received RIM on SGSN but expected it on other PCU");
2876 }
2877 [] any from RIM_SGSN.receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +01002878 f_shutdown(__FILE__, __LINE__, fail, log2str("Unexpected BSSGP on SGSN side: ", rx));
Harald Weltef86f1852021-01-16 21:56:17 +01002879 }
2880 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +01002881 f_shutdown(__FILE__, __LINE__, fail,
2882 log2str("Timeout waiting for BSSGP on SGSN side: ", exp_rx));
Harald Weltef86f1852021-01-16 21:56:17 +01002883 }
2884 }
2885}
2886
2887
2888type function rim_fn(integer sgsn_idx, integer pcu_idx, integer bvc_idx) runs on GlobalTest_CT;
2889
2890/* helper function for the RIM test cases: Execute 'fn' for each BVC on each PCU for
2891 each SGSN */
2892private function f_rim_iterator(rim_fn fn) runs on GlobalTest_CT
2893{
2894 var integer sgsn_idx, pcu_idx, bvc_idx;
2895 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx+1) {
2896 for (pcu_idx := 0; pcu_idx < lengthof(g_pcu); pcu_idx := pcu_idx+1) {
2897 for (bvc_idx := 0; bvc_idx < lengthof(g_pcu[pcu_idx].cfg.bvc); bvc_idx := bvc_idx+1) {
2898 log("Testing RIM SGSN[", sgsn_idx, "] <-> PCU[", pcu_idx, "][", bvc_idx, "]");
2899 fn.apply(sgsn_idx, pcu_idx, bvc_idx);
2900 }
2901 }
2902 }
2903}
2904
2905/* RAN-INFORMATION-REQUEST */
2906private function f_TC_rim_info_req(integer sgsn_idx, integer pcu_idx, integer bvc_idx := 0)
2907runs on GlobalTest_CT
2908{
2909 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
Philipp Maier14d3a8e2021-01-28 21:43:16 +01002910 var template (value) RAN_Information_Request_RIM_Container cont_tx;
2911 var template RAN_Information_Request_RIM_Container cont_rx;
2912 var template RIM_Routing_Address ra_pcu;
2913 var template RIM_Routing_Address ra_sgsn;
Harald Weltef86f1852021-01-16 21:56:17 +01002914
Philipp Maier14d3a8e2021-01-28 21:43:16 +01002915 ra_pcu := t_RIM_Routing_Address_cid(cell_id);
2916 ra_sgsn := t_RIM_Routing_Address_cid(cell_id_sgsn);
2917
2918 cont_tx := ts_RAN_Information_Request_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
2919 ts_RIM_Sequence_Number(0),
2920 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
2921 cont_rx := tr_RAN_Information_Request_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
2922 tr_RIM_Sequence_Number(0),
2923 tr_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
2924
2925 f_rim_pcu2sgsn(ts_RAN_INFORMATION_REQUEST(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
2926 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
2927 cont := cont_tx),
2928 tr_RAN_INFORMATION_REQUEST(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
2929 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
2930 cont := cont_rx),
2931 pcu_idx);
2932
2933 f_rim_sgsn2pcu(ts_RAN_INFORMATION_REQUEST(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
2934 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
2935 cont := cont_tx),
2936 tr_RAN_INFORMATION_REQUEST(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
2937 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
2938 cont := cont_rx),
Harald Weltef86f1852021-01-16 21:56:17 +01002939 sgsn_idx, pcu_idx);
2940}
2941testcase TC_rim_info_req() runs on GlobalTest_CT
2942{
2943 f_init();
2944 f_global_init();
2945 f_rim_iterator(refers(f_TC_rim_info_req));
2946 f_cleanup();
2947}
2948
2949/* RAN-INFORMATION */
2950private function f_TC_rim_info(integer sgsn_idx, integer pcu_idx, integer bvc_idx := 0)
2951runs on GlobalTest_CT
2952{
2953 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
Philipp Maier14d3a8e2021-01-28 21:43:16 +01002954 var template (value) RAN_Information_RIM_Container cont_tx;
2955 var template RAN_Information_RIM_Container cont_rx;
2956 var template RIM_Routing_Address ra_pcu;
2957 var template RIM_Routing_Address ra_sgsn;
Harald Weltef86f1852021-01-16 21:56:17 +01002958
Philipp Maier14d3a8e2021-01-28 21:43:16 +01002959 ra_pcu := t_RIM_Routing_Address_cid(cell_id);
2960 ra_sgsn := t_RIM_Routing_Address_cid(cell_id_sgsn);
2961
2962 cont_tx := ts_RAN_Information_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
2963 ts_RIM_Sequence_Number(0),
2964 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
2965
2966 cont_rx := tr_RAN_Information_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
2967 tr_RIM_Sequence_Number(0),
2968 tr_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
2969
2970 f_rim_pcu2sgsn(ts_PDU_BSSGP_RAN_INFORMATION(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
2971 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
2972 cont := cont_tx),
2973 tr_PDU_BSSGP_RAN_INFORMATION(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
2974 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
2975 cont := cont_rx),
2976 pcu_idx);
2977
2978 f_rim_sgsn2pcu(ts_PDU_BSSGP_RAN_INFORMATION(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
2979 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
2980 cont := cont_tx),
2981 tr_PDU_BSSGP_RAN_INFORMATION(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
2982 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
2983 cont := cont_rx),
Harald Weltef86f1852021-01-16 21:56:17 +01002984 sgsn_idx, pcu_idx);
2985}
2986testcase TC_rim_info() runs on GlobalTest_CT
2987{
2988 f_init();
2989 f_global_init();
2990 f_rim_iterator(refers(f_TC_rim_info));
2991 f_cleanup();
2992}
2993
2994/* RAN-INFORMATION-ACK */
2995private function f_TC_rim_info_ack(integer sgsn_idx, integer pcu_idx, integer bvc_idx := 0)
2996runs on GlobalTest_CT
2997{
2998 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
Philipp Maier14d3a8e2021-01-28 21:43:16 +01002999 var template (value) RAN_Information_Ack_RIM_Container cont_tx;
3000 var template RAN_Information_Ack_RIM_Container cont_rx;
3001 var template RIM_Routing_Address ra_pcu;
3002 var template RIM_Routing_Address ra_sgsn;
Harald Weltef86f1852021-01-16 21:56:17 +01003003
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003004 ra_pcu := t_RIM_Routing_Address_cid(cell_id);
3005 ra_sgsn := t_RIM_Routing_Address_cid(cell_id_sgsn);
3006
3007 cont_tx := ts_RAN_Information_Ack_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3008 ts_RIM_Sequence_Number(0));
3009
3010 cont_rx := tr_RAN_Information_Ack_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
3011 tr_RIM_Sequence_Number(0));
3012
3013 f_rim_pcu2sgsn(ts_PDU_BSSGP_RAN_INFORMATION_ACK(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3014 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3015 cont := cont_tx),
3016 tr_PDU_BSSGP_RAN_INFORMATION_ACK(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3017 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3018 cont := cont_rx),
3019 pcu_idx);
3020
3021 f_rim_sgsn2pcu(ts_PDU_BSSGP_RAN_INFORMATION_ACK(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3022 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3023 cont := cont_tx),
3024 tr_PDU_BSSGP_RAN_INFORMATION_ACK(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3025 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3026 cont := cont_rx),
Harald Weltef86f1852021-01-16 21:56:17 +01003027 sgsn_idx, pcu_idx);
3028}
3029testcase TC_rim_info_ack() runs on GlobalTest_CT
3030{
3031 f_init();
3032 f_global_init();
3033 f_rim_iterator(refers(f_TC_rim_info_ack));
3034 f_cleanup();
3035}
3036
3037/* RAN-INFORMATION-ERROR */
3038private function f_TC_rim_info_error(integer sgsn_idx, integer pcu_idx, integer bvc_idx := 0)
3039runs on GlobalTest_CT
3040{
3041 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003042 var template (value) RAN_Information_Error_RIM_Container cont_tx;
3043 var template RAN_Information_Error_RIM_Container cont_rx;
3044 var template RIM_Routing_Address ra_pcu;
3045 var template RIM_Routing_Address ra_sgsn;
Harald Weltef86f1852021-01-16 21:56:17 +01003046
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003047 ra_pcu := t_RIM_Routing_Address_cid(cell_id);
3048 ra_sgsn := t_RIM_Routing_Address_cid(cell_id_sgsn);
3049
3050 cont_tx := ts_RAN_Information_Error_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3051 ts_BSSGP_CAUSE(BSSGP_CAUSE_EQUIMENT_FAILURE),
Pau Espin Pedrol6ee01262021-02-05 13:05:06 +01003052 omit, valueof(ts_BVC_UNBLOCK(23)));
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003053
3054 cont_rx := tr_RAN_Information_Error_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
Pau Espin Pedrol6ee01262021-02-05 13:05:06 +01003055 ts_BSSGP_CAUSE(BSSGP_CAUSE_EQUIMENT_FAILURE),
3056 omit, enc_PDU_BSSGP(valueof(tr_BVC_UNBLOCK(23))));
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003057
3058 f_rim_pcu2sgsn(ts_PDU_BSSGP_RAN_INFORMATION_ERROR(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3059 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3060 cont := cont_tx),
3061 tr_PDU_BSSGP_RAN_INFORMATION_ERROR(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3062 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3063 cont := cont_rx),
3064 pcu_idx);
3065
3066 f_rim_sgsn2pcu(ts_PDU_BSSGP_RAN_INFORMATION_ERROR(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3067 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3068 cont := cont_tx),
3069 tr_PDU_BSSGP_RAN_INFORMATION_ERROR(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3070 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3071 cont := cont_rx),
Harald Weltef86f1852021-01-16 21:56:17 +01003072 sgsn_idx, pcu_idx);
3073}
3074testcase TC_rim_info_error() runs on GlobalTest_CT
3075{
3076 f_init();
3077 f_global_init();
3078 f_rim_iterator(refers(f_TC_rim_info_error));
3079 f_cleanup();
3080}
3081
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003082//////////////////
Harald Weltef86f1852021-01-16 21:56:17 +01003083/* RAN-INFORMATION-APPLICATION-ERROR */
3084private function f_TC_rim_info_app_error(integer sgsn_idx, integer pcu_idx, integer bvc_idx := 0)
3085runs on GlobalTest_CT
3086{
3087 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003088 var template (value) Application_Error_Container app_cont_tx;
3089 var template Application_Error_Container app_cont_rx;
3090 var template (value) RAN_Information_Application_Error_RIM_Container cont_tx;
3091 var template RAN_Information_Application_Error_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 app_cont_tx := tsu_Application_Error_Container_NACC(cell_id, 23,
3099 tsu_Application_Container_IE_NACC_req(cell_id));
3100
3101 app_cont_rx := rsu_Application_Error_Container_NACC(cell_id, 23,
3102 rsu_Application_Container_IE_NACC_req(cell_id));
3103
3104 cont_tx := ts_RAN_Information_Application_Error_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3105 ts_RIM_Sequence_Number(0),
3106 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP),
3107 omit, app_cont_tx);
3108 cont_rx := tr_RAN_Information_Application_Error_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
3109 tr_RIM_Sequence_Number(0),
3110 tr_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP),
3111 omit, app_cont_rx);
3112
3113 f_rim_pcu2sgsn(ts_PDU_BSSGP_RAN_INFORMATION_APPLICATION_ERROR(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3114 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3115 cont := cont_tx),
3116 tr_PDU_BSSGP_RAN_INFORMATION_APPLICATION_ERROR(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3117 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3118 cont := cont_rx),
3119 pcu_idx);
3120
3121 f_rim_sgsn2pcu(ts_PDU_BSSGP_RAN_INFORMATION_APPLICATION_ERROR(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3122 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3123 cont := cont_tx),
3124 tr_PDU_BSSGP_RAN_INFORMATION_APPLICATION_ERROR(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3125 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3126 cont := cont_rx),
Harald Weltef86f1852021-01-16 21:56:17 +01003127 sgsn_idx, pcu_idx);
3128}
3129testcase TC_rim_info_app_error() runs on GlobalTest_CT
3130{
3131 f_init();
3132 f_global_init();
3133 f_rim_iterator(refers(f_TC_rim_info_app_error));
3134 f_cleanup();
3135}
3136
3137/* RAN-INFORMATION routing directly between PCUs, without SGSN involvement */
3138private function f_TC_rim_info_pcu2pcu(integer src_pcu_idx, integer src_bvc_idx,
3139 integer dst_pcu_idx, integer dst_bvc_idx)
3140runs on GlobalTest_CT
3141{
3142 var BssgpCellId cell_id_src := g_pcu[src_pcu_idx].cfg.bvc[src_bvc_idx].cell_id;
3143 var BssgpCellId cell_id_dst := g_pcu[dst_pcu_idx].cfg.bvc[dst_bvc_idx].cell_id;
Philipp Maier1bd60ce2021-02-10 18:25:50 +01003144 var template (value) RIM_Routing_Information ri_pcu_src_tx;
3145 var template (value) RIM_Routing_Information ri_pcu_dst_tx;
3146 var template RIM_Routing_Information ri_pcu_src_rx;
3147 var template RIM_Routing_Information ri_pcu_dst_rx;
3148 var template (value) RAN_Information_RIM_Container cont_tx;
3149 var template RAN_Information_RIM_Container cont_rx;
Harald Weltef86f1852021-01-16 21:56:17 +01003150
3151 log("Testing RIM PCU2PCU from PCU[", src_pcu_idx, "][", src_bvc_idx, "] to PCU[",
3152 dst_pcu_idx, "][", dst_bvc_idx, "]");
3153
Philipp Maier1bd60ce2021-02-10 18:25:50 +01003154 ri_pcu_src_tx := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID,
Harald Weltef86f1852021-01-16 21:56:17 +01003155 t_RIM_Routing_Address_cid(cell_id_src));
Philipp Maier1bd60ce2021-02-10 18:25:50 +01003156 ri_pcu_dst_tx := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID,
Harald Weltef86f1852021-01-16 21:56:17 +01003157 t_RIM_Routing_Address_cid(cell_id_dst));
Philipp Maier1bd60ce2021-02-10 18:25:50 +01003158 ri_pcu_src_rx := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID,
3159 t_RIM_Routing_Address_cid(cell_id_src));
3160 ri_pcu_dst_rx := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID,
3161 t_RIM_Routing_Address_cid(cell_id_dst));
3162
3163 cont_tx := ts_RAN_Information_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3164 ts_RIM_Sequence_Number(0),
3165 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
3166 cont_rx := tr_RAN_Information_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
3167 tr_RIM_Sequence_Number(0),
3168 tr_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
3169
3170 f_rim_pcu2pcu(ts_PDU_BSSGP_RAN_INFORMATION(dst := ri_pcu_dst_tx, src := ri_pcu_src_tx, cont := cont_tx),
3171 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 +01003172 src_pcu_idx, dst_pcu_idx);
3173}
3174testcase TC_rim_info_pcu2pcu() runs on GlobalTest_CT
3175{
3176 var integer src_pcu_idx, dst_pcu_idx;
3177 var integer src_bvc_idx, dst_bvc_idx;
3178 f_init();
3179 f_global_init();
3180
3181 for (src_pcu_idx := 0; src_pcu_idx < lengthof(g_pcu); src_pcu_idx := src_pcu_idx + 1) {
3182 for (src_bvc_idx := 0; src_bvc_idx < lengthof(g_pcu[src_pcu_idx].cfg.bvc); src_bvc_idx := src_bvc_idx + 1) {
3183 for (dst_pcu_idx := 0; dst_pcu_idx < lengthof(g_pcu); dst_pcu_idx := dst_pcu_idx + 1) {
3184 if (dst_pcu_idx == src_pcu_idx) {
3185 continue;
3186 }
3187
3188 for (dst_bvc_idx := 0; dst_bvc_idx < lengthof(g_pcu[dst_pcu_idx].cfg.bvc);
3189dst_bvc_idx := dst_bvc_idx + 1) {
3190 f_TC_rim_info_pcu2pcu(src_pcu_idx, src_bvc_idx, dst_pcu_idx, dst_bvc_idx);
3191 }
3192 }
3193 }
3194 }
3195
3196 f_cleanup();
3197}
3198
Harald Welte04358652021-01-17 13:48:13 +01003199/***********************************************************************
3200 * STATUS handling
3201 ***********************************************************************/
3202
3203/* BSSGP STATUS PDU must be routed based on inner "PDU In Error" message */
3204
3205/* generate a TMSI with NRI matching sgsn_idx + nri_idx */
3206private function f_gen_tmsi_for_sgsn_nri(integer sgsn_idx, integer nri_idx) runs on test_CT return OCT4
3207{
3208 var integer nri := mp_sgsn_nri[sgsn_idx][nri_idx];
3209 return f_gen_tmsi(0, nri_v := nri, nri_bitlen := mp_nri_bitlength);
3210}
3211
3212/* generate a TLLI with NRI matching sgsn_idx + nri_idx */
3213private function f_gen_tlli_for_sgsn_nri(integer sgsn_idx, integer nri_idx) runs on test_CT return OCT4
3214{
3215 var OCT4 p_tmsi := f_gen_tmsi_for_sgsn_nri(sgsn_idx, nri_idx);
3216 return f_gprs_tlli_from_tmsi(p_tmsi, TLLI_LOCAL);
3217}
3218
3219/* STATUS in uplink direction; expect routing by its NRI */
3220private function f_TC_status_ul(integer pcu_idx, integer sgsn_idx, PDU_BSSGP inner)
3221runs on GlobalTest_CT
3222{
3223 var template (value) PDU_BSSGP tx := ts_BSSGP_STATUS(omit, BSSGP_CAUSE_EQUIMENT_FAILURE, inner);
3224 var template (present) PDU_BSSGP exp_rx :=
3225 tr_BSSGP_STATUS(omit, BSSGP_CAUSE_EQUIMENT_FAILURE,
3226 tx.pDU_BSSGP_STATUS.pDU_in_Error.erroneous_BSSGP_PDU);
3227
3228 f_global_pcu2sgsn(tx, exp_rx, pcu_idx, sgsn_idx);
3229}
3230
3231/* STATUS in uplink direction; expect routing by its NRI */
3232private function f_TC_status_dl(integer sgsn_idx, integer pcu_idx, PDU_BSSGP inner)
3233runs on GlobalTest_CT
3234{
3235 var template (value) PDU_BSSGP tx := ts_BSSGP_STATUS(omit, BSSGP_CAUSE_EQUIMENT_FAILURE, inner);
3236 var template (present) PDU_BSSGP exp_rx :=
3237 tr_BSSGP_STATUS(omit, BSSGP_CAUSE_EQUIMENT_FAILURE,
3238 tx.pDU_BSSGP_STATUS.pDU_in_Error.erroneous_BSSGP_PDU);
3239
3240 f_global_sgsn2pcu(tx, exp_rx, sgsn_idx, pcu_idx);
3241}
3242
3243/* STATUS in uplink direction on SIG-BVC containing a TLLI; expect routing by its NRI */
3244testcase TC_status_sig_ul_tlli() runs on GlobalTest_CT
3245{
3246 var integer sgsn_idx, nri_idx;
3247
3248 f_init();
3249 f_global_init();
3250
3251 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3252 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx + 1) {
3253 /* some downlink PDU occurring on SIG-BVC with a TLLI */
3254 var OCT4 tlli := f_gen_tlli_for_sgsn_nri(sgsn_idx, nri_idx);
3255 var PDU_BSSGP inner := valueof(ts_BSSGP_FLUSH_LL(tlli, 2342));
3256
3257 f_TC_status_ul(0, sgsn_idx, inner);
3258 }
3259 }
3260
3261 f_cleanup();
3262}
3263
3264/* STATUS in uplink direction on SIG-BVC containing a TMSI; expect routing by its NRI */
3265testcase TC_status_sig_ul_tmsi() runs on GlobalTest_CT
3266{
3267 var integer sgsn_idx, nri_idx;
3268
3269 f_init();
3270 f_global_init();
3271
3272 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3273 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx + 1) {
3274 /* some downlink PDU occurring on SIG-BVC with a TMSI */
3275 const hexstring imsi := '001010123456789'H
3276 var OCT4 tmsi := f_gen_tmsi_for_sgsn_nri(sgsn_idx, nri_idx);
3277 var BssgpBvci bvci := g_pcu[0].cfg.bvc[0].bvci;
3278 var PDU_BSSGP inner := valueof(ts_BSSGP_CS_PAGING_PTMSI(bvci, imsi, oct2int(tmsi)));
3279 f_TC_status_ul(0, sgsn_idx, inner);
3280 }
3281 }
3282
3283 f_cleanup();
3284}
3285
3286
3287/* STATUS in uplink direction on PTP-BVC containing a TLLI; expect routing by its NRI */
3288testcase TC_status_ptp_ul_tlli() runs on GlobalTest_CT
3289{
3290 var integer sgsn_idx, nri_idx;
3291
3292 f_init();
3293 f_global_init_ptp();
3294
3295 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3296 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx + 1) {
3297 /* some downlink PDU occurring on PTP-BVC with a TLLI */
3298 var OCT4 tlli := f_gen_tlli_for_sgsn_nri(sgsn_idx, nri_idx);
3299 var PDU_BSSGP inner := valueof(ts_BSSGP_DL_UD(tlli, '2342'O));
3300
3301 f_TC_status_ul(0, sgsn_idx, inner);
3302 }
3303 }
3304
3305 f_cleanup();
3306}
3307
3308/* STATUS in uplink direction on PTP-BVC containing a TMSI; expect routing by its NRI */
3309testcase TC_status_ptp_ul_tmsi() runs on GlobalTest_CT
3310{
3311 var integer sgsn_idx, nri_idx;
3312
3313 f_init();
3314 f_global_init_ptp();
3315
3316 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3317 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx + 1) {
3318 /* some downlink PDU occurring on PTP-BVC with a TMSI */
3319 const hexstring imsi := '001010123456789'H
3320 var OCT4 tmsi := f_gen_tmsi_for_sgsn_nri(sgsn_idx, nri_idx);
3321 var BssgpBvci bvci := g_pcu[0].cfg.bvc[0].bvci;
3322 var PDU_BSSGP inner := valueof(ts_BSSGP_CS_PAGING_PTMSI(bvci, imsi, oct2int(tmsi)));
3323 f_TC_status_ul(0, sgsn_idx, inner);
3324 }
3325 }
3326
3327 f_cleanup();
3328}
3329
3330/* STATUS in downlink direction in SIG-BVC containing a BVCI; expect routing by it */
3331testcase TC_status_sig_dl_bvci() runs on GlobalTest_CT
3332{
3333 var integer sgsn_idx, pcu_idx, bvc_idx;
3334
3335 f_init();
3336 f_global_init();
3337
3338 /* test each BVC in each PCU from each SGSN */
3339 for (pcu_idx := 0; pcu_idx < lengthof(g_pcu); pcu_idx := pcu_idx + 1) {
3340 for (bvc_idx := 0; bvc_idx < lengthof(g_pcu[pcu_idx].cfg.bvc); bvc_idx := bvc_idx + 1) {
3341 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3342 /* some uplink PDU occurring on SIG-BVC containing a BVCI */
3343 var BssgpBvci bvci := g_pcu[pcu_idx].cfg.bvc[bvc_idx].bvci;
3344 var PDU_BSSGP inner := valueof(ts_BSSGP_LLC_DISCARDED('12345678'O, 1, bvci, 23));
3345 f_TC_status_dl(sgsn_idx, pcu_idx, inner);
3346 }
3347 }
3348 }
3349
3350 f_cleanup();
3351}
3352
3353/* STATUS in downlink direction in PTP-BVC; expect routing by BVCI */
3354testcase TC_status_ptp_dl_bvci() runs on GlobalTest_CT
3355{
3356 var integer sgsn_idx, pcu_idx, bvc_idx;
3357
3358 f_init();
3359 f_global_init_ptp();
3360
3361 /* test each BVC in each PCU from each SGSN */
3362 for (pcu_idx := 0; pcu_idx < lengthof(g_pcu); pcu_idx := pcu_idx + 1) {
3363 for (bvc_idx := 0; bvc_idx < lengthof(g_pcu[pcu_idx].cfg.bvc); bvc_idx := bvc_idx + 1) {
3364 var BssgpBvci bvci := g_pcu[pcu_idx].cfg.bvc[bvc_idx].bvci;
3365 f_global_ptp_connect_pcu_bvci(pcu_idx, bvci);
3366 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3367 f_global_ptp_connect_sgsn_bvci(sgsn_idx, bvci);
3368
3369 /* some uplink PDU occurring on PTP-BVC */
3370 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
3371 var PDU_BSSGP inner := valueof(ts_BSSGP_UL_UD('12345678'O, cell_id, '4223'O));
3372 f_TC_status_dl(sgsn_idx, pcu_idx, inner);
3373 }
3374 }
3375 }
3376
3377 f_cleanup();
3378}
3379
3380/* TODO: test case for DL-STATUS(SUSPEND/RESUME) containing RA-ID; expect routing by RA-ID */
3381/* 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 +01003382
Daniel Willmann423d8f42020-09-08 18:58:22 +02003383control {
3384 execute( TC_BVC_bringup() );
Harald Welte92686012020-11-15 21:45:49 +01003385 execute( TC_ul_unitdata() );
Harald Welte78d8db92020-11-15 23:27:27 +01003386 execute( TC_dl_unitdata() );
Harald Welte6dc2ac42020-11-16 09:16:17 +01003387 execute( TC_ra_capability() );
Daniel Willmannace3ece2020-11-16 19:53:26 +01003388 execute( TC_ra_capability_upd() );
Daniel Willmann165d6612020-11-19 14:27:29 +01003389 execute( TC_radio_status() );
Harald Welte3148a962021-01-17 11:15:28 +01003390 execute( TC_radio_status_tmsi() );
3391 execute( TC_radio_status_imsi() );
Daniel Willmannfa67f492020-11-19 15:48:05 +01003392 execute( TC_suspend() );
Daniel Willmann087a33d2020-11-19 15:58:43 +01003393 execute( TC_resume() );
Harald Weltef8e5c5d2020-11-27 22:37:23 +01003394 execute( TC_trace() );
Harald Weltec0351d12020-11-27 22:49:02 +01003395 execute( TC_llc_discarded() );
Harald Weltef20af412020-11-28 16:11:11 +01003396 execute( TC_overload() );
Harald Welte239aa502020-11-24 23:14:20 +01003397 execute( TC_bvc_block_ptp() );
3398 execute( TC_bvc_unblock_ptp() );
Harald Welte60a8ec72020-11-25 17:12:53 +01003399 execute( TC_bvc_reset_ptp_from_bss() );
Harald Welte16786e92020-11-27 19:11:56 +01003400 execute( TC_bvc_reset_sig_from_bss() );
Harald Welte60a8ec72020-11-25 17:12:53 +01003401 execute( TC_bvc_reset_ptp_from_sgsn() );
Harald Welte16786e92020-11-27 19:11:56 +01003402 execute( TC_bvc_reset_sig_from_sgsn() );
Harald Weltef6e59b02020-12-08 08:29:09 +01003403 if (mp_enable_bss_load_sharing) {
Harald Weltef8ef0282020-11-18 12:16:59 +01003404 /* don't enable this by default, as we don't yet have any automatic test setup for FR with 4 NS-VC */
3405 execute( TC_load_sharing_dl() );
3406 }
Harald Welte0e188242020-11-22 21:46:48 +01003407
3408 /* PAGING-PS over PTP BVC */
3409 execute( TC_paging_ps_ptp_bss() );
3410 execute( TC_paging_ps_ptp_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01003411 execute( TC_paging_ps_ptp_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003412 execute( TC_paging_ps_ptp_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01003413 execute( TC_paging_ps_ptp_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003414 execute( TC_paging_ps_ptp_bvci() );
Harald Welteb5a04aa2021-01-16 13:04:40 +01003415 execute( TC_paging_ps_ptp_bvci_imsi() );
Harald Welte7462a592020-11-23 22:07:07 +01003416 execute( TC_paging_ps_ptp_bvci_unknown() );
Harald Weltecf200072021-01-16 15:20:46 +01003417 execute( TC_paging_ps_reject_ptp_bvci() );
3418 execute( TC_paging_ps_reject_ptp_bvci_imsi() );
Harald Welte7595d562021-01-16 19:09:20 +01003419 execute( TC_dummy_paging_ps_ptp() );
Harald Welte0e188242020-11-22 21:46:48 +01003420
3421 /* PAGING-PS over SIG BVC */
3422 execute( TC_paging_ps_sig_bss() );
3423 execute( TC_paging_ps_sig_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01003424 execute( TC_paging_ps_sig_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003425 execute( TC_paging_ps_sig_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01003426 execute( TC_paging_ps_sig_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003427 execute( TC_paging_ps_sig_bvci() );
Harald Welteb5a04aa2021-01-16 13:04:40 +01003428 execute( TC_paging_ps_sig_bvci_imsi() );
Harald Welte7462a592020-11-23 22:07:07 +01003429 execute( TC_paging_ps_sig_bvci_unknown() );
Harald Weltecf200072021-01-16 15:20:46 +01003430 execute( TC_paging_ps_reject_sig_bvci() );
3431 execute( TC_paging_ps_reject_sig_bvci_imsi() );
Harald Welte7595d562021-01-16 19:09:20 +01003432 execute( TC_dummy_paging_ps_sig() );
Harald Welte0e188242020-11-22 21:46:48 +01003433
3434 /* PAGING-CS over PTP BVC */
3435 execute( TC_paging_cs_ptp_bss() );
3436 execute( TC_paging_cs_ptp_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01003437 execute( TC_paging_cs_ptp_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003438 execute( TC_paging_cs_ptp_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01003439 execute( TC_paging_cs_ptp_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003440 execute( TC_paging_cs_ptp_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01003441 execute( TC_paging_cs_ptp_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003442
3443 /* PAGING-CS over SIG BVC */
3444 execute( TC_paging_cs_sig_bss() );
3445 execute( TC_paging_cs_sig_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01003446 execute( TC_paging_cs_sig_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003447 execute( TC_paging_cs_sig_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01003448 execute( TC_paging_cs_sig_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003449 execute( TC_paging_cs_sig_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01003450 execute( TC_paging_cs_sig_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003451
Harald Weltef86f1852021-01-16 21:56:17 +01003452 /* RAN Information Management */
3453 execute( TC_rim_info_req() );
3454 execute( TC_rim_info() );
3455 execute( TC_rim_info_ack() );
3456 execute( TC_rim_info_error() );
3457 execute( TC_rim_info_app_error() );
3458 execute( TC_rim_info_pcu2pcu() );
3459
Harald Welte0e188242020-11-22 21:46:48 +01003460
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01003461 execute( TC_flush_ll() );
Harald Welte299aa482020-12-09 15:10:55 +01003462 execute( TC_fc_bvc() );
Harald Weltecc3894b2020-12-09 16:50:12 +01003463 execute( TC_fc_ms() );
Harald Welted6f89812021-01-16 18:57:49 +01003464 execute( TC_ms_reg_enq() );
Harald Welte04358652021-01-17 13:48:13 +01003465
3466 /* Uplink STATUS */
3467 execute( TC_status_sig_ul_tlli() );
3468 execute( TC_status_sig_ul_tmsi() );
3469 execute( TC_status_ptp_ul_tlli() );
3470 execute( TC_status_ptp_ul_tmsi() );
3471
3472 /* Downlink STATUS */
3473 execute( TC_status_sig_dl_bvci() );
3474 execute( TC_status_ptp_dl_bvci() );
Daniel Willmann423d8f42020-09-08 18:58:22 +02003475}
3476
3477
3478}