blob: 5ae153f50bbb6a4d936df10f0fad65ed58db4fa0 [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 Welteb978ed62020-12-12 14:01:11 +0100501/* count the number of unblocked BVCI for each SGSN NSE */
502private altstep as_count_unblocked4nse(integer sgsn_idx, inout roro_integer bvci_unblocked)
503runs on test_CT {
504 var BssgpStatusIndication bsi;
505 [] SGSN_MGMT.receive(BssgpStatusIndication:{g_sgsn[sgsn_idx].cfg.nsei, ?, BVC_S_UNBLOCKED}) -> value bsi {
506 bvci_unblocked[sgsn_idx] := bvci_unblocked[sgsn_idx] & { bsi.bvci };
507 /* 'repeat' until sufficient number of BVC-rest has been received on all SGSNs */
508 for (var integer i := 0; i < lengthof(bvci_unblocked); i := i+1) {
509 if (lengthof(bvci_unblocked[i]) < lengthof(g_sgsn[i].cfg.bvc)) {
510 repeat;
511 }
512 }
513 }
514}
515
Harald Welte425d3762020-12-09 14:33:18 +0100516function f_init(float t_guard := 30.0) runs on test_CT {
Harald Welteb978ed62020-12-12 14:01:11 +0100517 var roro_integer bvci_unblocked;
Harald Weltefbae83f2020-11-15 23:25:55 +0100518 var BssgpStatusIndication bsi;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200519 var integer i;
520
521 if (g_initialized == true) {
522 return;
523 }
524 g_initialized := true;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200525
Harald Welte425d3762020-12-09 14:33:18 +0100526 g_Tguard.start(t_guard);
527 activate(as_gTguard(g_Tguard));
528
Harald Welteb978ed62020-12-12 14:01:11 +0100529 var BssgpBvcConfigs bvcs := { };
Harald Welte6d63f742020-11-15 19:44:04 +0100530 for (i := 0; i < lengthof(mp_gbconfigs); i := i+1) {
531 g_pcu[i].cfg := mp_gbconfigs[i];
Harald Welte95339432020-12-02 18:50:52 +0100532 /* make sure all have a proper crate_cb, which cannot be specified in config file */
533 f_fix_create_cb(g_pcu[i].cfg);
Harald Welte6d63f742020-11-15 19:44:04 +0100534 /* concatenate all the PCU-side BVCs for the SGSN side */
Harald Welteb978ed62020-12-12 14:01:11 +0100535 bvcs := bvcs & g_pcu[i].cfg.bvc;
536 }
537
538 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
539 g_sgsn[i].cfg := {
540 nsei := mp_nsconfig_sgsn[i].nsei,
541 sgsn_role := true,
542 bvc := bvcs
543 }
Harald Welte6d63f742020-11-15 19:44:04 +0100544 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200545
546 f_init_vty();
Harald Welte6d63f742020-11-15 19:44:04 +0100547 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
Daniel Willmann443fc572020-11-18 13:26:57 +0100548 f_vty_transceive(GBPVTY, "nsvc nsei " & int2str(g_sgsn[i].cfg.nsei) & " force-unconfigured");
Daniel Willmannad93c052020-12-04 14:14:38 +0100549 }
550 for (i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
551 f_vty_transceive(GBPVTY, "nsvc nsei " & int2str(g_pcu[i].cfg.nsei) & " force-unconfigured");
552 f_vty_transceive(GBPVTY, "delete-gbproxy-peer " & int2str(g_pcu[i].cfg.nsei) & " only-bvc");
553 }
554
555 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
Harald Welteea1ba592020-11-17 18:05:13 +0100556 f_init_gb_sgsn(g_sgsn[i], "GbProxy_Test", i);
Harald Welte6d63f742020-11-15 19:44:04 +0100557 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200558 f_sleep(4.0);
Harald Welte6d63f742020-11-15 19:44:04 +0100559 for (i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
Harald Welteb419d0e2020-11-16 16:45:05 +0100560 f_init_gb_pcu(g_pcu[i], "GbProxy_Test", i);
Harald Welte6d63f742020-11-15 19:44:04 +0100561 }
Harald Weltefbae83f2020-11-15 23:25:55 +0100562
Harald Welteb978ed62020-12-12 14:01:11 +0100563 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
564 bvci_unblocked[i] := {};
565 }
566
Harald Weltefbae83f2020-11-15 23:25:55 +0100567 /* wait until all BVC are unblocked on both sides */
Harald Welted2801272020-11-17 19:22:58 +0100568 timer T := 15.0;
Harald Weltefbae83f2020-11-15 23:25:55 +0100569 T.start;
570 alt {
Harald Welteb978ed62020-12-12 14:01:11 +0100571 /* TODO: We need to add more lines if NUM_SGSN increases. Activating default altsteps
572 * unfortunately doesn't work as we want to access the local variable bvci_unblocked. */
573 [] as_count_unblocked4nse(0, bvci_unblocked);
574 [lengthof(g_sgsn) > 1] as_count_unblocked4nse(1, bvci_unblocked);
Harald Weltefbae83f2020-11-15 23:25:55 +0100575 [] SGSN_MGMT.receive(BssgpStatusIndication:{*, ?, ?}) {
576 repeat;
577 }
Harald Welte3c905152020-11-26 20:56:09 +0100578 [] SGSN_MGMT.receive(BssgpResetIndication:?) {
579 repeat;
580 }
Harald Weltefbae83f2020-11-15 23:25:55 +0100581 [] SGSN_MGMT.receive {
Harald Welted5b7e742021-01-27 10:50:24 +0100582 f_shutdown(__FILE__, __LINE__, fail, "Received unexpected message on SGSN_MGMT");
Harald Weltefbae83f2020-11-15 23:25:55 +0100583 }
584
585 [] PCU_MGMT.receive(BssgpStatusIndication:{*, ?, BVC_S_UNBLOCKED}) -> value bsi {
586 repeat;
587 }
588 [] PCU_MGMT.receive(BssgpStatusIndication:{*, ?, ?}) {
589 repeat;
590 }
591 [] PCU_MGMT.receive(BssgpResetIndication:{0}) {
592 repeat;
593 }
594 [] PCU_MGMT.receive {
Harald Welted5b7e742021-01-27 10:50:24 +0100595 f_shutdown(__FILE__, __LINE__, fail, "Received unexpected message on PCU_MGMT");
Harald Weltefbae83f2020-11-15 23:25:55 +0100596 }
597
598 [] T.timeout {
Harald Welte6929e322020-12-12 13:10:45 +0100599 setverdict(fail, "Timeout waiting for unblock of all BVCs on SGSN side; ",
Harald Welteb978ed62020-12-12 14:01:11 +0100600 "unblocked so far: ", bvci_unblocked);
Harald Welte6929e322020-12-12 13:10:45 +0100601 /* don't stop here but print below analysis */
Harald Weltefbae83f2020-11-15 23:25:55 +0100602 }
603 }
604
Harald Welteb978ed62020-12-12 14:01:11 +0100605 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
606 /* iterate over list and check all BVCI */
607 for (var integer j := 0; j < lengthof(g_sgsn[i].cfg.bvc); j := j+1) {
608 var BssgpBvci bvci := g_sgsn[i].cfg.bvc[j].bvci;
609 if (not ro_integer_contains(bvci_unblocked[i], bvci)) {
Harald Welted5b7e742021-01-27 10:50:24 +0100610 f_shutdown(__FILE__, __LINE__, fail,
611 log2str("SGSN ", i, " BVCI=", bvci, " was not unblocked during start-up"));
Harald Welteb978ed62020-12-12 14:01:11 +0100612 }
Harald Weltefbae83f2020-11-15 23:25:55 +0100613 }
614 }
Harald Welte425d3762020-12-09 14:33:18 +0100615
616 /* re-start guard timer after all BVCs are up, so it only counts the actual test case */
617 g_Tguard.start(t_guard);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200618}
619
620function f_cleanup() runs on test_CT {
Harald Welteb9f0fdc2020-12-09 14:44:50 +0100621 var integer i;
622
Daniel Willmann491af2a2021-01-08 01:32:51 +0100623 /* To avoid a dynamic test case error we need to prevent messages arriving on unconnected
624 * ports. Waiting here ensures that any messages "in flight" will be delivered to the port
625 * before the component is shutdown and disconnected. */
626 f_sleep(0.2);
627
Harald Welteb9f0fdc2020-12-09 14:44:50 +0100628 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
629 f_destroy_gb(g_sgsn[i]);
630 }
631 for (i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
632 f_destroy_gb(g_pcu[i]);
633 }
634
635 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, pass);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200636}
637
638type function void_fn(charstring id) runs on BSSGP_ConnHdlr;
639
640/* helper function to create, connect and start a BSSGP_ConnHdlr component */
Harald Welte207166c2021-01-16 12:52:30 +0100641function f_start_handler(void_fn fn, charstring id, integer imsi_suffix, float t_guard := 30.0,
642 integer sgsn_idx := 0, integer nri_idx := 0, boolean have_ptmsi := true)
Daniel Willmann423d8f42020-09-08 18:58:22 +0200643runs on test_CT return BSSGP_ConnHdlr {
644 var BSSGP_ConnHdlr vc_conn;
Harald Weltec5f486b2021-01-16 11:07:01 +0100645 var integer nri := mp_sgsn_nri[sgsn_idx][nri_idx];
Harald Welte77218d02021-01-15 19:59:15 +0100646 var OCT4 p_tmsi := f_gen_tmsi(imsi_suffix, nri_v := nri, nri_bitlen := mp_nri_bitlength);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200647
648 var BSSGP_ConnHdlrPars pars := {
649 imei := f_gen_imei(imsi_suffix),
650 imsi := f_gen_imsi(imsi_suffix),
651 msisdn := f_gen_msisdn(imsi_suffix),
Harald Weltedbd5e672021-01-14 21:03:14 +0100652 p_tmsi := p_tmsi,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200653 p_tmsi_sig := omit,
Harald Weltedbd5e672021-01-14 21:03:14 +0100654 tlli := f_gprs_tlli_from_tmsi(p_tmsi, TLLI_LOCAL),
Daniel Willmann423d8f42020-09-08 18:58:22 +0200655 tlli_old := omit,
656 ra := omit,
Harald Welte2ecbca82021-01-16 11:23:09 +0100657 pcu := g_pcu,
658 sgsn := g_sgsn,
Harald Weltec5f486b2021-01-16 11:07:01 +0100659 sgsn_idx := sgsn_idx,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200660 t_guard := t_guard
661 };
Harald Welte207166c2021-01-16 12:52:30 +0100662 if (not have_ptmsi) {
663 pars.p_tmsi := omit;
664 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200665
666 vc_conn := BSSGP_ConnHdlr.create(id);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200667
Harald Welte25a04b12021-01-17 11:09:49 +0100668 log("Starting ", id, " for SGSN[", sgsn_idx, "], NRI=", nri, ", P-TMSI=", pars.p_tmsi,
669 ", TLLI=", pars.tlli, ", IMSI=", pars.imsi, " on component=", vc_conn);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200670 vc_conn.start(f_handler_init(fn, id, pars));
671 return vc_conn;
672}
673
Harald Welte207166c2021-01-16 12:52:30 +0100674function f_start_handlers(void_fn fn, charstring id, integer imsi_suffix, float t_guard := 30.0,
675 boolean have_ptmsi := true)
Harald Weltec5f486b2021-01-16 11:07:01 +0100676runs on test_CT
677{
678 var integer sgsn_idx, nri_idx;
679 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx:=sgsn_idx+1) {
680 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx:=nri_idx+1) {
681 var integer extd_imsi_suffix := 1000*sgsn_idx + 100*nri_idx;
682 var BSSGP_ConnHdlr vc_conn;
Harald Welte207166c2021-01-16 12:52:30 +0100683 vc_conn := f_start_handler(fn, id, extd_imsi_suffix, t_guard, sgsn_idx, nri_idx,
684 have_ptmsi);
Harald Weltec5f486b2021-01-16 11:07:01 +0100685 /* Idea: we could also run them in parallel ? */
686 vc_conn.done;
687 }
688 }
689}
690
Harald Welte3dd21b32020-11-17 19:21:00 +0100691/* 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 +0100692private function f_connect_to_pcu_bvc(integer port_idx, integer nse_idx, integer bvc_idx)
693runs on BSSGP_ConnHdlr {
694 var BSSGP_BVC_CT bvc_ct := g_pars.pcu[nse_idx].vc_BSSGP_BVC[bvc_idx]
Harald Welte158becf2020-12-09 12:32:32 +0100695 if (PCU_PTP[port_idx].checkstate("Connected")) {
Harald Welte3dd21b32020-11-17 19:21:00 +0100696 /* unregister + disconnect from old BVC */
697 f_client_unregister(g_pars.imsi, PCU_PROC[port_idx]);
Harald Welte158becf2020-12-09 12:32:32 +0100698 disconnect(self:PCU_PTP[port_idx], pcu_ct[port_idx]:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100699 disconnect(self:PCU_SIG[port_idx], pcu_ct[port_idx]:BSSGP_SP_SIG);
700 disconnect(self:PCU_PROC[port_idx], pcu_ct[port_idx]:BSSGP_PROC);
701 }
702 /* connect to new BVC and register us */
Harald Welte158becf2020-12-09 12:32:32 +0100703 connect(self:PCU_PTP[port_idx], bvc_ct:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100704 connect(self:PCU_SIG[port_idx], bvc_ct:BSSGP_SP_SIG);
705 connect(self:PCU_PROC[port_idx], bvc_ct:BSSGP_PROC);
706 f_client_register(g_pars.imsi, g_pars.tlli, PCU_PROC[port_idx]);
707 pcu_ct[port_idx] := bvc_ct;
Harald Welte0e188242020-11-22 21:46:48 +0100708 pcu_bvc_cfg[port_idx] := g_pars.pcu[nse_idx].cfg.bvc[bvc_idx];
Harald Welte3dd21b32020-11-17 19:21:00 +0100709}
710
711/* Connect the SGSN-side per-BVC ports (SGSN/SGSN_SIG/SGSN_PROC) array slot 'port_idx' to specified per-BVC component */
712private 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 +0100713 if (SGSN_PTP[port_idx].checkstate("Connected")) {
Harald Welte3dd21b32020-11-17 19:21:00 +0100714 /* unregister + disconnect from old BVC */
715 f_client_unregister(g_pars.imsi, SGSN_PROC[port_idx]);
Harald Welte158becf2020-12-09 12:32:32 +0100716 disconnect(self:SGSN_PTP[port_idx], sgsn_ct[port_idx]:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100717 disconnect(self:SGSN_SIG[port_idx], sgsn_ct[port_idx]:BSSGP_SP_SIG);
718 disconnect(self:SGSN_PROC[port_idx], sgsn_ct[port_idx]:BSSGP_PROC);
719 }
720 /* connect to new BVC and register us */
Harald Welte158becf2020-12-09 12:32:32 +0100721 connect(self:SGSN_PTP[port_idx], bvc_ct:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100722 connect(self:SGSN_SIG[port_idx], bvc_ct:BSSGP_SP_SIG);
723 connect(self:SGSN_PROC[port_idx], bvc_ct:BSSGP_PROC);
724 f_client_register(g_pars.imsi, g_pars.tlli, SGSN_PROC[port_idx]);
725 sgsn_ct[port_idx] := bvc_ct;
726}
727
Harald Welte425d3762020-12-09 14:33:18 +0100728private altstep as_gTguard(timer Tguard) {
729 [] Tguard.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +0100730 f_shutdown(__FILE__, __LINE__, fail, "Tguard timeout");
Daniel Willmann423d8f42020-09-08 18:58:22 +0200731 }
732}
733
734/* first function called in every ConnHdlr */
735private function f_handler_init(void_fn fn, charstring id, BSSGP_ConnHdlrPars pars)
736runs on BSSGP_ConnHdlr {
Harald Welte1e834f32020-11-15 20:02:59 +0100737 var integer i;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200738 /* do some common stuff like setting up g_pars */
739 g_pars := pars;
740
741 llc := f_llc_create(false);
742
Harald Welte3dd21b32020-11-17 19:21:00 +0100743 /* default connections on PCU side: First BVC of each NSE/PCU */
744 for (i := 0; i < lengthof(g_pars.pcu); i := i+1) {
Harald Welte0e188242020-11-22 21:46:48 +0100745 f_connect_to_pcu_bvc(port_idx := i, nse_idx := i, bvc_idx := 0);
Harald Welte1e834f32020-11-15 20:02:59 +0100746 }
Harald Welte3dd21b32020-11-17 19:21:00 +0100747
748 /* default connections on SGSN side: First BVC of each NSE/SGSN */
749 for (i := 0; i < lengthof(g_pars.sgsn); i := i+1) {
750 f_connect_to_sgsn_bvc(i, g_pars.sgsn[i].vc_BSSGP_BVC[0]);
Harald Welte1e834f32020-11-15 20:02:59 +0100751 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200752
753 g_Tguard.start(pars.t_guard);
Harald Welte425d3762020-12-09 14:33:18 +0100754 activate(as_gTguard(g_Tguard));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200755
756 /* call the user-supplied test case function */
757 fn.apply(id);
Harald Welteb33fb592021-01-16 12:50:56 +0100758
759 for (i := 0; i < NUM_SGSN; i := i+1) {
760 if (SGSN_PROC[i].checkstate("Connected")) {
761 f_client_unregister(g_pars.imsi, SGSN_PROC[i])
762 }
763 }
764
765 for (i := 0; i < NUM_PCU; i := i+1) {
766 if (PCU_PROC[i].checkstate("Connected")) {
767 f_client_unregister(g_pars.imsi, PCU_PROC[i])
768 }
769 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200770}
771
Harald Welte1e834f32020-11-15 20:02:59 +0100772private function f_client_register(hexstring imsi, OCT4 tlli, BSSGP_PROC_PT PT)
773runs on BSSGP_ConnHdlr {
774 PT.call(BSSGP_register_client:{imsi, tlli}) {
775 [] PT.getreply(BSSGP_register_client:{imsi, tlli}) {};
776 }
777}
778
779private function f_client_unregister(hexstring imsi, BSSGP_PROC_PT PT)
780runs on BSSGP_ConnHdlr {
781 PT.call(BSSGP_unregister_client:{imsi}) {
782 [] PT.getreply(BSSGP_unregister_client:{imsi}) {};
783 }
784}
785
Harald Welte22ef5d92020-11-16 13:35:14 +0100786/* Send 'tx' on PTP-BVCI from PCU; expect 'rx' on SGSN */
787friend function f_pcu2sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
Harald Weltec5f486b2021-01-16 11:07:01 +0100788 integer pcu_idx := 0, boolean use_sig := false) runs on BSSGP_ConnHdlr {
789 var integer sgsn_idx := g_pars.sgsn_idx;
Harald Welte22ef5d92020-11-16 13:35:14 +0100790 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +0100791 timer T := 2.0;
Harald Welte22ef5d92020-11-16 13:35:14 +0100792
Daniel Willmann4798fd72020-11-24 16:23:29 +0100793 if (use_sig) {
794 PCU_SIG[pcu_idx].send(tx);
795 } else {
Harald Welte158becf2020-12-09 12:32:32 +0100796 PCU_PTP[pcu_idx].send(tx);
Daniel Willmann4798fd72020-11-24 16:23:29 +0100797 }
798
Harald Welte22ef5d92020-11-16 13:35:14 +0100799 T.start;
800 alt {
Daniel Willmann4798fd72020-11-24 16:23:29 +0100801 [use_sig] SGSN_SIG[sgsn_idx].receive(exp_rx) {
802 setverdict(pass);
803 }
Harald Welte158becf2020-12-09 12:32:32 +0100804 [not use_sig] SGSN_PTP[sgsn_idx].receive(exp_rx) {
Harald Welte22ef5d92020-11-16 13:35:14 +0100805 setverdict(pass);
806 }
Harald Welte158becf2020-12-09 12:32:32 +0100807 [] SGSN_PTP[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +0100808 f_shutdown(__FILE__, __LINE__, fail,
809 log2str("Unexpected BSSGP on SGSN[", sgsn_idx, "] side: ", rx));
Harald Welte22ef5d92020-11-16 13:35:14 +0100810 }
Daniel Willmann4798fd72020-11-24 16:23:29 +0100811 [] SGSN_SIG[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +0100812 f_shutdown(__FILE__, __LINE__, fail,
813 log2str("Unexpected SIG BSSGP on SGSN[", sgsn_idx, "] side: ", rx));
Daniel Willmann4798fd72020-11-24 16:23:29 +0100814 }
Harald Welte22ef5d92020-11-16 13:35:14 +0100815 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +0100816 f_shutdown(__FILE__, __LINE__, fail,
817 log2str("Timeout waiting for BSSGP on SGSN[", sgsn_idx, "] side: ", exp_rx));
Harald Welte22ef5d92020-11-16 13:35:14 +0100818 }
819 }
820}
821
Harald Welte3148a962021-01-17 11:15:28 +0100822/* Send 'tx' from PCU; expect 'exp_rx' on _any_ SGSN */
823friend function f_pcu2any_sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
824 integer pcu_idx := 0, boolean use_sig := false)
825runs on BSSGP_ConnHdlr return integer {
826 var integer rx_idx := -1;
827 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +0100828 timer T := 2.0;
Harald Welte3148a962021-01-17 11:15:28 +0100829
830 if (use_sig) {
831 PCU_SIG[pcu_idx].send(tx);
832 } else {
833 PCU_PTP[pcu_idx].send(tx);
834 }
835
836 T.start;
837 alt {
838 [use_sig] any from SGSN_SIG.receive(exp_rx) -> @index value rx_idx {
839 setverdict(pass);
840 }
841 [not use_sig] any from SGSN_PTP.receive(exp_rx) -> @index value rx_idx {
842 setverdict(pass);
843 }
844 [] any from SGSN_PTP.receive(PDU_BSSGP:?) -> value rx @index value rx_idx {
Harald Welted5b7e742021-01-27 10:50:24 +0100845 f_shutdown(__FILE__, __LINE__, fail,
846 log2str("Unexpected BSSGP on SGSN[", rx_idx, "] side: ", rx));
Harald Welte3148a962021-01-17 11:15:28 +0100847 }
848 [] any from SGSN_SIG.receive(PDU_BSSGP:?) -> value rx @index value rx_idx {
Harald Welted5b7e742021-01-27 10:50:24 +0100849 f_shutdown(__FILE__, __LINE__, fail,
850 log2str("Unexpected SIG BSSGP on SGSN[", rx_idx, "] side: ", rx));
Harald Welte3148a962021-01-17 11:15:28 +0100851 }
852 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +0100853 f_shutdown(__FILE__, __LINE__, fail,
854 log2str("Timeout waiting for BSSGP on SGSN side: ", exp_rx));
Harald Welte3148a962021-01-17 11:15:28 +0100855 }
856 }
857 return rx_idx;
858}
859
Harald Welte22ef5d92020-11-16 13:35:14 +0100860/* Send 'tx' on PTP-BVCI from SGSN; expect 'rx' on PCU */
861friend function f_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
Harald Weltec5f486b2021-01-16 11:07:01 +0100862 integer pcu_idx := 0, boolean use_sig := false) runs on BSSGP_ConnHdlr {
863 var integer sgsn_idx := g_pars.sgsn_idx;
Harald Welte22ef5d92020-11-16 13:35:14 +0100864 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +0100865 timer T := 2.0;
Harald Welte22ef5d92020-11-16 13:35:14 +0100866
Daniel Willmann4798fd72020-11-24 16:23:29 +0100867 if (use_sig) {
868 SGSN_SIG[sgsn_idx].send(tx);
869 } else {
Harald Welte158becf2020-12-09 12:32:32 +0100870 SGSN_PTP[sgsn_idx].send(tx);
Daniel Willmann4798fd72020-11-24 16:23:29 +0100871 }
872
Harald Welte22ef5d92020-11-16 13:35:14 +0100873 T.start;
874 alt {
Daniel Willmann4798fd72020-11-24 16:23:29 +0100875 [use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
876 setverdict(pass);
877 }
Harald Welte158becf2020-12-09 12:32:32 +0100878 [not use_sig] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte22ef5d92020-11-16 13:35:14 +0100879 setverdict(pass);
880 }
Harald Welte158becf2020-12-09 12:32:32 +0100881 [] PCU_PTP[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +0100882 f_shutdown(__FILE__, __LINE__, fail, log2str("Unexpected BSSGP on PCU side: ", rx));
Harald Welte22ef5d92020-11-16 13:35:14 +0100883 }
Daniel Willmann4798fd72020-11-24 16:23:29 +0100884 [] PCU_SIG[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +0100885 f_shutdown(__FILE__, __LINE__, fail, log2str("Unexpected SIG BSSGP on PCU side: ", rx));
Daniel Willmann4798fd72020-11-24 16:23:29 +0100886 }
Harald Welte22ef5d92020-11-16 13:35:14 +0100887 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +0100888 f_shutdown(__FILE__, __LINE__, fail,
889 log2str("Timeout waiting for BSSGP on PCU side: ", exp_rx));
Harald Welte22ef5d92020-11-16 13:35:14 +0100890 }
891 }
892}
Harald Welte1e834f32020-11-15 20:02:59 +0100893
Harald Welte3807ed12020-11-24 19:05:22 +0100894/***********************************************************************
895 * GlobaLTest_CT: Using the per-NSE GLOBAL ports on PCU + SGSN side
896 ***********************************************************************/
897
898type component GlobalTest_CT extends test_CT {
899 port BSSGP_PT G_PCU[NUM_PCU];
Harald Welte04358652021-01-17 13:48:13 +0100900 var integer g_pcu_idx[NUM_PCU]; /* BVC index currently connected to G_PCU */
Harald Welte3807ed12020-11-24 19:05:22 +0100901 port BSSGP_PT G_SGSN[NUM_SGSN];
Harald Welte04358652021-01-17 13:48:13 +0100902 var integer g_sgsn_idx[NUM_SGSN]; /* BVC index currently connected to G_SGSN */
Harald Weltef86f1852021-01-16 21:56:17 +0100903 port BSSGP_PT RIM_PCU[NUM_PCU];
904 port BSSGP_PT RIM_SGSN[NUM_SGSN];
Harald Welte3807ed12020-11-24 19:05:22 +0100905};
906
Harald Welte299aa482020-12-09 15:10:55 +0100907/* connect the signaling BVC of each NSE to the G_PCU / G_SGSN ports */
Harald Welte3807ed12020-11-24 19:05:22 +0100908private function f_global_init() runs on GlobalTest_CT {
909 var integer i;
910 for (i := 0; i < lengthof(g_sgsn); i := i+1) {
911 connect(self:G_SGSN[i], g_sgsn[i].vc_BSSGP:GLOBAL);
Harald Weltef86f1852021-01-16 21:56:17 +0100912 connect(self:RIM_SGSN[i], g_sgsn[i].vc_BSSGP:RIM);
Harald Welte3807ed12020-11-24 19:05:22 +0100913 }
914 for (i := 0; i < lengthof(g_pcu); i := i+1) {
915 connect(self:G_PCU[i], g_pcu[i].vc_BSSGP:GLOBAL);
Harald Weltef86f1852021-01-16 21:56:17 +0100916 connect(self:RIM_PCU[i], g_pcu[i].vc_BSSGP:RIM);
Harald Welte3807ed12020-11-24 19:05:22 +0100917 }
918}
919
Harald Welte299aa482020-12-09 15:10:55 +0100920/* connect the first PTP BVC of each NSE to the G_PCU / G_SGSN ports */
921private function f_global_init_ptp() runs on GlobalTest_CT {
922 var integer i;
923 for (i := 0; i < lengthof(g_sgsn); i := i+1) {
Harald Welte04358652021-01-17 13:48:13 +0100924 log("Connecting G_SGSN[", i, "] to BVCI=", g_sgsn[i].cfg.bvc[0].bvci);
Harald Welte299aa482020-12-09 15:10:55 +0100925 connect(self:G_SGSN[i], g_sgsn[i].vc_BSSGP_BVC[0]:GLOBAL);
Harald Welte04358652021-01-17 13:48:13 +0100926 g_sgsn_idx[i] := 0;
Harald Welte299aa482020-12-09 15:10:55 +0100927 }
928 for (i := 0; i < lengthof(g_pcu); i := i+1) {
Harald Welte04358652021-01-17 13:48:13 +0100929 log("Connecting G_PCU[", i, "] to BVCI=", g_pcu[i].cfg.bvc[0].bvci);
Harald Welte299aa482020-12-09 15:10:55 +0100930 connect(self:G_PCU[i], g_pcu[i].vc_BSSGP_BVC[0]:GLOBAL);
Harald Welte04358652021-01-17 13:48:13 +0100931 g_pcu_idx[i] := 0;
Harald Welte299aa482020-12-09 15:10:55 +0100932 }
933}
934
Harald Welte04358652021-01-17 13:48:13 +0100935/* (re)connect G_SGSN[sgsn_idx] to a specific PTP BVCI */
936private function f_global_ptp_connect_sgsn_bvci(integer sgsn_idx, BssgpBvci bvci) runs on GlobalTest_CT
937{
938 var integer sgsn_bvc_idx := get_bvc_idx_for_bvci(g_sgsn[sgsn_idx], bvci);
939 var integer old_sgsn_bvc_idx := g_sgsn_idx[sgsn_idx];
940 disconnect(self:G_SGSN[sgsn_idx], g_sgsn[sgsn_idx].vc_BSSGP_BVC[old_sgsn_bvc_idx]:GLOBAL);
941 connect(self:G_SGSN[sgsn_idx], g_sgsn[sgsn_idx].vc_BSSGP_BVC[sgsn_bvc_idx]:GLOBAL);
942 g_sgsn_idx[sgsn_idx] := sgsn_bvc_idx;
943}
944
945/* (re)connect G_PCU[pcu_idx] to a specific PTP BVCI */
946private function f_global_ptp_connect_pcu_bvci(integer pcu_idx, BssgpBvci bvci) runs on GlobalTest_CT
947{
948 var integer pcu_bvc_idx := get_bvc_idx_for_bvci(g_pcu[pcu_idx], bvci);
949 var integer old_pcu_bvc_idx := g_pcu_idx[pcu_idx];
950 disconnect(self:G_PCU[pcu_idx], g_pcu[pcu_idx].vc_BSSGP_BVC[old_pcu_bvc_idx]:GLOBAL);
951 connect(self:G_PCU[pcu_idx], g_pcu[pcu_idx].vc_BSSGP_BVC[pcu_bvc_idx]:GLOBAL);
952 g_pcu_idx[pcu_idx] := pcu_bvc_idx;
953}
954
Harald Welte3807ed12020-11-24 19:05:22 +0100955/* Send 'tx' on PTP-BVCI from PCU; expect 'rx' on SGSN */
956friend function f_global_pcu2sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
957 integer pcu_idx := 0, integer sgsn_idx := 0) runs on GlobalTest_CT {
Harald Welte04358652021-01-17 13:48:13 +0100958 var integer rx_idx;
Harald Welte3807ed12020-11-24 19:05:22 +0100959 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +0100960 timer T := 2.0;
Harald Welte3807ed12020-11-24 19:05:22 +0100961
962 G_PCU[pcu_idx].send(tx);
963 T.start;
964 alt {
965 [] G_SGSN[sgsn_idx].receive(exp_rx) {
966 setverdict(pass);
967 }
Harald Welte04358652021-01-17 13:48:13 +0100968 [] any from G_SGSN.receive(exp_rx) -> @index value rx_idx {
969 setverdict(fail, "BSSGP arrived on wrong SGSN[", rx_idx, "] instead of SGSN[", sgsn_idx, "]");
970 }
Harald Welte3807ed12020-11-24 19:05:22 +0100971 [] G_SGSN[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +0100972 f_shutdown(__FILE__, __LINE__, fail, log2str("Unexpected BSSGP on SGSN side: ", rx));
Harald Welte3807ed12020-11-24 19:05:22 +0100973 }
974 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +0100975 f_shutdown(__FILE__, __LINE__, fail, log2str("Timeout waiting for BSSGP on SGSN side: ", exp_rx));
Harald Welte3807ed12020-11-24 19:05:22 +0100976 }
977 }
978}
979
980/* Send 'tx' on PTP-BVCI from SGSN; expect 'rx' on PCU */
981friend function f_global_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
982 integer sgsn_idx := 0, integer pcu_idx := 0) runs on GlobalTest_CT {
Harald Welte04358652021-01-17 13:48:13 +0100983 var integer rx_idx;
Harald Welte3807ed12020-11-24 19:05:22 +0100984 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +0100985 timer T := 2.0;
Harald Welte3807ed12020-11-24 19:05:22 +0100986
987 G_SGSN[sgsn_idx].send(tx);
988 T.start;
989 alt {
990 [] G_PCU[pcu_idx].receive(exp_rx) {
991 setverdict(pass);
992 }
Harald Welte04358652021-01-17 13:48:13 +0100993 [] any from G_PCU.receive(exp_rx) -> @index value rx_idx {
994 setverdict(fail, "BSSGP arrived on wrong PCU[", rx_idx, "] instead of PCU[", pcu_idx, "]");
995 }
Harald Welte3807ed12020-11-24 19:05:22 +0100996 [] G_PCU[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +0100997 f_shutdown(__FILE__, __LINE__, fail, log2str("Unexpected BSSGP on PCU side: ", rx));
Harald Welte3807ed12020-11-24 19:05:22 +0100998 }
999 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +01001000 f_shutdown(__FILE__, __LINE__, fail, log2str("Timeout waiting for BSSGP on PCU side: ", exp_rx));
Harald Welte3807ed12020-11-24 19:05:22 +01001001 }
1002 }
1003}
1004
1005
Daniel Willmann423d8f42020-09-08 18:58:22 +02001006/* TODO:
1007 * Detach without Attach
1008 * SM procedures without attach / RAU
1009 * ATTACH / RAU
1010 ** with / without authentication
1011 ** with / without P-TMSI allocation
1012 * re-transmissions of LLC frames
1013 * PDP Context activation
1014 ** with different GGSN config in SGSN VTY
1015 ** with different PDP context type (v4/v6/v46)
1016 ** timeout from GGSN
1017 ** multiple / secondary PDP context
1018 */
1019
1020private function f_TC_BVC_bringup(charstring id) runs on BSSGP_ConnHdlr {
1021 f_sleep(5.0);
1022 setverdict(pass);
1023}
1024
1025testcase TC_BVC_bringup() runs on test_CT {
Daniel Willmann423d8f42020-09-08 18:58:22 +02001026 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001027 f_start_handlers(refers(f_TC_BVC_bringup), testcasename(), 51);
Daniel Willmann423d8f42020-09-08 18:58:22 +02001028 f_cleanup();
1029}
1030
1031friend function f_bssgp_suspend(integer ran_idx := 0) runs on BSSGP_ConnHdlr return OCT1 {
Harald Welte16357a92020-11-17 18:20:00 +01001032 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Daniel Willmann423d8f42020-09-08 18:58:22 +02001033 timer T := 5.0;
1034 var PDU_BSSGP rx_pdu;
Harald Welte16357a92020-11-17 18:20:00 +01001035 PCU_SIG[ran_idx].send(ts_BSSGP_SUSPEND(g_pars.tlli, bvcc.cell_id.ra_id));
Daniel Willmann423d8f42020-09-08 18:58:22 +02001036 T.start;
1037 alt {
Harald Welte16357a92020-11-17 18:20:00 +01001038 [] 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 +02001039 return rx_pdu.pDU_BSSGP_SUSPEND_ACK.suspend_Reference_Number.suspend_Reference_Number_value;
1040 }
Harald Welte16357a92020-11-17 18:20:00 +01001041 [] PCU_SIG[ran_idx].receive(tr_BSSGP_SUSPEND_NACK(g_pars.tlli, bvcc.cell_id.ra_id, ?)) -> value rx_pdu {
Harald Welted5b7e742021-01-27 10:50:24 +01001042 f_shutdown(__FILE__, __LINE__, fail,
1043 log2str("SUSPEND-NACK in response to SUSPEND for TLLI ", g_pars.tlli));
Daniel Willmann423d8f42020-09-08 18:58:22 +02001044 }
1045 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +01001046 f_shutdown(__FILE__, __LINE__, fail,
1047 log2str("No SUSPEND-ACK in response to SUSPEND for TLLI ", g_pars.tlli));
Daniel Willmann423d8f42020-09-08 18:58:22 +02001048 }
1049 }
1050 return '00'O;
1051}
1052
1053friend function f_bssgp_resume(OCT1 susp_ref, integer ran_idx := 0) runs on BSSGP_ConnHdlr {
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;
Harald Welte16357a92020-11-17 18:20:00 +01001056 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 +02001057 T.start;
1058 alt {
Harald Welte16357a92020-11-17 18:20:00 +01001059 [] PCU_SIG[ran_idx].receive(tr_BSSGP_RESUME_ACK(g_pars.tlli, bvcc.cell_id.ra_id));
1060 [] PCU_SIG[ran_idx].receive(tr_BSSGP_RESUME_NACK(g_pars.tlli, bvcc.cell_id.ra_id, ?)) {
Harald Welted5b7e742021-01-27 10:50:24 +01001061 f_shutdown(__FILE__, __LINE__, fail,
1062 log2str("RESUME-NACK in response to RESUME for TLLI ", g_pars.tlli));
Daniel Willmann423d8f42020-09-08 18:58:22 +02001063 }
1064 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +01001065 f_shutdown(__FILE__, __LINE__, fail,
1066 log2str("No RESUME-ACK in response to SUSPEND for TLLI ", g_pars.tlli));
Daniel Willmann423d8f42020-09-08 18:58:22 +02001067 }
1068 }
1069}
1070
1071
Harald Welte92686012020-11-15 21:45:49 +01001072/* send uplink-unitdata of a variety of different sizes; expect it to show up on SGSN */
1073private function f_TC_ul_unitdata(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte16357a92020-11-17 18:20:00 +01001074 var integer ran_idx := 0;
1075 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Harald Welte92686012020-11-15 21:45:49 +01001076 var integer i;
1077
Harald Welte0d5fceb2020-11-29 16:04:07 +01001078 for (i := 0; i < max_fr_info_size-4; i := i+4) {
Harald Welte92686012020-11-15 21:45:49 +01001079 var octetstring payload := f_rnd_octstring(i);
Harald Welte16357a92020-11-17 18:20:00 +01001080 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 +01001081 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte16357a92020-11-17 18:20:00 +01001082 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 +01001083
Harald Welte0d5fceb2020-11-29 16:04:07 +01001084 log("UL-UNITDATA(payload_size=", i);
Harald Welte22ef5d92020-11-16 13:35:14 +01001085 f_pcu2sgsn(pdu_tx, pdu_rx);
Harald Welte92686012020-11-15 21:45:49 +01001086 }
1087 setverdict(pass);
1088}
1089
1090testcase TC_ul_unitdata() runs on test_CT
1091{
Daniel Willmannc879f342021-02-11 14:28:01 +01001092 f_init(60.0);
Harald Welte2ecbca82021-01-16 11:23:09 +01001093 f_start_handlers(refers(f_TC_ul_unitdata), testcasename(), 1);
Harald Welte92686012020-11-15 21:45:49 +01001094 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Welte92686012020-11-15 21:45:49 +01001095 f_cleanup();
1096}
1097
Harald Welte78d8db92020-11-15 23:27:27 +01001098/* send downlink-unitdata of a variety of different sizes; expect it to show up on PCU */
1099private function f_TC_dl_unitdata(charstring id) runs on BSSGP_ConnHdlr {
1100 var integer i;
1101
Harald Welte0d5fceb2020-11-29 16:04:07 +01001102 for (i := 0; i < max_fr_info_size-4; i := i+4) {
Harald Welte78d8db92020-11-15 23:27:27 +01001103 var octetstring payload := f_rnd_octstring(i);
1104 var template (value) PDU_BSSGP pdu_tx :=
1105 ts_BSSGP_DL_UD(g_pars.tlli, payload, omit, ts_BSSGP_IMSI(g_pars.imsi));
1106 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1107 var template (present) PDU_BSSGP pdu_rx :=
Daniel Willmann325458d2021-02-11 14:22:42 +01001108 tr_BSSGP_DL_UD(g_pars.tlli, payload, tr_BSSGP_IMSI(g_pars.imsi));
Harald Welte78d8db92020-11-15 23:27:27 +01001109
Harald Welte0d5fceb2020-11-29 16:04:07 +01001110 log("DL-UNITDATA(payload_size=", i);
Harald Welte22ef5d92020-11-16 13:35:14 +01001111 f_sgsn2pcu(pdu_tx, pdu_rx);
Harald Welte78d8db92020-11-15 23:27:27 +01001112 }
1113 setverdict(pass);
1114}
1115
1116testcase TC_dl_unitdata() runs on test_CT
1117{
Daniel Willmannc879f342021-02-11 14:28:01 +01001118 f_init(60.0);
Harald Welte2ecbca82021-01-16 11:23:09 +01001119 f_start_handlers(refers(f_TC_dl_unitdata), testcasename(), 2);
Harald Welte78d8db92020-11-15 23:27:27 +01001120 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Welte78d8db92020-11-15 23:27:27 +01001121 f_cleanup();
1122}
Harald Welte92686012020-11-15 21:45:49 +01001123
Harald Welte6dc2ac42020-11-16 09:16:17 +01001124private function f_TC_ra_capability(charstring id) runs on BSSGP_ConnHdlr {
1125 var integer i;
1126
1127 for (i := 0; i < 10; i := i+1) {
1128 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RA_CAP(g_pars.tlli, { ts_RaCapRec_BSSGP });
1129 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1130 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RA_CAP(g_pars.tlli, { tr_RaCapRec_BSSGP })
1131
Harald Welte22ef5d92020-11-16 13:35:14 +01001132 f_sgsn2pcu(pdu_tx, pdu_rx);
Harald Welte6dc2ac42020-11-16 09:16:17 +01001133 }
1134 setverdict(pass);
1135}
1136testcase TC_ra_capability() runs on test_CT
1137{
Harald Welte6dc2ac42020-11-16 09:16:17 +01001138 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001139 f_start_handlers(refers(f_TC_ra_capability), testcasename(), 3);
Harald Welte6dc2ac42020-11-16 09:16:17 +01001140 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Welte6dc2ac42020-11-16 09:16:17 +01001141 f_cleanup();
1142}
1143
Daniel Willmannace3ece2020-11-16 19:53:26 +01001144private function f_TC_ra_capability_upd(charstring id) runs on BSSGP_ConnHdlr {
1145 var integer i;
1146 var OCT1 tag;
1147 for (i := 0; i < 10; i := i+1) {
1148 tag := int2oct(23 + i, 1);
1149 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RA_CAP_UPD(g_pars.tlli, tag);
1150 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1151 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RA_CAP_UPD(g_pars.tlli, tag)
1152
1153 f_pcu2sgsn(pdu_tx, pdu_rx);
1154
1155 pdu_tx := ts_BSSGP_RA_CAP_UPD_ACK(g_pars.tlli, tag, '42'O);
1156 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1157 pdu_rx := tr_BSSGP_RA_CAP_UPD_ACK(g_pars.tlli, tag, '42'O)
1158
1159 f_sgsn2pcu(pdu_tx, pdu_rx);
1160 }
1161 setverdict(pass);
1162}
1163testcase TC_ra_capability_upd() runs on test_CT
1164{
Daniel Willmannace3ece2020-11-16 19:53:26 +01001165 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001166 f_start_handlers(refers(f_TC_ra_capability_upd), testcasename(), 4);
Daniel Willmannace3ece2020-11-16 19:53:26 +01001167 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Daniel Willmannace3ece2020-11-16 19:53:26 +01001168 f_cleanup();
1169}
1170
Daniel Willmann165d6612020-11-19 14:27:29 +01001171private function f_TC_radio_status(charstring id) runs on BSSGP_ConnHdlr {
1172 var integer i;
1173 var BssgpRadioCause cause := BSSGP_RADIO_CAUSE_CONTACT_LOST;
1174 for (i := 0; i < 10; i := i+1) {
1175 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RADIO_STATUS(g_pars.tlli, cause);
1176 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1177 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RADIO_STATUS(g_pars.tlli, cause)
1178
1179 f_pcu2sgsn(pdu_tx, pdu_rx);
1180 }
1181 setverdict(pass);
1182}
1183testcase TC_radio_status() runs on test_CT
1184{
Daniel Willmann165d6612020-11-19 14:27:29 +01001185 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001186 f_start_handlers(refers(f_TC_radio_status), testcasename(), 5);
Daniel Willmann165d6612020-11-19 14:27:29 +01001187 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Daniel Willmann165d6612020-11-19 14:27:29 +01001188 f_cleanup();
1189}
1190
Harald Welte3148a962021-01-17 11:15:28 +01001191private function f_TC_radio_status_tmsi(charstring id) runs on BSSGP_ConnHdlr {
1192 var integer i;
1193 var BssgpRadioCause cause := BSSGP_RADIO_CAUSE_CONTACT_LOST;
1194 for (i := 0; i < 10; i := i+1) {
1195 var integer tmsi_int := oct2int(g_pars.p_tmsi);
1196 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RADIO_STATUS(omit, cause, tmsi_int);
1197 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1198 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RADIO_STATUS(omit, cause, tmsi_int);
1199 f_pcu2sgsn(pdu_tx, pdu_rx);
1200 }
1201 setverdict(pass);
1202}
1203testcase TC_radio_status_tmsi() runs on test_CT
1204{
1205 f_init();
1206 f_start_handlers(refers(f_TC_radio_status_tmsi), testcasename(), 5);
1207 f_cleanup();
1208}
1209
1210private function f_TC_radio_status_imsi(charstring id) runs on BSSGP_ConnHdlr {
1211 var integer i;
1212 var BssgpRadioCause cause := BSSGP_RADIO_CAUSE_CONTACT_LOST;
1213 for (i := 0; i < 10; i := i+1) {
1214 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RADIO_STATUS(omit, cause, imsi := g_pars.imsi);
1215 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1216 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RADIO_STATUS(omit, cause, imsi := g_pars.imsi);
1217 f_pcu2any_sgsn(pdu_tx, pdu_rx);
1218 }
1219 setverdict(pass);
1220}
1221testcase TC_radio_status_imsi() runs on test_CT
1222{
1223 f_init();
1224 f_start_handlers(refers(f_TC_radio_status_imsi), testcasename(), 5);
1225 f_cleanup();
1226}
1227
1228
1229
Harald Welte99ed5072021-01-15 20:38:58 +01001230private function f_suspend_one(integer sgsn_idx, integer nri_idx, integer pcu_idx, integer bvc_idx,
1231 integer suffix)
Harald Welte00963752021-01-15 20:33:11 +01001232runs on GlobalTest_CT
1233{
1234 var RoutingAreaIdentification ra_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id.ra_id;
Harald Welte99ed5072021-01-15 20:38:58 +01001235 var OCT4 p_tmsi := f_gen_tmsi(suffix, nri_v := mp_sgsn_nri[sgsn_idx][nri_idx],
1236 nri_bitlen := mp_nri_bitlength);
1237 var OCT4 tlli := f_gprs_tlli_from_tmsi(p_tmsi, TLLI_LOCAL);
Harald Welte00963752021-01-15 20:33:11 +01001238 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_SUSPEND(tlli, ra_id);
1239 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1240 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_SUSPEND(tlli, ra_id);
1241 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1242
1243 pdu_tx := ts_BSSGP_SUSPEND_ACK(tlli, ra_id, int2oct(suffix, 1));
1244 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1245 pdu_rx := tr_BSSGP_SUSPEND_ACK(tlli, ra_id, int2oct(suffix, 1));
1246 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1247
1248 pdu_tx := ts_BSSGP_SUSPEND(tlli, ra_id);
1249 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1250 pdu_rx := tr_BSSGP_SUSPEND(tlli, ra_id);
1251 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1252
1253 /* These messages are simple passed through so just also test sending NACK */
1254 pdu_tx := ts_BSSGP_SUSPEND_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1255 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1256 pdu_rx := tr_BSSGP_SUSPEND_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1257 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1258}
1259
Harald Weltec5c33732021-01-15 21:04:35 +01001260private function f_TC_suspend(integer sgsn_idx, integer nri_idx, integer pcu_idx, integer bvc_idx)
1261runs on GlobalTest_CT {
Daniel Willmannfa67f492020-11-19 15:48:05 +01001262 var integer i;
Daniel Willmann165d6612020-11-19 14:27:29 +01001263
Daniel Willmannfa67f492020-11-19 15:48:05 +01001264 for (i := 0; i < 10; i := i+1) {
Harald Weltec5c33732021-01-15 21:04:35 +01001265 f_suspend_one(sgsn_idx, nri_idx, pcu_idx, bvc_idx, suffix := i);
Daniel Willmannfa67f492020-11-19 15:48:05 +01001266 }
1267 setverdict(pass);
1268}
Harald Welte3807ed12020-11-24 19:05:22 +01001269testcase TC_suspend() runs on GlobalTest_CT
Daniel Willmannfa67f492020-11-19 15:48:05 +01001270{
Harald Weltec5c33732021-01-15 21:04:35 +01001271 var integer sgsn_idx, nri_idx;
Daniel Willmannfa67f492020-11-19 15:48:05 +01001272 f_init();
Harald Welte3807ed12020-11-24 19:05:22 +01001273 f_global_init();
Harald Weltec5c33732021-01-15 21:04:35 +01001274 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx+1) {
1275 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx+1) {
1276 f_TC_suspend(sgsn_idx, nri_idx, pcu_idx:=0, bvc_idx:=0);
1277 }
1278 }
Daniel Willmannfa67f492020-11-19 15:48:05 +01001279 f_cleanup();
1280}
Harald Welte6dc2ac42020-11-16 09:16:17 +01001281
Harald Welte99ed5072021-01-15 20:38:58 +01001282private function f_resume_one(integer sgsn_idx, integer nri_idx, integer pcu_idx, integer bvc_idx,
1283 integer suffix)
Harald Welte00963752021-01-15 20:33:11 +01001284runs on GlobalTest_CT
1285{
1286 var RoutingAreaIdentification ra_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id.ra_id;
Harald Welte99ed5072021-01-15 20:38:58 +01001287 var OCT4 p_tmsi := f_gen_tmsi(suffix, nri_v := mp_sgsn_nri[sgsn_idx][nri_idx],
1288 nri_bitlen := mp_nri_bitlength);
1289 var OCT4 tlli := f_gprs_tlli_from_tmsi(p_tmsi, TLLI_LOCAL);
Harald Welte00963752021-01-15 20:33:11 +01001290 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1291 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1292 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1293 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1294
1295 pdu_tx := ts_BSSGP_RESUME_ACK(tlli, ra_id);
1296 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1297 pdu_rx := tr_BSSGP_RESUME_ACK(tlli, ra_id);
1298 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1299
1300 pdu_tx := ts_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1301 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1302 pdu_rx := tr_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1303 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1304
1305 /* These messages are simple passed through so just also test sending NACK */
1306 pdu_tx := ts_BSSGP_RESUME_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1307 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1308 pdu_rx := tr_BSSGP_RESUME_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1309 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1310}
1311
Harald Weltec5c33732021-01-15 21:04:35 +01001312private function f_TC_resume(integer sgsn_idx, integer nri_idx, integer pcu_idx, integer bvc_idx)
1313runs on GlobalTest_CT {
Daniel Willmann087a33d2020-11-19 15:58:43 +01001314 var integer i;
1315
Daniel Willmann087a33d2020-11-19 15:58:43 +01001316 for (i := 0; i < 10; i := i+1) {
Harald Weltec5c33732021-01-15 21:04:35 +01001317 f_resume_one(sgsn_idx, nri_idx, pcu_idx, bvc_idx, suffix := i);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001318 }
1319 setverdict(pass);
1320}
Harald Welte3807ed12020-11-24 19:05:22 +01001321testcase TC_resume() runs on GlobalTest_CT
Daniel Willmann087a33d2020-11-19 15:58:43 +01001322{
Harald Weltec5c33732021-01-15 21:04:35 +01001323 var integer sgsn_idx, nri_idx;
Daniel Willmann087a33d2020-11-19 15:58:43 +01001324 f_init();
Harald Welte3807ed12020-11-24 19:05:22 +01001325 f_global_init();
Harald Weltec5c33732021-01-15 21:04:35 +01001326 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx+1) {
1327 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx+1) {
1328 f_TC_resume(sgsn_idx, nri_idx, pcu_idx:=0, bvc_idx:=0);
1329 }
1330 }
Daniel Willmann087a33d2020-11-19 15:58:43 +01001331 f_cleanup();
1332}
1333
Harald Weltef8ef0282020-11-18 12:16:59 +01001334/* test the load-sharing between multiple NS-VC on the BSS side */
1335private function f_TC_dl_ud_unidir(charstring id) runs on BSSGP_ConnHdlr {
1336 var integer i;
1337
1338 for (i := 0; i < 10; i := i+1) {
1339 var octetstring payload := f_rnd_octstring(i);
1340 var template (value) PDU_BSSGP pdu_tx :=
1341 ts_BSSGP_DL_UD(g_pars.tlli, payload, omit, ts_BSSGP_IMSI(g_pars.imsi));
Harald Welte09a1ce42021-01-16 11:18:38 +01001342 SGSN_PTP[g_pars.sgsn_idx].send(pdu_tx);
Harald Weltef8ef0282020-11-18 12:16:59 +01001343 }
1344 setverdict(pass);
1345}
Harald Welte09a1ce42021-01-16 11:18:38 +01001346
1347private function f_TC_load_sharing_dl(integer sgsn_idx) runs on test_CT_NS
Harald Weltef8ef0282020-11-18 12:16:59 +01001348{
1349 const integer num_ue := 10;
1350 var BSSGP_ConnHdlr vc_conn[num_ue];
Harald Weltef8ef0282020-11-18 12:16:59 +01001351 /* all BVC are now fully brought up. We disconnect BSSGP from NS on the BSS
1352 * side so we get the raw NsUnitdataIndication and hence observe different
1353 * NSVCI */
1354 disconnect(g_pcu[0].vc_NS:NS_SP, g_pcu[0].vc_BSSGP:BSCP);
1355 connect(g_pcu[0].vc_NS:NS_SP, self:NS);
1356
1357 /* there may still be some NS-VCs coming up? After all, the BVC-RESET succeeds after the first
1358 * of the NS-VC is ALIVE/UNBLOCKED */
1359 f_sleep(3.0);
1360
1361 /* start parallel components generating DL-UNITDATA from the SGSN side */
1362 for (var integer i:= 0; i < num_ue; i := i+1) {
Harald Welte2ecbca82021-01-16 11:23:09 +01001363 vc_conn[i] := f_start_handler(refers(f_TC_dl_ud_unidir), testcasename(),
Harald Welte09a1ce42021-01-16 11:18:38 +01001364 5+i, 30.0, sgsn_idx);
Harald Weltef8ef0282020-11-18 12:16:59 +01001365 }
1366
1367 /* now start counting all the messages that were queued before */
1368 /* TODO: We have a hard-coded assumption of 4 NS-VC in one NSE/NS-VCG here! */
1369 var ro_integer rx_count := { 0, 0, 0, 0 };
1370 timer T := 2.0;
1371 T.start;
1372 alt {
1373 [] as_NsUdiCount(0, rx_count);
1374 [] as_NsUdiCount(1, rx_count);
1375 [] as_NsUdiCount(2, rx_count);
1376 [] as_NsUdiCount(3, rx_count);
1377 [] NS.receive(NsUnitdataIndication:{0,?,?,*,*}) { repeat; } /* signaling BVC */
1378 [] NS.receive(NsStatusIndication:?) { repeat; }
1379 [] NS.receive {
Harald Welted5b7e742021-01-27 10:50:24 +01001380 f_shutdown(__FILE__, __LINE__, fail, "Rx unexpected NS");
Harald Weltef8ef0282020-11-18 12:16:59 +01001381 }
1382 [] T.timeout {
1383 }
1384 }
1385 for (var integer i := 0; i < lengthof(rx_count); i := i+1) {
1386 log("Rx on NSVCI ", mp_nsconfig_pcu[0].nsvc[i].nsvci, ": ", rx_count[i]);
1387 if (rx_count[i] == 0) {
1388 setverdict(fail, "Data not shared over all NSVC");
1389 }
1390 }
Harald Welte09a1ce42021-01-16 11:18:38 +01001391}
1392
1393testcase TC_load_sharing_dl() runs on test_CT_NS
1394{
1395 var integer sgsn_idx, nri_idx;
1396 f_init();
1397 for (sgsn_idx:=0; sgsn_idx < NUM_SGSN; sgsn_idx:=sgsn_idx+1) {
1398 f_TC_load_sharing_dl(sgsn_idx);
1399 }
Harald Weltef8ef0282020-11-18 12:16:59 +01001400 setverdict(pass);
1401}
1402private altstep as_NsUdiCount(integer nsvc_idx, inout ro_integer roi) runs on test_CT_NS {
1403 var NsUnitdataIndication udi;
1404 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[0];
1405 [] NS.receive(NsUnitdataIndication:{bvcc.bvci, g_pcu[0].cfg.nsei, mp_nsconfig_pcu[0].nsvc[nsvc_idx].nsvci, *, *}) -> value udi {
1406 roi[nsvc_idx] := roi[nsvc_idx] + 1;
1407 repeat;
1408 }
1409}
1410type component test_CT_NS extends test_CT {
1411 port NS_PT NS;
1412};
1413
1414
Harald Welte0e188242020-11-22 21:46:48 +01001415/***********************************************************************
1416 * PAGING PS procedure
1417 ***********************************************************************/
1418
1419private function f_send_paging_ps(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1420 boolean use_sig := false)
1421runs on BSSGP_ConnHdlr return template (present) PDU_BSSGP {
1422 var template (value) PDU_BSSGP pdu_tx;
1423 var template (present) PDU_BSSGP pdu_rx;
1424 /* we always specify '0' as BVCI in the templates below, as we override it with
1425 * 'p4' later anyway */
1426 pdu_rx := tr_BSSGP_PS_PAGING(0);
1427 pdu_rx.pDU_BSSGP_PAGING_PS.iMSI := tr_BSSGP_IMSI(g_pars.imsi);
1428 if (ispresent(g_pars.p_tmsi)) {
1429 pdu_tx := ts_BSSGP_PS_PAGING_PTMSI(0, g_pars.imsi, oct2int(g_pars.p_tmsi));
1430 pdu_rx.pDU_BSSGP_PAGING_PS.pTMSI := tr_BSSGP_TMSI(oct2int(g_pars.p_tmsi));
1431 } else {
1432 pdu_tx := ts_BSSGP_PS_PAGING_IMSI(0, g_pars.imsi);
1433 pdu_rx.pDU_BSSGP_PAGING_PS.pTMSI := omit;
1434 }
1435 pdu_tx.pDU_BSSGP_PAGING_PS.paging_Field4 := p4;
1436 pdu_rx.pDU_BSSGP_PAGING_PS.paging_Field4 := p4;
1437 if (use_sig == false) {
Harald Welte158becf2020-12-09 12:32:32 +01001438 SGSN_PTP[sgsn_idx].send(pdu_tx);
Harald Welte0e188242020-11-22 21:46:48 +01001439 } else {
1440 SGSN_SIG[sgsn_idx].send(pdu_tx);
1441 }
1442 return pdu_rx;
1443}
1444
1445/* send paging defined by 'p4' on given SGSN-side index (ptp or signaling) and expect one paging to arrive on
1446 * specified PCU index */
1447private function f_send_paging_ps_exp_one_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1448 boolean use_sig := false,integer pcu_idx := 0)
1449runs on BSSGP_ConnHdlr {
1450 var template (present) PDU_BSSGP exp_rx;
Daniel Willmann1a859712020-12-04 00:59:45 +01001451 var boolean test_done := false;
Harald Welte0e188242020-11-22 21:46:48 +01001452 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1453 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1454 exp_rx := f_send_paging_ps(p4, sgsn_idx, use_sig);
1455 /* Expect paging to propagate to the one BSS addressed by the BVCI only */
1456 timer T := 2.0;
1457 T.start;
1458 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001459 [not use_sig and not test_done] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001460 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001461 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001462 repeat;
1463 }
1464 [not use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
1465 setverdict(fail, "Received paging on SIGNALING BVC, expected PTP BVC");
1466 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001467 [use_sig and not test_done] PCU_SIG[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001468 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001469 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001470 repeat;
1471 }
Harald Welte158becf2020-12-09 12:32:32 +01001472 [use_sig] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001473 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1474 }
Harald Welte158becf2020-12-09 12:32:32 +01001475 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001476 setverdict(fail, "Paging received on unexpected BVC");
1477 }
1478 [] any from PCU_SIG.receive(exp_rx) {
1479 setverdict(fail, "Paging received on unexpected BVC");
1480 }
Harald Welte158becf2020-12-09 12:32:32 +01001481 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01001482 setverdict(fail, "Different Paging than expected received PTP BVC");
1483 }
1484 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1485 setverdict(fail, "Different Paging than expected on SIGNALING BVC");
1486 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001487 [not test_done] T.timeout {
1488 setverdict(fail, "Timeout waiting for paging");
1489 }
1490 [test_done] T.timeout;
Harald Welte0e188242020-11-22 21:46:48 +01001491 }
1492}
1493
Harald Welte7462a592020-11-23 22:07:07 +01001494/* send a PS-PAGING but don't expect it to show up on any PTP or SIG BVC */
1495private function f_send_paging_ps_exp_no_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1496 boolean use_sig := false)
1497runs on BSSGP_ConnHdlr {
1498 var template (present) PDU_BSSGP exp_rx;
1499 exp_rx := f_send_paging_ps(p4, sgsn_idx, use_sig);
1500 /* Expect paging to propagate to no BSS */
1501 timer T := 2.0;
1502 T.start;
1503 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001504 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte7462a592020-11-23 22:07:07 +01001505 setverdict(fail, "Paging received on unexpected BVC");
1506 }
1507 [] any from PCU_SIG.receive(exp_rx) {
1508 setverdict(fail, "Paging received on unexpected BVC");
1509 }
Harald Welte158becf2020-12-09 12:32:32 +01001510 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte7462a592020-11-23 22:07:07 +01001511 setverdict(fail, "Different Paging received on PTP BVC");
1512 }
1513 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1514 setverdict(fail, "Different Paging received on SIGNALING BVC");
1515 }
1516 [] T.timeout {
1517 setverdict(pass);
1518 }
1519 }
1520}
1521
Harald Welte0e188242020-11-22 21:46:48 +01001522private function f_TC_paging_ps_ptp_bss(charstring id) runs on BSSGP_ConnHdlr
1523{
1524 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1525 * at that BVC (cell) only, and paging all over the BSS area is not possible */
Daniel Willmann2a330672021-01-18 18:50:02 +01001526 f_send_paging_ps_exp_one_bss(ts_BssgpP4BssArea, g_pars.sgsn_idx, false, 0);
Harald Welte0e188242020-11-22 21:46:48 +01001527}
1528testcase TC_paging_ps_ptp_bss() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001529 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001530 f_start_handlers(refers(f_TC_paging_ps_ptp_bss), testcasename(), 9);
Harald Welte0e188242020-11-22 21:46:48 +01001531 f_cleanup();
1532}
1533
1534/* PS-PAGING on PTP-BVC for Location Area */
1535private function f_TC_paging_ps_ptp_lac(charstring id) runs on BSSGP_ConnHdlr
1536{
1537 var template (present) PDU_BSSGP exp_rx;
1538 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1539 * at that BVC (cell) only, and paging all over the BSS area is not possible */
Daniel Willmann2a330672021-01-18 18:50:02 +01001540 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 +01001541}
1542testcase TC_paging_ps_ptp_lac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001543 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001544 f_start_handlers(refers(f_TC_paging_ps_ptp_lac), testcasename(), 10);
Harald Welte0e188242020-11-22 21:46:48 +01001545 f_cleanup();
1546}
1547
Harald Welte7462a592020-11-23 22:07:07 +01001548/* PS-PAGING on PTP-BVC for unknown Location Area */
1549private function f_TC_paging_ps_ptp_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1550{
1551 var GSM_Types.LocationAreaIdentification unknown_la := {
1552 mcc_mnc := '567F99'H,
1553 lac := 33333
1554 };
1555 /* as it's sent on the PTP BVC, we expect it to pass even for unknown LAC */
Daniel Willmann2a330672021-01-18 18:50:02 +01001556 f_send_paging_ps_exp_one_bss(ts_BssgpP4LAC(unknown_la), g_pars.sgsn_idx, false, 0);
Harald Welte7462a592020-11-23 22:07:07 +01001557}
1558testcase TC_paging_ps_ptp_lac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001559 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001560 f_start_handlers(refers(f_TC_paging_ps_ptp_lac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001561 f_cleanup();
1562}
1563
Harald Welte0e188242020-11-22 21:46:48 +01001564/* PS-PAGING on PTP-BVC for Routeing Area */
1565private function f_TC_paging_ps_ptp_rac(charstring id) runs on BSSGP_ConnHdlr
1566{
1567 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1568 * at that BVC (cell) only, and paging all over the BSS area is not possible */
Daniel Willmann2a330672021-01-18 18:50:02 +01001569 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 +01001570}
1571testcase TC_paging_ps_ptp_rac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001572 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001573 f_start_handlers(refers(f_TC_paging_ps_ptp_rac), testcasename(), 11);
Harald Welte0e188242020-11-22 21:46:48 +01001574 f_cleanup();
1575}
1576
Harald Welte7462a592020-11-23 22:07:07 +01001577/* PS-PAGING on PTP-BVC for unknown Routeing Area */
1578private function f_TC_paging_ps_ptp_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1579{
1580 var RoutingAreaIdentification unknown_ra := {
1581 lai := {
1582 mcc_mnc := '567F99'H,
1583 lac := 33333
1584 },
1585 rac := 254
1586 };
1587 /* as it's sent on the PTP BVC, we expect it to pass even for unknown RAC */
Daniel Willmann2a330672021-01-18 18:50:02 +01001588 f_send_paging_ps_exp_one_bss(ts_BssgpP4RAC(unknown_ra), g_pars.sgsn_idx, false, 0);
Harald Welte7462a592020-11-23 22:07:07 +01001589}
1590testcase TC_paging_ps_ptp_rac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001591 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001592 f_start_handlers(refers(f_TC_paging_ps_ptp_rac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001593 f_cleanup();
1594}
1595
Harald Welte0e188242020-11-22 21:46:48 +01001596/* PS-PAGING on PTP-BVC for BVCI (one cell) */
1597private function f_TC_paging_ps_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
1598{
1599 /* this should be the normal case for MS in READY MM state after a lower layer failure */
Daniel Willmann2a330672021-01-18 18:50:02 +01001600 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 +01001601}
1602testcase TC_paging_ps_ptp_bvci() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001603 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001604 f_start_handlers(refers(f_TC_paging_ps_ptp_bvci), testcasename(), 12);
Harald Welte0e188242020-11-22 21:46:48 +01001605 f_cleanup();
1606}
1607
Harald Welteb5a04aa2021-01-16 13:04:40 +01001608
1609/* PS-PAGING on PTP-BVC for BVCI (one cell) using IMSI only (no P-TMSI allocated) */
1610testcase TC_paging_ps_ptp_bvci_imsi() runs on test_CT {
1611 f_init();
1612 f_start_handlers(refers(f_TC_paging_ps_ptp_bvci), testcasename(), 12, have_ptmsi:=false);
1613 f_cleanup();
1614}
1615
Harald Weltecf200072021-01-16 15:20:46 +01001616/* Rejected PS-PAGING on PTP-BVC for BVCI (one cell) */
1617testcase TC_paging_ps_reject_ptp_bvci() runs on test_CT {
1618 f_init();
1619 f_start_handlers(refers(f_TC_paging_ps_reject_ptp_bvci), testcasename(), 16);
1620 f_cleanup();
1621}
1622
1623/* Rejected PS-PAGING on PTP-BVC for BVCI (one cell) using IMSI only (no P-TMSI allocated) */
1624private function f_TC_paging_ps_reject_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
1625{
1626 /* first send the PS-PAGING from SGSN -> PCU */
Daniel Willmann2a330672021-01-18 18:50:02 +01001627 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 +01001628 /* then simulate the PS-PAGING-REJECT from the PCU */
1629 f_send_paging_ps_rej(use_sig:=false);
1630}
1631testcase TC_paging_ps_reject_ptp_bvci_imsi() runs on test_CT {
1632 f_init();
1633 f_start_handlers(refers(f_TC_paging_ps_reject_ptp_bvci), testcasename(), 16, have_ptmsi:=false);
1634 f_cleanup();
1635}
Harald Welteb5a04aa2021-01-16 13:04:40 +01001636
Harald Welte7462a592020-11-23 22:07:07 +01001637/* PS-PAGING on PTP-BVC for unknown BVCI */
1638private function f_TC_paging_ps_ptp_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1639{
1640 /* as it's sent on the PTP BVC, we expect it to pass even for unknown BVCI */
Daniel Willmann2a330672021-01-18 18:50:02 +01001641 f_send_paging_ps_exp_one_bss(ts_BssgpP4Bvci(33333), g_pars.sgsn_idx, false, 0);
Harald Welte7462a592020-11-23 22:07:07 +01001642}
1643testcase TC_paging_ps_ptp_bvci_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001644 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001645 f_start_handlers(refers(f_TC_paging_ps_ptp_bvci_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001646 f_cleanup();
1647}
1648
Harald Welte7595d562021-01-16 19:09:20 +01001649/* DUMMY PAGING PS on PTP BVC */
1650private function f_TC_dummy_paging_ps_ptp(charstring id) runs on BSSGP_ConnHdlr
1651{
1652 f_sgsn2pcu(ts_BSSGP_DUMMY_PAGING_PS(g_pars.imsi, omit),
1653 tr_BSSGP_DUMMY_PAGING_PS(g_pars.imsi, omit), use_sig := false);
1654 f_pcu2sgsn(ts_BSSGP_DUMMY_PAGING_PS_RESP(g_pars.imsi, 1, 5),
1655 tr_BSSGP_DUMMY_PAGING_PS_RESP(g_pars.imsi, 1, 5), use_sig := false)
1656}
1657testcase TC_dummy_paging_ps_ptp() runs on test_CT {
1658 f_init();
1659 f_start_handlers(refers(f_TC_dummy_paging_ps_ptp), testcasename(), 11);
1660 f_cleanup();
1661}
1662
Harald Welte0e188242020-11-22 21:46:48 +01001663/* altstep for expecting BSSGP PDU on signaling BVC of given pcu_idx + storing in 'roi' */
1664private altstep as_paging_sig_pcu(integer pcu_idx, template (present) PDU_BSSGP exp_rx, inout ro_integer roi)
1665runs on BSSGP_ConnHdlr {
1666[] PCU_SIG[pcu_idx].receive(exp_rx) {
1667 if (ro_integer_contains(roi, pcu_idx)) {
1668 setverdict(fail, "Received multiple paging on same SIG BVC");
1669 }
1670 roi := roi & { pcu_idx };
1671 repeat;
1672 }
Harald Welte158becf2020-12-09 12:32:32 +01001673[] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001674 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1675 }
1676[] PCU_SIG[pcu_idx].receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1677 setverdict(fail, "Different Paging than expected received SIGNALING BVC");
1678 }
Harald Welte158becf2020-12-09 12:32:32 +01001679[] PCU_PTP[pcu_idx].receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01001680 setverdict(fail, "Different Paging than expected received PTP BVC");
1681 }
1682}
1683
1684type record of default ro_default;
1685
1686/* send PS-PAGING on SIG BVC, expect it to arrive on given list of PCU indexes */
1687private function f_send_paging_ps_exp_multi(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1688 ro_integer exp_on_pcu_idx) runs on BSSGP_ConnHdlr
1689{
1690 var template (present) PDU_BSSGP exp_rx;
Daniel Willmann193e1a02021-01-17 12:55:53 +01001691 exp_rx := f_send_paging_ps(p4, sgsn_idx, true);
Harald Welte0e188242020-11-22 21:46:48 +01001692
1693 /* FIXME: make sure the relevant BVCs/BSS are connected to the ports! */
1694 var ro_default defaults := {};
1695 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1696 var default d := activate(as_paging_sig_pcu(i, exp_rx, g_roi));
1697 defaults := defaults & { d };
1698 }
1699 f_sleep(2.0);
1700 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
1701 deactivate(defaults[i]);
1702 }
1703 log("Paging received on PCU ", g_roi);
1704
1705 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1706 var boolean rx_on_i := ro_integer_contains(g_roi, i);
1707 var boolean exp_on_i := ro_integer_contains(exp_on_pcu_idx, i);
1708 if (exp_on_i and not rx_on_i) {
1709 setverdict(fail, "PS-PAGING not received on ", mp_nsconfig_pcu[i].nsei);
1710 }
1711 if (not exp_on_i and rx_on_i) {
1712 setverdict(fail, "PS-PAGING not expected but received on ", mp_nsconfig_pcu[i].nsei);
1713 }
1714 }
1715 setverdict(pass);
1716}
1717
Harald Weltecf200072021-01-16 15:20:46 +01001718/* Send PAGING-PS-REJECT on SIG BVC, expect it to arrive on the "right" SGSN */
1719private function f_send_paging_ps_rej(boolean use_sig := true, integer pcu_idx := 0) runs on BSSGP_ConnHdlr
1720{
1721 var template (value) PDU_BSSGP pdu_tx;
1722 var template (present) PDU_BSSGP exp_rx;
1723 var PDU_BSSGP pdu_rx;
1724 timer T := 5.0;
1725 var template (omit) GsmTmsi tmsi_int := omit;
1726
1727 if (ispresent(g_pars.p_tmsi)) {
1728 tmsi_int := oct2int(g_pars.p_tmsi);
1729 }
1730
1731 pdu_tx := ts_BSSGP_PAGING_PS_REJ(g_pars.imsi, 23, 42, tmsi_int);
1732 exp_rx := tr_BSSGP_PAGING_PS_REJ(g_pars.imsi, 23, 42, tmsi_int);
1733
1734 if (use_sig) {
1735 PCU_SIG[pcu_idx].send(pdu_tx);
1736 } else {
1737 PCU_PTP[pcu_idx].send(pdu_tx);
1738 }
1739 T.start;
1740 alt {
1741 [use_sig] SGSN_SIG[g_pars.sgsn_idx].receive(exp_rx) -> value pdu_rx {
1742 setverdict(pass);
1743 }
1744 [use_sig] SGSN_SIG[g_pars.sgsn_idx].receive {
1745 setverdict(fail, "Unexpected PDU on SGSN");
1746 }
1747 [use_sig] any from SGSN_SIG.receive(exp_rx) -> value pdu_rx {
1748 setverdict(fail, "PAGING-PS-REJECT arrived on wrong SGSN");
1749 }
1750 [not use_sig] SGSN_PTP[g_pars.sgsn_idx].receive(exp_rx) -> value pdu_rx {
1751 setverdict(pass);
1752 }
1753 [not use_sig] SGSN_PTP[g_pars.sgsn_idx].receive {
1754 setverdict(fail, "Unexpected PDU on SGSN");
1755 }
1756 [not use_sig] any from SGSN_PTP.receive(exp_rx) -> value pdu_rx {
1757 setverdict(fail, "PAGING-PS-REJECT arrived on wrong SGSN");
1758 }
1759 [] T.timeout {
1760 setverdict(fail, "Timeout waiting for PAGING-PS-REJECT");
1761 }
1762 }
1763}
1764
Harald Welte0e188242020-11-22 21:46:48 +01001765/* PS-PAGING on SIG-BVC for BSS Area */
1766private function f_TC_paging_ps_sig_bss(charstring id) runs on BSSGP_ConnHdlr
1767{
1768 /* we expect the paging to arrive on all three NSE */
Daniel Willmann43320442021-01-17 14:07:05 +01001769 f_send_paging_ps_exp_multi(ts_BssgpP4BssArea, g_pars.sgsn_idx, {0, 1, 2});
Harald Welte0e188242020-11-22 21:46:48 +01001770}
1771testcase TC_paging_ps_sig_bss() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001772 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001773 f_start_handlers(refers(f_TC_paging_ps_sig_bss), testcasename(), 13);
Harald Welte0e188242020-11-22 21:46:48 +01001774 f_cleanup();
1775}
1776
1777/* PS-PAGING on SIG-BVC for Location Area */
1778private function f_TC_paging_ps_sig_lac(charstring id) runs on BSSGP_ConnHdlr
1779{
Daniel Willmann2c9300f2020-12-01 10:54:08 +01001780 /* The first LAC (13135) is shared by all three NSEs */
Daniel Willmann43320442021-01-17 14:07:05 +01001781 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 +01001782 /* Reset state */
1783 g_roi := {};
1784 /* Make LAC (13300) available on pcu index 2 */
1785 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
Daniel Willmann43320442021-01-17 14:07:05 +01001786 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 +01001787}
1788testcase TC_paging_ps_sig_lac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001789 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001790 f_start_handlers(refers(f_TC_paging_ps_sig_lac), testcasename(), 14);
Harald Welte0e188242020-11-22 21:46:48 +01001791 f_cleanup();
1792}
1793
Harald Welte7462a592020-11-23 22:07:07 +01001794/* PS-PAGING on SIG-BVC for unknown Location Area */
1795private function f_TC_paging_ps_sig_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1796{
1797 var GSM_Types.LocationAreaIdentification unknown_la := {
1798 mcc_mnc := '567F99'H,
1799 lac := 33333
1800 };
Daniel Willmann2a330672021-01-18 18:50:02 +01001801 f_send_paging_ps_exp_no_bss(ts_BssgpP4LAC(unknown_la), g_pars.sgsn_idx, true);
Harald Welte7462a592020-11-23 22:07:07 +01001802}
1803testcase TC_paging_ps_sig_lac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001804 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001805 f_start_handlers(refers(f_TC_paging_ps_sig_lac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001806 f_cleanup();
1807}
1808
Harald Welte0e188242020-11-22 21:46:48 +01001809/* PS-PAGING on SIG-BVC for Routeing Area */
1810private function f_TC_paging_ps_sig_rac(charstring id) runs on BSSGP_ConnHdlr
1811{
Daniel Willmann2c9300f2020-12-01 10:54:08 +01001812 /* Only PCU index 0 has a matching BVC with the RA ID */
Daniel Willmann43320442021-01-17 14:07:05 +01001813 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 +01001814 g_roi := {};
1815 /* PCU index 1 and 2 have a matching BVC with the RA ID */
Daniel Willmann43320442021-01-17 14:07:05 +01001816 f_send_paging_ps_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[2].cell_id.ra_id), g_pars.sgsn_idx, {1, 2});
Daniel Willmann2c9300f2020-12-01 10:54:08 +01001817 g_roi := {};
1818 /* PCU index 2 has two matching BVCs with the RA ID */
1819 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
Daniel Willmann43320442021-01-17 14:07:05 +01001820 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 +01001821}
1822testcase TC_paging_ps_sig_rac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001823 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001824 f_start_handlers(refers(f_TC_paging_ps_sig_rac), testcasename(), 15);
Harald Welte0e188242020-11-22 21:46:48 +01001825 f_cleanup();
1826}
1827
Harald Welte7462a592020-11-23 22:07:07 +01001828/* PS-PAGING on SIG-BVC for unknown Routeing Area */
1829private function f_TC_paging_ps_sig_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1830{
1831 var RoutingAreaIdentification unknown_ra := {
1832 lai := {
1833 mcc_mnc := '567F99'H,
1834 lac := 33333
1835 },
1836 rac := 254
1837 };
Daniel Willmann2a330672021-01-18 18:50:02 +01001838 f_send_paging_ps_exp_no_bss(ts_BssgpP4RAC(unknown_ra), g_pars.sgsn_idx, true);
Harald Welte7462a592020-11-23 22:07:07 +01001839}
1840testcase TC_paging_ps_sig_rac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001841 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001842 f_start_handlers(refers(f_TC_paging_ps_sig_rac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001843 f_cleanup();
1844}
1845
Harald Welte0e188242020-11-22 21:46:48 +01001846/* PS-PAGING on SIG-BVC for BVCI (one cell) */
1847private function f_TC_paging_ps_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
1848{
Daniel Willmann43320442021-01-17 14:07:05 +01001849 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 +01001850}
1851testcase TC_paging_ps_sig_bvci() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001852 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001853 f_start_handlers(refers(f_TC_paging_ps_sig_bvci), testcasename(), 16);
Harald Welte0e188242020-11-22 21:46:48 +01001854 f_cleanup();
1855}
1856
Harald Welteb5a04aa2021-01-16 13:04:40 +01001857/* PS-PAGING on SIG-BVC for BVCI (one cell) using IMSI only (no P-TMSI allocated) */
1858testcase TC_paging_ps_sig_bvci_imsi() runs on test_CT {
1859 f_init();
1860 f_start_handlers(refers(f_TC_paging_ps_sig_bvci), testcasename(), 16, have_ptmsi:=false);
1861 f_cleanup();
1862}
1863
Harald Weltecf200072021-01-16 15:20:46 +01001864/* Rejected PS-PAGING on SIG-BVC for BVCI (one cell) */
1865private function f_TC_paging_ps_reject_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
1866{
1867 /* first send the PS-PAGING from SGSN -> PCU */
Daniel Willmann43320442021-01-17 14:07:05 +01001868 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 +01001869 /* then simulate the PS-PAGING-REJECT from the PCU */
1870 f_send_paging_ps_rej(use_sig:=true);
1871
1872}
1873testcase TC_paging_ps_reject_sig_bvci() runs on test_CT {
1874 f_init();
1875 f_start_handlers(refers(f_TC_paging_ps_reject_sig_bvci), testcasename(), 16);
1876 f_cleanup();
1877}
1878
1879/* Rejected PS-PAGING on SIG-BVC for BVCI (one cell) using IMSI only (no P-TMSI allocated) */
1880testcase TC_paging_ps_reject_sig_bvci_imsi() runs on test_CT {
1881 f_init();
1882 f_start_handlers(refers(f_TC_paging_ps_reject_sig_bvci), testcasename(), 16, have_ptmsi:=false);
1883 f_cleanup();
1884}
1885
Harald Welte7462a592020-11-23 22:07:07 +01001886/* PS-PAGING on SIG-BVC for unknown BVCI */
1887private function f_TC_paging_ps_sig_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1888{
Daniel Willmann2a330672021-01-18 18:50:02 +01001889 f_send_paging_ps_exp_no_bss(ts_BssgpP4Bvci(33333), g_pars.sgsn_idx, true);
Harald Welte7462a592020-11-23 22:07:07 +01001890}
1891testcase TC_paging_ps_sig_bvci_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001892 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001893 f_start_handlers(refers(f_TC_paging_ps_sig_bvci_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001894 f_cleanup();
1895}
1896
Harald Welte7595d562021-01-16 19:09:20 +01001897/* DUMMY PAGING PS on SIG BVC */
1898private function f_TC_dummy_paging_ps_sig(charstring id) runs on BSSGP_ConnHdlr
1899{
1900 f_sgsn2pcu(ts_BSSGP_DUMMY_PAGING_PS(g_pars.imsi, omit),
1901 tr_BSSGP_DUMMY_PAGING_PS(g_pars.imsi, omit), use_sig := true);
1902 f_pcu2sgsn(ts_BSSGP_DUMMY_PAGING_PS_RESP(g_pars.imsi, 1, 5),
1903 tr_BSSGP_DUMMY_PAGING_PS_RESP(g_pars.imsi, 1, 5), use_sig := true)
1904}
1905testcase TC_dummy_paging_ps_sig() runs on test_CT {
1906 f_init();
1907 f_start_handlers(refers(f_TC_dummy_paging_ps_sig), testcasename(), 11);
1908 f_cleanup();
1909}
1910
Harald Welte7462a592020-11-23 22:07:07 +01001911
Harald Welte0e188242020-11-22 21:46:48 +01001912
1913/***********************************************************************
1914 * PAGING CS procedure
1915 ***********************************************************************/
1916
1917private function f_send_paging_cs(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1918 boolean use_sig := false)
1919runs on BSSGP_ConnHdlr return template (present) PDU_BSSGP {
1920 var template (value) PDU_BSSGP pdu_tx;
1921 var template (present) PDU_BSSGP pdu_rx;
1922 /* we always specify '0' as BVCI in the templates below, as we override it with
1923 * 'p4' later anyway */
1924 pdu_rx := tr_BSSGP_CS_PAGING(0);
1925 pdu_rx.pDU_BSSGP_PAGING_CS.iMSI := tr_BSSGP_IMSI(g_pars.imsi);
1926 if (ispresent(g_pars.p_tmsi)) {
1927 pdu_tx := ts_BSSGP_CS_PAGING_PTMSI(0, g_pars.imsi, oct2int(g_pars.p_tmsi));
1928 pdu_rx.pDU_BSSGP_PAGING_CS.tMSI := tr_BSSGP_TMSI(oct2int(g_pars.p_tmsi));
1929 } else {
1930 pdu_tx := ts_BSSGP_CS_PAGING_IMSI(0, g_pars.imsi);
1931 pdu_rx.pDU_BSSGP_PAGING_CS.tMSI := omit;
1932 }
1933 pdu_tx.pDU_BSSGP_PAGING_CS.paging_Field4 := p4;
1934 pdu_rx.pDU_BSSGP_PAGING_CS.paging_Field4 := p4;
1935 if (use_sig == false) {
Harald Welte158becf2020-12-09 12:32:32 +01001936 SGSN_PTP[sgsn_idx].send(pdu_tx);
Harald Welte0e188242020-11-22 21:46:48 +01001937 } else {
1938 SGSN_SIG[sgsn_idx].send(pdu_tx);
1939 }
1940 return pdu_rx;
1941}
1942
1943/* send paging defined by 'p4' on given SGSN-side index (ptp or signaling) and expect one paging to arrive on
1944 * specified PCU index */
1945private function f_send_paging_cs_exp_one_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1946 boolean use_sig := false,integer pcu_idx := 0)
1947runs on BSSGP_ConnHdlr {
1948 var template (present) PDU_BSSGP exp_rx;
Daniel Willmann1a859712020-12-04 00:59:45 +01001949 var boolean test_done := false;
Harald Welte0e188242020-11-22 21:46:48 +01001950 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1951 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1952 exp_rx := f_send_paging_cs(p4, sgsn_idx, use_sig);
1953 /* Expect paging to propagate to the one BSS addressed by the BVCI only */
1954 timer T := 2.0;
1955 T.start;
1956 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001957 [not use_sig and not test_done] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001958 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001959 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001960 repeat;
1961 }
1962 [not use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
1963 setverdict(fail, "Received paging on SIGNALING BVC, expected PTP BVC");
1964 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001965 [use_sig and not test_done] PCU_SIG[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001966 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001967 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001968 repeat;
1969 }
Harald Welte158becf2020-12-09 12:32:32 +01001970 [use_sig] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001971 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1972 }
Harald Welte158becf2020-12-09 12:32:32 +01001973 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001974 setverdict(fail, "Paging received on unexpected BVC");
1975 }
1976 [] any from PCU_SIG.receive(exp_rx) {
1977 setverdict(fail, "Paging received on unexpected BVC");
1978 }
Harald Welte158becf2020-12-09 12:32:32 +01001979 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01001980 setverdict(fail, "Different Paging than expected received PTP BVC");
1981 }
1982 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
1983 setverdict(fail, "Different Paging than expected on SIGNALING BVC");
1984 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001985 [not test_done] T.timeout {
1986 setverdict(fail, "Timeout while waiting for paging")
1987 }
1988 [test_done] T.timeout;
Harald Welte0e188242020-11-22 21:46:48 +01001989 }
1990}
1991
Harald Welte7462a592020-11-23 22:07:07 +01001992/* send a CS-PAGING but don't expect it to show up on any PTP or SIG BVC */
1993private function f_send_paging_cs_exp_no_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1994 boolean use_sig := false)
1995runs on BSSGP_ConnHdlr {
1996 var template (present) PDU_BSSGP exp_rx;
1997 exp_rx := f_send_paging_cs(p4, sgsn_idx, use_sig);
1998 /* Expect paging to propagate to no BSS */
1999 timer T := 2.0;
2000 T.start;
2001 alt {
Harald Welte158becf2020-12-09 12:32:32 +01002002 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte7462a592020-11-23 22:07:07 +01002003 setverdict(fail, "Paging received on unexpected BVC");
2004 }
2005 [] any from PCU_SIG.receive(exp_rx) {
2006 setverdict(fail, "Paging received on unexpected BVC");
2007 }
Harald Welte158becf2020-12-09 12:32:32 +01002008 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
Harald Welte7462a592020-11-23 22:07:07 +01002009 setverdict(fail, "Different Paging received on PTP BVC");
2010 }
2011 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
2012 setverdict(fail, "Different Paging received on SIGNALING BVC");
2013 }
2014 [] T.timeout {
2015 setverdict(pass);
2016 }
2017 }
2018}
2019
Harald Welte0e188242020-11-22 21:46:48 +01002020private function f_TC_paging_cs_ptp_bss(charstring id) runs on BSSGP_ConnHdlr
2021{
2022 /* doesn't really make sense: Sending to a single BVCI means the message ends up
2023 * at that BVC (cell) only, and paging all over the BSS area is not possible */
2024 f_send_paging_cs_exp_one_bss(ts_BssgpP4BssArea, 0, false, 0);
2025}
2026testcase TC_paging_cs_ptp_bss() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002027 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002028 f_start_handlers(refers(f_TC_paging_cs_ptp_bss), testcasename(), 17);
Harald Welte0e188242020-11-22 21:46:48 +01002029 f_cleanup();
2030}
2031
2032/* CS-PAGING on PTP-BVC for Location Area */
2033private function f_TC_paging_cs_ptp_lac(charstring id) runs on BSSGP_ConnHdlr
2034{
2035 var template (present) PDU_BSSGP exp_rx;
2036 /* doesn't really make sense: Sending to a single BVCI means the message ends up
2037 * at that BVC (cell) only, and paging all over the BSS area is not possible */
2038 f_send_paging_cs_exp_one_bss(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, false, 0);
2039}
2040testcase TC_paging_cs_ptp_lac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002041 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002042 f_start_handlers(refers(f_TC_paging_cs_ptp_lac), testcasename(), 18);
Harald Welte0e188242020-11-22 21:46:48 +01002043 f_cleanup();
2044}
2045
Harald Welte7462a592020-11-23 22:07:07 +01002046/* CS-PAGING on PTP-BVC for unknown Location Area */
2047private function f_TC_paging_cs_ptp_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
2048{
2049 var GSM_Types.LocationAreaIdentification unknown_la := {
2050 mcc_mnc := '567F99'H,
2051 lac := 33333
2052 };
2053 /* as it's sent on the PTP BVC, we expect it to pass even for unknown LAC */
2054 f_send_paging_cs_exp_one_bss(ts_BssgpP4LAC(unknown_la), 0, false, 0);
2055}
2056testcase TC_paging_cs_ptp_lac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002057 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002058 f_start_handlers(refers(f_TC_paging_cs_ptp_lac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002059 f_cleanup();
2060}
2061
Harald Welte0e188242020-11-22 21:46:48 +01002062/* CS-PAGING on PTP-BVC for Routeing Area */
2063private function f_TC_paging_cs_ptp_rac(charstring id) runs on BSSGP_ConnHdlr
2064{
2065 /* doesn't really make sense: Sending to a single BVCI means the message ends up
2066 * at that BVC (cell) only, and paging all over the BSS area is not possible */
2067 f_send_paging_cs_exp_one_bss(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, false, 0);
2068}
2069testcase TC_paging_cs_ptp_rac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002070 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002071 f_start_handlers(refers(f_TC_paging_cs_ptp_rac), testcasename(), 19);
Harald Welte0e188242020-11-22 21:46:48 +01002072 f_cleanup();
2073}
2074
Harald Welte7462a592020-11-23 22:07:07 +01002075/* CS-PAGING on PTP-BVC for unknown Routeing Area */
2076private function f_TC_paging_cs_ptp_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
2077{
2078 var RoutingAreaIdentification unknown_ra := {
2079 lai := {
2080 mcc_mnc := '567F99'H,
2081 lac := 33333
2082 },
2083 rac := 254
2084 };
2085 /* as it's sent on the PTP BVC, we expect it to pass even for unknown RAC */
2086 f_send_paging_cs_exp_one_bss(ts_BssgpP4RAC(unknown_ra), 0, false, 0);
2087}
2088testcase TC_paging_cs_ptp_rac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002089 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002090 f_start_handlers(refers(f_TC_paging_cs_ptp_rac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002091 f_cleanup();
2092}
2093
Harald Welte0e188242020-11-22 21:46:48 +01002094/* CS-PAGING on PTP-BVC for BVCI (one cell) */
2095private function f_TC_paging_cs_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
2096{
2097 /* this should be the normal case for MS in READY MM state after a lower layer failure */
2098 f_send_paging_cs_exp_one_bss(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, false, 0);
2099}
2100testcase TC_paging_cs_ptp_bvci() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002101 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002102 f_start_handlers(refers(f_TC_paging_cs_ptp_bvci), testcasename(), 20);
Harald Welte0e188242020-11-22 21:46:48 +01002103 f_cleanup();
2104}
2105
Harald Welte7462a592020-11-23 22:07:07 +01002106/* CS-PAGING on PTP-BVC for unknown BVCI */
2107private function f_TC_paging_cs_ptp_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
2108{
2109 /* as it's sent on the PTP BVC, we expect it to pass even for unknown BVCI */
2110 f_send_paging_cs_exp_one_bss(ts_BssgpP4Bvci(33333), 0, false, 0);
2111}
2112testcase TC_paging_cs_ptp_bvci_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002113 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002114 f_start_handlers(refers(f_TC_paging_cs_ptp_bvci_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002115 f_cleanup();
2116}
2117
Harald Welte0e188242020-11-22 21:46:48 +01002118/* send CS-PAGING on SIG BVC, expect it to arrive on given list of PCU indexes */
2119private function f_send_paging_cs_exp_multi(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
2120 ro_integer exp_on_pcu_idx) runs on BSSGP_ConnHdlr
2121{
2122 var template (present) PDU_BSSGP exp_rx;
2123 exp_rx := f_send_paging_cs(p4, 0, true);
2124
2125 /* FIXME: make sure the relevant BVCs/BSS are connected to the ports! */
2126 var ro_default defaults := {};
2127 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
2128 var default d := activate(as_paging_sig_pcu(i, exp_rx, g_roi));
2129 defaults := defaults & { d };
2130 }
2131 f_sleep(2.0);
2132 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2133 deactivate(defaults[i]);
2134 }
2135 log("Paging received on PCU ", g_roi);
2136
2137 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
2138 var boolean rx_on_i := ro_integer_contains(g_roi, i);
2139 var boolean exp_on_i := ro_integer_contains(exp_on_pcu_idx, i);
2140 if (exp_on_i and not rx_on_i) {
2141 setverdict(fail, "PS-PAGING not received on ", mp_nsconfig_pcu[i].nsei);
2142 }
2143 if (not exp_on_i and rx_on_i) {
2144 setverdict(fail, "PS-PAGING not expected but received on ", mp_nsconfig_pcu[i].nsei);
2145 }
2146 }
2147 setverdict(pass);
2148}
2149
2150/* CS-PAGING on SIG-BVC for BSS Area */
2151private function f_TC_paging_cs_sig_bss(charstring id) runs on BSSGP_ConnHdlr
2152{
2153 /* we expect the paging to arrive on all three NSE */
2154 f_send_paging_cs_exp_multi(ts_BssgpP4BssArea, 0, {0, 1, 2});
2155}
2156testcase TC_paging_cs_sig_bss() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002157 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002158 f_start_handlers(refers(f_TC_paging_cs_sig_bss), testcasename(), 13);
Harald Welte0e188242020-11-22 21:46:48 +01002159 f_cleanup();
2160}
2161
2162/* CS-PAGING on SIG-BVC for Location Area */
2163private function f_TC_paging_cs_sig_lac(charstring id) runs on BSSGP_ConnHdlr
2164{
Daniel Willmannd4fb73c2020-12-07 13:57:17 +01002165 /* The first LAC (13135) is shared by all three NSEs */
2166 f_send_paging_cs_exp_multi(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, {0, 1, 2});
2167 /* Reset state */
2168 g_roi := {};
2169 /* Make LAC (13300) available on pcu index 2 */
2170 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
2171 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 +01002172}
2173testcase TC_paging_cs_sig_lac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002174 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002175 f_start_handlers(refers(f_TC_paging_cs_sig_lac), testcasename(), 14);
Harald Welte0e188242020-11-22 21:46:48 +01002176 f_cleanup();
2177}
2178
Harald Welte7462a592020-11-23 22:07:07 +01002179/* CS-PAGING on SIG-BVC for unknown Location Area */
2180private function f_TC_paging_cs_sig_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
2181{
2182 var GSM_Types.LocationAreaIdentification unknown_la := {
2183 mcc_mnc := '567F99'H,
2184 lac := 33333
2185 };
2186 f_send_paging_cs_exp_no_bss(ts_BssgpP4LAC(unknown_la), 0, true);
2187}
2188testcase TC_paging_cs_sig_lac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002189 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002190 f_start_handlers(refers(f_TC_paging_cs_sig_lac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002191 f_cleanup();
2192}
2193
Harald Welte0e188242020-11-22 21:46:48 +01002194/* CS-PAGING on SIG-BVC for Routeing Area */
2195private function f_TC_paging_cs_sig_rac(charstring id) runs on BSSGP_ConnHdlr
2196{
Daniel Willmannd4fb73c2020-12-07 13:57:17 +01002197 /* Only PCU index 0 has a matching BVC with the RA ID */
Harald Welte0e188242020-11-22 21:46:48 +01002198 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 +01002199 g_roi := {};
2200 /* PCU index 1 and 2 have a matching BVC with the RA ID */
2201 f_send_paging_cs_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[2].cell_id.ra_id), 0, {1, 2});
2202 g_roi := {};
2203 /* PCU index 2 has two matching BVCs with the RA ID */
2204 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
2205 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 +01002206}
2207testcase TC_paging_cs_sig_rac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002208 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002209 f_start_handlers(refers(f_TC_paging_cs_sig_rac), testcasename(), 15);
Harald Welte0e188242020-11-22 21:46:48 +01002210 f_cleanup();
2211}
2212
Harald Welte7462a592020-11-23 22:07:07 +01002213/* CS-PAGING on SIG-BVC for unknown Routeing Area */
2214private function f_TC_paging_cs_sig_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
2215{
2216 var RoutingAreaIdentification unknown_ra := {
2217 lai := {
2218 mcc_mnc := '567F99'H,
2219 lac := 33333
2220 },
2221 rac := 254
2222 };
2223 f_send_paging_cs_exp_no_bss(ts_BssgpP4RAC(unknown_ra), 0, true);
2224}
2225testcase TC_paging_cs_sig_rac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002226 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002227 f_start_handlers(refers(f_TC_paging_cs_sig_rac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002228 f_cleanup();
2229}
2230
Harald Welte0e188242020-11-22 21:46:48 +01002231/* CS-PAGING on SIG-BVC for BVCI (one cell) */
2232private function f_TC_paging_cs_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
2233{
2234 f_send_paging_cs_exp_multi(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, {0});
2235}
2236testcase TC_paging_cs_sig_bvci() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002237 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002238 f_start_handlers(refers(f_TC_paging_cs_sig_bvci), testcasename(), 16);
Harald Welte0e188242020-11-22 21:46:48 +01002239 f_cleanup();
2240}
2241
Harald Welte7462a592020-11-23 22:07:07 +01002242/* CS-PAGING on SIG-BVC for unknown BVCI */
2243private function f_TC_paging_cs_sig_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
2244{
2245 f_send_paging_cs_exp_no_bss(ts_BssgpP4Bvci(33333), 0, true);
2246}
2247testcase TC_paging_cs_sig_bvci_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002248 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002249 f_start_handlers(refers(f_TC_paging_cs_sig_bvci_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002250 f_cleanup();
2251}
2252
Harald Welte4f91c3b2020-12-09 12:25:51 +01002253/***********************************************************************
2254 * FLUSH-LL procedure
2255 ***********************************************************************/
2256
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002257private function f_TC_flush_ll(charstring id) runs on BSSGP_ConnHdlr {
2258 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
2259 var integer i;
2260 for (i := 0; i < 10; i := i+1) {
2261 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_FLUSH_LL(g_pars.tlli, bvci, bvci_new := bvci);
2262 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2263 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_FLUSH_LL(g_pars.tlli, bvci, bvci_new := bvci);
2264
2265 f_sgsn2pcu(pdu_tx, pdu_rx, use_sig := true);
2266
2267 pdu_tx := ts_BSSGP_FLUSH_LL_ACK(g_pars.tlli, int2oct(0, 1), 23, bvci_new := bvci);
2268 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2269 pdu_rx := tr_BSSGP_FLUSH_LL_ACK(g_pars.tlli, int2oct(0, 1), 23, bvci_new := bvci);
2270
2271 f_pcu2sgsn(pdu_tx, pdu_rx, use_sig := true);
2272 }
2273 setverdict(pass);
2274}
2275testcase TC_flush_ll() runs on test_CT
2276{
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002277 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002278 f_start_handlers(refers(f_TC_flush_ll), testcasename(), 6);
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002279 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002280 f_cleanup();
2281}
Harald Welte6dc2ac42020-11-16 09:16:17 +01002282
Harald Welte4f91c3b2020-12-09 12:25:51 +01002283/***********************************************************************
2284 * SGSN-INVOKE-TRACE procedure
2285 ***********************************************************************/
2286
Harald Weltef8e5c5d2020-11-27 22:37:23 +01002287private altstep as_bssgp_g_pcu_count(integer pcu_idx, template (present) PDU_BSSGP exp_rx, inout ro_integer roi)
2288runs on GlobalTest_CT {
2289[] G_PCU[pcu_idx].receive(exp_rx) from g_pcu[pcu_idx].vc_BSSGP {
2290 if (ro_integer_contains(roi, pcu_idx)) {
2291 setverdict(fail, "Received multiple on same SIG BVC");
2292 }
2293 roi := roi & { pcu_idx };
2294 repeat;
2295 }
2296}
2297/* send a INVOKE-TRACE from SGSN and expect to receive a copy on each NSE */
2298testcase TC_trace() runs on GlobalTest_CT
2299{
2300 var BSSGP_ConnHdlr vc_conn;
2301 f_init();
2302 f_global_init();
2303
2304 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_INVOKE_TRACE('23'O, '4321'O);
2305 var template (present) PDU_BSSGP exp_rx := ts_BSSGP_INVOKE_TRACE('23'O, '4321'O);
2306
2307 var ro_default defaults := {};
2308 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2309 activate(as_bssgp_g_pcu_count(i, exp_rx, g_roi));
2310 }
2311 G_SGSN[0].send(pdu_tx);
2312 f_sleep(2.0);
2313 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2314 deactivate(defaults[i]);
2315 }
2316
2317 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2318 if (not ro_integer_contains(g_roi, i)) {
2319 setverdict(fail, "Failed to receive TRACE on PCU index ", i);
2320 }
2321 }
2322 setverdict(pass);
2323
2324 f_cleanup();
2325}
2326
Harald Welte4f91c3b2020-12-09 12:25:51 +01002327/***********************************************************************
2328 * LLC-DISCARDED procedure
2329 ***********************************************************************/
2330
Harald Weltec0351d12020-11-27 22:49:02 +01002331private function f_TC_llc_discarded(charstring id) runs on BSSGP_ConnHdlr {
2332 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
2333
2334 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_LLC_DISCARDED(g_pars.tlli, 23, bvci, 2342);
2335 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2336 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_LLC_DISCARDED(g_pars.tlli, 23, bvci, 2342);
2337
2338 f_pcu2sgsn(pdu_tx, pdu_rx, use_sig := true);
2339
2340 setverdict(pass);
2341}
2342/* Send a LLC-DISCARDED from BSS side and expect it to show up on SGSN (SIG BVC) */
2343testcase TC_llc_discarded() runs on test_CT
2344{
Harald Weltec0351d12020-11-27 22:49:02 +01002345 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002346 f_start_handlers(refers(f_TC_llc_discarded), testcasename(), 6);
Harald Weltec0351d12020-11-27 22:49:02 +01002347 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Weltec0351d12020-11-27 22:49:02 +01002348 f_cleanup();
2349}
2350
Harald Welte4f91c3b2020-12-09 12:25:51 +01002351/***********************************************************************
2352 * OVERLOAD procedure
2353 ***********************************************************************/
2354
Harald Weltef20af412020-11-28 16:11:11 +01002355/* Send an OVERLOAD from SGSN side and expect it to show up on each PCU (SIG BVC) */
2356testcase TC_overload() runs on GlobalTest_CT
2357{
2358 f_init();
2359 f_global_init();
2360
2361 var template (value) PDU_BSSGP pdu_tx := ts_OVERLOAD('1'B);
2362 var template (present) PDU_BSSGP exp_rx := tr_OVERLOAD('1'B);
2363
2364 var ro_default defaults := {};
2365 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2366 activate(as_bssgp_g_pcu_count(i, exp_rx, g_roi));
2367 }
2368 G_SGSN[0].send(pdu_tx);
2369 f_sleep(2.0);
2370 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2371 deactivate(defaults[i]);
2372 }
2373
2374 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2375 if (not ro_integer_contains(g_roi, i)) {
2376 setverdict(fail, "Failed to receive OVERLOAD on PCU index ", i);
2377 }
2378 }
2379 setverdict(pass);
2380
2381 f_cleanup();
2382}
2383
Harald Welte4f91c3b2020-12-09 12:25:51 +01002384/***********************************************************************
2385 * BVC-BLOCK / BVC-UNBLOCK procedure
2386 ***********************************************************************/
2387
Harald Welte239aa502020-11-24 23:14:20 +01002388private function f_block_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2389{
2390 var BSSGP_BVC_CT bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2391 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2392 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2393
2394 SGSN_MGMT.clear;
2395 PCU_MGMT.clear;
2396
2397 /* block the PTP BVC from the PCU side */
2398 PCU_MGMT.send(BssgpBlockRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to bvc_ct;
2399 /* expect state on both PCU and SGSN side to change */
2400 interleave {
2401 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_BLOCKED)) from bvc_ct;
2402 [] SGSN_MGMT.receive(tr_BssgpStsInd(*, bvc_cfg.bvci, BVC_S_BLOCKED));
2403 }
2404 setverdict(pass);
2405}
2406testcase TC_bvc_block_ptp() runs on test_CT
2407{
2408 f_init();
2409 f_sleep(1.0);
2410 f_block_ptp_bvc_from_pcu(0, 0);
2411 f_cleanup();
2412}
2413
2414private function f_unblock_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2415{
2416 var BSSGP_BVC_CT bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2417 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2418 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2419
2420 SGSN_MGMT.clear;
2421 PCU_MGMT.clear;
2422
2423 /* block the PTP BVC from the PCU side */
2424 PCU_MGMT.send(BssgpUnblockRequest:{}) to bvc_ct;
2425 /* expect state on both PCU and SGSN side to change */
2426 interleave {
2427 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_UNBLOCKED)) from bvc_ct;
2428 [] SGSN_MGMT.receive(tr_BssgpStsInd(*, bvc_cfg.bvci, BVC_S_UNBLOCKED));
2429 }
2430 setverdict(pass);
2431}
2432testcase TC_bvc_unblock_ptp() runs on test_CT
2433{
2434 f_init();
2435 f_sleep(1.0);
2436 f_block_ptp_bvc_from_pcu(0, 0);
2437 f_sleep(1.0);
2438 f_unblock_ptp_bvc_from_pcu(0, 0);
2439 f_cleanup();
2440}
2441
Harald Welte4f91c3b2020-12-09 12:25:51 +01002442/***********************************************************************
2443 * BVC-RESET procedure
2444 ***********************************************************************/
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002445private altstep as_count_bvc_reset(integer sgsn_idx, BssgpBvci bvci, inout roro_integer roroi)
2446runs on test_CT {
2447 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(sgsn_idx, bvci);
2448 [] SGSN_MGMT.receive(BssgpResetIndication:{bvci}) from sgsn_bvc_ct {
2449 roroi[sgsn_idx] := roroi[sgsn_idx] & { bvci };
2450 repeat;
2451 }
2452}
Harald Welte60a8ec72020-11-25 17:12:53 +01002453private altstep as_ignore_status(BSSGP_BVC_MGMT_PT pt) {
2454[] pt.receive(BssgpStatusIndication:?) { repeat; }
2455}
2456private function f_get_sgsn_bvc_ct(integer sgsn_idx, BssgpBvci bvci) runs on test_CT return BSSGP_BVC_CT {
2457 for (var integer i := 0; i < lengthof(g_sgsn[sgsn_idx].cfg.bvc); i := i+1) {
2458 if (g_sgsn[sgsn_idx].cfg.bvc[i].bvci == bvci) {
2459 return g_sgsn[sgsn_idx].vc_BSSGP_BVC[i];
2460 }
2461 }
2462 return null;
2463}
2464private function f_reset_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2465{
2466 var BSSGP_BVC_CT pcu_bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2467 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2468 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002469 var ro_default defaults;
2470 var integer i;
Harald Welte60a8ec72020-11-25 17:12:53 +01002471
2472 SGSN_MGMT.clear;
2473 PCU_MGMT.clear;
2474
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002475 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
2476 g_roroi[i] := {};
2477 }
2478
Harald Welte60a8ec72020-11-25 17:12:53 +01002479 /* block the PTP BVC from the PCU side */
2480 PCU_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to pcu_bvc_ct;
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002481
Harald Welte60a8ec72020-11-25 17:12:53 +01002482 /* expect state on both PCU and SGSN side to change */
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002483 defaults := { activate(as_ignore_status(SGSN_MGMT)) };
2484
2485 /* Activate altsteps: One for each SGSN */
2486 for (i := 0; i < lengthof(g_sgsn); i := i+1) {
2487 var default d := activate(as_count_bvc_reset(i, bvc_cfg.bvci, g_roroi));
2488 defaults := defaults & { d };
Harald Welte60a8ec72020-11-25 17:12:53 +01002489 }
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002490
2491 timer T := 3.0;
2492 T.start;
2493 alt {
2494 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_BLOCKED)) from pcu_bvc_ct {
2495 g_roi := g_roi & { bvc_cfg.bvci };
2496 repeat;
2497 }
2498 [] T.timeout;
2499 }
2500
2501 for (i := 0; i < lengthof(defaults); i := i+1) {
2502 deactivate(defaults[i]);
2503 }
2504
2505 /* Check if BVC-RESET was received at all SGSNs */
2506 for (i := 0; i < lengthof(g_sgsn); i := i+1) {
2507 if (not ro_integer_contains(g_roroi[i], bvc_cfg.bvci)) {
2508 setverdict(fail, "Missing SGSN[", i, "] BVC-BLOCK of BVCI=", bvc_cfg.bvci);
2509 }
2510 }
2511
Harald Welte60a8ec72020-11-25 17:12:53 +01002512 setverdict(pass);
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002513 f_cleanup();
Harald Welte60a8ec72020-11-25 17:12:53 +01002514}
2515/* Send a BVC-RESET for a PTP BVC from the BSS side: expect it to propagate */
2516testcase TC_bvc_reset_ptp_from_bss() runs on test_CT
2517{
2518 f_init();
2519 f_sleep(3.0);
2520 f_reset_ptp_bvc_from_pcu(0, 0);
2521 f_cleanup();
2522}
2523
Harald Welteb1cc0b22021-03-30 12:16:36 +02002524private altstep as_count_bvc_sts(integer sgsn_idx, BssgpBvci bvci,
2525 template (present) BvcState exp_bvc_state, inout roro_integer roroi)
Harald Welte16786e92020-11-27 19:11:56 +01002526runs on test_CT {
2527 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(sgsn_idx, bvci);
Harald Welteb1cc0b22021-03-30 12:16:36 +02002528 [] SGSN_MGMT.receive(tr_BssgpStsInd(?, bvci, exp_bvc_state)) from sgsn_bvc_ct {
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002529 roroi[sgsn_idx] := roroi[sgsn_idx] & { bvci };
Harald Welteb2647f72020-12-07 14:36:35 +01002530 repeat;
Harald Welte16786e92020-11-27 19:11:56 +01002531 }
2532}
Harald Welteb1cc0b22021-03-30 12:16:36 +02002533
2534private altstep as_count_bvc_block(integer sgsn_idx, BssgpBvci bvci, inout roro_integer roroi)
2535runs on test_CT {
2536 [] as_count_bvc_sts(sgsn_idx, bvci, BVC_S_BLOCKED, roroi);
2537}
2538
2539private altstep as_count_bvc_unblock(integer sgsn_idx, BssgpBvci bvci, inout roro_integer roroi)
2540runs on test_CT {
2541 [] as_count_bvc_sts(sgsn_idx, bvci, BVC_S_UNBLOCKED, roroi);
2542}
2543
Harald Welte16786e92020-11-27 19:11:56 +01002544/* reset the signaling BVC from one BSS; expect no signaling BVC reset on SGSN; but BVC-BLOCK for PTP */
2545testcase TC_bvc_reset_sig_from_bss() runs on test_CT {
2546
2547 f_init();
2548 f_sleep(3.0);
2549
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002550 for (var integer i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
2551 g_roroi[i] := {};
2552 }
2553
Harald Welte16786e92020-11-27 19:11:56 +01002554 /* Start BVC-RESET procedure for BVCI=0 */
2555 PCU_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to g_pcu[0].vc_BSSGP;
2556
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002557 /* Activate altsteps: One for each PTP BVC and SGSN within that PCUs NSE */
Harald Welte16786e92020-11-27 19:11:56 +01002558 var ro_default defaults := {};
2559 for (var integer i := 0; i < lengthof(g_pcu[0].cfg.bvc); i := i+1) {
2560 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[i];
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002561 for (var integer j := 0; j < lengthof(g_sgsn); j := j+1) {
2562 var default d := activate(as_count_bvc_block(j, bvcc.bvci, g_roroi));
2563 defaults := defaults & { d };
2564 }
Harald Welte16786e92020-11-27 19:11:56 +01002565 }
2566
2567 timer T := 3.0;
2568 T.start;
2569 alt {
2570 [] SGSN_MGMT.receive(BssgpResetIndication:{0}) {
2571 setverdict(fail, "BSS-side Reset of BVCI=0 should not propagate");
2572 }
2573 [] T.timeout;
2574 }
2575
2576 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2577 deactivate(defaults[i]);
2578 }
2579
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002580 /* check if BVC-block was received on all expected BVC/SGSN */
Harald Welte16786e92020-11-27 19:11:56 +01002581 for (var integer i := 0; i < lengthof(g_pcu[0].cfg.bvc); i := i+1) {
2582 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[i];
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002583 for (var integer j := 0; j < lengthof(g_sgsn); j := j+1) {
2584 if (not ro_integer_contains(g_roroi[j], bvcc.bvci)) {
2585 setverdict(fail, "Missing SGSN[", j, "] BVC-BLOCK of BVCI=", bvcc.bvci);
2586 }
Harald Welte16786e92020-11-27 19:11:56 +01002587 }
2588 }
2589
2590 /* check if BVC-block was not received on any unexpected BVC is not required as
2591 * such a message would basically run into 'no matching clause' */
Daniel Willmannf2590212020-12-04 14:20:50 +01002592 setverdict(pass);
Harald Welte16786e92020-11-27 19:11:56 +01002593 f_cleanup();
2594}
2595
Harald Welte60a8ec72020-11-25 17:12:53 +01002596private function f_reset_ptp_bvc_from_sgsn(integer pcu_idx, integer bvc_idx) runs on test_CT
2597{
2598 var BSSGP_BVC_CT pcu_bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2599 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2600 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2601 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(0, bvc_cfg.bvci);
2602 var default d;
2603
2604 SGSN_MGMT.clear;
2605 PCU_MGMT.clear;
2606
2607 /* block the PTP BVC from the PCU side */
2608 SGSN_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to sgsn_bvc_ct;
2609 /* expect state on both PCU and SGSN side to change */
2610 d := activate(as_ignore_status(PCU_MGMT));
2611 interleave {
2612 [] SGSN_MGMT.receive(tr_BssgpStsInd(?, bvc_cfg.bvci, BVC_S_BLOCKED)) from sgsn_bvc_ct;
2613 [] PCU_MGMT.receive(BssgpResetIndication:{bvc_cfg.bvci}) from pcu_bvc_ct;
2614 }
2615 deactivate(d);
2616 setverdict(pass);
2617}
2618/* Send a BVC-RESET for a PTP BVC from the SGSN side: expect it to propagate */
2619testcase TC_bvc_reset_ptp_from_sgsn() runs on test_CT
2620{
2621 f_init();
2622 f_sleep(3.0);
2623 f_reset_ptp_bvc_from_sgsn(0, 0);
2624 f_cleanup();
2625}
2626
Daniel Willmannef7015f2021-01-08 00:43:56 +01002627private altstep as_ignore_mgmt(BSSGP_BVC_MGMT_PT pt) {
2628 [] pt.receive {repeat; }
2629}
2630
Harald Welte16786e92020-11-27 19:11:56 +01002631private altstep as_count_bvc0_block(integer pcu_idx, Nsei nsei, inout ro_integer roi)
2632runs on test_CT {
2633 var BSSGP_CT pcu_ct := g_pcu[pcu_idx].vc_BSSGP;
2634 [] PCU_MGMT.receive(BssgpResetIndication:{0}) from pcu_ct {
2635 roi := roi & { nsei };
Daniel Willmannef7015f2021-01-08 00:43:56 +01002636 repeat;
Harald Welte16786e92020-11-27 19:11:56 +01002637 }
2638}
Daniel Willmannef7015f2021-01-08 00:43:56 +01002639
Harald Welte16786e92020-11-27 19:11:56 +01002640/* reset the signaling BVC from the SGSN; expect all signaling BVC on all BSS to be reset */
2641testcase TC_bvc_reset_sig_from_sgsn() runs on test_CT {
2642
2643 f_init();
2644 f_sleep(3.0);
2645
Daniel Willmannef7015f2021-01-08 00:43:56 +01002646 SGSN_MGMT.clear;
2647 PCU_MGMT.clear;
2648
Harald Welte16786e92020-11-27 19:11:56 +01002649 /* Start BVC-RESET procedure for BVCI=0 */
2650 SGSN_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to g_sgsn[0].vc_BSSGP;
2651
Daniel Willmannef7015f2021-01-08 00:43:56 +01002652 /* Defaults match in reverse activation order, this one is a catch-all for Status indications
2653 * and reset indications sent from other components (like the ptp_bvcs). If we don't drain
2654 * the port and a different message sits at the front we wait forever and fail the test.
2655 */
2656 var ro_default defaults := { activate(as_ignore_mgmt(PCU_MGMT)) };
2657
Harald Welte16786e92020-11-27 19:11:56 +01002658 /* Activate altsteps: One for each PCU NSE */
Harald Welte16786e92020-11-27 19:11:56 +01002659 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2660 var NSConfiguration nscfg := mp_nsconfig_pcu[i];
2661 var default d := activate(as_count_bvc0_block(i, nscfg.nsei, g_roi));
2662 defaults := defaults & { d };
2663 }
2664
2665 f_sleep(3.0);
2666
2667 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2668 deactivate(defaults[i]);
2669 }
2670
2671 /* check if BVC-block was received on all expected BVC */
2672 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2673 var NSConfiguration nscfg := mp_nsconfig_pcu[i];
2674 if (not ro_integer_contains(g_roi, nscfg.nsei)) {
2675 setverdict(fail, "Missing PCU-side BVC-RESET of BVCI=0 on PCU index ", i);
2676 }
2677 }
2678
2679 /* check if BVC-block was not received on any unexpected BVC is not required as
2680 * such a message would basically run into 'no matching clause' */
2681
2682 f_cleanup();
2683}
2684
Harald Welte299aa482020-12-09 15:10:55 +01002685/***********************************************************************
2686 * FLOW-CONTROL-BVC procedure
2687 ***********************************************************************/
2688
2689private altstep as_g_count_sgsn(integer sgsn_idx, inout ro_integer roi,
2690 template PDU_BSSGP exp_rx, template (omit) PDU_BSSGP tx_reply)
2691runs on GlobalTest_CT {
2692 [] G_SGSN[sgsn_idx].receive(exp_rx) {
2693 roi := roi & { sgsn_idx };
2694 if (ispresent(tx_reply)) {
2695 G_SGSN[sgsn_idx].send(tx_reply);
2696 }
Harald Welte5fb01742021-01-15 21:07:52 +01002697 repeat;
Harald Welte299aa482020-12-09 15:10:55 +01002698 }
2699}
2700/* Send FC-BVC from simulated PCU; expect each SGSN to receive it; expect PCU to receive ACK */
2701testcase TC_fc_bvc() runs on GlobalTest_CT
2702{
2703 f_init();
2704 f_global_init_ptp();
2705
Pau Espin Pedrol6ee01262021-02-05 13:05:06 +01002706 var template (value) PDU_BSSGP pdu_tx := ts_BVC_FC_BVC(10240, 2000, 1024, 1000, '01'O);
Harald Welte299aa482020-12-09 15:10:55 +01002707 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2708 var template (present) PDU_BSSGP pdu_rx := tr_BVC_FC_BVC(10240, 2000, 1024, 1000, '01'O);
Pau Espin Pedrol6ee01262021-02-05 13:05:06 +01002709 var template (value) PDU_BSSGP ack_tx :=
2710 ts_BVC_FC_BVC_ACK(pdu_tx.pDU_BSSGP_FLOW_CONTROL_BVC.tag.unstructured_Value);
Harald Welte299aa482020-12-09 15:10:55 +01002711
2712 /* Send a FC-BVC from BSS to gbproxy, expect an ACK in response */
2713 G_PCU[0].send(pdu_tx);
2714
2715 /* Activate altsteps: One for each SGSN-side PTP BVC port */
2716 var ro_default defaults := {};
2717 for (var integer i := 0; i < lengthof(g_sgsn); i := i+1) {
2718 var default d := activate(as_g_count_sgsn(i, g_roi, pdu_rx, ack_tx));
2719 defaults := defaults & { d };
2720 }
2721
2722 f_sleep(3.0);
2723
2724 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2725 deactivate(defaults[i]);
2726 }
2727
2728 /* check if BVC-block was received on all expected BVC */
2729 for (var integer i := 0; i < lengthof(g_sgsn); i := i+1) {
2730 if (not ro_integer_contains(g_roi, i)) {
2731 setverdict(fail, "Missing BVC-FLOW-CONTROL on SGSN index ", i);
2732 }
2733 }
2734
2735 /* Expect ACK on PCU side */
2736 G_PCU[0].receive(ack_tx);
2737
2738 setverdict(pass);
2739
2740 f_cleanup();
2741}
2742
Harald Weltecc3894b2020-12-09 16:50:12 +01002743/***********************************************************************
2744 * FLOW-CONTROL-MS procedure
2745 ***********************************************************************/
2746
2747private function f_TC_fc_ms(charstring id) runs on BSSGP_ConnHdlr {
2748 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
2749
2750 var template (value) PDU_BSSGP fc_tx := ts_BVC_FC_MS(g_pars.tlli, 100, 200, '12'O);
2751 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2752 var template (present) PDU_BSSGP fc_rx := tr_BVC_FC_MS(g_pars.tlli, 100, 200, '12'O);
2753 var template (value) PDU_BSSGP ack_tx := ts_BVC_FC_MS_ACK(g_pars.tlli, '12'O);
2754
2755 f_pcu2sgsn(fc_tx, fc_rx, use_sig := false);
2756 f_sgsn2pcu(ack_tx, ack_tx, use_sig := false);
2757
2758 setverdict(pass);
2759}
2760/* Send a FLOW-CONTROL-MS from BSS side and expect it to show up on SGSN (PTP BVC) */
2761testcase TC_fc_ms() runs on test_CT
2762{
Harald Weltecc3894b2020-12-09 16:50:12 +01002763 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002764 f_start_handlers(refers(f_TC_fc_ms), testcasename(), 21);
Harald Weltecc3894b2020-12-09 16:50:12 +01002765 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Weltecc3894b2020-12-09 16:50:12 +01002766 f_cleanup();
2767}
2768
Harald Welted6f89812021-01-16 18:57:49 +01002769/***********************************************************************
2770 * MS-REGISTRATION ENQUIRY procedure
2771 ***********************************************************************/
Harald Weltecc3894b2020-12-09 16:50:12 +01002772
Harald Welted6f89812021-01-16 18:57:49 +01002773private function f_TC_ms_reg_enq(charstring id) runs on BSSGP_ConnHdlr
2774{
2775 f_pcu2sgsn(ts_BSSGP_MS_REG_ENQ(g_pars.imsi), tr_BSSGP_MS_REG_ENQ(g_pars.imsi), use_sig := true);
2776 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);
2777}
2778testcase TC_ms_reg_enq() runs on test_CT
2779{
2780 f_init();
2781 f_start_handlers(refers(f_TC_ms_reg_enq), testcasename(), 22);
2782 f_cleanup();
2783}
Harald Welte299aa482020-12-09 15:10:55 +01002784
Harald Weltef86f1852021-01-16 21:56:17 +01002785/***********************************************************************
2786 * RIM (RAN Information Management)
2787 ***********************************************************************/
2788
2789/* Our tests here are rather synthetic, as they don't reflect normal message flows
2790 as they would be observed in a live network. However, for testing gbproxy, this shouldn't
2791 matter as gbproxy is not concerned with anything but the source / destination routing
2792 information */
2793
2794/* gbproxy must route all unknown RIM Routing Info (Cell Id) to the SGSN. We just define
2795 one here of which we know it is not used among the [simulated] PCUs */
2796const BssgpCellId cell_id_sgsn := {
2797 ra_id := {
2798 lai := {
2799 mcc_mnc := c_mcc_mnc,
2800 lac := 65534
2801 },
2802 rac := 0
2803 },
2804 cell_id := 65533
2805};
2806
2807/* Send 'tx' on PTP-BVCI from PCU; expect 'rx' on any of our SGSN (RIM can be routed anywhere) */
2808friend function f_rim_pcu2sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
2809 integer pcu_idx := 0) runs on GlobalTest_CT {
2810 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +01002811 timer T := 2.0;
Harald Weltef86f1852021-01-16 21:56:17 +01002812
2813 RIM_PCU[pcu_idx].send(tx);
2814 T.start;
2815 alt {
2816 [] any from RIM_SGSN.receive(exp_rx) {
2817 setverdict(pass);
2818 }
2819 [] any from RIM_SGSN.receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +01002820 f_shutdown(__FILE__, __LINE__, fail, log2str("Unexpected BSSGP on SGSN side: ", rx));
Harald Weltef86f1852021-01-16 21:56:17 +01002821 }
2822 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +01002823 f_shutdown(__FILE__, __LINE__, fail,
2824 log2str("Timeout waiting for BSSGP on SGSN side: ", exp_rx));
Harald Weltef86f1852021-01-16 21:56:17 +01002825 }
2826 }
2827}
2828
2829/* Send 'tx' on PTP-BVCI from SGSN; expect 'rx' on PCU */
2830friend function f_rim_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
2831 integer sgsn_idx := 0, integer pcu_idx := 0) runs on GlobalTest_CT {
2832 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +01002833 timer T := 2.0;
Harald Weltef86f1852021-01-16 21:56:17 +01002834
2835 RIM_SGSN[sgsn_idx].send(tx);
2836 T.start;
2837 alt {
2838 [] RIM_PCU[pcu_idx].receive(exp_rx) {
2839 setverdict(pass);
2840 }
2841 [] RIM_PCU[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +01002842 f_shutdown(__FILE__, __LINE__, fail, log2str("Unexpected BSSGP on PCU side: ", rx));
Harald Weltef86f1852021-01-16 21:56:17 +01002843 }
2844 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +01002845 f_shutdown(__FILE__, __LINE__, fail,
2846 log2str("Timeout waiting for BSSGP on PCU side: ", exp_rx));
Harald Weltef86f1852021-01-16 21:56:17 +01002847 }
2848 }
2849}
2850
2851/* Send 'tx' on PTP-BVCI from SRC-PCU; expect 'rx' on DST-PCU */
2852friend function f_rim_pcu2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
2853 integer src_pcu_idx, integer dst_pcu_idx) runs on GlobalTest_CT {
2854 var integer rx_idx;
2855 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +01002856 timer T := 2.0;
Harald Weltef86f1852021-01-16 21:56:17 +01002857
2858 RIM_PCU[src_pcu_idx].send(tx);
2859 T.start;
2860 alt {
2861 [] RIM_PCU[dst_pcu_idx].receive(exp_rx) -> value rx{
2862 setverdict(pass);
2863 }
2864 [] any from RIM_PCU.receive(exp_rx) -> @index value rx_idx {
2865 setverdict(fail, "Received RIM on wrong PCU[", rx_idx ,"], expected on PCU[", dst_pcu_idx, "]");
2866 }
2867 [] any from RIM_SGSN.receive(exp_rx) {
2868 setverdict(fail, "Received RIM on SGSN but expected it on other PCU");
2869 }
2870 [] any from RIM_SGSN.receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +01002871 f_shutdown(__FILE__, __LINE__, fail, log2str("Unexpected BSSGP on SGSN side: ", rx));
Harald Weltef86f1852021-01-16 21:56:17 +01002872 }
2873 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +01002874 f_shutdown(__FILE__, __LINE__, fail,
2875 log2str("Timeout waiting for BSSGP on SGSN side: ", exp_rx));
Harald Weltef86f1852021-01-16 21:56:17 +01002876 }
2877 }
2878}
2879
2880
2881type function rim_fn(integer sgsn_idx, integer pcu_idx, integer bvc_idx) runs on GlobalTest_CT;
2882
2883/* helper function for the RIM test cases: Execute 'fn' for each BVC on each PCU for
2884 each SGSN */
2885private function f_rim_iterator(rim_fn fn) runs on GlobalTest_CT
2886{
2887 var integer sgsn_idx, pcu_idx, bvc_idx;
2888 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx+1) {
2889 for (pcu_idx := 0; pcu_idx < lengthof(g_pcu); pcu_idx := pcu_idx+1) {
2890 for (bvc_idx := 0; bvc_idx < lengthof(g_pcu[pcu_idx].cfg.bvc); bvc_idx := bvc_idx+1) {
2891 log("Testing RIM SGSN[", sgsn_idx, "] <-> PCU[", pcu_idx, "][", bvc_idx, "]");
2892 fn.apply(sgsn_idx, pcu_idx, bvc_idx);
2893 }
2894 }
2895 }
2896}
2897
2898/* RAN-INFORMATION-REQUEST */
2899private function f_TC_rim_info_req(integer sgsn_idx, integer pcu_idx, integer bvc_idx := 0)
2900runs on GlobalTest_CT
2901{
2902 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
Philipp Maier14d3a8e2021-01-28 21:43:16 +01002903 var template (value) RAN_Information_Request_RIM_Container cont_tx;
2904 var template RAN_Information_Request_RIM_Container cont_rx;
2905 var template RIM_Routing_Address ra_pcu;
2906 var template RIM_Routing_Address ra_sgsn;
Harald Weltef86f1852021-01-16 21:56:17 +01002907
Philipp Maier14d3a8e2021-01-28 21:43:16 +01002908 ra_pcu := t_RIM_Routing_Address_cid(cell_id);
2909 ra_sgsn := t_RIM_Routing_Address_cid(cell_id_sgsn);
2910
2911 cont_tx := ts_RAN_Information_Request_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
2912 ts_RIM_Sequence_Number(0),
2913 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
2914 cont_rx := tr_RAN_Information_Request_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
2915 tr_RIM_Sequence_Number(0),
2916 tr_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
2917
2918 f_rim_pcu2sgsn(ts_RAN_INFORMATION_REQUEST(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
2919 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
2920 cont := cont_tx),
2921 tr_RAN_INFORMATION_REQUEST(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
2922 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
2923 cont := cont_rx),
2924 pcu_idx);
2925
2926 f_rim_sgsn2pcu(ts_RAN_INFORMATION_REQUEST(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
2927 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
2928 cont := cont_tx),
2929 tr_RAN_INFORMATION_REQUEST(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
2930 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
2931 cont := cont_rx),
Harald Weltef86f1852021-01-16 21:56:17 +01002932 sgsn_idx, pcu_idx);
2933}
2934testcase TC_rim_info_req() runs on GlobalTest_CT
2935{
2936 f_init();
2937 f_global_init();
2938 f_rim_iterator(refers(f_TC_rim_info_req));
2939 f_cleanup();
2940}
2941
2942/* RAN-INFORMATION */
2943private function f_TC_rim_info(integer sgsn_idx, integer pcu_idx, integer bvc_idx := 0)
2944runs on GlobalTest_CT
2945{
2946 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
Philipp Maier14d3a8e2021-01-28 21:43:16 +01002947 var template (value) RAN_Information_RIM_Container cont_tx;
2948 var template RAN_Information_RIM_Container cont_rx;
2949 var template RIM_Routing_Address ra_pcu;
2950 var template RIM_Routing_Address ra_sgsn;
Harald Weltef86f1852021-01-16 21:56:17 +01002951
Philipp Maier14d3a8e2021-01-28 21:43:16 +01002952 ra_pcu := t_RIM_Routing_Address_cid(cell_id);
2953 ra_sgsn := t_RIM_Routing_Address_cid(cell_id_sgsn);
2954
2955 cont_tx := ts_RAN_Information_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
2956 ts_RIM_Sequence_Number(0),
2957 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
2958
2959 cont_rx := tr_RAN_Information_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
2960 tr_RIM_Sequence_Number(0),
2961 tr_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
2962
2963 f_rim_pcu2sgsn(ts_PDU_BSSGP_RAN_INFORMATION(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
2964 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
2965 cont := cont_tx),
2966 tr_PDU_BSSGP_RAN_INFORMATION(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
2967 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
2968 cont := cont_rx),
2969 pcu_idx);
2970
2971 f_rim_sgsn2pcu(ts_PDU_BSSGP_RAN_INFORMATION(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
2972 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
2973 cont := cont_tx),
2974 tr_PDU_BSSGP_RAN_INFORMATION(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
2975 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
2976 cont := cont_rx),
Harald Weltef86f1852021-01-16 21:56:17 +01002977 sgsn_idx, pcu_idx);
2978}
2979testcase TC_rim_info() runs on GlobalTest_CT
2980{
2981 f_init();
2982 f_global_init();
2983 f_rim_iterator(refers(f_TC_rim_info));
2984 f_cleanup();
2985}
2986
2987/* RAN-INFORMATION-ACK */
2988private function f_TC_rim_info_ack(integer sgsn_idx, integer pcu_idx, integer bvc_idx := 0)
2989runs on GlobalTest_CT
2990{
2991 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
Philipp Maier14d3a8e2021-01-28 21:43:16 +01002992 var template (value) RAN_Information_Ack_RIM_Container cont_tx;
2993 var template RAN_Information_Ack_RIM_Container cont_rx;
2994 var template RIM_Routing_Address ra_pcu;
2995 var template RIM_Routing_Address ra_sgsn;
Harald Weltef86f1852021-01-16 21:56:17 +01002996
Philipp Maier14d3a8e2021-01-28 21:43:16 +01002997 ra_pcu := t_RIM_Routing_Address_cid(cell_id);
2998 ra_sgsn := t_RIM_Routing_Address_cid(cell_id_sgsn);
2999
3000 cont_tx := ts_RAN_Information_Ack_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3001 ts_RIM_Sequence_Number(0));
3002
3003 cont_rx := tr_RAN_Information_Ack_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
3004 tr_RIM_Sequence_Number(0));
3005
3006 f_rim_pcu2sgsn(ts_PDU_BSSGP_RAN_INFORMATION_ACK(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3007 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3008 cont := cont_tx),
3009 tr_PDU_BSSGP_RAN_INFORMATION_ACK(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3010 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3011 cont := cont_rx),
3012 pcu_idx);
3013
3014 f_rim_sgsn2pcu(ts_PDU_BSSGP_RAN_INFORMATION_ACK(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3015 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3016 cont := cont_tx),
3017 tr_PDU_BSSGP_RAN_INFORMATION_ACK(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3018 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3019 cont := cont_rx),
Harald Weltef86f1852021-01-16 21:56:17 +01003020 sgsn_idx, pcu_idx);
3021}
3022testcase TC_rim_info_ack() runs on GlobalTest_CT
3023{
3024 f_init();
3025 f_global_init();
3026 f_rim_iterator(refers(f_TC_rim_info_ack));
3027 f_cleanup();
3028}
3029
3030/* RAN-INFORMATION-ERROR */
3031private function f_TC_rim_info_error(integer sgsn_idx, integer pcu_idx, integer bvc_idx := 0)
3032runs on GlobalTest_CT
3033{
3034 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003035 var template (value) RAN_Information_Error_RIM_Container cont_tx;
3036 var template RAN_Information_Error_RIM_Container cont_rx;
3037 var template RIM_Routing_Address ra_pcu;
3038 var template RIM_Routing_Address ra_sgsn;
Harald Weltef86f1852021-01-16 21:56:17 +01003039
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003040 ra_pcu := t_RIM_Routing_Address_cid(cell_id);
3041 ra_sgsn := t_RIM_Routing_Address_cid(cell_id_sgsn);
3042
3043 cont_tx := ts_RAN_Information_Error_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3044 ts_BSSGP_CAUSE(BSSGP_CAUSE_EQUIMENT_FAILURE),
Pau Espin Pedrol6ee01262021-02-05 13:05:06 +01003045 omit, valueof(ts_BVC_UNBLOCK(23)));
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003046
3047 cont_rx := tr_RAN_Information_Error_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
Pau Espin Pedrol6ee01262021-02-05 13:05:06 +01003048 ts_BSSGP_CAUSE(BSSGP_CAUSE_EQUIMENT_FAILURE),
3049 omit, enc_PDU_BSSGP(valueof(tr_BVC_UNBLOCK(23))));
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003050
3051 f_rim_pcu2sgsn(ts_PDU_BSSGP_RAN_INFORMATION_ERROR(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3052 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3053 cont := cont_tx),
3054 tr_PDU_BSSGP_RAN_INFORMATION_ERROR(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3055 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3056 cont := cont_rx),
3057 pcu_idx);
3058
3059 f_rim_sgsn2pcu(ts_PDU_BSSGP_RAN_INFORMATION_ERROR(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3060 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3061 cont := cont_tx),
3062 tr_PDU_BSSGP_RAN_INFORMATION_ERROR(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3063 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3064 cont := cont_rx),
Harald Weltef86f1852021-01-16 21:56:17 +01003065 sgsn_idx, pcu_idx);
3066}
3067testcase TC_rim_info_error() runs on GlobalTest_CT
3068{
3069 f_init();
3070 f_global_init();
3071 f_rim_iterator(refers(f_TC_rim_info_error));
3072 f_cleanup();
3073}
3074
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003075//////////////////
Harald Weltef86f1852021-01-16 21:56:17 +01003076/* RAN-INFORMATION-APPLICATION-ERROR */
3077private function f_TC_rim_info_app_error(integer sgsn_idx, integer pcu_idx, integer bvc_idx := 0)
3078runs on GlobalTest_CT
3079{
3080 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003081 var template (value) Application_Error_Container app_cont_tx;
3082 var template Application_Error_Container app_cont_rx;
3083 var template (value) RAN_Information_Application_Error_RIM_Container cont_tx;
3084 var template RAN_Information_Application_Error_RIM_Container cont_rx;
3085 var template RIM_Routing_Address ra_pcu;
3086 var template RIM_Routing_Address ra_sgsn;
Harald Weltef86f1852021-01-16 21:56:17 +01003087
Philipp Maier14d3a8e2021-01-28 21:43:16 +01003088 ra_pcu := t_RIM_Routing_Address_cid(cell_id);
3089 ra_sgsn := t_RIM_Routing_Address_cid(cell_id_sgsn);
3090
3091 app_cont_tx := tsu_Application_Error_Container_NACC(cell_id, 23,
3092 tsu_Application_Container_IE_NACC_req(cell_id));
3093
3094 app_cont_rx := rsu_Application_Error_Container_NACC(cell_id, 23,
3095 rsu_Application_Container_IE_NACC_req(cell_id));
3096
3097 cont_tx := ts_RAN_Information_Application_Error_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3098 ts_RIM_Sequence_Number(0),
3099 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP),
3100 omit, app_cont_tx);
3101 cont_rx := tr_RAN_Information_Application_Error_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
3102 tr_RIM_Sequence_Number(0),
3103 tr_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP),
3104 omit, app_cont_rx);
3105
3106 f_rim_pcu2sgsn(ts_PDU_BSSGP_RAN_INFORMATION_APPLICATION_ERROR(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3107 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3108 cont := cont_tx),
3109 tr_PDU_BSSGP_RAN_INFORMATION_APPLICATION_ERROR(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3110 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3111 cont := cont_rx),
3112 pcu_idx);
3113
3114 f_rim_sgsn2pcu(ts_PDU_BSSGP_RAN_INFORMATION_APPLICATION_ERROR(dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3115 src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3116 cont := cont_tx),
3117 tr_PDU_BSSGP_RAN_INFORMATION_APPLICATION_ERROR(dst := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_pcu),
3118 src := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, ra_sgsn),
3119 cont := cont_rx),
Harald Weltef86f1852021-01-16 21:56:17 +01003120 sgsn_idx, pcu_idx);
3121}
3122testcase TC_rim_info_app_error() runs on GlobalTest_CT
3123{
3124 f_init();
3125 f_global_init();
3126 f_rim_iterator(refers(f_TC_rim_info_app_error));
3127 f_cleanup();
3128}
3129
3130/* RAN-INFORMATION routing directly between PCUs, without SGSN involvement */
3131private function f_TC_rim_info_pcu2pcu(integer src_pcu_idx, integer src_bvc_idx,
3132 integer dst_pcu_idx, integer dst_bvc_idx)
3133runs on GlobalTest_CT
3134{
3135 var BssgpCellId cell_id_src := g_pcu[src_pcu_idx].cfg.bvc[src_bvc_idx].cell_id;
3136 var BssgpCellId cell_id_dst := g_pcu[dst_pcu_idx].cfg.bvc[dst_bvc_idx].cell_id;
Philipp Maier1bd60ce2021-02-10 18:25:50 +01003137 var template (value) RIM_Routing_Information ri_pcu_src_tx;
3138 var template (value) RIM_Routing_Information ri_pcu_dst_tx;
3139 var template RIM_Routing_Information ri_pcu_src_rx;
3140 var template RIM_Routing_Information ri_pcu_dst_rx;
3141 var template (value) RAN_Information_RIM_Container cont_tx;
3142 var template RAN_Information_RIM_Container cont_rx;
Harald Weltef86f1852021-01-16 21:56:17 +01003143
3144 log("Testing RIM PCU2PCU from PCU[", src_pcu_idx, "][", src_bvc_idx, "] to PCU[",
3145 dst_pcu_idx, "][", dst_bvc_idx, "]");
3146
Philipp Maier1bd60ce2021-02-10 18:25:50 +01003147 ri_pcu_src_tx := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID,
Harald Weltef86f1852021-01-16 21:56:17 +01003148 t_RIM_Routing_Address_cid(cell_id_src));
Philipp Maier1bd60ce2021-02-10 18:25:50 +01003149 ri_pcu_dst_tx := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID,
Harald Weltef86f1852021-01-16 21:56:17 +01003150 t_RIM_Routing_Address_cid(cell_id_dst));
Philipp Maier1bd60ce2021-02-10 18:25:50 +01003151 ri_pcu_src_rx := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID,
3152 t_RIM_Routing_Address_cid(cell_id_src));
3153 ri_pcu_dst_rx := tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID,
3154 t_RIM_Routing_Address_cid(cell_id_dst));
3155
3156 cont_tx := ts_RAN_Information_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3157 ts_RIM_Sequence_Number(0),
3158 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
3159 cont_rx := tr_RAN_Information_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
3160 tr_RIM_Sequence_Number(0),
3161 tr_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
3162
3163 f_rim_pcu2pcu(ts_PDU_BSSGP_RAN_INFORMATION(dst := ri_pcu_dst_tx, src := ri_pcu_src_tx, cont := cont_tx),
3164 tr_PDU_BSSGP_RAN_INFORMATION(dst := ri_pcu_dst_rx, src := ri_pcu_src_rx, cont := cont_rx),
Harald Weltef86f1852021-01-16 21:56:17 +01003165 src_pcu_idx, dst_pcu_idx);
3166}
3167testcase TC_rim_info_pcu2pcu() runs on GlobalTest_CT
3168{
3169 var integer src_pcu_idx, dst_pcu_idx;
3170 var integer src_bvc_idx, dst_bvc_idx;
3171 f_init();
3172 f_global_init();
3173
3174 for (src_pcu_idx := 0; src_pcu_idx < lengthof(g_pcu); src_pcu_idx := src_pcu_idx + 1) {
3175 for (src_bvc_idx := 0; src_bvc_idx < lengthof(g_pcu[src_pcu_idx].cfg.bvc); src_bvc_idx := src_bvc_idx + 1) {
3176 for (dst_pcu_idx := 0; dst_pcu_idx < lengthof(g_pcu); dst_pcu_idx := dst_pcu_idx + 1) {
3177 if (dst_pcu_idx == src_pcu_idx) {
3178 continue;
3179 }
3180
3181 for (dst_bvc_idx := 0; dst_bvc_idx < lengthof(g_pcu[dst_pcu_idx].cfg.bvc);
3182dst_bvc_idx := dst_bvc_idx + 1) {
3183 f_TC_rim_info_pcu2pcu(src_pcu_idx, src_bvc_idx, dst_pcu_idx, dst_bvc_idx);
3184 }
3185 }
3186 }
3187 }
3188
3189 f_cleanup();
3190}
3191
Harald Welte04358652021-01-17 13:48:13 +01003192/***********************************************************************
3193 * STATUS handling
3194 ***********************************************************************/
3195
3196/* BSSGP STATUS PDU must be routed based on inner "PDU In Error" message */
3197
3198/* generate a TMSI with NRI matching sgsn_idx + nri_idx */
3199private function f_gen_tmsi_for_sgsn_nri(integer sgsn_idx, integer nri_idx) runs on test_CT return OCT4
3200{
3201 var integer nri := mp_sgsn_nri[sgsn_idx][nri_idx];
3202 return f_gen_tmsi(0, nri_v := nri, nri_bitlen := mp_nri_bitlength);
3203}
3204
3205/* generate a TLLI with NRI matching sgsn_idx + nri_idx */
3206private function f_gen_tlli_for_sgsn_nri(integer sgsn_idx, integer nri_idx) runs on test_CT return OCT4
3207{
3208 var OCT4 p_tmsi := f_gen_tmsi_for_sgsn_nri(sgsn_idx, nri_idx);
3209 return f_gprs_tlli_from_tmsi(p_tmsi, TLLI_LOCAL);
3210}
3211
3212/* STATUS in uplink direction; expect routing by its NRI */
3213private function f_TC_status_ul(integer pcu_idx, integer sgsn_idx, PDU_BSSGP inner)
3214runs on GlobalTest_CT
3215{
3216 var template (value) PDU_BSSGP tx := ts_BSSGP_STATUS(omit, BSSGP_CAUSE_EQUIMENT_FAILURE, inner);
3217 var template (present) PDU_BSSGP exp_rx :=
3218 tr_BSSGP_STATUS(omit, BSSGP_CAUSE_EQUIMENT_FAILURE,
3219 tx.pDU_BSSGP_STATUS.pDU_in_Error.erroneous_BSSGP_PDU);
3220
3221 f_global_pcu2sgsn(tx, exp_rx, pcu_idx, sgsn_idx);
3222}
3223
3224/* STATUS in uplink direction; expect routing by its NRI */
3225private function f_TC_status_dl(integer sgsn_idx, integer pcu_idx, PDU_BSSGP inner)
3226runs on GlobalTest_CT
3227{
3228 var template (value) PDU_BSSGP tx := ts_BSSGP_STATUS(omit, BSSGP_CAUSE_EQUIMENT_FAILURE, inner);
3229 var template (present) PDU_BSSGP exp_rx :=
3230 tr_BSSGP_STATUS(omit, BSSGP_CAUSE_EQUIMENT_FAILURE,
3231 tx.pDU_BSSGP_STATUS.pDU_in_Error.erroneous_BSSGP_PDU);
3232
3233 f_global_sgsn2pcu(tx, exp_rx, sgsn_idx, pcu_idx);
3234}
3235
3236/* STATUS in uplink direction on SIG-BVC containing a TLLI; expect routing by its NRI */
3237testcase TC_status_sig_ul_tlli() runs on GlobalTest_CT
3238{
3239 var integer sgsn_idx, nri_idx;
3240
3241 f_init();
3242 f_global_init();
3243
3244 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3245 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx + 1) {
3246 /* some downlink PDU occurring on SIG-BVC with a TLLI */
3247 var OCT4 tlli := f_gen_tlli_for_sgsn_nri(sgsn_idx, nri_idx);
3248 var PDU_BSSGP inner := valueof(ts_BSSGP_FLUSH_LL(tlli, 2342));
3249
3250 f_TC_status_ul(0, sgsn_idx, inner);
3251 }
3252 }
3253
3254 f_cleanup();
3255}
3256
3257/* STATUS in uplink direction on SIG-BVC containing a TMSI; expect routing by its NRI */
3258testcase TC_status_sig_ul_tmsi() runs on GlobalTest_CT
3259{
3260 var integer sgsn_idx, nri_idx;
3261
3262 f_init();
3263 f_global_init();
3264
3265 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3266 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx + 1) {
3267 /* some downlink PDU occurring on SIG-BVC with a TMSI */
3268 const hexstring imsi := '001010123456789'H
3269 var OCT4 tmsi := f_gen_tmsi_for_sgsn_nri(sgsn_idx, nri_idx);
3270 var BssgpBvci bvci := g_pcu[0].cfg.bvc[0].bvci;
3271 var PDU_BSSGP inner := valueof(ts_BSSGP_CS_PAGING_PTMSI(bvci, imsi, oct2int(tmsi)));
3272 f_TC_status_ul(0, sgsn_idx, inner);
3273 }
3274 }
3275
3276 f_cleanup();
3277}
3278
3279
3280/* STATUS in uplink direction on PTP-BVC containing a TLLI; expect routing by its NRI */
3281testcase TC_status_ptp_ul_tlli() runs on GlobalTest_CT
3282{
3283 var integer sgsn_idx, nri_idx;
3284
3285 f_init();
3286 f_global_init_ptp();
3287
3288 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3289 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx + 1) {
3290 /* some downlink PDU occurring on PTP-BVC with a TLLI */
3291 var OCT4 tlli := f_gen_tlli_for_sgsn_nri(sgsn_idx, nri_idx);
3292 var PDU_BSSGP inner := valueof(ts_BSSGP_DL_UD(tlli, '2342'O));
3293
3294 f_TC_status_ul(0, sgsn_idx, inner);
3295 }
3296 }
3297
3298 f_cleanup();
3299}
3300
3301/* STATUS in uplink direction on PTP-BVC containing a TMSI; expect routing by its NRI */
3302testcase TC_status_ptp_ul_tmsi() runs on GlobalTest_CT
3303{
3304 var integer sgsn_idx, nri_idx;
3305
3306 f_init();
3307 f_global_init_ptp();
3308
3309 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3310 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx + 1) {
3311 /* some downlink PDU occurring on PTP-BVC with a TMSI */
3312 const hexstring imsi := '001010123456789'H
3313 var OCT4 tmsi := f_gen_tmsi_for_sgsn_nri(sgsn_idx, nri_idx);
3314 var BssgpBvci bvci := g_pcu[0].cfg.bvc[0].bvci;
3315 var PDU_BSSGP inner := valueof(ts_BSSGP_CS_PAGING_PTMSI(bvci, imsi, oct2int(tmsi)));
3316 f_TC_status_ul(0, sgsn_idx, inner);
3317 }
3318 }
3319
3320 f_cleanup();
3321}
3322
3323/* STATUS in downlink direction in SIG-BVC containing a BVCI; expect routing by it */
3324testcase TC_status_sig_dl_bvci() runs on GlobalTest_CT
3325{
3326 var integer sgsn_idx, pcu_idx, bvc_idx;
3327
3328 f_init();
3329 f_global_init();
3330
3331 /* test each BVC in each PCU from each SGSN */
3332 for (pcu_idx := 0; pcu_idx < lengthof(g_pcu); pcu_idx := pcu_idx + 1) {
3333 for (bvc_idx := 0; bvc_idx < lengthof(g_pcu[pcu_idx].cfg.bvc); bvc_idx := bvc_idx + 1) {
3334 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3335 /* some uplink PDU occurring on SIG-BVC containing a BVCI */
3336 var BssgpBvci bvci := g_pcu[pcu_idx].cfg.bvc[bvc_idx].bvci;
3337 var PDU_BSSGP inner := valueof(ts_BSSGP_LLC_DISCARDED('12345678'O, 1, bvci, 23));
3338 f_TC_status_dl(sgsn_idx, pcu_idx, inner);
3339 }
3340 }
3341 }
3342
3343 f_cleanup();
3344}
3345
3346/* STATUS in downlink direction in PTP-BVC; expect routing by BVCI */
3347testcase TC_status_ptp_dl_bvci() runs on GlobalTest_CT
3348{
3349 var integer sgsn_idx, pcu_idx, bvc_idx;
3350
3351 f_init();
3352 f_global_init_ptp();
3353
3354 /* test each BVC in each PCU from each SGSN */
3355 for (pcu_idx := 0; pcu_idx < lengthof(g_pcu); pcu_idx := pcu_idx + 1) {
3356 for (bvc_idx := 0; bvc_idx < lengthof(g_pcu[pcu_idx].cfg.bvc); bvc_idx := bvc_idx + 1) {
3357 var BssgpBvci bvci := g_pcu[pcu_idx].cfg.bvc[bvc_idx].bvci;
3358 f_global_ptp_connect_pcu_bvci(pcu_idx, bvci);
3359 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3360 f_global_ptp_connect_sgsn_bvci(sgsn_idx, bvci);
3361
3362 /* some uplink PDU occurring on PTP-BVC */
3363 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
3364 var PDU_BSSGP inner := valueof(ts_BSSGP_UL_UD('12345678'O, cell_id, '4223'O));
3365 f_TC_status_dl(sgsn_idx, pcu_idx, inner);
3366 }
3367 }
3368 }
3369
3370 f_cleanup();
3371}
3372
3373/* TODO: test case for DL-STATUS(SUSPEND/RESUME) containing RA-ID; expect routing by RA-ID */
3374/* 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 +01003375
Daniel Willmann423d8f42020-09-08 18:58:22 +02003376control {
3377 execute( TC_BVC_bringup() );
Harald Welte92686012020-11-15 21:45:49 +01003378 execute( TC_ul_unitdata() );
Harald Welte78d8db92020-11-15 23:27:27 +01003379 execute( TC_dl_unitdata() );
Harald Welte6dc2ac42020-11-16 09:16:17 +01003380 execute( TC_ra_capability() );
Daniel Willmannace3ece2020-11-16 19:53:26 +01003381 execute( TC_ra_capability_upd() );
Daniel Willmann165d6612020-11-19 14:27:29 +01003382 execute( TC_radio_status() );
Harald Welte3148a962021-01-17 11:15:28 +01003383 execute( TC_radio_status_tmsi() );
3384 execute( TC_radio_status_imsi() );
Daniel Willmannfa67f492020-11-19 15:48:05 +01003385 execute( TC_suspend() );
Daniel Willmann087a33d2020-11-19 15:58:43 +01003386 execute( TC_resume() );
Harald Weltef8e5c5d2020-11-27 22:37:23 +01003387 execute( TC_trace() );
Harald Weltec0351d12020-11-27 22:49:02 +01003388 execute( TC_llc_discarded() );
Harald Weltef20af412020-11-28 16:11:11 +01003389 execute( TC_overload() );
Harald Welte239aa502020-11-24 23:14:20 +01003390 execute( TC_bvc_block_ptp() );
3391 execute( TC_bvc_unblock_ptp() );
Harald Welte60a8ec72020-11-25 17:12:53 +01003392 execute( TC_bvc_reset_ptp_from_bss() );
Harald Welte16786e92020-11-27 19:11:56 +01003393 execute( TC_bvc_reset_sig_from_bss() );
Harald Welte60a8ec72020-11-25 17:12:53 +01003394 execute( TC_bvc_reset_ptp_from_sgsn() );
Harald Welte16786e92020-11-27 19:11:56 +01003395 execute( TC_bvc_reset_sig_from_sgsn() );
Harald Weltef6e59b02020-12-08 08:29:09 +01003396 if (mp_enable_bss_load_sharing) {
Harald Weltef8ef0282020-11-18 12:16:59 +01003397 /* don't enable this by default, as we don't yet have any automatic test setup for FR with 4 NS-VC */
3398 execute( TC_load_sharing_dl() );
3399 }
Harald Welte0e188242020-11-22 21:46:48 +01003400
3401 /* PAGING-PS over PTP BVC */
3402 execute( TC_paging_ps_ptp_bss() );
3403 execute( TC_paging_ps_ptp_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01003404 execute( TC_paging_ps_ptp_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003405 execute( TC_paging_ps_ptp_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01003406 execute( TC_paging_ps_ptp_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003407 execute( TC_paging_ps_ptp_bvci() );
Harald Welteb5a04aa2021-01-16 13:04:40 +01003408 execute( TC_paging_ps_ptp_bvci_imsi() );
Harald Welte7462a592020-11-23 22:07:07 +01003409 execute( TC_paging_ps_ptp_bvci_unknown() );
Harald Weltecf200072021-01-16 15:20:46 +01003410 execute( TC_paging_ps_reject_ptp_bvci() );
3411 execute( TC_paging_ps_reject_ptp_bvci_imsi() );
Harald Welte7595d562021-01-16 19:09:20 +01003412 execute( TC_dummy_paging_ps_ptp() );
Harald Welte0e188242020-11-22 21:46:48 +01003413
3414 /* PAGING-PS over SIG BVC */
3415 execute( TC_paging_ps_sig_bss() );
3416 execute( TC_paging_ps_sig_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01003417 execute( TC_paging_ps_sig_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003418 execute( TC_paging_ps_sig_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01003419 execute( TC_paging_ps_sig_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003420 execute( TC_paging_ps_sig_bvci() );
Harald Welteb5a04aa2021-01-16 13:04:40 +01003421 execute( TC_paging_ps_sig_bvci_imsi() );
Harald Welte7462a592020-11-23 22:07:07 +01003422 execute( TC_paging_ps_sig_bvci_unknown() );
Harald Weltecf200072021-01-16 15:20:46 +01003423 execute( TC_paging_ps_reject_sig_bvci() );
3424 execute( TC_paging_ps_reject_sig_bvci_imsi() );
Harald Welte7595d562021-01-16 19:09:20 +01003425 execute( TC_dummy_paging_ps_sig() );
Harald Welte0e188242020-11-22 21:46:48 +01003426
3427 /* PAGING-CS over PTP BVC */
3428 execute( TC_paging_cs_ptp_bss() );
3429 execute( TC_paging_cs_ptp_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01003430 execute( TC_paging_cs_ptp_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003431 execute( TC_paging_cs_ptp_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01003432 execute( TC_paging_cs_ptp_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003433 execute( TC_paging_cs_ptp_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01003434 execute( TC_paging_cs_ptp_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003435
3436 /* PAGING-CS over SIG BVC */
3437 execute( TC_paging_cs_sig_bss() );
3438 execute( TC_paging_cs_sig_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01003439 execute( TC_paging_cs_sig_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003440 execute( TC_paging_cs_sig_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01003441 execute( TC_paging_cs_sig_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003442 execute( TC_paging_cs_sig_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01003443 execute( TC_paging_cs_sig_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003444
Harald Weltef86f1852021-01-16 21:56:17 +01003445 /* RAN Information Management */
3446 execute( TC_rim_info_req() );
3447 execute( TC_rim_info() );
3448 execute( TC_rim_info_ack() );
3449 execute( TC_rim_info_error() );
3450 execute( TC_rim_info_app_error() );
3451 execute( TC_rim_info_pcu2pcu() );
3452
Harald Welte0e188242020-11-22 21:46:48 +01003453
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01003454 execute( TC_flush_ll() );
Harald Welte299aa482020-12-09 15:10:55 +01003455 execute( TC_fc_bvc() );
Harald Weltecc3894b2020-12-09 16:50:12 +01003456 execute( TC_fc_ms() );
Harald Welted6f89812021-01-16 18:57:49 +01003457 execute( TC_ms_reg_enq() );
Harald Welte04358652021-01-17 13:48:13 +01003458
3459 /* Uplink STATUS */
3460 execute( TC_status_sig_ul_tlli() );
3461 execute( TC_status_sig_ul_tmsi() );
3462 execute( TC_status_ptp_ul_tlli() );
3463 execute( TC_status_ptp_ul_tmsi() );
3464
3465 /* Downlink STATUS */
3466 execute( TC_status_sig_dl_bvci() );
3467 execute( TC_status_ptp_dl_bvci() );
Daniel Willmann423d8f42020-09-08 18:58:22 +02003468}
3469
3470
3471}