blob: 44b2ac97669b710f69544cd532537687575191cd [file] [log] [blame]
Daniel Willmann423d8f42020-09-08 18:58:22 +02001module GBProxy_Tests {
2
3/* Osmocom GBProxy test suite in TTCN-3
4 * (C) 2020 sysmocom - s.f.m.c. GmbH
5 * All rights reserved.
6 *
7 * Author: Daniel Willmann <dwillmann@sysmocom.de>
8
9 * Released under the terms of GNU General Public License, Version 2 or
10 * (at your option) any later version.
11 *
12 * SPDX-License-Identifier: GPL-2.0-or-later
13 */
14
15import from General_Types all;
16import from Osmocom_Types all;
Harald Welteb9f0fdc2020-12-09 14:44:50 +010017import from Misc_Helpers all;
Daniel Willmann423d8f42020-09-08 18:58:22 +020018import from GSM_Types all;
19import from Native_Functions all;
20import from NS_Types all;
21import from NS_Emulation all;
22import from BSSGP_Types all;
23import from BSSGP_Emulation all;
24import from SCCPasp_Types all;
25import from Osmocom_Gb_Types all;
26
27import from MobileL3_CommonIE_Types all;
28import from MobileL3_GMM_SM_Types all;
29import from MobileL3_Types all;
30import from L3_Templates all;
31import from L3_Common all;
32
33import from TELNETasp_PortType all;
34import from Osmocom_VTY_Functions all;
35
36import from LLC_Types all;
37import from LLC_Templates all;
38
39import from GSM_RR_Types all;
40
Harald Welte6d63f742020-11-15 19:44:04 +010041/* mcc_mnc is 24.008 10.5.5.15 encoded. 262 42 */
42const BcdMccMnc c_mcc_mnc := '262F42'H;
43
Harald Welte0d5fceb2020-11-29 16:04:07 +010044/* 48.016 section 6.1.4.2: The default maximum information field size of 1600 octets shall be supported on the Gb interface */
45const integer max_fr_info_size := 1600;
46
Daniel Willmann423d8f42020-09-08 18:58:22 +020047modulepar {
Harald Weltef6e59b02020-12-08 08:29:09 +010048 boolean mp_enable_bss_load_sharing := false;
Daniel Willmann2c9300f2020-12-01 10:54:08 +010049 /* SGSN NS configuration */
Harald Welte6d63f742020-11-15 19:44:04 +010050 NSConfigurations mp_nsconfig_sgsn := {
Daniel Willmann423d8f42020-09-08 18:58:22 +020051 {
Daniel Willmann423d8f42020-09-08 18:58:22 +020052 nsei := 101,
53 role_sgsn := true,
Harald Welte90f19742020-11-06 19:34:40 +010054 handle_sns := false,
55 nsvc := {
56 {
57 provider := {
58 ip := {
59 address_family := AF_INET,
60 local_udp_port := 7777,
61 local_ip := "127.0.0.1",
62 remote_udp_port := 23000,
63 remote_ip := "127.0.0.1"
64 }
65 },
66 nsvci := 101
67 }
68 }
Harald Welteb978ed62020-12-12 14:01:11 +010069 }, {
70 nsei := 102,
71 role_sgsn := true,
72 handle_sns := false,
73 nsvc := {
74 {
75 provider := {
76 ip := {
77 address_family := AF_INET,
78 local_udp_port := 8888,
79 local_ip := "127.0.0.1",
80 remote_udp_port := 23000,
81 remote_ip := "127.0.0.1"
82 }
83 },
84 nsvci := 102
85 }
86 }
Daniel Willmann423d8f42020-09-08 18:58:22 +020087 }
88 };
Daniel Willmann2c9300f2020-12-01 10:54:08 +010089 /* BSS NSEI start at 2000 + x
90 * NSVCI start from value of NSEI + 100
91 * UDP port is NSVCI * 10 */
Harald Welte6d63f742020-11-15 19:44:04 +010092 NSConfigurations mp_nsconfig_pcu := {
Daniel Willmann423d8f42020-09-08 18:58:22 +020093 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +010094 nsei := 2001,
Daniel Willmann423d8f42020-09-08 18:58:22 +020095 role_sgsn := false,
Harald Welte90f19742020-11-06 19:34:40 +010096 handle_sns := false,
97 nsvc := {
98 {
99 provider := {
100 ip := {
101 address_family := AF_INET,
102 local_udp_port := 21010,
103 local_ip := "127.0.0.1",
104 remote_udp_port := 23000,
105 remote_ip := "127.0.0.1"
106 }
107 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100108 nsvci := 2101
Harald Welte90f19742020-11-06 19:34:40 +0100109 }
110 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200111 },
112 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100113 nsei := 2002,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200114 role_sgsn := false,
Harald Welte90f19742020-11-06 19:34:40 +0100115 handle_sns := false,
116 nsvc := {
117 {
118 provider := {
119 ip := {
120 address_family := AF_INET,
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100121 local_udp_port := 21020,
Harald Welte90f19742020-11-06 19:34:40 +0100122 local_ip := "127.0.0.1",
123 remote_udp_port := 23000,
124 remote_ip := "127.0.0.1"
125 }
126 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100127 nsvci := 2102
Harald Welte90f19742020-11-06 19:34:40 +0100128 }
129 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200130 },
131 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100132 nsei := 2003,
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,
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100140 local_udp_port := 21030,
Harald Welte90f19742020-11-06 19:34:40 +0100141 local_ip := "127.0.0.1",
142 remote_udp_port := 23000,
143 remote_ip := "127.0.0.1"
144 }
145 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100146 nsvci := 2103
Harald Welte90f19742020-11-06 19:34:40 +0100147 }
148 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200149 }
150 };
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100151 /* BVCI are NSEI*10 + x
152 * The first NSE only has one BVC, the second one 2 and so on
153 * The Cell ID is BVCI + 10000
154 * LAC/RAC are configured in such a way that:
155 * LAC 13135 is present once in NSE(2001), twice in NSE(2002) and once in NSE(2003)
156 * LAC 13300 is present twice in NSE(2003)
157 * RAI 13135-1 is present in NSE(2002) and NSE(2003)
158 * RAI 13300-0 is present twice in NSE(2003)
159 */
Harald Welte6d63f742020-11-15 19:44:04 +0100160 BssgpConfigs mp_gbconfigs := {
161 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100162 nsei := 2001,
Harald Welte6d63f742020-11-15 19:44:04 +0100163 sgsn_role := false,
164 bvc := {
165 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100166 bvci := 20011,
Harald Welte6d63f742020-11-15 19:44:04 +0100167 cell_id := {
168 ra_id := {
169 lai := {
170 mcc_mnc := c_mcc_mnc,
171 lac := 13135
172 },
173 rac := 0
174 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100175 cell_id := 30011
Harald Welte6d63f742020-11-15 19:44:04 +0100176 },
177 depth := BSSGP_DECODE_DEPTH_BSSGP,
178 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
179 }
180 }
181 }, {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100182 nsei := 2002,
Harald Welte6d63f742020-11-15 19:44:04 +0100183 sgsn_role := false,
184 bvc := {
185 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100186 bvci := 20021,
Harald Welte6d63f742020-11-15 19:44:04 +0100187 cell_id := {
188 ra_id := {
189 lai := {
190 mcc_mnc := c_mcc_mnc,
Harald Welte0e188242020-11-22 21:46:48 +0100191 lac := 13135
Harald Welte6d63f742020-11-15 19:44:04 +0100192 },
Harald Welte0e188242020-11-22 21:46:48 +0100193 rac := 1
Harald Welte6d63f742020-11-15 19:44:04 +0100194 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100195 cell_id := 30021
196 },
197 depth := BSSGP_DECODE_DEPTH_BSSGP,
198 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
199 },
200 {
201 bvci := 20022,
202 cell_id := {
203 ra_id := {
204 lai := {
205 mcc_mnc := c_mcc_mnc,
206 lac := 13135
207 },
208 rac := 2
209 },
210 cell_id := 30022
Harald Welte6d63f742020-11-15 19:44:04 +0100211 },
212 depth := BSSGP_DECODE_DEPTH_BSSGP,
213 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
214 }
215 }
216 }, {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100217 nsei := 2003,
Harald Welte6d63f742020-11-15 19:44:04 +0100218 sgsn_role := false,
219 bvc := {
220 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100221 bvci := 20031,
222 cell_id := {
223 ra_id := {
224 lai := {
225 mcc_mnc := c_mcc_mnc,
226 lac := 13135
227 },
228 rac := 1
229 },
230 cell_id := 30031
231 },
232 depth := BSSGP_DECODE_DEPTH_BSSGP,
233 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
234 },
235 {
236 bvci := 20032,
Harald Welte6d63f742020-11-15 19:44:04 +0100237 cell_id := {
238 ra_id := {
239 lai := {
240 mcc_mnc := c_mcc_mnc,
241 lac := 13300
242 },
243 rac := 0
244 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100245 cell_id := 30032
246 },
247 depth := BSSGP_DECODE_DEPTH_BSSGP,
248 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
249 },
250 {
251 bvci := 20033,
252 cell_id := {
253 ra_id := {
254 lai := {
255 mcc_mnc := c_mcc_mnc,
256 lac := 13300
257 },
258 rac := 0
259 },
260 cell_id := 30033
Harald Welte6d63f742020-11-15 19:44:04 +0100261 },
262 depth := BSSGP_DECODE_DEPTH_BSSGP,
263 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
264 }
265 }
266 }
267 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200268};
269
Daniel Willmann423d8f42020-09-08 18:58:22 +0200270type record GbInstance {
271 NS_CT vc_NS,
272 BSSGP_CT vc_BSSGP,
Harald Welte67dc8c22020-11-17 18:32:29 +0100273 BSSGP_BVC_CTs vc_BSSGP_BVC,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200274 BssgpConfig cfg
275};
Harald Welte67dc8c22020-11-17 18:32:29 +0100276type record of BSSGP_BVC_CT BSSGP_BVC_CTs
Daniel Willmann423d8f42020-09-08 18:58:22 +0200277
278const integer NUM_PCU := 3;
Harald Welte6d63f742020-11-15 19:44:04 +0100279type record of GbInstance GbInstances;
280type record of BssgpConfig BssgpConfigs;
281type record of NSConfiguration NSConfigurations;
282type record of BssgpCellId BssgpCellIds;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200283
Harald Welteb978ed62020-12-12 14:01:11 +0100284const integer NUM_SGSN := 2;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200285
286type component test_CT {
Harald Welte6d63f742020-11-15 19:44:04 +0100287 var GbInstances g_pcu;
288 var GbInstances g_sgsn;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200289
290 port BSSGP_CT_PROC_PT PROC;
291
Harald Weltefbae83f2020-11-15 23:25:55 +0100292 port BSSGP_BVC_MGMT_PT SGSN_MGMT;
293 port BSSGP_BVC_MGMT_PT PCU_MGMT;
294
Daniel Willmann423d8f42020-09-08 18:58:22 +0200295 port TELNETasp_PT GBPVTY;
296
297 var boolean g_initialized := false;
298 var boolean g_use_echo := false;
Harald Welte16786e92020-11-27 19:11:56 +0100299
300 var ro_integer g_roi := {};
Harald Welte425d3762020-12-09 14:33:18 +0100301 timer g_Tguard;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200302};
303
304type component BSSGP_ConnHdlr {
Harald Welte3dd21b32020-11-17 19:21:00 +0100305 /* array of per-BVC ports on the PCU side */
Harald Welte158becf2020-12-09 12:32:32 +0100306 port BSSGP_PT PCU_PTP[NUM_PCU];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200307 port BSSGP_PT PCU_SIG[NUM_PCU];
308 port BSSGP_PROC_PT PCU_PROC[NUM_PCU];
Harald Welte3dd21b32020-11-17 19:21:00 +0100309 /* component reference to the component to which we're currently connected */
310 var BSSGP_BVC_CT pcu_ct[NUM_PCU];
Harald Welte0e188242020-11-22 21:46:48 +0100311 /* BSSGP BVC configuration of the component to which we're currently connected */
312 var BssgpBvcConfig pcu_bvc_cfg[NUM_PCU];
Harald Welte3dd21b32020-11-17 19:21:00 +0100313
314 /* array of per-BVC ports on the SGSN side */
Harald Welte158becf2020-12-09 12:32:32 +0100315 port BSSGP_PT SGSN_PTP[NUM_SGSN];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200316 port BSSGP_PT SGSN_SIG[NUM_SGSN];
317 port BSSGP_PROC_PT SGSN_PROC[NUM_SGSN];
Harald Welte3dd21b32020-11-17 19:21:00 +0100318 /* component reference to the component to which we're currently connected */
319 var BSSGP_BVC_CT sgsn_ct[NUM_PCU];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200320
321 var BSSGP_ConnHdlrPars g_pars;
322 timer g_Tguard;
323 var LLC_Entities llc;
Harald Welte0e188242020-11-22 21:46:48 +0100324
325 var ro_integer g_roi := {};
Daniel Willmann423d8f42020-09-08 18:58:22 +0200326}
327
328type record SGSN_ConnHdlrNetworkPars {
329 boolean expect_ptmsi,
330 boolean expect_auth,
331 boolean expect_ciph
332};
333
334type record BSSGP_ConnHdlrPars {
335 /* IMEI of the simulated ME */
336 hexstring imei,
337 /* IMSI of the simulated MS */
338 hexstring imsi,
339 /* MSISDN of the simulated MS (probably unused) */
340 hexstring msisdn,
341 /* P-TMSI allocated to the simulated MS */
342 OCT4 p_tmsi optional,
343 OCT3 p_tmsi_sig optional,
344 /* TLLI of the simulated MS */
345 OCT4 tlli,
346 OCT4 tlli_old optional,
347 RoutingAreaIdentificationV ra optional,
Harald Welte16357a92020-11-17 18:20:00 +0100348 GbInstances pcu,
Harald Welte3dd21b32020-11-17 19:21:00 +0100349 GbInstances sgsn,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200350 float t_guard
351};
352
353private function f_cellid_to_RAI(in BssgpCellId cell_id) return RoutingAreaIdentificationV {
354 /* mcc_mnc is encoded as of 24.008 10.5.5.15 */
355 var BcdMccMnc mcc_mnc := cell_id.ra_id.lai.mcc_mnc;
356
357 var RoutingAreaIdentificationV ret := {
358 mccDigit1 := mcc_mnc[0],
359 mccDigit2 := mcc_mnc[1],
360 mccDigit3 := mcc_mnc[2],
361 mncDigit3 := mcc_mnc[3],
362 mncDigit1 := mcc_mnc[4],
363 mncDigit2 := mcc_mnc[5],
364 lac := int2oct(cell_id.ra_id.lai.lac, 16),
365 rac := int2oct(cell_id.ra_id.rac, 8)
366 }
367 return ret;
368};
369
Harald Welte95339432020-12-02 18:50:52 +0100370private function f_fix_create_cb(inout BssgpConfig cfg)
371{
372 for (var integer i := 0; i < lengthof(cfg.bvc); i := i + 1) {
373 if (not isbound(cfg.bvc[i].create_cb)) {
374 cfg.bvc[i].create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
375 }
376 }
377}
378
Daniel Willmann423d8f42020-09-08 18:58:22 +0200379private function f_init_gb_pcu(inout GbInstance gb, charstring id, integer offset) runs on test_CT {
Harald Welteb419d0e2020-11-16 16:45:05 +0100380 var charstring ns_id := id & "-NS(PCU[" & int2str(offset) & "])";
381 var charstring bssgp_id := id & "-BSSGP(PCU[" & int2str(offset) & "])";
382 gb.vc_NS := NS_CT.create(ns_id);
383 gb.vc_BSSGP := BSSGP_CT.create(bssgp_id);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200384 /* connect lower end of BSSGP emulation with NS upper port */
385 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
386
Harald Welteb419d0e2020-11-16 16:45:05 +0100387 gb.vc_NS.start(NSStart(mp_nsconfig_pcu[offset], ns_id));
388 gb.vc_BSSGP.start(BssgpStart(gb.cfg, bssgp_id));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200389
390 for (var integer i := 0; i < lengthof(gb.cfg.bvc); i := i + 1) {
Harald Welteb978ed62020-12-12 14:01:11 +0100391 /* obtain the component reference of the BSSGP_BVC_CT for each PTP BVC */
Daniel Willmann423d8f42020-09-08 18:58:22 +0200392 connect(self:PROC, gb.vc_BSSGP:PROC);
393 gb.vc_BSSGP_BVC[i] := f_bssgp_get_bvci_ct(gb.cfg.bvc[i].bvci, PROC);
394 disconnect(self:PROC, gb.vc_BSSGP:PROC);
Harald Welteb978ed62020-12-12 14:01:11 +0100395 /* connect all of the per-BVC MGMT ports to our PCU_MGMT port (1:N) */
Harald Weltefbae83f2020-11-15 23:25:55 +0100396 connect(self:PCU_MGMT, gb.vc_BSSGP_BVC[i]:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200397 }
Harald Welteb978ed62020-12-12 14:01:11 +0100398 /* connect all of the BSSGP/NSE global MGMT port to our PCU_MGMT port (1:N) */
Harald Welte16786e92020-11-27 19:11:56 +0100399 connect(self:PCU_MGMT, gb.vc_BSSGP:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200400}
401
402private function f_init_gb_sgsn(inout GbInstance gb, charstring id, integer offset) runs on test_CT {
Harald Welteb419d0e2020-11-16 16:45:05 +0100403 var charstring ns_id := id & "-NS(SGSN[" & int2str(offset) & "])";
404 var charstring bssgp_id := id & "-BSSGP(SGSN[" & int2str(offset) & "])";
405 gb.vc_NS := NS_CT.create(ns_id);
406 gb.vc_BSSGP := BSSGP_CT.create(bssgp_id);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200407 /* connect lower end of BSSGP emulation with NS upper port */
408 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
409
Harald Welteb419d0e2020-11-16 16:45:05 +0100410 gb.vc_NS.start(NSStart(mp_nsconfig_sgsn[offset], ns_id));
411 gb.vc_BSSGP.start(BssgpStart(gb.cfg, bssgp_id));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200412
413 for (var integer i := 0; i < lengthof(gb.cfg.bvc); i := i + 1) {
Harald Welteb978ed62020-12-12 14:01:11 +0100414 /* obtain the component reference of the BSSGP_BVC_CT for each PTP BVC */
Daniel Willmann423d8f42020-09-08 18:58:22 +0200415 connect(self:PROC, gb.vc_BSSGP:PROC);
416 gb.vc_BSSGP_BVC[i] := f_bssgp_get_bvci_ct(gb.cfg.bvc[i].bvci, PROC);
417 disconnect(self:PROC, gb.vc_BSSGP:PROC);
Harald Welteb978ed62020-12-12 14:01:11 +0100418 /* connect all of the per-BVC MGMT ports to our SGSN_MGMT port (1:N) */
Harald Weltefbae83f2020-11-15 23:25:55 +0100419 connect(self:SGSN_MGMT, gb.vc_BSSGP_BVC[i]:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200420 }
Harald Welteb978ed62020-12-12 14:01:11 +0100421 /* connect all of the BSSGP/NSE global MGMT port to our SGSN_MGMT port (1:N) */
Harald Welte16786e92020-11-27 19:11:56 +0100422 connect(self:SGSN_MGMT, gb.vc_BSSGP:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200423}
424
425
Harald Welteb9f0fdc2020-12-09 14:44:50 +0100426private function f_destroy_gb(inout GbInstance gb) runs on test_CT {
427 gb.vc_NS.stop;
428 gb.vc_BSSGP.stop;
429
430 for (var integer i := 0; i < lengthof(gb.cfg.bvc); i := i + 1) {
431 gb.vc_BSSGP_BVC[i].stop;
432 }
433}
434
Daniel Willmann423d8f42020-09-08 18:58:22 +0200435private function f_init_vty() runs on test_CT {
436 map(self:GBPVTY, system:GBPVTY);
437 f_vty_set_prompts(GBPVTY);
438 f_vty_transceive(GBPVTY, "enable");
439}
440
Harald Weltefbae83f2020-11-15 23:25:55 +0100441type record of integer ro_integer;
442
443private function ro_integer_contains(ro_integer r, integer x) return boolean {
444 for (var integer j := 0; j < lengthof(r); j := j+1) {
445 if (r[j] == x) {
446 return true;
447 }
448 }
449 return false;
450}
451
Harald Welteb978ed62020-12-12 14:01:11 +0100452private type record of ro_integer roro_integer;
453
454/* count the number of unblocked BVCI for each SGSN NSE */
455private altstep as_count_unblocked4nse(integer sgsn_idx, inout roro_integer bvci_unblocked)
456runs on test_CT {
457 var BssgpStatusIndication bsi;
458 [] SGSN_MGMT.receive(BssgpStatusIndication:{g_sgsn[sgsn_idx].cfg.nsei, ?, BVC_S_UNBLOCKED}) -> value bsi {
459 bvci_unblocked[sgsn_idx] := bvci_unblocked[sgsn_idx] & { bsi.bvci };
460 /* 'repeat' until sufficient number of BVC-rest has been received on all SGSNs */
461 for (var integer i := 0; i < lengthof(bvci_unblocked); i := i+1) {
462 if (lengthof(bvci_unblocked[i]) < lengthof(g_sgsn[i].cfg.bvc)) {
463 repeat;
464 }
465 }
466 }
467}
468
Harald Welte425d3762020-12-09 14:33:18 +0100469function f_init(float t_guard := 30.0) runs on test_CT {
Harald Welteb978ed62020-12-12 14:01:11 +0100470 var roro_integer bvci_unblocked;
Harald Weltefbae83f2020-11-15 23:25:55 +0100471 var BssgpStatusIndication bsi;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200472 var integer i;
473
474 if (g_initialized == true) {
475 return;
476 }
477 g_initialized := true;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200478
Harald Welte425d3762020-12-09 14:33:18 +0100479 g_Tguard.start(t_guard);
480 activate(as_gTguard(g_Tguard));
481
Harald Welteb978ed62020-12-12 14:01:11 +0100482 var BssgpBvcConfigs bvcs := { };
Harald Welte6d63f742020-11-15 19:44:04 +0100483 for (i := 0; i < lengthof(mp_gbconfigs); i := i+1) {
484 g_pcu[i].cfg := mp_gbconfigs[i];
Harald Welte95339432020-12-02 18:50:52 +0100485 /* make sure all have a proper crate_cb, which cannot be specified in config file */
486 f_fix_create_cb(g_pcu[i].cfg);
Harald Welte6d63f742020-11-15 19:44:04 +0100487 /* concatenate all the PCU-side BVCs for the SGSN side */
Harald Welteb978ed62020-12-12 14:01:11 +0100488 bvcs := bvcs & g_pcu[i].cfg.bvc;
489 }
490
491 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
492 g_sgsn[i].cfg := {
493 nsei := mp_nsconfig_sgsn[i].nsei,
494 sgsn_role := true,
495 bvc := bvcs
496 }
Harald Welte6d63f742020-11-15 19:44:04 +0100497 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200498
499 f_init_vty();
Harald Welte6d63f742020-11-15 19:44:04 +0100500 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
Daniel Willmann443fc572020-11-18 13:26:57 +0100501 f_vty_transceive(GBPVTY, "nsvc nsei " & int2str(g_sgsn[i].cfg.nsei) & " force-unconfigured");
Daniel Willmannad93c052020-12-04 14:14:38 +0100502 }
503 for (i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
504 f_vty_transceive(GBPVTY, "nsvc nsei " & int2str(g_pcu[i].cfg.nsei) & " force-unconfigured");
505 f_vty_transceive(GBPVTY, "delete-gbproxy-peer " & int2str(g_pcu[i].cfg.nsei) & " only-bvc");
506 }
507
508 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
Harald Welteea1ba592020-11-17 18:05:13 +0100509 f_init_gb_sgsn(g_sgsn[i], "GbProxy_Test", i);
Harald Welte6d63f742020-11-15 19:44:04 +0100510 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200511 f_sleep(4.0);
Harald Welte6d63f742020-11-15 19:44:04 +0100512 for (i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
Harald Welteb419d0e2020-11-16 16:45:05 +0100513 f_init_gb_pcu(g_pcu[i], "GbProxy_Test", i);
Harald Welte6d63f742020-11-15 19:44:04 +0100514 }
Harald Weltefbae83f2020-11-15 23:25:55 +0100515
Harald Welteb978ed62020-12-12 14:01:11 +0100516 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
517 bvci_unblocked[i] := {};
518 }
519
Harald Weltefbae83f2020-11-15 23:25:55 +0100520 /* wait until all BVC are unblocked on both sides */
Harald Welted2801272020-11-17 19:22:58 +0100521 timer T := 15.0;
Harald Weltefbae83f2020-11-15 23:25:55 +0100522 T.start;
523 alt {
Harald Welteb978ed62020-12-12 14:01:11 +0100524 /* TODO: We need to add more lines if NUM_SGSN increases. Activating default altsteps
525 * unfortunately doesn't work as we want to access the local variable bvci_unblocked. */
526 [] as_count_unblocked4nse(0, bvci_unblocked);
527 [lengthof(g_sgsn) > 1] as_count_unblocked4nse(1, bvci_unblocked);
Harald Weltefbae83f2020-11-15 23:25:55 +0100528 [] SGSN_MGMT.receive(BssgpStatusIndication:{*, ?, ?}) {
529 repeat;
530 }
Harald Welte3c905152020-11-26 20:56:09 +0100531 [] SGSN_MGMT.receive(BssgpResetIndication:?) {
532 repeat;
533 }
Harald Weltefbae83f2020-11-15 23:25:55 +0100534 [] SGSN_MGMT.receive {
535 setverdict(fail, "Received unexpected message on SGSN_MGMT");
536 mtc.stop;
537 }
538
539 [] PCU_MGMT.receive(BssgpStatusIndication:{*, ?, BVC_S_UNBLOCKED}) -> value bsi {
540 repeat;
541 }
542 [] PCU_MGMT.receive(BssgpStatusIndication:{*, ?, ?}) {
543 repeat;
544 }
545 [] PCU_MGMT.receive(BssgpResetIndication:{0}) {
546 repeat;
547 }
548 [] PCU_MGMT.receive {
549 setverdict(fail, "Received unexpected message on PCU_MGMT");
550 mtc.stop;
551 }
552
553 [] T.timeout {
Harald Welte6929e322020-12-12 13:10:45 +0100554 setverdict(fail, "Timeout waiting for unblock of all BVCs on SGSN side; ",
Harald Welteb978ed62020-12-12 14:01:11 +0100555 "unblocked so far: ", bvci_unblocked);
Harald Welte6929e322020-12-12 13:10:45 +0100556 /* don't stop here but print below analysis */
Harald Weltefbae83f2020-11-15 23:25:55 +0100557 }
558 }
559
Harald Welteb978ed62020-12-12 14:01:11 +0100560 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
561 /* iterate over list and check all BVCI */
562 for (var integer j := 0; j < lengthof(g_sgsn[i].cfg.bvc); j := j+1) {
563 var BssgpBvci bvci := g_sgsn[i].cfg.bvc[j].bvci;
564 if (not ro_integer_contains(bvci_unblocked[i], bvci)) {
565 setverdict(fail, "SGSN ", i, " BVCI=", bvci, " was not unblocked during start-up");
566 mtc.stop;
567 }
Harald Weltefbae83f2020-11-15 23:25:55 +0100568 }
569 }
Harald Welte425d3762020-12-09 14:33:18 +0100570
571 /* re-start guard timer after all BVCs are up, so it only counts the actual test case */
572 g_Tguard.start(t_guard);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200573}
574
575function f_cleanup() runs on test_CT {
Harald Welteb9f0fdc2020-12-09 14:44:50 +0100576 var integer i;
577
Daniel Willmann491af2a2021-01-08 01:32:51 +0100578 /* To avoid a dynamic test case error we need to prevent messages arriving on unconnected
579 * ports. Waiting here ensures that any messages "in flight" will be delivered to the port
580 * before the component is shutdown and disconnected. */
581 f_sleep(0.2);
582
Harald Welteb9f0fdc2020-12-09 14:44:50 +0100583 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
584 f_destroy_gb(g_sgsn[i]);
585 }
586 for (i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
587 f_destroy_gb(g_pcu[i]);
588 }
589
590 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, pass);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200591}
592
593type function void_fn(charstring id) runs on BSSGP_ConnHdlr;
594
595/* helper function to create, connect and start a BSSGP_ConnHdlr component */
Harald Welte6d63f742020-11-15 19:44:04 +0100596function f_start_handler(void_fn fn, charstring id, GbInstances pcu, GbInstances sgsn, integer imsi_suffix,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200597 float t_guard := 30.0)
598runs on test_CT return BSSGP_ConnHdlr {
599 var BSSGP_ConnHdlr vc_conn;
600
601 var BSSGP_ConnHdlrPars pars := {
602 imei := f_gen_imei(imsi_suffix),
603 imsi := f_gen_imsi(imsi_suffix),
604 msisdn := f_gen_msisdn(imsi_suffix),
605 p_tmsi := omit,
606 p_tmsi_sig := omit,
607 tlli := f_gprs_tlli_random(),
608 tlli_old := omit,
609 ra := omit,
Harald Welte16357a92020-11-17 18:20:00 +0100610 pcu := g_pcu,
Harald Welte3dd21b32020-11-17 19:21:00 +0100611 sgsn := g_sgsn,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200612 t_guard := t_guard
613 };
614
615 vc_conn := BSSGP_ConnHdlr.create(id);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200616
617 vc_conn.start(f_handler_init(fn, id, pars));
618 return vc_conn;
619}
620
Harald Welte3dd21b32020-11-17 19:21:00 +0100621/* 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 +0100622private function f_connect_to_pcu_bvc(integer port_idx, integer nse_idx, integer bvc_idx)
623runs on BSSGP_ConnHdlr {
624 var BSSGP_BVC_CT bvc_ct := g_pars.pcu[nse_idx].vc_BSSGP_BVC[bvc_idx]
Harald Welte158becf2020-12-09 12:32:32 +0100625 if (PCU_PTP[port_idx].checkstate("Connected")) {
Harald Welte3dd21b32020-11-17 19:21:00 +0100626 /* unregister + disconnect from old BVC */
627 f_client_unregister(g_pars.imsi, PCU_PROC[port_idx]);
Harald Welte158becf2020-12-09 12:32:32 +0100628 disconnect(self:PCU_PTP[port_idx], pcu_ct[port_idx]:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100629 disconnect(self:PCU_SIG[port_idx], pcu_ct[port_idx]:BSSGP_SP_SIG);
630 disconnect(self:PCU_PROC[port_idx], pcu_ct[port_idx]:BSSGP_PROC);
631 }
632 /* connect to new BVC and register us */
Harald Welte158becf2020-12-09 12:32:32 +0100633 connect(self:PCU_PTP[port_idx], bvc_ct:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100634 connect(self:PCU_SIG[port_idx], bvc_ct:BSSGP_SP_SIG);
635 connect(self:PCU_PROC[port_idx], bvc_ct:BSSGP_PROC);
636 f_client_register(g_pars.imsi, g_pars.tlli, PCU_PROC[port_idx]);
637 pcu_ct[port_idx] := bvc_ct;
Harald Welte0e188242020-11-22 21:46:48 +0100638 pcu_bvc_cfg[port_idx] := g_pars.pcu[nse_idx].cfg.bvc[bvc_idx];
Harald Welte3dd21b32020-11-17 19:21:00 +0100639}
640
641/* Connect the SGSN-side per-BVC ports (SGSN/SGSN_SIG/SGSN_PROC) array slot 'port_idx' to specified per-BVC component */
642private 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 +0100643 if (SGSN_PTP[port_idx].checkstate("Connected")) {
Harald Welte3dd21b32020-11-17 19:21:00 +0100644 /* unregister + disconnect from old BVC */
645 f_client_unregister(g_pars.imsi, SGSN_PROC[port_idx]);
Harald Welte158becf2020-12-09 12:32:32 +0100646 disconnect(self:SGSN_PTP[port_idx], sgsn_ct[port_idx]:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100647 disconnect(self:SGSN_SIG[port_idx], sgsn_ct[port_idx]:BSSGP_SP_SIG);
648 disconnect(self:SGSN_PROC[port_idx], sgsn_ct[port_idx]:BSSGP_PROC);
649 }
650 /* connect to new BVC and register us */
Harald Welte158becf2020-12-09 12:32:32 +0100651 connect(self:SGSN_PTP[port_idx], bvc_ct:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100652 connect(self:SGSN_SIG[port_idx], bvc_ct:BSSGP_SP_SIG);
653 connect(self:SGSN_PROC[port_idx], bvc_ct:BSSGP_PROC);
654 f_client_register(g_pars.imsi, g_pars.tlli, SGSN_PROC[port_idx]);
655 sgsn_ct[port_idx] := bvc_ct;
656}
657
Harald Welte425d3762020-12-09 14:33:18 +0100658private altstep as_gTguard(timer Tguard) {
659 [] Tguard.timeout {
Daniel Willmann423d8f42020-09-08 18:58:22 +0200660 setverdict(fail, "Tguard timeout");
661 mtc.stop;
662 }
663}
664
665/* first function called in every ConnHdlr */
666private function f_handler_init(void_fn fn, charstring id, BSSGP_ConnHdlrPars pars)
667runs on BSSGP_ConnHdlr {
Harald Welte1e834f32020-11-15 20:02:59 +0100668 var integer i;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200669 /* do some common stuff like setting up g_pars */
670 g_pars := pars;
671
672 llc := f_llc_create(false);
673
Harald Welte3dd21b32020-11-17 19:21:00 +0100674 /* default connections on PCU side: First BVC of each NSE/PCU */
675 for (i := 0; i < lengthof(g_pars.pcu); i := i+1) {
Harald Welte0e188242020-11-22 21:46:48 +0100676 f_connect_to_pcu_bvc(port_idx := i, nse_idx := i, bvc_idx := 0);
Harald Welte1e834f32020-11-15 20:02:59 +0100677 }
Harald Welte3dd21b32020-11-17 19:21:00 +0100678
679 /* default connections on SGSN side: First BVC of each NSE/SGSN */
680 for (i := 0; i < lengthof(g_pars.sgsn); i := i+1) {
681 f_connect_to_sgsn_bvc(i, g_pars.sgsn[i].vc_BSSGP_BVC[0]);
Harald Welte1e834f32020-11-15 20:02:59 +0100682 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200683
684 g_Tguard.start(pars.t_guard);
Harald Welte425d3762020-12-09 14:33:18 +0100685 activate(as_gTguard(g_Tguard));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200686
687 /* call the user-supplied test case function */
688 fn.apply(id);
689}
690
Harald Welte1e834f32020-11-15 20:02:59 +0100691private function f_client_register(hexstring imsi, OCT4 tlli, BSSGP_PROC_PT PT)
692runs on BSSGP_ConnHdlr {
693 PT.call(BSSGP_register_client:{imsi, tlli}) {
694 [] PT.getreply(BSSGP_register_client:{imsi, tlli}) {};
695 }
696}
697
698private function f_client_unregister(hexstring imsi, BSSGP_PROC_PT PT)
699runs on BSSGP_ConnHdlr {
700 PT.call(BSSGP_unregister_client:{imsi}) {
701 [] PT.getreply(BSSGP_unregister_client:{imsi}) {};
702 }
703}
704
Harald Welte22ef5d92020-11-16 13:35:14 +0100705/* Send 'tx' on PTP-BVCI from PCU; expect 'rx' on SGSN */
706friend function f_pcu2sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
Daniel Willmann4798fd72020-11-24 16:23:29 +0100707 integer pcu_idx := 0, integer sgsn_idx := 0, boolean use_sig := false) runs on BSSGP_ConnHdlr {
Harald Welte22ef5d92020-11-16 13:35:14 +0100708 var PDU_BSSGP rx;
709 timer T := 1.0;
710
Daniel Willmann4798fd72020-11-24 16:23:29 +0100711 if (use_sig) {
712 PCU_SIG[pcu_idx].send(tx);
713 } else {
Harald Welte158becf2020-12-09 12:32:32 +0100714 PCU_PTP[pcu_idx].send(tx);
Daniel Willmann4798fd72020-11-24 16:23:29 +0100715 }
716
Harald Welte22ef5d92020-11-16 13:35:14 +0100717 T.start;
718 alt {
Daniel Willmann4798fd72020-11-24 16:23:29 +0100719 [use_sig] SGSN_SIG[sgsn_idx].receive(exp_rx) {
720 setverdict(pass);
721 }
Harald Welte158becf2020-12-09 12:32:32 +0100722 [not use_sig] SGSN_PTP[sgsn_idx].receive(exp_rx) {
Harald Welte22ef5d92020-11-16 13:35:14 +0100723 setverdict(pass);
724 }
Harald Welte158becf2020-12-09 12:32:32 +0100725 [] SGSN_PTP[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welte22ef5d92020-11-16 13:35:14 +0100726 setverdict(fail, "Unexpected BSSGP on SGSN side: ", rx);
727 mtc.stop;
728 }
Daniel Willmann4798fd72020-11-24 16:23:29 +0100729 [] SGSN_SIG[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
730 setverdict(fail, "Unexpected SIG BSSGP on SGSN side: ", rx);
731 mtc.stop;
732 }
Harald Welte22ef5d92020-11-16 13:35:14 +0100733 [] T.timeout {
Harald Welte8b326412020-11-29 16:05:38 +0100734 setverdict(fail, "Timeout waiting for BSSGP on SGSN side: ", exp_rx);
Harald Welte22ef5d92020-11-16 13:35:14 +0100735 mtc.stop;
736 }
737 }
738}
739
740/* Send 'tx' on PTP-BVCI from SGSN; expect 'rx' on PCU */
741friend function f_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
Daniel Willmann4798fd72020-11-24 16:23:29 +0100742 integer sgsn_idx:= 0, integer pcu_idx := 0, boolean use_sig := false) runs on BSSGP_ConnHdlr {
Harald Welte22ef5d92020-11-16 13:35:14 +0100743 var PDU_BSSGP rx;
744 timer T := 1.0;
745
Daniel Willmann4798fd72020-11-24 16:23:29 +0100746 if (use_sig) {
747 SGSN_SIG[sgsn_idx].send(tx);
748 } else {
Harald Welte158becf2020-12-09 12:32:32 +0100749 SGSN_PTP[sgsn_idx].send(tx);
Daniel Willmann4798fd72020-11-24 16:23:29 +0100750 }
751
Harald Welte22ef5d92020-11-16 13:35:14 +0100752 T.start;
753 alt {
Daniel Willmann4798fd72020-11-24 16:23:29 +0100754 [use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
755 setverdict(pass);
756 }
Harald Welte158becf2020-12-09 12:32:32 +0100757 [not use_sig] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte22ef5d92020-11-16 13:35:14 +0100758 setverdict(pass);
759 }
Harald Welte158becf2020-12-09 12:32:32 +0100760 [] PCU_PTP[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welte22ef5d92020-11-16 13:35:14 +0100761 setverdict(fail, "Unexpected BSSGP on PCU side: ", rx);
762 mtc.stop;
763 }
Daniel Willmann4798fd72020-11-24 16:23:29 +0100764 [] PCU_SIG[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
765 setverdict(fail, "Unexpected SIG BSSGP on PCU side: ", rx);
766 mtc.stop;
767 }
Harald Welte22ef5d92020-11-16 13:35:14 +0100768 [] T.timeout {
Harald Welte8b326412020-11-29 16:05:38 +0100769 setverdict(fail, "Timeout waiting for BSSGP on PCU side: ", exp_rx);
Harald Welte22ef5d92020-11-16 13:35:14 +0100770 mtc.stop;
771 }
772 }
773}
Harald Welte1e834f32020-11-15 20:02:59 +0100774
Harald Welte3807ed12020-11-24 19:05:22 +0100775/***********************************************************************
776 * GlobaLTest_CT: Using the per-NSE GLOBAL ports on PCU + SGSN side
777 ***********************************************************************/
778
779type component GlobalTest_CT extends test_CT {
780 port BSSGP_PT G_PCU[NUM_PCU];
781 port BSSGP_PT G_SGSN[NUM_SGSN];
782};
783
Harald Welte299aa482020-12-09 15:10:55 +0100784/* connect the signaling BVC of each NSE to the G_PCU / G_SGSN ports */
Harald Welte3807ed12020-11-24 19:05:22 +0100785private function f_global_init() runs on GlobalTest_CT {
786 var integer i;
787 for (i := 0; i < lengthof(g_sgsn); i := i+1) {
788 connect(self:G_SGSN[i], g_sgsn[i].vc_BSSGP:GLOBAL);
789 }
790 for (i := 0; i < lengthof(g_pcu); i := i+1) {
791 connect(self:G_PCU[i], g_pcu[i].vc_BSSGP:GLOBAL);
792 }
793}
794
Harald Welte299aa482020-12-09 15:10:55 +0100795/* connect the first PTP BVC of each NSE to the G_PCU / G_SGSN ports */
796private function f_global_init_ptp() runs on GlobalTest_CT {
797 var integer i;
798 for (i := 0; i < lengthof(g_sgsn); i := i+1) {
799 connect(self:G_SGSN[i], g_sgsn[i].vc_BSSGP_BVC[0]:GLOBAL);
800 }
801 for (i := 0; i < lengthof(g_pcu); i := i+1) {
802 connect(self:G_PCU[i], g_pcu[i].vc_BSSGP_BVC[0]:GLOBAL);
803 }
804}
805
Harald Welte3807ed12020-11-24 19:05:22 +0100806/* Send 'tx' on PTP-BVCI from PCU; expect 'rx' on SGSN */
807friend function f_global_pcu2sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
808 integer pcu_idx := 0, integer sgsn_idx := 0) runs on GlobalTest_CT {
809 var PDU_BSSGP rx;
810 timer T := 1.0;
811
812 G_PCU[pcu_idx].send(tx);
813 T.start;
814 alt {
815 [] G_SGSN[sgsn_idx].receive(exp_rx) {
816 setverdict(pass);
817 }
818 [] G_SGSN[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
819 setverdict(fail, "Unexpected BSSGP on SGSN side: ", rx);
820 mtc.stop;
821 }
822 [] T.timeout {
Harald Weltedc805c02020-12-11 10:59:17 +0100823 setverdict(fail, "Timeout waiting for BSSGP on SGSN side: ", exp_rx);
Harald Welte3807ed12020-11-24 19:05:22 +0100824 mtc.stop;
825 }
826 }
827}
828
829/* Send 'tx' on PTP-BVCI from SGSN; expect 'rx' on PCU */
830friend function f_global_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
831 integer sgsn_idx := 0, integer pcu_idx := 0) runs on GlobalTest_CT {
832 var PDU_BSSGP rx;
833 timer T := 1.0;
834
835 G_SGSN[sgsn_idx].send(tx);
836 T.start;
837 alt {
838 [] G_PCU[pcu_idx].receive(exp_rx) {
839 setverdict(pass);
840 }
841 [] G_PCU[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
842 setverdict(fail, "Unexpected BSSGP on PCU side: ", rx);
843 mtc.stop;
844 }
845 [] T.timeout {
Harald Weltedc805c02020-12-11 10:59:17 +0100846 setverdict(fail, "Timeout waiting for BSSGP on PCU side: ", exp_rx);
Harald Welte3807ed12020-11-24 19:05:22 +0100847 mtc.stop;
848 }
849 }
850}
851
852
Daniel Willmann423d8f42020-09-08 18:58:22 +0200853/* TODO:
854 * Detach without Attach
855 * SM procedures without attach / RAU
856 * ATTACH / RAU
857 ** with / without authentication
858 ** with / without P-TMSI allocation
859 * re-transmissions of LLC frames
860 * PDP Context activation
861 ** with different GGSN config in SGSN VTY
862 ** with different PDP context type (v4/v6/v46)
863 ** timeout from GGSN
864 ** multiple / secondary PDP context
865 */
866
867private function f_TC_BVC_bringup(charstring id) runs on BSSGP_ConnHdlr {
868 f_sleep(5.0);
869 setverdict(pass);
870}
871
872testcase TC_BVC_bringup() runs on test_CT {
873 var BSSGP_ConnHdlr vc_conn;
874 f_init();
875
876 vc_conn := f_start_handler(refers(f_TC_BVC_bringup), testcasename(), g_pcu, g_sgsn, 51);
877 vc_conn.done;
878
879 f_cleanup();
880}
881
882friend function f_bssgp_suspend(integer ran_idx := 0) runs on BSSGP_ConnHdlr return OCT1 {
Harald Welte16357a92020-11-17 18:20:00 +0100883 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200884 timer T := 5.0;
885 var PDU_BSSGP rx_pdu;
Harald Welte16357a92020-11-17 18:20:00 +0100886 PCU_SIG[ran_idx].send(ts_BSSGP_SUSPEND(g_pars.tlli, bvcc.cell_id.ra_id));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200887 T.start;
888 alt {
Harald Welte16357a92020-11-17 18:20:00 +0100889 [] 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 +0200890 return rx_pdu.pDU_BSSGP_SUSPEND_ACK.suspend_Reference_Number.suspend_Reference_Number_value;
891 }
Harald Welte16357a92020-11-17 18:20:00 +0100892 [] PCU_SIG[ran_idx].receive(tr_BSSGP_SUSPEND_NACK(g_pars.tlli, bvcc.cell_id.ra_id, ?)) -> value rx_pdu {
Daniel Willmann423d8f42020-09-08 18:58:22 +0200893 setverdict(fail, "SUSPEND-NACK in response to SUSPEND for TLLI ", g_pars.tlli);
894 mtc.stop;
895 }
896 [] T.timeout {
897 setverdict(fail, "No SUSPEND-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
898 mtc.stop;
899 }
900 }
901 return '00'O;
902}
903
904friend function f_bssgp_resume(OCT1 susp_ref, integer ran_idx := 0) runs on BSSGP_ConnHdlr {
Harald Welte16357a92020-11-17 18:20:00 +0100905 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200906 timer T := 5.0;
Harald Welte16357a92020-11-17 18:20:00 +0100907 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 +0200908 T.start;
909 alt {
Harald Welte16357a92020-11-17 18:20:00 +0100910 [] PCU_SIG[ran_idx].receive(tr_BSSGP_RESUME_ACK(g_pars.tlli, bvcc.cell_id.ra_id));
911 [] PCU_SIG[ran_idx].receive(tr_BSSGP_RESUME_NACK(g_pars.tlli, bvcc.cell_id.ra_id, ?)) {
Daniel Willmann423d8f42020-09-08 18:58:22 +0200912 setverdict(fail, "RESUME-NACK in response to RESUME for TLLI ", g_pars.tlli);
913 mtc.stop;
914 }
915 [] T.timeout {
916 setverdict(fail, "No RESUME-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
917 mtc.stop;
918 }
919 }
920}
921
922
Harald Welte92686012020-11-15 21:45:49 +0100923/* send uplink-unitdata of a variety of different sizes; expect it to show up on SGSN */
924private function f_TC_ul_unitdata(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte16357a92020-11-17 18:20:00 +0100925 var integer ran_idx := 0;
926 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Harald Welte92686012020-11-15 21:45:49 +0100927 var integer i;
928
Harald Welte0d5fceb2020-11-29 16:04:07 +0100929 for (i := 0; i < max_fr_info_size-4; i := i+4) {
Harald Welte92686012020-11-15 21:45:49 +0100930 var octetstring payload := f_rnd_octstring(i);
Harald Welte16357a92020-11-17 18:20:00 +0100931 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 +0100932 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte16357a92020-11-17 18:20:00 +0100933 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 +0100934
Harald Welte0d5fceb2020-11-29 16:04:07 +0100935 log("UL-UNITDATA(payload_size=", i);
Harald Welte22ef5d92020-11-16 13:35:14 +0100936 f_pcu2sgsn(pdu_tx, pdu_rx);
Harald Welte92686012020-11-15 21:45:49 +0100937 }
938 setverdict(pass);
939}
940
941testcase TC_ul_unitdata() runs on test_CT
942{
943 var BSSGP_ConnHdlr vc_conn;
944 f_init();
945
946 vc_conn := f_start_handler(refers(f_TC_ul_unitdata), testcasename(), g_pcu, g_sgsn, 1);
947 vc_conn.done;
948 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
949
950 f_cleanup();
951}
952
Harald Welte78d8db92020-11-15 23:27:27 +0100953/* send downlink-unitdata of a variety of different sizes; expect it to show up on PCU */
954private function f_TC_dl_unitdata(charstring id) runs on BSSGP_ConnHdlr {
955 var integer i;
956
Harald Welte0d5fceb2020-11-29 16:04:07 +0100957 for (i := 0; i < max_fr_info_size-4; i := i+4) {
Harald Welte78d8db92020-11-15 23:27:27 +0100958 var octetstring payload := f_rnd_octstring(i);
959 var template (value) PDU_BSSGP pdu_tx :=
960 ts_BSSGP_DL_UD(g_pars.tlli, payload, omit, ts_BSSGP_IMSI(g_pars.imsi));
961 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
962 var template (present) PDU_BSSGP pdu_rx :=
963 tr_BSSGP_DL_UD(g_pars.tlli, payload, tr_BSSGP_IMSI(g_pars.imsi));
964
Harald Welte0d5fceb2020-11-29 16:04:07 +0100965 log("DL-UNITDATA(payload_size=", i);
Harald Welte22ef5d92020-11-16 13:35:14 +0100966 f_sgsn2pcu(pdu_tx, pdu_rx);
Harald Welte78d8db92020-11-15 23:27:27 +0100967 }
968 setverdict(pass);
969}
970
971testcase TC_dl_unitdata() runs on test_CT
972{
973 var BSSGP_ConnHdlr vc_conn;
974 f_init();
975
976 vc_conn := f_start_handler(refers(f_TC_dl_unitdata), testcasename(), g_pcu, g_sgsn, 2);
977 vc_conn.done;
978 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
979
980 f_cleanup();
981}
Harald Welte92686012020-11-15 21:45:49 +0100982
Harald Welte6dc2ac42020-11-16 09:16:17 +0100983private function f_TC_ra_capability(charstring id) runs on BSSGP_ConnHdlr {
984 var integer i;
985
986 for (i := 0; i < 10; i := i+1) {
987 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RA_CAP(g_pars.tlli, { ts_RaCapRec_BSSGP });
988 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
989 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RA_CAP(g_pars.tlli, { tr_RaCapRec_BSSGP })
990
Harald Welte22ef5d92020-11-16 13:35:14 +0100991 f_sgsn2pcu(pdu_tx, pdu_rx);
Harald Welte6dc2ac42020-11-16 09:16:17 +0100992 }
993 setverdict(pass);
994}
995testcase TC_ra_capability() runs on test_CT
996{
997 var BSSGP_ConnHdlr vc_conn;
998 f_init();
999
1000 vc_conn := f_start_handler(refers(f_TC_ra_capability), testcasename(), g_pcu, g_sgsn, 3);
1001 vc_conn.done;
1002 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
1003
1004 f_cleanup();
1005}
1006
Daniel Willmannace3ece2020-11-16 19:53:26 +01001007private function f_TC_ra_capability_upd(charstring id) runs on BSSGP_ConnHdlr {
1008 var integer i;
1009 var OCT1 tag;
1010 for (i := 0; i < 10; i := i+1) {
1011 tag := int2oct(23 + i, 1);
1012 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RA_CAP_UPD(g_pars.tlli, tag);
1013 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1014 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RA_CAP_UPD(g_pars.tlli, tag)
1015
1016 f_pcu2sgsn(pdu_tx, pdu_rx);
1017
1018 pdu_tx := ts_BSSGP_RA_CAP_UPD_ACK(g_pars.tlli, tag, '42'O);
1019 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1020 pdu_rx := tr_BSSGP_RA_CAP_UPD_ACK(g_pars.tlli, tag, '42'O)
1021
1022 f_sgsn2pcu(pdu_tx, pdu_rx);
1023 }
1024 setverdict(pass);
1025}
1026testcase TC_ra_capability_upd() runs on test_CT
1027{
1028 var BSSGP_ConnHdlr vc_conn;
1029 f_init();
1030
Daniel Willmann54833f22020-11-19 15:43:52 +01001031 vc_conn := f_start_handler(refers(f_TC_ra_capability_upd), testcasename(), g_pcu, g_sgsn, 4);
Daniel Willmannace3ece2020-11-16 19:53:26 +01001032 vc_conn.done;
1033 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
1034
1035 f_cleanup();
1036}
1037
Daniel Willmann165d6612020-11-19 14:27:29 +01001038private function f_TC_radio_status(charstring id) runs on BSSGP_ConnHdlr {
1039 var integer i;
1040 var BssgpRadioCause cause := BSSGP_RADIO_CAUSE_CONTACT_LOST;
1041 for (i := 0; i < 10; i := i+1) {
1042 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RADIO_STATUS(g_pars.tlli, cause);
1043 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1044 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RADIO_STATUS(g_pars.tlli, cause)
1045
1046 f_pcu2sgsn(pdu_tx, pdu_rx);
1047 }
1048 setverdict(pass);
1049}
1050testcase TC_radio_status() runs on test_CT
1051{
1052 var BSSGP_ConnHdlr vc_conn;
1053 f_init();
1054
Daniel Willmann54833f22020-11-19 15:43:52 +01001055 vc_conn := f_start_handler(refers(f_TC_radio_status), testcasename(), g_pcu, g_sgsn, 5);
Daniel Willmann165d6612020-11-19 14:27:29 +01001056 vc_conn.done;
1057 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
1058
1059 f_cleanup();
1060}
1061
Harald Welte3807ed12020-11-24 19:05:22 +01001062private function f_TC_suspend() runs on GlobalTest_CT {
Daniel Willmannfa67f492020-11-19 15:48:05 +01001063 var integer i;
Daniel Willmann165d6612020-11-19 14:27:29 +01001064
Daniel Willmannfa67f492020-11-19 15:48:05 +01001065 /* TODO: Generate RA ID for each ConnHdlr */
Harald Welte3807ed12020-11-24 19:05:22 +01001066 var RoutingAreaIdentification ra_id := g_pcu[0].cfg.bvc[0].cell_id.ra_id;
Daniel Willmannfa67f492020-11-19 15:48:05 +01001067 for (i := 0; i < 10; i := i+1) {
Harald Welte3807ed12020-11-24 19:05:22 +01001068 var OCT4 tlli := f_gprs_tlli_random();
1069 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_SUSPEND(tlli, ra_id);
Daniel Willmannfa67f492020-11-19 15:48:05 +01001070 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +01001071 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_SUSPEND(tlli, ra_id);
Daniel Willmannfa67f492020-11-19 15:48:05 +01001072
Harald Welte3807ed12020-11-24 19:05:22 +01001073 f_global_pcu2sgsn(pdu_tx, pdu_rx);
Daniel Willmannfa67f492020-11-19 15:48:05 +01001074
Harald Welte3807ed12020-11-24 19:05:22 +01001075 pdu_tx := ts_BSSGP_SUSPEND_ACK(tlli, ra_id, int2oct(i, 1));
Daniel Willmannfa67f492020-11-19 15:48:05 +01001076 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +01001077 pdu_rx := tr_BSSGP_SUSPEND_ACK(tlli, ra_id, int2oct(i, 1));
Daniel Willmannfa67f492020-11-19 15:48:05 +01001078
Harald Welte3807ed12020-11-24 19:05:22 +01001079 f_global_sgsn2pcu(pdu_tx, pdu_rx);
Daniel Willmannfa67f492020-11-19 15:48:05 +01001080
Daniel Willmann4c534bb2021-01-07 18:05:10 +01001081 pdu_tx := ts_BSSGP_SUSPEND(tlli, ra_id);
1082 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1083 pdu_rx := tr_BSSGP_SUSPEND(tlli, ra_id);
1084
1085 f_global_pcu2sgsn(pdu_tx, pdu_rx);
1086
Daniel Willmannfa67f492020-11-19 15:48:05 +01001087 /* These messages are simple passed through so just also test sending NACK */
Harald Welte3807ed12020-11-24 19:05:22 +01001088 pdu_tx := ts_BSSGP_SUSPEND_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
Daniel Willmannfa67f492020-11-19 15:48:05 +01001089 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +01001090 pdu_rx := tr_BSSGP_SUSPEND_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
Daniel Willmannfa67f492020-11-19 15:48:05 +01001091
Harald Welte3807ed12020-11-24 19:05:22 +01001092 f_global_sgsn2pcu(pdu_tx, pdu_rx);
Daniel Willmannfa67f492020-11-19 15:48:05 +01001093 }
1094 setverdict(pass);
1095}
Harald Welte3807ed12020-11-24 19:05:22 +01001096testcase TC_suspend() runs on GlobalTest_CT
Daniel Willmannfa67f492020-11-19 15:48:05 +01001097{
Daniel Willmannfa67f492020-11-19 15:48:05 +01001098 f_init();
Harald Welte3807ed12020-11-24 19:05:22 +01001099 f_global_init();
1100 f_TC_suspend();
Daniel Willmannfa67f492020-11-19 15:48:05 +01001101 f_cleanup();
1102}
Harald Welte6dc2ac42020-11-16 09:16:17 +01001103
Harald Welte3807ed12020-11-24 19:05:22 +01001104private function f_TC_resume() runs on GlobalTest_CT {
Daniel Willmann087a33d2020-11-19 15:58:43 +01001105 var integer i;
1106
1107 /* TODO: Generate RA ID for each ConnHdlr */
Harald Welte3807ed12020-11-24 19:05:22 +01001108 var RoutingAreaIdentification ra_id := g_pcu[0].cfg.bvc[0].cell_id.ra_id;
Daniel Willmann087a33d2020-11-19 15:58:43 +01001109 for (i := 0; i < 10; i := i+1) {
Harald Welte3807ed12020-11-24 19:05:22 +01001110 var OCT4 tlli := f_gprs_tlli_random();
1111 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RESUME(tlli, ra_id, int2oct(i, 1));
Daniel Willmann087a33d2020-11-19 15:58:43 +01001112 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +01001113 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RESUME(tlli, ra_id, int2oct(i, 1));
Daniel Willmann087a33d2020-11-19 15:58:43 +01001114
Harald Welte3807ed12020-11-24 19:05:22 +01001115 f_global_pcu2sgsn(pdu_tx, pdu_rx);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001116
Harald Welte3807ed12020-11-24 19:05:22 +01001117 pdu_tx := ts_BSSGP_RESUME_ACK(tlli, ra_id);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001118 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +01001119 pdu_rx := tr_BSSGP_RESUME_ACK(tlli, ra_id);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001120
Harald Welte3807ed12020-11-24 19:05:22 +01001121 f_global_sgsn2pcu(pdu_tx, pdu_rx);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001122
Daniel Willmann4c534bb2021-01-07 18:05:10 +01001123 pdu_tx := ts_BSSGP_RESUME(tlli, ra_id, int2oct(i, 1));
1124 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1125 pdu_rx := tr_BSSGP_RESUME(tlli, ra_id, int2oct(i, 1));
1126
1127 f_global_pcu2sgsn(pdu_tx, pdu_rx);
1128
Daniel Willmann087a33d2020-11-19 15:58:43 +01001129 /* These messages are simple passed through so just also test sending NACK */
Harald Welte3807ed12020-11-24 19:05:22 +01001130 pdu_tx := ts_BSSGP_RESUME_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001131 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +01001132 pdu_rx := tr_BSSGP_RESUME_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001133
Harald Welte3807ed12020-11-24 19:05:22 +01001134 f_global_sgsn2pcu(pdu_tx, pdu_rx);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001135 }
1136 setverdict(pass);
1137}
Harald Welte3807ed12020-11-24 19:05:22 +01001138testcase TC_resume() runs on GlobalTest_CT
Daniel Willmann087a33d2020-11-19 15:58:43 +01001139{
Daniel Willmann087a33d2020-11-19 15:58:43 +01001140 f_init();
Harald Welte3807ed12020-11-24 19:05:22 +01001141 f_global_init();
1142 f_TC_resume();
Daniel Willmann087a33d2020-11-19 15:58:43 +01001143 f_cleanup();
1144}
1145
Harald Weltef8ef0282020-11-18 12:16:59 +01001146/* test the load-sharing between multiple NS-VC on the BSS side */
1147private function f_TC_dl_ud_unidir(charstring id) runs on BSSGP_ConnHdlr {
1148 var integer i;
1149
1150 for (i := 0; i < 10; i := i+1) {
1151 var octetstring payload := f_rnd_octstring(i);
1152 var template (value) PDU_BSSGP pdu_tx :=
1153 ts_BSSGP_DL_UD(g_pars.tlli, payload, omit, ts_BSSGP_IMSI(g_pars.imsi));
Harald Welte158becf2020-12-09 12:32:32 +01001154 SGSN_PTP[0].send(pdu_tx);
Harald Weltef8ef0282020-11-18 12:16:59 +01001155 }
1156 setverdict(pass);
1157}
1158testcase TC_load_sharing_dl() runs on test_CT_NS
1159{
1160 const integer num_ue := 10;
1161 var BSSGP_ConnHdlr vc_conn[num_ue];
1162 f_init();
1163
1164 /* all BVC are now fully brought up. We disconnect BSSGP from NS on the BSS
1165 * side so we get the raw NsUnitdataIndication and hence observe different
1166 * NSVCI */
1167 disconnect(g_pcu[0].vc_NS:NS_SP, g_pcu[0].vc_BSSGP:BSCP);
1168 connect(g_pcu[0].vc_NS:NS_SP, self:NS);
1169
1170 /* there may still be some NS-VCs coming up? After all, the BVC-RESET succeeds after the first
1171 * of the NS-VC is ALIVE/UNBLOCKED */
1172 f_sleep(3.0);
1173
1174 /* start parallel components generating DL-UNITDATA from the SGSN side */
1175 for (var integer i:= 0; i < num_ue; i := i+1) {
1176 vc_conn[i] := f_start_handler(refers(f_TC_dl_ud_unidir), testcasename(), g_pcu, g_sgsn, 5+i);
1177 }
1178
1179 /* now start counting all the messages that were queued before */
1180 /* TODO: We have a hard-coded assumption of 4 NS-VC in one NSE/NS-VCG here! */
1181 var ro_integer rx_count := { 0, 0, 0, 0 };
1182 timer T := 2.0;
1183 T.start;
1184 alt {
1185 [] as_NsUdiCount(0, rx_count);
1186 [] as_NsUdiCount(1, rx_count);
1187 [] as_NsUdiCount(2, rx_count);
1188 [] as_NsUdiCount(3, rx_count);
1189 [] NS.receive(NsUnitdataIndication:{0,?,?,*,*}) { repeat; } /* signaling BVC */
1190 [] NS.receive(NsStatusIndication:?) { repeat; }
1191 [] NS.receive {
1192 setverdict(fail, "Rx unexpected NS");
1193 mtc.stop;
1194 }
1195 [] T.timeout {
1196 }
1197 }
1198 for (var integer i := 0; i < lengthof(rx_count); i := i+1) {
1199 log("Rx on NSVCI ", mp_nsconfig_pcu[0].nsvc[i].nsvci, ": ", rx_count[i]);
1200 if (rx_count[i] == 0) {
1201 setverdict(fail, "Data not shared over all NSVC");
1202 }
1203 }
1204 setverdict(pass);
1205}
1206private altstep as_NsUdiCount(integer nsvc_idx, inout ro_integer roi) runs on test_CT_NS {
1207 var NsUnitdataIndication udi;
1208 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[0];
1209 [] NS.receive(NsUnitdataIndication:{bvcc.bvci, g_pcu[0].cfg.nsei, mp_nsconfig_pcu[0].nsvc[nsvc_idx].nsvci, *, *}) -> value udi {
1210 roi[nsvc_idx] := roi[nsvc_idx] + 1;
1211 repeat;
1212 }
1213}
1214type component test_CT_NS extends test_CT {
1215 port NS_PT NS;
1216};
1217
1218
Harald Welte0e188242020-11-22 21:46:48 +01001219/***********************************************************************
1220 * PAGING PS procedure
1221 ***********************************************************************/
1222
1223private function f_send_paging_ps(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1224 boolean use_sig := false)
1225runs on BSSGP_ConnHdlr return template (present) PDU_BSSGP {
1226 var template (value) PDU_BSSGP pdu_tx;
1227 var template (present) PDU_BSSGP pdu_rx;
1228 /* we always specify '0' as BVCI in the templates below, as we override it with
1229 * 'p4' later anyway */
1230 pdu_rx := tr_BSSGP_PS_PAGING(0);
1231 pdu_rx.pDU_BSSGP_PAGING_PS.iMSI := tr_BSSGP_IMSI(g_pars.imsi);
1232 if (ispresent(g_pars.p_tmsi)) {
1233 pdu_tx := ts_BSSGP_PS_PAGING_PTMSI(0, g_pars.imsi, oct2int(g_pars.p_tmsi));
1234 pdu_rx.pDU_BSSGP_PAGING_PS.pTMSI := tr_BSSGP_TMSI(oct2int(g_pars.p_tmsi));
1235 } else {
1236 pdu_tx := ts_BSSGP_PS_PAGING_IMSI(0, g_pars.imsi);
1237 pdu_rx.pDU_BSSGP_PAGING_PS.pTMSI := omit;
1238 }
1239 pdu_tx.pDU_BSSGP_PAGING_PS.paging_Field4 := p4;
1240 pdu_rx.pDU_BSSGP_PAGING_PS.paging_Field4 := p4;
1241 if (use_sig == false) {
Harald Welte158becf2020-12-09 12:32:32 +01001242 SGSN_PTP[sgsn_idx].send(pdu_tx);
Harald Welte0e188242020-11-22 21:46:48 +01001243 } else {
1244 SGSN_SIG[sgsn_idx].send(pdu_tx);
1245 }
1246 return pdu_rx;
1247}
1248
1249/* send paging defined by 'p4' on given SGSN-side index (ptp or signaling) and expect one paging to arrive on
1250 * specified PCU index */
1251private function f_send_paging_ps_exp_one_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1252 boolean use_sig := false,integer pcu_idx := 0)
1253runs on BSSGP_ConnHdlr {
1254 var template (present) PDU_BSSGP exp_rx;
Daniel Willmann1a859712020-12-04 00:59:45 +01001255 var boolean test_done := false;
Harald Welte0e188242020-11-22 21:46:48 +01001256 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1257 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1258 exp_rx := f_send_paging_ps(p4, sgsn_idx, use_sig);
1259 /* Expect paging to propagate to the one BSS addressed by the BVCI only */
1260 timer T := 2.0;
1261 T.start;
1262 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001263 [not use_sig and not test_done] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001264 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001265 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001266 repeat;
1267 }
1268 [not use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
1269 setverdict(fail, "Received paging on SIGNALING BVC, expected PTP BVC");
1270 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001271 [use_sig and not test_done] PCU_SIG[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001272 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001273 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001274 repeat;
1275 }
Harald Welte158becf2020-12-09 12:32:32 +01001276 [use_sig] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001277 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1278 }
Harald Welte158becf2020-12-09 12:32:32 +01001279 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001280 setverdict(fail, "Paging received on unexpected BVC");
1281 }
1282 [] any from PCU_SIG.receive(exp_rx) {
1283 setverdict(fail, "Paging received on unexpected BVC");
1284 }
Harald Welte158becf2020-12-09 12:32:32 +01001285 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01001286 setverdict(fail, "Different Paging than expected received PTP BVC");
1287 }
1288 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1289 setverdict(fail, "Different Paging than expected on SIGNALING BVC");
1290 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001291 [not test_done] T.timeout {
1292 setverdict(fail, "Timeout waiting for paging");
1293 }
1294 [test_done] T.timeout;
Harald Welte0e188242020-11-22 21:46:48 +01001295 }
1296}
1297
Harald Welte7462a592020-11-23 22:07:07 +01001298/* send a PS-PAGING but don't expect it to show up on any PTP or SIG BVC */
1299private function f_send_paging_ps_exp_no_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1300 boolean use_sig := false)
1301runs on BSSGP_ConnHdlr {
1302 var template (present) PDU_BSSGP exp_rx;
1303 exp_rx := f_send_paging_ps(p4, sgsn_idx, use_sig);
1304 /* Expect paging to propagate to no BSS */
1305 timer T := 2.0;
1306 T.start;
1307 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001308 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte7462a592020-11-23 22:07:07 +01001309 setverdict(fail, "Paging received on unexpected BVC");
1310 }
1311 [] any from PCU_SIG.receive(exp_rx) {
1312 setverdict(fail, "Paging received on unexpected BVC");
1313 }
Harald Welte158becf2020-12-09 12:32:32 +01001314 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte7462a592020-11-23 22:07:07 +01001315 setverdict(fail, "Different Paging received on PTP BVC");
1316 }
1317 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1318 setverdict(fail, "Different Paging received on SIGNALING BVC");
1319 }
1320 [] T.timeout {
1321 setverdict(pass);
1322 }
1323 }
1324}
1325
Harald Welte0e188242020-11-22 21:46:48 +01001326private function f_TC_paging_ps_ptp_bss(charstring id) runs on BSSGP_ConnHdlr
1327{
1328 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1329 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1330 f_send_paging_ps_exp_one_bss(ts_BssgpP4BssArea, 0, false, 0);
1331}
1332testcase TC_paging_ps_ptp_bss() runs on test_CT {
1333 var BSSGP_ConnHdlr vc_conn;
1334 f_init();
1335
1336 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_bss), testcasename(), g_pcu, g_sgsn, 9);
1337 vc_conn.done;
1338
1339 f_cleanup();
1340}
1341
1342/* PS-PAGING on PTP-BVC for Location Area */
1343private function f_TC_paging_ps_ptp_lac(charstring id) runs on BSSGP_ConnHdlr
1344{
1345 var template (present) PDU_BSSGP exp_rx;
1346 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1347 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1348 f_send_paging_ps_exp_one_bss(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, false, 0);
1349}
1350testcase TC_paging_ps_ptp_lac() runs on test_CT {
1351 var BSSGP_ConnHdlr vc_conn;
1352 f_init();
1353
1354 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_lac), testcasename(), g_pcu, g_sgsn, 10);
1355 vc_conn.done;
1356
1357 f_cleanup();
1358}
1359
Harald Welte7462a592020-11-23 22:07:07 +01001360/* PS-PAGING on PTP-BVC for unknown Location Area */
1361private function f_TC_paging_ps_ptp_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1362{
1363 var GSM_Types.LocationAreaIdentification unknown_la := {
1364 mcc_mnc := '567F99'H,
1365 lac := 33333
1366 };
1367 /* as it's sent on the PTP BVC, we expect it to pass even for unknown LAC */
1368 f_send_paging_ps_exp_one_bss(ts_BssgpP4LAC(unknown_la), 0, false, 0);
1369}
1370testcase TC_paging_ps_ptp_lac_unknown() runs on test_CT {
1371 var BSSGP_ConnHdlr vc_conn;
1372 f_init();
1373
1374 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_lac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1375 vc_conn.done;
1376
1377 f_cleanup();
1378}
1379
Harald Welte0e188242020-11-22 21:46:48 +01001380/* PS-PAGING on PTP-BVC for Routeing Area */
1381private function f_TC_paging_ps_ptp_rac(charstring id) runs on BSSGP_ConnHdlr
1382{
1383 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1384 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1385 f_send_paging_ps_exp_one_bss(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, false, 0);
1386}
1387testcase TC_paging_ps_ptp_rac() runs on test_CT {
1388 var BSSGP_ConnHdlr vc_conn;
1389 f_init();
1390
1391 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_rac), testcasename(), g_pcu, g_sgsn, 11);
1392 vc_conn.done;
1393
1394 f_cleanup();
1395}
1396
Harald Welte7462a592020-11-23 22:07:07 +01001397/* PS-PAGING on PTP-BVC for unknown Routeing Area */
1398private function f_TC_paging_ps_ptp_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1399{
1400 var RoutingAreaIdentification unknown_ra := {
1401 lai := {
1402 mcc_mnc := '567F99'H,
1403 lac := 33333
1404 },
1405 rac := 254
1406 };
1407 /* as it's sent on the PTP BVC, we expect it to pass even for unknown RAC */
1408 f_send_paging_ps_exp_one_bss(ts_BssgpP4RAC(unknown_ra), 0, false, 0);
1409}
1410testcase TC_paging_ps_ptp_rac_unknown() runs on test_CT {
1411 var BSSGP_ConnHdlr vc_conn;
1412 f_init();
1413
1414 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_rac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1415 vc_conn.done;
1416
1417 f_cleanup();
1418}
1419
Harald Welte0e188242020-11-22 21:46:48 +01001420/* PS-PAGING on PTP-BVC for BVCI (one cell) */
1421private function f_TC_paging_ps_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
1422{
1423 /* this should be the normal case for MS in READY MM state after a lower layer failure */
1424 f_send_paging_ps_exp_one_bss(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, false, 0);
1425}
1426testcase TC_paging_ps_ptp_bvci() runs on test_CT {
1427 var BSSGP_ConnHdlr vc_conn;
1428 f_init();
1429
1430 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_bvci), testcasename(), g_pcu, g_sgsn, 12);
1431 vc_conn.done;
1432
1433 f_cleanup();
1434}
1435
Harald Welte7462a592020-11-23 22:07:07 +01001436/* PS-PAGING on PTP-BVC for unknown BVCI */
1437private function f_TC_paging_ps_ptp_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1438{
1439 /* as it's sent on the PTP BVC, we expect it to pass even for unknown BVCI */
1440 f_send_paging_ps_exp_one_bss(ts_BssgpP4Bvci(33333), 0, false, 0);
1441}
1442testcase TC_paging_ps_ptp_bvci_unknown() runs on test_CT {
1443 var BSSGP_ConnHdlr vc_conn;
1444 f_init();
1445
1446 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
1447 vc_conn.done;
1448
1449 f_cleanup();
1450}
1451
Harald Welte0e188242020-11-22 21:46:48 +01001452/* altstep for expecting BSSGP PDU on signaling BVC of given pcu_idx + storing in 'roi' */
1453private altstep as_paging_sig_pcu(integer pcu_idx, template (present) PDU_BSSGP exp_rx, inout ro_integer roi)
1454runs on BSSGP_ConnHdlr {
1455[] PCU_SIG[pcu_idx].receive(exp_rx) {
1456 if (ro_integer_contains(roi, pcu_idx)) {
1457 setverdict(fail, "Received multiple paging on same SIG BVC");
1458 }
1459 roi := roi & { pcu_idx };
1460 repeat;
1461 }
Harald Welte158becf2020-12-09 12:32:32 +01001462[] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001463 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1464 }
1465[] PCU_SIG[pcu_idx].receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1466 setverdict(fail, "Different Paging than expected received SIGNALING BVC");
1467 }
Harald Welte158becf2020-12-09 12:32:32 +01001468[] PCU_PTP[pcu_idx].receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01001469 setverdict(fail, "Different Paging than expected received PTP BVC");
1470 }
1471}
1472
1473type record of default ro_default;
1474
1475/* send PS-PAGING on SIG BVC, expect it to arrive on given list of PCU indexes */
1476private function f_send_paging_ps_exp_multi(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1477 ro_integer exp_on_pcu_idx) runs on BSSGP_ConnHdlr
1478{
1479 var template (present) PDU_BSSGP exp_rx;
1480 exp_rx := f_send_paging_ps(p4, 0, true);
1481
1482 /* FIXME: make sure the relevant BVCs/BSS are connected to the ports! */
1483 var ro_default defaults := {};
1484 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1485 var default d := activate(as_paging_sig_pcu(i, exp_rx, g_roi));
1486 defaults := defaults & { d };
1487 }
1488 f_sleep(2.0);
1489 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
1490 deactivate(defaults[i]);
1491 }
1492 log("Paging received on PCU ", g_roi);
1493
1494 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1495 var boolean rx_on_i := ro_integer_contains(g_roi, i);
1496 var boolean exp_on_i := ro_integer_contains(exp_on_pcu_idx, i);
1497 if (exp_on_i and not rx_on_i) {
1498 setverdict(fail, "PS-PAGING not received on ", mp_nsconfig_pcu[i].nsei);
1499 }
1500 if (not exp_on_i and rx_on_i) {
1501 setverdict(fail, "PS-PAGING not expected but received on ", mp_nsconfig_pcu[i].nsei);
1502 }
1503 }
1504 setverdict(pass);
1505}
1506
1507/* PS-PAGING on SIG-BVC for BSS Area */
1508private function f_TC_paging_ps_sig_bss(charstring id) runs on BSSGP_ConnHdlr
1509{
1510 /* we expect the paging to arrive on all three NSE */
1511 f_send_paging_ps_exp_multi(ts_BssgpP4BssArea, 0, {0, 1, 2});
1512}
1513testcase TC_paging_ps_sig_bss() runs on test_CT {
1514 var BSSGP_ConnHdlr vc_conn;
1515 f_init();
1516
1517 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_bss), testcasename(), g_pcu, g_sgsn, 13);
1518 vc_conn.done;
1519
1520 f_cleanup();
1521}
1522
1523/* PS-PAGING on SIG-BVC for Location Area */
1524private function f_TC_paging_ps_sig_lac(charstring id) runs on BSSGP_ConnHdlr
1525{
Daniel Willmann2c9300f2020-12-01 10:54:08 +01001526 /* The first LAC (13135) is shared by all three NSEs */
1527 f_send_paging_ps_exp_multi(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, {0, 1, 2});
1528 /* Reset state */
1529 g_roi := {};
1530 /* Make LAC (13300) available on pcu index 2 */
1531 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
1532 f_send_paging_ps_exp_multi(ts_BssgpP4LAC(pcu_bvc_cfg[2].cell_id.ra_id.lai), 0, {2});
Harald Welte0e188242020-11-22 21:46:48 +01001533}
1534testcase TC_paging_ps_sig_lac() runs on test_CT {
1535 var BSSGP_ConnHdlr vc_conn;
1536 f_init();
1537
1538 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_lac), testcasename(), g_pcu, g_sgsn, 14);
1539 vc_conn.done;
1540
1541 f_cleanup();
1542}
1543
Harald Welte7462a592020-11-23 22:07:07 +01001544/* PS-PAGING on SIG-BVC for unknown Location Area */
1545private function f_TC_paging_ps_sig_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1546{
1547 var GSM_Types.LocationAreaIdentification unknown_la := {
1548 mcc_mnc := '567F99'H,
1549 lac := 33333
1550 };
1551 f_send_paging_ps_exp_no_bss(ts_BssgpP4LAC(unknown_la), 0, true);
1552}
1553testcase TC_paging_ps_sig_lac_unknown() runs on test_CT {
1554 var BSSGP_ConnHdlr vc_conn;
1555 f_init();
1556
1557 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_lac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1558 vc_conn.done;
1559
1560 f_cleanup();
1561}
1562
Harald Welte0e188242020-11-22 21:46:48 +01001563/* PS-PAGING on SIG-BVC for Routeing Area */
1564private function f_TC_paging_ps_sig_rac(charstring id) runs on BSSGP_ConnHdlr
1565{
Daniel Willmann2c9300f2020-12-01 10:54:08 +01001566 /* Only PCU index 0 has a matching BVC with the RA ID */
Harald Welte0e188242020-11-22 21:46:48 +01001567 f_send_paging_ps_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, {0});
Daniel Willmann2c9300f2020-12-01 10:54:08 +01001568 g_roi := {};
1569 /* PCU index 1 and 2 have a matching BVC with the RA ID */
1570 f_send_paging_ps_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[2].cell_id.ra_id), 0, {1, 2});
1571 g_roi := {};
1572 /* PCU index 2 has two matching BVCs with the RA ID */
1573 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
1574 f_send_paging_ps_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[2].cell_id.ra_id), 0, {2});
Harald Welte0e188242020-11-22 21:46:48 +01001575}
1576testcase TC_paging_ps_sig_rac() runs on test_CT {
1577 var BSSGP_ConnHdlr vc_conn;
1578 f_init();
1579
1580 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_rac), testcasename(), g_pcu, g_sgsn, 15);
1581 vc_conn.done;
1582
1583 f_cleanup();
1584}
1585
Harald Welte7462a592020-11-23 22:07:07 +01001586/* PS-PAGING on SIG-BVC for unknown Routeing Area */
1587private function f_TC_paging_ps_sig_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1588{
1589 var RoutingAreaIdentification unknown_ra := {
1590 lai := {
1591 mcc_mnc := '567F99'H,
1592 lac := 33333
1593 },
1594 rac := 254
1595 };
1596 f_send_paging_ps_exp_no_bss(ts_BssgpP4RAC(unknown_ra), 0, true);
1597}
1598testcase TC_paging_ps_sig_rac_unknown() runs on test_CT {
1599 var BSSGP_ConnHdlr vc_conn;
1600 f_init();
1601
1602 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_rac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1603 vc_conn.done;
1604
1605 f_cleanup();
1606}
1607
Harald Welte0e188242020-11-22 21:46:48 +01001608/* PS-PAGING on SIG-BVC for BVCI (one cell) */
1609private function f_TC_paging_ps_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
1610{
1611 f_send_paging_ps_exp_multi(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, {0});
1612}
1613testcase TC_paging_ps_sig_bvci() runs on test_CT {
1614 var BSSGP_ConnHdlr vc_conn;
1615 f_init();
1616
1617 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_bvci), testcasename(), g_pcu, g_sgsn, 16);
1618 vc_conn.done;
1619
1620 f_cleanup();
1621}
1622
Harald Welte7462a592020-11-23 22:07:07 +01001623/* PS-PAGING on SIG-BVC for unknown BVCI */
1624private function f_TC_paging_ps_sig_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1625{
1626 f_send_paging_ps_exp_no_bss(ts_BssgpP4Bvci(33333), 0, true);
1627}
1628testcase TC_paging_ps_sig_bvci_unknown() runs on test_CT {
1629 var BSSGP_ConnHdlr vc_conn;
1630 f_init();
1631
1632 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
1633 vc_conn.done;
1634
1635 f_cleanup();
1636}
1637
1638
Harald Welte0e188242020-11-22 21:46:48 +01001639
1640/***********************************************************************
1641 * PAGING CS procedure
1642 ***********************************************************************/
1643
1644private function f_send_paging_cs(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1645 boolean use_sig := false)
1646runs on BSSGP_ConnHdlr return template (present) PDU_BSSGP {
1647 var template (value) PDU_BSSGP pdu_tx;
1648 var template (present) PDU_BSSGP pdu_rx;
1649 /* we always specify '0' as BVCI in the templates below, as we override it with
1650 * 'p4' later anyway */
1651 pdu_rx := tr_BSSGP_CS_PAGING(0);
1652 pdu_rx.pDU_BSSGP_PAGING_CS.iMSI := tr_BSSGP_IMSI(g_pars.imsi);
1653 if (ispresent(g_pars.p_tmsi)) {
1654 pdu_tx := ts_BSSGP_CS_PAGING_PTMSI(0, g_pars.imsi, oct2int(g_pars.p_tmsi));
1655 pdu_rx.pDU_BSSGP_PAGING_CS.tMSI := tr_BSSGP_TMSI(oct2int(g_pars.p_tmsi));
1656 } else {
1657 pdu_tx := ts_BSSGP_CS_PAGING_IMSI(0, g_pars.imsi);
1658 pdu_rx.pDU_BSSGP_PAGING_CS.tMSI := omit;
1659 }
1660 pdu_tx.pDU_BSSGP_PAGING_CS.paging_Field4 := p4;
1661 pdu_rx.pDU_BSSGP_PAGING_CS.paging_Field4 := p4;
1662 if (use_sig == false) {
Harald Welte158becf2020-12-09 12:32:32 +01001663 SGSN_PTP[sgsn_idx].send(pdu_tx);
Harald Welte0e188242020-11-22 21:46:48 +01001664 } else {
1665 SGSN_SIG[sgsn_idx].send(pdu_tx);
1666 }
1667 return pdu_rx;
1668}
1669
1670/* send paging defined by 'p4' on given SGSN-side index (ptp or signaling) and expect one paging to arrive on
1671 * specified PCU index */
1672private function f_send_paging_cs_exp_one_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1673 boolean use_sig := false,integer pcu_idx := 0)
1674runs on BSSGP_ConnHdlr {
1675 var template (present) PDU_BSSGP exp_rx;
Daniel Willmann1a859712020-12-04 00:59:45 +01001676 var boolean test_done := false;
Harald Welte0e188242020-11-22 21:46:48 +01001677 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1678 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1679 exp_rx := f_send_paging_cs(p4, sgsn_idx, use_sig);
1680 /* Expect paging to propagate to the one BSS addressed by the BVCI only */
1681 timer T := 2.0;
1682 T.start;
1683 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001684 [not use_sig and not test_done] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001685 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001686 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001687 repeat;
1688 }
1689 [not use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
1690 setverdict(fail, "Received paging on SIGNALING BVC, expected PTP BVC");
1691 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001692 [use_sig and not test_done] PCU_SIG[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001693 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001694 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001695 repeat;
1696 }
Harald Welte158becf2020-12-09 12:32:32 +01001697 [use_sig] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001698 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1699 }
Harald Welte158becf2020-12-09 12:32:32 +01001700 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001701 setverdict(fail, "Paging received on unexpected BVC");
1702 }
1703 [] any from PCU_SIG.receive(exp_rx) {
1704 setverdict(fail, "Paging received on unexpected BVC");
1705 }
Harald Welte158becf2020-12-09 12:32:32 +01001706 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01001707 setverdict(fail, "Different Paging than expected received PTP BVC");
1708 }
1709 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
1710 setverdict(fail, "Different Paging than expected on SIGNALING BVC");
1711 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001712 [not test_done] T.timeout {
1713 setverdict(fail, "Timeout while waiting for paging")
1714 }
1715 [test_done] T.timeout;
Harald Welte0e188242020-11-22 21:46:48 +01001716 }
1717}
1718
Harald Welte7462a592020-11-23 22:07:07 +01001719/* send a CS-PAGING but don't expect it to show up on any PTP or SIG BVC */
1720private function f_send_paging_cs_exp_no_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1721 boolean use_sig := false)
1722runs on BSSGP_ConnHdlr {
1723 var template (present) PDU_BSSGP exp_rx;
1724 exp_rx := f_send_paging_cs(p4, sgsn_idx, use_sig);
1725 /* Expect paging to propagate to no BSS */
1726 timer T := 2.0;
1727 T.start;
1728 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001729 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte7462a592020-11-23 22:07:07 +01001730 setverdict(fail, "Paging received on unexpected BVC");
1731 }
1732 [] any from PCU_SIG.receive(exp_rx) {
1733 setverdict(fail, "Paging received on unexpected BVC");
1734 }
Harald Welte158becf2020-12-09 12:32:32 +01001735 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
Harald Welte7462a592020-11-23 22:07:07 +01001736 setverdict(fail, "Different Paging received on PTP BVC");
1737 }
1738 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
1739 setverdict(fail, "Different Paging received on SIGNALING BVC");
1740 }
1741 [] T.timeout {
1742 setverdict(pass);
1743 }
1744 }
1745}
1746
Harald Welte0e188242020-11-22 21:46:48 +01001747private function f_TC_paging_cs_ptp_bss(charstring id) runs on BSSGP_ConnHdlr
1748{
1749 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1750 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1751 f_send_paging_cs_exp_one_bss(ts_BssgpP4BssArea, 0, false, 0);
1752}
1753testcase TC_paging_cs_ptp_bss() runs on test_CT {
1754 var BSSGP_ConnHdlr vc_conn;
1755 f_init();
1756
1757 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_bss), testcasename(), g_pcu, g_sgsn, 17);
1758 vc_conn.done;
1759
1760 f_cleanup();
1761}
1762
1763/* CS-PAGING on PTP-BVC for Location Area */
1764private function f_TC_paging_cs_ptp_lac(charstring id) runs on BSSGP_ConnHdlr
1765{
1766 var template (present) PDU_BSSGP exp_rx;
1767 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1768 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1769 f_send_paging_cs_exp_one_bss(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, false, 0);
1770}
1771testcase TC_paging_cs_ptp_lac() runs on test_CT {
1772 var BSSGP_ConnHdlr vc_conn;
1773 f_init();
1774
1775 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_lac), testcasename(), g_pcu, g_sgsn, 18);
1776 vc_conn.done;
1777
1778 f_cleanup();
1779}
1780
Harald Welte7462a592020-11-23 22:07:07 +01001781/* CS-PAGING on PTP-BVC for unknown Location Area */
1782private function f_TC_paging_cs_ptp_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1783{
1784 var GSM_Types.LocationAreaIdentification unknown_la := {
1785 mcc_mnc := '567F99'H,
1786 lac := 33333
1787 };
1788 /* as it's sent on the PTP BVC, we expect it to pass even for unknown LAC */
1789 f_send_paging_cs_exp_one_bss(ts_BssgpP4LAC(unknown_la), 0, false, 0);
1790}
1791testcase TC_paging_cs_ptp_lac_unknown() runs on test_CT {
1792 var BSSGP_ConnHdlr vc_conn;
1793 f_init();
1794
1795 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_lac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1796 vc_conn.done;
1797
1798 f_cleanup();
1799}
1800
Harald Welte0e188242020-11-22 21:46:48 +01001801/* CS-PAGING on PTP-BVC for Routeing Area */
1802private function f_TC_paging_cs_ptp_rac(charstring id) runs on BSSGP_ConnHdlr
1803{
1804 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1805 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1806 f_send_paging_cs_exp_one_bss(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, false, 0);
1807}
1808testcase TC_paging_cs_ptp_rac() runs on test_CT {
1809 var BSSGP_ConnHdlr vc_conn;
1810 f_init();
1811
1812 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_rac), testcasename(), g_pcu, g_sgsn, 19);
1813 vc_conn.done;
1814
1815 f_cleanup();
1816}
1817
Harald Welte7462a592020-11-23 22:07:07 +01001818/* CS-PAGING on PTP-BVC for unknown Routeing Area */
1819private function f_TC_paging_cs_ptp_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1820{
1821 var RoutingAreaIdentification unknown_ra := {
1822 lai := {
1823 mcc_mnc := '567F99'H,
1824 lac := 33333
1825 },
1826 rac := 254
1827 };
1828 /* as it's sent on the PTP BVC, we expect it to pass even for unknown RAC */
1829 f_send_paging_cs_exp_one_bss(ts_BssgpP4RAC(unknown_ra), 0, false, 0);
1830}
1831testcase TC_paging_cs_ptp_rac_unknown() runs on test_CT {
1832 var BSSGP_ConnHdlr vc_conn;
1833 f_init();
1834
1835 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_rac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1836 vc_conn.done;
1837
1838 f_cleanup();
1839}
1840
Harald Welte0e188242020-11-22 21:46:48 +01001841/* CS-PAGING on PTP-BVC for BVCI (one cell) */
1842private function f_TC_paging_cs_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
1843{
1844 /* this should be the normal case for MS in READY MM state after a lower layer failure */
1845 f_send_paging_cs_exp_one_bss(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, false, 0);
1846}
1847testcase TC_paging_cs_ptp_bvci() runs on test_CT {
1848 var BSSGP_ConnHdlr vc_conn;
1849 f_init();
1850
1851 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_bvci), testcasename(), g_pcu, g_sgsn, 20);
1852 vc_conn.done;
1853
1854 f_cleanup();
1855}
1856
Harald Welte7462a592020-11-23 22:07:07 +01001857/* CS-PAGING on PTP-BVC for unknown BVCI */
1858private function f_TC_paging_cs_ptp_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1859{
1860 /* as it's sent on the PTP BVC, we expect it to pass even for unknown BVCI */
1861 f_send_paging_cs_exp_one_bss(ts_BssgpP4Bvci(33333), 0, false, 0);
1862}
1863testcase TC_paging_cs_ptp_bvci_unknown() runs on test_CT {
1864 var BSSGP_ConnHdlr vc_conn;
1865 f_init();
1866
1867 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
1868 vc_conn.done;
1869
1870 f_cleanup();
1871}
1872
Harald Welte0e188242020-11-22 21:46:48 +01001873/* send CS-PAGING on SIG BVC, expect it to arrive on given list of PCU indexes */
1874private function f_send_paging_cs_exp_multi(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1875 ro_integer exp_on_pcu_idx) runs on BSSGP_ConnHdlr
1876{
1877 var template (present) PDU_BSSGP exp_rx;
1878 exp_rx := f_send_paging_cs(p4, 0, true);
1879
1880 /* FIXME: make sure the relevant BVCs/BSS are connected to the ports! */
1881 var ro_default defaults := {};
1882 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1883 var default d := activate(as_paging_sig_pcu(i, exp_rx, g_roi));
1884 defaults := defaults & { d };
1885 }
1886 f_sleep(2.0);
1887 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
1888 deactivate(defaults[i]);
1889 }
1890 log("Paging received on PCU ", g_roi);
1891
1892 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1893 var boolean rx_on_i := ro_integer_contains(g_roi, i);
1894 var boolean exp_on_i := ro_integer_contains(exp_on_pcu_idx, i);
1895 if (exp_on_i and not rx_on_i) {
1896 setverdict(fail, "PS-PAGING not received on ", mp_nsconfig_pcu[i].nsei);
1897 }
1898 if (not exp_on_i and rx_on_i) {
1899 setverdict(fail, "PS-PAGING not expected but received on ", mp_nsconfig_pcu[i].nsei);
1900 }
1901 }
1902 setverdict(pass);
1903}
1904
1905/* CS-PAGING on SIG-BVC for BSS Area */
1906private function f_TC_paging_cs_sig_bss(charstring id) runs on BSSGP_ConnHdlr
1907{
1908 /* we expect the paging to arrive on all three NSE */
1909 f_send_paging_cs_exp_multi(ts_BssgpP4BssArea, 0, {0, 1, 2});
1910}
1911testcase TC_paging_cs_sig_bss() runs on test_CT {
1912 var BSSGP_ConnHdlr vc_conn;
1913 f_init();
1914
1915 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_bss), testcasename(), g_pcu, g_sgsn, 13);
1916 vc_conn.done;
1917
1918 f_cleanup();
1919}
1920
1921/* CS-PAGING on SIG-BVC for Location Area */
1922private function f_TC_paging_cs_sig_lac(charstring id) runs on BSSGP_ConnHdlr
1923{
Daniel Willmannd4fb73c2020-12-07 13:57:17 +01001924 /* The first LAC (13135) is shared by all three NSEs */
1925 f_send_paging_cs_exp_multi(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, {0, 1, 2});
1926 /* Reset state */
1927 g_roi := {};
1928 /* Make LAC (13300) available on pcu index 2 */
1929 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
1930 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 +01001931}
1932testcase TC_paging_cs_sig_lac() runs on test_CT {
1933 var BSSGP_ConnHdlr vc_conn;
1934 f_init();
1935
1936 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_lac), testcasename(), g_pcu, g_sgsn, 14);
1937 vc_conn.done;
1938
1939 f_cleanup();
1940}
1941
Harald Welte7462a592020-11-23 22:07:07 +01001942/* CS-PAGING on SIG-BVC for unknown Location Area */
1943private function f_TC_paging_cs_sig_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1944{
1945 var GSM_Types.LocationAreaIdentification unknown_la := {
1946 mcc_mnc := '567F99'H,
1947 lac := 33333
1948 };
1949 f_send_paging_cs_exp_no_bss(ts_BssgpP4LAC(unknown_la), 0, true);
1950}
1951testcase TC_paging_cs_sig_lac_unknown() runs on test_CT {
1952 var BSSGP_ConnHdlr vc_conn;
1953 f_init();
1954
1955 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_lac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1956 vc_conn.done;
1957
1958 f_cleanup();
1959}
1960
Harald Welte0e188242020-11-22 21:46:48 +01001961/* CS-PAGING on SIG-BVC for Routeing Area */
1962private function f_TC_paging_cs_sig_rac(charstring id) runs on BSSGP_ConnHdlr
1963{
Daniel Willmannd4fb73c2020-12-07 13:57:17 +01001964 /* Only PCU index 0 has a matching BVC with the RA ID */
Harald Welte0e188242020-11-22 21:46:48 +01001965 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 +01001966 g_roi := {};
1967 /* PCU index 1 and 2 have a matching BVC with the RA ID */
1968 f_send_paging_cs_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[2].cell_id.ra_id), 0, {1, 2});
1969 g_roi := {};
1970 /* PCU index 2 has two matching BVCs with the RA ID */
1971 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
1972 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 +01001973}
1974testcase TC_paging_cs_sig_rac() runs on test_CT {
1975 var BSSGP_ConnHdlr vc_conn;
1976 f_init();
1977
1978 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_rac), testcasename(), g_pcu, g_sgsn, 15);
1979 vc_conn.done;
1980
1981 f_cleanup();
1982}
1983
Harald Welte7462a592020-11-23 22:07:07 +01001984/* CS-PAGING on SIG-BVC for unknown Routeing Area */
1985private function f_TC_paging_cs_sig_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1986{
1987 var RoutingAreaIdentification unknown_ra := {
1988 lai := {
1989 mcc_mnc := '567F99'H,
1990 lac := 33333
1991 },
1992 rac := 254
1993 };
1994 f_send_paging_cs_exp_no_bss(ts_BssgpP4RAC(unknown_ra), 0, true);
1995}
1996testcase TC_paging_cs_sig_rac_unknown() runs on test_CT {
1997 var BSSGP_ConnHdlr vc_conn;
1998 f_init();
1999
2000 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_rac_unknown), testcasename(), g_pcu, g_sgsn, 11);
2001 vc_conn.done;
2002
2003 f_cleanup();
2004}
2005
Harald Welte0e188242020-11-22 21:46:48 +01002006/* CS-PAGING on SIG-BVC for BVCI (one cell) */
2007private function f_TC_paging_cs_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
2008{
2009 f_send_paging_cs_exp_multi(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, {0});
2010}
2011testcase TC_paging_cs_sig_bvci() runs on test_CT {
2012 var BSSGP_ConnHdlr vc_conn;
2013 f_init();
2014
2015 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_bvci), testcasename(), g_pcu, g_sgsn, 16);
2016 vc_conn.done;
2017
2018 f_cleanup();
2019}
2020
Harald Welte7462a592020-11-23 22:07:07 +01002021/* CS-PAGING on SIG-BVC for unknown BVCI */
2022private function f_TC_paging_cs_sig_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
2023{
2024 f_send_paging_cs_exp_no_bss(ts_BssgpP4Bvci(33333), 0, true);
2025}
2026testcase TC_paging_cs_sig_bvci_unknown() runs on test_CT {
2027 var BSSGP_ConnHdlr vc_conn;
2028 f_init();
2029
2030 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
2031 vc_conn.done;
2032
2033 f_cleanup();
2034}
2035
Harald Welte4f91c3b2020-12-09 12:25:51 +01002036/***********************************************************************
2037 * FLUSH-LL procedure
2038 ***********************************************************************/
2039
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002040private function f_TC_flush_ll(charstring id) runs on BSSGP_ConnHdlr {
2041 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
2042 var integer i;
2043 for (i := 0; i < 10; i := i+1) {
2044 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_FLUSH_LL(g_pars.tlli, bvci, bvci_new := bvci);
2045 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2046 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_FLUSH_LL(g_pars.tlli, bvci, bvci_new := bvci);
2047
2048 f_sgsn2pcu(pdu_tx, pdu_rx, use_sig := true);
2049
2050 pdu_tx := ts_BSSGP_FLUSH_LL_ACK(g_pars.tlli, int2oct(0, 1), 23, bvci_new := bvci);
2051 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2052 pdu_rx := tr_BSSGP_FLUSH_LL_ACK(g_pars.tlli, int2oct(0, 1), 23, bvci_new := bvci);
2053
2054 f_pcu2sgsn(pdu_tx, pdu_rx, use_sig := true);
2055 }
2056 setverdict(pass);
2057}
2058testcase TC_flush_ll() runs on test_CT
2059{
2060 var BSSGP_ConnHdlr vc_conn;
2061 f_init();
2062
2063 vc_conn := f_start_handler(refers(f_TC_flush_ll), testcasename(), g_pcu, g_sgsn, 6);
2064 vc_conn.done;
2065 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
2066
2067 f_cleanup();
2068}
Harald Welte6dc2ac42020-11-16 09:16:17 +01002069
Harald Welte4f91c3b2020-12-09 12:25:51 +01002070/***********************************************************************
2071 * SGSN-INVOKE-TRACE procedure
2072 ***********************************************************************/
2073
Harald Weltef8e5c5d2020-11-27 22:37:23 +01002074private altstep as_bssgp_g_pcu_count(integer pcu_idx, template (present) PDU_BSSGP exp_rx, inout ro_integer roi)
2075runs on GlobalTest_CT {
2076[] G_PCU[pcu_idx].receive(exp_rx) from g_pcu[pcu_idx].vc_BSSGP {
2077 if (ro_integer_contains(roi, pcu_idx)) {
2078 setverdict(fail, "Received multiple on same SIG BVC");
2079 }
2080 roi := roi & { pcu_idx };
2081 repeat;
2082 }
2083}
2084/* send a INVOKE-TRACE from SGSN and expect to receive a copy on each NSE */
2085testcase TC_trace() runs on GlobalTest_CT
2086{
2087 var BSSGP_ConnHdlr vc_conn;
2088 f_init();
2089 f_global_init();
2090
2091 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_INVOKE_TRACE('23'O, '4321'O);
2092 var template (present) PDU_BSSGP exp_rx := ts_BSSGP_INVOKE_TRACE('23'O, '4321'O);
2093
2094 var ro_default defaults := {};
2095 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2096 activate(as_bssgp_g_pcu_count(i, exp_rx, g_roi));
2097 }
2098 G_SGSN[0].send(pdu_tx);
2099 f_sleep(2.0);
2100 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2101 deactivate(defaults[i]);
2102 }
2103
2104 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2105 if (not ro_integer_contains(g_roi, i)) {
2106 setverdict(fail, "Failed to receive TRACE on PCU index ", i);
2107 }
2108 }
2109 setverdict(pass);
2110
2111 f_cleanup();
2112}
2113
Harald Welte4f91c3b2020-12-09 12:25:51 +01002114/***********************************************************************
2115 * LLC-DISCARDED procedure
2116 ***********************************************************************/
2117
Harald Weltec0351d12020-11-27 22:49:02 +01002118private function f_TC_llc_discarded(charstring id) runs on BSSGP_ConnHdlr {
2119 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
2120
2121 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_LLC_DISCARDED(g_pars.tlli, 23, bvci, 2342);
2122 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2123 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_LLC_DISCARDED(g_pars.tlli, 23, bvci, 2342);
2124
2125 f_pcu2sgsn(pdu_tx, pdu_rx, use_sig := true);
2126
2127 setverdict(pass);
2128}
2129/* Send a LLC-DISCARDED from BSS side and expect it to show up on SGSN (SIG BVC) */
2130testcase TC_llc_discarded() runs on test_CT
2131{
2132 var BSSGP_ConnHdlr vc_conn;
2133 f_init();
2134
2135 vc_conn := f_start_handler(refers(f_TC_llc_discarded), testcasename(), g_pcu, g_sgsn, 6);
2136 vc_conn.done;
2137 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
2138
2139 f_cleanup();
2140}
2141
Harald Welte4f91c3b2020-12-09 12:25:51 +01002142/***********************************************************************
2143 * OVERLOAD procedure
2144 ***********************************************************************/
2145
Harald Weltef20af412020-11-28 16:11:11 +01002146/* Send an OVERLOAD from SGSN side and expect it to show up on each PCU (SIG BVC) */
2147testcase TC_overload() runs on GlobalTest_CT
2148{
2149 f_init();
2150 f_global_init();
2151
2152 var template (value) PDU_BSSGP pdu_tx := ts_OVERLOAD('1'B);
2153 var template (present) PDU_BSSGP exp_rx := tr_OVERLOAD('1'B);
2154
2155 var ro_default defaults := {};
2156 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2157 activate(as_bssgp_g_pcu_count(i, exp_rx, g_roi));
2158 }
2159 G_SGSN[0].send(pdu_tx);
2160 f_sleep(2.0);
2161 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2162 deactivate(defaults[i]);
2163 }
2164
2165 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2166 if (not ro_integer_contains(g_roi, i)) {
2167 setverdict(fail, "Failed to receive OVERLOAD on PCU index ", i);
2168 }
2169 }
2170 setverdict(pass);
2171
2172 f_cleanup();
2173}
2174
Harald Welte4f91c3b2020-12-09 12:25:51 +01002175/***********************************************************************
2176 * BVC-BLOCK / BVC-UNBLOCK procedure
2177 ***********************************************************************/
2178
Harald Welte239aa502020-11-24 23:14:20 +01002179private function f_block_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2180{
2181 var BSSGP_BVC_CT bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2182 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2183 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2184
2185 SGSN_MGMT.clear;
2186 PCU_MGMT.clear;
2187
2188 /* block the PTP BVC from the PCU side */
2189 PCU_MGMT.send(BssgpBlockRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to bvc_ct;
2190 /* expect state on both PCU and SGSN side to change */
2191 interleave {
2192 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_BLOCKED)) from bvc_ct;
2193 [] SGSN_MGMT.receive(tr_BssgpStsInd(*, bvc_cfg.bvci, BVC_S_BLOCKED));
2194 }
2195 setverdict(pass);
2196}
2197testcase TC_bvc_block_ptp() runs on test_CT
2198{
2199 f_init();
2200 f_sleep(1.0);
2201 f_block_ptp_bvc_from_pcu(0, 0);
2202 f_cleanup();
2203}
2204
2205private function f_unblock_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2206{
2207 var BSSGP_BVC_CT bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2208 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2209 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2210
2211 SGSN_MGMT.clear;
2212 PCU_MGMT.clear;
2213
2214 /* block the PTP BVC from the PCU side */
2215 PCU_MGMT.send(BssgpUnblockRequest:{}) to bvc_ct;
2216 /* expect state on both PCU and SGSN side to change */
2217 interleave {
2218 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_UNBLOCKED)) from bvc_ct;
2219 [] SGSN_MGMT.receive(tr_BssgpStsInd(*, bvc_cfg.bvci, BVC_S_UNBLOCKED));
2220 }
2221 setverdict(pass);
2222}
2223testcase TC_bvc_unblock_ptp() runs on test_CT
2224{
2225 f_init();
2226 f_sleep(1.0);
2227 f_block_ptp_bvc_from_pcu(0, 0);
2228 f_sleep(1.0);
2229 f_unblock_ptp_bvc_from_pcu(0, 0);
2230 f_cleanup();
2231}
2232
Harald Welte4f91c3b2020-12-09 12:25:51 +01002233/***********************************************************************
2234 * BVC-RESET procedure
2235 ***********************************************************************/
2236
Harald Welte60a8ec72020-11-25 17:12:53 +01002237private altstep as_ignore_status(BSSGP_BVC_MGMT_PT pt) {
2238[] pt.receive(BssgpStatusIndication:?) { repeat; }
2239}
2240private function f_get_sgsn_bvc_ct(integer sgsn_idx, BssgpBvci bvci) runs on test_CT return BSSGP_BVC_CT {
2241 for (var integer i := 0; i < lengthof(g_sgsn[sgsn_idx].cfg.bvc); i := i+1) {
2242 if (g_sgsn[sgsn_idx].cfg.bvc[i].bvci == bvci) {
2243 return g_sgsn[sgsn_idx].vc_BSSGP_BVC[i];
2244 }
2245 }
2246 return null;
2247}
2248private function f_reset_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2249{
2250 var BSSGP_BVC_CT pcu_bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2251 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2252 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2253 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(0, bvc_cfg.bvci);
2254 var default d;
2255
2256 SGSN_MGMT.clear;
2257 PCU_MGMT.clear;
2258
2259 /* block the PTP BVC from the PCU side */
2260 PCU_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to pcu_bvc_ct;
2261 /* expect state on both PCU and SGSN side to change */
2262 d := activate(as_ignore_status(SGSN_MGMT));
2263 interleave {
2264 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_BLOCKED)) from pcu_bvc_ct;
2265 [] SGSN_MGMT.receive(BssgpResetIndication:{bvc_cfg.bvci}) from sgsn_bvc_ct;
2266 }
2267 deactivate(d);
2268 setverdict(pass);
2269}
2270/* Send a BVC-RESET for a PTP BVC from the BSS side: expect it to propagate */
2271testcase TC_bvc_reset_ptp_from_bss() runs on test_CT
2272{
2273 f_init();
2274 f_sleep(3.0);
2275 f_reset_ptp_bvc_from_pcu(0, 0);
2276 f_cleanup();
2277}
2278
Harald Welte16786e92020-11-27 19:11:56 +01002279private altstep as_count_bvc_block(integer sgsn_idx, BssgpBvci bvci, inout ro_integer roi)
2280runs on test_CT {
2281 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(sgsn_idx, bvci);
2282 [] SGSN_MGMT.receive(tr_BssgpStsInd(?, bvci, BVC_S_BLOCKED)) from sgsn_bvc_ct {
2283 roi := roi & { bvci };
Harald Welteb2647f72020-12-07 14:36:35 +01002284 repeat;
Harald Welte16786e92020-11-27 19:11:56 +01002285 }
2286}
2287/* reset the signaling BVC from one BSS; expect no signaling BVC reset on SGSN; but BVC-BLOCK for PTP */
2288testcase TC_bvc_reset_sig_from_bss() runs on test_CT {
2289
2290 f_init();
2291 f_sleep(3.0);
2292
2293 /* Start BVC-RESET procedure for BVCI=0 */
2294 PCU_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to g_pcu[0].vc_BSSGP;
2295
2296 /* Activate altsteps: One for each PTP BVC within that PCUs NSE */
2297 var ro_default defaults := {};
2298 for (var integer i := 0; i < lengthof(g_pcu[0].cfg.bvc); i := i+1) {
2299 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[i];
2300 var default d := activate(as_count_bvc_block(0, bvcc.bvci, g_roi));
2301 defaults := defaults & { d };
2302 }
2303
2304 timer T := 3.0;
2305 T.start;
2306 alt {
2307 [] SGSN_MGMT.receive(BssgpResetIndication:{0}) {
2308 setverdict(fail, "BSS-side Reset of BVCI=0 should not propagate");
2309 }
2310 [] T.timeout;
2311 }
2312
2313 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2314 deactivate(defaults[i]);
2315 }
2316
2317 /* check if BVC-block was received on all expected BVC */
2318 for (var integer i := 0; i < lengthof(g_pcu[0].cfg.bvc); i := i+1) {
2319 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[i];
2320 if (not ro_integer_contains(g_roi, bvcc.bvci)) {
2321 setverdict(fail, "Missing SGSN-side BVC-BLOCK of BVCI=", bvcc.bvci);
2322 }
2323 }
2324
2325 /* check if BVC-block was not received on any unexpected BVC is not required as
2326 * such a message would basically run into 'no matching clause' */
Daniel Willmannf2590212020-12-04 14:20:50 +01002327 setverdict(pass);
Harald Welte16786e92020-11-27 19:11:56 +01002328 f_cleanup();
2329}
2330
Harald Welte60a8ec72020-11-25 17:12:53 +01002331private function f_reset_ptp_bvc_from_sgsn(integer pcu_idx, integer bvc_idx) runs on test_CT
2332{
2333 var BSSGP_BVC_CT pcu_bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2334 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2335 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2336 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(0, bvc_cfg.bvci);
2337 var default d;
2338
2339 SGSN_MGMT.clear;
2340 PCU_MGMT.clear;
2341
2342 /* block the PTP BVC from the PCU side */
2343 SGSN_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to sgsn_bvc_ct;
2344 /* expect state on both PCU and SGSN side to change */
2345 d := activate(as_ignore_status(PCU_MGMT));
2346 interleave {
2347 [] SGSN_MGMT.receive(tr_BssgpStsInd(?, bvc_cfg.bvci, BVC_S_BLOCKED)) from sgsn_bvc_ct;
2348 [] PCU_MGMT.receive(BssgpResetIndication:{bvc_cfg.bvci}) from pcu_bvc_ct;
2349 }
2350 deactivate(d);
2351 setverdict(pass);
2352}
2353/* Send a BVC-RESET for a PTP BVC from the SGSN side: expect it to propagate */
2354testcase TC_bvc_reset_ptp_from_sgsn() runs on test_CT
2355{
2356 f_init();
2357 f_sleep(3.0);
2358 f_reset_ptp_bvc_from_sgsn(0, 0);
2359 f_cleanup();
2360}
2361
Daniel Willmannef7015f2021-01-08 00:43:56 +01002362private altstep as_ignore_mgmt(BSSGP_BVC_MGMT_PT pt) {
2363 [] pt.receive {repeat; }
2364}
2365
Harald Welte16786e92020-11-27 19:11:56 +01002366private altstep as_count_bvc0_block(integer pcu_idx, Nsei nsei, inout ro_integer roi)
2367runs on test_CT {
2368 var BSSGP_CT pcu_ct := g_pcu[pcu_idx].vc_BSSGP;
2369 [] PCU_MGMT.receive(BssgpResetIndication:{0}) from pcu_ct {
2370 roi := roi & { nsei };
Daniel Willmannef7015f2021-01-08 00:43:56 +01002371 repeat;
Harald Welte16786e92020-11-27 19:11:56 +01002372 }
2373}
Daniel Willmannef7015f2021-01-08 00:43:56 +01002374
Harald Welte16786e92020-11-27 19:11:56 +01002375/* reset the signaling BVC from the SGSN; expect all signaling BVC on all BSS to be reset */
2376testcase TC_bvc_reset_sig_from_sgsn() runs on test_CT {
2377
2378 f_init();
2379 f_sleep(3.0);
2380
Daniel Willmannef7015f2021-01-08 00:43:56 +01002381 SGSN_MGMT.clear;
2382 PCU_MGMT.clear;
2383
Harald Welte16786e92020-11-27 19:11:56 +01002384 /* Start BVC-RESET procedure for BVCI=0 */
2385 SGSN_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to g_sgsn[0].vc_BSSGP;
2386
Daniel Willmannef7015f2021-01-08 00:43:56 +01002387 /* Defaults match in reverse activation order, this one is a catch-all for Status indications
2388 * and reset indications sent from other components (like the ptp_bvcs). If we don't drain
2389 * the port and a different message sits at the front we wait forever and fail the test.
2390 */
2391 var ro_default defaults := { activate(as_ignore_mgmt(PCU_MGMT)) };
2392
Harald Welte16786e92020-11-27 19:11:56 +01002393 /* Activate altsteps: One for each PCU NSE */
Harald Welte16786e92020-11-27 19:11:56 +01002394 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2395 var NSConfiguration nscfg := mp_nsconfig_pcu[i];
2396 var default d := activate(as_count_bvc0_block(i, nscfg.nsei, g_roi));
2397 defaults := defaults & { d };
2398 }
2399
2400 f_sleep(3.0);
2401
2402 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2403 deactivate(defaults[i]);
2404 }
2405
2406 /* check if BVC-block was received on all expected BVC */
2407 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2408 var NSConfiguration nscfg := mp_nsconfig_pcu[i];
2409 if (not ro_integer_contains(g_roi, nscfg.nsei)) {
2410 setverdict(fail, "Missing PCU-side BVC-RESET of BVCI=0 on PCU index ", i);
2411 }
2412 }
2413
2414 /* check if BVC-block was not received on any unexpected BVC is not required as
2415 * such a message would basically run into 'no matching clause' */
2416
2417 f_cleanup();
2418}
2419
Harald Welte299aa482020-12-09 15:10:55 +01002420/***********************************************************************
2421 * FLOW-CONTROL-BVC procedure
2422 ***********************************************************************/
2423
2424private altstep as_g_count_sgsn(integer sgsn_idx, inout ro_integer roi,
2425 template PDU_BSSGP exp_rx, template (omit) PDU_BSSGP tx_reply)
2426runs on GlobalTest_CT {
2427 [] G_SGSN[sgsn_idx].receive(exp_rx) {
2428 roi := roi & { sgsn_idx };
2429 if (ispresent(tx_reply)) {
2430 G_SGSN[sgsn_idx].send(tx_reply);
2431 }
2432 }
2433}
2434/* Send FC-BVC from simulated PCU; expect each SGSN to receive it; expect PCU to receive ACK */
2435testcase TC_fc_bvc() runs on GlobalTest_CT
2436{
2437 f_init();
2438 f_global_init_ptp();
2439
2440 var template (value) PDU_BSSGP pdu_tx := t_BVC_FC_BVC(10240, 2000, 1024, 1000, '01'O);
2441 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2442 var template (present) PDU_BSSGP pdu_rx := tr_BVC_FC_BVC(10240, 2000, 1024, 1000, '01'O);
2443 var template (omit) PDU_BSSGP ack_tx :=
2444 t_BVC_FC_BVC_ACK(pdu_tx.pDU_BSSGP_FLOW_CONTROL_BVC.tag.unstructured_Value);
2445
2446 /* Send a FC-BVC from BSS to gbproxy, expect an ACK in response */
2447 G_PCU[0].send(pdu_tx);
2448
2449 /* Activate altsteps: One for each SGSN-side PTP BVC port */
2450 var ro_default defaults := {};
2451 for (var integer i := 0; i < lengthof(g_sgsn); i := i+1) {
2452 var default d := activate(as_g_count_sgsn(i, g_roi, pdu_rx, ack_tx));
2453 defaults := defaults & { d };
2454 }
2455
2456 f_sleep(3.0);
2457
2458 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2459 deactivate(defaults[i]);
2460 }
2461
2462 /* check if BVC-block was received on all expected BVC */
2463 for (var integer i := 0; i < lengthof(g_sgsn); i := i+1) {
2464 if (not ro_integer_contains(g_roi, i)) {
2465 setverdict(fail, "Missing BVC-FLOW-CONTROL on SGSN index ", i);
2466 }
2467 }
2468
2469 /* Expect ACK on PCU side */
2470 G_PCU[0].receive(ack_tx);
2471
2472 setverdict(pass);
2473
2474 f_cleanup();
2475}
2476
Harald Weltecc3894b2020-12-09 16:50:12 +01002477/***********************************************************************
2478 * FLOW-CONTROL-MS procedure
2479 ***********************************************************************/
2480
2481private function f_TC_fc_ms(charstring id) runs on BSSGP_ConnHdlr {
2482 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
2483
2484 var template (value) PDU_BSSGP fc_tx := ts_BVC_FC_MS(g_pars.tlli, 100, 200, '12'O);
2485 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2486 var template (present) PDU_BSSGP fc_rx := tr_BVC_FC_MS(g_pars.tlli, 100, 200, '12'O);
2487 var template (value) PDU_BSSGP ack_tx := ts_BVC_FC_MS_ACK(g_pars.tlli, '12'O);
2488
2489 f_pcu2sgsn(fc_tx, fc_rx, use_sig := false);
2490 f_sgsn2pcu(ack_tx, ack_tx, use_sig := false);
2491
2492 setverdict(pass);
2493}
2494/* Send a FLOW-CONTROL-MS from BSS side and expect it to show up on SGSN (PTP BVC) */
2495testcase TC_fc_ms() runs on test_CT
2496{
2497 var BSSGP_ConnHdlr vc_conn;
2498 f_init();
2499
2500 vc_conn := f_start_handler(refers(f_TC_fc_ms), testcasename(), g_pcu, g_sgsn, 21);
2501 vc_conn.done;
2502 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
2503
2504 f_cleanup();
2505}
2506
2507
Harald Welte299aa482020-12-09 15:10:55 +01002508
Daniel Willmann423d8f42020-09-08 18:58:22 +02002509control {
2510 execute( TC_BVC_bringup() );
Harald Welte92686012020-11-15 21:45:49 +01002511 execute( TC_ul_unitdata() );
Harald Welte78d8db92020-11-15 23:27:27 +01002512 execute( TC_dl_unitdata() );
Harald Welte6dc2ac42020-11-16 09:16:17 +01002513 execute( TC_ra_capability() );
Daniel Willmannace3ece2020-11-16 19:53:26 +01002514 execute( TC_ra_capability_upd() );
Daniel Willmann165d6612020-11-19 14:27:29 +01002515 execute( TC_radio_status() );
Daniel Willmannfa67f492020-11-19 15:48:05 +01002516 execute( TC_suspend() );
Daniel Willmann087a33d2020-11-19 15:58:43 +01002517 execute( TC_resume() );
Harald Weltef8e5c5d2020-11-27 22:37:23 +01002518 execute( TC_trace() );
Harald Weltec0351d12020-11-27 22:49:02 +01002519 execute( TC_llc_discarded() );
Harald Weltef20af412020-11-28 16:11:11 +01002520 execute( TC_overload() );
Harald Welte239aa502020-11-24 23:14:20 +01002521 execute( TC_bvc_block_ptp() );
2522 execute( TC_bvc_unblock_ptp() );
Harald Welte60a8ec72020-11-25 17:12:53 +01002523 execute( TC_bvc_reset_ptp_from_bss() );
Harald Welte16786e92020-11-27 19:11:56 +01002524 execute( TC_bvc_reset_sig_from_bss() );
Harald Welte60a8ec72020-11-25 17:12:53 +01002525 execute( TC_bvc_reset_ptp_from_sgsn() );
Harald Welte16786e92020-11-27 19:11:56 +01002526 execute( TC_bvc_reset_sig_from_sgsn() );
Harald Weltef6e59b02020-12-08 08:29:09 +01002527 if (mp_enable_bss_load_sharing) {
Harald Weltef8ef0282020-11-18 12:16:59 +01002528 /* don't enable this by default, as we don't yet have any automatic test setup for FR with 4 NS-VC */
2529 execute( TC_load_sharing_dl() );
2530 }
Harald Welte0e188242020-11-22 21:46:48 +01002531
2532 /* PAGING-PS over PTP BVC */
2533 execute( TC_paging_ps_ptp_bss() );
2534 execute( TC_paging_ps_ptp_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002535 execute( TC_paging_ps_ptp_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002536 execute( TC_paging_ps_ptp_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002537 execute( TC_paging_ps_ptp_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002538 execute( TC_paging_ps_ptp_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002539 execute( TC_paging_ps_ptp_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002540
2541 /* PAGING-PS over SIG BVC */
2542 execute( TC_paging_ps_sig_bss() );
2543 execute( TC_paging_ps_sig_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002544 execute( TC_paging_ps_sig_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002545 execute( TC_paging_ps_sig_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002546 execute( TC_paging_ps_sig_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002547 execute( TC_paging_ps_sig_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002548 execute( TC_paging_ps_sig_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002549
2550 /* PAGING-CS over PTP BVC */
2551 execute( TC_paging_cs_ptp_bss() );
2552 execute( TC_paging_cs_ptp_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002553 execute( TC_paging_cs_ptp_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002554 execute( TC_paging_cs_ptp_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002555 execute( TC_paging_cs_ptp_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002556 execute( TC_paging_cs_ptp_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002557 execute( TC_paging_cs_ptp_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002558
2559 /* PAGING-CS over SIG BVC */
2560 execute( TC_paging_cs_sig_bss() );
2561 execute( TC_paging_cs_sig_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002562 execute( TC_paging_cs_sig_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002563 execute( TC_paging_cs_sig_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002564 execute( TC_paging_cs_sig_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002565 execute( TC_paging_cs_sig_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002566 execute( TC_paging_cs_sig_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002567
2568
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002569 execute( TC_flush_ll() );
Harald Welte299aa482020-12-09 15:10:55 +01002570 execute( TC_fc_bvc() );
Harald Weltecc3894b2020-12-09 16:50:12 +01002571 execute( TC_fc_ms() );
Daniel Willmann423d8f42020-09-08 18:58:22 +02002572}
2573
2574
2575}