blob: df27a3dfc2eca225d6acc13d28b10758685f1bdb [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 Welteb978ed62020-12-12 14:01:11 +0100328const integer NUM_SGSN := 2;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200329
330type component test_CT {
Harald Welte6d63f742020-11-15 19:44:04 +0100331 var GbInstances g_pcu;
332 var GbInstances g_sgsn;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200333
334 port BSSGP_CT_PROC_PT PROC;
335
Harald Weltefbae83f2020-11-15 23:25:55 +0100336 port BSSGP_BVC_MGMT_PT SGSN_MGMT;
337 port BSSGP_BVC_MGMT_PT PCU_MGMT;
338
Daniel Willmann423d8f42020-09-08 18:58:22 +0200339 port TELNETasp_PT GBPVTY;
340
341 var boolean g_initialized := false;
342 var boolean g_use_echo := false;
Harald Welte16786e92020-11-27 19:11:56 +0100343
344 var ro_integer g_roi := {};
Daniel Willmannc38c85d2021-01-21 18:11:12 +0100345 var roro_integer g_roroi := {};
Harald Welte425d3762020-12-09 14:33:18 +0100346 timer g_Tguard;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200347};
348
349type component BSSGP_ConnHdlr {
Harald Welte3dd21b32020-11-17 19:21:00 +0100350 /* array of per-BVC ports on the PCU side */
Harald Welte158becf2020-12-09 12:32:32 +0100351 port BSSGP_PT PCU_PTP[NUM_PCU];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200352 port BSSGP_PT PCU_SIG[NUM_PCU];
353 port BSSGP_PROC_PT PCU_PROC[NUM_PCU];
Harald Welte3dd21b32020-11-17 19:21:00 +0100354 /* component reference to the component to which we're currently connected */
355 var BSSGP_BVC_CT pcu_ct[NUM_PCU];
Harald Welte0e188242020-11-22 21:46:48 +0100356 /* BSSGP BVC configuration of the component to which we're currently connected */
357 var BssgpBvcConfig pcu_bvc_cfg[NUM_PCU];
Harald Welte3dd21b32020-11-17 19:21:00 +0100358
359 /* array of per-BVC ports on the SGSN side */
Harald Welte158becf2020-12-09 12:32:32 +0100360 port BSSGP_PT SGSN_PTP[NUM_SGSN];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200361 port BSSGP_PT SGSN_SIG[NUM_SGSN];
362 port BSSGP_PROC_PT SGSN_PROC[NUM_SGSN];
Harald Welte3dd21b32020-11-17 19:21:00 +0100363 /* component reference to the component to which we're currently connected */
364 var BSSGP_BVC_CT sgsn_ct[NUM_PCU];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200365
366 var BSSGP_ConnHdlrPars g_pars;
367 timer g_Tguard;
368 var LLC_Entities llc;
Harald Welte0e188242020-11-22 21:46:48 +0100369
370 var ro_integer g_roi := {};
Daniel Willmann423d8f42020-09-08 18:58:22 +0200371}
372
373type record SGSN_ConnHdlrNetworkPars {
374 boolean expect_ptmsi,
375 boolean expect_auth,
376 boolean expect_ciph
377};
378
379type record BSSGP_ConnHdlrPars {
380 /* IMEI of the simulated ME */
381 hexstring imei,
382 /* IMSI of the simulated MS */
383 hexstring imsi,
384 /* MSISDN of the simulated MS (probably unused) */
385 hexstring msisdn,
386 /* P-TMSI allocated to the simulated MS */
387 OCT4 p_tmsi optional,
388 OCT3 p_tmsi_sig optional,
389 /* TLLI of the simulated MS */
390 OCT4 tlli,
391 OCT4 tlli_old optional,
392 RoutingAreaIdentificationV ra optional,
Harald Welte16357a92020-11-17 18:20:00 +0100393 GbInstances pcu,
Harald Welte3dd21b32020-11-17 19:21:00 +0100394 GbInstances sgsn,
Harald Weltec5f486b2021-01-16 11:07:01 +0100395 /* The SGSN index to be used within the test */
396 integer sgsn_idx,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200397 float t_guard
398};
399
Harald Welte04358652021-01-17 13:48:13 +0100400private function get_bvc_idx_for_bvci(GbInstance gbi, BssgpBvci bvci) return integer
401{
402 var integer i;
403
404 for (i := 0; i < lengthof(gbi.cfg.bvc); i := i + 1) {
405 if (gbi.cfg.bvc[i].bvci == bvci) {
406 return i;
407 }
408 }
409 setverdict(fail, "Could not find BVC Index for BVCI ", bvci);
410 return -1;
411}
412
Daniel Willmann423d8f42020-09-08 18:58:22 +0200413private function f_cellid_to_RAI(in BssgpCellId cell_id) return RoutingAreaIdentificationV {
414 /* mcc_mnc is encoded as of 24.008 10.5.5.15 */
415 var BcdMccMnc mcc_mnc := cell_id.ra_id.lai.mcc_mnc;
416
417 var RoutingAreaIdentificationV ret := {
418 mccDigit1 := mcc_mnc[0],
419 mccDigit2 := mcc_mnc[1],
420 mccDigit3 := mcc_mnc[2],
421 mncDigit3 := mcc_mnc[3],
422 mncDigit1 := mcc_mnc[4],
423 mncDigit2 := mcc_mnc[5],
424 lac := int2oct(cell_id.ra_id.lai.lac, 16),
425 rac := int2oct(cell_id.ra_id.rac, 8)
426 }
427 return ret;
428};
429
Harald Welte95339432020-12-02 18:50:52 +0100430private function f_fix_create_cb(inout BssgpConfig cfg)
431{
432 for (var integer i := 0; i < lengthof(cfg.bvc); i := i + 1) {
433 if (not isbound(cfg.bvc[i].create_cb)) {
434 cfg.bvc[i].create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
435 }
436 }
437}
438
Daniel Willmann423d8f42020-09-08 18:58:22 +0200439private function f_init_gb_pcu(inout GbInstance gb, charstring id, integer offset) runs on test_CT {
Harald Welteb419d0e2020-11-16 16:45:05 +0100440 var charstring ns_id := id & "-NS(PCU[" & int2str(offset) & "])";
441 var charstring bssgp_id := id & "-BSSGP(PCU[" & int2str(offset) & "])";
442 gb.vc_NS := NS_CT.create(ns_id);
443 gb.vc_BSSGP := BSSGP_CT.create(bssgp_id);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200444 /* connect lower end of BSSGP emulation with NS upper port */
445 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
446
Harald Welteb419d0e2020-11-16 16:45:05 +0100447 gb.vc_NS.start(NSStart(mp_nsconfig_pcu[offset], ns_id));
448 gb.vc_BSSGP.start(BssgpStart(gb.cfg, bssgp_id));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200449
450 for (var integer i := 0; i < lengthof(gb.cfg.bvc); i := i + 1) {
Harald Welteb978ed62020-12-12 14:01:11 +0100451 /* obtain the component reference of the BSSGP_BVC_CT for each PTP BVC */
Daniel Willmann423d8f42020-09-08 18:58:22 +0200452 connect(self:PROC, gb.vc_BSSGP:PROC);
453 gb.vc_BSSGP_BVC[i] := f_bssgp_get_bvci_ct(gb.cfg.bvc[i].bvci, PROC);
454 disconnect(self:PROC, gb.vc_BSSGP:PROC);
Harald Welteb978ed62020-12-12 14:01:11 +0100455 /* connect all of the per-BVC MGMT ports to our PCU_MGMT port (1:N) */
Harald Weltefbae83f2020-11-15 23:25:55 +0100456 connect(self:PCU_MGMT, gb.vc_BSSGP_BVC[i]:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200457 }
Harald Welteb978ed62020-12-12 14:01:11 +0100458 /* connect all of the BSSGP/NSE global MGMT port to our PCU_MGMT port (1:N) */
Harald Welte16786e92020-11-27 19:11:56 +0100459 connect(self:PCU_MGMT, gb.vc_BSSGP:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200460}
461
462private function f_init_gb_sgsn(inout GbInstance gb, charstring id, integer offset) runs on test_CT {
Harald Welteb419d0e2020-11-16 16:45:05 +0100463 var charstring ns_id := id & "-NS(SGSN[" & int2str(offset) & "])";
464 var charstring bssgp_id := id & "-BSSGP(SGSN[" & int2str(offset) & "])";
465 gb.vc_NS := NS_CT.create(ns_id);
466 gb.vc_BSSGP := BSSGP_CT.create(bssgp_id);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200467 /* connect lower end of BSSGP emulation with NS upper port */
468 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
469
Harald Welteb419d0e2020-11-16 16:45:05 +0100470 gb.vc_NS.start(NSStart(mp_nsconfig_sgsn[offset], ns_id));
471 gb.vc_BSSGP.start(BssgpStart(gb.cfg, bssgp_id));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200472
473 for (var integer i := 0; i < lengthof(gb.cfg.bvc); i := i + 1) {
Harald Welteb978ed62020-12-12 14:01:11 +0100474 /* obtain the component reference of the BSSGP_BVC_CT for each PTP BVC */
Daniel Willmann423d8f42020-09-08 18:58:22 +0200475 connect(self:PROC, gb.vc_BSSGP:PROC);
476 gb.vc_BSSGP_BVC[i] := f_bssgp_get_bvci_ct(gb.cfg.bvc[i].bvci, PROC);
477 disconnect(self:PROC, gb.vc_BSSGP:PROC);
Harald Welteb978ed62020-12-12 14:01:11 +0100478 /* connect all of the per-BVC MGMT ports to our SGSN_MGMT port (1:N) */
Harald Weltefbae83f2020-11-15 23:25:55 +0100479 connect(self:SGSN_MGMT, gb.vc_BSSGP_BVC[i]:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200480 }
Harald Welteb978ed62020-12-12 14:01:11 +0100481 /* connect all of the BSSGP/NSE global MGMT port to our SGSN_MGMT port (1:N) */
Harald Welte16786e92020-11-27 19:11:56 +0100482 connect(self:SGSN_MGMT, gb.vc_BSSGP:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200483}
484
485
Harald Welteb9f0fdc2020-12-09 14:44:50 +0100486private function f_destroy_gb(inout GbInstance gb) runs on test_CT {
487 gb.vc_NS.stop;
488 gb.vc_BSSGP.stop;
489
490 for (var integer i := 0; i < lengthof(gb.cfg.bvc); i := i + 1) {
491 gb.vc_BSSGP_BVC[i].stop;
492 }
493}
494
Daniel Willmann423d8f42020-09-08 18:58:22 +0200495private function f_init_vty() runs on test_CT {
496 map(self:GBPVTY, system:GBPVTY);
497 f_vty_set_prompts(GBPVTY);
498 f_vty_transceive(GBPVTY, "enable");
499}
500
Harald Weltefbae83f2020-11-15 23:25:55 +0100501type record of integer ro_integer;
502
503private function ro_integer_contains(ro_integer r, integer x) return boolean {
504 for (var integer j := 0; j < lengthof(r); j := j+1) {
505 if (r[j] == x) {
506 return true;
507 }
508 }
509 return false;
510}
511
Harald Welteb978ed62020-12-12 14:01:11 +0100512private type record of ro_integer roro_integer;
513
514/* count the number of unblocked BVCI for each SGSN NSE */
515private altstep as_count_unblocked4nse(integer sgsn_idx, inout roro_integer bvci_unblocked)
516runs on test_CT {
517 var BssgpStatusIndication bsi;
518 [] SGSN_MGMT.receive(BssgpStatusIndication:{g_sgsn[sgsn_idx].cfg.nsei, ?, BVC_S_UNBLOCKED}) -> value bsi {
519 bvci_unblocked[sgsn_idx] := bvci_unblocked[sgsn_idx] & { bsi.bvci };
520 /* 'repeat' until sufficient number of BVC-rest has been received on all SGSNs */
521 for (var integer i := 0; i < lengthof(bvci_unblocked); i := i+1) {
522 if (lengthof(bvci_unblocked[i]) < lengthof(g_sgsn[i].cfg.bvc)) {
523 repeat;
524 }
525 }
526 }
527}
528
Harald Welte425d3762020-12-09 14:33:18 +0100529function f_init(float t_guard := 30.0) runs on test_CT {
Harald Welteb978ed62020-12-12 14:01:11 +0100530 var roro_integer bvci_unblocked;
Harald Weltefbae83f2020-11-15 23:25:55 +0100531 var BssgpStatusIndication bsi;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200532 var integer i;
533
534 if (g_initialized == true) {
535 return;
536 }
537 g_initialized := true;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200538
Harald Welte425d3762020-12-09 14:33:18 +0100539 g_Tguard.start(t_guard);
540 activate(as_gTguard(g_Tguard));
541
Harald Welteb978ed62020-12-12 14:01:11 +0100542 var BssgpBvcConfigs bvcs := { };
Harald Welte6d63f742020-11-15 19:44:04 +0100543 for (i := 0; i < lengthof(mp_gbconfigs); i := i+1) {
544 g_pcu[i].cfg := mp_gbconfigs[i];
Harald Welte95339432020-12-02 18:50:52 +0100545 /* make sure all have a proper crate_cb, which cannot be specified in config file */
546 f_fix_create_cb(g_pcu[i].cfg);
Harald Welte6d63f742020-11-15 19:44:04 +0100547 /* concatenate all the PCU-side BVCs for the SGSN side */
Harald Welteb978ed62020-12-12 14:01:11 +0100548 bvcs := bvcs & g_pcu[i].cfg.bvc;
549 }
550
551 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
552 g_sgsn[i].cfg := {
553 nsei := mp_nsconfig_sgsn[i].nsei,
554 sgsn_role := true,
555 bvc := bvcs
556 }
Harald Welte6d63f742020-11-15 19:44:04 +0100557 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200558
559 f_init_vty();
Harald Welte6d63f742020-11-15 19:44:04 +0100560 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
Daniel Willmann443fc572020-11-18 13:26:57 +0100561 f_vty_transceive(GBPVTY, "nsvc nsei " & int2str(g_sgsn[i].cfg.nsei) & " force-unconfigured");
Daniel Willmannad93c052020-12-04 14:14:38 +0100562 }
563 for (i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
564 f_vty_transceive(GBPVTY, "nsvc nsei " & int2str(g_pcu[i].cfg.nsei) & " force-unconfigured");
565 f_vty_transceive(GBPVTY, "delete-gbproxy-peer " & int2str(g_pcu[i].cfg.nsei) & " only-bvc");
566 }
567
568 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
Harald Welteea1ba592020-11-17 18:05:13 +0100569 f_init_gb_sgsn(g_sgsn[i], "GbProxy_Test", i);
Harald Welte6d63f742020-11-15 19:44:04 +0100570 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200571 f_sleep(4.0);
Harald Welte6d63f742020-11-15 19:44:04 +0100572 for (i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
Harald Welteb419d0e2020-11-16 16:45:05 +0100573 f_init_gb_pcu(g_pcu[i], "GbProxy_Test", i);
Harald Welte6d63f742020-11-15 19:44:04 +0100574 }
Harald Weltefbae83f2020-11-15 23:25:55 +0100575
Harald Welteb978ed62020-12-12 14:01:11 +0100576 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
577 bvci_unblocked[i] := {};
578 }
579
Harald Weltefbae83f2020-11-15 23:25:55 +0100580 /* wait until all BVC are unblocked on both sides */
Harald Welted2801272020-11-17 19:22:58 +0100581 timer T := 15.0;
Harald Weltefbae83f2020-11-15 23:25:55 +0100582 T.start;
583 alt {
Harald Welteb978ed62020-12-12 14:01:11 +0100584 /* TODO: We need to add more lines if NUM_SGSN increases. Activating default altsteps
585 * unfortunately doesn't work as we want to access the local variable bvci_unblocked. */
586 [] as_count_unblocked4nse(0, bvci_unblocked);
587 [lengthof(g_sgsn) > 1] as_count_unblocked4nse(1, bvci_unblocked);
Harald Weltefbae83f2020-11-15 23:25:55 +0100588 [] SGSN_MGMT.receive(BssgpStatusIndication:{*, ?, ?}) {
589 repeat;
590 }
Harald Welte3c905152020-11-26 20:56:09 +0100591 [] SGSN_MGMT.receive(BssgpResetIndication:?) {
592 repeat;
593 }
Harald Weltefbae83f2020-11-15 23:25:55 +0100594 [] SGSN_MGMT.receive {
595 setverdict(fail, "Received unexpected message on SGSN_MGMT");
596 mtc.stop;
597 }
598
599 [] PCU_MGMT.receive(BssgpStatusIndication:{*, ?, BVC_S_UNBLOCKED}) -> value bsi {
600 repeat;
601 }
602 [] PCU_MGMT.receive(BssgpStatusIndication:{*, ?, ?}) {
603 repeat;
604 }
605 [] PCU_MGMT.receive(BssgpResetIndication:{0}) {
606 repeat;
607 }
608 [] PCU_MGMT.receive {
609 setverdict(fail, "Received unexpected message on PCU_MGMT");
610 mtc.stop;
611 }
612
613 [] T.timeout {
Harald Welte6929e322020-12-12 13:10:45 +0100614 setverdict(fail, "Timeout waiting for unblock of all BVCs on SGSN side; ",
Harald Welteb978ed62020-12-12 14:01:11 +0100615 "unblocked so far: ", bvci_unblocked);
Harald Welte6929e322020-12-12 13:10:45 +0100616 /* don't stop here but print below analysis */
Harald Weltefbae83f2020-11-15 23:25:55 +0100617 }
618 }
619
Harald Welteb978ed62020-12-12 14:01:11 +0100620 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
621 /* iterate over list and check all BVCI */
622 for (var integer j := 0; j < lengthof(g_sgsn[i].cfg.bvc); j := j+1) {
623 var BssgpBvci bvci := g_sgsn[i].cfg.bvc[j].bvci;
624 if (not ro_integer_contains(bvci_unblocked[i], bvci)) {
625 setverdict(fail, "SGSN ", i, " BVCI=", bvci, " was not unblocked during start-up");
626 mtc.stop;
627 }
Harald Weltefbae83f2020-11-15 23:25:55 +0100628 }
629 }
Harald Welte425d3762020-12-09 14:33:18 +0100630
631 /* re-start guard timer after all BVCs are up, so it only counts the actual test case */
632 g_Tguard.start(t_guard);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200633}
634
635function f_cleanup() runs on test_CT {
Harald Welteb9f0fdc2020-12-09 14:44:50 +0100636 var integer i;
637
Daniel Willmann491af2a2021-01-08 01:32:51 +0100638 /* To avoid a dynamic test case error we need to prevent messages arriving on unconnected
639 * ports. Waiting here ensures that any messages "in flight" will be delivered to the port
640 * before the component is shutdown and disconnected. */
641 f_sleep(0.2);
642
Harald Welteb9f0fdc2020-12-09 14:44:50 +0100643 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
644 f_destroy_gb(g_sgsn[i]);
645 }
646 for (i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
647 f_destroy_gb(g_pcu[i]);
648 }
649
650 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, pass);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200651}
652
653type function void_fn(charstring id) runs on BSSGP_ConnHdlr;
654
655/* helper function to create, connect and start a BSSGP_ConnHdlr component */
Harald Welte207166c2021-01-16 12:52:30 +0100656function f_start_handler(void_fn fn, charstring id, integer imsi_suffix, float t_guard := 30.0,
657 integer sgsn_idx := 0, integer nri_idx := 0, boolean have_ptmsi := true)
Daniel Willmann423d8f42020-09-08 18:58:22 +0200658runs on test_CT return BSSGP_ConnHdlr {
659 var BSSGP_ConnHdlr vc_conn;
Harald Weltec5f486b2021-01-16 11:07:01 +0100660 var integer nri := mp_sgsn_nri[sgsn_idx][nri_idx];
Harald Welte77218d02021-01-15 19:59:15 +0100661 var OCT4 p_tmsi := f_gen_tmsi(imsi_suffix, nri_v := nri, nri_bitlen := mp_nri_bitlength);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200662
663 var BSSGP_ConnHdlrPars pars := {
664 imei := f_gen_imei(imsi_suffix),
665 imsi := f_gen_imsi(imsi_suffix),
666 msisdn := f_gen_msisdn(imsi_suffix),
Harald Weltedbd5e672021-01-14 21:03:14 +0100667 p_tmsi := p_tmsi,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200668 p_tmsi_sig := omit,
Harald Weltedbd5e672021-01-14 21:03:14 +0100669 tlli := f_gprs_tlli_from_tmsi(p_tmsi, TLLI_LOCAL),
Daniel Willmann423d8f42020-09-08 18:58:22 +0200670 tlli_old := omit,
671 ra := omit,
Harald Welte2ecbca82021-01-16 11:23:09 +0100672 pcu := g_pcu,
673 sgsn := g_sgsn,
Harald Weltec5f486b2021-01-16 11:07:01 +0100674 sgsn_idx := sgsn_idx,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200675 t_guard := t_guard
676 };
Harald Welte207166c2021-01-16 12:52:30 +0100677 if (not have_ptmsi) {
678 pars.p_tmsi := omit;
679 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200680
681 vc_conn := BSSGP_ConnHdlr.create(id);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200682
Harald Welte25a04b12021-01-17 11:09:49 +0100683 log("Starting ", id, " for SGSN[", sgsn_idx, "], NRI=", nri, ", P-TMSI=", pars.p_tmsi,
684 ", TLLI=", pars.tlli, ", IMSI=", pars.imsi, " on component=", vc_conn);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200685 vc_conn.start(f_handler_init(fn, id, pars));
686 return vc_conn;
687}
688
Harald Welte207166c2021-01-16 12:52:30 +0100689function f_start_handlers(void_fn fn, charstring id, integer imsi_suffix, float t_guard := 30.0,
690 boolean have_ptmsi := true)
Harald Weltec5f486b2021-01-16 11:07:01 +0100691runs on test_CT
692{
693 var integer sgsn_idx, nri_idx;
694 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx:=sgsn_idx+1) {
695 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx:=nri_idx+1) {
696 var integer extd_imsi_suffix := 1000*sgsn_idx + 100*nri_idx;
697 var BSSGP_ConnHdlr vc_conn;
Harald Welte207166c2021-01-16 12:52:30 +0100698 vc_conn := f_start_handler(fn, id, extd_imsi_suffix, t_guard, sgsn_idx, nri_idx,
699 have_ptmsi);
Harald Weltec5f486b2021-01-16 11:07:01 +0100700 /* Idea: we could also run them in parallel ? */
701 vc_conn.done;
702 }
703 }
704}
705
Harald Welte3dd21b32020-11-17 19:21:00 +0100706/* 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 +0100707private function f_connect_to_pcu_bvc(integer port_idx, integer nse_idx, integer bvc_idx)
708runs on BSSGP_ConnHdlr {
709 var BSSGP_BVC_CT bvc_ct := g_pars.pcu[nse_idx].vc_BSSGP_BVC[bvc_idx]
Harald Welte158becf2020-12-09 12:32:32 +0100710 if (PCU_PTP[port_idx].checkstate("Connected")) {
Harald Welte3dd21b32020-11-17 19:21:00 +0100711 /* unregister + disconnect from old BVC */
712 f_client_unregister(g_pars.imsi, PCU_PROC[port_idx]);
Harald Welte158becf2020-12-09 12:32:32 +0100713 disconnect(self:PCU_PTP[port_idx], pcu_ct[port_idx]:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100714 disconnect(self:PCU_SIG[port_idx], pcu_ct[port_idx]:BSSGP_SP_SIG);
715 disconnect(self:PCU_PROC[port_idx], pcu_ct[port_idx]:BSSGP_PROC);
716 }
717 /* connect to new BVC and register us */
Harald Welte158becf2020-12-09 12:32:32 +0100718 connect(self:PCU_PTP[port_idx], bvc_ct:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100719 connect(self:PCU_SIG[port_idx], bvc_ct:BSSGP_SP_SIG);
720 connect(self:PCU_PROC[port_idx], bvc_ct:BSSGP_PROC);
721 f_client_register(g_pars.imsi, g_pars.tlli, PCU_PROC[port_idx]);
722 pcu_ct[port_idx] := bvc_ct;
Harald Welte0e188242020-11-22 21:46:48 +0100723 pcu_bvc_cfg[port_idx] := g_pars.pcu[nse_idx].cfg.bvc[bvc_idx];
Harald Welte3dd21b32020-11-17 19:21:00 +0100724}
725
726/* Connect the SGSN-side per-BVC ports (SGSN/SGSN_SIG/SGSN_PROC) array slot 'port_idx' to specified per-BVC component */
727private 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 +0100728 if (SGSN_PTP[port_idx].checkstate("Connected")) {
Harald Welte3dd21b32020-11-17 19:21:00 +0100729 /* unregister + disconnect from old BVC */
730 f_client_unregister(g_pars.imsi, SGSN_PROC[port_idx]);
Harald Welte158becf2020-12-09 12:32:32 +0100731 disconnect(self:SGSN_PTP[port_idx], sgsn_ct[port_idx]:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100732 disconnect(self:SGSN_SIG[port_idx], sgsn_ct[port_idx]:BSSGP_SP_SIG);
733 disconnect(self:SGSN_PROC[port_idx], sgsn_ct[port_idx]:BSSGP_PROC);
734 }
735 /* connect to new BVC and register us */
Harald Welte158becf2020-12-09 12:32:32 +0100736 connect(self:SGSN_PTP[port_idx], bvc_ct:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100737 connect(self:SGSN_SIG[port_idx], bvc_ct:BSSGP_SP_SIG);
738 connect(self:SGSN_PROC[port_idx], bvc_ct:BSSGP_PROC);
739 f_client_register(g_pars.imsi, g_pars.tlli, SGSN_PROC[port_idx]);
740 sgsn_ct[port_idx] := bvc_ct;
741}
742
Harald Welte425d3762020-12-09 14:33:18 +0100743private altstep as_gTguard(timer Tguard) {
744 [] Tguard.timeout {
Daniel Willmann423d8f42020-09-08 18:58:22 +0200745 setverdict(fail, "Tguard timeout");
746 mtc.stop;
747 }
748}
749
750/* first function called in every ConnHdlr */
751private function f_handler_init(void_fn fn, charstring id, BSSGP_ConnHdlrPars pars)
752runs on BSSGP_ConnHdlr {
Harald Welte1e834f32020-11-15 20:02:59 +0100753 var integer i;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200754 /* do some common stuff like setting up g_pars */
755 g_pars := pars;
756
757 llc := f_llc_create(false);
758
Harald Welte3dd21b32020-11-17 19:21:00 +0100759 /* default connections on PCU side: First BVC of each NSE/PCU */
760 for (i := 0; i < lengthof(g_pars.pcu); i := i+1) {
Harald Welte0e188242020-11-22 21:46:48 +0100761 f_connect_to_pcu_bvc(port_idx := i, nse_idx := i, bvc_idx := 0);
Harald Welte1e834f32020-11-15 20:02:59 +0100762 }
Harald Welte3dd21b32020-11-17 19:21:00 +0100763
764 /* default connections on SGSN side: First BVC of each NSE/SGSN */
765 for (i := 0; i < lengthof(g_pars.sgsn); i := i+1) {
766 f_connect_to_sgsn_bvc(i, g_pars.sgsn[i].vc_BSSGP_BVC[0]);
Harald Welte1e834f32020-11-15 20:02:59 +0100767 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200768
769 g_Tguard.start(pars.t_guard);
Harald Welte425d3762020-12-09 14:33:18 +0100770 activate(as_gTguard(g_Tguard));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200771
772 /* call the user-supplied test case function */
773 fn.apply(id);
Harald Welteb33fb592021-01-16 12:50:56 +0100774
775 for (i := 0; i < NUM_SGSN; i := i+1) {
776 if (SGSN_PROC[i].checkstate("Connected")) {
777 f_client_unregister(g_pars.imsi, SGSN_PROC[i])
778 }
779 }
780
781 for (i := 0; i < NUM_PCU; i := i+1) {
782 if (PCU_PROC[i].checkstate("Connected")) {
783 f_client_unregister(g_pars.imsi, PCU_PROC[i])
784 }
785 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200786}
787
Harald Welte1e834f32020-11-15 20:02:59 +0100788private function f_client_register(hexstring imsi, OCT4 tlli, BSSGP_PROC_PT PT)
789runs on BSSGP_ConnHdlr {
790 PT.call(BSSGP_register_client:{imsi, tlli}) {
791 [] PT.getreply(BSSGP_register_client:{imsi, tlli}) {};
792 }
793}
794
795private function f_client_unregister(hexstring imsi, BSSGP_PROC_PT PT)
796runs on BSSGP_ConnHdlr {
797 PT.call(BSSGP_unregister_client:{imsi}) {
798 [] PT.getreply(BSSGP_unregister_client:{imsi}) {};
799 }
800}
801
Harald Welte22ef5d92020-11-16 13:35:14 +0100802/* Send 'tx' on PTP-BVCI from PCU; expect 'rx' on SGSN */
803friend function f_pcu2sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
Harald Weltec5f486b2021-01-16 11:07:01 +0100804 integer pcu_idx := 0, boolean use_sig := false) runs on BSSGP_ConnHdlr {
805 var integer sgsn_idx := g_pars.sgsn_idx;
Harald Welte22ef5d92020-11-16 13:35:14 +0100806 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +0100807 timer T := 2.0;
Harald Welte22ef5d92020-11-16 13:35:14 +0100808
Daniel Willmann4798fd72020-11-24 16:23:29 +0100809 if (use_sig) {
810 PCU_SIG[pcu_idx].send(tx);
811 } else {
Harald Welte158becf2020-12-09 12:32:32 +0100812 PCU_PTP[pcu_idx].send(tx);
Daniel Willmann4798fd72020-11-24 16:23:29 +0100813 }
814
Harald Welte22ef5d92020-11-16 13:35:14 +0100815 T.start;
816 alt {
Daniel Willmann4798fd72020-11-24 16:23:29 +0100817 [use_sig] SGSN_SIG[sgsn_idx].receive(exp_rx) {
818 setverdict(pass);
819 }
Harald Welte158becf2020-12-09 12:32:32 +0100820 [not use_sig] SGSN_PTP[sgsn_idx].receive(exp_rx) {
Harald Welte22ef5d92020-11-16 13:35:14 +0100821 setverdict(pass);
822 }
Harald Welte158becf2020-12-09 12:32:32 +0100823 [] SGSN_PTP[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Weltec5f486b2021-01-16 11:07:01 +0100824 setverdict(fail, "Unexpected BSSGP on SGSN[", sgsn_idx, "] side: ", rx);
Harald Welte22ef5d92020-11-16 13:35:14 +0100825 mtc.stop;
826 }
Daniel Willmann4798fd72020-11-24 16:23:29 +0100827 [] SGSN_SIG[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Weltec5f486b2021-01-16 11:07:01 +0100828 setverdict(fail, "Unexpected SIG BSSGP on SGSN[", sgsn_idx, "] side: ", rx);
Daniel Willmann4798fd72020-11-24 16:23:29 +0100829 mtc.stop;
830 }
Harald Welte22ef5d92020-11-16 13:35:14 +0100831 [] T.timeout {
Harald Weltec5f486b2021-01-16 11:07:01 +0100832 setverdict(fail, "Timeout waiting for BSSGP on SGSN[", sgsn_idx, "] side: ", exp_rx);
Harald Welte22ef5d92020-11-16 13:35:14 +0100833 mtc.stop;
834 }
835 }
836}
837
Harald Welte3148a962021-01-17 11:15:28 +0100838/* Send 'tx' from PCU; expect 'exp_rx' on _any_ SGSN */
839friend function f_pcu2any_sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
840 integer pcu_idx := 0, boolean use_sig := false)
841runs on BSSGP_ConnHdlr return integer {
842 var integer rx_idx := -1;
843 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +0100844 timer T := 2.0;
Harald Welte3148a962021-01-17 11:15:28 +0100845
846 if (use_sig) {
847 PCU_SIG[pcu_idx].send(tx);
848 } else {
849 PCU_PTP[pcu_idx].send(tx);
850 }
851
852 T.start;
853 alt {
854 [use_sig] any from SGSN_SIG.receive(exp_rx) -> @index value rx_idx {
855 setverdict(pass);
856 }
857 [not use_sig] any from SGSN_PTP.receive(exp_rx) -> @index value rx_idx {
858 setverdict(pass);
859 }
860 [] any from SGSN_PTP.receive(PDU_BSSGP:?) -> value rx @index value rx_idx {
861 setverdict(fail, "Unexpected BSSGP on SGSN[", rx_idx, "] side: ", rx);
862 mtc.stop;
863 }
864 [] any from SGSN_SIG.receive(PDU_BSSGP:?) -> value rx @index value rx_idx {
865 setverdict(fail, "Unexpected SIG BSSGP on SGSN[", rx_idx, "] side: ", rx);
866 mtc.stop;
867 }
868 [] T.timeout {
869 setverdict(fail, "Timeout waiting for BSSGP on SGSN side: ", exp_rx);
870 mtc.stop;
871 }
872 }
873 return rx_idx;
874}
875
Harald Welte22ef5d92020-11-16 13:35:14 +0100876/* Send 'tx' on PTP-BVCI from SGSN; expect 'rx' on PCU */
877friend function f_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
Harald Weltec5f486b2021-01-16 11:07:01 +0100878 integer pcu_idx := 0, boolean use_sig := false) runs on BSSGP_ConnHdlr {
879 var integer sgsn_idx := g_pars.sgsn_idx;
Harald Welte22ef5d92020-11-16 13:35:14 +0100880 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +0100881 timer T := 2.0;
Harald Welte22ef5d92020-11-16 13:35:14 +0100882
Daniel Willmann4798fd72020-11-24 16:23:29 +0100883 if (use_sig) {
884 SGSN_SIG[sgsn_idx].send(tx);
885 } else {
Harald Welte158becf2020-12-09 12:32:32 +0100886 SGSN_PTP[sgsn_idx].send(tx);
Daniel Willmann4798fd72020-11-24 16:23:29 +0100887 }
888
Harald Welte22ef5d92020-11-16 13:35:14 +0100889 T.start;
890 alt {
Daniel Willmann4798fd72020-11-24 16:23:29 +0100891 [use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
892 setverdict(pass);
893 }
Harald Welte158becf2020-12-09 12:32:32 +0100894 [not use_sig] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte22ef5d92020-11-16 13:35:14 +0100895 setverdict(pass);
896 }
Harald Welte158becf2020-12-09 12:32:32 +0100897 [] PCU_PTP[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welte22ef5d92020-11-16 13:35:14 +0100898 setverdict(fail, "Unexpected BSSGP on PCU side: ", rx);
899 mtc.stop;
900 }
Daniel Willmann4798fd72020-11-24 16:23:29 +0100901 [] PCU_SIG[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
902 setverdict(fail, "Unexpected SIG BSSGP on PCU side: ", rx);
903 mtc.stop;
904 }
Harald Welte22ef5d92020-11-16 13:35:14 +0100905 [] T.timeout {
Harald Welte8b326412020-11-29 16:05:38 +0100906 setverdict(fail, "Timeout waiting for BSSGP on PCU side: ", exp_rx);
Harald Welte22ef5d92020-11-16 13:35:14 +0100907 mtc.stop;
908 }
909 }
910}
Harald Welte1e834f32020-11-15 20:02:59 +0100911
Harald Welte3807ed12020-11-24 19:05:22 +0100912/***********************************************************************
913 * GlobaLTest_CT: Using the per-NSE GLOBAL ports on PCU + SGSN side
914 ***********************************************************************/
915
916type component GlobalTest_CT extends test_CT {
917 port BSSGP_PT G_PCU[NUM_PCU];
Harald Welte04358652021-01-17 13:48:13 +0100918 var integer g_pcu_idx[NUM_PCU]; /* BVC index currently connected to G_PCU */
Harald Welte3807ed12020-11-24 19:05:22 +0100919 port BSSGP_PT G_SGSN[NUM_SGSN];
Harald Welte04358652021-01-17 13:48:13 +0100920 var integer g_sgsn_idx[NUM_SGSN]; /* BVC index currently connected to G_SGSN */
Harald Weltef86f1852021-01-16 21:56:17 +0100921 port BSSGP_PT RIM_PCU[NUM_PCU];
922 port BSSGP_PT RIM_SGSN[NUM_SGSN];
Harald Welte3807ed12020-11-24 19:05:22 +0100923};
924
Harald Welte299aa482020-12-09 15:10:55 +0100925/* connect the signaling BVC of each NSE to the G_PCU / G_SGSN ports */
Harald Welte3807ed12020-11-24 19:05:22 +0100926private function f_global_init() runs on GlobalTest_CT {
927 var integer i;
928 for (i := 0; i < lengthof(g_sgsn); i := i+1) {
929 connect(self:G_SGSN[i], g_sgsn[i].vc_BSSGP:GLOBAL);
Harald Weltef86f1852021-01-16 21:56:17 +0100930 connect(self:RIM_SGSN[i], g_sgsn[i].vc_BSSGP:RIM);
Harald Welte3807ed12020-11-24 19:05:22 +0100931 }
932 for (i := 0; i < lengthof(g_pcu); i := i+1) {
933 connect(self:G_PCU[i], g_pcu[i].vc_BSSGP:GLOBAL);
Harald Weltef86f1852021-01-16 21:56:17 +0100934 connect(self:RIM_PCU[i], g_pcu[i].vc_BSSGP:RIM);
Harald Welte3807ed12020-11-24 19:05:22 +0100935 }
936}
937
Harald Welte299aa482020-12-09 15:10:55 +0100938/* connect the first PTP BVC of each NSE to the G_PCU / G_SGSN ports */
939private function f_global_init_ptp() runs on GlobalTest_CT {
940 var integer i;
941 for (i := 0; i < lengthof(g_sgsn); i := i+1) {
Harald Welte04358652021-01-17 13:48:13 +0100942 log("Connecting G_SGSN[", i, "] to BVCI=", g_sgsn[i].cfg.bvc[0].bvci);
Harald Welte299aa482020-12-09 15:10:55 +0100943 connect(self:G_SGSN[i], g_sgsn[i].vc_BSSGP_BVC[0]:GLOBAL);
Harald Welte04358652021-01-17 13:48:13 +0100944 g_sgsn_idx[i] := 0;
Harald Welte299aa482020-12-09 15:10:55 +0100945 }
946 for (i := 0; i < lengthof(g_pcu); i := i+1) {
Harald Welte04358652021-01-17 13:48:13 +0100947 log("Connecting G_PCU[", i, "] to BVCI=", g_pcu[i].cfg.bvc[0].bvci);
Harald Welte299aa482020-12-09 15:10:55 +0100948 connect(self:G_PCU[i], g_pcu[i].vc_BSSGP_BVC[0]:GLOBAL);
Harald Welte04358652021-01-17 13:48:13 +0100949 g_pcu_idx[i] := 0;
Harald Welte299aa482020-12-09 15:10:55 +0100950 }
951}
952
Harald Welte04358652021-01-17 13:48:13 +0100953/* (re)connect G_SGSN[sgsn_idx] to a specific PTP BVCI */
954private function f_global_ptp_connect_sgsn_bvci(integer sgsn_idx, BssgpBvci bvci) runs on GlobalTest_CT
955{
956 var integer sgsn_bvc_idx := get_bvc_idx_for_bvci(g_sgsn[sgsn_idx], bvci);
957 var integer old_sgsn_bvc_idx := g_sgsn_idx[sgsn_idx];
958 disconnect(self:G_SGSN[sgsn_idx], g_sgsn[sgsn_idx].vc_BSSGP_BVC[old_sgsn_bvc_idx]:GLOBAL);
959 connect(self:G_SGSN[sgsn_idx], g_sgsn[sgsn_idx].vc_BSSGP_BVC[sgsn_bvc_idx]:GLOBAL);
960 g_sgsn_idx[sgsn_idx] := sgsn_bvc_idx;
961}
962
963/* (re)connect G_PCU[pcu_idx] to a specific PTP BVCI */
964private function f_global_ptp_connect_pcu_bvci(integer pcu_idx, BssgpBvci bvci) runs on GlobalTest_CT
965{
966 var integer pcu_bvc_idx := get_bvc_idx_for_bvci(g_pcu[pcu_idx], bvci);
967 var integer old_pcu_bvc_idx := g_pcu_idx[pcu_idx];
968 disconnect(self:G_PCU[pcu_idx], g_pcu[pcu_idx].vc_BSSGP_BVC[old_pcu_bvc_idx]:GLOBAL);
969 connect(self:G_PCU[pcu_idx], g_pcu[pcu_idx].vc_BSSGP_BVC[pcu_bvc_idx]:GLOBAL);
970 g_pcu_idx[pcu_idx] := pcu_bvc_idx;
971}
972
Harald Welte3807ed12020-11-24 19:05:22 +0100973/* Send 'tx' on PTP-BVCI from PCU; expect 'rx' on SGSN */
974friend function f_global_pcu2sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
975 integer pcu_idx := 0, integer sgsn_idx := 0) runs on GlobalTest_CT {
Harald Welte04358652021-01-17 13:48:13 +0100976 var integer rx_idx;
Harald Welte3807ed12020-11-24 19:05:22 +0100977 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +0100978 timer T := 2.0;
Harald Welte3807ed12020-11-24 19:05:22 +0100979
980 G_PCU[pcu_idx].send(tx);
981 T.start;
982 alt {
983 [] G_SGSN[sgsn_idx].receive(exp_rx) {
984 setverdict(pass);
985 }
Harald Welte04358652021-01-17 13:48:13 +0100986 [] any from G_SGSN.receive(exp_rx) -> @index value rx_idx {
987 setverdict(fail, "BSSGP arrived on wrong SGSN[", rx_idx, "] instead of SGSN[", sgsn_idx, "]");
988 }
Harald Welte3807ed12020-11-24 19:05:22 +0100989 [] G_SGSN[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
990 setverdict(fail, "Unexpected BSSGP on SGSN side: ", rx);
991 mtc.stop;
992 }
993 [] T.timeout {
Harald Weltedc805c02020-12-11 10:59:17 +0100994 setverdict(fail, "Timeout waiting for BSSGP on SGSN side: ", exp_rx);
Harald Welte3807ed12020-11-24 19:05:22 +0100995 mtc.stop;
996 }
997 }
998}
999
1000/* Send 'tx' on PTP-BVCI from SGSN; expect 'rx' on PCU */
1001friend function f_global_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
1002 integer sgsn_idx := 0, integer pcu_idx := 0) runs on GlobalTest_CT {
Harald Welte04358652021-01-17 13:48:13 +01001003 var integer rx_idx;
Harald Welte3807ed12020-11-24 19:05:22 +01001004 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +01001005 timer T := 2.0;
Harald Welte3807ed12020-11-24 19:05:22 +01001006
1007 G_SGSN[sgsn_idx].send(tx);
1008 T.start;
1009 alt {
1010 [] G_PCU[pcu_idx].receive(exp_rx) {
1011 setverdict(pass);
1012 }
Harald Welte04358652021-01-17 13:48:13 +01001013 [] any from G_PCU.receive(exp_rx) -> @index value rx_idx {
1014 setverdict(fail, "BSSGP arrived on wrong PCU[", rx_idx, "] instead of PCU[", pcu_idx, "]");
1015 }
Harald Welte3807ed12020-11-24 19:05:22 +01001016 [] G_PCU[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
1017 setverdict(fail, "Unexpected BSSGP on PCU side: ", rx);
1018 mtc.stop;
1019 }
1020 [] T.timeout {
Harald Weltedc805c02020-12-11 10:59:17 +01001021 setverdict(fail, "Timeout waiting for BSSGP on PCU side: ", exp_rx);
Harald Welte3807ed12020-11-24 19:05:22 +01001022 mtc.stop;
1023 }
1024 }
1025}
1026
1027
Daniel Willmann423d8f42020-09-08 18:58:22 +02001028/* TODO:
1029 * Detach without Attach
1030 * SM procedures without attach / RAU
1031 * ATTACH / RAU
1032 ** with / without authentication
1033 ** with / without P-TMSI allocation
1034 * re-transmissions of LLC frames
1035 * PDP Context activation
1036 ** with different GGSN config in SGSN VTY
1037 ** with different PDP context type (v4/v6/v46)
1038 ** timeout from GGSN
1039 ** multiple / secondary PDP context
1040 */
1041
1042private function f_TC_BVC_bringup(charstring id) runs on BSSGP_ConnHdlr {
1043 f_sleep(5.0);
1044 setverdict(pass);
1045}
1046
1047testcase TC_BVC_bringup() runs on test_CT {
Daniel Willmann423d8f42020-09-08 18:58:22 +02001048 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001049 f_start_handlers(refers(f_TC_BVC_bringup), testcasename(), 51);
Daniel Willmann423d8f42020-09-08 18:58:22 +02001050 f_cleanup();
1051}
1052
1053friend function f_bssgp_suspend(integer ran_idx := 0) runs on BSSGP_ConnHdlr return OCT1 {
Harald Welte16357a92020-11-17 18:20:00 +01001054 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Daniel Willmann423d8f42020-09-08 18:58:22 +02001055 timer T := 5.0;
1056 var PDU_BSSGP rx_pdu;
Harald Welte16357a92020-11-17 18:20:00 +01001057 PCU_SIG[ran_idx].send(ts_BSSGP_SUSPEND(g_pars.tlli, bvcc.cell_id.ra_id));
Daniel Willmann423d8f42020-09-08 18:58:22 +02001058 T.start;
1059 alt {
Harald Welte16357a92020-11-17 18:20:00 +01001060 [] 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 +02001061 return rx_pdu.pDU_BSSGP_SUSPEND_ACK.suspend_Reference_Number.suspend_Reference_Number_value;
1062 }
Harald Welte16357a92020-11-17 18:20:00 +01001063 [] PCU_SIG[ran_idx].receive(tr_BSSGP_SUSPEND_NACK(g_pars.tlli, bvcc.cell_id.ra_id, ?)) -> value rx_pdu {
Daniel Willmann423d8f42020-09-08 18:58:22 +02001064 setverdict(fail, "SUSPEND-NACK in response to SUSPEND for TLLI ", g_pars.tlli);
1065 mtc.stop;
1066 }
1067 [] T.timeout {
1068 setverdict(fail, "No SUSPEND-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
1069 mtc.stop;
1070 }
1071 }
1072 return '00'O;
1073}
1074
1075friend function f_bssgp_resume(OCT1 susp_ref, integer ran_idx := 0) runs on BSSGP_ConnHdlr {
Harald Welte16357a92020-11-17 18:20:00 +01001076 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Daniel Willmann423d8f42020-09-08 18:58:22 +02001077 timer T := 5.0;
Harald Welte16357a92020-11-17 18:20:00 +01001078 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 +02001079 T.start;
1080 alt {
Harald Welte16357a92020-11-17 18:20:00 +01001081 [] PCU_SIG[ran_idx].receive(tr_BSSGP_RESUME_ACK(g_pars.tlli, bvcc.cell_id.ra_id));
1082 [] PCU_SIG[ran_idx].receive(tr_BSSGP_RESUME_NACK(g_pars.tlli, bvcc.cell_id.ra_id, ?)) {
Daniel Willmann423d8f42020-09-08 18:58:22 +02001083 setverdict(fail, "RESUME-NACK in response to RESUME for TLLI ", g_pars.tlli);
1084 mtc.stop;
1085 }
1086 [] T.timeout {
1087 setverdict(fail, "No RESUME-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
1088 mtc.stop;
1089 }
1090 }
1091}
1092
1093
Harald Welte92686012020-11-15 21:45:49 +01001094/* send uplink-unitdata of a variety of different sizes; expect it to show up on SGSN */
1095private function f_TC_ul_unitdata(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte16357a92020-11-17 18:20:00 +01001096 var integer ran_idx := 0;
1097 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Harald Welte92686012020-11-15 21:45:49 +01001098 var integer i;
1099
Harald Welte0d5fceb2020-11-29 16:04:07 +01001100 for (i := 0; i < max_fr_info_size-4; i := i+4) {
Harald Welte92686012020-11-15 21:45:49 +01001101 var octetstring payload := f_rnd_octstring(i);
Harald Welte16357a92020-11-17 18:20:00 +01001102 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 +01001103 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte16357a92020-11-17 18:20:00 +01001104 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 +01001105
Harald Welte0d5fceb2020-11-29 16:04:07 +01001106 log("UL-UNITDATA(payload_size=", i);
Harald Welte22ef5d92020-11-16 13:35:14 +01001107 f_pcu2sgsn(pdu_tx, pdu_rx);
Harald Welte92686012020-11-15 21:45:49 +01001108 }
1109 setverdict(pass);
1110}
1111
1112testcase TC_ul_unitdata() runs on test_CT
1113{
Harald Welte92686012020-11-15 21:45:49 +01001114 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001115 f_start_handlers(refers(f_TC_ul_unitdata), testcasename(), 1);
Harald Welte92686012020-11-15 21:45:49 +01001116 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Welte92686012020-11-15 21:45:49 +01001117 f_cleanup();
1118}
1119
Harald Welte78d8db92020-11-15 23:27:27 +01001120/* send downlink-unitdata of a variety of different sizes; expect it to show up on PCU */
1121private function f_TC_dl_unitdata(charstring id) runs on BSSGP_ConnHdlr {
1122 var integer i;
1123
Harald Welte0d5fceb2020-11-29 16:04:07 +01001124 for (i := 0; i < max_fr_info_size-4; i := i+4) {
Harald Welte78d8db92020-11-15 23:27:27 +01001125 var octetstring payload := f_rnd_octstring(i);
1126 var template (value) PDU_BSSGP pdu_tx :=
1127 ts_BSSGP_DL_UD(g_pars.tlli, payload, omit, ts_BSSGP_IMSI(g_pars.imsi));
1128 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1129 var template (present) PDU_BSSGP pdu_rx :=
1130 tr_BSSGP_DL_UD(g_pars.tlli, payload, tr_BSSGP_IMSI(g_pars.imsi));
1131
Harald Welte0d5fceb2020-11-29 16:04:07 +01001132 log("DL-UNITDATA(payload_size=", i);
Harald Welte22ef5d92020-11-16 13:35:14 +01001133 f_sgsn2pcu(pdu_tx, pdu_rx);
Harald Welte78d8db92020-11-15 23:27:27 +01001134 }
1135 setverdict(pass);
1136}
1137
1138testcase TC_dl_unitdata() runs on test_CT
1139{
Harald Welte78d8db92020-11-15 23:27:27 +01001140 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001141 f_start_handlers(refers(f_TC_dl_unitdata), testcasename(), 2);
Harald Welte78d8db92020-11-15 23:27:27 +01001142 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Welte78d8db92020-11-15 23:27:27 +01001143 f_cleanup();
1144}
Harald Welte92686012020-11-15 21:45:49 +01001145
Harald Welte6dc2ac42020-11-16 09:16:17 +01001146private function f_TC_ra_capability(charstring id) runs on BSSGP_ConnHdlr {
1147 var integer i;
1148
1149 for (i := 0; i < 10; i := i+1) {
1150 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RA_CAP(g_pars.tlli, { ts_RaCapRec_BSSGP });
1151 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1152 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RA_CAP(g_pars.tlli, { tr_RaCapRec_BSSGP })
1153
Harald Welte22ef5d92020-11-16 13:35:14 +01001154 f_sgsn2pcu(pdu_tx, pdu_rx);
Harald Welte6dc2ac42020-11-16 09:16:17 +01001155 }
1156 setverdict(pass);
1157}
1158testcase TC_ra_capability() runs on test_CT
1159{
Harald Welte6dc2ac42020-11-16 09:16:17 +01001160 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001161 f_start_handlers(refers(f_TC_ra_capability), testcasename(), 3);
Harald Welte6dc2ac42020-11-16 09:16:17 +01001162 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Welte6dc2ac42020-11-16 09:16:17 +01001163 f_cleanup();
1164}
1165
Daniel Willmannace3ece2020-11-16 19:53:26 +01001166private function f_TC_ra_capability_upd(charstring id) runs on BSSGP_ConnHdlr {
1167 var integer i;
1168 var OCT1 tag;
1169 for (i := 0; i < 10; i := i+1) {
1170 tag := int2oct(23 + i, 1);
1171 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RA_CAP_UPD(g_pars.tlli, tag);
1172 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1173 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RA_CAP_UPD(g_pars.tlli, tag)
1174
1175 f_pcu2sgsn(pdu_tx, pdu_rx);
1176
1177 pdu_tx := ts_BSSGP_RA_CAP_UPD_ACK(g_pars.tlli, tag, '42'O);
1178 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1179 pdu_rx := tr_BSSGP_RA_CAP_UPD_ACK(g_pars.tlli, tag, '42'O)
1180
1181 f_sgsn2pcu(pdu_tx, pdu_rx);
1182 }
1183 setverdict(pass);
1184}
1185testcase TC_ra_capability_upd() runs on test_CT
1186{
Daniel Willmannace3ece2020-11-16 19:53:26 +01001187 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001188 f_start_handlers(refers(f_TC_ra_capability_upd), testcasename(), 4);
Daniel Willmannace3ece2020-11-16 19:53:26 +01001189 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Daniel Willmannace3ece2020-11-16 19:53:26 +01001190 f_cleanup();
1191}
1192
Daniel Willmann165d6612020-11-19 14:27:29 +01001193private function f_TC_radio_status(charstring id) runs on BSSGP_ConnHdlr {
1194 var integer i;
1195 var BssgpRadioCause cause := BSSGP_RADIO_CAUSE_CONTACT_LOST;
1196 for (i := 0; i < 10; i := i+1) {
1197 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RADIO_STATUS(g_pars.tlli, cause);
1198 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1199 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RADIO_STATUS(g_pars.tlli, cause)
1200
1201 f_pcu2sgsn(pdu_tx, pdu_rx);
1202 }
1203 setverdict(pass);
1204}
1205testcase TC_radio_status() runs on test_CT
1206{
Daniel Willmann165d6612020-11-19 14:27:29 +01001207 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001208 f_start_handlers(refers(f_TC_radio_status), testcasename(), 5);
Daniel Willmann165d6612020-11-19 14:27:29 +01001209 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Daniel Willmann165d6612020-11-19 14:27:29 +01001210 f_cleanup();
1211}
1212
Harald Welte3148a962021-01-17 11:15:28 +01001213private function f_TC_radio_status_tmsi(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 integer tmsi_int := oct2int(g_pars.p_tmsi);
1218 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RADIO_STATUS(omit, cause, tmsi_int);
1219 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1220 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RADIO_STATUS(omit, cause, tmsi_int);
1221 f_pcu2sgsn(pdu_tx, pdu_rx);
1222 }
1223 setverdict(pass);
1224}
1225testcase TC_radio_status_tmsi() runs on test_CT
1226{
1227 f_init();
1228 f_start_handlers(refers(f_TC_radio_status_tmsi), testcasename(), 5);
1229 f_cleanup();
1230}
1231
1232private function f_TC_radio_status_imsi(charstring id) runs on BSSGP_ConnHdlr {
1233 var integer i;
1234 var BssgpRadioCause cause := BSSGP_RADIO_CAUSE_CONTACT_LOST;
1235 for (i := 0; i < 10; i := i+1) {
1236 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RADIO_STATUS(omit, cause, imsi := g_pars.imsi);
1237 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1238 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RADIO_STATUS(omit, cause, imsi := g_pars.imsi);
1239 f_pcu2any_sgsn(pdu_tx, pdu_rx);
1240 }
1241 setverdict(pass);
1242}
1243testcase TC_radio_status_imsi() runs on test_CT
1244{
1245 f_init();
1246 f_start_handlers(refers(f_TC_radio_status_imsi), testcasename(), 5);
1247 f_cleanup();
1248}
1249
1250
1251
Harald Welte99ed5072021-01-15 20:38:58 +01001252private function f_suspend_one(integer sgsn_idx, integer nri_idx, integer pcu_idx, integer bvc_idx,
1253 integer suffix)
Harald Welte00963752021-01-15 20:33:11 +01001254runs on GlobalTest_CT
1255{
1256 var RoutingAreaIdentification ra_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id.ra_id;
Harald Welte99ed5072021-01-15 20:38:58 +01001257 var OCT4 p_tmsi := f_gen_tmsi(suffix, nri_v := mp_sgsn_nri[sgsn_idx][nri_idx],
1258 nri_bitlen := mp_nri_bitlength);
1259 var OCT4 tlli := f_gprs_tlli_from_tmsi(p_tmsi, TLLI_LOCAL);
Harald Welte00963752021-01-15 20:33:11 +01001260 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_SUSPEND(tlli, ra_id);
1261 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1262 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_SUSPEND(tlli, ra_id);
1263 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1264
1265 pdu_tx := ts_BSSGP_SUSPEND_ACK(tlli, ra_id, int2oct(suffix, 1));
1266 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1267 pdu_rx := tr_BSSGP_SUSPEND_ACK(tlli, ra_id, int2oct(suffix, 1));
1268 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1269
1270 pdu_tx := ts_BSSGP_SUSPEND(tlli, ra_id);
1271 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1272 pdu_rx := tr_BSSGP_SUSPEND(tlli, ra_id);
1273 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1274
1275 /* These messages are simple passed through so just also test sending NACK */
1276 pdu_tx := ts_BSSGP_SUSPEND_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1277 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1278 pdu_rx := tr_BSSGP_SUSPEND_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1279 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1280}
1281
Harald Weltec5c33732021-01-15 21:04:35 +01001282private function f_TC_suspend(integer sgsn_idx, integer nri_idx, integer pcu_idx, integer bvc_idx)
1283runs on GlobalTest_CT {
Daniel Willmannfa67f492020-11-19 15:48:05 +01001284 var integer i;
Daniel Willmann165d6612020-11-19 14:27:29 +01001285
Daniel Willmannfa67f492020-11-19 15:48:05 +01001286 for (i := 0; i < 10; i := i+1) {
Harald Weltec5c33732021-01-15 21:04:35 +01001287 f_suspend_one(sgsn_idx, nri_idx, pcu_idx, bvc_idx, suffix := i);
Daniel Willmannfa67f492020-11-19 15:48:05 +01001288 }
1289 setverdict(pass);
1290}
Harald Welte3807ed12020-11-24 19:05:22 +01001291testcase TC_suspend() runs on GlobalTest_CT
Daniel Willmannfa67f492020-11-19 15:48:05 +01001292{
Harald Weltec5c33732021-01-15 21:04:35 +01001293 var integer sgsn_idx, nri_idx;
Daniel Willmannfa67f492020-11-19 15:48:05 +01001294 f_init();
Harald Welte3807ed12020-11-24 19:05:22 +01001295 f_global_init();
Harald Weltec5c33732021-01-15 21:04:35 +01001296 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx+1) {
1297 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx+1) {
1298 f_TC_suspend(sgsn_idx, nri_idx, pcu_idx:=0, bvc_idx:=0);
1299 }
1300 }
Daniel Willmannfa67f492020-11-19 15:48:05 +01001301 f_cleanup();
1302}
Harald Welte6dc2ac42020-11-16 09:16:17 +01001303
Harald Welte99ed5072021-01-15 20:38:58 +01001304private function f_resume_one(integer sgsn_idx, integer nri_idx, integer pcu_idx, integer bvc_idx,
1305 integer suffix)
Harald Welte00963752021-01-15 20:33:11 +01001306runs on GlobalTest_CT
1307{
1308 var RoutingAreaIdentification ra_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id.ra_id;
Harald Welte99ed5072021-01-15 20:38:58 +01001309 var OCT4 p_tmsi := f_gen_tmsi(suffix, nri_v := mp_sgsn_nri[sgsn_idx][nri_idx],
1310 nri_bitlen := mp_nri_bitlength);
1311 var OCT4 tlli := f_gprs_tlli_from_tmsi(p_tmsi, TLLI_LOCAL);
Harald Welte00963752021-01-15 20:33:11 +01001312 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1313 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1314 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1315 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1316
1317 pdu_tx := ts_BSSGP_RESUME_ACK(tlli, ra_id);
1318 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1319 pdu_rx := tr_BSSGP_RESUME_ACK(tlli, ra_id);
1320 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1321
1322 pdu_tx := ts_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1323 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1324 pdu_rx := tr_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1325 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1326
1327 /* These messages are simple passed through so just also test sending NACK */
1328 pdu_tx := ts_BSSGP_RESUME_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1329 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1330 pdu_rx := tr_BSSGP_RESUME_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1331 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1332}
1333
Harald Weltec5c33732021-01-15 21:04:35 +01001334private function f_TC_resume(integer sgsn_idx, integer nri_idx, integer pcu_idx, integer bvc_idx)
1335runs on GlobalTest_CT {
Daniel Willmann087a33d2020-11-19 15:58:43 +01001336 var integer i;
1337
Daniel Willmann087a33d2020-11-19 15:58:43 +01001338 for (i := 0; i < 10; i := i+1) {
Harald Weltec5c33732021-01-15 21:04:35 +01001339 f_resume_one(sgsn_idx, nri_idx, pcu_idx, bvc_idx, suffix := i);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001340 }
1341 setverdict(pass);
1342}
Harald Welte3807ed12020-11-24 19:05:22 +01001343testcase TC_resume() runs on GlobalTest_CT
Daniel Willmann087a33d2020-11-19 15:58:43 +01001344{
Harald Weltec5c33732021-01-15 21:04:35 +01001345 var integer sgsn_idx, nri_idx;
Daniel Willmann087a33d2020-11-19 15:58:43 +01001346 f_init();
Harald Welte3807ed12020-11-24 19:05:22 +01001347 f_global_init();
Harald Weltec5c33732021-01-15 21:04:35 +01001348 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx+1) {
1349 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx+1) {
1350 f_TC_resume(sgsn_idx, nri_idx, pcu_idx:=0, bvc_idx:=0);
1351 }
1352 }
Daniel Willmann087a33d2020-11-19 15:58:43 +01001353 f_cleanup();
1354}
1355
Harald Weltef8ef0282020-11-18 12:16:59 +01001356/* test the load-sharing between multiple NS-VC on the BSS side */
1357private function f_TC_dl_ud_unidir(charstring id) runs on BSSGP_ConnHdlr {
1358 var integer i;
1359
1360 for (i := 0; i < 10; i := i+1) {
1361 var octetstring payload := f_rnd_octstring(i);
1362 var template (value) PDU_BSSGP pdu_tx :=
1363 ts_BSSGP_DL_UD(g_pars.tlli, payload, omit, ts_BSSGP_IMSI(g_pars.imsi));
Harald Welte09a1ce42021-01-16 11:18:38 +01001364 SGSN_PTP[g_pars.sgsn_idx].send(pdu_tx);
Harald Weltef8ef0282020-11-18 12:16:59 +01001365 }
1366 setverdict(pass);
1367}
Harald Welte09a1ce42021-01-16 11:18:38 +01001368
1369private function f_TC_load_sharing_dl(integer sgsn_idx) runs on test_CT_NS
Harald Weltef8ef0282020-11-18 12:16:59 +01001370{
1371 const integer num_ue := 10;
1372 var BSSGP_ConnHdlr vc_conn[num_ue];
Harald Weltef8ef0282020-11-18 12:16:59 +01001373 /* all BVC are now fully brought up. We disconnect BSSGP from NS on the BSS
1374 * side so we get the raw NsUnitdataIndication and hence observe different
1375 * NSVCI */
1376 disconnect(g_pcu[0].vc_NS:NS_SP, g_pcu[0].vc_BSSGP:BSCP);
1377 connect(g_pcu[0].vc_NS:NS_SP, self:NS);
1378
1379 /* there may still be some NS-VCs coming up? After all, the BVC-RESET succeeds after the first
1380 * of the NS-VC is ALIVE/UNBLOCKED */
1381 f_sleep(3.0);
1382
1383 /* start parallel components generating DL-UNITDATA from the SGSN side */
1384 for (var integer i:= 0; i < num_ue; i := i+1) {
Harald Welte2ecbca82021-01-16 11:23:09 +01001385 vc_conn[i] := f_start_handler(refers(f_TC_dl_ud_unidir), testcasename(),
Harald Welte09a1ce42021-01-16 11:18:38 +01001386 5+i, 30.0, sgsn_idx);
Harald Weltef8ef0282020-11-18 12:16:59 +01001387 }
1388
1389 /* now start counting all the messages that were queued before */
1390 /* TODO: We have a hard-coded assumption of 4 NS-VC in one NSE/NS-VCG here! */
1391 var ro_integer rx_count := { 0, 0, 0, 0 };
1392 timer T := 2.0;
1393 T.start;
1394 alt {
1395 [] as_NsUdiCount(0, rx_count);
1396 [] as_NsUdiCount(1, rx_count);
1397 [] as_NsUdiCount(2, rx_count);
1398 [] as_NsUdiCount(3, rx_count);
1399 [] NS.receive(NsUnitdataIndication:{0,?,?,*,*}) { repeat; } /* signaling BVC */
1400 [] NS.receive(NsStatusIndication:?) { repeat; }
1401 [] NS.receive {
1402 setverdict(fail, "Rx unexpected NS");
1403 mtc.stop;
1404 }
1405 [] T.timeout {
1406 }
1407 }
1408 for (var integer i := 0; i < lengthof(rx_count); i := i+1) {
1409 log("Rx on NSVCI ", mp_nsconfig_pcu[0].nsvc[i].nsvci, ": ", rx_count[i]);
1410 if (rx_count[i] == 0) {
1411 setverdict(fail, "Data not shared over all NSVC");
1412 }
1413 }
Harald Welte09a1ce42021-01-16 11:18:38 +01001414}
1415
1416testcase TC_load_sharing_dl() runs on test_CT_NS
1417{
1418 var integer sgsn_idx, nri_idx;
1419 f_init();
1420 for (sgsn_idx:=0; sgsn_idx < NUM_SGSN; sgsn_idx:=sgsn_idx+1) {
1421 f_TC_load_sharing_dl(sgsn_idx);
1422 }
Harald Weltef8ef0282020-11-18 12:16:59 +01001423 setverdict(pass);
1424}
1425private altstep as_NsUdiCount(integer nsvc_idx, inout ro_integer roi) runs on test_CT_NS {
1426 var NsUnitdataIndication udi;
1427 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[0];
1428 [] NS.receive(NsUnitdataIndication:{bvcc.bvci, g_pcu[0].cfg.nsei, mp_nsconfig_pcu[0].nsvc[nsvc_idx].nsvci, *, *}) -> value udi {
1429 roi[nsvc_idx] := roi[nsvc_idx] + 1;
1430 repeat;
1431 }
1432}
1433type component test_CT_NS extends test_CT {
1434 port NS_PT NS;
1435};
1436
1437
Harald Welte0e188242020-11-22 21:46:48 +01001438/***********************************************************************
1439 * PAGING PS procedure
1440 ***********************************************************************/
1441
1442private function f_send_paging_ps(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1443 boolean use_sig := false)
1444runs on BSSGP_ConnHdlr return template (present) PDU_BSSGP {
1445 var template (value) PDU_BSSGP pdu_tx;
1446 var template (present) PDU_BSSGP pdu_rx;
1447 /* we always specify '0' as BVCI in the templates below, as we override it with
1448 * 'p4' later anyway */
1449 pdu_rx := tr_BSSGP_PS_PAGING(0);
1450 pdu_rx.pDU_BSSGP_PAGING_PS.iMSI := tr_BSSGP_IMSI(g_pars.imsi);
1451 if (ispresent(g_pars.p_tmsi)) {
1452 pdu_tx := ts_BSSGP_PS_PAGING_PTMSI(0, g_pars.imsi, oct2int(g_pars.p_tmsi));
1453 pdu_rx.pDU_BSSGP_PAGING_PS.pTMSI := tr_BSSGP_TMSI(oct2int(g_pars.p_tmsi));
1454 } else {
1455 pdu_tx := ts_BSSGP_PS_PAGING_IMSI(0, g_pars.imsi);
1456 pdu_rx.pDU_BSSGP_PAGING_PS.pTMSI := omit;
1457 }
1458 pdu_tx.pDU_BSSGP_PAGING_PS.paging_Field4 := p4;
1459 pdu_rx.pDU_BSSGP_PAGING_PS.paging_Field4 := p4;
1460 if (use_sig == false) {
Harald Welte158becf2020-12-09 12:32:32 +01001461 SGSN_PTP[sgsn_idx].send(pdu_tx);
Harald Welte0e188242020-11-22 21:46:48 +01001462 } else {
1463 SGSN_SIG[sgsn_idx].send(pdu_tx);
1464 }
1465 return pdu_rx;
1466}
1467
1468/* send paging defined by 'p4' on given SGSN-side index (ptp or signaling) and expect one paging to arrive on
1469 * specified PCU index */
1470private function f_send_paging_ps_exp_one_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1471 boolean use_sig := false,integer pcu_idx := 0)
1472runs on BSSGP_ConnHdlr {
1473 var template (present) PDU_BSSGP exp_rx;
Daniel Willmann1a859712020-12-04 00:59:45 +01001474 var boolean test_done := false;
Harald Welte0e188242020-11-22 21:46:48 +01001475 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1476 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1477 exp_rx := f_send_paging_ps(p4, sgsn_idx, use_sig);
1478 /* Expect paging to propagate to the one BSS addressed by the BVCI only */
1479 timer T := 2.0;
1480 T.start;
1481 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001482 [not use_sig and not test_done] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001483 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001484 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001485 repeat;
1486 }
1487 [not use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
1488 setverdict(fail, "Received paging on SIGNALING BVC, expected PTP BVC");
1489 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001490 [use_sig and not test_done] PCU_SIG[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001491 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001492 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001493 repeat;
1494 }
Harald Welte158becf2020-12-09 12:32:32 +01001495 [use_sig] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001496 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1497 }
Harald Welte158becf2020-12-09 12:32:32 +01001498 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001499 setverdict(fail, "Paging received on unexpected BVC");
1500 }
1501 [] any from PCU_SIG.receive(exp_rx) {
1502 setverdict(fail, "Paging received on unexpected BVC");
1503 }
Harald Welte158becf2020-12-09 12:32:32 +01001504 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01001505 setverdict(fail, "Different Paging than expected received PTP BVC");
1506 }
1507 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1508 setverdict(fail, "Different Paging than expected on SIGNALING BVC");
1509 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001510 [not test_done] T.timeout {
1511 setverdict(fail, "Timeout waiting for paging");
1512 }
1513 [test_done] T.timeout;
Harald Welte0e188242020-11-22 21:46:48 +01001514 }
1515}
1516
Harald Welte7462a592020-11-23 22:07:07 +01001517/* send a PS-PAGING but don't expect it to show up on any PTP or SIG BVC */
1518private function f_send_paging_ps_exp_no_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1519 boolean use_sig := false)
1520runs on BSSGP_ConnHdlr {
1521 var template (present) PDU_BSSGP exp_rx;
1522 exp_rx := f_send_paging_ps(p4, sgsn_idx, use_sig);
1523 /* Expect paging to propagate to no BSS */
1524 timer T := 2.0;
1525 T.start;
1526 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001527 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte7462a592020-11-23 22:07:07 +01001528 setverdict(fail, "Paging received on unexpected BVC");
1529 }
1530 [] any from PCU_SIG.receive(exp_rx) {
1531 setverdict(fail, "Paging received on unexpected BVC");
1532 }
Harald Welte158becf2020-12-09 12:32:32 +01001533 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte7462a592020-11-23 22:07:07 +01001534 setverdict(fail, "Different Paging received on PTP BVC");
1535 }
1536 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1537 setverdict(fail, "Different Paging received on SIGNALING BVC");
1538 }
1539 [] T.timeout {
1540 setverdict(pass);
1541 }
1542 }
1543}
1544
Harald Welte0e188242020-11-22 21:46:48 +01001545private function f_TC_paging_ps_ptp_bss(charstring id) runs on BSSGP_ConnHdlr
1546{
1547 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1548 * at that BVC (cell) only, and paging all over the BSS area is not possible */
Daniel Willmann2a330672021-01-18 18:50:02 +01001549 f_send_paging_ps_exp_one_bss(ts_BssgpP4BssArea, g_pars.sgsn_idx, false, 0);
Harald Welte0e188242020-11-22 21:46:48 +01001550}
1551testcase TC_paging_ps_ptp_bss() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001552 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001553 f_start_handlers(refers(f_TC_paging_ps_ptp_bss), testcasename(), 9);
Harald Welte0e188242020-11-22 21:46:48 +01001554 f_cleanup();
1555}
1556
1557/* PS-PAGING on PTP-BVC for Location Area */
1558private function f_TC_paging_ps_ptp_lac(charstring id) runs on BSSGP_ConnHdlr
1559{
1560 var template (present) PDU_BSSGP exp_rx;
1561 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1562 * at that BVC (cell) only, and paging all over the BSS area is not possible */
Daniel Willmann2a330672021-01-18 18:50:02 +01001563 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 +01001564}
1565testcase TC_paging_ps_ptp_lac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001566 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001567 f_start_handlers(refers(f_TC_paging_ps_ptp_lac), testcasename(), 10);
Harald Welte0e188242020-11-22 21:46:48 +01001568 f_cleanup();
1569}
1570
Harald Welte7462a592020-11-23 22:07:07 +01001571/* PS-PAGING on PTP-BVC for unknown Location Area */
1572private function f_TC_paging_ps_ptp_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1573{
1574 var GSM_Types.LocationAreaIdentification unknown_la := {
1575 mcc_mnc := '567F99'H,
1576 lac := 33333
1577 };
1578 /* as it's sent on the PTP BVC, we expect it to pass even for unknown LAC */
Daniel Willmann2a330672021-01-18 18:50:02 +01001579 f_send_paging_ps_exp_one_bss(ts_BssgpP4LAC(unknown_la), g_pars.sgsn_idx, false, 0);
Harald Welte7462a592020-11-23 22:07:07 +01001580}
1581testcase TC_paging_ps_ptp_lac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001582 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001583 f_start_handlers(refers(f_TC_paging_ps_ptp_lac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001584 f_cleanup();
1585}
1586
Harald Welte0e188242020-11-22 21:46:48 +01001587/* PS-PAGING on PTP-BVC for Routeing Area */
1588private function f_TC_paging_ps_ptp_rac(charstring id) runs on BSSGP_ConnHdlr
1589{
1590 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1591 * at that BVC (cell) only, and paging all over the BSS area is not possible */
Daniel Willmann2a330672021-01-18 18:50:02 +01001592 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 +01001593}
1594testcase TC_paging_ps_ptp_rac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001595 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001596 f_start_handlers(refers(f_TC_paging_ps_ptp_rac), testcasename(), 11);
Harald Welte0e188242020-11-22 21:46:48 +01001597 f_cleanup();
1598}
1599
Harald Welte7462a592020-11-23 22:07:07 +01001600/* PS-PAGING on PTP-BVC for unknown Routeing Area */
1601private function f_TC_paging_ps_ptp_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1602{
1603 var RoutingAreaIdentification unknown_ra := {
1604 lai := {
1605 mcc_mnc := '567F99'H,
1606 lac := 33333
1607 },
1608 rac := 254
1609 };
1610 /* as it's sent on the PTP BVC, we expect it to pass even for unknown RAC */
Daniel Willmann2a330672021-01-18 18:50:02 +01001611 f_send_paging_ps_exp_one_bss(ts_BssgpP4RAC(unknown_ra), g_pars.sgsn_idx, false, 0);
Harald Welte7462a592020-11-23 22:07:07 +01001612}
1613testcase TC_paging_ps_ptp_rac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001614 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001615 f_start_handlers(refers(f_TC_paging_ps_ptp_rac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001616 f_cleanup();
1617}
1618
Harald Welte0e188242020-11-22 21:46:48 +01001619/* PS-PAGING on PTP-BVC for BVCI (one cell) */
1620private function f_TC_paging_ps_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
1621{
1622 /* this should be the normal case for MS in READY MM state after a lower layer failure */
Daniel Willmann2a330672021-01-18 18:50:02 +01001623 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 +01001624}
1625testcase TC_paging_ps_ptp_bvci() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001626 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001627 f_start_handlers(refers(f_TC_paging_ps_ptp_bvci), testcasename(), 12);
Harald Welte0e188242020-11-22 21:46:48 +01001628 f_cleanup();
1629}
1630
Harald Welteb5a04aa2021-01-16 13:04:40 +01001631
1632/* PS-PAGING on PTP-BVC for BVCI (one cell) using IMSI only (no P-TMSI allocated) */
1633testcase TC_paging_ps_ptp_bvci_imsi() runs on test_CT {
1634 f_init();
1635 f_start_handlers(refers(f_TC_paging_ps_ptp_bvci), testcasename(), 12, have_ptmsi:=false);
1636 f_cleanup();
1637}
1638
Harald Weltecf200072021-01-16 15:20:46 +01001639/* Rejected PS-PAGING on PTP-BVC for BVCI (one cell) */
1640testcase TC_paging_ps_reject_ptp_bvci() runs on test_CT {
1641 f_init();
1642 f_start_handlers(refers(f_TC_paging_ps_reject_ptp_bvci), testcasename(), 16);
1643 f_cleanup();
1644}
1645
1646/* Rejected PS-PAGING on PTP-BVC for BVCI (one cell) using IMSI only (no P-TMSI allocated) */
1647private function f_TC_paging_ps_reject_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
1648{
1649 /* first send the PS-PAGING from SGSN -> PCU */
Daniel Willmann2a330672021-01-18 18:50:02 +01001650 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 +01001651 /* then simulate the PS-PAGING-REJECT from the PCU */
1652 f_send_paging_ps_rej(use_sig:=false);
1653}
1654testcase TC_paging_ps_reject_ptp_bvci_imsi() runs on test_CT {
1655 f_init();
1656 f_start_handlers(refers(f_TC_paging_ps_reject_ptp_bvci), testcasename(), 16, have_ptmsi:=false);
1657 f_cleanup();
1658}
Harald Welteb5a04aa2021-01-16 13:04:40 +01001659
Harald Welte7462a592020-11-23 22:07:07 +01001660/* PS-PAGING on PTP-BVC for unknown BVCI */
1661private function f_TC_paging_ps_ptp_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1662{
1663 /* as it's sent on the PTP BVC, we expect it to pass even for unknown BVCI */
Daniel Willmann2a330672021-01-18 18:50:02 +01001664 f_send_paging_ps_exp_one_bss(ts_BssgpP4Bvci(33333), g_pars.sgsn_idx, false, 0);
Harald Welte7462a592020-11-23 22:07:07 +01001665}
1666testcase TC_paging_ps_ptp_bvci_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001667 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001668 f_start_handlers(refers(f_TC_paging_ps_ptp_bvci_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001669 f_cleanup();
1670}
1671
Harald Welte7595d562021-01-16 19:09:20 +01001672/* DUMMY PAGING PS on PTP BVC */
1673private function f_TC_dummy_paging_ps_ptp(charstring id) runs on BSSGP_ConnHdlr
1674{
1675 f_sgsn2pcu(ts_BSSGP_DUMMY_PAGING_PS(g_pars.imsi, omit),
1676 tr_BSSGP_DUMMY_PAGING_PS(g_pars.imsi, omit), use_sig := false);
1677 f_pcu2sgsn(ts_BSSGP_DUMMY_PAGING_PS_RESP(g_pars.imsi, 1, 5),
1678 tr_BSSGP_DUMMY_PAGING_PS_RESP(g_pars.imsi, 1, 5), use_sig := false)
1679}
1680testcase TC_dummy_paging_ps_ptp() runs on test_CT {
1681 f_init();
1682 f_start_handlers(refers(f_TC_dummy_paging_ps_ptp), testcasename(), 11);
1683 f_cleanup();
1684}
1685
Harald Welte0e188242020-11-22 21:46:48 +01001686/* altstep for expecting BSSGP PDU on signaling BVC of given pcu_idx + storing in 'roi' */
1687private altstep as_paging_sig_pcu(integer pcu_idx, template (present) PDU_BSSGP exp_rx, inout ro_integer roi)
1688runs on BSSGP_ConnHdlr {
1689[] PCU_SIG[pcu_idx].receive(exp_rx) {
1690 if (ro_integer_contains(roi, pcu_idx)) {
1691 setverdict(fail, "Received multiple paging on same SIG BVC");
1692 }
1693 roi := roi & { pcu_idx };
1694 repeat;
1695 }
Harald Welte158becf2020-12-09 12:32:32 +01001696[] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001697 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1698 }
1699[] PCU_SIG[pcu_idx].receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1700 setverdict(fail, "Different Paging than expected received SIGNALING BVC");
1701 }
Harald Welte158becf2020-12-09 12:32:32 +01001702[] PCU_PTP[pcu_idx].receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01001703 setverdict(fail, "Different Paging than expected received PTP BVC");
1704 }
1705}
1706
1707type record of default ro_default;
1708
1709/* send PS-PAGING on SIG BVC, expect it to arrive on given list of PCU indexes */
1710private function f_send_paging_ps_exp_multi(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1711 ro_integer exp_on_pcu_idx) runs on BSSGP_ConnHdlr
1712{
1713 var template (present) PDU_BSSGP exp_rx;
Daniel Willmann193e1a02021-01-17 12:55:53 +01001714 exp_rx := f_send_paging_ps(p4, sgsn_idx, true);
Harald Welte0e188242020-11-22 21:46:48 +01001715
1716 /* FIXME: make sure the relevant BVCs/BSS are connected to the ports! */
1717 var ro_default defaults := {};
1718 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1719 var default d := activate(as_paging_sig_pcu(i, exp_rx, g_roi));
1720 defaults := defaults & { d };
1721 }
1722 f_sleep(2.0);
1723 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
1724 deactivate(defaults[i]);
1725 }
1726 log("Paging received on PCU ", g_roi);
1727
1728 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1729 var boolean rx_on_i := ro_integer_contains(g_roi, i);
1730 var boolean exp_on_i := ro_integer_contains(exp_on_pcu_idx, i);
1731 if (exp_on_i and not rx_on_i) {
1732 setverdict(fail, "PS-PAGING not received on ", mp_nsconfig_pcu[i].nsei);
1733 }
1734 if (not exp_on_i and rx_on_i) {
1735 setverdict(fail, "PS-PAGING not expected but received on ", mp_nsconfig_pcu[i].nsei);
1736 }
1737 }
1738 setverdict(pass);
1739}
1740
Harald Weltecf200072021-01-16 15:20:46 +01001741/* Send PAGING-PS-REJECT on SIG BVC, expect it to arrive on the "right" SGSN */
1742private function f_send_paging_ps_rej(boolean use_sig := true, integer pcu_idx := 0) runs on BSSGP_ConnHdlr
1743{
1744 var template (value) PDU_BSSGP pdu_tx;
1745 var template (present) PDU_BSSGP exp_rx;
1746 var PDU_BSSGP pdu_rx;
1747 timer T := 5.0;
1748 var template (omit) GsmTmsi tmsi_int := omit;
1749
1750 if (ispresent(g_pars.p_tmsi)) {
1751 tmsi_int := oct2int(g_pars.p_tmsi);
1752 }
1753
1754 pdu_tx := ts_BSSGP_PAGING_PS_REJ(g_pars.imsi, 23, 42, tmsi_int);
1755 exp_rx := tr_BSSGP_PAGING_PS_REJ(g_pars.imsi, 23, 42, tmsi_int);
1756
1757 if (use_sig) {
1758 PCU_SIG[pcu_idx].send(pdu_tx);
1759 } else {
1760 PCU_PTP[pcu_idx].send(pdu_tx);
1761 }
1762 T.start;
1763 alt {
1764 [use_sig] SGSN_SIG[g_pars.sgsn_idx].receive(exp_rx) -> value pdu_rx {
1765 setverdict(pass);
1766 }
1767 [use_sig] SGSN_SIG[g_pars.sgsn_idx].receive {
1768 setverdict(fail, "Unexpected PDU on SGSN");
1769 }
1770 [use_sig] any from SGSN_SIG.receive(exp_rx) -> value pdu_rx {
1771 setverdict(fail, "PAGING-PS-REJECT arrived on wrong SGSN");
1772 }
1773 [not use_sig] SGSN_PTP[g_pars.sgsn_idx].receive(exp_rx) -> value pdu_rx {
1774 setverdict(pass);
1775 }
1776 [not use_sig] SGSN_PTP[g_pars.sgsn_idx].receive {
1777 setverdict(fail, "Unexpected PDU on SGSN");
1778 }
1779 [not use_sig] any from SGSN_PTP.receive(exp_rx) -> value pdu_rx {
1780 setverdict(fail, "PAGING-PS-REJECT arrived on wrong SGSN");
1781 }
1782 [] T.timeout {
1783 setverdict(fail, "Timeout waiting for PAGING-PS-REJECT");
1784 }
1785 }
1786}
1787
Harald Welte0e188242020-11-22 21:46:48 +01001788/* PS-PAGING on SIG-BVC for BSS Area */
1789private function f_TC_paging_ps_sig_bss(charstring id) runs on BSSGP_ConnHdlr
1790{
1791 /* we expect the paging to arrive on all three NSE */
Daniel Willmann43320442021-01-17 14:07:05 +01001792 f_send_paging_ps_exp_multi(ts_BssgpP4BssArea, g_pars.sgsn_idx, {0, 1, 2});
Harald Welte0e188242020-11-22 21:46:48 +01001793}
1794testcase TC_paging_ps_sig_bss() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001795 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001796 f_start_handlers(refers(f_TC_paging_ps_sig_bss), testcasename(), 13);
Harald Welte0e188242020-11-22 21:46:48 +01001797 f_cleanup();
1798}
1799
1800/* PS-PAGING on SIG-BVC for Location Area */
1801private function f_TC_paging_ps_sig_lac(charstring id) runs on BSSGP_ConnHdlr
1802{
Daniel Willmann2c9300f2020-12-01 10:54:08 +01001803 /* The first LAC (13135) is shared by all three NSEs */
Daniel Willmann43320442021-01-17 14:07:05 +01001804 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 +01001805 /* Reset state */
1806 g_roi := {};
1807 /* Make LAC (13300) available on pcu index 2 */
1808 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
Daniel Willmann43320442021-01-17 14:07:05 +01001809 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 +01001810}
1811testcase TC_paging_ps_sig_lac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001812 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001813 f_start_handlers(refers(f_TC_paging_ps_sig_lac), testcasename(), 14);
Harald Welte0e188242020-11-22 21:46:48 +01001814 f_cleanup();
1815}
1816
Harald Welte7462a592020-11-23 22:07:07 +01001817/* PS-PAGING on SIG-BVC for unknown Location Area */
1818private function f_TC_paging_ps_sig_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1819{
1820 var GSM_Types.LocationAreaIdentification unknown_la := {
1821 mcc_mnc := '567F99'H,
1822 lac := 33333
1823 };
Daniel Willmann2a330672021-01-18 18:50:02 +01001824 f_send_paging_ps_exp_no_bss(ts_BssgpP4LAC(unknown_la), g_pars.sgsn_idx, true);
Harald Welte7462a592020-11-23 22:07:07 +01001825}
1826testcase TC_paging_ps_sig_lac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001827 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001828 f_start_handlers(refers(f_TC_paging_ps_sig_lac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001829 f_cleanup();
1830}
1831
Harald Welte0e188242020-11-22 21:46:48 +01001832/* PS-PAGING on SIG-BVC for Routeing Area */
1833private function f_TC_paging_ps_sig_rac(charstring id) runs on BSSGP_ConnHdlr
1834{
Daniel Willmann2c9300f2020-12-01 10:54:08 +01001835 /* Only PCU index 0 has a matching BVC with the RA ID */
Daniel Willmann43320442021-01-17 14:07:05 +01001836 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 +01001837 g_roi := {};
1838 /* PCU index 1 and 2 have a matching BVC with the RA ID */
Daniel Willmann43320442021-01-17 14:07:05 +01001839 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 +01001840 g_roi := {};
1841 /* PCU index 2 has two matching BVCs with the RA ID */
1842 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
Daniel Willmann43320442021-01-17 14:07:05 +01001843 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 +01001844}
1845testcase TC_paging_ps_sig_rac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001846 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001847 f_start_handlers(refers(f_TC_paging_ps_sig_rac), testcasename(), 15);
Harald Welte0e188242020-11-22 21:46:48 +01001848 f_cleanup();
1849}
1850
Harald Welte7462a592020-11-23 22:07:07 +01001851/* PS-PAGING on SIG-BVC for unknown Routeing Area */
1852private function f_TC_paging_ps_sig_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1853{
1854 var RoutingAreaIdentification unknown_ra := {
1855 lai := {
1856 mcc_mnc := '567F99'H,
1857 lac := 33333
1858 },
1859 rac := 254
1860 };
Daniel Willmann2a330672021-01-18 18:50:02 +01001861 f_send_paging_ps_exp_no_bss(ts_BssgpP4RAC(unknown_ra), g_pars.sgsn_idx, true);
Harald Welte7462a592020-11-23 22:07:07 +01001862}
1863testcase TC_paging_ps_sig_rac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001864 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001865 f_start_handlers(refers(f_TC_paging_ps_sig_rac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001866 f_cleanup();
1867}
1868
Harald Welte0e188242020-11-22 21:46:48 +01001869/* PS-PAGING on SIG-BVC for BVCI (one cell) */
1870private function f_TC_paging_ps_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
1871{
Daniel Willmann43320442021-01-17 14:07:05 +01001872 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 +01001873}
1874testcase TC_paging_ps_sig_bvci() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001875 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001876 f_start_handlers(refers(f_TC_paging_ps_sig_bvci), testcasename(), 16);
Harald Welte0e188242020-11-22 21:46:48 +01001877 f_cleanup();
1878}
1879
Harald Welteb5a04aa2021-01-16 13:04:40 +01001880/* PS-PAGING on SIG-BVC for BVCI (one cell) using IMSI only (no P-TMSI allocated) */
1881testcase TC_paging_ps_sig_bvci_imsi() runs on test_CT {
1882 f_init();
1883 f_start_handlers(refers(f_TC_paging_ps_sig_bvci), testcasename(), 16, have_ptmsi:=false);
1884 f_cleanup();
1885}
1886
Harald Weltecf200072021-01-16 15:20:46 +01001887/* Rejected PS-PAGING on SIG-BVC for BVCI (one cell) */
1888private function f_TC_paging_ps_reject_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
1889{
1890 /* first send the PS-PAGING from SGSN -> PCU */
Daniel Willmann43320442021-01-17 14:07:05 +01001891 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 +01001892 /* then simulate the PS-PAGING-REJECT from the PCU */
1893 f_send_paging_ps_rej(use_sig:=true);
1894
1895}
1896testcase TC_paging_ps_reject_sig_bvci() runs on test_CT {
1897 f_init();
1898 f_start_handlers(refers(f_TC_paging_ps_reject_sig_bvci), testcasename(), 16);
1899 f_cleanup();
1900}
1901
1902/* Rejected PS-PAGING on SIG-BVC for BVCI (one cell) using IMSI only (no P-TMSI allocated) */
1903testcase TC_paging_ps_reject_sig_bvci_imsi() runs on test_CT {
1904 f_init();
1905 f_start_handlers(refers(f_TC_paging_ps_reject_sig_bvci), testcasename(), 16, have_ptmsi:=false);
1906 f_cleanup();
1907}
1908
Harald Welte7462a592020-11-23 22:07:07 +01001909/* PS-PAGING on SIG-BVC for unknown BVCI */
1910private function f_TC_paging_ps_sig_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1911{
Daniel Willmann2a330672021-01-18 18:50:02 +01001912 f_send_paging_ps_exp_no_bss(ts_BssgpP4Bvci(33333), g_pars.sgsn_idx, true);
Harald Welte7462a592020-11-23 22:07:07 +01001913}
1914testcase TC_paging_ps_sig_bvci_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001915 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001916 f_start_handlers(refers(f_TC_paging_ps_sig_bvci_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001917 f_cleanup();
1918}
1919
Harald Welte7595d562021-01-16 19:09:20 +01001920/* DUMMY PAGING PS on SIG BVC */
1921private function f_TC_dummy_paging_ps_sig(charstring id) runs on BSSGP_ConnHdlr
1922{
1923 f_sgsn2pcu(ts_BSSGP_DUMMY_PAGING_PS(g_pars.imsi, omit),
1924 tr_BSSGP_DUMMY_PAGING_PS(g_pars.imsi, omit), use_sig := true);
1925 f_pcu2sgsn(ts_BSSGP_DUMMY_PAGING_PS_RESP(g_pars.imsi, 1, 5),
1926 tr_BSSGP_DUMMY_PAGING_PS_RESP(g_pars.imsi, 1, 5), use_sig := true)
1927}
1928testcase TC_dummy_paging_ps_sig() runs on test_CT {
1929 f_init();
1930 f_start_handlers(refers(f_TC_dummy_paging_ps_sig), testcasename(), 11);
1931 f_cleanup();
1932}
1933
Harald Welte7462a592020-11-23 22:07:07 +01001934
Harald Welte0e188242020-11-22 21:46:48 +01001935
1936/***********************************************************************
1937 * PAGING CS procedure
1938 ***********************************************************************/
1939
1940private function f_send_paging_cs(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1941 boolean use_sig := false)
1942runs on BSSGP_ConnHdlr return template (present) PDU_BSSGP {
1943 var template (value) PDU_BSSGP pdu_tx;
1944 var template (present) PDU_BSSGP pdu_rx;
1945 /* we always specify '0' as BVCI in the templates below, as we override it with
1946 * 'p4' later anyway */
1947 pdu_rx := tr_BSSGP_CS_PAGING(0);
1948 pdu_rx.pDU_BSSGP_PAGING_CS.iMSI := tr_BSSGP_IMSI(g_pars.imsi);
1949 if (ispresent(g_pars.p_tmsi)) {
1950 pdu_tx := ts_BSSGP_CS_PAGING_PTMSI(0, g_pars.imsi, oct2int(g_pars.p_tmsi));
1951 pdu_rx.pDU_BSSGP_PAGING_CS.tMSI := tr_BSSGP_TMSI(oct2int(g_pars.p_tmsi));
1952 } else {
1953 pdu_tx := ts_BSSGP_CS_PAGING_IMSI(0, g_pars.imsi);
1954 pdu_rx.pDU_BSSGP_PAGING_CS.tMSI := omit;
1955 }
1956 pdu_tx.pDU_BSSGP_PAGING_CS.paging_Field4 := p4;
1957 pdu_rx.pDU_BSSGP_PAGING_CS.paging_Field4 := p4;
1958 if (use_sig == false) {
Harald Welte158becf2020-12-09 12:32:32 +01001959 SGSN_PTP[sgsn_idx].send(pdu_tx);
Harald Welte0e188242020-11-22 21:46:48 +01001960 } else {
1961 SGSN_SIG[sgsn_idx].send(pdu_tx);
1962 }
1963 return pdu_rx;
1964}
1965
1966/* send paging defined by 'p4' on given SGSN-side index (ptp or signaling) and expect one paging to arrive on
1967 * specified PCU index */
1968private function f_send_paging_cs_exp_one_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1969 boolean use_sig := false,integer pcu_idx := 0)
1970runs on BSSGP_ConnHdlr {
1971 var template (present) PDU_BSSGP exp_rx;
Daniel Willmann1a859712020-12-04 00:59:45 +01001972 var boolean test_done := false;
Harald Welte0e188242020-11-22 21:46:48 +01001973 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1974 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1975 exp_rx := f_send_paging_cs(p4, sgsn_idx, use_sig);
1976 /* Expect paging to propagate to the one BSS addressed by the BVCI only */
1977 timer T := 2.0;
1978 T.start;
1979 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001980 [not use_sig and not test_done] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001981 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001982 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001983 repeat;
1984 }
1985 [not use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
1986 setverdict(fail, "Received paging on SIGNALING BVC, expected PTP BVC");
1987 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001988 [use_sig and not test_done] PCU_SIG[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001989 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001990 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001991 repeat;
1992 }
Harald Welte158becf2020-12-09 12:32:32 +01001993 [use_sig] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001994 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1995 }
Harald Welte158becf2020-12-09 12:32:32 +01001996 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001997 setverdict(fail, "Paging received on unexpected BVC");
1998 }
1999 [] any from PCU_SIG.receive(exp_rx) {
2000 setverdict(fail, "Paging received on unexpected BVC");
2001 }
Harald Welte158becf2020-12-09 12:32:32 +01002002 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01002003 setverdict(fail, "Different Paging than expected received PTP BVC");
2004 }
2005 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
2006 setverdict(fail, "Different Paging than expected on SIGNALING BVC");
2007 }
Daniel Willmann1a859712020-12-04 00:59:45 +01002008 [not test_done] T.timeout {
2009 setverdict(fail, "Timeout while waiting for paging")
2010 }
2011 [test_done] T.timeout;
Harald Welte0e188242020-11-22 21:46:48 +01002012 }
2013}
2014
Harald Welte7462a592020-11-23 22:07:07 +01002015/* send a CS-PAGING but don't expect it to show up on any PTP or SIG BVC */
2016private function f_send_paging_cs_exp_no_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
2017 boolean use_sig := false)
2018runs on BSSGP_ConnHdlr {
2019 var template (present) PDU_BSSGP exp_rx;
2020 exp_rx := f_send_paging_cs(p4, sgsn_idx, use_sig);
2021 /* Expect paging to propagate to no BSS */
2022 timer T := 2.0;
2023 T.start;
2024 alt {
Harald Welte158becf2020-12-09 12:32:32 +01002025 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte7462a592020-11-23 22:07:07 +01002026 setverdict(fail, "Paging received on unexpected BVC");
2027 }
2028 [] any from PCU_SIG.receive(exp_rx) {
2029 setverdict(fail, "Paging received on unexpected BVC");
2030 }
Harald Welte158becf2020-12-09 12:32:32 +01002031 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
Harald Welte7462a592020-11-23 22:07:07 +01002032 setverdict(fail, "Different Paging received on PTP BVC");
2033 }
2034 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
2035 setverdict(fail, "Different Paging received on SIGNALING BVC");
2036 }
2037 [] T.timeout {
2038 setverdict(pass);
2039 }
2040 }
2041}
2042
Harald Welte0e188242020-11-22 21:46:48 +01002043private function f_TC_paging_cs_ptp_bss(charstring id) runs on BSSGP_ConnHdlr
2044{
2045 /* doesn't really make sense: Sending to a single BVCI means the message ends up
2046 * at that BVC (cell) only, and paging all over the BSS area is not possible */
2047 f_send_paging_cs_exp_one_bss(ts_BssgpP4BssArea, 0, false, 0);
2048}
2049testcase TC_paging_cs_ptp_bss() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002050 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002051 f_start_handlers(refers(f_TC_paging_cs_ptp_bss), testcasename(), 17);
Harald Welte0e188242020-11-22 21:46:48 +01002052 f_cleanup();
2053}
2054
2055/* CS-PAGING on PTP-BVC for Location Area */
2056private function f_TC_paging_cs_ptp_lac(charstring id) runs on BSSGP_ConnHdlr
2057{
2058 var template (present) PDU_BSSGP exp_rx;
2059 /* doesn't really make sense: Sending to a single BVCI means the message ends up
2060 * at that BVC (cell) only, and paging all over the BSS area is not possible */
2061 f_send_paging_cs_exp_one_bss(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, false, 0);
2062}
2063testcase TC_paging_cs_ptp_lac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002064 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002065 f_start_handlers(refers(f_TC_paging_cs_ptp_lac), testcasename(), 18);
Harald Welte0e188242020-11-22 21:46:48 +01002066 f_cleanup();
2067}
2068
Harald Welte7462a592020-11-23 22:07:07 +01002069/* CS-PAGING on PTP-BVC for unknown Location Area */
2070private function f_TC_paging_cs_ptp_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
2071{
2072 var GSM_Types.LocationAreaIdentification unknown_la := {
2073 mcc_mnc := '567F99'H,
2074 lac := 33333
2075 };
2076 /* as it's sent on the PTP BVC, we expect it to pass even for unknown LAC */
2077 f_send_paging_cs_exp_one_bss(ts_BssgpP4LAC(unknown_la), 0, false, 0);
2078}
2079testcase TC_paging_cs_ptp_lac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002080 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002081 f_start_handlers(refers(f_TC_paging_cs_ptp_lac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002082 f_cleanup();
2083}
2084
Harald Welte0e188242020-11-22 21:46:48 +01002085/* CS-PAGING on PTP-BVC for Routeing Area */
2086private function f_TC_paging_cs_ptp_rac(charstring id) runs on BSSGP_ConnHdlr
2087{
2088 /* doesn't really make sense: Sending to a single BVCI means the message ends up
2089 * at that BVC (cell) only, and paging all over the BSS area is not possible */
2090 f_send_paging_cs_exp_one_bss(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, false, 0);
2091}
2092testcase TC_paging_cs_ptp_rac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002093 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002094 f_start_handlers(refers(f_TC_paging_cs_ptp_rac), testcasename(), 19);
Harald Welte0e188242020-11-22 21:46:48 +01002095 f_cleanup();
2096}
2097
Harald Welte7462a592020-11-23 22:07:07 +01002098/* CS-PAGING on PTP-BVC for unknown Routeing Area */
2099private function f_TC_paging_cs_ptp_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
2100{
2101 var RoutingAreaIdentification unknown_ra := {
2102 lai := {
2103 mcc_mnc := '567F99'H,
2104 lac := 33333
2105 },
2106 rac := 254
2107 };
2108 /* as it's sent on the PTP BVC, we expect it to pass even for unknown RAC */
2109 f_send_paging_cs_exp_one_bss(ts_BssgpP4RAC(unknown_ra), 0, false, 0);
2110}
2111testcase TC_paging_cs_ptp_rac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002112 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002113 f_start_handlers(refers(f_TC_paging_cs_ptp_rac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002114 f_cleanup();
2115}
2116
Harald Welte0e188242020-11-22 21:46:48 +01002117/* CS-PAGING on PTP-BVC for BVCI (one cell) */
2118private function f_TC_paging_cs_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
2119{
2120 /* this should be the normal case for MS in READY MM state after a lower layer failure */
2121 f_send_paging_cs_exp_one_bss(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, false, 0);
2122}
2123testcase TC_paging_cs_ptp_bvci() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002124 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002125 f_start_handlers(refers(f_TC_paging_cs_ptp_bvci), testcasename(), 20);
Harald Welte0e188242020-11-22 21:46:48 +01002126 f_cleanup();
2127}
2128
Harald Welte7462a592020-11-23 22:07:07 +01002129/* CS-PAGING on PTP-BVC for unknown BVCI */
2130private function f_TC_paging_cs_ptp_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
2131{
2132 /* as it's sent on the PTP BVC, we expect it to pass even for unknown BVCI */
2133 f_send_paging_cs_exp_one_bss(ts_BssgpP4Bvci(33333), 0, false, 0);
2134}
2135testcase TC_paging_cs_ptp_bvci_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002136 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002137 f_start_handlers(refers(f_TC_paging_cs_ptp_bvci_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002138 f_cleanup();
2139}
2140
Harald Welte0e188242020-11-22 21:46:48 +01002141/* send CS-PAGING on SIG BVC, expect it to arrive on given list of PCU indexes */
2142private function f_send_paging_cs_exp_multi(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
2143 ro_integer exp_on_pcu_idx) runs on BSSGP_ConnHdlr
2144{
2145 var template (present) PDU_BSSGP exp_rx;
2146 exp_rx := f_send_paging_cs(p4, 0, true);
2147
2148 /* FIXME: make sure the relevant BVCs/BSS are connected to the ports! */
2149 var ro_default defaults := {};
2150 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
2151 var default d := activate(as_paging_sig_pcu(i, exp_rx, g_roi));
2152 defaults := defaults & { d };
2153 }
2154 f_sleep(2.0);
2155 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2156 deactivate(defaults[i]);
2157 }
2158 log("Paging received on PCU ", g_roi);
2159
2160 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
2161 var boolean rx_on_i := ro_integer_contains(g_roi, i);
2162 var boolean exp_on_i := ro_integer_contains(exp_on_pcu_idx, i);
2163 if (exp_on_i and not rx_on_i) {
2164 setverdict(fail, "PS-PAGING not received on ", mp_nsconfig_pcu[i].nsei);
2165 }
2166 if (not exp_on_i and rx_on_i) {
2167 setverdict(fail, "PS-PAGING not expected but received on ", mp_nsconfig_pcu[i].nsei);
2168 }
2169 }
2170 setverdict(pass);
2171}
2172
2173/* CS-PAGING on SIG-BVC for BSS Area */
2174private function f_TC_paging_cs_sig_bss(charstring id) runs on BSSGP_ConnHdlr
2175{
2176 /* we expect the paging to arrive on all three NSE */
2177 f_send_paging_cs_exp_multi(ts_BssgpP4BssArea, 0, {0, 1, 2});
2178}
2179testcase TC_paging_cs_sig_bss() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002180 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002181 f_start_handlers(refers(f_TC_paging_cs_sig_bss), testcasename(), 13);
Harald Welte0e188242020-11-22 21:46:48 +01002182 f_cleanup();
2183}
2184
2185/* CS-PAGING on SIG-BVC for Location Area */
2186private function f_TC_paging_cs_sig_lac(charstring id) runs on BSSGP_ConnHdlr
2187{
Daniel Willmannd4fb73c2020-12-07 13:57:17 +01002188 /* The first LAC (13135) is shared by all three NSEs */
2189 f_send_paging_cs_exp_multi(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, {0, 1, 2});
2190 /* Reset state */
2191 g_roi := {};
2192 /* Make LAC (13300) available on pcu index 2 */
2193 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
2194 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 +01002195}
2196testcase TC_paging_cs_sig_lac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002197 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002198 f_start_handlers(refers(f_TC_paging_cs_sig_lac), testcasename(), 14);
Harald Welte0e188242020-11-22 21:46:48 +01002199 f_cleanup();
2200}
2201
Harald Welte7462a592020-11-23 22:07:07 +01002202/* CS-PAGING on SIG-BVC for unknown Location Area */
2203private function f_TC_paging_cs_sig_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
2204{
2205 var GSM_Types.LocationAreaIdentification unknown_la := {
2206 mcc_mnc := '567F99'H,
2207 lac := 33333
2208 };
2209 f_send_paging_cs_exp_no_bss(ts_BssgpP4LAC(unknown_la), 0, true);
2210}
2211testcase TC_paging_cs_sig_lac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002212 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002213 f_start_handlers(refers(f_TC_paging_cs_sig_lac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002214 f_cleanup();
2215}
2216
Harald Welte0e188242020-11-22 21:46:48 +01002217/* CS-PAGING on SIG-BVC for Routeing Area */
2218private function f_TC_paging_cs_sig_rac(charstring id) runs on BSSGP_ConnHdlr
2219{
Daniel Willmannd4fb73c2020-12-07 13:57:17 +01002220 /* Only PCU index 0 has a matching BVC with the RA ID */
Harald Welte0e188242020-11-22 21:46:48 +01002221 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 +01002222 g_roi := {};
2223 /* PCU index 1 and 2 have a matching BVC with the RA ID */
2224 f_send_paging_cs_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[2].cell_id.ra_id), 0, {1, 2});
2225 g_roi := {};
2226 /* PCU index 2 has two matching BVCs with the RA ID */
2227 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
2228 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 +01002229}
2230testcase TC_paging_cs_sig_rac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002231 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002232 f_start_handlers(refers(f_TC_paging_cs_sig_rac), testcasename(), 15);
Harald Welte0e188242020-11-22 21:46:48 +01002233 f_cleanup();
2234}
2235
Harald Welte7462a592020-11-23 22:07:07 +01002236/* CS-PAGING on SIG-BVC for unknown Routeing Area */
2237private function f_TC_paging_cs_sig_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
2238{
2239 var RoutingAreaIdentification unknown_ra := {
2240 lai := {
2241 mcc_mnc := '567F99'H,
2242 lac := 33333
2243 },
2244 rac := 254
2245 };
2246 f_send_paging_cs_exp_no_bss(ts_BssgpP4RAC(unknown_ra), 0, true);
2247}
2248testcase TC_paging_cs_sig_rac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002249 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002250 f_start_handlers(refers(f_TC_paging_cs_sig_rac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002251 f_cleanup();
2252}
2253
Harald Welte0e188242020-11-22 21:46:48 +01002254/* CS-PAGING on SIG-BVC for BVCI (one cell) */
2255private function f_TC_paging_cs_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
2256{
2257 f_send_paging_cs_exp_multi(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, {0});
2258}
2259testcase TC_paging_cs_sig_bvci() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002260 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002261 f_start_handlers(refers(f_TC_paging_cs_sig_bvci), testcasename(), 16);
Harald Welte0e188242020-11-22 21:46:48 +01002262 f_cleanup();
2263}
2264
Harald Welte7462a592020-11-23 22:07:07 +01002265/* CS-PAGING on SIG-BVC for unknown BVCI */
2266private function f_TC_paging_cs_sig_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
2267{
2268 f_send_paging_cs_exp_no_bss(ts_BssgpP4Bvci(33333), 0, true);
2269}
2270testcase TC_paging_cs_sig_bvci_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002271 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002272 f_start_handlers(refers(f_TC_paging_cs_sig_bvci_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002273 f_cleanup();
2274}
2275
Harald Welte4f91c3b2020-12-09 12:25:51 +01002276/***********************************************************************
2277 * FLUSH-LL procedure
2278 ***********************************************************************/
2279
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002280private function f_TC_flush_ll(charstring id) runs on BSSGP_ConnHdlr {
2281 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
2282 var integer i;
2283 for (i := 0; i < 10; i := i+1) {
2284 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_FLUSH_LL(g_pars.tlli, bvci, bvci_new := bvci);
2285 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2286 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_FLUSH_LL(g_pars.tlli, bvci, bvci_new := bvci);
2287
2288 f_sgsn2pcu(pdu_tx, pdu_rx, use_sig := true);
2289
2290 pdu_tx := ts_BSSGP_FLUSH_LL_ACK(g_pars.tlli, int2oct(0, 1), 23, bvci_new := bvci);
2291 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2292 pdu_rx := tr_BSSGP_FLUSH_LL_ACK(g_pars.tlli, int2oct(0, 1), 23, bvci_new := bvci);
2293
2294 f_pcu2sgsn(pdu_tx, pdu_rx, use_sig := true);
2295 }
2296 setverdict(pass);
2297}
2298testcase TC_flush_ll() runs on test_CT
2299{
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002300 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002301 f_start_handlers(refers(f_TC_flush_ll), testcasename(), 6);
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002302 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002303 f_cleanup();
2304}
Harald Welte6dc2ac42020-11-16 09:16:17 +01002305
Harald Welte4f91c3b2020-12-09 12:25:51 +01002306/***********************************************************************
2307 * SGSN-INVOKE-TRACE procedure
2308 ***********************************************************************/
2309
Harald Weltef8e5c5d2020-11-27 22:37:23 +01002310private altstep as_bssgp_g_pcu_count(integer pcu_idx, template (present) PDU_BSSGP exp_rx, inout ro_integer roi)
2311runs on GlobalTest_CT {
2312[] G_PCU[pcu_idx].receive(exp_rx) from g_pcu[pcu_idx].vc_BSSGP {
2313 if (ro_integer_contains(roi, pcu_idx)) {
2314 setverdict(fail, "Received multiple on same SIG BVC");
2315 }
2316 roi := roi & { pcu_idx };
2317 repeat;
2318 }
2319}
2320/* send a INVOKE-TRACE from SGSN and expect to receive a copy on each NSE */
2321testcase TC_trace() runs on GlobalTest_CT
2322{
2323 var BSSGP_ConnHdlr vc_conn;
2324 f_init();
2325 f_global_init();
2326
2327 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_INVOKE_TRACE('23'O, '4321'O);
2328 var template (present) PDU_BSSGP exp_rx := ts_BSSGP_INVOKE_TRACE('23'O, '4321'O);
2329
2330 var ro_default defaults := {};
2331 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2332 activate(as_bssgp_g_pcu_count(i, exp_rx, g_roi));
2333 }
2334 G_SGSN[0].send(pdu_tx);
2335 f_sleep(2.0);
2336 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2337 deactivate(defaults[i]);
2338 }
2339
2340 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2341 if (not ro_integer_contains(g_roi, i)) {
2342 setverdict(fail, "Failed to receive TRACE on PCU index ", i);
2343 }
2344 }
2345 setverdict(pass);
2346
2347 f_cleanup();
2348}
2349
Harald Welte4f91c3b2020-12-09 12:25:51 +01002350/***********************************************************************
2351 * LLC-DISCARDED procedure
2352 ***********************************************************************/
2353
Harald Weltec0351d12020-11-27 22:49:02 +01002354private function f_TC_llc_discarded(charstring id) runs on BSSGP_ConnHdlr {
2355 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
2356
2357 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_LLC_DISCARDED(g_pars.tlli, 23, bvci, 2342);
2358 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2359 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_LLC_DISCARDED(g_pars.tlli, 23, bvci, 2342);
2360
2361 f_pcu2sgsn(pdu_tx, pdu_rx, use_sig := true);
2362
2363 setverdict(pass);
2364}
2365/* Send a LLC-DISCARDED from BSS side and expect it to show up on SGSN (SIG BVC) */
2366testcase TC_llc_discarded() runs on test_CT
2367{
Harald Weltec0351d12020-11-27 22:49:02 +01002368 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002369 f_start_handlers(refers(f_TC_llc_discarded), testcasename(), 6);
Harald Weltec0351d12020-11-27 22:49:02 +01002370 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Weltec0351d12020-11-27 22:49:02 +01002371 f_cleanup();
2372}
2373
Harald Welte4f91c3b2020-12-09 12:25:51 +01002374/***********************************************************************
2375 * OVERLOAD procedure
2376 ***********************************************************************/
2377
Harald Weltef20af412020-11-28 16:11:11 +01002378/* Send an OVERLOAD from SGSN side and expect it to show up on each PCU (SIG BVC) */
2379testcase TC_overload() runs on GlobalTest_CT
2380{
2381 f_init();
2382 f_global_init();
2383
2384 var template (value) PDU_BSSGP pdu_tx := ts_OVERLOAD('1'B);
2385 var template (present) PDU_BSSGP exp_rx := tr_OVERLOAD('1'B);
2386
2387 var ro_default defaults := {};
2388 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2389 activate(as_bssgp_g_pcu_count(i, exp_rx, g_roi));
2390 }
2391 G_SGSN[0].send(pdu_tx);
2392 f_sleep(2.0);
2393 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2394 deactivate(defaults[i]);
2395 }
2396
2397 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2398 if (not ro_integer_contains(g_roi, i)) {
2399 setverdict(fail, "Failed to receive OVERLOAD on PCU index ", i);
2400 }
2401 }
2402 setverdict(pass);
2403
2404 f_cleanup();
2405}
2406
Harald Welte4f91c3b2020-12-09 12:25:51 +01002407/***********************************************************************
2408 * BVC-BLOCK / BVC-UNBLOCK procedure
2409 ***********************************************************************/
2410
Harald Welte239aa502020-11-24 23:14:20 +01002411private function f_block_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2412{
2413 var BSSGP_BVC_CT bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2414 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2415 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2416
2417 SGSN_MGMT.clear;
2418 PCU_MGMT.clear;
2419
2420 /* block the PTP BVC from the PCU side */
2421 PCU_MGMT.send(BssgpBlockRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to bvc_ct;
2422 /* expect state on both PCU and SGSN side to change */
2423 interleave {
2424 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_BLOCKED)) from bvc_ct;
2425 [] SGSN_MGMT.receive(tr_BssgpStsInd(*, bvc_cfg.bvci, BVC_S_BLOCKED));
2426 }
2427 setverdict(pass);
2428}
2429testcase TC_bvc_block_ptp() runs on test_CT
2430{
2431 f_init();
2432 f_sleep(1.0);
2433 f_block_ptp_bvc_from_pcu(0, 0);
2434 f_cleanup();
2435}
2436
2437private function f_unblock_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2438{
2439 var BSSGP_BVC_CT bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2440 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2441 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2442
2443 SGSN_MGMT.clear;
2444 PCU_MGMT.clear;
2445
2446 /* block the PTP BVC from the PCU side */
2447 PCU_MGMT.send(BssgpUnblockRequest:{}) to bvc_ct;
2448 /* expect state on both PCU and SGSN side to change */
2449 interleave {
2450 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_UNBLOCKED)) from bvc_ct;
2451 [] SGSN_MGMT.receive(tr_BssgpStsInd(*, bvc_cfg.bvci, BVC_S_UNBLOCKED));
2452 }
2453 setverdict(pass);
2454}
2455testcase TC_bvc_unblock_ptp() runs on test_CT
2456{
2457 f_init();
2458 f_sleep(1.0);
2459 f_block_ptp_bvc_from_pcu(0, 0);
2460 f_sleep(1.0);
2461 f_unblock_ptp_bvc_from_pcu(0, 0);
2462 f_cleanup();
2463}
2464
Harald Welte4f91c3b2020-12-09 12:25:51 +01002465/***********************************************************************
2466 * BVC-RESET procedure
2467 ***********************************************************************/
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002468private altstep as_count_bvc_reset(integer sgsn_idx, BssgpBvci bvci, inout roro_integer roroi)
2469runs on test_CT {
2470 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(sgsn_idx, bvci);
2471 [] SGSN_MGMT.receive(BssgpResetIndication:{bvci}) from sgsn_bvc_ct {
2472 roroi[sgsn_idx] := roroi[sgsn_idx] & { bvci };
2473 repeat;
2474 }
2475}
Harald Welte60a8ec72020-11-25 17:12:53 +01002476private altstep as_ignore_status(BSSGP_BVC_MGMT_PT pt) {
2477[] pt.receive(BssgpStatusIndication:?) { repeat; }
2478}
2479private function f_get_sgsn_bvc_ct(integer sgsn_idx, BssgpBvci bvci) runs on test_CT return BSSGP_BVC_CT {
2480 for (var integer i := 0; i < lengthof(g_sgsn[sgsn_idx].cfg.bvc); i := i+1) {
2481 if (g_sgsn[sgsn_idx].cfg.bvc[i].bvci == bvci) {
2482 return g_sgsn[sgsn_idx].vc_BSSGP_BVC[i];
2483 }
2484 }
2485 return null;
2486}
2487private function f_reset_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2488{
2489 var BSSGP_BVC_CT pcu_bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2490 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2491 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002492 var ro_default defaults;
2493 var integer i;
Harald Welte60a8ec72020-11-25 17:12:53 +01002494
2495 SGSN_MGMT.clear;
2496 PCU_MGMT.clear;
2497
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002498 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
2499 g_roroi[i] := {};
2500 }
2501
Harald Welte60a8ec72020-11-25 17:12:53 +01002502 /* block the PTP BVC from the PCU side */
2503 PCU_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to pcu_bvc_ct;
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002504
Harald Welte60a8ec72020-11-25 17:12:53 +01002505 /* expect state on both PCU and SGSN side to change */
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002506 defaults := { activate(as_ignore_status(SGSN_MGMT)) };
2507
2508 /* Activate altsteps: One for each SGSN */
2509 for (i := 0; i < lengthof(g_sgsn); i := i+1) {
2510 var default d := activate(as_count_bvc_reset(i, bvc_cfg.bvci, g_roroi));
2511 defaults := defaults & { d };
Harald Welte60a8ec72020-11-25 17:12:53 +01002512 }
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002513
2514 timer T := 3.0;
2515 T.start;
2516 alt {
2517 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_BLOCKED)) from pcu_bvc_ct {
2518 g_roi := g_roi & { bvc_cfg.bvci };
2519 repeat;
2520 }
2521 [] T.timeout;
2522 }
2523
2524 for (i := 0; i < lengthof(defaults); i := i+1) {
2525 deactivate(defaults[i]);
2526 }
2527
2528 /* Check if BVC-RESET was received at all SGSNs */
2529 for (i := 0; i < lengthof(g_sgsn); i := i+1) {
2530 if (not ro_integer_contains(g_roroi[i], bvc_cfg.bvci)) {
2531 setverdict(fail, "Missing SGSN[", i, "] BVC-BLOCK of BVCI=", bvc_cfg.bvci);
2532 }
2533 }
2534
Harald Welte60a8ec72020-11-25 17:12:53 +01002535 setverdict(pass);
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002536 f_cleanup();
Harald Welte60a8ec72020-11-25 17:12:53 +01002537}
2538/* Send a BVC-RESET for a PTP BVC from the BSS side: expect it to propagate */
2539testcase TC_bvc_reset_ptp_from_bss() runs on test_CT
2540{
2541 f_init();
2542 f_sleep(3.0);
2543 f_reset_ptp_bvc_from_pcu(0, 0);
2544 f_cleanup();
2545}
2546
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002547private altstep as_count_bvc_block(integer sgsn_idx, BssgpBvci bvci, inout roro_integer roroi)
Harald Welte16786e92020-11-27 19:11:56 +01002548runs on test_CT {
2549 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(sgsn_idx, bvci);
2550 [] SGSN_MGMT.receive(tr_BssgpStsInd(?, bvci, BVC_S_BLOCKED)) from sgsn_bvc_ct {
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002551 roroi[sgsn_idx] := roroi[sgsn_idx] & { bvci };
Harald Welteb2647f72020-12-07 14:36:35 +01002552 repeat;
Harald Welte16786e92020-11-27 19:11:56 +01002553 }
2554}
2555/* reset the signaling BVC from one BSS; expect no signaling BVC reset on SGSN; but BVC-BLOCK for PTP */
2556testcase TC_bvc_reset_sig_from_bss() runs on test_CT {
2557
2558 f_init();
2559 f_sleep(3.0);
2560
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002561 for (var integer i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
2562 g_roroi[i] := {};
2563 }
2564
Harald Welte16786e92020-11-27 19:11:56 +01002565 /* Start BVC-RESET procedure for BVCI=0 */
2566 PCU_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to g_pcu[0].vc_BSSGP;
2567
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002568 /* Activate altsteps: One for each PTP BVC and SGSN within that PCUs NSE */
Harald Welte16786e92020-11-27 19:11:56 +01002569 var ro_default defaults := {};
2570 for (var integer i := 0; i < lengthof(g_pcu[0].cfg.bvc); i := i+1) {
2571 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[i];
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002572 for (var integer j := 0; j < lengthof(g_sgsn); j := j+1) {
2573 var default d := activate(as_count_bvc_block(j, bvcc.bvci, g_roroi));
2574 defaults := defaults & { d };
2575 }
Harald Welte16786e92020-11-27 19:11:56 +01002576 }
2577
2578 timer T := 3.0;
2579 T.start;
2580 alt {
2581 [] SGSN_MGMT.receive(BssgpResetIndication:{0}) {
2582 setverdict(fail, "BSS-side Reset of BVCI=0 should not propagate");
2583 }
2584 [] T.timeout;
2585 }
2586
2587 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2588 deactivate(defaults[i]);
2589 }
2590
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002591 /* check if BVC-block was received on all expected BVC/SGSN */
Harald Welte16786e92020-11-27 19:11:56 +01002592 for (var integer i := 0; i < lengthof(g_pcu[0].cfg.bvc); i := i+1) {
2593 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[i];
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002594 for (var integer j := 0; j < lengthof(g_sgsn); j := j+1) {
2595 if (not ro_integer_contains(g_roroi[j], bvcc.bvci)) {
2596 setverdict(fail, "Missing SGSN[", j, "] BVC-BLOCK of BVCI=", bvcc.bvci);
2597 }
Harald Welte16786e92020-11-27 19:11:56 +01002598 }
2599 }
2600
2601 /* check if BVC-block was not received on any unexpected BVC is not required as
2602 * such a message would basically run into 'no matching clause' */
Daniel Willmannf2590212020-12-04 14:20:50 +01002603 setverdict(pass);
Harald Welte16786e92020-11-27 19:11:56 +01002604 f_cleanup();
2605}
2606
Harald Welte60a8ec72020-11-25 17:12:53 +01002607private function f_reset_ptp_bvc_from_sgsn(integer pcu_idx, integer bvc_idx) runs on test_CT
2608{
2609 var BSSGP_BVC_CT pcu_bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2610 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2611 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2612 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(0, bvc_cfg.bvci);
2613 var default d;
2614
2615 SGSN_MGMT.clear;
2616 PCU_MGMT.clear;
2617
2618 /* block the PTP BVC from the PCU side */
2619 SGSN_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to sgsn_bvc_ct;
2620 /* expect state on both PCU and SGSN side to change */
2621 d := activate(as_ignore_status(PCU_MGMT));
2622 interleave {
2623 [] SGSN_MGMT.receive(tr_BssgpStsInd(?, bvc_cfg.bvci, BVC_S_BLOCKED)) from sgsn_bvc_ct;
2624 [] PCU_MGMT.receive(BssgpResetIndication:{bvc_cfg.bvci}) from pcu_bvc_ct;
2625 }
2626 deactivate(d);
2627 setverdict(pass);
2628}
2629/* Send a BVC-RESET for a PTP BVC from the SGSN side: expect it to propagate */
2630testcase TC_bvc_reset_ptp_from_sgsn() runs on test_CT
2631{
2632 f_init();
2633 f_sleep(3.0);
2634 f_reset_ptp_bvc_from_sgsn(0, 0);
2635 f_cleanup();
2636}
2637
Daniel Willmannef7015f2021-01-08 00:43:56 +01002638private altstep as_ignore_mgmt(BSSGP_BVC_MGMT_PT pt) {
2639 [] pt.receive {repeat; }
2640}
2641
Harald Welte16786e92020-11-27 19:11:56 +01002642private altstep as_count_bvc0_block(integer pcu_idx, Nsei nsei, inout ro_integer roi)
2643runs on test_CT {
2644 var BSSGP_CT pcu_ct := g_pcu[pcu_idx].vc_BSSGP;
2645 [] PCU_MGMT.receive(BssgpResetIndication:{0}) from pcu_ct {
2646 roi := roi & { nsei };
Daniel Willmannef7015f2021-01-08 00:43:56 +01002647 repeat;
Harald Welte16786e92020-11-27 19:11:56 +01002648 }
2649}
Daniel Willmannef7015f2021-01-08 00:43:56 +01002650
Harald Welte16786e92020-11-27 19:11:56 +01002651/* reset the signaling BVC from the SGSN; expect all signaling BVC on all BSS to be reset */
2652testcase TC_bvc_reset_sig_from_sgsn() runs on test_CT {
2653
2654 f_init();
2655 f_sleep(3.0);
2656
Daniel Willmannef7015f2021-01-08 00:43:56 +01002657 SGSN_MGMT.clear;
2658 PCU_MGMT.clear;
2659
Harald Welte16786e92020-11-27 19:11:56 +01002660 /* Start BVC-RESET procedure for BVCI=0 */
2661 SGSN_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to g_sgsn[0].vc_BSSGP;
2662
Daniel Willmannef7015f2021-01-08 00:43:56 +01002663 /* Defaults match in reverse activation order, this one is a catch-all for Status indications
2664 * and reset indications sent from other components (like the ptp_bvcs). If we don't drain
2665 * the port and a different message sits at the front we wait forever and fail the test.
2666 */
2667 var ro_default defaults := { activate(as_ignore_mgmt(PCU_MGMT)) };
2668
Harald Welte16786e92020-11-27 19:11:56 +01002669 /* Activate altsteps: One for each PCU NSE */
Harald Welte16786e92020-11-27 19:11:56 +01002670 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2671 var NSConfiguration nscfg := mp_nsconfig_pcu[i];
2672 var default d := activate(as_count_bvc0_block(i, nscfg.nsei, g_roi));
2673 defaults := defaults & { d };
2674 }
2675
2676 f_sleep(3.0);
2677
2678 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2679 deactivate(defaults[i]);
2680 }
2681
2682 /* check if BVC-block was received on all expected BVC */
2683 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2684 var NSConfiguration nscfg := mp_nsconfig_pcu[i];
2685 if (not ro_integer_contains(g_roi, nscfg.nsei)) {
2686 setverdict(fail, "Missing PCU-side BVC-RESET of BVCI=0 on PCU index ", i);
2687 }
2688 }
2689
2690 /* check if BVC-block was not received on any unexpected BVC is not required as
2691 * such a message would basically run into 'no matching clause' */
2692
2693 f_cleanup();
2694}
2695
Harald Welte299aa482020-12-09 15:10:55 +01002696/***********************************************************************
2697 * FLOW-CONTROL-BVC procedure
2698 ***********************************************************************/
2699
2700private altstep as_g_count_sgsn(integer sgsn_idx, inout ro_integer roi,
2701 template PDU_BSSGP exp_rx, template (omit) PDU_BSSGP tx_reply)
2702runs on GlobalTest_CT {
2703 [] G_SGSN[sgsn_idx].receive(exp_rx) {
2704 roi := roi & { sgsn_idx };
2705 if (ispresent(tx_reply)) {
2706 G_SGSN[sgsn_idx].send(tx_reply);
2707 }
Harald Welte5fb01742021-01-15 21:07:52 +01002708 repeat;
Harald Welte299aa482020-12-09 15:10:55 +01002709 }
2710}
2711/* Send FC-BVC from simulated PCU; expect each SGSN to receive it; expect PCU to receive ACK */
2712testcase TC_fc_bvc() runs on GlobalTest_CT
2713{
2714 f_init();
2715 f_global_init_ptp();
2716
2717 var template (value) PDU_BSSGP pdu_tx := t_BVC_FC_BVC(10240, 2000, 1024, 1000, '01'O);
2718 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2719 var template (present) PDU_BSSGP pdu_rx := tr_BVC_FC_BVC(10240, 2000, 1024, 1000, '01'O);
2720 var template (omit) PDU_BSSGP ack_tx :=
2721 t_BVC_FC_BVC_ACK(pdu_tx.pDU_BSSGP_FLOW_CONTROL_BVC.tag.unstructured_Value);
2722
2723 /* Send a FC-BVC from BSS to gbproxy, expect an ACK in response */
2724 G_PCU[0].send(pdu_tx);
2725
2726 /* Activate altsteps: One for each SGSN-side PTP BVC port */
2727 var ro_default defaults := {};
2728 for (var integer i := 0; i < lengthof(g_sgsn); i := i+1) {
2729 var default d := activate(as_g_count_sgsn(i, g_roi, pdu_rx, ack_tx));
2730 defaults := defaults & { d };
2731 }
2732
2733 f_sleep(3.0);
2734
2735 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2736 deactivate(defaults[i]);
2737 }
2738
2739 /* check if BVC-block was received on all expected BVC */
2740 for (var integer i := 0; i < lengthof(g_sgsn); i := i+1) {
2741 if (not ro_integer_contains(g_roi, i)) {
2742 setverdict(fail, "Missing BVC-FLOW-CONTROL on SGSN index ", i);
2743 }
2744 }
2745
2746 /* Expect ACK on PCU side */
2747 G_PCU[0].receive(ack_tx);
2748
2749 setverdict(pass);
2750
2751 f_cleanup();
2752}
2753
Harald Weltecc3894b2020-12-09 16:50:12 +01002754/***********************************************************************
2755 * FLOW-CONTROL-MS procedure
2756 ***********************************************************************/
2757
2758private function f_TC_fc_ms(charstring id) runs on BSSGP_ConnHdlr {
2759 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
2760
2761 var template (value) PDU_BSSGP fc_tx := ts_BVC_FC_MS(g_pars.tlli, 100, 200, '12'O);
2762 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2763 var template (present) PDU_BSSGP fc_rx := tr_BVC_FC_MS(g_pars.tlli, 100, 200, '12'O);
2764 var template (value) PDU_BSSGP ack_tx := ts_BVC_FC_MS_ACK(g_pars.tlli, '12'O);
2765
2766 f_pcu2sgsn(fc_tx, fc_rx, use_sig := false);
2767 f_sgsn2pcu(ack_tx, ack_tx, use_sig := false);
2768
2769 setverdict(pass);
2770}
2771/* Send a FLOW-CONTROL-MS from BSS side and expect it to show up on SGSN (PTP BVC) */
2772testcase TC_fc_ms() runs on test_CT
2773{
Harald Weltecc3894b2020-12-09 16:50:12 +01002774 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002775 f_start_handlers(refers(f_TC_fc_ms), testcasename(), 21);
Harald Weltecc3894b2020-12-09 16:50:12 +01002776 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Weltecc3894b2020-12-09 16:50:12 +01002777 f_cleanup();
2778}
2779
Harald Welted6f89812021-01-16 18:57:49 +01002780/***********************************************************************
2781 * MS-REGISTRATION ENQUIRY procedure
2782 ***********************************************************************/
Harald Weltecc3894b2020-12-09 16:50:12 +01002783
Harald Welted6f89812021-01-16 18:57:49 +01002784private function f_TC_ms_reg_enq(charstring id) runs on BSSGP_ConnHdlr
2785{
2786 f_pcu2sgsn(ts_BSSGP_MS_REG_ENQ(g_pars.imsi), tr_BSSGP_MS_REG_ENQ(g_pars.imsi), use_sig := true);
2787 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);
2788}
2789testcase TC_ms_reg_enq() runs on test_CT
2790{
2791 f_init();
2792 f_start_handlers(refers(f_TC_ms_reg_enq), testcasename(), 22);
2793 f_cleanup();
2794}
Harald Welte299aa482020-12-09 15:10:55 +01002795
Harald Weltef86f1852021-01-16 21:56:17 +01002796/***********************************************************************
2797 * RIM (RAN Information Management)
2798 ***********************************************************************/
2799
2800/* Our tests here are rather synthetic, as they don't reflect normal message flows
2801 as they would be observed in a live network. However, for testing gbproxy, this shouldn't
2802 matter as gbproxy is not concerned with anything but the source / destination routing
2803 information */
2804
2805/* gbproxy must route all unknown RIM Routing Info (Cell Id) to the SGSN. We just define
2806 one here of which we know it is not used among the [simulated] PCUs */
2807const BssgpCellId cell_id_sgsn := {
2808 ra_id := {
2809 lai := {
2810 mcc_mnc := c_mcc_mnc,
2811 lac := 65534
2812 },
2813 rac := 0
2814 },
2815 cell_id := 65533
2816};
2817
2818/* Send 'tx' on PTP-BVCI from PCU; expect 'rx' on any of our SGSN (RIM can be routed anywhere) */
2819friend function f_rim_pcu2sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
2820 integer pcu_idx := 0) runs on GlobalTest_CT {
2821 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +01002822 timer T := 2.0;
Harald Weltef86f1852021-01-16 21:56:17 +01002823
2824 RIM_PCU[pcu_idx].send(tx);
2825 T.start;
2826 alt {
2827 [] any from RIM_SGSN.receive(exp_rx) {
2828 setverdict(pass);
2829 }
2830 [] any from RIM_SGSN.receive(PDU_BSSGP:?) -> value rx {
2831 setverdict(fail, "Unexpected BSSGP on SGSN side: ", rx);
2832 mtc.stop;
2833 }
2834 [] T.timeout {
2835 setverdict(fail, "Timeout waiting for BSSGP on SGSN side: ", exp_rx);
2836 mtc.stop;
2837 }
2838 }
2839}
2840
2841/* Send 'tx' on PTP-BVCI from SGSN; expect 'rx' on PCU */
2842friend function f_rim_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
2843 integer sgsn_idx := 0, integer pcu_idx := 0) runs on GlobalTest_CT {
2844 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +01002845 timer T := 2.0;
Harald Weltef86f1852021-01-16 21:56:17 +01002846
2847 RIM_SGSN[sgsn_idx].send(tx);
2848 T.start;
2849 alt {
2850 [] RIM_PCU[pcu_idx].receive(exp_rx) {
2851 setverdict(pass);
2852 }
2853 [] RIM_PCU[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
2854 setverdict(fail, "Unexpected BSSGP on PCU side: ", rx);
2855 mtc.stop;
2856 }
2857 [] T.timeout {
2858 setverdict(fail, "Timeout waiting for BSSGP on PCU side: ", exp_rx);
2859 mtc.stop;
2860 }
2861 }
2862}
2863
2864/* Send 'tx' on PTP-BVCI from SRC-PCU; expect 'rx' on DST-PCU */
2865friend function f_rim_pcu2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
2866 integer src_pcu_idx, integer dst_pcu_idx) runs on GlobalTest_CT {
2867 var integer rx_idx;
2868 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +01002869 timer T := 2.0;
Harald Weltef86f1852021-01-16 21:56:17 +01002870
2871 RIM_PCU[src_pcu_idx].send(tx);
2872 T.start;
2873 alt {
2874 [] RIM_PCU[dst_pcu_idx].receive(exp_rx) -> value rx{
2875 setverdict(pass);
2876 }
2877 [] any from RIM_PCU.receive(exp_rx) -> @index value rx_idx {
2878 setverdict(fail, "Received RIM on wrong PCU[", rx_idx ,"], expected on PCU[", dst_pcu_idx, "]");
2879 }
2880 [] any from RIM_SGSN.receive(exp_rx) {
2881 setverdict(fail, "Received RIM on SGSN but expected it on other PCU");
2882 }
2883 [] any from RIM_SGSN.receive(PDU_BSSGP:?) -> value rx {
2884 setverdict(fail, "Unexpected BSSGP on SGSN side: ", rx);
2885 mtc.stop;
2886 }
2887 [] T.timeout {
2888 setverdict(fail, "Timeout waiting for BSSGP on SGSN side: ", exp_rx);
2889 mtc.stop;
2890 }
2891 }
2892}
2893
2894
2895type function rim_fn(integer sgsn_idx, integer pcu_idx, integer bvc_idx) runs on GlobalTest_CT;
2896
2897/* helper function for the RIM test cases: Execute 'fn' for each BVC on each PCU for
2898 each SGSN */
2899private function f_rim_iterator(rim_fn fn) runs on GlobalTest_CT
2900{
2901 var integer sgsn_idx, pcu_idx, bvc_idx;
2902 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx+1) {
2903 for (pcu_idx := 0; pcu_idx < lengthof(g_pcu); pcu_idx := pcu_idx+1) {
2904 for (bvc_idx := 0; bvc_idx < lengthof(g_pcu[pcu_idx].cfg.bvc); bvc_idx := bvc_idx+1) {
2905 log("Testing RIM SGSN[", sgsn_idx, "] <-> PCU[", pcu_idx, "][", bvc_idx, "]");
2906 fn.apply(sgsn_idx, pcu_idx, bvc_idx);
2907 }
2908 }
2909 }
2910}
2911
2912/* RAN-INFORMATION-REQUEST */
2913private function f_TC_rim_info_req(integer sgsn_idx, integer pcu_idx, integer bvc_idx := 0)
2914runs on GlobalTest_CT
2915{
2916 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
2917 var template (value) RIM_Routing_Information ri_pcu;
2918 var template (value) RIM_Routing_Information ri_sgsn;
2919 var template (value) RAN_Information_Request_RIM_Container cont;
2920
2921 ri_sgsn := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, t_RIM_Routing_Address_cid(cell_id_sgsn));
2922 ri_pcu := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, t_RIM_Routing_Address_cid(cell_id));
2923 cont := ts_RAN_Information_Request_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
2924 ts_RIM_Sequence_Number(0),
2925 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
2926 f_rim_pcu2sgsn(ts_RAN_INFORMATION_REQUEST(dst := ri_sgsn, src := ri_pcu, cont := cont),
2927 tr_RAN_INFORMATION_REQUEST(dst := ri_sgsn, src := ri_pcu, cont := cont),
2928 pcu_idx);
2929 f_rim_sgsn2pcu(ts_RAN_INFORMATION_REQUEST(dst := ri_pcu, src := ri_sgsn, cont := cont),
2930 tr_RAN_INFORMATION_REQUEST(dst := ri_pcu, src := ri_sgsn, cont := cont),
2931 sgsn_idx, pcu_idx);
2932}
2933testcase TC_rim_info_req() runs on GlobalTest_CT
2934{
2935 f_init();
2936 f_global_init();
2937 f_rim_iterator(refers(f_TC_rim_info_req));
2938 f_cleanup();
2939}
2940
2941/* RAN-INFORMATION */
2942private function f_TC_rim_info(integer sgsn_idx, integer pcu_idx, integer bvc_idx := 0)
2943runs on GlobalTest_CT
2944{
2945 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
2946 var template (value) RIM_Routing_Information ri_pcu;
2947 var template (value) RIM_Routing_Information ri_sgsn;
2948 var template (value) RAN_Information_RIM_Container cont;
2949
2950 ri_sgsn := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, t_RIM_Routing_Address_cid(cell_id_sgsn));
2951 ri_pcu := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, t_RIM_Routing_Address_cid(cell_id));
2952 cont := ts_RAN_Information_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
2953 ts_RIM_Sequence_Number(0),
2954 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
2955 f_rim_pcu2sgsn(ts_PDU_BSSGP_RAN_INFORMATION(dst := ri_sgsn, src := ri_pcu, cont := cont),
2956 tr_PDU_BSSGP_RAN_INFORMATION(dst := ri_sgsn, src := ri_pcu, cont := cont),
2957 pcu_idx);
2958 f_rim_sgsn2pcu(ts_PDU_BSSGP_RAN_INFORMATION(dst := ri_pcu, src := ri_sgsn, cont := cont),
2959 tr_PDU_BSSGP_RAN_INFORMATION(dst := ri_pcu, src := ri_sgsn, cont := cont),
2960 sgsn_idx, pcu_idx);
2961}
2962testcase TC_rim_info() runs on GlobalTest_CT
2963{
2964 f_init();
2965 f_global_init();
2966 f_rim_iterator(refers(f_TC_rim_info));
2967 f_cleanup();
2968}
2969
2970/* RAN-INFORMATION-ACK */
2971private function f_TC_rim_info_ack(integer sgsn_idx, integer pcu_idx, integer bvc_idx := 0)
2972runs on GlobalTest_CT
2973{
2974 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
2975 var template (value) RIM_Routing_Information ri_pcu;
2976 var template (value) RIM_Routing_Information ri_sgsn;
2977 var template (value) RAN_Information_Ack_RIM_Container cont;
2978
2979 ri_sgsn := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, t_RIM_Routing_Address_cid(cell_id_sgsn));
2980 ri_pcu := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, t_RIM_Routing_Address_cid(cell_id));
2981 cont := ts_RAN_Information_Ack_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
2982 ts_RIM_Sequence_Number(0));
2983 f_rim_pcu2sgsn(ts_PDU_BSSGP_RAN_INFORMATION_ACK(dst := ri_sgsn, src := ri_pcu, cont := cont),
2984 tr_PDU_BSSGP_RAN_INFORMATION_ACK(dst := ri_sgsn, src := ri_pcu, cont := cont),
2985 pcu_idx);
2986 f_rim_sgsn2pcu(ts_PDU_BSSGP_RAN_INFORMATION_ACK(dst := ri_pcu, src := ri_sgsn, cont := cont),
2987 tr_PDU_BSSGP_RAN_INFORMATION_ACK(dst := ri_pcu, src := ri_sgsn, cont := cont),
2988 sgsn_idx, pcu_idx);
2989}
2990testcase TC_rim_info_ack() runs on GlobalTest_CT
2991{
2992 f_init();
2993 f_global_init();
2994 f_rim_iterator(refers(f_TC_rim_info_ack));
2995 f_cleanup();
2996}
2997
2998/* RAN-INFORMATION-ERROR */
2999private function f_TC_rim_info_error(integer sgsn_idx, integer pcu_idx, integer bvc_idx := 0)
3000runs on GlobalTest_CT
3001{
3002 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
3003 var template (value) RIM_Routing_Information ri_pcu;
3004 var template (value) RIM_Routing_Information ri_sgsn;
3005 var template (value) RAN_Information_Error_RIM_Container cont;
3006
3007 ri_sgsn := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, t_RIM_Routing_Address_cid(cell_id_sgsn));
3008 ri_pcu := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, t_RIM_Routing_Address_cid(cell_id));
3009 cont := ts_RAN_Information_Error_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3010 ts_BSSGP_CAUSE(BSSGP_CAUSE_EQUIMENT_FAILURE),
3011 omit, valueof(t_BVC_UNBLOCK(23)));
3012 f_rim_pcu2sgsn(ts_PDU_BSSGP_RAN_INFORMATION_ERROR(dst := ri_sgsn, src := ri_pcu, cont := cont),
3013 tr_PDU_BSSGP_RAN_INFORMATION_ERROR(dst := ri_sgsn, src := ri_pcu, cont := cont),
3014 pcu_idx);
3015 f_rim_sgsn2pcu(ts_PDU_BSSGP_RAN_INFORMATION_ERROR(dst := ri_pcu, src := ri_sgsn, cont := cont),
3016 tr_PDU_BSSGP_RAN_INFORMATION_ERROR(dst := ri_pcu, src := ri_sgsn, cont := cont),
3017 sgsn_idx, pcu_idx);
3018}
3019testcase TC_rim_info_error() runs on GlobalTest_CT
3020{
3021 f_init();
3022 f_global_init();
3023 f_rim_iterator(refers(f_TC_rim_info_error));
3024 f_cleanup();
3025}
3026
3027/* RAN-INFORMATION-APPLICATION-ERROR */
3028private function f_TC_rim_info_app_error(integer sgsn_idx, integer pcu_idx, integer bvc_idx := 0)
3029runs on GlobalTest_CT
3030{
3031 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
3032 var template (value) RIM_Routing_Information ri_pcu;
3033 var template (value) RIM_Routing_Information ri_sgsn;
3034 var template (value) Application_Error_Container app_cont;
3035 var template (value) RAN_Information_Application_Error_RIM_Container cont;
3036
3037 ri_sgsn := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, t_RIM_Routing_Address_cid(cell_id_sgsn));
3038 ri_pcu := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, t_RIM_Routing_Address_cid(cell_id));
3039 app_cont := tsu_Application_Error_Container_NACC(cell_id, 23,
3040 tsu_Application_Container_IE_NACC_req(cell_id));
3041 cont := ts_RAN_Information_Application_Error_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3042 ts_RIM_Sequence_Number(0),
3043 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP),
3044 omit, app_cont);
3045 f_rim_pcu2sgsn(ts_PDU_BSSGP_RAN_INFORMATION_APPLICATION_ERROR(dst := ri_sgsn, src := ri_pcu, cont := cont),
3046 tr_PDU_BSSGP_RAN_INFORMATION_APPLICATION_ERROR(dst := ri_sgsn, src := ri_pcu, cont := cont),
3047 pcu_idx);
3048 f_rim_sgsn2pcu(ts_PDU_BSSGP_RAN_INFORMATION_APPLICATION_ERROR(dst := ri_pcu, src := ri_sgsn, cont := cont),
3049 tr_PDU_BSSGP_RAN_INFORMATION_APPLICATION_ERROR(dst := ri_pcu, src := ri_sgsn, cont := cont),
3050 sgsn_idx, pcu_idx);
3051}
3052testcase TC_rim_info_app_error() runs on GlobalTest_CT
3053{
3054 f_init();
3055 f_global_init();
3056 f_rim_iterator(refers(f_TC_rim_info_app_error));
3057 f_cleanup();
3058}
3059
3060/* RAN-INFORMATION routing directly between PCUs, without SGSN involvement */
3061private function f_TC_rim_info_pcu2pcu(integer src_pcu_idx, integer src_bvc_idx,
3062 integer dst_pcu_idx, integer dst_bvc_idx)
3063runs on GlobalTest_CT
3064{
3065 var BssgpCellId cell_id_src := g_pcu[src_pcu_idx].cfg.bvc[src_bvc_idx].cell_id;
3066 var BssgpCellId cell_id_dst := g_pcu[dst_pcu_idx].cfg.bvc[dst_bvc_idx].cell_id;
3067 var template (value) RIM_Routing_Information ri_pcu_src;
3068 var template (value) RIM_Routing_Information ri_pcu_dst;
3069 var template (value) RAN_Information_RIM_Container cont;
3070
3071 log("Testing RIM PCU2PCU from PCU[", src_pcu_idx, "][", src_bvc_idx, "] to PCU[",
3072 dst_pcu_idx, "][", dst_bvc_idx, "]");
3073
3074 ri_pcu_src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID,
3075 t_RIM_Routing_Address_cid(cell_id_src));
3076 ri_pcu_dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID,
3077 t_RIM_Routing_Address_cid(cell_id_dst));
3078 cont := ts_RAN_Information_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3079 ts_RIM_Sequence_Number(0),
3080 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
3081 f_rim_pcu2pcu(ts_PDU_BSSGP_RAN_INFORMATION(dst := ri_pcu_dst, src := ri_pcu_src, cont := cont),
3082 tr_PDU_BSSGP_RAN_INFORMATION(dst := ri_pcu_dst, src := ri_pcu_src, cont := cont),
3083 src_pcu_idx, dst_pcu_idx);
3084}
3085testcase TC_rim_info_pcu2pcu() runs on GlobalTest_CT
3086{
3087 var integer src_pcu_idx, dst_pcu_idx;
3088 var integer src_bvc_idx, dst_bvc_idx;
3089 f_init();
3090 f_global_init();
3091
3092 for (src_pcu_idx := 0; src_pcu_idx < lengthof(g_pcu); src_pcu_idx := src_pcu_idx + 1) {
3093 for (src_bvc_idx := 0; src_bvc_idx < lengthof(g_pcu[src_pcu_idx].cfg.bvc); src_bvc_idx := src_bvc_idx + 1) {
3094 for (dst_pcu_idx := 0; dst_pcu_idx < lengthof(g_pcu); dst_pcu_idx := dst_pcu_idx + 1) {
3095 if (dst_pcu_idx == src_pcu_idx) {
3096 continue;
3097 }
3098
3099 for (dst_bvc_idx := 0; dst_bvc_idx < lengthof(g_pcu[dst_pcu_idx].cfg.bvc);
3100dst_bvc_idx := dst_bvc_idx + 1) {
3101 f_TC_rim_info_pcu2pcu(src_pcu_idx, src_bvc_idx, dst_pcu_idx, dst_bvc_idx);
3102 }
3103 }
3104 }
3105 }
3106
3107 f_cleanup();
3108}
3109
Harald Welte04358652021-01-17 13:48:13 +01003110/***********************************************************************
3111 * STATUS handling
3112 ***********************************************************************/
3113
3114/* BSSGP STATUS PDU must be routed based on inner "PDU In Error" message */
3115
3116/* generate a TMSI with NRI matching sgsn_idx + nri_idx */
3117private function f_gen_tmsi_for_sgsn_nri(integer sgsn_idx, integer nri_idx) runs on test_CT return OCT4
3118{
3119 var integer nri := mp_sgsn_nri[sgsn_idx][nri_idx];
3120 return f_gen_tmsi(0, nri_v := nri, nri_bitlen := mp_nri_bitlength);
3121}
3122
3123/* generate a TLLI with NRI matching sgsn_idx + nri_idx */
3124private function f_gen_tlli_for_sgsn_nri(integer sgsn_idx, integer nri_idx) runs on test_CT return OCT4
3125{
3126 var OCT4 p_tmsi := f_gen_tmsi_for_sgsn_nri(sgsn_idx, nri_idx);
3127 return f_gprs_tlli_from_tmsi(p_tmsi, TLLI_LOCAL);
3128}
3129
3130/* STATUS in uplink direction; expect routing by its NRI */
3131private function f_TC_status_ul(integer pcu_idx, integer sgsn_idx, PDU_BSSGP inner)
3132runs on GlobalTest_CT
3133{
3134 var template (value) PDU_BSSGP tx := ts_BSSGP_STATUS(omit, BSSGP_CAUSE_EQUIMENT_FAILURE, inner);
3135 var template (present) PDU_BSSGP exp_rx :=
3136 tr_BSSGP_STATUS(omit, BSSGP_CAUSE_EQUIMENT_FAILURE,
3137 tx.pDU_BSSGP_STATUS.pDU_in_Error.erroneous_BSSGP_PDU);
3138
3139 f_global_pcu2sgsn(tx, exp_rx, pcu_idx, sgsn_idx);
3140}
3141
3142/* STATUS in uplink direction; expect routing by its NRI */
3143private function f_TC_status_dl(integer sgsn_idx, integer pcu_idx, PDU_BSSGP inner)
3144runs on GlobalTest_CT
3145{
3146 var template (value) PDU_BSSGP tx := ts_BSSGP_STATUS(omit, BSSGP_CAUSE_EQUIMENT_FAILURE, inner);
3147 var template (present) PDU_BSSGP exp_rx :=
3148 tr_BSSGP_STATUS(omit, BSSGP_CAUSE_EQUIMENT_FAILURE,
3149 tx.pDU_BSSGP_STATUS.pDU_in_Error.erroneous_BSSGP_PDU);
3150
3151 f_global_sgsn2pcu(tx, exp_rx, sgsn_idx, pcu_idx);
3152}
3153
3154/* STATUS in uplink direction on SIG-BVC containing a TLLI; expect routing by its NRI */
3155testcase TC_status_sig_ul_tlli() runs on GlobalTest_CT
3156{
3157 var integer sgsn_idx, nri_idx;
3158
3159 f_init();
3160 f_global_init();
3161
3162 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3163 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx + 1) {
3164 /* some downlink PDU occurring on SIG-BVC with a TLLI */
3165 var OCT4 tlli := f_gen_tlli_for_sgsn_nri(sgsn_idx, nri_idx);
3166 var PDU_BSSGP inner := valueof(ts_BSSGP_FLUSH_LL(tlli, 2342));
3167
3168 f_TC_status_ul(0, sgsn_idx, inner);
3169 }
3170 }
3171
3172 f_cleanup();
3173}
3174
3175/* STATUS in uplink direction on SIG-BVC containing a TMSI; expect routing by its NRI */
3176testcase TC_status_sig_ul_tmsi() runs on GlobalTest_CT
3177{
3178 var integer sgsn_idx, nri_idx;
3179
3180 f_init();
3181 f_global_init();
3182
3183 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3184 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx + 1) {
3185 /* some downlink PDU occurring on SIG-BVC with a TMSI */
3186 const hexstring imsi := '001010123456789'H
3187 var OCT4 tmsi := f_gen_tmsi_for_sgsn_nri(sgsn_idx, nri_idx);
3188 var BssgpBvci bvci := g_pcu[0].cfg.bvc[0].bvci;
3189 var PDU_BSSGP inner := valueof(ts_BSSGP_CS_PAGING_PTMSI(bvci, imsi, oct2int(tmsi)));
3190 f_TC_status_ul(0, sgsn_idx, inner);
3191 }
3192 }
3193
3194 f_cleanup();
3195}
3196
3197
3198/* STATUS in uplink direction on PTP-BVC containing a TLLI; expect routing by its NRI */
3199testcase TC_status_ptp_ul_tlli() runs on GlobalTest_CT
3200{
3201 var integer sgsn_idx, nri_idx;
3202
3203 f_init();
3204 f_global_init_ptp();
3205
3206 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3207 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx + 1) {
3208 /* some downlink PDU occurring on PTP-BVC with a TLLI */
3209 var OCT4 tlli := f_gen_tlli_for_sgsn_nri(sgsn_idx, nri_idx);
3210 var PDU_BSSGP inner := valueof(ts_BSSGP_DL_UD(tlli, '2342'O));
3211
3212 f_TC_status_ul(0, sgsn_idx, inner);
3213 }
3214 }
3215
3216 f_cleanup();
3217}
3218
3219/* STATUS in uplink direction on PTP-BVC containing a TMSI; expect routing by its NRI */
3220testcase TC_status_ptp_ul_tmsi() runs on GlobalTest_CT
3221{
3222 var integer sgsn_idx, nri_idx;
3223
3224 f_init();
3225 f_global_init_ptp();
3226
3227 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3228 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx + 1) {
3229 /* some downlink PDU occurring on PTP-BVC with a TMSI */
3230 const hexstring imsi := '001010123456789'H
3231 var OCT4 tmsi := f_gen_tmsi_for_sgsn_nri(sgsn_idx, nri_idx);
3232 var BssgpBvci bvci := g_pcu[0].cfg.bvc[0].bvci;
3233 var PDU_BSSGP inner := valueof(ts_BSSGP_CS_PAGING_PTMSI(bvci, imsi, oct2int(tmsi)));
3234 f_TC_status_ul(0, sgsn_idx, inner);
3235 }
3236 }
3237
3238 f_cleanup();
3239}
3240
3241/* STATUS in downlink direction in SIG-BVC containing a BVCI; expect routing by it */
3242testcase TC_status_sig_dl_bvci() runs on GlobalTest_CT
3243{
3244 var integer sgsn_idx, pcu_idx, bvc_idx;
3245
3246 f_init();
3247 f_global_init();
3248
3249 /* test each BVC in each PCU from each SGSN */
3250 for (pcu_idx := 0; pcu_idx < lengthof(g_pcu); pcu_idx := pcu_idx + 1) {
3251 for (bvc_idx := 0; bvc_idx < lengthof(g_pcu[pcu_idx].cfg.bvc); bvc_idx := bvc_idx + 1) {
3252 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3253 /* some uplink PDU occurring on SIG-BVC containing a BVCI */
3254 var BssgpBvci bvci := g_pcu[pcu_idx].cfg.bvc[bvc_idx].bvci;
3255 var PDU_BSSGP inner := valueof(ts_BSSGP_LLC_DISCARDED('12345678'O, 1, bvci, 23));
3256 f_TC_status_dl(sgsn_idx, pcu_idx, inner);
3257 }
3258 }
3259 }
3260
3261 f_cleanup();
3262}
3263
3264/* STATUS in downlink direction in PTP-BVC; expect routing by BVCI */
3265testcase TC_status_ptp_dl_bvci() runs on GlobalTest_CT
3266{
3267 var integer sgsn_idx, pcu_idx, bvc_idx;
3268
3269 f_init();
3270 f_global_init_ptp();
3271
3272 /* test each BVC in each PCU from each SGSN */
3273 for (pcu_idx := 0; pcu_idx < lengthof(g_pcu); pcu_idx := pcu_idx + 1) {
3274 for (bvc_idx := 0; bvc_idx < lengthof(g_pcu[pcu_idx].cfg.bvc); bvc_idx := bvc_idx + 1) {
3275 var BssgpBvci bvci := g_pcu[pcu_idx].cfg.bvc[bvc_idx].bvci;
3276 f_global_ptp_connect_pcu_bvci(pcu_idx, bvci);
3277 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3278 f_global_ptp_connect_sgsn_bvci(sgsn_idx, bvci);
3279
3280 /* some uplink PDU occurring on PTP-BVC */
3281 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
3282 var PDU_BSSGP inner := valueof(ts_BSSGP_UL_UD('12345678'O, cell_id, '4223'O));
3283 f_TC_status_dl(sgsn_idx, pcu_idx, inner);
3284 }
3285 }
3286 }
3287
3288 f_cleanup();
3289}
3290
3291/* TODO: test case for DL-STATUS(SUSPEND/RESUME) containing RA-ID; expect routing by RA-ID */
3292/* 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 +01003293
Daniel Willmann423d8f42020-09-08 18:58:22 +02003294control {
3295 execute( TC_BVC_bringup() );
Harald Welte92686012020-11-15 21:45:49 +01003296 execute( TC_ul_unitdata() );
Harald Welte78d8db92020-11-15 23:27:27 +01003297 execute( TC_dl_unitdata() );
Harald Welte6dc2ac42020-11-16 09:16:17 +01003298 execute( TC_ra_capability() );
Daniel Willmannace3ece2020-11-16 19:53:26 +01003299 execute( TC_ra_capability_upd() );
Daniel Willmann165d6612020-11-19 14:27:29 +01003300 execute( TC_radio_status() );
Harald Welte3148a962021-01-17 11:15:28 +01003301 execute( TC_radio_status_tmsi() );
3302 execute( TC_radio_status_imsi() );
Daniel Willmannfa67f492020-11-19 15:48:05 +01003303 execute( TC_suspend() );
Daniel Willmann087a33d2020-11-19 15:58:43 +01003304 execute( TC_resume() );
Harald Weltef8e5c5d2020-11-27 22:37:23 +01003305 execute( TC_trace() );
Harald Weltec0351d12020-11-27 22:49:02 +01003306 execute( TC_llc_discarded() );
Harald Weltef20af412020-11-28 16:11:11 +01003307 execute( TC_overload() );
Harald Welte239aa502020-11-24 23:14:20 +01003308 execute( TC_bvc_block_ptp() );
3309 execute( TC_bvc_unblock_ptp() );
Harald Welte60a8ec72020-11-25 17:12:53 +01003310 execute( TC_bvc_reset_ptp_from_bss() );
Harald Welte16786e92020-11-27 19:11:56 +01003311 execute( TC_bvc_reset_sig_from_bss() );
Harald Welte60a8ec72020-11-25 17:12:53 +01003312 execute( TC_bvc_reset_ptp_from_sgsn() );
Harald Welte16786e92020-11-27 19:11:56 +01003313 execute( TC_bvc_reset_sig_from_sgsn() );
Harald Weltef6e59b02020-12-08 08:29:09 +01003314 if (mp_enable_bss_load_sharing) {
Harald Weltef8ef0282020-11-18 12:16:59 +01003315 /* don't enable this by default, as we don't yet have any automatic test setup for FR with 4 NS-VC */
3316 execute( TC_load_sharing_dl() );
3317 }
Harald Welte0e188242020-11-22 21:46:48 +01003318
3319 /* PAGING-PS over PTP BVC */
3320 execute( TC_paging_ps_ptp_bss() );
3321 execute( TC_paging_ps_ptp_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01003322 execute( TC_paging_ps_ptp_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003323 execute( TC_paging_ps_ptp_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01003324 execute( TC_paging_ps_ptp_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003325 execute( TC_paging_ps_ptp_bvci() );
Harald Welteb5a04aa2021-01-16 13:04:40 +01003326 execute( TC_paging_ps_ptp_bvci_imsi() );
Harald Welte7462a592020-11-23 22:07:07 +01003327 execute( TC_paging_ps_ptp_bvci_unknown() );
Harald Weltecf200072021-01-16 15:20:46 +01003328 execute( TC_paging_ps_reject_ptp_bvci() );
3329 execute( TC_paging_ps_reject_ptp_bvci_imsi() );
Harald Welte7595d562021-01-16 19:09:20 +01003330 execute( TC_dummy_paging_ps_ptp() );
Harald Welte0e188242020-11-22 21:46:48 +01003331
3332 /* PAGING-PS over SIG BVC */
3333 execute( TC_paging_ps_sig_bss() );
3334 execute( TC_paging_ps_sig_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01003335 execute( TC_paging_ps_sig_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003336 execute( TC_paging_ps_sig_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01003337 execute( TC_paging_ps_sig_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003338 execute( TC_paging_ps_sig_bvci() );
Harald Welteb5a04aa2021-01-16 13:04:40 +01003339 execute( TC_paging_ps_sig_bvci_imsi() );
Harald Welte7462a592020-11-23 22:07:07 +01003340 execute( TC_paging_ps_sig_bvci_unknown() );
Harald Weltecf200072021-01-16 15:20:46 +01003341 execute( TC_paging_ps_reject_sig_bvci() );
3342 execute( TC_paging_ps_reject_sig_bvci_imsi() );
Harald Welte7595d562021-01-16 19:09:20 +01003343 execute( TC_dummy_paging_ps_sig() );
Harald Welte0e188242020-11-22 21:46:48 +01003344
3345 /* PAGING-CS over PTP BVC */
3346 execute( TC_paging_cs_ptp_bss() );
3347 execute( TC_paging_cs_ptp_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01003348 execute( TC_paging_cs_ptp_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003349 execute( TC_paging_cs_ptp_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01003350 execute( TC_paging_cs_ptp_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003351 execute( TC_paging_cs_ptp_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01003352 execute( TC_paging_cs_ptp_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003353
3354 /* PAGING-CS over SIG BVC */
3355 execute( TC_paging_cs_sig_bss() );
3356 execute( TC_paging_cs_sig_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01003357 execute( TC_paging_cs_sig_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003358 execute( TC_paging_cs_sig_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01003359 execute( TC_paging_cs_sig_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003360 execute( TC_paging_cs_sig_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01003361 execute( TC_paging_cs_sig_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003362
Harald Weltef86f1852021-01-16 21:56:17 +01003363 /* RAN Information Management */
3364 execute( TC_rim_info_req() );
3365 execute( TC_rim_info() );
3366 execute( TC_rim_info_ack() );
3367 execute( TC_rim_info_error() );
3368 execute( TC_rim_info_app_error() );
3369 execute( TC_rim_info_pcu2pcu() );
3370
Harald Welte0e188242020-11-22 21:46:48 +01003371
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01003372 execute( TC_flush_ll() );
Harald Welte299aa482020-12-09 15:10:55 +01003373 execute( TC_fc_bvc() );
Harald Weltecc3894b2020-12-09 16:50:12 +01003374 execute( TC_fc_ms() );
Harald Welted6f89812021-01-16 18:57:49 +01003375 execute( TC_ms_reg_enq() );
Harald Welte04358652021-01-17 13:48:13 +01003376
3377 /* Uplink STATUS */
3378 execute( TC_status_sig_ul_tlli() );
3379 execute( TC_status_sig_ul_tmsi() );
3380 execute( TC_status_ptp_ul_tlli() );
3381 execute( TC_status_ptp_ul_tmsi() );
3382
3383 /* Downlink STATUS */
3384 execute( TC_status_sig_dl_bvci() );
3385 execute( TC_status_ptp_dl_bvci() );
Daniel Willmann423d8f42020-09-08 18:58:22 +02003386}
3387
3388
3389}